diff options
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/widget/Editor.java | 115 |
1 files changed, 50 insertions, 65 deletions
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 34620e6b620f..19184d619e46 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -3495,6 +3495,10 @@ public class Editor { mIdealVerticalOffset = 0.7f * handleHeight; } + public float getIdealVerticalOffset() { + return mIdealVerticalOffset; + } + protected void updateDrawable() { final int offset = getCurrentCursorOffset(); final boolean isRtlCharAtOffset = mTextView.getLayout().isRtlCharAt(offset); @@ -4279,6 +4283,7 @@ public class Editor { private int mStartOffset = -1; // Indicates whether the user is selecting text and using the drag accelerator. private boolean mDragAcceleratorActive; + private boolean mHaventMovedEnoughToStartDrag; SelectionModifierCursorController() { resetTouchOffsets(); @@ -4343,19 +4348,20 @@ public class Editor { public void onTouchEvent(MotionEvent event) { // This is done even when the View does not have focus, so that long presses can start // selection and tap can move cursor from this tap position. + final float eventX = event.getX(); + final float eventY = event.getY(); switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: - final float x = event.getX(); - final float y = event.getY(); // Remember finger down position, to be able to start selection from there. - mMinTouchOffset = mMaxTouchOffset = mTextView.getOffsetForPosition(x, y); + mMinTouchOffset = mMaxTouchOffset = mTextView.getOffsetForPosition( + eventX, eventY); // Double tap detection if (mGestureStayedInTapRegion) { if (mDoubleTap) { - final float deltaX = x - mDownPositionX; - final float deltaY = y - mDownPositionY; + final float deltaX = eventX - mDownPositionX; + final float deltaY = eventY - mDownPositionY; final float distanceSquared = deltaX * deltaX + deltaY * deltaY; ViewConfiguration viewConfiguration = ViewConfiguration.get( @@ -4363,16 +4369,17 @@ public class Editor { int doubleTapSlop = viewConfiguration.getScaledDoubleTapSlop(); boolean stayedInArea = distanceSquared < doubleTapSlop * doubleTapSlop; - if (stayedInArea && isPositionOnText(x, y)) { + if (stayedInArea && isPositionOnText(eventX, eventY)) { startSelectionActionModeWithSelectionAndStartDrag(); mDiscardNextActionUp = true; } } } - mDownPositionX = x; - mDownPositionY = y; + mDownPositionX = eventX; + mDownPositionY = eventY; mGestureStayedInTapRegion = true; + mHaventMovedEnoughToStartDrag = true; break; case MotionEvent.ACTION_POINTER_DOWN: @@ -4386,18 +4393,24 @@ public class Editor { break; case MotionEvent.ACTION_MOVE: - final ViewConfiguration viewConfiguration = ViewConfiguration.get( + final ViewConfiguration viewConfig = ViewConfiguration.get( mTextView.getContext()); + final int touchSlop = viewConfig.getScaledTouchSlop(); - if (mGestureStayedInTapRegion) { - final float deltaX = event.getX() - mDownPositionX; - final float deltaY = event.getY() - mDownPositionY; + if (mGestureStayedInTapRegion || mHaventMovedEnoughToStartDrag) { + final float deltaX = eventX - mDownPositionX; + final float deltaY = eventY - mDownPositionY; final float distanceSquared = deltaX * deltaX + deltaY * deltaY; - int doubleTapTouchSlop = viewConfiguration.getScaledDoubleTapTouchSlop(); - - if (distanceSquared > doubleTapTouchSlop * doubleTapTouchSlop) { - mGestureStayedInTapRegion = false; + if (mGestureStayedInTapRegion) { + int doubleTapTouchSlop = viewConfig.getScaledDoubleTapTouchSlop(); + mGestureStayedInTapRegion = + distanceSquared <= doubleTapTouchSlop * doubleTapTouchSlop; + } + if (mHaventMovedEnoughToStartDrag) { + // We don't start dragging until the user has moved enough. + mHaventMovedEnoughToStartDrag = + distanceSquared <= touchSlop * touchSlop; } } @@ -4407,56 +4420,28 @@ public class Editor { } if (mStartOffset != -1) { - final int rawOffset = mTextView.getOffsetForPosition(event.getX(), - event.getY()); - int offset = rawOffset; - - // We don't start "dragging" until the user is past the initial word that - // gets selected on long press. - int firstWordStart = getWordStart(mStartOffset); - int firstWordEnd = getWordEnd(mStartOffset); - if (offset > firstWordEnd || offset < firstWordStart) { - - // Basically the goal in the below code is to have the highlight be - // offset so that your finger isn't covering the end point. - int fingerOffset = viewConfiguration.getScaledTouchSlop(); - float mx = event.getX(); - float my = event.getY(); - if (mx > fingerOffset) mx -= fingerOffset; - if (my > fingerOffset) my -= fingerOffset; - offset = mTextView.getOffsetForPosition(mx, my); - - // Perform the check for closeness at edge of view, if we're very close - // don't adjust the offset to be in front of the finger - otherwise the - // user can't select words at the edge. - if (mTextView.getWidth() - fingerOffset > mx) { - // We're going by word, so we need to make sure that the offset - // that we get is within this, so we'll get the previous boundary. - final WordIterator wordIterator = getWordIteratorWithText(); - - final int precedingOffset = wordIterator.preceding(offset); - if (mStartOffset < offset) { - // Expanding with bottom handle, in this case the selection end - // is before the finger. - offset = Math.max(precedingOffset - 1, 0); - } else { - // Expand with the start handle, in this case the selection - // start is before the finger. - if (precedingOffset == WordIterator.DONE) { - offset = 0; - } else { - offset = wordIterator.preceding(precedingOffset); - } - } + if (!mHaventMovedEnoughToStartDrag) { + // Offset the finger by the same vertical offset as the handles. This + // improves visibility of the content being selected by shifting + // the finger below the content. + final float fingerOffset = (mStartHandle != null) + ? mStartHandle.getIdealVerticalOffset() + : touchSlop; + int offset = + mTextView.getOffsetForPosition(eventX, eventY - fingerOffset); + int startOffset; + // Snap to word boundaries. + if (mStartOffset < offset) { + // Expanding with end handle. + offset = getWordEnd(offset); + startOffset = getWordStart(mStartOffset); + } else { + // Expanding with start handle. + offset = getWordStart(offset); + startOffset = getWordEnd(mStartOffset); } - if (offset == WordIterator.DONE) - offset = rawOffset; - - // Need to adjust start offset based on direction of movement. - int newStart = mStartOffset < offset ? getWordStart(mStartOffset) - : getWordEnd(mStartOffset); - Selection.setSelection((Spannable) mTextView.getText(), newStart, - offset); + Selection.setSelection((Spannable) mTextView.getText(), + startOffset, offset); } } break; |
