blob: f47d9d8cbbef3e4d4356442baf37c411940a5dff [file] [log] [blame]
Michael Kolb8872c232013-01-29 10:33:22 -08001/*
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
17package com.android.camera;
18
19import android.content.Context;
20import android.graphics.PixelFormat;
21import android.os.Handler;
22import android.view.Gravity;
23import android.view.LayoutInflater;
24import android.view.View;
25import android.view.WindowManager;
26import android.widget.TextView;
27
Sascha Haeberling8e963a52013-08-06 11:43:02 -070028import com.android.camera2.R;
John Reck54987e82013-02-15 15:51:30 -080029
Michael Kolb8872c232013-01-29 10:33:22 -080030/**
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 */
42public 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