00001 /* 00002 * Copyright (C) 2008 The Android Open Source Project 00003 * Copyright 2011 Robert Theis 00004 * Copyright 2012 Jaime Navarro Santapau 00005 * 00006 * Licensed under the Apache License, Version 2.0 (the "License"); 00007 * you may not use this file except in compliance with the License. 00008 * You may obtain a copy of the License at 00009 * 00010 * http://www.apache.org/licenses/LICENSE-2.0 00011 * 00012 * Unless required by applicable law or agreed to in writing, software 00013 * distributed under the License is distributed on an "AS IS" BASIS, 00014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 * See the License for the specific language governing permissions and 00016 * limitations under the License. 00017 */ 00018 00026 package edu.uoc.ocr.camera; 00027 00028 import android.content.Context; 00029 import android.util.AttributeSet; 00030 import android.widget.ImageView; 00031 00039 public class ShutterButton extends ImageView { 00040 00046 public interface OnShutterButtonListener { 00047 00053 void onShutterButtonFocus(ShutterButton b, boolean pressed); 00054 00055 void onShutterButtonClick(ShutterButton b); 00056 } 00057 00058 private OnShutterButtonListener mListener; 00059 private boolean mOldPressed; 00060 00061 public ShutterButton(Context context) { 00062 super(context); 00063 } 00064 00065 public ShutterButton(Context context, AttributeSet attrs) { 00066 super(context, attrs); 00067 } 00068 00069 public ShutterButton(Context context, AttributeSet attrs, int defStyle) { 00070 super(context, attrs, defStyle); 00071 } 00072 00073 public void setOnShutterButtonListener(OnShutterButtonListener listener) { 00074 mListener = listener; 00075 } 00076 00082 @Override 00083 protected void drawableStateChanged() { 00084 super.drawableStateChanged(); 00085 final boolean pressed = isPressed(); 00086 if (pressed != mOldPressed) { 00087 if (!pressed) { 00088 // When pressing the physical camera button the sequence of 00089 // events is: 00090 // focus pressed, optional camera pressed, focus released. 00091 // We want to emulate this sequence of events with the shutter 00092 // button. When clicking using a trackball button, the view 00093 // system changes the the drawable state before posting click 00094 // notification, so the sequence of events is: 00095 // pressed(true), optional click, pressed(false) 00096 // When clicking using touch events, the view system changes the 00097 // drawable state after posting click notification, so the 00098 // sequence of events is: 00099 // pressed(true), pressed(false), optional click 00100 // Since we're emulating the physical camera button, we want to 00101 // have the same order of events. So we want the optional click 00102 // callback to be delivered before the pressed(false) callback. 00103 // 00104 // To do this, we delay the posting of the pressed(false) event 00105 // slightly by pushing it on the event queue. This moves it 00106 // after the optional click notification, so our client always 00107 // sees events in this sequence: 00108 // pressed(true), optional click, pressed(false) 00109 post(new Runnable() { 00110 public void run() { 00111 callShutterButtonFocus(pressed); 00112 } 00113 }); 00114 } else { 00115 callShutterButtonFocus(pressed); 00116 } 00117 mOldPressed = pressed; 00118 } 00119 } 00120 00121 private void callShutterButtonFocus(boolean pressed) { 00122 if (mListener != null) { 00123 mListener.onShutterButtonFocus(this, pressed); 00124 } 00125 } 00126 00127 @Override 00128 public boolean performClick() { 00129 boolean result = super.performClick(); 00130 if (mListener != null) { 00131 mListener.onShutterButtonClick(this); 00132 } 00133 return result; 00134 } 00135 }