Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 155aecb1 authored by Keisuke Kuroyanagi's avatar Keisuke Kuroyanagi
Browse files

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
parent 2b69da51
Loading
Loading
Loading
Loading
+41 −7
Original line number Original line Diff line number Diff line
@@ -230,8 +230,14 @@ public class Editor {
    // Set when this TextView gained focus with some text selected. Will start selection mode.
    // Set when this TextView gained focus with some text selected. Will start selection mode.
    boolean mCreatedWithASelection;
    boolean mCreatedWithASelection;


    boolean mDoubleTap = false;
    // Indicates the current tap state (first tap, double tap, or triple click).
    boolean mTripleClick = false;
    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;
    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) {
    void onTouchEvent(MotionEvent event) {
        updateTapState(event);
        updateFloatingToolbarVisibility(event);
        updateFloatingToolbarVisibility(event);


        if (hasSelectionController()) {
        if (hasSelectionController()) {
@@ -3976,13 +4006,16 @@ public class Editor {


            // Cancel the single tap delayed runnable.
            // Cancel the single tap delayed runnable.
            if (mInsertionActionModeRunnable != null
            if (mInsertionActionModeRunnable != null
                    && (mDoubleTap || mTripleClick || isCursorInsideEasyCorrectionSpan())) {
                    && ((mTapState == TAP_STATE_DOUBLE_TAP)
                            || (mTapState == TAP_STATE_TRIPLE_CLICK)
                            || isCursorInsideEasyCorrectionSpan())) {
                mTextView.removeCallbacks(mInsertionActionModeRunnable);
                mTextView.removeCallbacks(mInsertionActionModeRunnable);
            }
            }


            // Prepare and schedule the single tap runnable to run exactly after the double tap
            // Prepare and schedule the single tap runnable to run exactly after the double tap
            // timeout has passed.
            // timeout has passed.
            if (!mDoubleTap && !mTripleClick && !isCursorInsideEasyCorrectionSpan()
            if ((mTapState != TAP_STATE_DOUBLE_TAP) && (mTapState != TAP_STATE_TRIPLE_CLICK)
                    && !isCursorInsideEasyCorrectionSpan()
                    && (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION)) {
                    && (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION)) {
                if (mTextActionMode == null) {
                if (mTextActionMode == null) {
                    if (mInsertionActionModeRunnable == null) {
                    if (mInsertionActionModeRunnable == null) {
@@ -4636,7 +4669,8 @@ public class Editor {


                        // Double tap detection
                        // Double tap detection
                        if (mGestureStayedInTapRegion) {
                        if (mGestureStayedInTapRegion) {
                            if (mDoubleTap || mTripleClick) {
                            if (mTapState == TAP_STATE_DOUBLE_TAP
                                    || mTapState == TAP_STATE_TRIPLE_CLICK) {
                                final float deltaX = eventX - mDownPositionX;
                                final float deltaX = eventX - mDownPositionX;
                                final float deltaY = eventY - mDownPositionY;
                                final float deltaY = eventY - mDownPositionY;
                                final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
                                final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
@@ -4648,9 +4682,9 @@ public class Editor {
                                        distanceSquared < doubleTapSlop * doubleTapSlop;
                                        distanceSquared < doubleTapSlop * doubleTapSlop;


                                if (stayedInArea && (isMouse || isPositionOnText(eventX, eventY))) {
                                if (stayedInArea && (isMouse || isPositionOnText(eventX, eventY))) {
                                    if (mDoubleTap) {
                                    if (mTapState == TAP_STATE_DOUBLE_TAP) {
                                        selectCurrentWordAndStartDrag();
                                        selectCurrentWordAndStartDrag();
                                    } else if (mTripleClick) {
                                    } else if (mTapState == TAP_STATE_TRIPLE_CLICK) {
                                        selectCurrentParagraphAndStartDrag();
                                        selectCurrentParagraphAndStartDrag();
                                    }
                                    }
                                    mDiscardNextActionUp = true;
                                    mDiscardNextActionUp = true;
+0 −30
Original line number Original line Diff line number Diff line
@@ -618,9 +618,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    private final Paint mHighlightPaint;
    private final Paint mHighlightPaint;
    private boolean mHighlightPathBogus = true;
    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
    // 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.
    // they are defined by the TextView's style and are theme-dependent.
    int mCursorDrawableRes;
    int mCursorDrawableRes;
@@ -8406,33 +8403,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    @Override
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    public boolean onTouchEvent(MotionEvent event) {
        final int action = event.getActionMasked();
        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) {
        if (mEditor != null) {
            mEditor.onTouchEvent(event);
            mEditor.onTouchEvent(event);