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

Commit 9659297d authored by Mady Mellor's avatar Mady Mellor Committed by Android Git Automerger
Browse files

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

* commit 'beb6e668':
  Allow text selection handles to scroll horizontally
parents 2384e2a4 beb6e668
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) {