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

Commit 0a301f58 authored by Gilles Debunne's avatar Gilles Debunne Committed by Android Git Automerger
Browse files

am 949d0c8c: Merge "Text handles positions\' are correctly updated." into honeycomb-mr1

* commit '949d0c8c':
  Text handles positions' are correctly updated.
parents f279269a 949d0c8c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1039,7 +1039,7 @@ public class PopupWindow {
     *
     * @return true if the popup is translated upwards to fit on screen
     */
    boolean findDropDownPosition(View anchor, WindowManager.LayoutParams p,
    private boolean findDropDownPosition(View anchor, WindowManager.LayoutParams p,
            int xoff, int yoff) {

        anchor.getLocationInWindow(mDrawingLocation);
+98 −128
Original line number Diff line number Diff line
@@ -4498,8 +4498,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        */

        canvas.restore();

        updateCursorControllerPositions();
    }

    private void updateCursorsPositions() {
@@ -4557,15 +4555,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
     * @hide
     */
    protected void updateCursorControllerPositions() {
        // No need to create the controllers if they were not already
        if (mInsertionPointCursorController != null &&
                mInsertionPointCursorController.isShowing()) {
            mInsertionPointCursorController.updatePosition();
        }
        if (mSelectionModifierCursorController != null &&
                mSelectionModifierCursorController.isShowing()) {
            mSelectionModifierCursorController.updatePosition();
        }
        // TODO remove
    }

    @Override
@@ -7356,14 +7346,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            }

            if (isTextEditable() || mTextIsSelectable) {
                if (mScrollX != oldScrollX || mScrollY != oldScrollY) {
                if (mScrollX != oldScrollX || mScrollY != oldScrollY) { // TODO remove
                    // Hide insertion anchor while scrolling. Leave selection.
                    hideInsertionPointCursorController();
                    // No need to create the controller, since there is nothing to update.
                    if (mSelectionModifierCursorController != null &&
                            mSelectionModifierCursorController.isShowing()) {
                        mSelectionModifierCursorController.updatePosition();
                    }
                    hideInsertionPointCursorController(); // TODO any motion should hide it
                }

                if (touchIsFinished) {
@@ -7373,7 +7358,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
                        handled |= imm != null && imm.showSoftInput(this, 0);
                    }


                    boolean selectAllGotFocus = mSelectAllOnFocus && didTouchFocusSelect();
                    if (!selectAllGotFocus && hasSelection()) {
                        startSelectionActionMode();
@@ -8653,26 +8637,31 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        }
    }

    private class HandleView extends View implements ViewTreeObserver.OnScrollChangedListener {
    private class HandleView extends View implements ViewTreeObserver.OnPreDrawListener {
        private Drawable mDrawable;
        private final ScrollingPopupWindow mContainer;
        private int mPositionX;
        private int mPositionY;
        private final PopupWindow mContainer;
        // Position with respect to the parent TextView
        private int mPositionX, mPositionY;
        private final CursorController mController;
        private boolean mIsDragging;
        private float mTouchToWindowOffsetX;
        private float mTouchToWindowOffsetY;
        // Offset from touch position to mPosition
        private float mTouchToWindowOffsetX, mTouchToWindowOffsetY;
        private float mHotspotX;
        // Offsets the hotspot point up, so that cursor is not hidden by the finger when moving up
        private float mTouchOffsetY;
        // Where the touch position should be on the handle to ensure a maximum cursor visibility
        private float mIdealVerticalOffset;
        private int mLastParentX;
        private int mLastParentY;
        // Parent's (TextView) position in window
        private int mLastParentX, mLastParentY;
        private float mDownPositionX, mDownPositionY;
        // PopupWindow container absolute position with respect to the enclosing window
        private int mContainerPositionX, mContainerPositionY;
        private long mTouchTimer;
        // Visible or not (scrolled off screen), whether or not this handle should be visible
        private boolean mIsActive = false;
        // The insertion handle can have an associated PastePopupMenu
        private boolean mIsInsertionHandle = false;
        // Used to detect taps on the insertion handle, which will affect the PastePopupMenu
        private long mTouchTimer;
        private PastePopupMenu mPastePopupWindow;

        // Touch-up filter: number of previous positions remembered
@@ -8684,12 +8673,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        private int mPreviousOffsetIndex = 0;
        private int mNumberPreviousOffsets = 0;

        public void startTouchUpFilter(int offset) {
        private void startTouchUpFilter(int offset) {
            mNumberPreviousOffsets = 0;
            addPositionToTouchUpFilter(offset);
        }

        public void addPositionToTouchUpFilter(int offset) {
        private void addPositionToTouchUpFilter(int offset) {
            if (mNumberPreviousOffsets > 0 &&
                    mPreviousOffsets[mPreviousOffsetIndex] == offset) {
                // Make sure only actual changes of position are recorded.
@@ -8702,7 +8691,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            mNumberPreviousOffsets++;
        }

        public void filterOnTouchUp() {
        private void filterOnTouchUp() {
            final long now = SystemClock.uptimeMillis();
            int i = 0;
            int index = mPreviousOffsetIndex;
@@ -8725,16 +8714,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        public HandleView(CursorController controller, int pos) {
            super(TextView.this.mContext);
            mController = controller;
            mContainer = new ScrollingPopupWindow(TextView.this.mContext, null,
            mContainer = new PopupWindow(TextView.this.mContext, null,
                    com.android.internal.R.attr.textSelectHandleWindowStyle);
            mContainer.setSplitTouchEnabled(true);
            mContainer.setClippingEnabled(false);
            mContainer.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
            mContainer.setContentView(this);

            setOrientation(pos);
            setPosition(pos);
        }

        public void setOrientation(int pos) {
        private void setPosition(int pos) {
            int handleWidth;
            switch (pos) {
                case LEFT: {
@@ -8774,38 +8764,48 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            }

            final int handleHeight = mDrawable.getIntrinsicHeight();

            mTouchOffsetY = -0.3f * handleHeight;
            mIdealVerticalOffset = 0.7f * handleHeight;

            invalidate();
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            setMeasuredDimension(mDrawable.getIntrinsicWidth(),
                    mDrawable.getIntrinsicHeight());
            setMeasuredDimension(mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());
        }

        public void show() {
            if (!isPositionVisible()) {
                hide();
                return;
            }
            mContainer.setContentView(this);
            mContainerPositionX = mPositionX;
            mContainerPositionY = mPositionY - TextView.this.getHeight();
            mContainer.showAsDropDown(TextView.this, mContainerPositionX, mContainerPositionY);
            updateContainerPosition();
            if (isShowing()) {
                mContainer.update(mContainerPositionX, mContainerPositionY,
                        mRight - mLeft, mBottom - mTop);

            // Hide paste view when handle is moved on screen.
                hidePastePopupWindow();
            } else {
                mContainer.showAtLocation(TextView.this, 0,
                        mContainerPositionX, mContainerPositionY);

                mIsActive = true;

                ViewTreeObserver vto = TextView.this.getViewTreeObserver();
                vto.addOnPreDrawListener(this);
            }
        }

        public void hide() {
        private void dismiss() {
            mIsDragging = false;
            mContainer.dismiss();
            hidePastePopupWindow();
        }

        public void hide() {
            dismiss();

            mIsActive = false;

            ViewTreeObserver vto = TextView.this.getViewTreeObserver();
            vto.removeOnScrollChangedListener(this);
            vto.removeOnPreDrawListener(this);
        }

        public boolean isShowing() {
@@ -8856,44 +8856,59 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        private void moveTo(int x, int y) {
            mPositionX = x - TextView.this.mScrollX;
            mPositionY = y - TextView.this.mScrollY;
            if (isPositionVisible()) {
                int[] coords = null;
                if (mContainer.isShowing()) {
                    final int containerPositionX = mPositionX;
                    final int containerPositionY = mPositionY - TextView.this.getHeight();

            if (mIsDragging) {
                TextView.this.getLocationInWindow(mTempCoords);
                if (mTempCoords[0] != mLastParentX || mTempCoords[1] != mLastParentY) {
                    mTouchToWindowOffsetX += mTempCoords[0] - mLastParentX;
                    mTouchToWindowOffsetY += mTempCoords[1] - mLastParentY;
                    mLastParentX = mTempCoords[0];
                    mLastParentY = mTempCoords[1];
                }
                // Hide paste popup window as soon as the handle is dragged.
                hidePastePopupWindow();
            }
        }

        /**
         * Updates the global container's position.
         * @return whether or not the position has actually changed
         */
        private boolean updateContainerPosition() {
            // TODO Prevent this using different HandleView subclasses
            mController.updateOffset(this, mController.getCurrentOffset(this));
            TextView.this.getLocationInWindow(mTempCoords);
            final int containerPositionX = mTempCoords[0] + mPositionX;
            final int containerPositionY = mTempCoords[1] + mPositionY;

            if (containerPositionX != mContainerPositionX ||
                containerPositionY != mContainerPositionY) {
                mContainerPositionX = containerPositionX;
                mContainerPositionY = containerPositionY;
                return true;
            }
            return false;
        }

                        mContainer.update(TextView.this, mContainerPositionX, mContainerPositionY,
        public boolean onPreDraw() {
            if (updateContainerPosition()) {
                if (isPositionVisible()) {
                    mContainer.update(mContainerPositionX, mContainerPositionY,
                            mRight - mLeft, mBottom - mTop);

                        // Hide paste popup window as soon as a scroll occurs.
                        hidePastePopupWindow();
                    }
                } else {
                    if (mIsActive && !isShowing()) {
                        show();
                    }

                if (mIsDragging) {
                    if (coords == null) {
                        coords = mTempCoords;
                        TextView.this.getLocationInWindow(coords);
                } else {
                    if (isShowing()) {
                        dismiss();
                    }
                    if (coords[0] != mLastParentX || coords[1] != mLastParentY) {
                        mTouchToWindowOffsetX += coords[0] - mLastParentX;
                        mTouchToWindowOffsetY += coords[1] - mLastParentY;
                        mLastParentX = coords[0];
                        mLastParentY = coords[1];
                }
                    // Hide paste popup window as soon as the handle is dragged.

                // Hide paste popup as soon as the view is scrolled or moved
                hidePastePopupWindow();
            }
            } else {
                hide();
            }
            return true;
        }

        @Override
@@ -8979,7 +8994,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            return mIsDragging;
        }

        void positionAtCursor(final int offset) {
        void positionAtCursor(int offset) {
            addPositionToTouchUpFilter(offset);
            final int width = mDrawable.getIntrinsicWidth();
            final int height = mDrawable.getIntrinsicHeight();
@@ -9013,50 +9028,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
                mPastePopupWindow.hide();
            }
        }

        /**
         * A popup window, attached to a view, and that listens to scroll events in its anchors'
         * view hierarchy, so that it is automatically moved on such events.
         */
        private class ScrollingPopupWindow extends PopupWindow {

            private int[] mDrawingLocations = new int[2];

            public ScrollingPopupWindow(Context context, AttributeSet attrs, int defStyle) {
                super(context, attrs, defStyle);
            }

            @Override
            public boolean findDropDownPosition(View anchor, WindowManager.LayoutParams p,
                    int xoff, int yoff) {
                anchor.getLocationInWindow(mDrawingLocations);
                p.x = mDrawingLocations[0] + xoff;
                p.y = mDrawingLocations[1] + anchor.getHeight() + yoff;

                // Hide paste popup as soon as the view is scrolled.
                hidePastePopupWindow();

                if (!isPositionVisible()) {
                    dismiss();
                    onHandleBecomeInvisible();
                }

                return false;
            }
        }

        public void onScrollChanged() {
            if (isPositionVisible()) {
                show();
                ViewTreeObserver vto = TextView.this.getViewTreeObserver();
                vto.removeOnScrollChangedListener(this);
            }
        }

        public void onHandleBecomeInvisible() {
            ViewTreeObserver vto = TextView.this.getViewTreeObserver();
            vto.addOnScrollChangedListener(this);
        }
    }

    private class InsertionPointCursorController implements CursorController {
@@ -9074,7 +9045,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        }

        public void show(int delayBeforePaste) {
            updatePosition();
            getHandle().show();
            hideDelayed();
            removePastePopupCallback();
            final long durationSinceCutOrCopy = SystemClock.uptimeMillis() - sLastCutOrCopyTime;
@@ -9213,7 +9184,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            if (mEndHandle == null) mEndHandle = new HandleView(this, HandleView.RIGHT);

            mIsShowing = true;
            updatePosition();

            mStartHandle.show();
            mEndHandle.show();