1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.camera.ui; 18 19 import com.android.camera.R; 20 21 import android.content.Context; 22 import android.os.Handler; 23 import android.os.Message; 24 import android.view.MotionEvent; 25 import android.view.View; 26 import android.view.animation.Animation; 27 import android.view.animation.AnimationUtils; 28 import android.widget.ImageView; 29 30 // This is an indicator button and pressing it opens a popup window. Ex: flash or other settings. 31 public abstract class AbstractIndicatorButton extends RotateImageView implements 32 PopupManager.OnOtherPopupShowedListener { 33 private final String TAG = "AbstractIndicatorButton"; 34 protected Animation mFadeIn, mFadeOut; 35 protected final int HIGHLIGHT_COLOR; 36 protected AbstractSettingPopup mPopup; 37 protected Handler mHandler = new MainHandler(); 38 private final int MSG_DISMISS_POPUP = 0; 39 private IndicatorChangeListener mListener; 40 41 public static interface IndicatorChangeListener { 42 public void onShowIndicator(View view, boolean showed); 43 } 44 45 public AbstractIndicatorButton(Context context) { 46 super(context); 47 mFadeIn = AnimationUtils.loadAnimation(context, R.anim.setting_popup_grow_fade_in); 48 mFadeOut = AnimationUtils.loadAnimation(context, R.anim.setting_popup_shrink_fade_out); 49 HIGHLIGHT_COLOR = context.getResources().getColor(R.color.review_control_pressed_color); 50 setScaleType(ImageView.ScaleType.CENTER); 51 PopupManager.getInstance(context).setOnOtherPopupShowedListener(this); 52 // Set the click listener to help the comprehension of the accessibility. 53 setClickable(true); 54 } 55 56 @Override 57 public void onOtherPopupShowed() { 58 dismissPopup(); 59 } 60 61 public void setIndicatorChangeListener(IndicatorChangeListener listener) { 62 mListener = listener; 63 } 64 65 // Whether scene mode affects this indicator and it cannot be changed. 66 public boolean isOverridden() { 67 return false; 68 } 69 70 // Scene mode may override other settings like flash, white-balance, and focus. 71 abstract public void overrideSettings(final String ... keyvalues); 72 73 @Override 74 public boolean onTouchEvent(MotionEvent ev) { 75 if (!isEnabled()) return false; 76 77 int action = ev.getAction(); 78 if (action == MotionEvent.ACTION_DOWN && !isOverridden()) { 79 if (mPopup == null || mPopup.getVisibility() != View.VISIBLE) { 80 showPopup(); 81 PopupManager.getInstance(getContext()).notifyShowPopup(this); 82 } else { 83 dismissPopup(); 84 } 85 return true; 86 } else if (action == MotionEvent.ACTION_CANCEL) { 87 dismissPopup(); 88 return true; 89 } 90 return false; 91 } 92 93 @Override 94 public void setEnabled(boolean enabled) { 95 // Do not enable the button if it is overridden by scene mode. 96 if (isOverridden()) { 97 enabled = false; 98 } 99 100 // Don't do anything if state is not changed so not to interfere with 101 // the "highlight" state. 102 if (isEnabled() ^ enabled) { 103 super.setEnabled(enabled); 104 } 105 } 106 107 @Override 108 public void setOrientation(int orientation) { 109 super.setOrientation(orientation); 110 if (mPopup != null) { 111 mPopup.setOrientation(orientation); 112 } 113 } 114 115 abstract protected void initializePopup(); 116 117 private void showPopup() { 118 setPressed(true); 119 mHandler.removeMessages(MSG_DISMISS_POPUP); 120 if (mPopup == null) initializePopup(); 121 122 mPopup.setVisibility(View.VISIBLE); 123 mPopup.setOrientation(getDegree()); 124 mPopup.clearAnimation(); 125 mPopup.startAnimation(mFadeIn); 126 if (mListener != null) mListener.onShowIndicator(this, true); 127 } 128 129 public boolean dismissPopup() { 130 setPressed(false); 131 mHandler.removeMessages(MSG_DISMISS_POPUP); 132 if (mPopup != null && mPopup.getVisibility() == View.VISIBLE) { 133 mPopup.clearAnimation(); 134 mPopup.startAnimation(mFadeOut); 135 mPopup.setVisibility(View.GONE); 136 if (mListener != null) mListener.onShowIndicator(this, false); 137 invalidate(); 138 // Indicator wheel needs to update the highlight indicator if this 139 // is dismissed by MSG_DISMISS_POPUP. 140 ((View) getParent()).invalidate(); 141 return true; 142 } 143 return false; 144 } 145 146 public AbstractSettingPopup getPopupWindow() { 147 if (mPopup != null && mPopup.getVisibility() == View.VISIBLE) { 148 return mPopup; 149 } else { 150 return null; 151 } 152 } 153 154 public void reloadPreference() { 155 if (mPopup != null) mPopup.reloadPreference(); 156 } 157 158 protected void dismissPopupDelayed() { 159 if (!mHandler.hasMessages(MSG_DISMISS_POPUP)) { 160 mHandler.sendEmptyMessage(MSG_DISMISS_POPUP); 161 } 162 } 163 164 private class MainHandler extends Handler { 165 @Override 166 public void handleMessage(Message msg) { 167 switch (msg.what) { 168 case MSG_DISMISS_POPUP: 169 dismissPopup(); 170 break; 171 } 172 } 173 } 174 } 175