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

Commit a41bc338 authored by Gilles Debunne's avatar Gilles Debunne Committed by Android (Google) Code Review
Browse files

Merge "Popup windows positions are updated when a TextView is scrolled"

parents f3d78eac f682a77d
Loading
Loading
Loading
Loading
+38 −26
Original line number Diff line number Diff line
@@ -9162,6 +9162,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
                startDrag(data, getTextThumbnailBuilder(selectedText), localState, 0);
                stopSelectionActionMode();
            } else {
                getSelectionController().hide();
                selectCurrentWord();
                getSelectionController().show();
            }
@@ -9209,7 +9210,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    }

    private interface TextViewPositionListener {
        public void updatePosition(int parentPositionX, int parentPositionY, boolean modified);
        public void updatePosition(int parentPositionX, int parentPositionY,
                boolean parentPositionChanged, boolean parentScrolled);
    }

    private class PositionListener implements ViewTreeObserver.OnPreDrawListener {
@@ -9222,6 +9224,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        // Absolute position of the TextView with respect to its parent window
        private int mPositionX, mPositionY;
        private int mNumberOfListeners;
        private boolean mScrollHasChanged;

        public void addSubscriber(TextViewPositionListener positionListener, boolean canMove) {
            if (mNumberOfListeners == 0) {
@@ -9273,15 +9276,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            updatePosition();

            for (int i = 0; i < MAXIMUM_NUMBER_OF_LISTENERS; i++) {
                if (mPositionHasChanged || mCanMove[i]) {
                if (mPositionHasChanged || mScrollHasChanged || mCanMove[i]) {
                    TextViewPositionListener positionListener = mPositionListeners[i];
                    if (positionListener != null) {
                        positionListener.updatePosition(mPositionX, mPositionY,
                                mPositionHasChanged);
                                mPositionHasChanged, mScrollHasChanged);
                    }
                }
            }

            mScrollHasChanged = false;
            return true;
        }

@@ -9323,6 +9327,18 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            final int primaryHorizontal = (int) mLayout.getPrimaryHorizontal(offset);
            return isVisible(primaryHorizontal, lineBottom);
        }

        public void onScrollChanged() {
            mScrollHasChanged = true;
        }
    }

    @Override
    protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) {
        super.onScrollChanged(horiz, vert, oldHoriz, oldVert);
        if (mPositionListener != null) {
            mPositionListener.onScrollChanged();
        }
    }

    private abstract class PinnedPopupWindow implements TextViewPositionListener {
@@ -9353,7 +9369,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        }

        public void show() {
            TextView.this.getPositionListener().addSubscriber(this, false);
            TextView.this.getPositionListener().addSubscriber(this, false /* offset is fixed */);

            computeLocalPosition();

@@ -9412,8 +9428,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        }

        @Override
        public void updatePosition(int parentPositionX, int parentPositionY, boolean modified) {
        public void updatePosition(int parentPositionX, int parentPositionY,
                boolean parentPositionChanged, boolean parentScrolled) {
            // Either parentPositionChanged or parentScrolled is true, check if still visible
            if (isShowing() && getPositionListener().isOffsetVisible(getTextOffset())) {
                if (parentScrolled) computeLocalPosition();
                updatePosition(parentPositionX, parentPositionY);
            } else {
                hide();
@@ -10366,7 +10385,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener

            if (i > 0 && i < iMax &&
                    (now - mPreviousOffsetsTimes[index]) > TOUCH_UP_FILTER_DELAY_BEFORE) {
                positionAtCursorOffset(mPreviousOffsets[index]);
                positionAtCursorOffset(mPreviousOffsets[index], false);
            }
        }

@@ -10382,11 +10401,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        public void show() {
            if (isShowing()) return;

            getPositionListener().addSubscriber(this, true);
            getPositionListener().addSubscriber(this, true /* local position may change */);

            // Make sure the offset is always considered new, even when focusing at same position
            mPreviousOffset = -1;
            positionAtCursorOffset(getCurrentCursorOffset());
            positionAtCursorOffset(getCurrentCursorOffset(), false);

            hideActionPopupWindow();
        }
@@ -10451,7 +10470,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener

        public abstract void updatePosition(float x, float y);

        protected void positionAtCursorOffset(int offset) {
        protected void positionAtCursorOffset(int offset, boolean parentScrolled) {
            // A HandleView relies on the layout, which may be nulled by external methods
            if (mLayout == null) {
                // Will update controllers' state, hiding them and stopping selection mode if needed
@@ -10459,7 +10478,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
                return;
            }

            if (offset != mPreviousOffset) {
            if (offset != mPreviousOffset || parentScrolled) {
                updateSelection(offset);
                addPositionToTouchUpFilter(offset);
                final int line = mLayout.getLineForOffset(offset);
@@ -10476,9 +10495,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            }
        }

        public void updatePosition(int parentPositionX, int parentPositionY, boolean modified) {
            positionAtCursorOffset(getCurrentCursorOffset());
            if (modified || mPositionHasChanged) {
        public void updatePosition(int parentPositionX, int parentPositionY,
                boolean parentPositionChanged, boolean parentScrolled) {
            positionAtCursorOffset(getCurrentCursorOffset(), parentScrolled);
            if (parentPositionChanged || mPositionHasChanged) {
                if (mIsDragging) {
                    // Update touchToWindow offset in case of parent scrolling while dragging
                    if (parentPositionX != mLastParentX || parentPositionY != mLastParentY) {
@@ -10683,7 +10703,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener

        @Override
        public void updatePosition(float x, float y) {
            positionAtCursorOffset(getOffsetForPosition(x, y));
            positionAtCursorOffset(getOffsetForPosition(x, y), false);
        }

        @Override
@@ -10722,17 +10742,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener

        @Override
        public void updatePosition(float x, float y) {
            final int selectionStart = getSelectionStart();
            final int selectionEnd = getSelectionEnd();

            int offset = getOffsetForPosition(x, y);

            // No need to redraw when the offset is unchanged
            if (offset == selectionStart) return;
            // Handles can not cross and selection is at least one character
            final int selectionEnd = getSelectionEnd();
            if (offset >= selectionEnd) offset = selectionEnd - 1;

            positionAtCursorOffset(offset);
            positionAtCursorOffset(offset, false);
        }

        public ActionPopupWindow getActionPopupWindow() {
@@ -10763,17 +10779,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener

        @Override
        public void updatePosition(float x, float y) {
            final int selectionStart = getSelectionStart();
            final int selectionEnd = getSelectionEnd();

            int offset = getOffsetForPosition(x, y);

            // No need to redraw when the offset is unchanged
            if (offset == selectionEnd) return;
            // Handles can not cross and selection is at least one character
            final int selectionStart = getSelectionStart();
            if (offset <= selectionStart) offset = selectionStart + 1;

            positionAtCursorOffset(offset);
            positionAtCursorOffset(offset, false);
        }

        public void setActionPopupWindow(ActionPopupWindow actionPopupWindow) {