• 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;
18 
19 import com.android.camera.ui.PopupManager;
20 import com.android.camera.ui.RotateImageView;
21 
22 import android.content.Context;
23 import android.graphics.PorterDuff;
24 import android.graphics.drawable.Drawable;
25 import android.util.AttributeSet;
26 import android.util.Log;
27 import android.view.View;
28 import android.view.animation.Animation;
29 import android.view.animation.Animation.AnimationListener;
30 import android.view.animation.AnimationUtils;
31 import android.widget.ImageView;
32 import android.widget.RelativeLayout;
33 
34 /**
35  * A widget that includes three mode selections {@code RotateImageView}'s and
36  * a current mode indicator.
37  */
38 public class ModePicker extends RelativeLayout implements View.OnClickListener,
39     PopupManager.OnOtherPopupShowedListener {
40     public static final int MODE_CAMERA = 0;
41     public static final int MODE_VIDEO = 1;
42     public static final int MODE_PANORAMA = 2;
43 
44     private static final String TAG = "ModePicker";
45     // Total mode number
46     private static final int MODE_NUM = 3;
47 
48     /** A callback to be called when the user wants to switch activity. */
49     public interface OnModeChangeListener {
50         // Returns true if the listener agrees that the mode can be changed.
onModeChanged(int newMode)51         public boolean onModeChanged(int newMode);
52     }
53 
54     private final int DISABLED_COLOR;
55     private final int CURRENT_MODE_BACKGROUND;
56 
57     private OnModeChangeListener mListener;
58     private View mModeSelectionFrame;
59     private RotateImageView mModeSelectionIcon[];
60     private View mCurrentModeFrame;
61     private RotateImageView mCurrentModeIcon[];
62     private View mCurrentModeBar;
63     private boolean mSelectionEnabled;
64 
65 
66     private int mCurrentMode = 0;
67     private Animation mFadeIn, mFadeOut;
68 
ModePicker(Context context, AttributeSet attrs)69     public ModePicker(Context context, AttributeSet attrs) {
70         super(context, attrs);
71         DISABLED_COLOR = context.getResources().getColor(R.color.icon_disabled_color);
72         CURRENT_MODE_BACKGROUND = R.drawable.btn_mode_background;
73         mFadeIn = AnimationUtils.loadAnimation(
74                 context, R.anim.mode_selection_fade_in);
75         mFadeOut = AnimationUtils.loadAnimation(
76                 context, R.anim.mode_selection_fade_out);
77         mFadeOut.setAnimationListener(mAnimationListener);
78         PopupManager.getInstance(context).setOnOtherPopupShowedListener(this);
79     }
80 
onFinishInflate()81     protected void onFinishInflate() {
82         super.onFinishInflate();
83 
84         mModeSelectionFrame = findViewById(R.id.mode_selection);
85         mModeSelectionIcon = new RotateImageView[MODE_NUM];
86         mModeSelectionIcon[MODE_PANORAMA] =
87                 (RotateImageView) findViewById(R.id.mode_panorama);
88         mModeSelectionIcon[MODE_VIDEO] =
89                 (RotateImageView) findViewById(R.id.mode_video);
90         mModeSelectionIcon[MODE_CAMERA] =
91                 (RotateImageView) findViewById(R.id.mode_camera);
92 
93         // The current mode frame is for Phone UI only.
94         mCurrentModeFrame = findViewById(R.id.current_mode);
95         if (mCurrentModeFrame != null) {
96             mCurrentModeIcon = new RotateImageView[MODE_NUM];
97             mCurrentModeIcon[0] = (RotateImageView) findViewById(R.id.mode_0);
98             mCurrentModeIcon[1] = (RotateImageView) findViewById(R.id.mode_1);
99             mCurrentModeIcon[2] = (RotateImageView) findViewById(R.id.mode_2);
100         } else {
101             // current_mode_bar is only for tablet.
102             mCurrentModeBar = findViewById(R.id.current_mode_bar);
103             enableModeSelection(true);
104         }
105         registerOnClickListener();
106     }
107 
registerOnClickListener()108     private void registerOnClickListener() {
109         if (mCurrentModeFrame != null) {
110             mCurrentModeFrame.setOnClickListener(this);
111         }
112         for (int i = 0; i < MODE_NUM; ++i) {
113             mModeSelectionIcon[i].setOnClickListener(this);
114         }
115     }
116 
117     @Override
onOtherPopupShowed()118     public void onOtherPopupShowed() {
119         if (mSelectionEnabled) enableModeSelection(false);
120     }
121 
122     private AnimationListener mAnimationListener = new AnimationListener() {
123         public void onAnimationEnd(Animation animation) {
124             changeToSelectedMode();
125             mCurrentModeFrame.setVisibility(View.VISIBLE);
126             mModeSelectionFrame.setVisibility(View.GONE);
127         }
128 
129         public void onAnimationRepeat(Animation animation) {
130         }
131 
132         public void onAnimationStart(Animation animation) {
133         }
134     };
135 
enableModeSelection(boolean enabled)136     private void enableModeSelection(boolean enabled) {
137         if (mCurrentModeFrame != null) {
138             mSelectionEnabled = enabled;
139             // Animation Effect is applied on Phone UI only.
140             mModeSelectionFrame.startAnimation(enabled ? mFadeIn : mFadeOut);
141             if (enabled) {
142                 mModeSelectionFrame.setVisibility(View.VISIBLE);
143                 mCurrentModeFrame.setVisibility(View.GONE);
144             }
145         }
146         updateModeState();
147     }
148 
changeToSelectedMode()149     private void changeToSelectedMode() {
150         if (mListener != null) {
151             if (mListener.onModeChanged(mCurrentMode)) {
152                 Log.e(TAG, "failed:onModeChanged:" + mCurrentMode);
153             }
154         }
155     }
156 
onClick(View view)157     public void onClick(View view) {
158         if (view == mCurrentModeFrame) {
159             PopupManager.getInstance(getContext()).notifyShowPopup(this);
160             enableModeSelection(true);
161         } else {
162             // Set the selected mode as the current one and switch to it.
163             for (int i = 0; i < MODE_NUM; ++i) {
164                 if (view == mModeSelectionIcon[i] && (mCurrentMode != i)) {
165                     setCurrentMode(i);
166                     break;
167                 }
168             }
169             if (mCurrentModeBar == null) {
170                 enableModeSelection(false);
171             } else {
172                 changeToSelectedMode();
173             }
174         }
175     }
176 
setOnModeChangeListener(OnModeChangeListener listener)177     public void setOnModeChangeListener(OnModeChangeListener listener) {
178         mListener = listener;
179     }
180 
setCurrentMode(int mode)181     public void setCurrentMode(int mode) {
182         mCurrentMode = mode;
183         updateModeState();
184     }
185 
onModeChanged(int mode)186     public boolean onModeChanged(int mode) {
187         setCurrentMode(mode);
188         return true;
189     }
190 
setDegree(int degree)191     public void setDegree(int degree) {
192         for (int i = 0; i < MODE_NUM; ++i) {
193             mModeSelectionIcon[i].setDegree(degree);
194             if (mCurrentModeFrame != null) {
195                 mCurrentModeIcon[i].setDegree(degree);
196             }
197         }
198     }
199 
200     @Override
setEnabled(boolean enabled)201     public void setEnabled(boolean enabled) {
202         super.setEnabled(enabled);
203 
204         // Enable or disable the frames.
205         if (mCurrentModeFrame != null) mCurrentModeFrame.setEnabled(enabled);
206         mModeSelectionFrame.setEnabled(enabled);
207 
208         // Enable or disable the icons.
209         for (int i = 0; i < MODE_NUM; ++i) {
210             mModeSelectionIcon[i].setEnabled(enabled);
211             if (mCurrentModeFrame != null) mCurrentModeIcon[i].setEnabled(enabled);
212         }
213         if (enabled) updateModeState();
214     }
215 
highlightView(ImageView view, boolean enabled)216     private void highlightView(ImageView view, boolean enabled) {
217         if (enabled) {
218             view.clearColorFilter();
219         } else {
220             view.setColorFilter(DISABLED_COLOR, PorterDuff.Mode.SRC_ATOP);
221         }
222     }
223 
updateModeState()224     private void updateModeState() {
225         // Grey-out the unselected icons.
226         for (int i = 0; i < MODE_NUM; ++i) {
227             highlightView(mModeSelectionIcon[i], (i == mCurrentMode));
228         }
229         // Update the current mode icons on the Phone UI. The selected mode
230         // should be in the center of the current mode icon bar.
231         if (mCurrentModeFrame != null) {
232             for (int i = 0, j = 0; i < MODE_NUM; ++i) {
233                 int target;
234                 if (i == 1) {
235                     // The second icon is always the selected mode.
236                     target = mCurrentMode;
237                 } else {
238                     // Set the icons in order of camera, video and panorama.
239                     if (j == mCurrentMode) j++;
240                     target = j++;
241                 }
242                 mCurrentModeIcon[i].setImageDrawable(
243                         mModeSelectionIcon[target].getDrawable());
244             }
245         }
246     }
247 
248     @Override
onLayout( boolean changed, int left, int top, int right, int bottom)249     protected void onLayout(
250             boolean changed, int left, int top, int right, int bottom) {
251         super.onLayout(changed, left, top, right, bottom);
252         // Layout the current mode indicator bar.
253         if (mCurrentModeBar != null) {
254             int viewWidth = mModeSelectionIcon[MODE_CAMERA].getWidth();
255             int iconWidth = ((ImageView) mModeSelectionIcon[MODE_CAMERA])
256                     .getDrawable().getIntrinsicWidth();
257             int padding = (viewWidth - iconWidth) / 2;
258             int l = mModeSelectionFrame.getLeft() + mCurrentMode * viewWidth;
259             mCurrentModeBar.layout((l + padding),
260                     (bottom - top - mCurrentModeBar.getHeight()),
261                     (l + padding + iconWidth),
262                     (bottom - top));
263         }
264     }
265 }
266