diff options
Diffstat (limited to 'src/com/android/camera/PreviewGestures.java')
-rw-r--r-- | src/com/android/camera/PreviewGestures.java | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/src/com/android/camera/PreviewGestures.java b/src/com/android/camera/PreviewGestures.java new file mode 100644 index 000000000..466172b7c --- /dev/null +++ b/src/com/android/camera/PreviewGestures.java @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2013 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.camera; + +import android.view.GestureDetector; +import android.view.MotionEvent; +import android.view.ScaleGestureDetector; +import android.view.View; + +import com.android.camera.ui.PieRenderer; +import com.android.camera.ui.RenderOverlay; +import com.android.camera.ui.ZoomRenderer; + +/* PreviewGestures disambiguates touch events received on RenderOverlay + * and dispatch them to the proper recipient (i.e. zoom renderer or pie renderer). + * Touch events on CameraControls will be handled by framework. + * */ +public class PreviewGestures + implements ScaleGestureDetector.OnScaleGestureListener { + + private static final String TAG = "CAM_gestures"; + + private static final int MODE_NONE = 0; + private static final int MODE_ZOOM = 2; + + public static final int DIR_UP = 0; + public static final int DIR_DOWN = 1; + public static final int DIR_LEFT = 2; + public static final int DIR_RIGHT = 3; + + private SingleTapListener mTapListener; + private RenderOverlay mOverlay; + private PieRenderer mPie; + private ZoomRenderer mZoom; + private MotionEvent mDown; + private MotionEvent mCurrent; + private ScaleGestureDetector mScale; + private int mMode; + private boolean mZoomEnabled; + private boolean mEnabled; + private boolean mZoomOnly; + private GestureDetector mGestureDetector; + + private GestureDetector.SimpleOnGestureListener mGestureListener = new GestureDetector.SimpleOnGestureListener() { + @Override + public void onLongPress (MotionEvent e) { + // Open pie + if (!mZoomOnly && mPie != null && !mPie.showsItems()) { + openPie(); + } + } + + @Override + public boolean onSingleTapUp (MotionEvent e) { + // Tap to focus when pie is not open + if (mPie == null || !mPie.showsItems()) { + mTapListener.onSingleTapUp(null, (int) e.getX(), (int) e.getY()); + return true; + } + return false; + } + + @Override + public boolean onScroll (MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + if (mZoomOnly || mMode == MODE_ZOOM) return false; + int deltaX = (int) (e1.getX() - e2.getX()); + int deltaY = (int) (e1.getY() - e2.getY()); + if (deltaY > 2 * deltaX && deltaY > -2 * deltaX) { + // Open pie on swipe up + if (mPie != null && !mPie.showsItems()) { + openPie(); + return true; + } + } + return false; + } + }; + + public interface SingleTapListener { + public void onSingleTapUp(View v, int x, int y); + } + + public PreviewGestures(CameraActivity ctx, SingleTapListener tapListener, + ZoomRenderer zoom, PieRenderer pie) { + mTapListener = tapListener; + mPie = pie; + mZoom = zoom; + mMode = MODE_NONE; + mScale = new ScaleGestureDetector(ctx, this); + mEnabled = true; + mGestureDetector = new GestureDetector(mGestureListener); + } + + public void setRenderOverlay(RenderOverlay overlay) { + mOverlay = overlay; + } + + public void setEnabled(boolean enabled) { + mEnabled = enabled; + } + + public void setZoomEnabled(boolean enable) { + mZoomEnabled = enable; + } + + public void setZoomOnly(boolean zoom) { + mZoomOnly = zoom; + } + + public boolean isEnabled() { + return mEnabled; + } + + public boolean dispatchTouch(MotionEvent m) { + if (!mEnabled) { + return false; + } + mCurrent = m; + if (MotionEvent.ACTION_DOWN == m.getActionMasked()) { + mMode = MODE_NONE; + mDown = MotionEvent.obtain(m); + } + + // If pie is open, redirects all the touch events to pie. + if (mPie != null && mPie.isOpen()) { + return sendToPie(m); + } + + // If pie is not open, send touch events to gesture detector and scale + // listener to recognize the gesture. + mGestureDetector.onTouchEvent(m); + if (mZoom != null) { + mScale.onTouchEvent(m); + if (MotionEvent.ACTION_POINTER_DOWN == m.getActionMasked()) { + mMode = MODE_ZOOM; + if (mZoomEnabled) { + // Start showing zoom UI as soon as there is a second finger down + mZoom.onScaleBegin(mScale); + } + } else if (MotionEvent.ACTION_POINTER_UP == m.getActionMasked()) { + mZoom.onScaleEnd(mScale); + } + } + return true; + } + + private MotionEvent makeCancelEvent(MotionEvent m) { + MotionEvent c = MotionEvent.obtain(m); + c.setAction(MotionEvent.ACTION_CANCEL); + return c; + } + + private void openPie() { + mGestureDetector.onTouchEvent(makeCancelEvent(mDown)); + mScale.onTouchEvent(makeCancelEvent(mDown)); + mOverlay.directDispatchTouch(mDown, mPie); + } + + private boolean sendToPie(MotionEvent m) { + return mOverlay.directDispatchTouch(m, mPie); + } + + // OnScaleGestureListener implementation + @Override + public boolean onScale(ScaleGestureDetector detector) { + return mZoom.onScale(detector); + } + + @Override + public boolean onScaleBegin(ScaleGestureDetector detector) { + if (mPie == null || !mPie.isOpen()) { + mMode = MODE_ZOOM; + mGestureDetector.onTouchEvent(makeCancelEvent(mCurrent)); + if (!mZoomEnabled) return false; + return mZoom.onScaleBegin(detector); + } + return false; + } + + @Override + public void onScaleEnd(ScaleGestureDetector detector) { + mZoom.onScaleEnd(detector); + } +} + |