118e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren/*
218e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren * Copyright (C) 2013 The Android Open Source Project
318e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren *
418e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren * Licensed under the Apache License, Version 2.0 (the "License");
518e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren * you may not use this file except in compliance with the License.
618e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren * You may obtain a copy of the License at
718e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren *
818e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren *      http://www.apache.org/licenses/LICENSE-2.0
918e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren *
1018e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren * Unless required by applicable law or agreed to in writing, software
1118e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren * distributed under the License is distributed on an "AS IS" BASIS,
1218e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1318e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren * See the License for the specific language governing permissions and
1418e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren * limitations under the License.
1518e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren */
1618e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren
1718e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgrenpackage com.android.camera;
1818e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren
190a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgrenimport android.content.Context;
2059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Spragueimport android.content.res.TypedArray;
2159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Spragueimport android.view.LayoutInflater;
2218e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgrenimport android.view.View;
2318e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgrenimport android.widget.ImageButton;
24e541dc2d520aae8d45f3c605c3d732e33dd3b616Spike Spragueimport android.widget.LinearLayout;
2518e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren
260a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgrenimport com.android.camera.app.AppController;
27abf54e2994961395a0feb0b08353e62718443f23Spike Spragueimport com.android.camera.app.CameraAppUI;
286190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgrenimport com.android.camera.settings.Keys;
2918e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgrenimport com.android.camera.settings.SettingsManager;
3059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Spragueimport com.android.camera.ui.RadioOptions;
31f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgrenimport com.android.camera.util.PhotoSphereHelper;
3259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Spragueimport com.android.camera.widget.ModeOptions;
331648c36927501ff32bf2918e8a445118d5208731Erin Dahlgrenimport com.android.camera2.R;
341648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren
3518e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren/**
3618e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren * A  class for generating pre-initialized
3718e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren * {@link #android.widget.ImageButton}s.
3818e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren */
391648c36927501ff32bf2918e8a445118d5208731Erin Dahlgrenpublic class ButtonManager implements SettingsManager.OnSettingChangedListener {
4018e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren    public static final int BUTTON_FLASH = 0;
410f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague    public static final int BUTTON_TORCH = 1;
42b4dd5659a53c625a611080db0d41f52f2b421354Sam Hasinoff    public static final int BUTTON_HDR_PLUS_FLASH = 2;
4315473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren    public static final int BUTTON_CAMERA = 3;
4415473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren    public static final int BUTTON_HDR_PLUS = 4;
4515473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren    public static final int BUTTON_HDR = 5;
46b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren    public static final int BUTTON_CANCEL = 6;
47b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren    public static final int BUTTON_DONE = 7;
48b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren    public static final int BUTTON_RETAKE = 8;
49b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren    public static final int BUTTON_REVIEW = 9;
5015473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren    public static final int BUTTON_GRID_LINES = 10;
5115473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren    public static final int BUTTON_EXPOSURE_COMPENSATION = 11;
5215473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren    public static final int BUTTON_COUNTDOWN = 12;
534efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren
541848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    /** For two state MultiToggleImageButtons, the off index. */
554efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren    public static final int OFF = 0;
561848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    /** For two state MultiToggleImageButtons, the on index. */
574efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren    public static final int ON = 1;
5818e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren
59c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague    private static final int NO_RESOURCE = -1;
60c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague
6118e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren    /** A reference to the application's settings manager. */
6258598dc16e1f5a747fe1407ec1641a5529f423e5Sascha Haeberling    private final SettingsManager mSettingsManager;
6318e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren
64a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren    /** Bottom bar options toggle buttons. */
65a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren    private MultiToggleImageButton mButtonCamera;
66a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren    private MultiToggleImageButton mButtonFlash;
67a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren    private MultiToggleImageButton mButtonHdr;
68a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren    private MultiToggleImageButton mButtonGridlines;
696c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu    private MultiToggleImageButton mButtonCountdown;
701848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren
711848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    /** Intent UI buttons. */
721848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    private ImageButton mButtonCancel;
731848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    private ImageButton mButtonDone;
741848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    private ImageButton mButtonRetake; // same as review.
751848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren
76abf54e2994961395a0feb0b08353e62718443f23Spike Sprague    private ImageButton mButtonExposureCompensation;
77abf54e2994961395a0feb0b08353e62718443f23Spike Sprague    private ImageButton mExposureN2;
78abf54e2994961395a0feb0b08353e62718443f23Spike Sprague    private ImageButton mExposureN1;
79abf54e2994961395a0feb0b08353e62718443f23Spike Sprague    private ImageButton mExposure0;
80abf54e2994961395a0feb0b08353e62718443f23Spike Sprague    private ImageButton mExposureP1;
81abf54e2994961395a0feb0b08353e62718443f23Spike Sprague    private ImageButton mExposureP2;
8259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    private RadioOptions mModeOptionsExposure;
8359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    private RadioOptions mModeOptionsPano;
8459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    private View mModeOptionsButtons;
8559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    private ModeOptions mModeOptions;
86abf54e2994961395a0feb0b08353e62718443f23Spike Sprague
87a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague    private int mMinExposureCompensation;
88a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague    private int mMaxExposureCompensation;
89a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague    private float mExposureCompensationStep;
90a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague
911848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    /** A listener for button enabled and visibility
921848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        state changes. */
931848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    private ButtonStatusListener mListener;
941848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren
950a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren    /** An reference to the gcam mode index. */
960a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren    private static int sGcamIndex;
970a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren
98ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava    /** Whether Camera Button can be enabled by generic operations. */
99ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava    private boolean mIsCameraButtonBlocked;
100ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava
1016190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren    private final AppController mAppController;
1026b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague
1038a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren    /**
1048a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren     * Get a new global ButtonManager.
1058a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren     */
1060a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren    public ButtonManager(AppController app) {
1070a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren        mAppController = app;
1080a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren
1090a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren        Context context = app.getAndroidContext();
1100a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren        sGcamIndex = context.getResources().getInteger(R.integer.camera_mode_gcam);
1110a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren
1120a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren        mSettingsManager = app.getSettingsManager();
1131648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren        mSettingsManager.addListener(this);
1141648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren    }
1151648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren
1161848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    /**
117f1b2e407b20ff16fe793158c598e59799c1990efErin Dahlgren     * Load references to buttons under a root View.
118f1b2e407b20ff16fe793158c598e59799c1990efErin Dahlgren     * Call this after the root clears/reloads all of its children
119f1b2e407b20ff16fe793158c598e59799c1990efErin Dahlgren     * to prevent stale references button views.
120f1b2e407b20ff16fe793158c598e59799c1990efErin Dahlgren     */
121f1b2e407b20ff16fe793158c598e59799c1990efErin Dahlgren    public void load(View root) {
122f1b2e407b20ff16fe793158c598e59799c1990efErin Dahlgren        getButtonsReferences(root);
123f1b2e407b20ff16fe793158c598e59799c1990efErin Dahlgren    }
124f1b2e407b20ff16fe793158c598e59799c1990efErin Dahlgren
125f1b2e407b20ff16fe793158c598e59799c1990efErin Dahlgren    /**
1261848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     * ButtonStatusListener provides callbacks for when button's
1271848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     * visibility changes and enabled status changes.
1281848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     */
1291848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    public interface ButtonStatusListener {
1301848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        /**
1311848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren         * A button's visibility has changed.
1321848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren         */
1331848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        public void onButtonVisibilityChanged(ButtonManager buttonManager, int buttonId);
1341848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren
1351848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        /**
1361848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren         * A button's enabled state has changed.
1371848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren         */
1381848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        public void onButtonEnabledChanged(ButtonManager buttonManager, int buttonId);
1391848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    }
1401848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren
1411848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    /**
1421848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     * Sets the ButtonStatusListener.
1431848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     */
1441848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    public void setListener(ButtonStatusListener listener) {
1451848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        mListener = listener;
1461848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    }
1471848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren
1481848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    /**
1491848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     * Gets references to all known buttons.
1501848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     */
1510a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren    private void getButtonsReferences(View root) {
152a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren        mButtonCamera
1530a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren            = (MultiToggleImageButton) root.findViewById(R.id.camera_toggle_button);
154a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren        mButtonFlash
155a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren            = (MultiToggleImageButton) root.findViewById(R.id.flash_toggle_button);
156a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren        mButtonHdr
1570a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren            = (MultiToggleImageButton) root.findViewById(R.id.hdr_plus_toggle_button);
158a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren        mButtonGridlines
159d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren            = (MultiToggleImageButton) root.findViewById(R.id.grid_lines_toggle_button);
1601848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        mButtonCancel
1610a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren            = (ImageButton) root.findViewById(R.id.cancel_button);
1621848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        mButtonDone
1630a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren            = (ImageButton) root.findViewById(R.id.done_button);
1641848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        mButtonRetake
1650a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren            = (ImageButton) root.findViewById(R.id.retake_button);
166abf54e2994961395a0feb0b08353e62718443f23Spike Sprague
167abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        mButtonExposureCompensation =
168abf54e2994961395a0feb0b08353e62718443f23Spike Sprague            (ImageButton) root.findViewById(R.id.exposure_button);
169abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        mExposureN2 = (ImageButton) root.findViewById(R.id.exposure_n2);
170abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        mExposureN1 = (ImageButton) root.findViewById(R.id.exposure_n1);
171abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        mExposure0 = (ImageButton) root.findViewById(R.id.exposure_0);
172abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        mExposureP1 = (ImageButton) root.findViewById(R.id.exposure_p1);
173abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        mExposureP2 = (ImageButton) root.findViewById(R.id.exposure_p2);
17459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        mModeOptionsExposure = (RadioOptions) root.findViewById(R.id.mode_options_exposure);
17559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        mModeOptionsPano = (RadioOptions) root.findViewById(R.id.mode_options_pano);
17659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        mModeOptionsButtons = root.findViewById(R.id.mode_options_buttons);
17759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        mModeOptions = (ModeOptions) root.findViewById(R.id.mode_options);
1786c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu
1796c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu        mButtonCountdown = (MultiToggleImageButton) root.findViewById(R.id.countdown_toggle_button);
1801848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    }
1811648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren
1821648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren    @Override
1836190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren    public void onSettingChanged(SettingsManager settingsManager, String key) {
1841648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren        MultiToggleImageButton button = null;
1851648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren        int index = 0;
1861648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren
1876190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        if (key.equals(Keys.KEY_FLASH_MODE)) {
1886190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            index = mSettingsManager.getIndexOfCurrentValue(mAppController.getCameraScope(),
1896190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                            Keys.KEY_FLASH_MODE);
1906190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            button = getButtonOrError(BUTTON_FLASH);
1916190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        } else if (key.equals(Keys.KEY_VIDEOCAMERA_FLASH_MODE)) {
1926190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            index = mSettingsManager.getIndexOfCurrentValue(mAppController.getCameraScope(),
1936190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                            Keys.KEY_VIDEOCAMERA_FLASH_MODE);
1946190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            button = getButtonOrError(BUTTON_TORCH);
1956190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        } else if (key.equals(Keys.KEY_HDR_PLUS_FLASH_MODE)) {
1966190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            index = mSettingsManager.getIndexOfCurrentValue(mAppController.getModuleScope(),
1976190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                            Keys.KEY_HDR_PLUS_FLASH_MODE);
1986190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            button = getButtonOrError(BUTTON_HDR_PLUS_FLASH);
1996190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        } else if (key.equals(Keys.KEY_CAMERA_ID)) {
2006190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            index = mSettingsManager.getIndexOfCurrentValue(mAppController.getModuleScope(),
2016190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                            Keys.KEY_CAMERA_ID);
2026190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            button = getButtonOrError(BUTTON_CAMERA);
2036190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        } else if (key.equals(Keys.KEY_CAMERA_HDR_PLUS)) {
2046190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL,
2056190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                            Keys.KEY_CAMERA_HDR_PLUS);
2066190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            button = getButtonOrError(BUTTON_HDR_PLUS);
2076190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        } else if (key.equals(Keys.KEY_CAMERA_HDR)) {
2086190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL,
2096190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                            Keys.KEY_CAMERA_HDR);
2106190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            button = getButtonOrError(BUTTON_HDR);
2116190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        } else if (key.equals(Keys.KEY_CAMERA_GRID_LINES)) {
2126190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL,
2136190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                            Keys.KEY_CAMERA_GRID_LINES);
2146190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            button = getButtonOrError(BUTTON_GRID_LINES);
2156190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        } else if (key.equals(Keys.KEY_CAMERA_PANO_ORIENTATION)) {
2166190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            updatePanoButtons();
2176190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        } else if (key.equals(Keys.KEY_EXPOSURE)) {
2186190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            updateExposureButtons();
2196190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        } else if (key.equals(Keys.KEY_COUNTDOWN_DURATION)) {
2206190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL,
2216190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                            Keys.KEY_COUNTDOWN_DURATION);
2226190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren            button = getButtonOrError(BUTTON_COUNTDOWN);
2231648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren        }
2241648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren
2251648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren        if (button != null && button.getState() != index) {
2261648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren            button.setState(Math.max(index, 0), false);
2271648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren        }
22818e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren    }
22918e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren
23018e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren    /**
23118e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren     * A callback executed in the state listener of a button.
23215473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren     *
2338a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren     * Used by a module to set specific behavior when a button's
23418e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren     * state changes.
23518e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren     */
23618e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren    public interface ButtonCallback {
23718e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren        public void onStateChanged(int state);
23818e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren    }
23918e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren
2401848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    /**
2411848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     * Returns the appropriate {@link com.android.camera.MultiToggleImageButton}
2421848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     * based on button id.  An IllegalStateException will be throw if the
2431848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     * button could not be found in the view hierarchy.
2441848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     */
2451848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    private MultiToggleImageButton getButtonOrError(int buttonId) {
2461848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        switch (buttonId) {
2471848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            case BUTTON_FLASH:
248a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren                if (mButtonFlash == null) {
2498a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren                    throw new IllegalStateException("Flash button could not be found.");
2501848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                }
251a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren                return mButtonFlash;
2521848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            case BUTTON_TORCH:
25315473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren                if (mButtonFlash == null) {
2540f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague                    throw new IllegalStateException("Torch button could not be found.");
2551848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                }
256a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren                return mButtonFlash;
257b4dd5659a53c625a611080db0d41f52f2b421354Sam Hasinoff            case BUTTON_HDR_PLUS_FLASH:
25815473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren                if (mButtonFlash == null) {
25915473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren                    throw new IllegalStateException("Hdr plus torch button could not be found.");
26015473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren                }
26115473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren                return mButtonFlash;
2621848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            case BUTTON_CAMERA:
263a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren                if (mButtonCamera == null) {
2648a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren                    throw new IllegalStateException("Camera button could not be found.");
2651848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                }
266a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren                return mButtonCamera;
26715473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren            case BUTTON_HDR_PLUS:
268a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren                if (mButtonHdr == null) {
269a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren                    throw new IllegalStateException("Hdr plus button could not be found.");
2701848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                }
271a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren                return mButtonHdr;
272b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren            case BUTTON_HDR:
273a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren                if (mButtonHdr == null) {
274b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren                    throw new IllegalStateException("Hdr button could not be found.");
275b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren                }
276a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren                return mButtonHdr;
277d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren            case BUTTON_GRID_LINES:
278a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren                if (mButtonGridlines == null) {
279d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren                    throw new IllegalStateException("Grid lines button could not be found.");
280d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren                }
281a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren                return mButtonGridlines;
2826c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu            case BUTTON_COUNTDOWN:
2836c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu                if (mButtonCountdown == null) {
2846c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu                    throw new IllegalStateException("Countdown button could not be found.");
2856c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu                }
2866c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu                return mButtonCountdown;
2871848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            default:
2881848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                throw new IllegalArgumentException("button not known by id=" + buttonId);
2898a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren        }
2908a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren    }
29118e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren
2921848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    /**
2931848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     * Returns the appropriate {@link android.widget.ImageButton}
2941848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     * based on button id.  An IllegalStateException will be throw if the
2951848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     * button could not be found in the view hierarchy.
2961848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     */
2971848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    private ImageButton getImageButtonOrError(int buttonId) {
2981848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        switch (buttonId) {
2991848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            case BUTTON_CANCEL:
3001848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                if (mButtonCancel == null) {
301eb3134f6ecc42f7d98625ca2c0ddfb06c9f07c43Spike Sprague                    throw new IllegalStateException("Cancel button could not be found.");
3021848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                }
3031848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                return mButtonCancel;
3041848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            case BUTTON_DONE:
3051848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                if (mButtonDone == null) {
306eb3134f6ecc42f7d98625ca2c0ddfb06c9f07c43Spike Sprague                    throw new IllegalStateException("Done button could not be found.");
3071848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                }
3081848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                return mButtonDone;
3091848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            case BUTTON_RETAKE:
3101848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                if (mButtonRetake == null) {
311eb3134f6ecc42f7d98625ca2c0ddfb06c9f07c43Spike Sprague                    throw new IllegalStateException("Retake button could not be found.");
3121848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                }
3131848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                return mButtonRetake;
3141848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            case BUTTON_REVIEW:
3151848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                if (mButtonRetake == null) {
316db44ef57cdb576704b1aafb2b81e30bf9ff261adSpike Sprague                    throw new IllegalStateException("Review button could not be found.");
3171848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                }
3181848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                return mButtonRetake;
319abf54e2994961395a0feb0b08353e62718443f23Spike Sprague            case BUTTON_EXPOSURE_COMPENSATION:
320abf54e2994961395a0feb0b08353e62718443f23Spike Sprague                if (mButtonExposureCompensation == null) {
321abf54e2994961395a0feb0b08353e62718443f23Spike Sprague                    throw new IllegalStateException("Exposure Compensation button could not be found.");
322abf54e2994961395a0feb0b08353e62718443f23Spike Sprague                }
323abf54e2994961395a0feb0b08353e62718443f23Spike Sprague                return mButtonExposureCompensation;
3241848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            default:
3251848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                throw new IllegalArgumentException("button not known by id=" + buttonId);
326eb3134f6ecc42f7d98625ca2c0ddfb06c9f07c43Spike Sprague        }
327eb3134f6ecc42f7d98625ca2c0ddfb06c9f07c43Spike Sprague    }
328eb3134f6ecc42f7d98625ca2c0ddfb06c9f07c43Spike Sprague
32918e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren    /**
3309a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava     * Initialize a known button by id with a state change callback, and then
3319a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava     * enable the button.
3329a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava     *
3339a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava     * @param buttonId The id if the button to be initialized.
3349a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava     * @param cb The callback to be executed after the button state change.
33518e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren     */
3368ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu    public void initializeButton(int buttonId, ButtonCallback cb) {
3379a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava        initializeButton(buttonId, cb, null);
3389a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava    }
3399a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava
3409a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava    /**
3419a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava     * Initialize a known button by id, with a state change callback and a state
3429a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava     * pre-change callback, and then enable the button.
3439a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava     *
3449a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava     * @param buttonId The id if the button to be initialized.
3459a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava     * @param cb The callback to be executed after the button state change.
3469a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava     * @param preCb The callback to be executed before the button state change.
3479a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava     */
3489a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava    public void initializeButton(int buttonId, ButtonCallback cb, ButtonCallback preCb) {
3491848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        MultiToggleImageButton button = getButtonOrError(buttonId);
3508a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren        switch (buttonId) {
35118e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren            case BUTTON_FLASH:
3529a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava                initializeFlashButton(button, cb, preCb, R.array.camera_flashmode_icons);
3538a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren                break;
3541848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            case BUTTON_TORCH:
3559a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava                initializeTorchButton(button, cb, preCb, R.array.video_flashmode_icons);
3561848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                break;
357b4dd5659a53c625a611080db0d41f52f2b421354Sam Hasinoff            case BUTTON_HDR_PLUS_FLASH:
3589a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava                initializeHdrPlusFlashButton(button, cb, preCb, R.array.camera_flashmode_icons);
35915473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren                break;
36018e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren            case BUTTON_CAMERA:
3619a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava                initializeCameraButton(button, cb, preCb, R.array.camera_id_icons);
3628a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren                break;
36315473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren            case BUTTON_HDR_PLUS:
3649a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava                initializeHdrPlusButton(button, cb, preCb, R.array.pref_camera_hdr_plus_icons);
365b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren                break;
366b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren            case BUTTON_HDR:
3679a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava                initializeHdrButton(button, cb, preCb, R.array.pref_camera_hdr_icons);
3688a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren                break;
369d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren            case BUTTON_GRID_LINES:
3709a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava                initializeGridLinesButton(button, cb, preCb, R.array.grid_lines_icons);
371d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren                break;
3726c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu            case BUTTON_COUNTDOWN:
3739a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava                initializeCountdownButton(button, cb, preCb, R.array.countdown_duration_icons);
3746c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu                break;
37518e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren            default:
3768a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren                throw new IllegalArgumentException("button not known by id=" + buttonId);
37718e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren        }
3781848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren
379e29804fdace7b653932314407a5bdcf58569e590Alan Newberger        showButton(buttonId);
3808ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu        enableButton(buttonId);
38118e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren    }
38218e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren
3834efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren    /**
384c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague     * Initialize a known button with a click listener and a drawable resource id,
385c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague     * and a content description resource id.
3864efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren     * Sets the button visible.
3874efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren     */
3888ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu    public void initializePushButton(int buttonId, View.OnClickListener cb,
389c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague            int imageId, int contentDescriptionId) {
3901848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        ImageButton button = getImageButtonOrError(buttonId);
3914efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren        button.setOnClickListener(cb);
392c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague        if (imageId != NO_RESOURCE) {
393c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague            button.setImageResource(imageId);
394c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague        }
395c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague        if (contentDescriptionId != NO_RESOURCE) {
396c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague            button.setContentDescription(mAppController
397c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague                    .getAndroidContext().getResources().getString(contentDescriptionId));
398c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague        }
3991848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren
4001848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        if (!button.isEnabled()) {
4011848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            button.setEnabled(true);
4021848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            if (mListener != null) {
4031848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                mListener.onButtonEnabledChanged(this, buttonId);
4041848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            }
4051848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        }
40666d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague        button.setTag(R.string.tag_enabled_id, buttonId);
407a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren
408a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        if (button.getVisibility() != View.VISIBLE) {
409a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren            button.setVisibility(View.VISIBLE);
410a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren            if (mListener != null) {
411a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren                mListener.onButtonVisibilityChanged(this, buttonId);
412a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren            }
413a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        }
4144efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren    }
4154efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren
4164efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren    /**
417c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague     * Initialize a known button with a click listener and a resource id.
418c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague     * Sets the button visible.
419c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague     */
420c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague    public void initializePushButton(int buttonId, View.OnClickListener cb,
421c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague            int imageId) {
422c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague        initializePushButton(buttonId, cb, imageId, NO_RESOURCE);
423c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague    }
424c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague
425c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague    /**
4268ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu     * Initialize a known button with a click listener. Sets the button visible.
4274efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren     */
4288ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu    public void initializePushButton(int buttonId, View.OnClickListener cb) {
429c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague        initializePushButton(buttonId, cb, NO_RESOURCE, NO_RESOURCE);
430eb3134f6ecc42f7d98625ca2c0ddfb06c9f07c43Spike Sprague    }
431eb3134f6ecc42f7d98625ca2c0ddfb06c9f07c43Spike Sprague
43218e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren    /**
433ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava     * Sets the camera button in its disabled (greyed out) state and blocks it
434ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava     * so no generic operation can enable it until it's explicitly re-enabled by
435ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava     * calling {@link #enableCameraButton()}.
436ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava     */
437ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava    public void disableCameraButtonAndBlock() {
438ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava        mIsCameraButtonBlocked = true;
439ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava        disableButton(BUTTON_CAMERA);
440ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava    }
441ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava
442ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava    /**
4434efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren     * Sets a button in its disabled (greyed out) state.
44418e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren     */
4451848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    public void disableButton(int buttonId) {
4460409c8594fd1629ee07df827cf0d7a0f336b9326zafir        View button;
4470409c8594fd1629ee07df827cf0d7a0f336b9326zafir        if (buttonId == BUTTON_EXPOSURE_COMPENSATION) {
4480409c8594fd1629ee07df827cf0d7a0f336b9326zafir            button = getImageButtonOrError(buttonId);
4490409c8594fd1629ee07df827cf0d7a0f336b9326zafir        } else {
4500409c8594fd1629ee07df827cf0d7a0f336b9326zafir            button = getButtonOrError(buttonId);
4510409c8594fd1629ee07df827cf0d7a0f336b9326zafir        }
452f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        // HDR and HDR+ buttons share the same button object,
453f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        // but change actual image icons at runtime.
454f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        // This extra check is to ensure the correct icons are used
455f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        // in the case of the HDR[+] button being disabled at startup,
456f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        // e.g. app startup with front-facing camera.
457f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        // b/18104680
458f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        if (buttonId == BUTTON_HDR_PLUS) {
4590409c8594fd1629ee07df827cf0d7a0f336b9326zafir            initializeHdrPlusButtonIcons((MultiToggleImageButton) button, R.array.pref_camera_hdr_plus_icons);
460f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        } else if (buttonId == BUTTON_HDR) {
4610409c8594fd1629ee07df827cf0d7a0f336b9326zafir            initializeHdrButtonIcons((MultiToggleImageButton) button, R.array.pref_camera_hdr_icons);
462f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        }
463f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague
4641848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        if (button.isEnabled()) {
4651848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            button.setEnabled(false);
4661848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            if (mListener != null) {
4671848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                mListener.onButtonEnabledChanged(this, buttonId);
4681848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            }
4691848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        }
470a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        button.setTag(R.string.tag_enabled_id, null);
4714efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren    }
4724efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren
4734efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren    /**
474ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava     * Enables the camera button and removes the block that was set by
475ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava     * {@link #disableCameraButtonAndBlock()}.
476ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava     */
477ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava    public void enableCameraButton() {
478ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava        mIsCameraButtonBlocked = false;
479ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava        enableButton(BUTTON_CAMERA);
480ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava    }
481ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava
482ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava    /**
4838ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu     * Enables a button that has already been initialized.
4848ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu     */
4858ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu    public void enableButton(int buttonId) {
486ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava        // If Camera Button is blocked, ignore the request.
487ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava        if(buttonId == BUTTON_CAMERA && mIsCameraButtonBlocked) {
488ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava            return;
489ca434e5414ae721e577da44c279a7fad9f43ca2aGabriel Nava        }
4900409c8594fd1629ee07df827cf0d7a0f336b9326zafir        ImageButton button;
4910409c8594fd1629ee07df827cf0d7a0f336b9326zafir        // Manual exposure uses a regular image button instead of a
4920409c8594fd1629ee07df827cf0d7a0f336b9326zafir        // MultiToggleImageButton, so it requires special handling.
4930409c8594fd1629ee07df827cf0d7a0f336b9326zafir        // TODO: Redesign ButtonManager's button getter methods into one method.
4940409c8594fd1629ee07df827cf0d7a0f336b9326zafir        if (buttonId == BUTTON_EXPOSURE_COMPENSATION) {
4950409c8594fd1629ee07df827cf0d7a0f336b9326zafir            button = getImageButtonOrError(buttonId);
4960409c8594fd1629ee07df827cf0d7a0f336b9326zafir        } else {
4970409c8594fd1629ee07df827cf0d7a0f336b9326zafir            button = getButtonOrError(buttonId);
4980409c8594fd1629ee07df827cf0d7a0f336b9326zafir        }
4998ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu        if (!button.isEnabled()) {
5008ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu            button.setEnabled(true);
5018ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu            if (mListener != null) {
5028ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu                mListener.onButtonEnabledChanged(this, buttonId);
5038ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu            }
5048ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu        }
5058ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu        button.setTag(R.string.tag_enabled_id, buttonId);
5068ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu    }
5078ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu
5088ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu    /**
50966d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague     * Disable click reactions for a button without affecting visual state.
51066d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague     * For most cases you'll want to use {@link #disableButton(int)}.
51166d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague     * @param buttonId The id of the button.
51266d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague     */
51366d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague    public void disableButtonClick(int buttonId) {
51466d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague        ImageButton button = getButtonOrError(buttonId);
51566d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague        if (button instanceof MultiToggleImageButton) {
51666d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague            ((MultiToggleImageButton) button).setClickEnabled(false);
51766d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague        }
51866d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague    }
51966d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague
52066d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague    /**
52166d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague     * Enable click reactions for a button without affecting visual state.
52266d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague     * For most cases you'll want to use {@link #enableButton(int)}.
52366d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague     * @param buttonId The id of the button.
52466d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague     */
52566d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague    public void enableButtonClick(int buttonId) {
52666d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague        ImageButton button = getButtonOrError(buttonId);
52766d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague        if (button instanceof MultiToggleImageButton) {
52866d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague            ((MultiToggleImageButton) button).setClickEnabled(true);
52966d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague        }
53066d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague    }
53166d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague
53266d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague    /**
5334efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren     * Hide a button by id.
5344efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren     */
5351848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    public void hideButton(int buttonId) {
536a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        View button;
537a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        try {
53866d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague            button = getButtonOrError(buttonId);
539a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        } catch (IllegalArgumentException e) {
54066d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague            button = getImageButtonOrError(buttonId);
541a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        }
5421848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        if (button.getVisibility() == View.VISIBLE) {
543c0ad2fbb43002cf013989489dc0321f459baf84cErin Dahlgren            button.setVisibility(View.GONE);
5441848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            if (mListener != null) {
5451848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren                mListener.onButtonVisibilityChanged(this, buttonId);
5461848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren            }
5471848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        }
5481848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    }
5491848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren
550e29804fdace7b653932314407a5bdcf58569e590Alan Newberger    /**
551e29804fdace7b653932314407a5bdcf58569e590Alan Newberger     * Show a button by id.
552e29804fdace7b653932314407a5bdcf58569e590Alan Newberger     */
553e29804fdace7b653932314407a5bdcf58569e590Alan Newberger    public void showButton(int buttonId) {
554e29804fdace7b653932314407a5bdcf58569e590Alan Newberger        View button;
555e29804fdace7b653932314407a5bdcf58569e590Alan Newberger        try {
556e29804fdace7b653932314407a5bdcf58569e590Alan Newberger            button = getButtonOrError(buttonId);
557e29804fdace7b653932314407a5bdcf58569e590Alan Newberger        } catch (IllegalArgumentException e) {
558e29804fdace7b653932314407a5bdcf58569e590Alan Newberger            button = getImageButtonOrError(buttonId);
559e29804fdace7b653932314407a5bdcf58569e590Alan Newberger        }
560e29804fdace7b653932314407a5bdcf58569e590Alan Newberger        if (button.getVisibility() != View.VISIBLE) {
561e29804fdace7b653932314407a5bdcf58569e590Alan Newberger            button.setVisibility(View.VISIBLE);
562e29804fdace7b653932314407a5bdcf58569e590Alan Newberger            if (mListener != null) {
563e29804fdace7b653932314407a5bdcf58569e590Alan Newberger                mListener.onButtonVisibilityChanged(this, buttonId);
564e29804fdace7b653932314407a5bdcf58569e590Alan Newberger            }
565e29804fdace7b653932314407a5bdcf58569e590Alan Newberger        }
566e29804fdace7b653932314407a5bdcf58569e590Alan Newberger    }
567e29804fdace7b653932314407a5bdcf58569e590Alan Newberger
568e29804fdace7b653932314407a5bdcf58569e590Alan Newberger
56959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    public void setToInitialState() {
57059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        mModeOptions.setMainBar(ModeOptions.BAR_STANDARD);
57159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    }
57259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague
573abf54e2994961395a0feb0b08353e62718443f23Spike Sprague    public void setExposureCompensationCallback(final CameraAppUI.BottomBarUISpec
574abf54e2994961395a0feb0b08353e62718443f23Spike Sprague                                        .ExposureCompensationSetCallback cb) {
575abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        if (cb == null) {
57659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            mModeOptionsExposure.setOnOptionClickListener(null);
577abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        } else {
57859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            mModeOptionsExposure
57959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                .setOnOptionClickListener(new RadioOptions.OnOptionClickListener() {
58059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    @Override
58159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    public void onOptionClicked(View v) {
58259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        int comp = Integer.parseInt((String)(v.getTag()));
58359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague
58459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        if (mExposureCompensationStep != 0.0f) {
58559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                            int compValue =
58659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                                Math.round(comp / mExposureCompensationStep);
58759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                            cb.setExposure(compValue);
58859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        }
589abf54e2994961395a0feb0b08353e62718443f23Spike Sprague                    }
59059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                });
591abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        }
592abf54e2994961395a0feb0b08353e62718443f23Spike Sprague    }
593abf54e2994961395a0feb0b08353e62718443f23Spike Sprague
5941848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    /**
595a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague     * Set the exposure compensation parameters supported by the current camera mode.
596a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague     * @param min Minimum exposure compensation value.
597a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague     * @param max Maximum exposure compensation value.
598a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague     * @param step Expsoure compensation step value.
599a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague     */
600a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague    public void setExposureCompensationParameters(int min, int max, float step) {
601a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague        mMaxExposureCompensation = max;
602a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague        mMinExposureCompensation = min;
603a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague        mExposureCompensationStep = step;
604a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague
605156f3e5b41cd2049230b1423c455763d31738693Spike Sprague
606156f3e5b41cd2049230b1423c455763d31738693Spike Sprague        setVisible(mExposureN2, (Math.round(min * step) <= -2));
607156f3e5b41cd2049230b1423c455763d31738693Spike Sprague        setVisible(mExposureN1, (Math.round(min * step) <= -1));
608156f3e5b41cd2049230b1423c455763d31738693Spike Sprague        setVisible(mExposureP1, (Math.round(max * step) >= 1));
609156f3e5b41cd2049230b1423c455763d31738693Spike Sprague        setVisible(mExposureP2, (Math.round(max * step) >= 2));
610a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague
611a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague        updateExposureButtons();
612156f3e5b41cd2049230b1423c455763d31738693Spike Sprague    }
613156f3e5b41cd2049230b1423c455763d31738693Spike Sprague
614156f3e5b41cd2049230b1423c455763d31738693Spike Sprague    private static void setVisible(View v, boolean visible) {
615156f3e5b41cd2049230b1423c455763d31738693Spike Sprague        if (visible) {
616156f3e5b41cd2049230b1423c455763d31738693Spike Sprague            v.setVisibility(View.VISIBLE);
617156f3e5b41cd2049230b1423c455763d31738693Spike Sprague        } else {
618156f3e5b41cd2049230b1423c455763d31738693Spike Sprague            v.setVisibility(View.INVISIBLE);
619156f3e5b41cd2049230b1423c455763d31738693Spike Sprague        }
620156f3e5b41cd2049230b1423c455763d31738693Spike Sprague    }
621156f3e5b41cd2049230b1423c455763d31738693Spike Sprague
622156f3e5b41cd2049230b1423c455763d31738693Spike Sprague    /**
623156f3e5b41cd2049230b1423c455763d31738693Spike Sprague     * @return The exposure compensation step value.
624156f3e5b41cd2049230b1423c455763d31738693Spike Sprague     **/
625156f3e5b41cd2049230b1423c455763d31738693Spike Sprague    public float getExposureCompensationStep() {
626156f3e5b41cd2049230b1423c455763d31738693Spike Sprague        return mExposureCompensationStep;
627a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague    }
628a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague
629a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague    /**
630a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren     * Check if a button is enabled with the given button id..
6311848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     */
6321848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    public boolean isEnabled(int buttonId) {
633a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        View button;
634a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        try {
63566d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague            button = getButtonOrError(buttonId);
636a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        } catch (IllegalArgumentException e) {
63766d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague            button = getImageButtonOrError(buttonId);
638a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        }
639a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren
640a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        Integer enabledId = (Integer) button.getTag(R.string.tag_enabled_id);
641a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        if (enabledId != null) {
642a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren            return (enabledId.intValue() == buttonId) && button.isEnabled();
643a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        } else {
644a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren            return false;
645a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        }
6461848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    }
6471848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren
6481848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    /**
6491848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     * Check if a button is visible.
6501848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren     */
6511848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren    public boolean isVisible(int buttonId) {
652a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        View button;
653a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        try {
65466d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague            button = getButtonOrError(buttonId);
655a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        } catch (IllegalArgumentException e) {
65666d3d0d0633324893b89e1ddec14a4710d8034c3Spike Sprague            button = getImageButtonOrError(buttonId);
657a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren        }
6581848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren        return (button.getVisibility() == View.VISIBLE);
6598a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren    }
66018e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren
6618a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren    /**
6628ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu     * Initialize a flash button.
6638a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren     */
6648ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu    private void initializeFlashButton(MultiToggleImageButton button,
6659a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava            final ButtonCallback cb, final ButtonCallback preCb, int resIdImages) {
66618e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren
66718e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren        if (resIdImages > 0) {
6688a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren            button.overrideImageIds(resIdImages);
66918e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren        }
67079718f6c6fb60aedd09edeedb2c16d1e2f9fe02dSpike Sprague        button.overrideContentDescriptions(R.array.camera_flash_descriptions);
67179718f6c6fb60aedd09edeedb2c16d1e2f9fe02dSpike Sprague
6726190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        int index = mSettingsManager.getIndexOfCurrentValue(mAppController.getCameraScope(),
6736190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                            Keys.KEY_FLASH_MODE);
6744efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren        button.setState(index >= 0 ? index : 0, false);
6754efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren
6769a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava        setPreChangeCallback(button, preCb);
6779a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava
6788a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren        button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() {
6796b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague            @Override
6806b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague            public void stateChanged(View view, int state) {
6816190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                mSettingsManager.setValueByIndex(mAppController.getCameraScope(),
6826190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                 Keys.KEY_FLASH_MODE, state);
6836b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague                if (cb != null) {
6846b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague                    cb.onStateChanged(state);
68518e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren                }
6866b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague            }
6876b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague        });
68818e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren    }
68918e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren
69018e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren    /**
6918ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu     * Initialize video torch button
6920f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague     */
6938ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu    private void initializeTorchButton(MultiToggleImageButton button,
6949a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava            final ButtonCallback cb, final ButtonCallback preCb, int resIdImages) {
6954efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren
6960f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague        if (resIdImages > 0) {
6970f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague            button.overrideImageIds(resIdImages);
6980f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague        }
69979718f6c6fb60aedd09edeedb2c16d1e2f9fe02dSpike Sprague        button.overrideContentDescriptions(R.array.video_flash_descriptions);
70079718f6c6fb60aedd09edeedb2c16d1e2f9fe02dSpike Sprague
7016190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        int index = mSettingsManager.getIndexOfCurrentValue(mAppController.getCameraScope(),
7026190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                            Keys.KEY_VIDEOCAMERA_FLASH_MODE);
7034efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren        button.setState(index >= 0 ? index : 0, false);
7044efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren
7059a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava        setPreChangeCallback(button, preCb);
7069a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava
7070f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague        button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() {
7086b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague            @Override
7096b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague            public void stateChanged(View view, int state) {
7106190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                mSettingsManager.setValueByIndex(mAppController.getCameraScope(),
7116190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                 Keys.KEY_VIDEOCAMERA_FLASH_MODE, state);
71215473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren                if (cb != null) {
71315473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren                    cb.onStateChanged(state);
71415473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren                }
71515473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren            }
71615473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren        });
71715473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren    }
71815473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren
71915473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren    /**
720b4dd5659a53c625a611080db0d41f52f2b421354Sam Hasinoff     * Initialize hdr plus flash button
72115473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren     */
722b4dd5659a53c625a611080db0d41f52f2b421354Sam Hasinoff    private void initializeHdrPlusFlashButton(MultiToggleImageButton button,
7239a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava            final ButtonCallback cb, final ButtonCallback preCb, int resIdImages) {
72415473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren
72515473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren        if (resIdImages > 0) {
72615473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren            button.overrideImageIds(resIdImages);
72715473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren        }
72815473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren        button.overrideContentDescriptions(R.array.hdr_plus_flash_descriptions);
72915473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren
7306190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        int index = mSettingsManager.getIndexOfCurrentValue(mAppController.getModuleScope(),
7316190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                            Keys.KEY_HDR_PLUS_FLASH_MODE);
73215473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren        button.setState(index >= 0 ? index : 0, false);
73315473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren
7349a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava        setPreChangeCallback(button, preCb);
7359a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava
73615473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren        button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() {
73715473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren            @Override
73815473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren            public void stateChanged(View view, int state) {
7396190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                mSettingsManager.setValueByIndex(mAppController.getModuleScope(),
7406190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                 Keys.KEY_HDR_PLUS_FLASH_MODE, state);
74115473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren                if (cb != null) {
7426b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague                    cb.onStateChanged(state);
7430f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague                }
7446b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague            }
7456b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague        });
7460f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague    }
7470f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague
7480f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague    /**
7498ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu     * Initialize a camera button.
75018e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren     */
7518ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu    private void initializeCameraButton(final MultiToggleImageButton button,
7529a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava            final ButtonCallback cb, final ButtonCallback preCb, int resIdImages) {
75318e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren
75418e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren        if (resIdImages > 0) {
7558a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren            button.overrideImageIds(resIdImages);
75618e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren        }
7578a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren
7586190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        int index = mSettingsManager.getIndexOfCurrentValue(mAppController.getModuleScope(),
7596190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                            Keys.KEY_CAMERA_ID);
7604efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren        button.setState(index >= 0 ? index : 0, false);
7618a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren
7629a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava        setPreChangeCallback(button, preCb);
7639a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava
7648a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren        button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() {
7656b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague            @Override
7666b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague            public void stateChanged(View view, int state) {
7676190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                mSettingsManager.setValueByIndex(mAppController.getModuleScope(),
7686190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                 Keys.KEY_CAMERA_ID, state);
7696190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                int cameraId = mSettingsManager.getInteger(mAppController.getModuleScope(),
7706190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                           Keys.KEY_CAMERA_ID);
771c8d9ad868e515ccebe1b6f52cb5fae1e6d13cbabAngus Kong                // This is a quick fix for ISE in Gcam module which can be
772c8d9ad868e515ccebe1b6f52cb5fae1e6d13cbabAngus Kong                // found by rapid pressing camera switch button. The assumption
773c8d9ad868e515ccebe1b6f52cb5fae1e6d13cbabAngus Kong                // here is that each time this button is clicked, the listener
774c8d9ad868e515ccebe1b6f52cb5fae1e6d13cbabAngus Kong                // will do something and then enable this button again.
775c8d9ad868e515ccebe1b6f52cb5fae1e6d13cbabAngus Kong                button.setEnabled(false);
7766b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague                if (cb != null) {
7776b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague                    cb.onStateChanged(cameraId);
77818e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren                }
779b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren                mAppController.getCameraAppUI().onChangeCamera();
7806b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague            }
7816b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague        });
78218e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren    }
78318e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren
78418e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren    /**
7858ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu     * Initialize an hdr plus button.
78618e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren     */
7878ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu    private void initializeHdrPlusButton(MultiToggleImageButton button,
7889a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava            final ButtonCallback cb, final ButtonCallback preCb, int resIdImages) {
78918e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren
790f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        initializeHdrPlusButtonIcons(button, resIdImages);
7918a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren
7926190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        int index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL,
7936190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                            Keys.KEY_CAMERA_HDR_PLUS);
7948ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu        button.setState(index >= 0 ? index : 0, false);
7958ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu
7969a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava        setPreChangeCallback(button, preCb);
7979a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava
7988ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu        button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() {
7998ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu            @Override
8008ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu            public void stateChanged(View view, int state) {
8016190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                mSettingsManager.setValueByIndex(SettingsManager.SCOPE_GLOBAL,
8026190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                 Keys.KEY_CAMERA_HDR_PLUS, state);
8038ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu                if (cb != null) {
8048ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu                    cb.onStateChanged(state);
8058ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu                }
8068ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu            }
8078ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu        });
8088ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu    }
8098ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu
810f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague    private void initializeHdrPlusButtonIcons(MultiToggleImageButton button, int resIdImages) {
811f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        if (resIdImages > 0) {
812f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague            button.overrideImageIds(resIdImages);
813f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        }
814f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        button.overrideContentDescriptions(R.array.hdr_plus_descriptions);
815f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague    }
816f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague
8178ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu    /**
8188ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu     * Initialize an hdr button.
8198ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu     */
8208ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu    private void initializeHdrButton(MultiToggleImageButton button,
8219a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava            final ButtonCallback cb, final ButtonCallback preCb, int resIdImages) {
8228ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu
823f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        initializeHdrButtonIcons(button, resIdImages);
8248ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu
8256190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        int index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL,
8266190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                            Keys.KEY_CAMERA_HDR);
8274efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren        button.setState(index >= 0 ? index : 0, false);
8288a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren
8299a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava        setPreChangeCallback(button, preCb);
8309a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava
8318a2933b2c0156b752425b499f3081e4ffc350061Erin Dahlgren        button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() {
8326b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague            @Override
8336b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague            public void stateChanged(View view, int state) {
8346190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                mSettingsManager.setValueByIndex(SettingsManager.SCOPE_GLOBAL,
8356190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                 Keys.KEY_CAMERA_HDR, state);
8366b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague                if (cb != null) {
8376b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague                    cb.onStateChanged(state);
83818e2ef6d2b2d36abcaa7378a0f7df792ecf8ed81Erin Dahlgren                }
8396b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague            }
8406b174190b43bb4c2d7a5493e4f117ef6aac5f684Spike Sprague        });
8414efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren    }
842d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren
843f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague    private void initializeHdrButtonIcons(MultiToggleImageButton button, int resIdImages) {
844f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        if (resIdImages > 0) {
845f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague            button.overrideImageIds(resIdImages);
846f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        }
847f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague        button.overrideContentDescriptions(R.array.hdr_descriptions);
848f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague    }
849f3d360e4d97e724286a530e30cba9fa19e2304d8Spike Sprague
850abf54e2994961395a0feb0b08353e62718443f23Spike Sprague    /**
8516c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu     * Initialize a countdown timer button.
8526c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu     */
8536c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu    private void initializeCountdownButton(MultiToggleImageButton button,
8549a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava            final ButtonCallback cb, final ButtonCallback preCb, int resIdImages) {
8556c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu        if (resIdImages > 0) {
8566c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu            button.overrideImageIds(resIdImages);
8576c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu        }
8586c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu
8596190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        int index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL,
8606190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                            Keys.KEY_COUNTDOWN_DURATION);
8616c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu        button.setState(index >= 0 ? index : 0, false);
8626c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu
8639a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava        setPreChangeCallback(button, preCb);
8649a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava
8656c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu        button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() {
8666c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu            @Override
8676c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu            public void stateChanged(View view, int state) {
8686190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                mSettingsManager.setValueByIndex(SettingsManager.SCOPE_GLOBAL,
8696190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                 Keys.KEY_COUNTDOWN_DURATION, state);
8706c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu                if(cb != null) {
8716c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu                    cb.onStateChanged(state);
8726c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu                }
8736c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu            }
8746c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu        });
8756c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu    }
8766c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu
8776c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu    /**
878abf54e2994961395a0feb0b08353e62718443f23Spike Sprague     * Update the visual state of the manual exposure buttons
879abf54e2994961395a0feb0b08353e62718443f23Spike Sprague     */
880abf54e2994961395a0feb0b08353e62718443f23Spike Sprague    public void updateExposureButtons() {
8816190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        int compValue = mSettingsManager.getInteger(mAppController.getCameraScope(),
8826190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                    Keys.KEY_EXPOSURE);
883a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague        if (mExposureCompensationStep != 0.0f) {
884a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague            int comp = Math.round(compValue * mExposureCompensationStep);
88559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            mModeOptionsExposure.setSelectedOptionByTag(String.valueOf(comp));
886abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        }
887abf54e2994961395a0feb0b08353e62718443f23Spike Sprague    }
8888ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu
8898ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu    /**
8908ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu     * Initialize a grid lines button.
891d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren     */
8928ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu    private void initializeGridLinesButton(MultiToggleImageButton button,
8939a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava            final ButtonCallback cb, final ButtonCallback preCb, int resIdImages) {
894d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren
895d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren        if (resIdImages > 0) {
896d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren            button.overrideImageIds(resIdImages);
897d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren        }
898d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren        button.overrideContentDescriptions(R.array.grid_lines_descriptions);
8996190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren
9009a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava        setPreChangeCallback(button, preCb);
9019a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava
902d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren        button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() {
903d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren            @Override
904d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren            public void stateChanged(View view, int state) {
9056190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                mSettingsManager.setValueByIndex(SettingsManager.SCOPE_GLOBAL,
9066190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                 Keys.KEY_CAMERA_GRID_LINES, state);
907d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren                if (cb != null) {
908d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren                    cb.onStateChanged(state);
909d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren                }
910d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren            }
911d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren        });
912517f32a7cb9b154ddde61d91f1f562d2f1889984Alan Newberger
913517f32a7cb9b154ddde61d91f1f562d2f1889984Alan Newberger        int index = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL,
914517f32a7cb9b154ddde61d91f1f562d2f1889984Alan Newberger                                                            Keys.KEY_CAMERA_GRID_LINES);
915517f32a7cb9b154ddde61d91f1f562d2f1889984Alan Newberger        button.setState(index >= 0 ? index : 0, true);
916d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren    }
917f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren
91859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    public boolean isPanoEnabled() {
91959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        return mModeOptions.getMainBar() == ModeOptions.BAR_PANO;
92059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    }
92159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague
922f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren   /**
92359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague     * Initialize a panorama orientation buttons.
924f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren     */
92559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    public void initializePanoOrientationButtons(final ButtonCallback cb) {
92659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        int resIdImages = PhotoSphereHelper.getPanoramaOrientationOptionArrayId();
92759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        int resIdDescriptions = PhotoSphereHelper.getPanoramaOrientationDescriptions();
928f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren        if (resIdImages > 0) {
92959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            TypedArray imageIds = null;
93059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            TypedArray descriptionIds = null;
93159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            try {
93259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                mModeOptions.setMainBar(ModeOptions.BAR_PANO);
93359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                imageIds = mAppController
93459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    .getAndroidContext().getResources().obtainTypedArray(resIdImages);
93559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                descriptionIds = mAppController
93659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    .getAndroidContext().getResources().obtainTypedArray(resIdDescriptions);
93759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                mModeOptionsPano.removeAllViews();
938e541dc2d520aae8d45f3c605c3d732e33dd3b616Spike Sprague                final boolean isHorizontal =
939e541dc2d520aae8d45f3c605c3d732e33dd3b616Spike Sprague                    (mModeOptionsPano.getOrientation() == LinearLayout.HORIZONTAL);
940e541dc2d520aae8d45f3c605c3d732e33dd3b616Spike Sprague                final int numImageIds = imageIds.length();
941e541dc2d520aae8d45f3c605c3d732e33dd3b616Spike Sprague                for (int index = 0; index < numImageIds; index++) {
942e541dc2d520aae8d45f3c605c3d732e33dd3b616Spike Sprague                    int i;
943e541dc2d520aae8d45f3c605c3d732e33dd3b616Spike Sprague                    // if in portrait orientation (pano bar horizonal), order buttons normally
944e541dc2d520aae8d45f3c605c3d732e33dd3b616Spike Sprague                    // if in landscape orientation (pano bar vertical), reverse button order
945e541dc2d520aae8d45f3c605c3d732e33dd3b616Spike Sprague                    if (isHorizontal) {
946e541dc2d520aae8d45f3c605c3d732e33dd3b616Spike Sprague                        i = index;
947e541dc2d520aae8d45f3c605c3d732e33dd3b616Spike Sprague                    } else {
948e541dc2d520aae8d45f3c605c3d732e33dd3b616Spike Sprague                        i = numImageIds - index - 1;
949e541dc2d520aae8d45f3c605c3d732e33dd3b616Spike Sprague                    }
950e541dc2d520aae8d45f3c605c3d732e33dd3b616Spike Sprague
95159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    int imageId = imageIds.getResourceId(i, 0);
95259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    if (imageId > 0) {
95359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        ImageButton imageButton = (ImageButton) LayoutInflater
95459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                            .from(mAppController.getAndroidContext())
95559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                            .inflate(R.layout.mode_options_imagebutton_template,
95659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                                     mModeOptionsPano, false);
95759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        imageButton.setImageResource(imageId);
95859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        imageButton.setTag(String.valueOf(i));
95959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        mModeOptionsPano.addView(imageButton);
96059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague
96159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        int descriptionId = descriptionIds.getResourceId(i, 0);
96259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        if (descriptionId > 0) {
96359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                            imageButton.setContentDescription(
96459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                                    mAppController.getAndroidContext().getString(descriptionId));
96559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        }
96659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    }
96759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                }
96859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                mModeOptionsPano.updateListeners();
96959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                mModeOptionsPano
97059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    .setOnOptionClickListener(new RadioOptions.OnOptionClickListener() {
97159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        @Override
97259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        public void onOptionClicked(View v) {
97359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                            if (cb != null) {
97459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                                int state = Integer.parseInt((String)v.getTag());
9756190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                mSettingsManager.setValueByIndex(SettingsManager.SCOPE_GLOBAL,
9766190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                                 Keys.KEY_CAMERA_PANO_ORIENTATION,
9776190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                                 state);
97859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                                cb.onStateChanged(state);
97959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                            }
98059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        }
98159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    });
982774f110f1aab1c28ca039943f5c3093cc0b27d98Spike Sprague                updatePanoButtons();
98359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            } finally {
98459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                if (imageIds != null) {
98559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    imageIds.recycle();
986f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren                }
98759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                if (descriptionIds != null) {
98859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    descriptionIds.recycle();
98959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                }
990f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren            }
99159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        }
99259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    }
993f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren
99459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    private void updatePanoButtons() {
9956190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren        int modeIndex = mSettingsManager.getIndexOfCurrentValue(SettingsManager.SCOPE_GLOBAL,
9966190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren                                                                Keys.KEY_CAMERA_PANO_ORIENTATION);
99759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        mModeOptionsPano.setSelectedOptionByTag(String.valueOf(modeIndex));
998f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren    }
9999a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava
10009a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava    private void setPreChangeCallback(MultiToggleImageButton button, final ButtonCallback preCb) {
10019a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava        button.setOnPreChangeListener(new MultiToggleImageButton.OnStateChangeListener() {
10029a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava            @Override
10039a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava            public void stateChanged(View view, int state) {
10049a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava                if(preCb != null) {
10059a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava                    preCb.onStateChanged(state);
10069a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava                }
10079a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava            }
10089a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava        });
10099a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava    }
1010d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren}
1011