summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMady Mellor <madym@google.com>2015-06-17 09:25:19 -0700
committerMady Mellor <madym@google.com>2015-06-17 09:25:19 -0700
commitcc65c37f108d916b931af2432337704696f175f0 (patch)
tree634dce1040dc63cfd6d52effd683474d0fd9c4ba
parent42376d6482804ac240fc84a75e50e7fae478b744 (diff)
downloadframeworks_base-cc65c37f108d916b931af2432337704696f175f0.zip
frameworks_base-cc65c37f108d916b931af2432337704696f175f0.tar.gz
frameworks_base-cc65c37f108d916b931af2432337704696f175f0.tar.bz2
Text selection: add some slop for moving between lines
It's pretty easy to accidentally move to a different line when selecting text. This CL makes an adjustment so that if the user is on a line, they must move above the top of it + slop to move up a line, and they must move below the bottom of it + slop to move down a line. This CL also makes a small modification to check if the layout is null and return early which simplifies some of the following code. Bug: 21306433 Change-Id: I4a854e644faafaf1e159201ae1f2838862f16b25
-rw-r--r--core/java/android/widget/Editor.java66
1 files changed, 56 insertions, 10 deletions
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index f89ee91..2c98961 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -122,6 +122,7 @@ public class Editor {
static final int BLINK = 500;
private static final float[] TEMP_POSITION = new float[2];
private static int DRAG_SHADOW_MAX_TEXT_LENGTH = 20;
+ private static final float LINE_SLOP_MULTIPLIER_FOR_HANDLEVIEWS = 0.5f;
// Tag used when the Editor maintains its own separate UndoManager.
private static final String UNDO_OWNER_TAG = "Editor";
@@ -4072,16 +4073,23 @@ public class Editor {
@Override
public void updatePosition(float x, float y) {
- final int selectionEnd = mTextView.getSelectionEnd();
final Layout layout = mTextView.getLayout();
- int initialOffset = mTextView.getOffsetForPosition(x, y);
- int currLine = mTextView.getLineAtCoordinate(y);
+ if (layout == null) {
+ // HandleView will deal appropriately in positionAtCursorOffset when
+ // layout is null.
+ positionAtCursorOffset(mTextView.getOffsetForPosition(x, y), false);
+ return;
+ }
+
boolean positionCursor = false;
+ final int selectionEnd = mTextView.getSelectionEnd();
+ int currLine = getCurrentLineAdjustedForSlop(layout, mPrevLine, y);
+ int initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
if (initialOffset >= selectionEnd) {
// Handles have crossed, bound it to the last selected line and
// adjust by word / char as normal.
- currLine = layout != null ? layout.getLineForOffset(selectionEnd) : mPrevLine;
+ currLine = layout.getLineForOffset(selectionEnd);
initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
}
@@ -4199,16 +4207,23 @@ public class Editor {
@Override
public void updatePosition(float x, float y) {
- final int selectionStart = mTextView.getSelectionStart();
final Layout layout = mTextView.getLayout();
- int initialOffset = mTextView.getOffsetForPosition(x, y);
- int currLine = mTextView.getLineAtCoordinate(y);
+ if (layout == null) {
+ // HandleView will deal appropriately in positionAtCursorOffset when
+ // layout is null.
+ positionAtCursorOffset(mTextView.getOffsetForPosition(x, y), false);
+ return;
+ }
+
boolean positionCursor = false;
+ final int selectionStart = mTextView.getSelectionStart();
+ int currLine = getCurrentLineAdjustedForSlop(layout, mPrevLine, y);
+ int initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
if (initialOffset <= selectionStart) {
// Handles have crossed, bound it to the first selected line and
// adjust by word / char as normal.
- currLine = layout != null ? layout.getLineForOffset(selectionStart) : mPrevLine;
+ currLine = layout.getLineForOffset(selectionStart);
initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
}
@@ -4228,7 +4243,7 @@ public class Editor {
offset = mPreviousOffset;
}
}
- if (layout != null && offset > initialOffset) {
+ if (offset > initialOffset) {
final float adjustedX = layout.getPrimaryHorizontal(offset);
mTouchWordDelta =
adjustedX - mTextView.convertToLocalHorizontalCoordinate(x);
@@ -4244,7 +4259,7 @@ public class Editor {
if (currLine < mPrevLine) {
// We're on a different line, so we'll snap to word boundaries.
offset = end;
- if (layout != null && offset > initialOffset) {
+ if (offset > initialOffset) {
final float adjustedX = layout.getPrimaryHorizontal(offset);
mTouchWordDelta =
adjustedX - mTextView.convertToLocalHorizontalCoordinate(x);
@@ -4285,6 +4300,37 @@ public class Editor {
}
}
+ private int getCurrentLineAdjustedForSlop(Layout layout, int prevLine, float y) {
+ if (layout == null || prevLine > layout.getLineCount()
+ || layout.getLineCount() <= 0 || prevLine < 0) {
+ // Invalid parameters, just return whatever line is at y.
+ return mTextView.getLineAtCoordinate(y);
+ }
+
+ final float verticalOffset = mTextView.viewportToContentVerticalOffset();
+ final int lineCount = layout.getLineCount();
+ final float slop = mTextView.getLineHeight() * LINE_SLOP_MULTIPLIER_FOR_HANDLEVIEWS;
+
+ final float firstLineTop = layout.getLineTop(0) + verticalOffset;
+ final float prevLineTop = layout.getLineTop(prevLine) + verticalOffset;
+ final float yTopBound = Math.max(prevLineTop - slop, firstLineTop + slop);
+
+ final float lastLineBottom = layout.getLineBottom(lineCount - 1) + verticalOffset;
+ final float prevLineBottom = layout.getLineBottom(prevLine) + verticalOffset;
+ final float yBottomBound = Math.min(prevLineBottom + slop, lastLineBottom - slop);
+
+ // Determine if we've moved lines based on y position and previous line.
+ int currLine;
+ if (y <= yTopBound) {
+ currLine = Math.max(prevLine - 1, 0);
+ } else if (y >= yBottomBound) {
+ currLine = Math.min(prevLine + 1, lineCount - 1);
+ } else {
+ currLine = prevLine;
+ }
+ return currLine;
+ }
+
/**
* A CursorController instance can be used to control a cursor in the text.
*/