Move double tap/triple click detection to Editor.

The logic was in TextView, but it's only for Editor.
Move it to Editor and have constants for the state.

Bug: 19544351
Change-Id: I391f66753aa5cbb26fbefcba5b4e7e3d917454e2
This commit is contained in:
Keisuke Kuroyanagi
2015-11-05 19:10:07 +09:00
parent 2b69da5183
commit 155aecb18b
2 changed files with 41 additions and 37 deletions

View File

@@ -230,8 +230,14 @@ public class Editor {
// Set when this TextView gained focus with some text selected. Will start selection mode.
boolean mCreatedWithASelection;
boolean mDoubleTap = false;
boolean mTripleClick = false;
// Indicates the current tap state (first tap, double tap, or triple click).
private int mTapState = TAP_STATE_INITIAL;
private long mLastTouchUpTime = 0;
private static final int TAP_STATE_INITIAL = 0;
private static final int TAP_STATE_FIRST_TAP = 1;
private static final int TAP_STATE_DOUBLE_TAP = 2;
// Only for mouse input.
private static final int TAP_STATE_TRIPLE_CLICK = 3;
private Runnable mInsertionActionModeRunnable;
@@ -1285,7 +1291,31 @@ public class Editor {
}
}
private void updateTapState(MotionEvent event) {
final int action = event.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
final boolean isMouse = event.isFromSource(InputDevice.SOURCE_MOUSE);
// Detect double tap and triple click.
if (((mTapState == TAP_STATE_FIRST_TAP)
|| ((mTapState == TAP_STATE_DOUBLE_TAP) && isMouse))
&& (SystemClock.uptimeMillis() - mLastTouchUpTime) <=
ViewConfiguration.getDoubleTapTimeout()) {
if (mTapState == TAP_STATE_FIRST_TAP) {
mTapState = TAP_STATE_DOUBLE_TAP;
} else {
mTapState = TAP_STATE_TRIPLE_CLICK;
}
} else {
mTapState = TAP_STATE_FIRST_TAP;
}
}
if (action == MotionEvent.ACTION_UP) {
mLastTouchUpTime = SystemClock.uptimeMillis();
}
}
void onTouchEvent(MotionEvent event) {
updateTapState(event);
updateFloatingToolbarVisibility(event);
if (hasSelectionController()) {
@@ -3976,13 +4006,16 @@ public class Editor {
// Cancel the single tap delayed runnable.
if (mInsertionActionModeRunnable != null
&& (mDoubleTap || mTripleClick || isCursorInsideEasyCorrectionSpan())) {
&& ((mTapState == TAP_STATE_DOUBLE_TAP)
|| (mTapState == TAP_STATE_TRIPLE_CLICK)
|| isCursorInsideEasyCorrectionSpan())) {
mTextView.removeCallbacks(mInsertionActionModeRunnable);
}
// Prepare and schedule the single tap runnable to run exactly after the double tap
// timeout has passed.
if (!mDoubleTap && !mTripleClick && !isCursorInsideEasyCorrectionSpan()
if ((mTapState != TAP_STATE_DOUBLE_TAP) && (mTapState != TAP_STATE_TRIPLE_CLICK)
&& !isCursorInsideEasyCorrectionSpan()
&& (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION)) {
if (mTextActionMode == null) {
if (mInsertionActionModeRunnable == null) {
@@ -4636,7 +4669,8 @@ public class Editor {
// Double tap detection
if (mGestureStayedInTapRegion) {
if (mDoubleTap || mTripleClick) {
if (mTapState == TAP_STATE_DOUBLE_TAP
|| mTapState == TAP_STATE_TRIPLE_CLICK) {
final float deltaX = eventX - mDownPositionX;
final float deltaY = eventY - mDownPositionY;
final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
@@ -4648,9 +4682,9 @@ public class Editor {
distanceSquared < doubleTapSlop * doubleTapSlop;
if (stayedInArea && (isMouse || isPositionOnText(eventX, eventY))) {
if (mDoubleTap) {
if (mTapState == TAP_STATE_DOUBLE_TAP) {
selectCurrentWordAndStartDrag();
} else if (mTripleClick) {
} else if (mTapState == TAP_STATE_TRIPLE_CLICK) {
selectCurrentParagraphAndStartDrag();
}
mDiscardNextActionUp = true;

View File

@@ -618,9 +618,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private final Paint mHighlightPaint;
private boolean mHighlightPathBogus = true;
private boolean mFirstTouch = false;
private long mLastTouchUpTime = 0;
// Although these fields are specific to editable text, they are not added to Editor because
// they are defined by the TextView's style and are theme-dependent.
int mCursorDrawableRes;
@@ -8406,33 +8403,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
if (mEditor != null && action == MotionEvent.ACTION_DOWN) {
final boolean isMouse = event.isFromSource(InputDevice.SOURCE_MOUSE);
// Detect double tap and triple click and inform the Editor.
if ((mFirstTouch || (mEditor.mDoubleTap && isMouse))
&& (SystemClock.uptimeMillis() - mLastTouchUpTime) <=
ViewConfiguration.getDoubleTapTimeout()) {
if (mFirstTouch) {
mEditor.mTripleClick = false;
mEditor.mDoubleTap = true;
mFirstTouch = false;
} else {
mEditor.mTripleClick = true;
mEditor.mDoubleTap = false;
mFirstTouch = false;
}
} else {
mEditor.mTripleClick = false;
mEditor.mDoubleTap = false;
mFirstTouch = true;
}
}
if (action == MotionEvent.ACTION_UP) {
mLastTouchUpTime = SystemClock.uptimeMillis();
}
if (mEditor != null) {
mEditor.onTouchEvent(event);