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

Commit beb6e668 authored by Mady Mellor's avatar Mady Mellor Committed by Android (Google) Code Review
Browse files

Merge "Allow text selection handles to scroll horizontally" into mnc-dev

parents ee2a16b5 42390aab
Loading
Loading
Loading
Loading
+102 −18
Original line number Diff line number Diff line
@@ -4060,9 +4060,17 @@ public class Editor {
        private float mPrevX;
        // Indicates if the handle has moved a boundary between LTR and RTL text.
        private boolean mLanguageDirectionChanged = false;
        // Distance from edge of horizontally scrolling text view
        // to use to switch to character mode.
        private final float mTextViewEdgeSlop;
        // Used to save text view location.
        private final int[] mTextViewLocation = new int[2];

        public SelectionStartHandleView(Drawable drawableLtr, Drawable drawableRtl) {
            super(drawableLtr, drawableRtl);
            ViewConfiguration viewConfiguration = ViewConfiguration.get(
                    mTextView.getContext());
            mTextViewEdgeSlop = viewConfiguration.getScaledTouchSlop() * 4;
        }

        @Override
@@ -4100,7 +4108,7 @@ public class Editor {
            if (layout == null) {
                // HandleView will deal appropriately in positionAtCursorOffset when
                // layout is null.
                positionAtCursorOffset(mTextView.getOffsetForPosition(x, y), false);
                positionAndAdjustForCrossingHandles(mTextView.getOffsetForPosition(x, y));
                return;
            }

@@ -4142,12 +4150,12 @@ public class Editor {
                // to the current position.
                mLanguageDirectionChanged = true;
                mTouchWordDelta = 0.0f;
                positionAtCursorOffset(offset, false);
                positionAndAdjustForCrossingHandles(offset);
                return;
            } else if (mLanguageDirectionChanged && !isLvlBoundary) {
                // We've just moved past the boundary so update the position. After this we can
                // figure out if the user is expanding or shrinking to go by word or character.
                positionAtCursorOffset(offset, false);
                positionAndAdjustForCrossingHandles(offset);
                mTouchWordDelta = 0.0f;
                mLanguageDirectionChanged = false;
                return;
@@ -4160,6 +4168,21 @@ public class Editor {
                }
            }

            if (mTextView.getHorizontallyScrolling()) {
                if (positionNearEdgeOfScrollingView(x, atRtl)
                        && (mTextView.getScrollX() != 0)
                        && ((isExpanding && offset < selectionStart) || !isExpanding)) {
                    // If we're expanding ensure that the offset is smaller than the
                    // selection start, if the handle snapped to the word, the finger position
                    // may be out of sync and we don't want the selection to jump back.
                    mTouchWordDelta = 0.0f;
                    final int nextOffset = atRtl ? layout.getOffsetToRightOf(mPreviousOffset)
                            : layout.getOffsetToLeftOf(mPreviousOffset);
                    positionAndAdjustForCrossingHandles(nextOffset);
                    return;
                }
            }

            if (isExpanding) {
                // User is increasing the selection.
                if (!mInWord || currLine < mPrevLine) {
@@ -4215,16 +4238,21 @@ public class Editor {
            }

            if (positionCursor) {
                // Handles can not cross and selection is at least one character.
                mPreviousLineTouched = currLine;
                positionAndAdjustForCrossingHandles(offset);
            }
            mPrevX = x;
        }

        private void positionAndAdjustForCrossingHandles(int offset) {
            final int selectionEnd = mTextView.getSelectionEnd();
            if (offset >= selectionEnd) {
                // Handles can not cross and selection is at least one character.
                offset = getNextCursorOffset(selectionEnd, false);
                mTouchWordDelta = 0.0f;
            }
                mPreviousLineTouched = currLine;
            positionAtCursorOffset(offset, false);
        }
            mPrevX = x;
        }

        @Override
        protected void positionAtCursorOffset(int offset, boolean parentScrolled) {
@@ -4243,6 +4271,20 @@ public class Editor {
            }
            return superResult;
        }

        private boolean positionNearEdgeOfScrollingView(float x, boolean atRtl) {
            mTextView.getLocationOnScreen(mTextViewLocation);
            boolean nearEdge;
            if (atRtl) {
                int rightEdge = mTextViewLocation[0] + mTextView.getWidth()
                        - mTextView.getPaddingRight();
                nearEdge = x > rightEdge - mTextViewEdgeSlop;
            } else {
                int leftEdge = mTextViewLocation[0] + mTextView.getPaddingLeft();
                nearEdge = x < leftEdge + mTextViewEdgeSlop;
            }
            return nearEdge;
        }
    }

    private class SelectionEndHandleView extends HandleView {
@@ -4254,9 +4296,17 @@ public class Editor {
        private float mPrevX;
        // Indicates if the handle has moved a boundary between LTR and RTL text.
        private boolean mLanguageDirectionChanged = false;
        // Distance from edge of horizontally scrolling text view
        // to use to switch to character mode.
        private final float mTextViewEdgeSlop;
        // Used to save the text view location.
        private final int[] mTextViewLocation = new int[2];

        public SelectionEndHandleView(Drawable drawableLtr, Drawable drawableRtl) {
            super(drawableLtr, drawableRtl);
            ViewConfiguration viewConfiguration = ViewConfiguration.get(
                    mTextView.getContext());
            mTextViewEdgeSlop = viewConfiguration.getScaledTouchSlop() * 4;
        }

        @Override
@@ -4294,7 +4344,7 @@ public class Editor {
            if (layout == null) {
                // HandleView will deal appropriately in positionAtCursorOffset when
                // layout is null.
                positionAtCursorOffset(mTextView.getOffsetForPosition(x, y), false);
                positionAndAdjustForCrossingHandles(mTextView.getOffsetForPosition(x, y));
                return;
            }

@@ -4336,12 +4386,12 @@ public class Editor {
                // to the current position.
                mLanguageDirectionChanged = true;
                mTouchWordDelta = 0.0f;
                positionAtCursorOffset(offset, false);
                positionAndAdjustForCrossingHandles(offset);
                return;
            } else if (mLanguageDirectionChanged && !isLvlBoundary) {
                // We've just moved past the boundary so update the position. After this we can
                // figure out if the user is expanding or shrinking to go by word or character.
                positionAtCursorOffset(offset, false);
                positionAndAdjustForCrossingHandles(offset);
                mTouchWordDelta = 0.0f;
                mLanguageDirectionChanged = false;
                return;
@@ -4354,6 +4404,21 @@ public class Editor {
                }
            }

            if (mTextView.getHorizontallyScrolling()) {
                if (positionNearEdgeOfScrollingView(x, atRtl)
                        && mTextView.canScrollHorizontally(atRtl ? -1 : 1)
                        && ((isExpanding && offset > selectionEnd) || !isExpanding)) {
                    // If we're expanding ensure that the offset is actually greater than the
                    // selection end, if the handle snapped to the word, the finger position
                    // may be out of sync and we don't want the selection to jump back.
                    mTouchWordDelta = 0.0f;
                    final int nextOffset = atRtl ? layout.getOffsetToLeftOf(mPreviousOffset)
                            : layout.getOffsetToRightOf(mPreviousOffset);
                    positionAndAdjustForCrossingHandles(nextOffset);
                    return;
                }
            }

            if (isExpanding) {
                // User is increasing the selection.
                if (!mInWord || currLine > mPrevLine) {
@@ -4409,16 +4474,21 @@ public class Editor {
            }

            if (positionCursor) {
                // Handles can not cross and selection is at least one character.
                mPreviousLineTouched = currLine;
                positionAndAdjustForCrossingHandles(offset);
            }
            mPrevX = x;
        }

        private void positionAndAdjustForCrossingHandles(int offset) {
            final int selectionStart = mTextView.getSelectionStart();
            if (offset <= selectionStart) {
                // Handles can not cross and selection is at least one character.
                offset = getNextCursorOffset(selectionStart, true);
                mTouchWordDelta = 0.0f;
            }
                mPreviousLineTouched = currLine;
            positionAtCursorOffset(offset, false);
        }
            mPrevX = x;
        }

        @Override
        protected void positionAtCursorOffset(int offset, boolean parentScrolled) {
@@ -4437,6 +4507,20 @@ public class Editor {
            }
            return superResult;
        }

        private boolean positionNearEdgeOfScrollingView(float x, boolean atRtl) {
            mTextView.getLocationOnScreen(mTextViewLocation);
            boolean nearEdge;
            if (atRtl) {
                int leftEdge = mTextViewLocation[0] + mTextView.getPaddingLeft();
                nearEdge = x < leftEdge + mTextViewEdgeSlop;
            } else {
                int rightEdge = mTextViewLocation[0] + mTextView.getWidth()
                        - mTextView.getPaddingRight();
                nearEdge = x > rightEdge - mTextViewEdgeSlop;
            }
            return nearEdge;
        }
    }

    private int getCurrentLineAdjustedForSlop(Layout layout, int prevLine, float y) {