From 762f8e20f608bc805d9e9f01fa2c4925f4735cf0 Mon Sep 17 00:00:00 2001 From: Chih-Chung Chang Date: Wed, 14 Mar 2012 17:39:42 +0800 Subject: Aggregate three gesture detectors. Change-Id: I270cd7bdeb81d9a8ea5d3aa122f44074413e7616 --- .../android/gallery3d/ui/GestureRecognizer.java | 121 +++++++++++++++++++ src/com/android/gallery3d/ui/PhotoView.java | 133 +++++++++------------ 2 files changed, 177 insertions(+), 77 deletions(-) create mode 100644 src/com/android/gallery3d/ui/GestureRecognizer.java diff --git a/src/com/android/gallery3d/ui/GestureRecognizer.java b/src/com/android/gallery3d/ui/GestureRecognizer.java new file mode 100644 index 000000000..492f993d7 --- /dev/null +++ b/src/com/android/gallery3d/ui/GestureRecognizer.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.ui; + +import android.content.Context; +import android.view.GestureDetector; +import android.view.MotionEvent; +import android.view.ScaleGestureDetector; + +// This class aggregates three gesture detectors: GestureDetector, +// ScaleGestureDetector, and DownUpDetector. +public class GestureRecognizer { + private static final String TAG = "GestureRecognizer"; + + public interface Listener { + boolean onSingleTapUp(float x, float y); + boolean onDoubleTap(float x, float y); + boolean onScroll(float dx, float dy); + boolean onFling(float velocityX, float velocityY); + boolean onScaleBegin(float focusX, float focusY); + boolean onScale(float focusX, float focusY, float scale); + void onScaleEnd(); + void onDown(); + void onUp(); + } + + private final GestureDetector mGestureDetector; + private final ScaleGestureDetector mScaleDetector; + private final DownUpDetector mDownUpDetector; + private final Listener mListener; + + public GestureRecognizer(Context context, Listener listener) { + mListener = listener; + mGestureDetector = new GestureDetector(context, new MyGestureListener(), + null, true /* ignoreMultitouch */); + mScaleDetector = new ScaleGestureDetector( + context, new MyScaleListener()); + mDownUpDetector = new DownUpDetector(new MyDownUpListener()); + } + + public void onTouchEvent(MotionEvent event) { + mGestureDetector.onTouchEvent(event); + mScaleDetector.onTouchEvent(event); + mDownUpDetector.onTouchEvent(event); + } + + public boolean isDown() { + return mDownUpDetector.isDown(); + } + + private class MyGestureListener + extends GestureDetector.SimpleOnGestureListener { + @Override + public boolean onSingleTapUp(MotionEvent e) { + return mListener.onSingleTapUp(e.getX(), e.getY()); + } + + @Override + public boolean onDoubleTap(MotionEvent e) { + return mListener.onDoubleTap(e.getX(), e.getY()); + } + + @Override + public boolean onScroll( + MotionEvent e1, MotionEvent e2, float dx, float dy) { + return mListener.onScroll(dx, dy); + } + + @Override + public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, + float velocityY) { + return mListener.onFling(velocityX, velocityY); + } + } + + private class MyScaleListener + extends ScaleGestureDetector.SimpleOnScaleGestureListener { + @Override + public boolean onScaleBegin(ScaleGestureDetector detector) { + return mListener.onScaleBegin( + detector.getFocusX(), detector.getFocusY()); + } + + @Override + public boolean onScale(ScaleGestureDetector detector) { + return mListener.onScale(detector.getFocusX(), + detector.getFocusY(), detector.getScaleFactor()); + } + + @Override + public void onScaleEnd(ScaleGestureDetector detector) { + mListener.onScaleEnd(); + } + } + + private class MyDownUpListener implements DownUpDetector.DownUpListener { + @Override + public void onDown(MotionEvent e) { + mListener.onDown(); + } + + @Override + public void onUp(MotionEvent e) { + mListener.onUp(); + } + } +} diff --git a/src/com/android/gallery3d/ui/PhotoView.java b/src/com/android/gallery3d/ui/PhotoView.java index 540846086..31e41bff7 100644 --- a/src/com/android/gallery3d/ui/PhotoView.java +++ b/src/com/android/gallery3d/ui/PhotoView.java @@ -21,9 +21,7 @@ import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.RectF; import android.os.Message; -import android.view.GestureDetector; import android.view.MotionEvent; -import android.view.ScaleGestureDetector; import com.android.gallery3d.R; import com.android.gallery3d.app.GalleryActivity; @@ -70,9 +68,7 @@ public class PhotoView extends GLView { // the previous/next image entries private final ScreenNailEntry mScreenNails[] = new ScreenNailEntry[2]; - private final ScaleGestureDetector mScaleDetector; - private final GestureDetector mGestureDetector; - private final DownUpDetector mDownUpDetector; + private final GestureRecognizer mGestureRecognizer; private PhotoTapListener mPhotoTapListener; @@ -137,10 +133,8 @@ public class PhotoView extends GLView { } }; - mGestureDetector = new GestureDetector(context, - new MyGestureListener(), null, true /* ignoreMultitouch */); - mScaleDetector = new ScaleGestureDetector(context, new MyScaleListener()); - mDownUpDetector = new DownUpDetector(new MyDownUpListener()); + mGestureRecognizer = new GestureRecognizer( + context, new MyGestureListener()); for (int i = 0, n = mScreenNails.length; i < n; ++i) { mScreenNails[i] = new ScreenNailEntry(); @@ -274,9 +268,7 @@ public class PhotoView extends GLView { @Override protected boolean onTouch(MotionEvent event) { - mGestureDetector.onTouchEvent(event); - mScaleDetector.onTouchEvent(event); - mDownUpDetector.onTouchEvent(event); + mGestureRecognizer.onTouchEvent(event); return true; } @@ -340,8 +332,6 @@ public class PhotoView extends GLView { @Override protected void render(GLCanvas canvas) { - PositionController p = mPositionController; - // Draw the current photo if (mLoadingState == LOADING_COMPLETE) { super.render(canvas); @@ -392,7 +382,7 @@ public class PhotoView extends GLView { } private void stopCurrentSwipingIfNeeded() { - // Enable fast sweeping + // Enable fast swiping if (mTransitionMode == TRANS_SWITCH_NEXT) { mTransitionMode = TRANS_NONE; mPositionController.stopAnimation(); @@ -472,13 +462,35 @@ public class PhotoView extends GLView { return false; } - private boolean mIgnoreUpEvent = false; + private class MyGestureListener implements GestureRecognizer.Listener { + private boolean mIgnoreUpEvent = false; + + @Override + public boolean onSingleTapUp(float x, float y) { + if (mPhotoTapListener != null) { + mPhotoTapListener.onSingleTapUp((int) x, (int) y); + } + return true; + } + + @Override + public boolean onDoubleTap(float x, float y) { + if (mTransitionMode != TRANS_NONE) return true; + PositionController controller = mPositionController; + float scale = controller.getCurrentScale(); + // onDoubleTap happened on the second ACTION_DOWN. + // We need to ignore the next UP event. + mIgnoreUpEvent = true; + if (scale <= 1.0f || controller.isAtMinimalScale()) { + controller.zoomIn(x, y, Math.max(1.5f, scale * 1.5f)); + } else { + controller.resetToFullView(); + } + return true; + } - private class MyGestureListener - extends GestureDetector.SimpleOnGestureListener { @Override - public boolean onScroll( - MotionEvent e1, MotionEvent e2, float dx, float dy) { + public boolean onScroll(float dx, float dy) { if (mTransitionMode != TRANS_NONE) return true; ScreenNailEntry next = mScreenNails[ENTRY_NEXT]; @@ -490,16 +502,7 @@ public class PhotoView extends GLView { } @Override - public boolean onSingleTapUp(MotionEvent e) { - if (mPhotoTapListener != null) { - mPhotoTapListener.onSingleTapUp((int) e.getX(), (int) e.getY()); - } - return true; - } - - @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, - float velocityY) { + public boolean onFling(float velocityX, float velocityY) { if (swipeImages(velocityX, velocityY)) { mIgnoreUpEvent = true; } else if (mTransitionMode != TRANS_NONE) { @@ -511,48 +514,41 @@ public class PhotoView extends GLView { } @Override - public boolean onDoubleTap(MotionEvent e) { - if (mTransitionMode != TRANS_NONE) return true; - PositionController controller = mPositionController; - float scale = controller.getCurrentScale(); - // onDoubleTap happened on the second ACTION_DOWN. - // We need to ignore the next UP event. - mIgnoreUpEvent = true; - if (scale <= 1.0f || controller.isAtMinimalScale()) { - controller.zoomIn( - e.getX(), e.getY(), Math.max(1.5f, scale * 1.5f)); - } else { - controller.resetToFullView(); - } + public boolean onScaleBegin(float focusX, float focusY) { + if (mTransitionMode != TRANS_NONE) return false; + mPositionController.beginScale(focusX, focusY); return true; } - } - - private class MyScaleListener - extends ScaleGestureDetector.SimpleOnScaleGestureListener { @Override - public boolean onScale(ScaleGestureDetector detector) { - float scale = detector.getScaleFactor(); + public boolean onScale(float focusX, float focusY, float scale) { if (Float.isNaN(scale) || Float.isInfinite(scale) || mTransitionMode != TRANS_NONE) return true; - mPositionController.scaleBy(scale, - detector.getFocusX(), detector.getFocusY()); + mPositionController.scaleBy(scale, focusX, focusY); return true; } @Override - public boolean onScaleBegin(ScaleGestureDetector detector) { - if (mTransitionMode != TRANS_NONE) return false; - mPositionController.beginScale( - detector.getFocusX(), detector.getFocusY()); - return true; + public void onScaleEnd() { + mPositionController.endScale(); + snapToNeighborImage(); } @Override - public void onScaleEnd(ScaleGestureDetector detector) { - mPositionController.endScale(); - snapToNeighborImage(); + public void onDown() { + } + + @Override + public void onUp() { + mEdgeView.onRelease(); + + if (mIgnoreUpEvent) { + mIgnoreUpEvent = false; + return; + } + if (!snapToNeighborImage() && mTransitionMode == TRANS_NONE) { + mPositionController.up(); + } } } @@ -580,23 +576,6 @@ public class PhotoView extends GLView { } } - private class MyDownUpListener implements DownUpDetector.DownUpListener { - public void onDown(MotionEvent e) { - } - - public void onUp(MotionEvent e) { - mEdgeView.onRelease(); - - if (mIgnoreUpEvent) { - mIgnoreUpEvent = false; - return; - } - if (!snapToNeighborImage() && mTransitionMode == TRANS_NONE) { - mPositionController.up(); - } - } - } - private void switchToNextImage() { // We update the texture here directly to prevent texture uploading. ScreenNailEntry prevNail = mScreenNails[ENTRY_PREVIOUS]; @@ -638,7 +617,7 @@ public class PhotoView extends GLView { } public boolean isDown() { - return mDownUpDetector.isDown(); + return mGestureRecognizer.isDown(); } public static interface Model extends TileImageView.Model { -- cgit v1.2.3