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