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

Commit 2d6b40b8 authored by Mihai Popa's avatar Mihai Popa
Browse files

[Magnifier-32] Do not magnify outside selection

Currently, for selection, if we move one handle towards the other, the
moving handle will stop when the selection becomes 1 character long.
However, the magnifier would continue to follow the finger after this,
no longer being helpful for the selection.

This CL fixes this, by replicating what happens when the magnifier
reaches the end of the line also for the case when it reaches the other
handle.

Bug: 72314536
Test: manual testing (both English and Arabic)
Test: atest FrameworksCoreTests:android.widget.TextViewActivityTest
Test: atest CtsWidgetTestCases:android.widget.cts.TextViewTest
Change-Id: I5bde622421c7fb8ecce0ea00f0d8d2af7aa72cf4
parent dfc752bc
Loading
Loading
Loading
Loading
+34 −11
Original line number Diff line number Diff line
@@ -4655,16 +4655,23 @@ public class Editor {

            final int trigger = getMagnifierHandleTrigger();
            final int offset;
            final int otherHandleOffset;
            switch (trigger) {
                case MagnifierHandleTrigger.INSERTION: // Fall through.
                case MagnifierHandleTrigger.INSERTION:
                    offset = mTextView.getSelectionStart();
                    otherHandleOffset = -1;
                    break;
                case MagnifierHandleTrigger.SELECTION_START:
                    offset = mTextView.getSelectionStart();
                    otherHandleOffset = mTextView.getSelectionEnd();
                    break;
                case MagnifierHandleTrigger.SELECTION_END:
                    offset = mTextView.getSelectionEnd();
                    otherHandleOffset = mTextView.getSelectionStart();
                    break;
                default:
                    offset = -1;
                    otherHandleOffset = -1;
                    break;
            }

@@ -4674,22 +4681,38 @@ public class Editor {

            final Layout layout = mTextView.getLayout();
            final int lineNumber = layout.getLineForOffset(offset);

            // Horizontally move the magnifier smoothly but clamp inside the current line.
            // Compute whether the selection handles are currently on the same line, and,
            // in this particular case, whether the selected text is right to left.
            final boolean sameLineSelection = otherHandleOffset != -1
                    && lineNumber == layout.getLineForOffset(otherHandleOffset);
            final boolean rtl = sameLineSelection
                    && (offset < otherHandleOffset)
                        != (getHorizontal(mTextView.getLayout(), offset)
                            < getHorizontal(mTextView.getLayout(), otherHandleOffset));

            // Horizontally move the magnifier smoothly, clamp inside the current line / selection.
            final int[] textViewLocationOnScreen = new int[2];
            mTextView.getLocationOnScreen(textViewLocationOnScreen);
            final float touchXInView = event.getRawX() - textViewLocationOnScreen[0];
            final float lineLeft = mTextView.getLayout().getLineLeft(lineNumber)
                    + mTextView.getTotalPaddingLeft() - mTextView.getScrollX();
            final float lineRight = mTextView.getLayout().getLineRight(lineNumber)
                    + mTextView.getTotalPaddingLeft() - mTextView.getScrollX();
            float leftBound = mTextView.getTotalPaddingLeft() - mTextView.getScrollX();
            float rightBound = mTextView.getTotalPaddingLeft() - mTextView.getScrollX();
            if (sameLineSelection && ((trigger == MagnifierHandleTrigger.SELECTION_END) ^ rtl)) {
                leftBound += getHorizontal(mTextView.getLayout(), otherHandleOffset);
            } else {
                leftBound += mTextView.getLayout().getLineLeft(lineNumber);
            }
            if (sameLineSelection && ((trigger == MagnifierHandleTrigger.SELECTION_START) ^ rtl)) {
                rightBound += getHorizontal(mTextView.getLayout(), otherHandleOffset);
            } else {
                rightBound += mTextView.getLayout().getLineRight(lineNumber);
            }
            final float contentWidth = Math.round(mMagnifier.getWidth() / mMagnifier.getZoom());
            if (touchXInView < lineLeft - contentWidth / 2
                    || touchXInView > lineRight + contentWidth / 2) {
                // The touch is too out of the bounds of the current line, so hide the magnifier.
            if (touchXInView < leftBound - contentWidth / 2
                    || touchXInView > rightBound + contentWidth / 2) {
                // The touch is too far from the current line / selection, so hide the magnifier.
                return false;
            }
            showPosInView.x = Math.max(lineLeft, Math.min(lineRight, touchXInView));
            showPosInView.x = Math.max(leftBound, Math.min(rightBound, touchXInView));

            // Vertically snap to middle of current line.
            showPosInView.y = (mTextView.getLayout().getLineTop(lineNumber)