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

Commit 01755d22 authored by Shu Chen's avatar Shu Chen Committed by Automerger Merge Worker
Browse files

Merge "Calculates the slop values per upper/lower line height." into rvc-dev...

Merge "Calculates the slop values per upper/lower line height." into rvc-dev am: 27daeb03 am: 1bb80852 am: 06e17736

Change-Id: I86b04f6027c2b9952b3e689212b7108640e38fee
parents 4c940479 06e17736
Loading
Loading
Loading
Loading
+36 −21
Original line number Diff line number Diff line
@@ -405,6 +405,13 @@ public class Editor {
    // The actual zoom value may changes based on this initial zoom value.
    private float mInitialZoom = 1f;

    // For calculating the line change slops while moving cursor/selection.
    // The slop max/min value include line height and the slop on the upper/lower line.
    private static final int LINE_CHANGE_SLOP_MAX_DP = 45;
    private static final int LINE_CHANGE_SLOP_MIN_DP = 12;
    private int mLineChangeSlopMax;
    private int mLineChangeSlopMin;

    Editor(TextView textView) {
        mTextView = textView;
        // Synchronize the filter list, which places the undo input filter at the end.
@@ -430,6 +437,14 @@ public class Editor {
            logCursor("Editor", "New magnifier is %s.",
                    mNewMagnifierEnabled ? "enabled" : "disabled");
        }

        mLineChangeSlopMax = (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, LINE_CHANGE_SLOP_MAX_DP,
                mTextView.getContext().getResources().getDisplayMetrics());
        mLineChangeSlopMin = (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, LINE_CHANGE_SLOP_MIN_DP,
                mTextView.getContext().getResources().getDisplayMetrics());

    }

    @VisibleForTesting
@@ -6018,7 +6033,14 @@ public class Editor {
        }
    }

    private int getCurrentLineAdjustedForSlop(Layout layout, int prevLine, float y) {
    @VisibleForTesting
    public void setLineChangeSlopMinMaxForTesting(final int min, final int max) {
        mLineChangeSlopMin = min;
        mLineChangeSlopMax = max;
    }

    @VisibleForTesting
    public int getCurrentLineAdjustedForSlop(Layout layout, int prevLine, float y) {
        final int trueLine = mTextView.getLineAtCoordinate(y);
        if (layout == null || prevLine > layout.getLineCount()
                || layout.getLineCount() <= 0 || prevLine < 0) {
@@ -6031,28 +6053,21 @@ public class Editor {
            return trueLine;
        }

        final int lineHeight = layout.getLineBottom(prevLine) - layout.getLineTop(prevLine);
        int slop = (int)(LINE_SLOP_MULTIPLIER_FOR_HANDLEVIEWS
                * (layout.getLineBottom(trueLine) - layout.getLineTop(trueLine)));
        slop = Math.max(mLineChangeSlopMin,
                Math.min(mLineChangeSlopMax, lineHeight + slop)) - lineHeight;
        slop = Math.max(0, slop);

        final float verticalOffset = mTextView.viewportToContentVerticalOffset();
        final int lineCount = layout.getLineCount();
        final float slop = mTextView.getLineHeight() * LINE_SLOP_MULTIPLIER_FOR_HANDLEVIEWS;

        final float firstLineTop = layout.getLineTop(0) + verticalOffset;
        final float prevLineTop = layout.getLineTop(prevLine) + verticalOffset;
        final float yTopBound = Math.max(prevLineTop - slop, firstLineTop + slop);

        final float lastLineBottom = layout.getLineBottom(lineCount - 1) + verticalOffset;
        final float prevLineBottom = layout.getLineBottom(prevLine) + verticalOffset;
        final float yBottomBound = Math.min(prevLineBottom + slop, lastLineBottom - slop);

        // Determine if we've moved lines based on y position and previous line.
        int currLine;
        if (y <= yTopBound) {
            currLine = Math.max(prevLine - 1, 0);
        } else if (y >= yBottomBound) {
            currLine = Math.min(prevLine + 1, lineCount - 1);
        } else {
            currLine = prevLine;
        if (trueLine > prevLine && y >= layout.getLineBottom(prevLine) + slop + verticalOffset) {
            return trueLine;
        }
        if (trueLine < prevLine && y <= layout.getLineTop(prevLine) - slop + verticalOffset) {
            return trueLine;
        }
        return currLine;
        return prevLine;
    }

    /**
+36 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.widget;

import static android.text.Spanned.SPAN_INCLUSIVE_EXCLUSIVE;
import static android.widget.espresso.TextViewActions.clickOnTextAtIndex;
import static android.widget.espresso.TextViewActions.dragOnText;
import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex;
@@ -37,6 +38,9 @@ import android.app.Activity;
import android.app.Instrumentation;
import android.graphics.Rect;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.AbsoluteSizeSpan;
import android.util.ArraySet;
import android.util.Log;
import android.view.InputDevice;
@@ -488,6 +492,38 @@ public class EditorCursorDragTest {
        simulateDrag(tv, events, true);
    }

    @Test
    public void testLineChangeSlop() throws Throwable {
        TextView tv = mActivity.findViewById(R.id.textview);
        Spannable s = new SpannableString("a\nb\nc");
        s.setSpan(new AbsoluteSizeSpan(10), 2, 4, SPAN_INCLUSIVE_EXCLUSIVE);
        s.setSpan(new AbsoluteSizeSpan(32), 4, 5, SPAN_INCLUSIVE_EXCLUSIVE);
        mInstrumentation.runOnMainSync(() -> tv.setText(s));

        Layout layout = tv.getLayout();
        Editor editor = tv.getEditorForTesting();
        final float verticalOffset = tv.getExtendedPaddingTop();
        editor.setLineChangeSlopMinMaxForTesting(30, 65);
        // Hit top part of upper line, jump to upper line.
        assertThat(editor.getCurrentLineAdjustedForSlop(layout, 1, 5 + verticalOffset))
                .isEqualTo(0);
        // Hit bottom part of upper line, stay at current line.
        assertThat(editor.getCurrentLineAdjustedForSlop(layout, 1, 40 + verticalOffset))
                .isEqualTo(1);
        // Hit current line, stay at current line.
        assertThat(editor.getCurrentLineAdjustedForSlop(layout, 1, 70 + verticalOffset))
                .isEqualTo(1);
        // Hit top part of lower line, stay at current line.
        assertThat(editor.getCurrentLineAdjustedForSlop(layout, 1, 85 + verticalOffset))
                .isEqualTo(1);
        // Hit bottom part of lower line, jump to lower line.
        assertThat(editor.getCurrentLineAdjustedForSlop(layout, 1, 110 + verticalOffset))
                .isEqualTo(2);
        // Hit lower line of lower line, jump to target line.
        assertThat(editor.getCurrentLineAdjustedForSlop(layout, 0, 110 + verticalOffset))
                .isEqualTo(2);
    }

    @Test
    public void testCursorDrag_snapDistance() throws Throwable {
        String text = "line1: This is the 1st line: A\n"