From 023755655b91453d574b3afba8835206b52658d3 Mon Sep 17 00:00:00 2001 From: Hannes Janetzek <hannes.janetzek@gmail.com> Date: Thu, 7 Feb 2013 14:24:57 +0100 Subject: [PATCH] fix jumping gestures: update pointer IDs on pointer up/down --- src/org/oscim/view/TouchHandler.java | 134 +++++++++++++++------------ 1 file changed, 74 insertions(+), 60 deletions(-) diff --git a/src/org/oscim/view/TouchHandler.java b/src/org/oscim/view/TouchHandler.java index cd795ef9..7226a043 100644 --- a/src/org/oscim/view/TouchHandler.java +++ b/src/org/oscim/view/TouchHandler.java @@ -67,7 +67,8 @@ final class TouchHandler implements OnGestureListener, OnDoubleTapListener { private double mAngle; - private int mActivePointerId; + private int mPointerId1; + private int mPointerId2; //private final ScaleGestureDetector mScaleGestureDetector; private final GestureDetector mGestureDetector; @@ -93,7 +94,8 @@ final class TouchHandler implements OnGestureListener, OnDoubleTapListener { mOverlayManager = mapView.getOverlayManager(); // ViewConfiguration viewConfiguration = ViewConfiguration.get(context); // mMapMoveDelta = viewConfiguration.getScaledTouchSlop(); - mActivePointerId = INVALID_POINTER_ID; + mPointerId1 = INVALID_POINTER_ID; + mPointerId2 = INVALID_POINTER_ID; //mScaleGestureDetector = new ScaleGestureDetector(context, this); mGestureDetector = new GestureDetector(context, this); mGestureDetector.setOnDoubleTapListener(this); @@ -106,73 +108,58 @@ final class TouchHandler implements OnGestureListener, OnDoubleTapListener { } /** - * @param event + * @param e * ... * @return ... */ - public boolean handleMotionEvent(MotionEvent event) { + public boolean handleMotionEvent(MotionEvent e) { - if (mOverlayManager.onTouchEvent(event, mMapView)) + if (mOverlayManager.onTouchEvent(e, mMapView)) return true; - mGestureDetector.onTouchEvent(event); + mGestureDetector.onTouchEvent(e); //boolean scaling = false; //mScaleGestureDetector.onTouchEvent(event); - int action = getAction(event); + int action = getAction(e); if (action == MotionEvent.ACTION_DOWN) { mMulti = 0; mWasMulti = false; - if (mOverlayManager.onDown(event, mMapView)) + if (mOverlayManager.onDown(e, mMapView)) return true; - return onActionDown(event); + return onActionDown(e); } else if (action == MotionEvent.ACTION_MOVE) { - return onActionMove(event); + return onActionMove(e); } else if (action == MotionEvent.ACTION_UP) { - return onActionUp(event); + return onActionUp(e); } else if (action == MotionEvent.ACTION_CANCEL) { return onActionCancel(); } else if (action == MotionEvent.ACTION_POINTER_DOWN) { - return onActionPointerDown(event); + return onActionPointerDown(e); } else if (action == MotionEvent.ACTION_POINTER_UP) { - return onActionPointerUp(event); + return onActionPointerUp(e); } return false; } - private static int getAction(MotionEvent motionEvent) { - return motionEvent.getAction() & MotionEvent.ACTION_MASK; + private static int getAction(MotionEvent e) { + return e.getAction() & MotionEvent.ACTION_MASK; } private boolean onActionCancel() { - mActivePointerId = INVALID_POINTER_ID; + mPointerId1 = INVALID_POINTER_ID; mLongPress = true; return true; } - private boolean onActionDown(MotionEvent event) { - mPrevX = event.getX(); - mPrevY = event.getY(); - mBeginRotate = false; - mBeginTilt = false; - mBeginScale = false; + private boolean onActionMove(MotionEvent e) { + int id = e.findPointerIndex(mPointerId1); - // save the ID of the pointer - mActivePointerId = event.getPointerId(0); - - return true; - } - - //private boolean mScaling = false; - - private boolean onActionMove(MotionEvent event) { - int id = event.findPointerIndex(mActivePointerId); - - float x1 = event.getX(id); - float y1 = event.getY(id); + float x1 = e.getX(id); + float y1 = e.getY(id); float mx = x1 - mPrevX; float my = y1 - mPrevY; @@ -196,12 +183,14 @@ final class TouchHandler implements OnGestureListener, OnDoubleTapListener { if (mMulti == 0) { // reset pinch variables - mPrevPinchWidth = -1; + //mPrevPinchWidth = -1; return true; } - float x2 = event.getX(1); - float y2 = event.getY(1); + int id2 = e.findPointerIndex(mPointerId2); + + float x2 = e.getX(id2); + float y2 = e.getY(id2); float dx = (x1 - x2); float dy = (y1 - y2); @@ -217,7 +206,7 @@ final class TouchHandler implements OnGestureListener, OnDoubleTapListener { double rad = Math.atan2(dy, dx); double r = rad - mAngle; - boolean startScale = (mPrevPinchWidth > 0 && Math.abs(deltaPinchWidth) > PINCH_ZOOM_THRESHOLD); + boolean startScale = (Math.abs(deltaPinchWidth) > PINCH_ZOOM_THRESHOLD); boolean changed = false; @@ -226,15 +215,16 @@ final class TouchHandler implements OnGestureListener, OnDoubleTapListener { float scale = (float) (pinchWidth / mPrevPinchWidth); + // decrease change of scale by the change of rotation + // * 20 is just arbitrary + if (mBeginRotate) + scale = 1 + ((scale - 1) * Math.max((1 - (float) Math.abs(r) * 20), 0)); + mSumScale *= scale; if (mSumScale < 0.95 || mSumScale > 1.05) mBeginRotate = false; - // decrease change of scale by the change of rotation - // pi * 10 is just arbitrary - scale = 1 + ((scale - 1) * Math.max((1 - (float)(Math.abs(r) * Math.PI) * 10), 0)); - float fx = (x2 + x1) / 2 - width / 2; float fy = (y2 + y1) / 2 - height / 2; @@ -309,24 +299,31 @@ final class TouchHandler implements OnGestureListener, OnDoubleTapListener { mSumScale = 1; if (mMulti == 1) { - mPrevX2 = event.getX(1); - mPrevY2 = event.getY(1); - double dx = event.getX(0) - mPrevX2; - double dy = event.getY(0) - mPrevY2; + int masked = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK); + int pointerIndex = masked >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; + mPointerId2 = event.getPointerId(pointerIndex); + + mPrevX2 = event.getX(pointerIndex); + mPrevY2 = event.getY(pointerIndex); + double dx = mPrevX - mPrevX2; + double dy = mPrevY - mPrevY2; mAngle = Math.atan2(dy, dx); + + mPrevPinchWidth = Math.sqrt(dx * dx + dy * dy); + } // Log.d("...", "mMulti down " + mMulti); return true; } - private boolean onActionPointerUp(MotionEvent motionEvent) { + private boolean onActionPointerUp(MotionEvent e) { // extract the index of the pointer that left the touch sensor - int masked = (motionEvent.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK); + int masked = (e.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK); int pointerIndex = masked >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - if (motionEvent.getPointerId(pointerIndex) == mActivePointerId) { + if (e.getPointerId(pointerIndex) == mPointerId1) { // the active pointer has gone up, choose a new one if (pointerIndex == 0) { pointerIndex = 1; @@ -334,12 +331,18 @@ final class TouchHandler implements OnGestureListener, OnDoubleTapListener { pointerIndex = 0; } // save the position of the event - // mPrevX = motionEvent.getX(pointerIndex); - mPrevY = motionEvent.getY(pointerIndex); - mActivePointerId = motionEvent.getPointerId(pointerIndex); + mPrevX = e.getX(pointerIndex); + mPrevY = e.getY(pointerIndex); + + mPointerId1 = e.getPointerId(pointerIndex); } + mMulti--; + if (mMulti == 0){ + mPointerId2 = INVALID_POINTER_ID; + } + mLongPress = false; // Log.d("...", "mMulti up " + mMulti); @@ -347,18 +350,29 @@ final class TouchHandler implements OnGestureListener, OnDoubleTapListener { return true; } + private boolean onActionDown(MotionEvent e) { + mPrevX = e.getX(); + mPrevY = e.getY(); + + mBeginRotate = false; + mBeginTilt = false; + mBeginScale = false; + + // save the ID of the pointer + mPointerId1 = e.getPointerId(0); + + return true; + } /** - * @param motionEvent - * ... + * @param event + * unused * @return ... */ - private boolean onActionUp(MotionEvent motionEvent) { - mActivePointerId = INVALID_POINTER_ID; - //mScaling = false; + private boolean onActionUp(MotionEvent event) { + mPointerId1 = INVALID_POINTER_ID; + mLongPress = false; - mMulti = 0; - mPrevPinchWidth = -1; mPrevPointerCount = 0;