am 46b70388: am b300d31b: Merge "Text selection: fix some issues with drag accelerator" into mnc-dev

* commit '46b7038811259a22c5494c0420185836cc4d3e76':
  Text selection: fix some issues with drag accelerator
This commit is contained in:
Mady Mellor
2015-05-20 18:38:35 +00:00
committed by Android Git Automerger

View File

@@ -3495,6 +3495,10 @@ public class Editor {
mIdealVerticalOffset = 0.7f * handleHeight; mIdealVerticalOffset = 0.7f * handleHeight;
} }
public float getIdealVerticalOffset() {
return mIdealVerticalOffset;
}
protected void updateDrawable() { protected void updateDrawable() {
final int offset = getCurrentCursorOffset(); final int offset = getCurrentCursorOffset();
final boolean isRtlCharAtOffset = mTextView.getLayout().isRtlCharAt(offset); final boolean isRtlCharAtOffset = mTextView.getLayout().isRtlCharAt(offset);
@@ -4279,6 +4283,7 @@ public class Editor {
private int mStartOffset = -1; private int mStartOffset = -1;
// Indicates whether the user is selecting text and using the drag accelerator. // Indicates whether the user is selecting text and using the drag accelerator.
private boolean mDragAcceleratorActive; private boolean mDragAcceleratorActive;
private boolean mHaventMovedEnoughToStartDrag;
SelectionModifierCursorController() { SelectionModifierCursorController() {
resetTouchOffsets(); resetTouchOffsets();
@@ -4343,19 +4348,20 @@ public class Editor {
public void onTouchEvent(MotionEvent event) { public void onTouchEvent(MotionEvent event) {
// This is done even when the View does not have focus, so that long presses can start // 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. // selection and tap can move cursor from this tap position.
final float eventX = event.getX();
final float eventY = event.getY();
switch (event.getActionMasked()) { switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN: 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. // 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 // Double tap detection
if (mGestureStayedInTapRegion) { if (mGestureStayedInTapRegion) {
if (mDoubleTap) { if (mDoubleTap) {
final float deltaX = x - mDownPositionX; final float deltaX = eventX - mDownPositionX;
final float deltaY = y - mDownPositionY; final float deltaY = eventY - mDownPositionY;
final float distanceSquared = deltaX * deltaX + deltaY * deltaY; final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
ViewConfiguration viewConfiguration = ViewConfiguration.get( ViewConfiguration viewConfiguration = ViewConfiguration.get(
@@ -4363,16 +4369,17 @@ public class Editor {
int doubleTapSlop = viewConfiguration.getScaledDoubleTapSlop(); int doubleTapSlop = viewConfiguration.getScaledDoubleTapSlop();
boolean stayedInArea = distanceSquared < doubleTapSlop * doubleTapSlop; boolean stayedInArea = distanceSquared < doubleTapSlop * doubleTapSlop;
if (stayedInArea && isPositionOnText(x, y)) { if (stayedInArea && isPositionOnText(eventX, eventY)) {
startSelectionActionModeWithSelectionAndStartDrag(); startSelectionActionModeWithSelectionAndStartDrag();
mDiscardNextActionUp = true; mDiscardNextActionUp = true;
} }
} }
} }
mDownPositionX = x; mDownPositionX = eventX;
mDownPositionY = y; mDownPositionY = eventY;
mGestureStayedInTapRegion = true; mGestureStayedInTapRegion = true;
mHaventMovedEnoughToStartDrag = true;
break; break;
case MotionEvent.ACTION_POINTER_DOWN: case MotionEvent.ACTION_POINTER_DOWN:
@@ -4386,18 +4393,24 @@ public class Editor {
break; break;
case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_MOVE:
final ViewConfiguration viewConfiguration = ViewConfiguration.get( final ViewConfiguration viewConfig = ViewConfiguration.get(
mTextView.getContext()); mTextView.getContext());
final int touchSlop = viewConfig.getScaledTouchSlop();
if (mGestureStayedInTapRegion) { if (mGestureStayedInTapRegion || mHaventMovedEnoughToStartDrag) {
final float deltaX = event.getX() - mDownPositionX; final float deltaX = eventX - mDownPositionX;
final float deltaY = event.getY() - mDownPositionY; final float deltaY = eventY - mDownPositionY;
final float distanceSquared = deltaX * deltaX + deltaY * deltaY; final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
int doubleTapTouchSlop = viewConfiguration.getScaledDoubleTapTouchSlop(); if (mGestureStayedInTapRegion) {
int doubleTapTouchSlop = viewConfig.getScaledDoubleTapTouchSlop();
if (distanceSquared > doubleTapTouchSlop * doubleTapTouchSlop) { mGestureStayedInTapRegion =
mGestureStayedInTapRegion = false; 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) { if (mStartOffset != -1) {
final int rawOffset = mTextView.getOffsetForPosition(event.getX(), if (!mHaventMovedEnoughToStartDrag) {
event.getY()); // Offset the finger by the same vertical offset as the handles. This
int offset = rawOffset; // improves visibility of the content being selected by shifting
// the finger below the content.
// We don't start "dragging" until the user is past the initial word that final float fingerOffset = (mStartHandle != null)
// gets selected on long press. ? mStartHandle.getIdealVerticalOffset()
int firstWordStart = getWordStart(mStartOffset); : touchSlop;
int firstWordEnd = getWordEnd(mStartOffset); int offset =
if (offset > firstWordEnd || offset < firstWordStart) { mTextView.getOffsetForPosition(eventX, eventY - fingerOffset);
int startOffset;
// Basically the goal in the below code is to have the highlight be // Snap to word boundaries.
// 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) { if (mStartOffset < offset) {
// Expanding with bottom handle, in this case the selection end // Expanding with end handle.
// is before the finger. offset = getWordEnd(offset);
offset = Math.max(precedingOffset - 1, 0); startOffset = getWordStart(mStartOffset);
} else { } else {
// Expand with the start handle, in this case the selection // Expanding with start handle.
// start is before the finger. offset = getWordStart(offset);
if (precedingOffset == WordIterator.DONE) { startOffset = getWordEnd(mStartOffset);
offset = 0;
} else {
offset = wordIterator.preceding(precedingOffset);
} }
} Selection.setSelection((Spannable) mTextView.getText(),
} startOffset, offset);
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);
} }
} }
break; break;