149b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong/* 249b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong * Copyright (C) 2013 The Android Open Source Project 349b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong * 449b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong * Licensed under the Apache License, Version 2.0 (the "License"); 549b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong * you may not use this file except in compliance with the License. 649b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong * You may obtain a copy of the License at 749b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong * 849b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong * http://www.apache.org/licenses/LICENSE-2.0 949b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong * 1049b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong * Unless required by applicable law or agreed to in writing, software 1149b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong * distributed under the License is distributed on an "AS IS" BASIS, 1249b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1349b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong * See the License for the specific language governing permissions and 1449b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong * limitations under the License. 1549b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong */ 1649b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong 1749b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kongpackage com.android.camera.ui; 1849b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong 1949b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kongimport android.content.Context; 2049b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kongimport android.view.GestureDetector; 2149b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kongimport android.view.MotionEvent; 2249b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kongimport android.view.ScaleGestureDetector; 2349b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong 24121022cb590955e37f1264f77190ce4711159976Doris Liu// This class aggregates two gesture detectors: GestureDetector, 2549b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong// ScaleGestureDetector. 2649b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kongpublic class FilmStripGestureRecognizer { 2749b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong @SuppressWarnings("unused") 2849b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong private static final String TAG = "FilmStripGestureRecognizer"; 2949b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong 3049b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong public interface Listener { 3149b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong boolean onSingleTapUp(float x, float y); 3249b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong boolean onDoubleTap(float x, float y); 3349b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong boolean onScroll(float x, float y, float dx, float dy); 3449b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong boolean onFling(float velocityX, float velocityY); 3549b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong boolean onScaleBegin(float focusX, float focusY); 3649b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong boolean onScale(float focusX, float focusY, float scale); 3749b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong boolean onDown(float x, float y); 3887f9a62f473a3c57505e2877b0a46ab3cb5e62acAngus Kong boolean onUp(float x, float y); 3949b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong void onScaleEnd(); 4049b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong } 4149b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong 4249b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong private final GestureDetector mGestureDetector; 4349b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong private final ScaleGestureDetector mScaleDetector; 4449b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong private final Listener mListener; 4549b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong 4649b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong public FilmStripGestureRecognizer(Context context, Listener listener) { 4749b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong mListener = listener; 4849b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong mGestureDetector = new GestureDetector(context, new MyGestureListener(), 4949b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong null, true /* ignoreMultitouch */); 50121022cb590955e37f1264f77190ce4711159976Doris Liu mGestureDetector.setOnDoubleTapListener(new MyDoubleTapListener()); 5149b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong mScaleDetector = new ScaleGestureDetector( 5249b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong context, new MyScaleListener()); 5349b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong } 5449b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong 557234f4d6ff4fdcd47eb428405d2b31a5711d20ceDoris Liu public void onTouchEvent(MotionEvent event) { 567234f4d6ff4fdcd47eb428405d2b31a5711d20ceDoris Liu mGestureDetector.onTouchEvent(event); 577234f4d6ff4fdcd47eb428405d2b31a5711d20ceDoris Liu mScaleDetector.onTouchEvent(event); 5887f9a62f473a3c57505e2877b0a46ab3cb5e62acAngus Kong if (event.getAction() == MotionEvent.ACTION_UP) { 5987f9a62f473a3c57505e2877b0a46ab3cb5e62acAngus Kong mListener.onUp(event.getX(), event.getY()); 6087f9a62f473a3c57505e2877b0a46ab3cb5e62acAngus Kong } 6149b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong } 6249b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong 6349b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong private class MyGestureListener 6449b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong extends GestureDetector.SimpleOnGestureListener { 6549b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong @Override 6649b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong public boolean onScroll( 6749b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong MotionEvent e1, MotionEvent e2, float dx, float dy) { 6849b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong return mListener.onScroll(e2.getX(), e2.getY(), dx, dy); 6949b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong } 7049b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong 7149b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong @Override 7249b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 7349b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong float velocityY) { 7449b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong return mListener.onFling(velocityX, velocityY); 7549b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong } 7649b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong 7749b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong @Override 7849b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong public boolean onDown(MotionEvent e) { 7949b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong mListener.onDown(e.getX(), e.getY()); 8049b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong return super.onDown(e); 8149b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong } 8249b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong } 8349b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong 84121022cb590955e37f1264f77190ce4711159976Doris Liu /** 85121022cb590955e37f1264f77190ce4711159976Doris Liu * The listener that is used to notify when a double-tap or a confirmed 86121022cb590955e37f1264f77190ce4711159976Doris Liu * single-tap occur. 87121022cb590955e37f1264f77190ce4711159976Doris Liu */ 88121022cb590955e37f1264f77190ce4711159976Doris Liu private class MyDoubleTapListener implements GestureDetector.OnDoubleTapListener { 89121022cb590955e37f1264f77190ce4711159976Doris Liu 90121022cb590955e37f1264f77190ce4711159976Doris Liu @Override 91121022cb590955e37f1264f77190ce4711159976Doris Liu public boolean onSingleTapConfirmed(MotionEvent e) { 92121022cb590955e37f1264f77190ce4711159976Doris Liu return mListener.onSingleTapUp(e.getX(), e.getY()); 93121022cb590955e37f1264f77190ce4711159976Doris Liu } 94121022cb590955e37f1264f77190ce4711159976Doris Liu 95121022cb590955e37f1264f77190ce4711159976Doris Liu @Override 96121022cb590955e37f1264f77190ce4711159976Doris Liu public boolean onDoubleTap(MotionEvent e) { 97121022cb590955e37f1264f77190ce4711159976Doris Liu return mListener.onDoubleTap(e.getX(), e.getY()); 98121022cb590955e37f1264f77190ce4711159976Doris Liu } 99121022cb590955e37f1264f77190ce4711159976Doris Liu 100121022cb590955e37f1264f77190ce4711159976Doris Liu @Override 101121022cb590955e37f1264f77190ce4711159976Doris Liu public boolean onDoubleTapEvent(MotionEvent e) { 102121022cb590955e37f1264f77190ce4711159976Doris Liu return true; 103121022cb590955e37f1264f77190ce4711159976Doris Liu } 104121022cb590955e37f1264f77190ce4711159976Doris Liu } 105121022cb590955e37f1264f77190ce4711159976Doris Liu 10649b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong private class MyScaleListener 10749b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong extends ScaleGestureDetector.SimpleOnScaleGestureListener { 10849b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong @Override 10949b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong public boolean onScaleBegin(ScaleGestureDetector detector) { 11049b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong return mListener.onScaleBegin( 11149b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong detector.getFocusX(), detector.getFocusY()); 11249b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong } 11349b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong 11449b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong @Override 11549b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong public boolean onScale(ScaleGestureDetector detector) { 11649b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong return mListener.onScale(detector.getFocusX(), 11749b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong detector.getFocusY(), detector.getScaleFactor()); 11849b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong } 11949b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong 12049b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong @Override 12149b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong public void onScaleEnd(ScaleGestureDetector detector) { 12249b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong mListener.onScaleEnd(); 12349b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong } 12449b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong } 12549b9ba2ba89760f297ecc7d6d94d68fb4b836be1Angus Kong} 126