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