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