blob: 8e8ba7df650fdd754d69bac9eac5cd76e113223c [file] [log] [blame]
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.camera;
import android.content.Context;
import android.view.View;
import android.widget.ImageButton;
import com.android.camera.ShutterButton;
import com.android.camera.app.AppController;
import com.android.camera.module.ModuleController;
import com.android.camera.settings.SettingsManager;
import com.android.camera2.R;
/**
* A class for generating pre-initialized
* {@link #android.widget.ImageButton}s.
*/
public class ButtonManager implements SettingsManager.OnSettingChangedListener {
public static final int BUTTON_FLASH = 0;
public static final int BUTTON_TORCH = 1;
public static final int BUTTON_CAMERA = 2;
public static final int BUTTON_HDRPLUS = 3;
public static final int BUTTON_HDR = 4;
public static final int BUTTON_REFOCUS = 5;
public static final int BUTTON_CANCEL = 6;
public static final int BUTTON_DONE = 7;
public static final int BUTTON_RETAKE = 8;
public static final int BUTTON_REVIEW = 9;
public static final int BUTTON_PANO_HORIZONTAL = 10;
public static final int BUTTON_PANO_VERTICAL = 11;
/** For two state MultiToggleImageButtons, the off index. */
public static final int OFF = 0;
/** For two state MultiToggleImageButtons, the on index. */
public static final int ON = 1;
/** A reference to the application's settings manager. */
private final SettingsManager mSettingsManager;
/** Bottom bar options toggle buttons. */
private MultiToggleImageButton mButtonPos1;
private MultiToggleImageButton mButtonPos2;
private MultiToggleImageButton mButtonPos3;
private MultiToggleImageButton mButtonPos4;
/** Intent UI buttons. */
private ImageButton mButtonCancel;
private ImageButton mButtonDone;
private ImageButton mButtonRetake; // same as review.
/** A listener for button enabled and visibility
state changes. */
private ButtonStatusListener mListener;
/** An reference to the gcam mode index. */
private static int sGcamIndex;
private ShutterButton mShutterButton;
private AppController mAppController;
/**
* Get a new global ButtonManager.
*/
public ButtonManager(AppController app) {
mAppController = app;
Context context = app.getAndroidContext();
sGcamIndex = context.getResources().getInteger(R.integer.camera_mode_gcam);
mSettingsManager = app.getSettingsManager();
mSettingsManager.addListener(this);
}
/**
* Load references to buttons under a root View.
* Call this after the root clears/reloads all of its children
* to prevent stale references button views.
*/
public void load(View root) {
getButtonsReferences(root);
}
/**
* ButtonStatusListener provides callbacks for when button's
* visibility changes and enabled status changes.
*/
public interface ButtonStatusListener {
/**
* A button's visibility has changed.
*/
public void onButtonVisibilityChanged(ButtonManager buttonManager, int buttonId);
/**
* A button's enabled state has changed.
*/
public void onButtonEnabledChanged(ButtonManager buttonManager, int buttonId);
}
/**
* Sets the ButtonStatusListener.
*/
public void setListener(ButtonStatusListener listener) {
mListener = listener;
}
/**
* Gets references to all known buttons.
*/
private void getButtonsReferences(View root) {
mButtonPos1
= (MultiToggleImageButton) root.findViewById(R.id.camera_toggle_button);
mButtonPos2
= (MultiToggleImageButton) root.findViewById(R.id.flash_toggle_button);
mButtonPos3
= (MultiToggleImageButton) root.findViewById(R.id.hdr_plus_toggle_button);
mButtonPos4
= (MultiToggleImageButton) root.findViewById(R.id.refocus_toggle_button);
mButtonCancel
= (ImageButton) root.findViewById(R.id.cancel_button);
mButtonDone
= (ImageButton) root.findViewById(R.id.done_button);
mButtonRetake
= (ImageButton) root.findViewById(R.id.retake_button);
mShutterButton
= (ShutterButton) root.findViewById(R.id.shutter_button);
}
@Override
public void onSettingChanged(SettingsManager settingsManager, int id) {
MultiToggleImageButton button = null;
int index = 0;
switch (id) {
case SettingsManager.SETTING_FLASH_MODE: {
index = mSettingsManager.getStringValueIndex(id);
button = getButtonOrError(BUTTON_FLASH);
break;
}
case SettingsManager.SETTING_VIDEOCAMERA_FLASH_MODE: {
index = mSettingsManager.getStringValueIndex(id);
button = getButtonOrError(BUTTON_TORCH);
break;
}
case SettingsManager.SETTING_CAMERA_ID: {
index = mSettingsManager.getStringValueIndex(id);
button = getButtonOrError(BUTTON_CAMERA);
break;
}
case SettingsManager.SETTING_CAMERA_HDR: {
index = mSettingsManager.getStringValueIndex(id);
button = getButtonOrError(BUTTON_HDRPLUS);
break;
}
case SettingsManager.SETTING_CAMERA_REFOCUS: {
index = mSettingsManager.getStringValueIndex(id);
button = getButtonOrError(BUTTON_REFOCUS);
break;
}
default: {
// Do nothing.
}
}
// In case SharedPreferences has changed but the button hasn't been toggled,
// make sure the toggle state is in sync.
if (button != null && button.getState() != index) {
button.setState(Math.max(index, 0), false);
}
}
/**
* A callback executed in the state listener of a button.
* Used by a module to set specific behavior when a button's
* state changes.
*/
public interface ButtonCallback {
public void onStateChanged(int state);
}
/**
* Returns the appropriate {@link com.android.camera.MultiToggleImageButton}
* based on button id. An IllegalStateException will be throw if the
* button could not be found in the view hierarchy.
*/
private MultiToggleImageButton getButtonOrError(int buttonId) {
switch (buttonId) {
case BUTTON_FLASH:
if (mButtonPos2 == null) {
throw new IllegalStateException("Flash button could not be found.");
}
return mButtonPos2;
case BUTTON_TORCH:
if (mButtonPos2 == null) {
throw new IllegalStateException("Torch button could not be found.");
}
return mButtonPos2;
case BUTTON_CAMERA:
if (mButtonPos1 == null) {
throw new IllegalStateException("Camera button could not be found.");
}
return mButtonPos1;
case BUTTON_HDRPLUS:
if (mButtonPos3 == null) {
throw new IllegalStateException("Hdr plus button could not be found.");
}
return mButtonPos3;
case BUTTON_HDR:
if (mButtonPos3 == null) {
throw new IllegalStateException("Hdr button could not be found.");
}
return mButtonPos3;
case BUTTON_REFOCUS:
if (mButtonPos4 == null) {
throw new IllegalStateException("Refocus button could not be found.");
}
return mButtonPos4;
default:
throw new IllegalArgumentException("button not known by id=" + buttonId);
}
}
/**
* Returns the appropriate {@link android.widget.ImageButton}
* based on button id. An IllegalStateException will be throw if the
* button could not be found in the view hierarchy.
*/
private ImageButton getImageButtonOrError(int buttonId) {
switch (buttonId) {
case BUTTON_PANO_VERTICAL:
if (mButtonPos1 == null) {
throw new IllegalStateException("Flash button could not be found.");
}
return (ImageButton) mButtonPos1;
case BUTTON_PANO_HORIZONTAL:
if (mButtonPos2 == null) {
throw new IllegalStateException("Flash button could not be found.");
}
return (ImageButton) mButtonPos2;
case BUTTON_CANCEL:
if (mButtonCancel == null) {
throw new IllegalStateException("Cancel button could not be found.");
}
return mButtonCancel;
case BUTTON_DONE:
if (mButtonDone == null) {
throw new IllegalStateException("Done button could not be found.");
}
return mButtonDone;
case BUTTON_RETAKE:
if (mButtonRetake == null) {
throw new IllegalStateException("Retake button could not be found.");
}
return mButtonRetake;
case BUTTON_REVIEW:
if (mButtonRetake == null) {
throw new IllegalStateException("Review button could not be found.");
}
return mButtonRetake;
default:
throw new IllegalArgumentException("button not known by id=" + buttonId);
}
}
/**
* Enable a known button by id, with a state change callback and
* a resource id that points to an array of drawables.
*/
public void enableButton(int buttonId, ButtonCallback cb) {
MultiToggleImageButton button = getButtonOrError(buttonId);
switch (buttonId) {
case BUTTON_FLASH:
enableFlashButton(button, cb, R.array.camera_flashmode_icons);
break;
case BUTTON_TORCH:
enableTorchButton(button, cb, R.array.video_flashmode_icons);
break;
case BUTTON_CAMERA:
enableCameraButton(button, cb, R.array.camera_id_icons);
break;
case BUTTON_HDRPLUS:
enableHdrPlusButton(button, cb, R.array.pref_camera_hdr_plus_icons);
break;
case BUTTON_HDR:
enableHdrPlusButton(button, cb, R.array.pref_camera_hdr_icons);
break;
case BUTTON_REFOCUS:
enableRefocusButton(button, cb, R.array.refocus_icons);
break;
default:
throw new IllegalArgumentException("button not known by id=" + buttonId);
}
if (!button.isEnabled()) {
button.setEnabled(true);
if (mListener != null) {
mListener.onButtonEnabledChanged(this, buttonId);
}
}
button.setTag(R.string.tag_enabled_id, (Integer) buttonId);
if (button.getVisibility() != View.VISIBLE) {
button.setVisibility(View.VISIBLE);
if (mListener != null) {
mListener.onButtonVisibilityChanged(this, buttonId);
}
}
}
/**
* Enable a known button with a click listener and a resource id.
* Sets the button visible.
*/
public void enablePushButton(int buttonId, View.OnClickListener cb,
int imageId) {
ImageButton button = getImageButtonOrError(buttonId);
button.setOnClickListener(cb);
button.setImageResource(imageId);
if (!button.isEnabled()) {
button.setEnabled(true);
if (mListener != null) {
mListener.onButtonEnabledChanged(this, buttonId);
}
}
button.setTag(R.string.tag_enabled_id, (Integer) buttonId);
if (button.getVisibility() != View.VISIBLE) {
button.setVisibility(View.VISIBLE);
if (mListener != null) {
mListener.onButtonVisibilityChanged(this, buttonId);
}
}
}
/**
* Enable a known button with a click listener. Sets the button visible.
*/
public void enablePushButton(int buttonId, View.OnClickListener cb) {
ImageButton button = getImageButtonOrError(buttonId);
button.setOnClickListener(cb);
if (!button.isEnabled()) {
button.setEnabled(true);
if (mListener != null) {
mListener.onButtonEnabledChanged(this, buttonId);
}
}
button.setTag(R.string.tag_enabled_id, (Integer) buttonId);
if (button.getVisibility() != View.VISIBLE) {
button.setVisibility(View.VISIBLE);
if (mListener != null) {
mListener.onButtonVisibilityChanged(this, buttonId);
}
}
}
/**
* Sets a button in its disabled (greyed out) state.
*/
public void disableButton(int buttonId) {
MultiToggleImageButton button = getButtonOrError(buttonId);
if (button.isEnabled()) {
button.setEnabled(false);
if (mListener != null) {
mListener.onButtonEnabledChanged(this, buttonId);
}
}
button.setTag(R.string.tag_enabled_id, null);
if (button.getVisibility() != View.VISIBLE) {
button.setVisibility(View.VISIBLE);
if (mListener != null) {
mListener.onButtonVisibilityChanged(this, buttonId);
}
}
}
/**
* Hide a button by id.
*/
public void hideButton(int buttonId) {
View button;
try {
button = (View) getButtonOrError(buttonId);
} catch (IllegalArgumentException e) {
button = (View) getImageButtonOrError(buttonId);
}
if (button.getVisibility() == View.VISIBLE) {
button.setVisibility(View.INVISIBLE);
if (mListener != null) {
mListener.onButtonVisibilityChanged(this, buttonId);
}
}
}
/**
* Check if a button is enabled with the given button id..
*/
public boolean isEnabled(int buttonId) {
View button;
try {
button = (View) getButtonOrError(buttonId);
} catch (IllegalArgumentException e) {
button = (View) getImageButtonOrError(buttonId);
}
Integer enabledId = (Integer) button.getTag(R.string.tag_enabled_id);
if (enabledId != null) {
return (enabledId.intValue() == buttonId) && button.isEnabled();
} else {
return false;
}
}
/**
* Check if a button is visible.
*/
public boolean isVisible(int buttonId) {
View button;
try {
button = (View) getButtonOrError(buttonId);
} catch (IllegalArgumentException e) {
button = (View) getImageButtonOrError(buttonId);
}
return (button.getVisibility() == View.VISIBLE);
}
/**
* Enable a flash button.
*/
private void enableFlashButton(MultiToggleImageButton button,
final ButtonCallback cb, int resIdImages) {
if (resIdImages > 0) {
button.overrideImageIds(resIdImages);
}
button.overrideContentDescriptions(R.array.camera_flash_descriptions);
int index = mSettingsManager.getStringValueIndex(SettingsManager.SETTING_FLASH_MODE);
button.setState(index >= 0 ? index : 0, false);
button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() {
@Override
public void stateChanged(View view, int state) {
mSettingsManager.setStringValueIndex(SettingsManager.SETTING_FLASH_MODE, state);
if (cb != null) {
cb.onStateChanged(state);
}
}
});
}
/**
* Enable video torch button
*/
private void enableTorchButton(MultiToggleImageButton button,
final ButtonCallback cb, int resIdImages) {
if (resIdImages > 0) {
button.overrideImageIds(resIdImages);
}
button.overrideContentDescriptions(R.array.video_flash_descriptions);
int index = mSettingsManager.getStringValueIndex(
SettingsManager.SETTING_VIDEOCAMERA_FLASH_MODE);
button.setState(index >= 0 ? index : 0, false);
button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() {
@Override
public void stateChanged(View view, int state) {
mSettingsManager.setStringValueIndex(
SettingsManager.SETTING_VIDEOCAMERA_FLASH_MODE, state);
if(cb != null) {
cb.onStateChanged(state);
}
}
});
}
/**
* Enable a camera button.
*/
private void enableCameraButton(MultiToggleImageButton button,
final ButtonCallback cb, int resIdImages) {
if (resIdImages > 0) {
button.overrideImageIds(resIdImages);
}
int index = mSettingsManager.getStringValueIndex(SettingsManager.SETTING_CAMERA_ID);
button.setState(index >= 0 ? index : 0, false);
button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() {
@Override
public void stateChanged(View view, int state) {
mSettingsManager.setStringValueIndex(SettingsManager.SETTING_CAMERA_ID, state);
int cameraId = Integer.parseInt(mSettingsManager.get(
SettingsManager.SETTING_CAMERA_ID));
if (cb != null) {
cb.onStateChanged(cameraId);
}
mAppController.getCameraAppUI().onChangeCamera();
}
});
}
/**
* Enable an hdr plus button.
*/
private void enableHdrPlusButton(MultiToggleImageButton button,
final ButtonCallback cb, int resIdImages) {
if (resIdImages > 0) {
button.overrideImageIds(resIdImages);
}
button.overrideContentDescriptions(R.array.hdr_plus_descriptions);
int index = mSettingsManager.getStringValueIndex(SettingsManager.SETTING_CAMERA_HDR);
button.setState(index >= 0 ? index : 0, false);
button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() {
@Override
public void stateChanged(View view, int state) {
mSettingsManager.setStringValueIndex(SettingsManager.SETTING_CAMERA_HDR, state);
if (cb != null) {
cb.onStateChanged(state);
}
}
});
}
/**
* Enable a refocus button.
*/
private void enableRefocusButton(MultiToggleImageButton button,
final ButtonCallback cb, int resIdImages) {
if (resIdImages > 0) {
button.overrideImageIds(resIdImages);
}
int index = mSettingsManager.getStringValueIndex(SettingsManager.SETTING_CAMERA_REFOCUS);
button.setState(index >= 0 ? index : 0, false);
button.setOnStateChangeListener(new MultiToggleImageButton.OnStateChangeListener() {
@Override
public void stateChanged(View view, int state) {
mSettingsManager.setStringValueIndex(SettingsManager.SETTING_CAMERA_REFOCUS, state);
if (cb != null) {
cb.onStateChanged(state);
}
}
});
}
}