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 42 public static interface IndicatorChangeListener { onShowIndicator(View view, boolean showed)43 public void onShowIndicator(View view, boolean showed); 44 } 45 AbstractIndicatorButton(Context context)46 public AbstractIndicatorButton(Context context) { 47 super(context); 48 mFadeIn = AnimationUtils.loadAnimation(context, R.anim.grow_fade_in_from_right); 49 mFadeOut = AnimationUtils.loadAnimation(context, R.anim.shrink_fade_out_from_right); 50 HIGHLIGHT_COLOR = context.getResources().getColor(R.color.review_control_pressed_color); 51 setScaleType(ImageView.ScaleType.CENTER); 52 PopupManager.getInstance(context).setOnOtherPopupShowedListener(this); 53 // Set the click listener to help the comprehension of the accessibility. 54 setClickable(true); 55 } 56 57 @Override onOtherPopupShowed()58 public void onOtherPopupShowed() { 59 dismissPopup(); 60 } 61 setIndicatorChangeListener(IndicatorChangeListener listener)62 public void setIndicatorChangeListener(IndicatorChangeListener listener) { 63 mListener = listener; 64 } 65 66 // Whether scene mode affects this indicator and it cannot be changed. isOverridden()67 public boolean isOverridden() { 68 return false; 69 } 70 71 // Scene mode may override other settings like flash, white-balance, and focus. overrideSettings(final String ... keyvalues)72 abstract public void overrideSettings(final String ... keyvalues); 73 74 @Override onTouchEvent(MotionEvent ev)75 public boolean onTouchEvent(MotionEvent ev) { 76 if (!isEnabled()) return false; 77 78 int action = ev.getAction(); 79 if (action == MotionEvent.ACTION_DOWN && !isOverridden()) { 80 if (mPopup == null || mPopup.getVisibility() != View.VISIBLE) { 81 showPopup(); 82 PopupManager.getInstance(getContext()).notifyShowPopup(this); 83 } else { 84 dismissPopup(); 85 } 86 return true; 87 } else if (action == MotionEvent.ACTION_CANCEL) { 88 dismissPopup(); 89 return true; 90 } 91 return false; 92 } 93 94 @Override setEnabled(boolean enabled)95 public void setEnabled(boolean enabled) { 96 // Do not enable the button if it is overridden by scene mode. 97 if (isOverridden()) { 98 enabled = false; 99 } 100 101 // Don't do anything if state is not changed so not to interfere with 102 // the "highlight" state. 103 if (isEnabled() ^ enabled) { 104 super.setEnabled(enabled); 105 } 106 } 107 108 @Override setDegree(int degree)109 public void setDegree(int degree) { 110 super.setDegree(degree); 111 if (mPopup != null) { 112 mPopup.setOrientation(degree); 113 } 114 } 115 initializePopup()116 abstract protected void initializePopup(); 117 showPopup()118 private void showPopup() { 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 dismissPopup()129 public boolean dismissPopup() { 130 mHandler.removeMessages(MSG_DISMISS_POPUP); 131 if (mPopup != null && mPopup.getVisibility() == View.VISIBLE) { 132 mPopup.clearAnimation(); 133 mPopup.startAnimation(mFadeOut); 134 mPopup.setVisibility(View.GONE); 135 if (mListener != null) mListener.onShowIndicator(this, false); 136 invalidate(); 137 // Indicator wheel needs to update the highlight indicator if this 138 // is dismissed by MSG_DISMISS_POPUP. 139 ((View) getParent()).invalidate(); 140 return true; 141 } 142 return false; 143 } 144 getPopupWindow()145 public AbstractSettingPopup getPopupWindow() { 146 if (mPopup != null && mPopup.getVisibility() == View.VISIBLE) { 147 return mPopup; 148 } else { 149 return null; 150 } 151 } 152 reloadPreference()153 public void reloadPreference() { 154 if (mPopup != null) mPopup.reloadPreference(); 155 } 156 dismissPopupDelayed()157 protected void dismissPopupDelayed() { 158 if (!mHandler.hasMessages(MSG_DISMISS_POPUP)) { 159 mHandler.sendEmptyMessage(MSG_DISMISS_POPUP); 160 } 161 } 162 163 private class MainHandler extends Handler { 164 @Override handleMessage(Message msg)165 public void handleMessage(Message msg) { 166 switch (msg.what) { 167 case MSG_DISMISS_POPUP: 168 dismissPopup(); 169 break; 170 } 171 } 172 } 173 } 174