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