From b499884ba1fa9577363524d1f28100627926d3b6 Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Sun, 23 Sep 2012 17:18:17 -0700 Subject: Better handling of multiple touch events in GlowPadView This fixes a bug where a secondary touch event from the edge of the screen would cause GlowPadView to choose the wrong target. The issue is resolved by keeping track of pointer ids and only allowing the one that initiated the gesture to complete it. Fixes bug 7133500 Change-Id: If296b60af2421bfa1a9a082e608ba77b2392a218 --- .../internal/widget/multiwaveview/GlowPadView.java | 33 +++++++++++++++++----- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java index 421e247cf52b..87ad01fc4315 100644 --- a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java +++ b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java @@ -197,6 +197,7 @@ public class GlowPadView extends View { private Tweener mBackgroundAnimator; private PointCloud mPointCloud; private float mInnerRadius; + private int mPointerId; public GlowPadView(Context context) { this(context, null); @@ -737,9 +738,10 @@ public class GlowPadView extends View { @Override public boolean onTouchEvent(MotionEvent event) { - final int action = event.getAction(); + final int action = event.getActionMasked(); boolean handled = false; switch (action) { + case MotionEvent.ACTION_POINTER_DOWN: case MotionEvent.ACTION_DOWN: if (DEBUG) Log.v(TAG, "*** DOWN ***"); handleDown(event); @@ -753,6 +755,7 @@ public class GlowPadView extends View { handled = true; break; + case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_UP: if (DEBUG) Log.v(TAG, "*** UP ***"); handleMove(event); @@ -766,6 +769,7 @@ public class GlowPadView extends View { handleCancel(event); handled = true; break; + } invalidate(); return handled ? true : super.onTouchEvent(event); @@ -777,19 +781,24 @@ public class GlowPadView extends View { } private void handleDown(MotionEvent event) { - float eventX = event.getX(); - float eventY = event.getY(); + int actionIndex = event.getActionIndex(); + float eventX = event.getX(actionIndex); + float eventY = event.getY(actionIndex); switchToState(STATE_START, eventX, eventY); if (!trySwitchToFirstTouchState(eventX, eventY)) { mDragging = false; } else { + mPointerId = event.getPointerId(actionIndex); updateGlowPosition(eventX, eventY); } } private void handleUp(MotionEvent event) { if (DEBUG && mDragging) Log.v(TAG, "** Handle RELEASE"); - switchToState(STATE_FINISH, event.getX(), event.getY()); + int actionIndex = event.getActionIndex(); + if (event.getPointerId(actionIndex) == mPointerId) { + switchToState(STATE_FINISH, event.getX(actionIndex), event.getY(actionIndex)); + } } private void handleCancel(MotionEvent event) { @@ -802,7 +811,9 @@ public class GlowPadView extends View { // mActiveTarget = -1; // Drop the active target if canceled. - switchToState(STATE_FINISH, event.getX(), event.getY()); + int actionIndex = event.findPointerIndex(mPointerId); + actionIndex = actionIndex == -1 ? 0 : actionIndex; + switchToState(STATE_FINISH, event.getX(actionIndex), event.getY(actionIndex)); } private void handleMove(MotionEvent event) { @@ -812,9 +823,17 @@ public class GlowPadView extends View { int ntargets = targets.size(); float x = 0.0f; float y = 0.0f; + int actionIndex = event.findPointerIndex(mPointerId); + + if (actionIndex == -1) { + return; // no data for this pointer + } + for (int k = 0; k < historySize + 1; k++) { - float eventX = k < historySize ? event.getHistoricalX(k) : event.getX(); - float eventY = k < historySize ? event.getHistoricalY(k) : event.getY(); + float eventX = k < historySize ? event.getHistoricalX(actionIndex, k) + : event.getX(actionIndex); + float eventY = k < historySize ? event.getHistoricalY(actionIndex, k) + : event.getY(actionIndex); // tx and ty are relative to wave center float tx = eventX - mWaveCenterX; float ty = eventY - mWaveCenterY; -- cgit v1.2.3-59-g8ed1b