* commit '9659297d9c26a8a2fdfa3c0e23b92e0fb72398ca': Allow text selection handles to scroll horizontally
This commit is contained in:
@@ -4060,9 +4060,17 @@ public class Editor {
|
||||
private float mPrevX;
|
||||
// Indicates if the handle has moved a boundary between LTR and RTL text.
|
||||
private boolean mLanguageDirectionChanged = false;
|
||||
// Distance from edge of horizontally scrolling text view
|
||||
// to use to switch to character mode.
|
||||
private final float mTextViewEdgeSlop;
|
||||
// Used to save text view location.
|
||||
private final int[] mTextViewLocation = new int[2];
|
||||
|
||||
public SelectionStartHandleView(Drawable drawableLtr, Drawable drawableRtl) {
|
||||
super(drawableLtr, drawableRtl);
|
||||
ViewConfiguration viewConfiguration = ViewConfiguration.get(
|
||||
mTextView.getContext());
|
||||
mTextViewEdgeSlop = viewConfiguration.getScaledTouchSlop() * 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -4100,7 +4108,7 @@ public class Editor {
|
||||
if (layout == null) {
|
||||
// HandleView will deal appropriately in positionAtCursorOffset when
|
||||
// layout is null.
|
||||
positionAtCursorOffset(mTextView.getOffsetForPosition(x, y), false);
|
||||
positionAndAdjustForCrossingHandles(mTextView.getOffsetForPosition(x, y));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4142,12 +4150,12 @@ public class Editor {
|
||||
// to the current position.
|
||||
mLanguageDirectionChanged = true;
|
||||
mTouchWordDelta = 0.0f;
|
||||
positionAtCursorOffset(offset, false);
|
||||
positionAndAdjustForCrossingHandles(offset);
|
||||
return;
|
||||
} else if (mLanguageDirectionChanged && !isLvlBoundary) {
|
||||
// We've just moved past the boundary so update the position. After this we can
|
||||
// figure out if the user is expanding or shrinking to go by word or character.
|
||||
positionAtCursorOffset(offset, false);
|
||||
positionAndAdjustForCrossingHandles(offset);
|
||||
mTouchWordDelta = 0.0f;
|
||||
mLanguageDirectionChanged = false;
|
||||
return;
|
||||
@@ -4160,6 +4168,21 @@ public class Editor {
|
||||
}
|
||||
}
|
||||
|
||||
if (mTextView.getHorizontallyScrolling()) {
|
||||
if (positionNearEdgeOfScrollingView(x, atRtl)
|
||||
&& (mTextView.getScrollX() != 0)
|
||||
&& ((isExpanding && offset < selectionStart) || !isExpanding)) {
|
||||
// If we're expanding ensure that the offset is smaller than the
|
||||
// selection start, if the handle snapped to the word, the finger position
|
||||
// may be out of sync and we don't want the selection to jump back.
|
||||
mTouchWordDelta = 0.0f;
|
||||
final int nextOffset = atRtl ? layout.getOffsetToRightOf(mPreviousOffset)
|
||||
: layout.getOffsetToLeftOf(mPreviousOffset);
|
||||
positionAndAdjustForCrossingHandles(nextOffset);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (isExpanding) {
|
||||
// User is increasing the selection.
|
||||
if (!mInWord || currLine < mPrevLine) {
|
||||
@@ -4215,17 +4238,22 @@ public class Editor {
|
||||
}
|
||||
|
||||
if (positionCursor) {
|
||||
// Handles can not cross and selection is at least one character.
|
||||
if (offset >= selectionEnd) {
|
||||
offset = getNextCursorOffset(selectionEnd, false);
|
||||
mTouchWordDelta = 0.0f;
|
||||
}
|
||||
mPreviousLineTouched = currLine;
|
||||
positionAtCursorOffset(offset, false);
|
||||
positionAndAdjustForCrossingHandles(offset);
|
||||
}
|
||||
mPrevX = x;
|
||||
}
|
||||
|
||||
private void positionAndAdjustForCrossingHandles(int offset) {
|
||||
final int selectionEnd = mTextView.getSelectionEnd();
|
||||
if (offset >= selectionEnd) {
|
||||
// Handles can not cross and selection is at least one character.
|
||||
offset = getNextCursorOffset(selectionEnd, false);
|
||||
mTouchWordDelta = 0.0f;
|
||||
}
|
||||
positionAtCursorOffset(offset, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void positionAtCursorOffset(int offset, boolean parentScrolled) {
|
||||
super.positionAtCursorOffset(offset, parentScrolled);
|
||||
@@ -4243,6 +4271,20 @@ public class Editor {
|
||||
}
|
||||
return superResult;
|
||||
}
|
||||
|
||||
private boolean positionNearEdgeOfScrollingView(float x, boolean atRtl) {
|
||||
mTextView.getLocationOnScreen(mTextViewLocation);
|
||||
boolean nearEdge;
|
||||
if (atRtl) {
|
||||
int rightEdge = mTextViewLocation[0] + mTextView.getWidth()
|
||||
- mTextView.getPaddingRight();
|
||||
nearEdge = x > rightEdge - mTextViewEdgeSlop;
|
||||
} else {
|
||||
int leftEdge = mTextViewLocation[0] + mTextView.getPaddingLeft();
|
||||
nearEdge = x < leftEdge + mTextViewEdgeSlop;
|
||||
}
|
||||
return nearEdge;
|
||||
}
|
||||
}
|
||||
|
||||
private class SelectionEndHandleView extends HandleView {
|
||||
@@ -4254,9 +4296,17 @@ public class Editor {
|
||||
private float mPrevX;
|
||||
// Indicates if the handle has moved a boundary between LTR and RTL text.
|
||||
private boolean mLanguageDirectionChanged = false;
|
||||
// Distance from edge of horizontally scrolling text view
|
||||
// to use to switch to character mode.
|
||||
private final float mTextViewEdgeSlop;
|
||||
// Used to save the text view location.
|
||||
private final int[] mTextViewLocation = new int[2];
|
||||
|
||||
public SelectionEndHandleView(Drawable drawableLtr, Drawable drawableRtl) {
|
||||
super(drawableLtr, drawableRtl);
|
||||
ViewConfiguration viewConfiguration = ViewConfiguration.get(
|
||||
mTextView.getContext());
|
||||
mTextViewEdgeSlop = viewConfiguration.getScaledTouchSlop() * 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -4294,7 +4344,7 @@ public class Editor {
|
||||
if (layout == null) {
|
||||
// HandleView will deal appropriately in positionAtCursorOffset when
|
||||
// layout is null.
|
||||
positionAtCursorOffset(mTextView.getOffsetForPosition(x, y), false);
|
||||
positionAndAdjustForCrossingHandles(mTextView.getOffsetForPosition(x, y));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4336,12 +4386,12 @@ public class Editor {
|
||||
// to the current position.
|
||||
mLanguageDirectionChanged = true;
|
||||
mTouchWordDelta = 0.0f;
|
||||
positionAtCursorOffset(offset, false);
|
||||
positionAndAdjustForCrossingHandles(offset);
|
||||
return;
|
||||
} else if (mLanguageDirectionChanged && !isLvlBoundary) {
|
||||
// We've just moved past the boundary so update the position. After this we can
|
||||
// figure out if the user is expanding or shrinking to go by word or character.
|
||||
positionAtCursorOffset(offset, false);
|
||||
positionAndAdjustForCrossingHandles(offset);
|
||||
mTouchWordDelta = 0.0f;
|
||||
mLanguageDirectionChanged = false;
|
||||
return;
|
||||
@@ -4354,6 +4404,21 @@ public class Editor {
|
||||
}
|
||||
}
|
||||
|
||||
if (mTextView.getHorizontallyScrolling()) {
|
||||
if (positionNearEdgeOfScrollingView(x, atRtl)
|
||||
&& mTextView.canScrollHorizontally(atRtl ? -1 : 1)
|
||||
&& ((isExpanding && offset > selectionEnd) || !isExpanding)) {
|
||||
// If we're expanding ensure that the offset is actually greater than the
|
||||
// selection end, if the handle snapped to the word, the finger position
|
||||
// may be out of sync and we don't want the selection to jump back.
|
||||
mTouchWordDelta = 0.0f;
|
||||
final int nextOffset = atRtl ? layout.getOffsetToLeftOf(mPreviousOffset)
|
||||
: layout.getOffsetToRightOf(mPreviousOffset);
|
||||
positionAndAdjustForCrossingHandles(nextOffset);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (isExpanding) {
|
||||
// User is increasing the selection.
|
||||
if (!mInWord || currLine > mPrevLine) {
|
||||
@@ -4409,17 +4474,22 @@ public class Editor {
|
||||
}
|
||||
|
||||
if (positionCursor) {
|
||||
// Handles can not cross and selection is at least one character.
|
||||
if (offset <= selectionStart) {
|
||||
offset = getNextCursorOffset(selectionStart, true);
|
||||
mTouchWordDelta = 0.0f;
|
||||
}
|
||||
mPreviousLineTouched = currLine;
|
||||
positionAtCursorOffset(offset, false);
|
||||
positionAndAdjustForCrossingHandles(offset);
|
||||
}
|
||||
mPrevX = x;
|
||||
}
|
||||
|
||||
private void positionAndAdjustForCrossingHandles(int offset) {
|
||||
final int selectionStart = mTextView.getSelectionStart();
|
||||
if (offset <= selectionStart) {
|
||||
// Handles can not cross and selection is at least one character.
|
||||
offset = getNextCursorOffset(selectionStart, true);
|
||||
mTouchWordDelta = 0.0f;
|
||||
}
|
||||
positionAtCursorOffset(offset, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void positionAtCursorOffset(int offset, boolean parentScrolled) {
|
||||
super.positionAtCursorOffset(offset, parentScrolled);
|
||||
@@ -4437,6 +4507,20 @@ public class Editor {
|
||||
}
|
||||
return superResult;
|
||||
}
|
||||
|
||||
private boolean positionNearEdgeOfScrollingView(float x, boolean atRtl) {
|
||||
mTextView.getLocationOnScreen(mTextViewLocation);
|
||||
boolean nearEdge;
|
||||
if (atRtl) {
|
||||
int leftEdge = mTextViewLocation[0] + mTextView.getPaddingLeft();
|
||||
nearEdge = x < leftEdge + mTextViewEdgeSlop;
|
||||
} else {
|
||||
int rightEdge = mTextViewLocation[0] + mTextView.getWidth()
|
||||
- mTextView.getPaddingRight();
|
||||
nearEdge = x > rightEdge - mTextViewEdgeSlop;
|
||||
}
|
||||
return nearEdge;
|
||||
}
|
||||
}
|
||||
|
||||
private int getCurrentLineAdjustedForSlop(Layout layout, int prevLine, float y) {
|
||||
|
||||
Reference in New Issue
Block a user