ShutterButton.java revision b64d345c9d51cabce43b5191532a0c185d2a70a5
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
17package com.android.camera;
18
19import android.content.Context;
20import android.util.AttributeSet;
21import android.widget.ImageView;
22
23/**
24 * A button designed to be used for the on-screen shutter button.
25 * It's currently an ImageView that can call a delegate when the pressed state changes.
26 */
27public class ShutterButton extends ImageView {
28    /**
29     * Interface definition for a callback to be invoked when a ModeButton's pressed state changes.
30     */
31    public interface OnShutterButtonListener {
32        /**
33         * Called when a ShutterButton has been pressed.
34         *
35         * @param b The ShutterButton that was pressed.
36         */
37        void onShutterButtonFocus(ShutterButton b, boolean pressed);
38        void onShutterButtonClick(ShutterButton b);
39    }
40
41    private OnShutterButtonListener mListener;
42    private boolean mOldPressed;
43
44    public ShutterButton(Context context) {
45        super(context);
46    }
47
48    public ShutterButton(Context context, AttributeSet attrs) {
49        super(context, attrs);
50    }
51
52    public ShutterButton(Context context, AttributeSet attrs, int defStyle) {
53        super(context, attrs, defStyle);
54    }
55
56    public void setOnShutterButtonListener(OnShutterButtonListener listener) {
57        mListener = listener;
58    }
59
60    /**
61     * Hook into the drawable state changing to get changes to isPressed -- the
62     * onPressed listener doesn't always get called when the pressed state changes.
63     */
64    @Override
65    protected void drawableStateChanged() {
66        super.drawableStateChanged();
67        final boolean pressed = isPressed();
68        if (pressed != mOldPressed) {
69            if (!pressed) {
70                // When pressing the physical camera button the sequence of events is:
71                //    focus pressed, optional camera pressed, focus released.
72                // We want to emulate this sequence of events with the shutter button.
73                // When clicking using a trackball button, the view system changes
74                // the the drawable state before posting click notification, so the
75                // sequence of events is:
76                //    pressed(true), optional click, pressed(false)
77                // When clicking using touch events, the view system changes the
78                // drawable state after posting click notification, so the sequence of
79                // events is:
80                //    pressed(true), pressed(false), optional click
81                // Since we're emulating the physical camera button, we want to have the
82                // same order of events. So we want the optional click callback to be delivered
83                // before the pressed(false) callback.
84                //
85                // To do this, we delay the posting of the pressed(false) event slightly by
86                // pushing it on the event queue. This moves it after the optional click
87                // notification, so our client always sees events in this sequence:
88                //     pressed(true), optional click, pressed(false)
89                post(new Runnable() {
90                    public void run() {
91                        callShutterButtonFocus(pressed);
92                    }
93                });
94            } else {
95                callShutterButtonFocus(pressed);
96            }
97            mOldPressed = pressed;
98        }
99    }
100
101    private void callShutterButtonFocus(boolean pressed) {
102        if (mListener != null) {
103            mListener.onShutterButtonFocus(this, pressed);
104        }
105    }
106
107    @Override
108    public boolean performClick() {
109        boolean result = super.performClick();
110        if (mListener != null) {
111            mListener.onShutterButtonClick(this);
112        }
113        return result;
114    }
115}
116