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