Home | History | Annotate | Download | only in camera
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.camera;
     18 
     19 import android.app.Activity;
     20 import android.content.Context;
     21 import android.graphics.PixelFormat;
     22 import android.os.Handler;
     23 import android.view.Gravity;
     24 import android.view.LayoutInflater;
     25 import android.view.View;
     26 import android.view.WindowManager;
     27 import android.widget.TextView;
     28 
     29 import com.android.camera.debug.Log;
     30 import com.android.camera2.R;
     31 
     32 /**
     33  * A on-screen hint is a view containing a little message for the user and will
     34  * be shown on the screen continuously.  This class helps you create and show
     35  * those.
     36  *
     37  * <p>
     38  * When the view is shown to the user, appears as a floating view over the
     39  * application.
     40  * <p>
     41  * The easiest way to use this class is to call one of the static methods that
     42  * constructs everything you need and returns a new {@code OnScreenHint} object.
     43  */
     44 public class OnScreenHint {
     45     static final Log.Tag TAG = new Log.Tag("OnScreenHint");
     46 
     47     int mGravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
     48     int mX, mY;
     49     float mHorizontalMargin;
     50     float mVerticalMargin;
     51     View mView;
     52     View mNextView;
     53 
     54     private final WindowManager.LayoutParams mParams =
     55             new WindowManager.LayoutParams();
     56     private final WindowManager mWM;
     57     private final Handler mHandler = new Handler();
     58 
     59     /**
     60      * Construct an empty OnScreenHint object.
     61      *
     62      * @param context  The context to use.  Usually your
     63      *                 {@link android.app.Application} or
     64      *                 {@link android.app.Activity} object.
     65      */
     66     private OnScreenHint(Activity activity) {
     67         mWM = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
     68         mY = activity.getResources().getDimensionPixelSize(
     69                 R.dimen.hint_y_offset);
     70 
     71         mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
     72         mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
     73         mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
     74                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
     75         mParams.format = PixelFormat.TRANSLUCENT;
     76         mParams.windowAnimations = R.style.Animation_OnScreenHint;
     77         mParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
     78         mParams.setTitle("OnScreenHint");
     79     }
     80 
     81     /**
     82      * Show the view on the screen.
     83      */
     84     public void show() {
     85         if (mNextView == null) {
     86             throw new RuntimeException("View is not initialized");
     87         }
     88         mHandler.post(mShow);
     89     }
     90 
     91     /**
     92      * Close the view if it's showing.
     93      */
     94     public void cancel() {
     95         mHandler.post(mHide);
     96     }
     97 
     98     /**
     99      * Make a standard hint that just contains a text view.
    100      *
    101      * @param context  The context to use.  Usually your
    102      *                 {@link android.app.Application} or
    103      *                 {@link android.app.Activity} object.
    104      * @param text     The text to show.  Can be formatted text.
    105      *
    106      */
    107     public static OnScreenHint makeText(Activity activity, CharSequence text) {
    108         OnScreenHint result = new OnScreenHint(activity);
    109 
    110         LayoutInflater inflate =
    111                 (LayoutInflater) activity.getSystemService(
    112                 Context.LAYOUT_INFLATER_SERVICE);
    113         View v = inflate.inflate(R.layout.on_screen_hint, null);
    114         TextView tv = (TextView) v.findViewById(R.id.message);
    115         tv.setText(text);
    116 
    117         result.mNextView = v;
    118 
    119         return result;
    120     }
    121 
    122     /**
    123      * Update the text in a OnScreenHint that was previously created using one
    124      * of the makeText() methods.
    125      * @param s The new text for the OnScreenHint.
    126      */
    127     public void setText(CharSequence s) {
    128         if (mNextView == null) {
    129             throw new RuntimeException("This OnScreenHint was not "
    130                     + "created with OnScreenHint.makeText()");
    131         }
    132         TextView tv = (TextView) mNextView.findViewById(R.id.message);
    133         if (tv == null) {
    134             throw new RuntimeException("This OnScreenHint was not "
    135                     + "created with OnScreenHint.makeText()");
    136         }
    137         tv.setText(s);
    138     }
    139 
    140     private synchronized void handleShow() {
    141         if (mView != mNextView) {
    142             // remove the old view if necessary
    143             handleHide();
    144             mView = mNextView;
    145             final int gravity = mGravity;
    146             mParams.gravity = gravity;
    147             if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK)
    148                     == Gravity.FILL_HORIZONTAL) {
    149                 mParams.horizontalWeight = 1.0f;
    150             }
    151             if ((gravity & Gravity.VERTICAL_GRAVITY_MASK)
    152                     == Gravity.FILL_VERTICAL) {
    153                 mParams.verticalWeight = 1.0f;
    154             }
    155             mParams.x = mX;
    156             mParams.y = mY;
    157             mParams.verticalMargin = mVerticalMargin;
    158             mParams.horizontalMargin = mHorizontalMargin;
    159             if (mView.getParent() != null) {
    160                 mWM.removeView(mView);
    161             }
    162             mWM.addView(mView, mParams);
    163         }
    164     }
    165 
    166     private synchronized void handleHide() {
    167         if (mView != null) {
    168             // note: checking parent() just to make sure the view has
    169             // been added...  i have seen cases where we get here when
    170             // the view isn't yet added, so let's try not to crash.
    171             if (mView.getParent() != null) {
    172                 mWM.removeView(mView);
    173             }
    174             mView = null;
    175         }
    176     }
    177 
    178     private final Runnable mShow = new Runnable() {
    179         @Override
    180         public void run() {
    181             handleShow();
    182         }
    183     };
    184 
    185     private final Runnable mHide = new Runnable() {
    186         @Override
    187         public void run() {
    188             handleHide();
    189         }
    190     };
    191 }
    192