1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.camera; 18 19 import android.content.Context; 20 import android.util.AttributeSet; 21 import android.view.View; 22 import android.widget.ImageView; 23 24 /** 25 * A button designed to be used for the on-screen shutter button. 26 * It's currently an {@code ImageView} that can call a delegate when the 27 * pressed state changes. 28 */ 29 public class ShutterButton extends ImageView implements View.OnLongClickListener { 30 /** 31 * A callback to be invoked when a ShutterButton's pressed state changes. 32 */ 33 public interface OnShutterButtonListener { 34 /** 35 * Called when a ShutterButton has been pressed. 36 * 37 * @param pressed The ShutterButton that was pressed. 38 */ 39 void onShutterButtonFocus(boolean pressed); 40 void onShutterButtonClick(); 41 } 42 43 /** 44 * A callback to be invoked when a ShutterButton's long pressed. 45 */ 46 public interface OnShutterButtonLongPressListener { 47 void onShutterButtonLongPressed(); 48 } 49 50 private OnShutterButtonListener mListener; 51 private OnShutterButtonLongPressListener mLongPressListener; 52 private boolean mOldPressed; 53 54 public ShutterButton(Context context, AttributeSet attrs) { 55 super(context, attrs); 56 setOnLongClickListener(this); 57 } 58 59 public void setOnShutterButtonListener(OnShutterButtonListener listener) { 60 mListener = listener; 61 } 62 63 public void setOnShutterButtonLongPressListener(OnShutterButtonLongPressListener listener) { 64 mLongPressListener = listener; 65 } 66 67 /** 68 * Hook into the drawable state changing to get changes to isPressed -- the 69 * onPressed listener doesn't always get called when the pressed state 70 * changes. 71 */ 72 @Override 73 protected void drawableStateChanged() { 74 super.drawableStateChanged(); 75 final boolean pressed = isPressed(); 76 if (pressed != mOldPressed) { 77 if (!pressed) { 78 // When pressing the physical camera button the sequence of 79 // events is: 80 // focus pressed, optional camera pressed, focus released. 81 // We want to emulate this sequence of events with the shutter 82 // button. When clicking using a trackball button, the view 83 // system changes the the drawable state before posting click 84 // notification, so the sequence of events is: 85 // pressed(true), optional click, pressed(false) 86 // When clicking using touch events, the view system changes the 87 // drawable state after posting click notification, so the 88 // sequence of events is: 89 // pressed(true), pressed(false), optional click 90 // Since we're emulating the physical camera button, we want to 91 // have the same order of events. So we want the optional click 92 // callback to be delivered before the pressed(false) callback. 93 // 94 // To do this, we delay the posting of the pressed(false) event 95 // slightly by pushing it on the event queue. This moves it 96 // after the optional click notification, so our client always 97 // sees events in this sequence: 98 // pressed(true), optional click, pressed(false) 99 post(new Runnable() { 100 public void run() { 101 callShutterButtonFocus(pressed); 102 } 103 }); 104 } else { 105 callShutterButtonFocus(pressed); 106 } 107 mOldPressed = pressed; 108 } 109 } 110 111 private void callShutterButtonFocus(boolean pressed) { 112 if (mListener != null) { 113 mListener.onShutterButtonFocus(pressed); 114 } 115 } 116 117 @Override 118 public boolean performClick() { 119 boolean result = super.performClick(); 120 if (mListener != null) { 121 mListener.onShutterButtonClick(); 122 } 123 return result; 124 } 125 126 @Override 127 public boolean onLongClick(View v) { 128 if (mLongPressListener != null) { 129 mLongPressListener.onShutterButtonLongPressed(); 130 } 131 return false; 132 } 133 } 134