• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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.ui;
18 
19 import android.content.Context;
20 import android.os.Handler;
21 import android.os.Message;
22 import android.view.MotionEvent;
23 import android.view.View;
24 import android.view.ViewGroup;
25 import android.view.animation.Animation;
26 import android.view.animation.AnimationUtils;
27 import android.widget.ImageView;
28 
29 import com.android.camera.R;
30 
31 // This is an indicator button and pressing it opens a popup window. Ex: flash or other settings.
32 public abstract class AbstractIndicatorButton extends RotateImageView implements
33         PopupManager.OnOtherPopupShowedListener {
34     @SuppressWarnings("unused")
35     private static final String TAG = "AbstractIndicatorButton";
36     protected Animation mFadeIn, mFadeOut;
37     protected final int HIGHLIGHT_COLOR;
38     protected AbstractSettingPopup mPopup;
39     protected Handler mHandler = new MainHandler();
40     private final int MSG_DISMISS_POPUP = 0;
41     private IndicatorChangeListener mListener;
42 
43     public static interface IndicatorChangeListener {
onShowIndicator(View view, boolean showed)44         public void onShowIndicator(View view, boolean showed);
45     }
46 
AbstractIndicatorButton(Context context)47     public AbstractIndicatorButton(Context context) {
48         super(context);
49         mFadeIn = AnimationUtils.loadAnimation(context, R.anim.setting_popup_grow_fade_in);
50         mFadeOut = AnimationUtils.loadAnimation(context, R.anim.setting_popup_shrink_fade_out);
51         HIGHLIGHT_COLOR = context.getResources().getColor(R.color.review_control_pressed_color);
52         setScaleType(ImageView.ScaleType.CENTER);
53         PopupManager.getInstance(context).setOnOtherPopupShowedListener(this);
54         // Set the click listener to help the comprehension of the accessibility.
55         setClickable(true);
56     }
57 
58     @Override
onOtherPopupShowed()59     public void onOtherPopupShowed() {
60         dismissPopup();
61     }
62 
setIndicatorChangeListener(IndicatorChangeListener listener)63     public void setIndicatorChangeListener(IndicatorChangeListener listener) {
64         mListener = listener;
65     }
66 
67     // Whether scene mode affects this indicator and it cannot be changed.
isOverridden()68     public boolean isOverridden() {
69         return false;
70     }
71 
72     // Scene mode may override other settings like flash, white-balance, and focus.
overrideSettings(final String ... keyvalues)73     abstract public void overrideSettings(final String ... keyvalues);
74 
75     @Override
onTouchEvent(MotionEvent ev)76     public boolean onTouchEvent(MotionEvent ev) {
77         if (!isEnabled()) return false;
78 
79         int action = ev.getAction();
80         if (action == MotionEvent.ACTION_DOWN && !isOverridden()) {
81             if (mPopup == null || mPopup.getVisibility() != View.VISIBLE) {
82                 showPopup();
83                 PopupManager.getInstance(getContext()).notifyShowPopup(this);
84             } else {
85                 dismissPopup();
86             }
87             return true;
88         } else if (action == MotionEvent.ACTION_CANCEL) {
89             dismissPopup();
90             return true;
91         }
92         return false;
93     }
94 
95     @Override
setEnabled(boolean enabled)96     public void setEnabled(boolean enabled) {
97         // Do not enable the button if it is overridden by scene mode.
98         if (isOverridden()) {
99             enabled = false;
100         }
101 
102         // Don't do anything if state is not changed so not to interfere with
103         // the "highlight" state.
104         if (isEnabled() ^ enabled) {
105             super.setEnabled(enabled);
106         }
107     }
108 
109     @Override
setOrientation(int orientation, boolean animation)110     public void setOrientation(int orientation, boolean animation) {
111         super.setOrientation(orientation, animation);
112         if (mPopup != null) {
113             mPopup.setOrientation(orientation, animation);
114         }
115     }
116 
initializePopup()117     abstract protected void initializePopup();
118 
showPopup()119     private void showPopup() {
120         setPressed(true);
121         mHandler.removeMessages(MSG_DISMISS_POPUP);
122         if (mPopup == null) initializePopup();
123 
124         mPopup.setVisibility(View.VISIBLE);
125         mPopup.setOrientation(getDegree(), false);
126         mPopup.clearAnimation();
127         mPopup.startAnimation(mFadeIn);
128         if (mListener != null) mListener.onShowIndicator(this, true);
129     }
130 
dismissPopup()131     public boolean dismissPopup() {
132         setPressed(false);
133         mHandler.removeMessages(MSG_DISMISS_POPUP);
134         if (mPopup != null && mPopup.getVisibility() == View.VISIBLE) {
135             mPopup.clearAnimation();
136             mPopup.startAnimation(mFadeOut);
137             mPopup.setVisibility(View.GONE);
138             if (mListener != null) mListener.onShowIndicator(this, false);
139             invalidate();
140             // Indicator wheel needs to update the highlight indicator if this
141             // is dismissed by MSG_DISMISS_POPUP.
142             ((View) getParent()).invalidate();
143             return true;
144         }
145         return false;
146     }
147 
getPopupWindow()148     public AbstractSettingPopup getPopupWindow() {
149         if (mPopup != null && mPopup.getVisibility() == View.VISIBLE) {
150             return mPopup;
151         } else {
152             return null;
153         }
154     }
155 
removePopupWindow()156     public void removePopupWindow() {
157         if (mPopup != null) {
158             ViewGroup root = (ViewGroup) getRootView().findViewById(R.id.frame_layout);
159             root.removeView(mPopup);
160             mPopup = null;
161         }
162     }
163 
reloadPreference()164     public void reloadPreference() {
165         if (mPopup != null) mPopup.reloadPreference();
166     }
167 
dismissPopupDelayed()168     protected void dismissPopupDelayed() {
169         if (!mHandler.hasMessages(MSG_DISMISS_POPUP)) {
170             mHandler.sendEmptyMessage(MSG_DISMISS_POPUP);
171         }
172     }
173 
174     private class MainHandler extends Handler {
175         @Override
handleMessage(Message msg)176         public void handleMessage(Message msg) {
177             switch (msg.what) {
178                 case MSG_DISMISS_POPUP:
179                     dismissPopup();
180                     break;
181             }
182         }
183     }
184 }
185