1 /* 2 * Copyright (C) 2014 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.widget; 18 19 import android.content.Context; 20 import android.content.res.TypedArray; 21 import android.graphics.drawable.Drawable; 22 import android.view.View; 23 import android.widget.ImageView; 24 25 import com.android.camera.ButtonManager; 26 import com.android.camera.app.AppController; 27 import com.android.camera.debug.Log; 28 import com.android.camera.settings.Keys; 29 import com.android.camera.settings.SettingsManager; 30 import com.android.camera.util.PhotoSphereHelper; 31 import com.android.camera2.R; 32 33 /** 34 * IndicatorIconController sets the visibility and icon state of 35 * on screen indicators. 36 * 37 * Indicators are only visible if they are in a non-default state. The 38 * visibility of an indicator is set when an indicator's setting changes. 39 */ 40 public class IndicatorIconController 41 implements SettingsManager.OnSettingChangedListener, 42 ButtonManager.ButtonStatusListener { 43 44 private final static Log.Tag TAG = new Log.Tag("IndicatorIconCtrlr"); 45 46 private ImageView mFlashIndicator; 47 private ImageView mHdrIndicator; 48 private ImageView mPanoIndicator; 49 private ImageView mCountdownTimerIndicator; 50 51 private ImageView mExposureIndicatorN2; 52 private ImageView mExposureIndicatorN1; 53 private ImageView mExposureIndicatorP1; 54 private ImageView mExposureIndicatorP2; 55 56 private TypedArray mFlashIndicatorPhotoIcons; 57 private TypedArray mFlashIndicatorVideoIcons; 58 private TypedArray mHdrPlusIndicatorIcons; 59 private TypedArray mHdrIndicatorIcons; 60 private TypedArray mPanoIndicatorIcons; 61 private TypedArray mCountdownTimerIndicatorIcons; 62 63 private AppController mController; 64 65 public IndicatorIconController(AppController controller, View root) { 66 mController = controller; 67 Context context = controller.getAndroidContext(); 68 69 mFlashIndicator = (ImageView) root.findViewById(R.id.flash_indicator); 70 mFlashIndicatorPhotoIcons = context.getResources().obtainTypedArray( 71 R.array.camera_flashmode_indicator_icons); 72 mFlashIndicatorVideoIcons = context.getResources().obtainTypedArray( 73 R.array.video_flashmode_indicator_icons); 74 75 mHdrIndicator = (ImageView) root.findViewById(R.id.hdr_indicator); 76 mHdrPlusIndicatorIcons = context.getResources().obtainTypedArray( 77 R.array.pref_camera_hdr_plus_indicator_icons); 78 mHdrIndicatorIcons = context.getResources().obtainTypedArray( 79 R.array.pref_camera_hdr_indicator_icons); 80 81 int panoIndicatorArrayId = PhotoSphereHelper.getPanoramaOrientationIndicatorArrayId(); 82 if (panoIndicatorArrayId > 0) { 83 mPanoIndicator = (ImageView) root.findViewById(R.id.pano_indicator); 84 mPanoIndicatorIcons = 85 context.getResources().obtainTypedArray(panoIndicatorArrayId); 86 } 87 88 mCountdownTimerIndicator = (ImageView) root.findViewById(R.id.countdown_timer_indicator); 89 mCountdownTimerIndicatorIcons = context.getResources().obtainTypedArray( 90 R.array.pref_camera_countdown_indicators); 91 92 mExposureIndicatorN2 = (ImageView) root.findViewById(R.id.exposure_n2_indicator); 93 mExposureIndicatorN1 = (ImageView) root.findViewById(R.id.exposure_n1_indicator); 94 mExposureIndicatorP1 = (ImageView) root.findViewById(R.id.exposure_p1_indicator); 95 mExposureIndicatorP2 = (ImageView) root.findViewById(R.id.exposure_p2_indicator); 96 } 97 98 @Override 99 public void onButtonVisibilityChanged(ButtonManager buttonManager, int buttonId) { 100 syncIndicatorWithButton(buttonId); 101 } 102 103 @Override 104 public void onButtonEnabledChanged(ButtonManager buttonManager, int buttonId) { 105 syncIndicatorWithButton(buttonId); 106 } 107 108 /** 109 * Syncs a specific indicator's icon and visibility 110 * based on the enabled state and visibility of a button. 111 */ 112 private void syncIndicatorWithButton(int buttonId) { 113 switch (buttonId) { 114 case ButtonManager.BUTTON_FLASH: { 115 syncFlashIndicator(); 116 break; 117 } 118 case ButtonManager.BUTTON_TORCH: { 119 syncFlashIndicator(); 120 break; 121 } 122 case ButtonManager.BUTTON_HDR_PLUS: { 123 syncHdrIndicator(); 124 break; 125 } 126 case ButtonManager.BUTTON_HDR: { 127 syncHdrIndicator(); 128 break; 129 } 130 case ButtonManager.BUTTON_EXPOSURE_COMPENSATION: { 131 syncExposureIndicator(); 132 break; 133 } 134 default: 135 // Do nothing. The indicator doesn't care 136 // about button that don't correspond to indicators. 137 } 138 } 139 140 /** 141 * Sets all indicators to the correct resource and visibility 142 * based on the current settings. 143 */ 144 public void syncIndicators() { 145 syncFlashIndicator(); 146 syncHdrIndicator(); 147 syncPanoIndicator(); 148 syncExposureIndicator(); 149 syncCountdownTimerIndicator(); 150 } 151 152 /** 153 * If the new visibility is different from the current visibility 154 * on a view, change the visibility and call any registered 155 * {@link OnIndicatorVisibilityChangedListener}. 156 */ 157 private static void changeVisibility(View view, int visibility) { 158 if (view.getVisibility() != visibility) { 159 view.setVisibility(visibility); 160 } 161 } 162 163 /** 164 * Sync the icon and visibility of the flash indicator. 165 */ 166 private void syncFlashIndicator() { 167 ButtonManager buttonManager = mController.getButtonManager(); 168 // If flash isn't an enabled and visible option, 169 // do not show the indicator. 170 if (buttonManager.isEnabled(ButtonManager.BUTTON_FLASH) 171 && buttonManager.isVisible(ButtonManager.BUTTON_FLASH)) { 172 173 int modeIndex = mController.getCurrentModuleIndex(); 174 if (modeIndex == mController.getAndroidContext().getResources() 175 .getInteger(R.integer.camera_mode_video)) { 176 setIndicatorState(mController.getCameraScope(), 177 Keys.KEY_VIDEOCAMERA_FLASH_MODE, mFlashIndicator, 178 mFlashIndicatorVideoIcons, false); 179 } else if (modeIndex == mController.getAndroidContext().getResources() 180 .getInteger(R.integer.camera_mode_gcam)) { 181 setIndicatorState(mController.getCameraScope(), 182 Keys.KEY_HDR_PLUS_FLASH_MODE, mFlashIndicator, 183 mFlashIndicatorPhotoIcons, false); 184 } else { 185 setIndicatorState(mController.getCameraScope(), 186 Keys.KEY_FLASH_MODE, mFlashIndicator, 187 mFlashIndicatorPhotoIcons, false); 188 } 189 } else { 190 changeVisibility(mFlashIndicator, View.GONE); 191 } 192 } 193 194 /** 195 * Sync the icon and the visibility of the hdr/hdrplus indicator. 196 */ 197 private void syncHdrIndicator() { 198 ButtonManager buttonManager = mController.getButtonManager(); 199 // If hdr isn't an enabled and visible option, 200 // do not show the indicator. 201 if (buttonManager.isEnabled(ButtonManager.BUTTON_HDR_PLUS) 202 && buttonManager.isVisible(ButtonManager.BUTTON_HDR_PLUS)) { 203 setIndicatorState(SettingsManager.SCOPE_GLOBAL, 204 Keys.KEY_CAMERA_HDR_PLUS, mHdrIndicator, 205 mHdrPlusIndicatorIcons, false); 206 } else if (buttonManager.isEnabled(ButtonManager.BUTTON_HDR) 207 && buttonManager.isVisible(ButtonManager.BUTTON_HDR)) { 208 setIndicatorState(SettingsManager.SCOPE_GLOBAL, 209 Keys.KEY_CAMERA_HDR, mHdrIndicator, 210 mHdrIndicatorIcons, false); 211 } else { 212 changeVisibility(mHdrIndicator, View.GONE); 213 } 214 } 215 216 /** 217 * Sync the icon and the visibility of the pano indicator. 218 */ 219 private void syncPanoIndicator() { 220 if (mPanoIndicator == null) { 221 Log.w(TAG, "Trying to sync a pano indicator that is not initialized."); 222 return; 223 } 224 225 ButtonManager buttonManager = mController.getButtonManager(); 226 if (buttonManager.isPanoEnabled()) { 227 setIndicatorState(SettingsManager.SCOPE_GLOBAL, 228 Keys.KEY_CAMERA_PANO_ORIENTATION, mPanoIndicator, 229 mPanoIndicatorIcons, true); 230 } else { 231 changeVisibility(mPanoIndicator, View.GONE); 232 } 233 } 234 235 private void syncExposureIndicator() { 236 if (mExposureIndicatorN2 == null 237 || mExposureIndicatorN1 == null 238 || mExposureIndicatorP1 == null 239 || mExposureIndicatorP2 == null) { 240 Log.w(TAG, "Trying to sync exposure indicators that are not initialized."); 241 return; 242 } 243 244 245 // Reset all exposure indicator icons. 246 changeVisibility(mExposureIndicatorN2, View.GONE); 247 changeVisibility(mExposureIndicatorN1, View.GONE); 248 changeVisibility(mExposureIndicatorP1, View.GONE); 249 changeVisibility(mExposureIndicatorP2, View.GONE); 250 251 ButtonManager buttonManager = mController.getButtonManager(); 252 if (buttonManager.isEnabled(ButtonManager.BUTTON_EXPOSURE_COMPENSATION) 253 && buttonManager.isVisible(ButtonManager.BUTTON_EXPOSURE_COMPENSATION)) { 254 255 int compValue = mController.getSettingsManager().getInteger( 256 mController.getCameraScope(), Keys.KEY_EXPOSURE); 257 int comp = Math.round(compValue * buttonManager.getExposureCompensationStep()); 258 259 // Turn on the appropriate indicator. 260 switch (comp) { 261 case -2: 262 changeVisibility(mExposureIndicatorN2, View.VISIBLE); 263 break; 264 case -1: 265 changeVisibility(mExposureIndicatorN1, View.VISIBLE); 266 break; 267 case 0: 268 // Do nothing. 269 break; 270 case 1: 271 changeVisibility(mExposureIndicatorP1, View.VISIBLE); 272 break; 273 case 2: 274 changeVisibility(mExposureIndicatorP2, View.VISIBLE); 275 } 276 } 277 } 278 279 private void syncCountdownTimerIndicator() { 280 ButtonManager buttonManager = mController.getButtonManager(); 281 282 if (buttonManager.isEnabled(ButtonManager.BUTTON_COUNTDOWN) 283 && buttonManager.isVisible(ButtonManager.BUTTON_COUNTDOWN)) { 284 setIndicatorState(SettingsManager.SCOPE_GLOBAL, 285 Keys.KEY_COUNTDOWN_DURATION, mCountdownTimerIndicator, 286 mCountdownTimerIndicatorIcons, false); 287 } else { 288 changeVisibility(mCountdownTimerIndicator, View.GONE); 289 } 290 } 291 292 /** 293 * Sets the image resource and visibility of the indicator 294 * based on the indicator's corresponding setting state. 295 */ 296 private void setIndicatorState(String scope, String key, ImageView imageView, 297 TypedArray iconArray, boolean showDefault) { 298 SettingsManager settingsManager = mController.getSettingsManager(); 299 300 int valueIndex = settingsManager.getIndexOfCurrentValue(scope, key); 301 if (valueIndex < 0) { 302 // This can happen when the setting is camera dependent 303 // and the camera is not yet open. CameraAppUI.onChangeCamera() 304 // will call this again when the camera is open. 305 Log.w(TAG, "The setting for this indicator is not available."); 306 imageView.setVisibility(View.GONE); 307 return; 308 } 309 Drawable drawable = iconArray.getDrawable(valueIndex); 310 if (drawable == null) { 311 throw new IllegalStateException("Indicator drawable is null."); 312 } 313 imageView.setImageDrawable(drawable); 314 315 // Set the indicator visible if not in default state. 316 boolean visibilityChanged = false; 317 if (!showDefault && settingsManager.isDefault(scope, key)) { 318 changeVisibility(imageView, View.GONE); 319 } else { 320 changeVisibility(imageView, View.VISIBLE); 321 } 322 } 323 324 @Override 325 public void onSettingChanged(SettingsManager settingsManager, String key) { 326 if (key.equals(Keys.KEY_FLASH_MODE)) { 327 syncFlashIndicator(); 328 return; 329 } 330 if (key.equals(Keys.KEY_VIDEOCAMERA_FLASH_MODE)) { 331 syncFlashIndicator(); 332 return; 333 } 334 if (key.equals(Keys.KEY_CAMERA_HDR_PLUS)) { 335 syncHdrIndicator(); 336 return; 337 } 338 if (key.equals(Keys.KEY_CAMERA_HDR)) { 339 syncHdrIndicator(); 340 return; 341 } 342 if (key.equals(Keys.KEY_CAMERA_PANO_ORIENTATION)) { 343 syncPanoIndicator(); 344 return; 345 } 346 if (key.equals(Keys.KEY_EXPOSURE)) { 347 syncExposureIndicator(); 348 return; 349 } 350 if (key.equals(Keys.KEY_COUNTDOWN_DURATION)) { 351 syncCountdownTimerIndicator(); 352 return; 353 } 354 } 355 356 } 357