diff options
Diffstat (limited to 'remoting/android')
-rw-r--r-- | remoting/android/java/src/org/chromium/chromoting/TapGestureDetector.java | 59 | ||||
-rw-r--r-- | remoting/android/java/src/org/chromium/chromoting/TrackingInputHandler.java | 71 |
2 files changed, 100 insertions, 30 deletions
diff --git a/remoting/android/java/src/org/chromium/chromoting/TapGestureDetector.java b/remoting/android/java/src/org/chromium/chromoting/TapGestureDetector.java index c0c2843..fa30b02 100644 --- a/remoting/android/java/src/org/chromium/chromoting/TapGestureDetector.java +++ b/remoting/android/java/src/org/chromium/chromoting/TapGestureDetector.java @@ -6,15 +6,16 @@ package org.chromium.chromoting; import android.content.Context; import android.graphics.PointF; -import android.util.Log; +import android.os.Handler; +import android.os.Message; import android.view.MotionEvent; import android.view.ViewConfiguration; import java.util.HashMap; /** - * This class detects multi-finger tap events. This is provided since the stock Android - * gesture-detectors only detect taps made with one finger. + * This class detects multi-finger tap and long-press events. This is provided since the stock + * Android gesture-detectors only detect taps/long-presses made with one finger. */ public class TapGestureDetector { /** The listener for receiving notifications of tap gestures. */ @@ -26,11 +27,21 @@ public class TapGestureDetector { * @return True if the event is consumed. */ boolean onTap(int pointerCount); + + /** + * Notified when a long-touch event occurs. + * + * @param pointerCount The number of fingers held down. + */ + void onLongPress(int pointerCount); } /** The listener to which notifications are sent. */ private OnTapListener mListener; + /** Handler used for posting tasks to be executed in the future. */ + private Handler mHandler; + /** The maximum number of fingers seen in the gesture. */ private int mPointerCount = 0; @@ -46,11 +57,20 @@ public class TapGestureDetector { */ private int mTouchSlopSquare; - /** Set to true whenever motion is detected in the gesture. */ - private boolean mMotionOccurred = false; + /** Set to true whenever motion is detected in the gesture, or a long-touch is triggered. */ + private boolean mTapCancelled = false; + + private class EventHandler extends Handler { + @Override + public void handleMessage(Message message) { + mListener.onLongPress(mPointerCount); + mTapCancelled = true; + } + } public TapGestureDetector(Context context, OnTapListener listener) { mListener = listener; + mHandler = new EventHandler(); ViewConfiguration config = ViewConfiguration.get(context); int touchSlop = config.getScaledTouchSlop(); mTouchSlopSquare = touchSlop * touchSlop; @@ -61,30 +81,41 @@ public class TapGestureDetector { boolean handled = false; switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: + reset(); + // Cause a long-press notification to be triggered after the timeout. + mHandler.sendEmptyMessageDelayed(0, ViewConfiguration.getLongPressTimeout()); + trackDownEvent(event); + mPointerCount = 1; + break; + case MotionEvent.ACTION_POINTER_DOWN: trackDownEvent(event); mPointerCount = Math.max(mPointerCount, event.getPointerCount()); break; case MotionEvent.ACTION_MOVE: - if (!mMotionOccurred) { - mMotionOccurred = trackMoveEvent(event); + if (!mTapCancelled) { + if (trackMoveEvent(event)) { + cancelLongTouchNotification(); + mTapCancelled = true; + } } break; case MotionEvent.ACTION_UP: - if (!mMotionOccurred) { + cancelLongTouchNotification(); + if (!mTapCancelled) { handled = mListener.onTap(mPointerCount); } - reset(); break; case MotionEvent.ACTION_POINTER_UP: + cancelLongTouchNotification(); trackUpEvent(event); break; case MotionEvent.ACTION_CANCEL: - reset(); + cancelLongTouchNotification(); break; default: @@ -144,8 +175,14 @@ public class TapGestureDetector { /** Cleans up any stored data for the gesture. */ private void reset() { + cancelLongTouchNotification(); mPointerCount = 0; mInitialPositions.clear(); - mMotionOccurred = false; + mTapCancelled = false; + } + + /** Cancels any pending long-touch notifications from the message-queue. */ + private void cancelLongTouchNotification() { + mHandler.removeMessages(0); } } diff --git a/remoting/android/java/src/org/chromium/chromoting/TrackingInputHandler.java b/remoting/android/java/src/org/chromium/chromoting/TrackingInputHandler.java index 92c1dec..4bddec5 100644 --- a/remoting/android/java/src/org/chromium/chromoting/TrackingInputHandler.java +++ b/remoting/android/java/src/org/chromium/chromoting/TrackingInputHandler.java @@ -58,6 +58,9 @@ public class TrackingInputHandler implements TouchInputHandler { */ private float mSwipeThreshold; + /** Mouse-button currently held down, or BUTTON_UNDEFINED otherwise. */ + private int mHeldButton = BUTTON_UNDEFINED; + public TrackingInputHandler(DesktopViewInterface viewer, Context context, RenderData renderData) { mViewer = viewer; @@ -211,19 +214,36 @@ public class TrackingInputHandler implements TouchInputHandler { return false; } + + /** Injects a button-up event if the button is currently held down (during a drag event). */ + private void releaseAnyHeldButton() { + if (mHeldButton != BUTTON_UNDEFINED) { + injectButtonEvent(mHeldButton, false); + mHeldButton = BUTTON_UNDEFINED; + } + } + @Override public boolean onTouchEvent(MotionEvent event) { - // Avoid short-circuit logic evaluation - ensure both gesture detectors see all events so + // Avoid short-circuit logic evaluation - ensure all gesture detectors see all events so // that they generate correct notifications. boolean handled = mScroller.onTouchEvent(event); handled |= mZoomer.onTouchEvent(event); handled |= mTapDetector.onTouchEvent(event); - if (event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { - mTotalMotionY = 0; - mSwipeCompleted = false; - } + switch (event.getActionMasked()) { + case MotionEvent.ACTION_POINTER_DOWN: + mTotalMotionY = 0; + mSwipeCompleted = false; + break; + case MotionEvent.ACTION_UP: + releaseAnyHeldButton(); + break; + + default: + break; + } return handled; } @@ -314,27 +334,40 @@ public class TrackingInputHandler implements TouchInputHandler { onScale(detector); } - /** Called when the user taps the screen with one or more fingers. */ - @Override - public boolean onTap(int pointerCount) { - int button; + /** Maps the number of fingers in a tap or long-press gesture to a mouse-button. */ + private int mouseButtonFromPointerCount(int pointerCount) { switch (pointerCount) { case 1: - button = BUTTON_LEFT; - break; + return BUTTON_LEFT; case 2: - button = BUTTON_RIGHT; - break; + return BUTTON_RIGHT; case 3: - button = BUTTON_MIDDLE; - break; + return BUTTON_MIDDLE; default: - return false; + return BUTTON_UNDEFINED; } + } - injectButtonEvent(button, true); - injectButtonEvent(button, false); - return true; + /** Called when the user taps the screen with one or more fingers. */ + @Override + public boolean onTap(int pointerCount) { + int button = mouseButtonFromPointerCount(pointerCount); + if (button == BUTTON_UNDEFINED) { + return false; + } else { + injectButtonEvent(button, true); + injectButtonEvent(button, false); + return true; + } + } + + /** Called when a long-press is triggered for one or more fingers. */ + @Override + public void onLongPress(int pointerCount) { + mHeldButton = mouseButtonFromPointerCount(pointerCount); + if (mHeldButton != BUTTON_UNDEFINED) { + injectButtonEvent(mHeldButton, true); + } } } } |