ButtonManager.java revision c989d417a53341b144e9f78304270ac66f8f5813
1/* 2 * Copyright (C) 2013 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 android.content.Context; 20import android.content.res.TypedArray; 21import android.view.LayoutInflater; 22import android.view.View; 23import android.widget.ImageButton; 24import android.widget.LinearLayout; 25 26import com.android.camera.app.AppController; 27import com.android.camera.app.CameraAppUI; 28import com.android.camera.settings.Keys; 29import com.android.camera.settings.SettingsManager; 30import com.android.camera.ui.RadioOptions; 31import com.android.camera.util.PhotoSphereHelper; 32import com.android.camera.widget.ModeOptions; 33import com.android.camera2.R; 34 35/** 36 * A class for generating pre-initialized 37 * {@link #android.widget.ImageButton}s. 38 */ 39public class ButtonManager implements SettingsManager.OnSettingChangedListener { 40 public static final int BUTTON_FLASH = 0; 41 public static final int BUTTON_TORCH = 1; 42 public static final int BUTTON_HDR_PLUS_FLASH = 2; 43 public static final int BUTTON_CAMERA = 3; 44 public static final int BUTTON_HDR_PLUS = 4; 45 public static final int BUTTON_HDR = 5; 46 public static final int BUTTON_CANCEL = 6; 47 public static final int BUTTON_DONE = 7; 48 public static final int BUTTON_RETAKE = 8; 49 public static final int BUTTON_REVIEW = 9; 50 public static final int BUTTON_GRID_LINES = 10; 51 public static final int BUTTON_EXPOSURE_COMPENSATION = 11; 52 public static final int BUTTON_COUNTDOWN = 12; 53 54 /** For two state MultiToggleImageButtons, the off index. */ 55 public static final int OFF = 0; 56 /** For two state MultiToggleImageButtons, the on index. */ 57 public static final int ON = 1; 58 59 private static final int NO_RESOURCE = -1; 60 61 /** A reference to the application's settings manager. */ 62 private final SettingsManager mSettingsManager; 63 64 /** Bottom bar options toggle buttons. */ 65 private MultiToggleImageButton mButtonCamera; 66 private MultiToggleImageButton mButtonFlash; 67 private MultiToggleImageButton mButtonHdr; 68 private MultiToggleImageButton mButtonGridlines; 69 private MultiToggleImageButton mButtonCountdown; 70 71 /** Intent UI buttons. */ 72 private ImageButton mButtonCancel; 73 private ImageButton mButtonDone; 74 private ImageButton mButtonRetake; // same as review. 75 76 private ImageButton mButtonExposureCompensation; 77 private ImageButton mExposureN2; 78 private ImageButton mExposureN1; 79 private ImageButton mExposure0; 80 private ImageButton mExposureP1; 81 private ImageButton mExposureP2; 82 private RadioOptions mModeOptionsExposure; 83 private RadioOptions mModeOptionsPano; 84 private View mModeOptionsButtons; 85 private ModeOptions mModeOptions; 86 87 private int mMinExposureCompensation; 88 private int mMaxExposureCompensation; 89 private float mExposureCompensationStep; 90 91 /** A listener for button enabled and visibility 92 state changes. */ 93 private ButtonStatusListener mListener; 94 95 /** An reference to the gcam mode index. */ 96 private static int sGcamIndex; 97 98 private final AppController mAppController; 99 100 /** 101 * Get a new global ButtonManager. 102 */ 103 public ButtonManager(AppController app) { 104 mAppController = app; 105 106 Context context = app.getAndroidContext(); 107 sGcamIndex = context.getResources().getInteger(R.integer.camera_mode_gcam); 108 109 mSettingsManager = app.getSettingsManager(); 110 mSettingsManager.addListener(this); 111 } 112 113 /** 114 * Load references to buttons under a root View. 115 * Call this after the root clears/reloads all of its children 116 * to prevent stale references button views. 117 */ 118 public void load(View root) { 119 getButtonsReferences(root); 120 } 121 122 /** 123 * ButtonStatusListener provides callbacks for when button's 124 * visibility changes and enabled status changes. 125 */ 126 public interface ButtonStatusListener { 127 /** 128 * A button's visibility has changed. 129 */ 130 public void onButtonVisibilityChanged(ButtonManager buttonManager, int buttonId); 131 132 /** 133 * A button's enabled state has changed. 134 */ 135 public void onButtonEnabledChanged(ButtonManager buttonManager, int buttonId); 136 } 137 138 /** 139 * Sets the ButtonStatusListener. 140 */ 141 public void setListener(ButtonStatusListener listener) { 142 mListener = listener; 143 } 144 145 /** 146 * Gets references to all known buttons. 147 */ 148 private void getButtonsReferences(View root) { 149 mButtonCamera 150 = (MultiToggleImageButton) root.findViewById(R.id.camera_toggle_button); 151 mButtonFlash 152 = (MultiToggleImageButton) root.findViewById(R.id.flash_toggle_button); 153 mButtonHdr 154 = (MultiToggleImageButton) root.findViewById(R.id.hdr_plus_toggle_button); 155 mButtonGridlines 156 = (MultiToggleImageButton) root.findViewById(R.id.grid_lines_toggle_button); 157 mButtonCancel 158 = (ImageButton) root.findViewById(R.id.cancel_button); 159 mButtonDone 160 = (ImageButton) root.findViewById(R.id.done_button); 161 mButtonRetake 162 = (ImageButton) root.findViewById(R.id.retake_button); 163 164 mButtonExposureCompensation = 165 (ImageButton) root.findViewById(R.id.exposure_button); 166 mExposureN2 = (ImageButton) root.findViewById(R.id.exposure_n2); 167 mExposureN1 = (ImageButton) root.findViewById(R.id.exposure_n1); 168 mExposure0 = (ImageButton) root.findViewById(R.id.exposure_0); 169 mExposureP1 = (ImageButton) root.findViewById(R.id.exposure_p1); 170 mExposureP2 = (ImageButton) root.findViewById(R.id.exposure_p2); 171 mModeOptionsExposure = (RadioOptions) root.findViewById(R.id.mode_options_exposure); 172 mModeOptionsPano = (RadioOptions) root.findViewById(R.id.mode_options_pano); 173 mModeOptionsButtons = root.findViewById(R.id.mode_options_buttons); 174 mModeOptions = (ModeOptions) root.findViewById(R.id.mode_options); 175 176 mButtonCountdown = (MultiToggleImageButton) root.findViewById(R.id.countdown_toggle_button); 177 } 178 179 @Override 180 public void onSettingChanged(SettingsManager settingsManager, String key) { 181 MultiToggleImageButton button = null; 182 int index = 0; 183 184 if (key.equals(Keys.KEY_FLASH_MODE)) { 185 index = mSettingsManager.getIndexOfCurrentValue(mAppController.getCameraScope(), 186 Keys.KEY_FLASH_MODE); 187 button = getButtonOrError(BUTTON_FLASH); 188 } else if (key.equals(Keys.KEY_VIDEOCAMERA_FLASH_MODE)) { 189 index = mSettingsManager.getIndexOfCurrentValue(mAppController.getCameraScope(), 190 Keys.KEY_VIDEOCAMERA_FLASH_MODE); 191 button = getButtonOrError(BUTTON_TORCH); 192 } else if (key.equals(Keys.KEY_HDR_PLUS_FLASH_MODE)) { 193 index = mSettingsManager.getIndexOfCurrentValue(mAppController.getModuleScope(), 194 Keys.KEY_HDR_PLUS_FLASH_MODE); 195 button = getButtonOrError(BUTTON_HDR_PLUS_FLASH); 196 } else if (key.equals(Keys.KEY_CAMERA_ID)) { 197 index = mSettingsManager.getIndexOfCurrentValue(mAppController.getModuleScope(), 198 Keys.KEY_CAMERA_ID); 199 button = getButtonOrError(BUTTON_CAMERA); 200 } else if (key.equals(Keys.KEY_CAMERA_HDR_PLUS)) { 201 index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL, 202 Keys.KEY_CAMERA_HDR_PLUS); 203 button = getButtonOrError(BUTTON_HDR_PLUS); 204 } else if (key.equals(Keys.KEY_CAMERA_HDR)) { 205 index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL, 206 Keys.KEY_CAMERA_HDR); 207 button = getButtonOrError(BUTTON_HDR); 208 } else if (key.equals(Keys.KEY_CAMERA_GRID_LINES)) { 209 index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL, 210 Keys.KEY_CAMERA_GRID_LINES); 211 button = getButtonOrError(BUTTON_GRID_LINES); 212 } else if (key.equals(Keys.KEY_CAMERA_PANO_ORIENTATION)) { 213 updatePanoButtons(); 214 } else if (key.equals(Keys.KEY_EXPOSURE)) { 215 updateExposureButtons(); 216 } else if (key.equals(Keys.KEY_COUNTDOWN_DURATION)) { 217 index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL, 218 Keys.KEY_COUNTDOWN_DURATION); 219 button = getButtonOrError(BUTTON_COUNTDOWN); 220 } 221 222 if (button != null && button.getState() != index) { 223 button.setState(Math.max(index, 0), false); 224 } 225 } 226 227 /** 228 * A callback executed in the state listener of a button. 229 * 230 * Used by a module to set specific behavior when a button's 231 * state changes. 232 */ 233 public interface ButtonCallback { 234 public void onStateChanged(int state); 235 } 236 237 /** 238 * Returns the appropriate {@link com.android.camera.MultiToggleImageButton} 239 * based on button id. An IllegalStateException will be throw if the 240 * button could not be found in the view hierarchy. 241 */ 242 private MultiToggleImageButton getButtonOrError(int buttonId) { 243 switch (buttonId) { 244 case BUTTON_FLASH: 245 if (mButtonFlash == null) { 246 throw new IllegalStateException("Flash button could not be found."); 247 } 248 return mButtonFlash; 249 case BUTTON_TORCH: 250 if (mButtonFlash == null) { 251 throw new IllegalStateException("Torch button could not be found."); 252 } 253 return mButtonFlash; 254 case BUTTON_HDR_PLUS_FLASH: 255 if (mButtonFlash == null) { 256 throw new IllegalStateException("Hdr plus torch button could not be found."); 257 } 258 return mButtonFlash; 259 case BUTTON_CAMERA: 260 if (mButtonCamera == null) { 261 throw new IllegalStateException("Camera button could not be found."); 262 } 263 return mButtonCamera; 264 case BUTTON_HDR_PLUS: 265 if (mButtonHdr == null) { 266 throw new IllegalStateException("Hdr plus button could not be found."); 267 } 268 return mButtonHdr; 269 case BUTTON_HDR: 270 if (mButtonHdr == null) { 271 throw new IllegalStateException("Hdr button could not be found."); 272 } 273 return mButtonHdr; 274 case BUTTON_GRID_LINES: 275 if (mButtonGridlines == null) { 276 throw new IllegalStateException("Grid lines button could not be found."); 277 } 278 return mButtonGridlines; 279 case BUTTON_COUNTDOWN: 280 if (mButtonCountdown == null) { 281 throw new IllegalStateException("Countdown button could not be found."); 282 } 283 return mButtonCountdown; 284 default: 285 throw new IllegalArgumentException("button not known by id=" + buttonId); 286 } 287 } 288 289 /** 290 * Returns the appropriate {@link android.widget.ImageButton} 291 * based on button id. An IllegalStateException will be throw if the 292 * button could not be found in the view hierarchy. 293 */ 294 private ImageButton getImageButtonOrError(int buttonId) { 295 switch (buttonId) { 296 case BUTTON_CANCEL: 297 if (mButtonCancel == null) { 298 throw new IllegalStateException("Cancel button could not be found."); 299 } 300 return mButtonCancel; 301 case BUTTON_DONE: 302 if (mButtonDone == null) { 303 throw new IllegalStateException("Done button could not be found."); 304 } 305 return mButtonDone; 306 case BUTTON_RETAKE: 307 if (mButtonRetake == null) { 308 throw new IllegalStateException("Retake button could not be found."); 309 } 310 return mButtonRetake; 311 case BUTTON_REVIEW: 312 if (mButtonRetake == null) { 313 throw new IllegalStateException("Review button could not be found."); 314 } 315 return mButtonRetake; 316 case BUTTON_EXPOSURE_COMPENSATION: 317 if (mButtonExposureCompensation == null) { 318 throw new IllegalStateException("Exposure Compensation button could not be found."); 319 } 320 return mButtonExposureCompensation; 321 default: 322 throw new IllegalArgumentException("button not known by id=" + buttonId); 323 } 324 } 325 326 /** 327 * Initialize a known button by id, with a state change callback and 328 * a resource id that points to an array of drawables, and then enable 329 * the button. 330 */ 331 public void initializeButton(int buttonId, ButtonCallback cb) { 332 MultiToggleImageButton button = getButtonOrError(buttonId); 333 switch (buttonId) { 334 case BUTTON_FLASH: 335 initializeFlashButton(button, cb, R.array.camera_flashmode_icons); 336 break; 337 case BUTTON_TORCH: 338 initializeTorchButton(button, cb, R.array.video_flashmode_icons); 339 break; 340 case BUTTON_HDR_PLUS_FLASH: 341 initializeHdrPlusFlashButton(button, cb, R.array.camera_flashmode_icons); 342 break; 343 case BUTTON_CAMERA: 344 initializeCameraButton(button, cb, R.array.camera_id_icons); 345 break; 346 case BUTTON_HDR_PLUS: 347 initializeHdrPlusButton(button, cb, R.array.pref_camera_hdr_plus_icons); 348 break; 349 case BUTTON_HDR: 350 initializeHdrButton(button, cb, R.array.pref_camera_hdr_icons); 351 break; 352 case BUTTON_GRID_LINES: 353 initializeGridLinesButton(button, cb, R.array.grid_lines_icons); 354 break; 355 case BUTTON_COUNTDOWN: 356 initializeCountdownButton(button, cb, R.array.countdown_duration_icons); 357 break; 358 default: 359 throw new IllegalArgumentException("button not known by id=" + buttonId); 360 } 361 362 showButton(buttonId); 363 enableButton(buttonId); 364 } 365 366 /** 367 * Initialize a known button with a click listener and a drawable resource id, 368 * and a content description resource id. 369 * Sets the button visible. 370 */ 371 public void initializePushButton(int buttonId, View.OnClickListener cb, 372 int imageId, int contentDescriptionId) { 373 ImageButton button = getImageButtonOrError(buttonId); 374 button.setOnClickListener(cb); 375 if (imageId != NO_RESOURCE) { 376 button.setImageResource(imageId); 377 } 378 if (contentDescriptionId != NO_RESOURCE) { 379 button.setContentDescription(mAppController 380 .getAndroidContext().getResources().getString(contentDescriptionId)); 381 } 382 383 if (!button.isEnabled()) { 384 button.setEnabled(true); 385 if (mListener != null) { 386 mListener.onButtonEnabledChanged(this, buttonId); 387 } 388 } 389 button.setTag(R.string.tag_enabled_id, buttonId); 390 391 if (button.getVisibility() != View.VISIBLE) { 392 button.setVisibility(View.VISIBLE); 393 if (mListener != null) { 394 mListener.onButtonVisibilityChanged(this, buttonId); 395 } 396 } 397 } 398 399 /** 400 * Initialize a known button with a click listener and a resource id. 401 * Sets the button visible. 402 */ 403 public void initializePushButton(int buttonId, View.OnClickListener cb, 404 int imageId) { 405 initializePushButton(buttonId, cb, imageId, NO_RESOURCE); 406 } 407 408 /** 409 * Initialize a known button with a click listener. Sets the button visible. 410 */ 411 public void initializePushButton(int buttonId, View.OnClickListener cb) { 412 initializePushButton(buttonId, cb, NO_RESOURCE, NO_RESOURCE); 413 } 414 415 /** 416 * Sets a button in its disabled (greyed out) state. 417 */ 418 public void disableButton(int buttonId) { 419 MultiToggleImageButton button = getButtonOrError(buttonId); 420 421 // HDR and HDR+ buttons share the same button object, 422 // but change actual image icons at runtime. 423 // This extra check is to ensure the correct icons are used 424 // in the case of the HDR[+] button being disabled at startup, 425 // e.g. app startup with front-facing camera. 426 // b/18104680 427 if (buttonId == BUTTON_HDR_PLUS) { 428 initializeHdrPlusButtonIcons(button, R.array.pref_camera_hdr_plus_icons); 429 } else if (buttonId == BUTTON_HDR) { 430 initializeHdrButtonIcons(button, R.array.pref_camera_hdr_icons); 431 } 432 433 if (button.isEnabled()) { 434 button.setEnabled(false); 435 if (mListener != null) { 436 mListener.onButtonEnabledChanged(this, buttonId); 437 } 438 } 439 button.setTag(R.string.tag_enabled_id, null); 440 } 441 442 /** 443 * Enables a button that has already been initialized. 444 */ 445 public void enableButton(int buttonId) { 446 ImageButton button = getButtonOrError(buttonId); 447 if (!button.isEnabled()) { 448 button.setEnabled(true); 449 if (mListener != null) { 450 mListener.onButtonEnabledChanged(this, buttonId); 451 } 452 } 453 button.setTag(R.string.tag_enabled_id, buttonId); 454 } 455 456 /** 457 * Disable click reactions for a button without affecting visual state. 458 * For most cases you'll want to use {@link #disableButton(int)}. 459 * @param buttonId The id of the button. 460 */ 461 public void disableButtonClick(int buttonId) { 462 ImageButton button = getButtonOrError(buttonId); 463 if (button instanceof MultiToggleImageButton) { 464 ((MultiToggleImageButton) button).setClickEnabled(false); 465 } 466 } 467 468 /** 469 * Enable click reactions for a button without affecting visual state. 470 * For most cases you'll want to use {@link #enableButton(int)}. 471 * @param buttonId The id of the button. 472 */ 473 public void enableButtonClick(int buttonId) { 474 ImageButton button = getButtonOrError(buttonId); 475 if (button instanceof MultiToggleImageButton) { 476 ((MultiToggleImageButton) button).setClickEnabled(true); 477 } 478 } 479 480 /** 481 * Hide a button by id. 482 */ 483 public void hideButton(int buttonId) { 484 View button; 485 try { 486 button = getButtonOrError(buttonId); 487 } catch (IllegalArgumentException e) { 488 button = getImageButtonOrError(buttonId); 489 } 490 if (button.getVisibility() == View.VISIBLE) { 491 button.setVisibility(View.GONE); 492 if (mListener != null) { 493 mListener.onButtonVisibilityChanged(this, buttonId); 494 } 495 } 496 } 497 498 /** 499 * Show a button by id. 500 */ 501 public void showButton(int buttonId) { 502 View button; 503 try { 504 button = getButtonOrError(buttonId); 505 } catch (IllegalArgumentException e) { 506 button = getImageButtonOrError(buttonId); 507 } 508 if (button.getVisibility() != View.VISIBLE) { 509 button.setVisibility(View.VISIBLE); 510 if (mListener != null) { 511 mListener.onButtonVisibilityChanged(this, buttonId); 512 } 513 } 514 } 515 516 517 public void setToInitialState() { 518 mModeOptions.setMainBar(ModeOptions.BAR_STANDARD); 519 } 520 521 public void setExposureCompensationCallback(final CameraAppUI.BottomBarUISpec 522 .ExposureCompensationSetCallback cb) { 523 if (cb == null) { 524 mModeOptionsExposure.setOnOptionClickListener(null); 525 } else { 526 mModeOptionsExposure 527 .setOnOptionClickListener(new RadioOptions.OnOptionClickListener() { 528 @Override 529 public void onOptionClicked(View v) { 530 int comp = Integer.parseInt((String)(v.getTag())); 531 532 if (mExposureCompensationStep != 0.0f) { 533 int compValue = 534 Math.round(comp / mExposureCompensationStep); 535 cb.setExposure(compValue); 536 } 537 } 538 }); 539 } 540 } 541 542 /** 543 * Set the exposure compensation parameters supported by the current camera mode. 544 * @param min Minimum exposure compensation value. 545 * @param max Maximum exposure compensation value. 546 * @param step Expsoure compensation step value. 547 */ 548 public void setExposureCompensationParameters(int min, int max, float step) { 549 mMaxExposureCompensation = max; 550 mMinExposureCompensation = min; 551 mExposureCompensationStep = step; 552 553 554 setVisible(mExposureN2, (Math.round(min * step) <= -2)); 555 setVisible(mExposureN1, (Math.round(min * step) <= -1)); 556 setVisible(mExposureP1, (Math.round(max * step) >= 1)); 557 setVisible(mExposureP2, (Math.round(max * step) >= 2)); 558 559 updateExposureButtons(); 560 } 561 562 private static void setVisible(View v, boolean visible) { 563 if (visible) { 564 v.setVisibility(View.VISIBLE); 565 } else { 566 v.setVisibility(View.INVISIBLE); 567 } 568 } 569 570 /** 571 * @return The exposure compensation step value. 572 **/ 573 public float getExposureCompensationStep() { 574 return mExposureCompensationStep; 575 } 576 577 /** 578 * Check if a button is enabled with the given button id.. 579 */ 580 public boolean isEnabled(int buttonId) { 581 View button; 582 try { 583 button = getButtonOrError(buttonId); 584 } catch (IllegalArgumentException e) { 585 button = getImageButtonOrError(buttonId); 586 } 587 588 Integer enabledId = (Integer) button.getTag(R.string.tag_enabled_id); 589 if (enabledId != null) { 590 return (enabledId.intValue() == buttonId) && button.isEnabled(); 591 } else { 592 return false; 593 } 594 } 595 596 /** 597 * Check if a button is visible. 598 */ 599 public boolean isVisible(int buttonId) { 600 View button; 601 try { 602 button = getButtonOrError(buttonId); 603 } catch (IllegalArgumentException e) { 604 button = getImageButtonOrError(buttonId); 605 } 606 return (button.getVisibility() == View.VISIBLE); 607 } 608 609 /** 610 * Initialize a flash button. 611 */ 612 private void initializeFlashButton(MultiToggleImageButton button, 613 final ButtonCallback cb, int resIdImages) { 614 615 if (resIdImages > 0) { 616 button.overrideImageIds(resIdImages); 617 } 618 button.overrideContentDescriptions(R.array.camera_flash_descriptions); 619 620 int index = mSettingsManager.getIndexOfCurrentValue(mAppController.getCameraScope(), 621 Keys.KEY_FLASH_MODE); 622 button.setState(index >= 0 ? index : 0, false); 623 624 button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() { 625 @Override 626 public void stateChanged(View view, int state) { 627 mSettingsManager.setValueByIndex(mAppController.getCameraScope(), 628 Keys.KEY_FLASH_MODE, state); 629 if (cb != null) { 630 cb.onStateChanged(state); 631 } 632 } 633 }); 634 } 635 636 /** 637 * Initialize video torch button 638 */ 639 private void initializeTorchButton(MultiToggleImageButton button, 640 final ButtonCallback cb, int resIdImages) { 641 642 if (resIdImages > 0) { 643 button.overrideImageIds(resIdImages); 644 } 645 button.overrideContentDescriptions(R.array.video_flash_descriptions); 646 647 int index = mSettingsManager.getIndexOfCurrentValue(mAppController.getCameraScope(), 648 Keys.KEY_VIDEOCAMERA_FLASH_MODE); 649 button.setState(index >= 0 ? index : 0, false); 650 651 button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() { 652 @Override 653 public void stateChanged(View view, int state) { 654 mSettingsManager.setValueByIndex(mAppController.getCameraScope(), 655 Keys.KEY_VIDEOCAMERA_FLASH_MODE, state); 656 if (cb != null) { 657 cb.onStateChanged(state); 658 } 659 } 660 }); 661 } 662 663 /** 664 * Initialize hdr plus flash button 665 */ 666 private void initializeHdrPlusFlashButton(MultiToggleImageButton button, 667 final ButtonCallback cb, int resIdImages) { 668 669 if (resIdImages > 0) { 670 button.overrideImageIds(resIdImages); 671 } 672 button.overrideContentDescriptions(R.array.hdr_plus_flash_descriptions); 673 674 int index = mSettingsManager.getIndexOfCurrentValue(mAppController.getModuleScope(), 675 Keys.KEY_HDR_PLUS_FLASH_MODE); 676 button.setState(index >= 0 ? index : 0, false); 677 678 button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() { 679 @Override 680 public void stateChanged(View view, int state) { 681 mSettingsManager.setValueByIndex(mAppController.getModuleScope(), 682 Keys.KEY_HDR_PLUS_FLASH_MODE, state); 683 if (cb != null) { 684 cb.onStateChanged(state); 685 } 686 } 687 }); 688 } 689 690 /** 691 * Initialize a camera button. 692 */ 693 private void initializeCameraButton(final MultiToggleImageButton button, 694 final ButtonCallback cb, int resIdImages) { 695 696 if (resIdImages > 0) { 697 button.overrideImageIds(resIdImages); 698 } 699 700 int index = mSettingsManager.getIndexOfCurrentValue(mAppController.getModuleScope(), 701 Keys.KEY_CAMERA_ID); 702 button.setState(index >= 0 ? index : 0, false); 703 704 button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() { 705 @Override 706 public void stateChanged(View view, int state) { 707 mSettingsManager.setValueByIndex(mAppController.getModuleScope(), 708 Keys.KEY_CAMERA_ID, state); 709 int cameraId = mSettingsManager.getInteger(mAppController.getModuleScope(), 710 Keys.KEY_CAMERA_ID); 711 // This is a quick fix for ISE in Gcam module which can be 712 // found by rapid pressing camera switch button. The assumption 713 // here is that each time this button is clicked, the listener 714 // will do something and then enable this button again. 715 button.setEnabled(false); 716 if (cb != null) { 717 cb.onStateChanged(cameraId); 718 } 719 mAppController.getCameraAppUI().onChangeCamera(); 720 } 721 }); 722 } 723 724 /** 725 * Initialize an hdr plus button. 726 */ 727 private void initializeHdrPlusButton(MultiToggleImageButton button, 728 final ButtonCallback cb, int resIdImages) { 729 730 initializeHdrPlusButtonIcons(button, resIdImages); 731 732 int index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL, 733 Keys.KEY_CAMERA_HDR_PLUS); 734 button.setState(index >= 0 ? index : 0, false); 735 736 button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() { 737 @Override 738 public void stateChanged(View view, int state) { 739 mSettingsManager.setValueByIndex(SettingsManager.SCOPE_GLOBAL, 740 Keys.KEY_CAMERA_HDR_PLUS, state); 741 if (cb != null) { 742 cb.onStateChanged(state); 743 } 744 } 745 }); 746 } 747 748 private void initializeHdrPlusButtonIcons(MultiToggleImageButton button, int resIdImages) { 749 if (resIdImages > 0) { 750 button.overrideImageIds(resIdImages); 751 } 752 button.overrideContentDescriptions(R.array.hdr_plus_descriptions); 753 } 754 755 /** 756 * Initialize an hdr button. 757 */ 758 private void initializeHdrButton(MultiToggleImageButton button, 759 final ButtonCallback cb, int resIdImages) { 760 761 initializeHdrButtonIcons(button, resIdImages); 762 763 int index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL, 764 Keys.KEY_CAMERA_HDR); 765 button.setState(index >= 0 ? index : 0, false); 766 767 button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() { 768 @Override 769 public void stateChanged(View view, int state) { 770 mSettingsManager.setValueByIndex(SettingsManager.SCOPE_GLOBAL, 771 Keys.KEY_CAMERA_HDR, state); 772 if (cb != null) { 773 cb.onStateChanged(state); 774 } 775 } 776 }); 777 } 778 779 private void initializeHdrButtonIcons(MultiToggleImageButton button, int resIdImages) { 780 if (resIdImages > 0) { 781 button.overrideImageIds(resIdImages); 782 } 783 button.overrideContentDescriptions(R.array.hdr_descriptions); 784 } 785 786 /** 787 * Initialize a countdown timer button. 788 */ 789 private void initializeCountdownButton(MultiToggleImageButton button, 790 final ButtonCallback cb, int resIdImages) { 791 if (resIdImages > 0) { 792 button.overrideImageIds(resIdImages); 793 } 794 795 int index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL, 796 Keys.KEY_COUNTDOWN_DURATION); 797 button.setState(index >= 0 ? index : 0, false); 798 799 button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() { 800 @Override 801 public void stateChanged(View view, int state) { 802 mSettingsManager.setValueByIndex(SettingsManager.SCOPE_GLOBAL, 803 Keys.KEY_COUNTDOWN_DURATION, state); 804 if(cb != null) { 805 cb.onStateChanged(state); 806 } 807 } 808 }); 809 } 810 811 /** 812 * Update the visual state of the manual exposure buttons 813 */ 814 public void updateExposureButtons() { 815 int compValue = mSettingsManager.getInteger(mAppController.getCameraScope(), 816 Keys.KEY_EXPOSURE); 817 if (mExposureCompensationStep != 0.0f) { 818 int comp = Math.round(compValue * mExposureCompensationStep); 819 mModeOptionsExposure.setSelectedOptionByTag(String.valueOf(comp)); 820 } 821 } 822 823 /** 824 * Initialize a grid lines button. 825 */ 826 private void initializeGridLinesButton(MultiToggleImageButton button, 827 final ButtonCallback cb, int resIdImages) { 828 829 if (resIdImages > 0) { 830 button.overrideImageIds(resIdImages); 831 } 832 button.overrideContentDescriptions(R.array.grid_lines_descriptions); 833 834 button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() { 835 @Override 836 public void stateChanged(View view, int state) { 837 mSettingsManager.setValueByIndex(SettingsManager.SCOPE_GLOBAL, 838 Keys.KEY_CAMERA_GRID_LINES, state); 839 if (cb != null) { 840 cb.onStateChanged(state); 841 } 842 } 843 }); 844 845 int index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL, 846 Keys.KEY_CAMERA_GRID_LINES); 847 button.setState(index >= 0 ? index : 0, true); 848 } 849 850 public boolean isPanoEnabled() { 851 return mModeOptions.getMainBar() == ModeOptions.BAR_PANO; 852 } 853 854 /** 855 * Initialize a panorama orientation buttons. 856 */ 857 public void initializePanoOrientationButtons(final ButtonCallback cb) { 858 int resIdImages = PhotoSphereHelper.getPanoramaOrientationOptionArrayId(); 859 int resIdDescriptions = PhotoSphereHelper.getPanoramaOrientationDescriptions(); 860 if (resIdImages > 0) { 861 TypedArray imageIds = null; 862 TypedArray descriptionIds = null; 863 try { 864 mModeOptions.setMainBar(ModeOptions.BAR_PANO); 865 imageIds = mAppController 866 .getAndroidContext().getResources().obtainTypedArray(resIdImages); 867 descriptionIds = mAppController 868 .getAndroidContext().getResources().obtainTypedArray(resIdDescriptions); 869 mModeOptionsPano.removeAllViews(); 870 final boolean isHorizontal = 871 (mModeOptionsPano.getOrientation() == LinearLayout.HORIZONTAL); 872 final int numImageIds = imageIds.length(); 873 for (int index = 0; index < numImageIds; index++) { 874 int i; 875 // if in portrait orientation (pano bar horizonal), order buttons normally 876 // if in landscape orientation (pano bar vertical), reverse button order 877 if (isHorizontal) { 878 i = index; 879 } else { 880 i = numImageIds - index - 1; 881 } 882 883 int imageId = imageIds.getResourceId(i, 0); 884 if (imageId > 0) { 885 ImageButton imageButton = (ImageButton) LayoutInflater 886 .from(mAppController.getAndroidContext()) 887 .inflate(R.layout.mode_options_imagebutton_template, 888 mModeOptionsPano, false); 889 imageButton.setImageResource(imageId); 890 imageButton.setTag(String.valueOf(i)); 891 mModeOptionsPano.addView(imageButton); 892 893 int descriptionId = descriptionIds.getResourceId(i, 0); 894 if (descriptionId > 0) { 895 imageButton.setContentDescription( 896 mAppController.getAndroidContext().getString(descriptionId)); 897 } 898 } 899 } 900 mModeOptionsPano.updateListeners(); 901 mModeOptionsPano 902 .setOnOptionClickListener(new RadioOptions.OnOptionClickListener() { 903 @Override 904 public void onOptionClicked(View v) { 905 if (cb != null) { 906 int state = Integer.parseInt((String)v.getTag()); 907 mSettingsManager.setValueByIndex(SettingsManager.SCOPE_GLOBAL, 908 Keys.KEY_CAMERA_PANO_ORIENTATION, 909 state); 910 cb.onStateChanged(state); 911 } 912 } 913 }); 914 updatePanoButtons(); 915 } finally { 916 if (imageIds != null) { 917 imageIds.recycle(); 918 } 919 if (descriptionIds != null) { 920 descriptionIds.recycle(); 921 } 922 } 923 } 924 } 925 926 private void updatePanoButtons() { 927 int modeIndex = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL, 928 Keys.KEY_CAMERA_PANO_ORIENTATION); 929 mModeOptionsPano.setSelectedOptionByTag(String.valueOf(modeIndex)); 930 } 931} 932