1/*
2 * Copyright (C) 2013 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.ui;
18
19import android.content.Context;
20import android.view.GestureDetector;
21import android.view.MotionEvent;
22import android.view.ScaleGestureDetector;
23
24import com.android.camera.debug.Log;
25
26// This class aggregates two gesture detectors: GestureDetector,
27// ScaleGestureDetector.
28public class FilmstripGestureRecognizer {
29    @SuppressWarnings("unused")
30    private static final Log.Tag TAG = new Log.Tag("FStripGestureRecog");
31
32    public interface Listener {
33        boolean onSingleTapUp(float x, float y);
34        boolean onDoubleTap(float x, float y);
35        boolean onScroll(float x, float y, float dx, float dy);
36        boolean onFling(float velocityX, float velocityY);
37        boolean onScaleBegin(float focusX, float focusY);
38        boolean onScale(float focusX, float focusY, float scale);
39        boolean onDown(float x, float y);
40        boolean onUp(float x, float y);
41        void onLongPress(float x, float y);
42        void onScaleEnd();
43    }
44
45    private final GestureDetector mGestureDetector;
46    private final ScaleGestureDetector mScaleDetector;
47    private final Listener mListener;
48
49    public FilmstripGestureRecognizer(Context context, Listener listener) {
50        mListener = listener;
51        mGestureDetector = new GestureDetector(context, new MyGestureListener(),
52                null, true /* ignoreMultitouch */);
53        mGestureDetector.setOnDoubleTapListener(new MyDoubleTapListener());
54        mScaleDetector = new ScaleGestureDetector(
55                context, new MyScaleListener());
56    }
57
58    public boolean onTouchEvent(MotionEvent event) {
59        final boolean gestureProcessed = mGestureDetector.onTouchEvent(event);
60        final boolean scaleProcessed = mScaleDetector.onTouchEvent(event);
61        if (event.getAction() == MotionEvent.ACTION_UP) {
62            mListener.onUp(event.getX(), event.getY());
63        }
64        return (gestureProcessed | scaleProcessed);
65    }
66
67    private class MyGestureListener
68                extends GestureDetector.SimpleOnGestureListener {
69        @Override
70        public void onLongPress(MotionEvent e) {
71            mListener.onLongPress(e.getX(), e.getY());
72        }
73
74        @Override
75        public boolean onScroll(
76                MotionEvent e1, MotionEvent e2, float dx, float dy) {
77            return mListener.onScroll(e2.getX(), e2.getY(), dx, dy);
78        }
79
80        @Override
81        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
82                float velocityY) {
83            return mListener.onFling(velocityX, velocityY);
84        }
85
86        @Override
87        public boolean onDown(MotionEvent e) {
88            mListener.onDown(e.getX(), e.getY());
89            return super.onDown(e);
90        }
91    }
92
93    /**
94     * The listener that is used to notify when a double-tap or a confirmed
95     * single-tap occur.
96     */
97    private class MyDoubleTapListener implements GestureDetector.OnDoubleTapListener {
98
99        @Override
100        public boolean onSingleTapConfirmed(MotionEvent e) {
101            return mListener.onSingleTapUp(e.getX(), e.getY());
102        }
103
104        @Override
105        public boolean onDoubleTap(MotionEvent e) {
106            return mListener.onDoubleTap(e.getX(), e.getY());
107        }
108
109        @Override
110        public boolean onDoubleTapEvent(MotionEvent e) {
111            return true;
112        }
113    }
114
115    private class MyScaleListener
116            extends ScaleGestureDetector.SimpleOnScaleGestureListener {
117        @Override
118        public boolean onScaleBegin(ScaleGestureDetector detector) {
119            return mListener.onScaleBegin(
120                    detector.getFocusX(), detector.getFocusY());
121        }
122
123        @Override
124        public boolean onScale(ScaleGestureDetector detector) {
125            return mListener.onScale(detector.getFocusX(),
126                    detector.getFocusY(), detector.getScaleFactor());
127        }
128
129        @Override
130        public void onScaleEnd(ScaleGestureDetector detector) {
131            mListener.onScaleEnd();
132        }
133    }
134}
135