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