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.camera2.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.
     59      *
     60      * @param context  The context to use.  Usually your
     61      *                 {@link android.app.Application} or
     62      *                 {@link android.app.Activity} object.
     63      */
     64     private OnScreenHint(Context context) {
     65         mWM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
     66         mY = context.getResources().getDimensionPixelSize(
     67                 R.dimen.hint_y_offset);
     68 
     69         mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
     70         mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
     71         mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
     72                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
     73         mParams.format = PixelFormat.TRANSLUCENT;
     74         mParams.windowAnimations = R.style.Animation_OnScreenHint;
     75         mParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
     76         mParams.setTitle("OnScreenHint");
     77     }
     78 
     79     /**
     80      * Show the view on the screen.
     81      */
     82     public void show() {
     83         if (mNextView == null) {
     84             throw new RuntimeException("View is not initialized");
     85         }
     86         mHandler.post(mShow);
     87     }
     88 
     89     /**
     90      * Close the view if it's showing.
     91      */
     92     public void cancel() {
     93         mHandler.post(mHide);
     94     }
     95 
     96     /**
     97      * Make a standard hint that just contains a text view.
     98      *
     99      * @param context  The context to use.  Usually your
    100      *                 {@link android.app.Application} or
    101      *                 {@link android.app.Activity} object.
    102      * @param text     The text to show.  Can be formatted text.
    103      *
    104      */
    105     public static OnScreenHint makeText(Context context, CharSequence text) {
    106         OnScreenHint result = new OnScreenHint(context);
    107 
    108         LayoutInflater inflate =
    109                 (LayoutInflater) context.getSystemService(
    110                 Context.LAYOUT_INFLATER_SERVICE);
    111         View v = inflate.inflate(R.layout.on_screen_hint, null);
    112         TextView tv = (TextView) v.findViewById(R.id.message);
    113         tv.setText(text);
    114 
    115         result.mNextView = v;
    116 
    117         return result;
    118     }
    119 
    120     /**
    121      * Update the text in a OnScreenHint that was previously created using one
    122      * of the makeText() methods.
    123      * @param s The new text for the OnScreenHint.
    124      */
    125     public void setText(CharSequence s) {
    126         if (mNextView == null) {
    127             throw new RuntimeException("This OnScreenHint was not "
    128                     + "created with OnScreenHint.makeText()");
    129         }
    130         TextView tv = (TextView) mNextView.findViewById(R.id.message);
    131         if (tv == null) {
    132             throw new RuntimeException("This OnScreenHint was not "
    133                     + "created with OnScreenHint.makeText()");
    134         }
    135         tv.setText(s);
    136     }
    137 
    138     private synchronized void handleShow() {
    139         if (mView != mNextView) {
    140             // remove the old view if necessary
    141             handleHide();
    142             mView = mNextView;
    143             final int gravity = mGravity;
    144             mParams.gravity = gravity;
    145             if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK)
    146                     == Gravity.FILL_HORIZONTAL) {
    147                 mParams.horizontalWeight = 1.0f;
    148             }
    149             if ((gravity & Gravity.VERTICAL_GRAVITY_MASK)
    150                     == Gravity.FILL_VERTICAL) {
    151                 mParams.verticalWeight = 1.0f;
    152             }
    153             mParams.x = mX;
    154             mParams.y = mY;
    155             mParams.verticalMargin = mVerticalMargin;
    156             mParams.horizontalMargin = mHorizontalMargin;
    157             if (mView.getParent() != null) {
    158                 mWM.removeView(mView);
    159             }
    160             mWM.addView(mView, mParams);
    161         }
    162     }
    163 
    164     private synchronized void handleHide() {
    165         if (mView != null) {
    166             // note: checking parent() just to make sure the view has
    167             // been added...  i have seen cases where we get here when
    168             // the view isn't yet added, so let's try not to crash.
    169             if (mView.getParent() != null) {
    170                 mWM.removeView(mView);
    171             }
    172             mView = null;
    173         }
    174     }
    175 
    176     private final Runnable mShow = new Runnable() {
    177         @Override
    178         public void run() {
    179             handleShow();
    180         }
    181     };
    182 
    183     private final Runnable mHide = new Runnable() {
    184         @Override
    185         public void run() {
    186             handleHide();
    187         }
    188     };
    189 }
    190 
    191