summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/PreviewGestures.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/camera/PreviewGestures.java')
-rw-r--r--src/com/android/camera/PreviewGestures.java199
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);
+ }
+}
+