Merge "Suppress horizontal scrolling with trailing blanks"
This commit is contained in:
@@ -792,8 +792,17 @@ public abstract class Layout {
|
||||
* the paragraph's primary direction.
|
||||
*/
|
||||
public float getPrimaryHorizontal(int offset) {
|
||||
return getPrimaryHorizontal(offset, false /* not clamped */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the primary horizontal position for the specified text offset, but
|
||||
* optionally clamp it so that it doesn't exceed the width of the layout.
|
||||
* @hide
|
||||
*/
|
||||
public float getPrimaryHorizontal(int offset, boolean clamped) {
|
||||
boolean trailing = primaryIsTrailingPrevious(offset);
|
||||
return getHorizontal(offset, trailing);
|
||||
return getHorizontal(offset, trailing, clamped);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -802,17 +811,26 @@ public abstract class Layout {
|
||||
* the direction other than the paragraph's primary direction.
|
||||
*/
|
||||
public float getSecondaryHorizontal(int offset) {
|
||||
boolean trailing = primaryIsTrailingPrevious(offset);
|
||||
return getHorizontal(offset, !trailing);
|
||||
return getSecondaryHorizontal(offset, false /* not clamped */);
|
||||
}
|
||||
|
||||
private float getHorizontal(int offset, boolean trailing) {
|
||||
/**
|
||||
* Get the secondary horizontal position for the specified text offset, but
|
||||
* optionally clamp it so that it doesn't exceed the width of the layout.
|
||||
* @hide
|
||||
*/
|
||||
public float getSecondaryHorizontal(int offset, boolean clamped) {
|
||||
boolean trailing = primaryIsTrailingPrevious(offset);
|
||||
return getHorizontal(offset, !trailing, clamped);
|
||||
}
|
||||
|
||||
private float getHorizontal(int offset, boolean trailing, boolean clamped) {
|
||||
int line = getLineForOffset(offset);
|
||||
|
||||
return getHorizontal(offset, trailing, line);
|
||||
return getHorizontal(offset, trailing, line, clamped);
|
||||
}
|
||||
|
||||
private float getHorizontal(int offset, boolean trailing, int line) {
|
||||
private float getHorizontal(int offset, boolean trailing, int line, boolean clamped) {
|
||||
int start = getLineStart(line);
|
||||
int end = getLineEnd(line);
|
||||
int dir = getParagraphDirection(line);
|
||||
@@ -834,6 +852,9 @@ public abstract class Layout {
|
||||
float wid = tl.measure(offset - start, trailing, null);
|
||||
TextLine.recycle(tl);
|
||||
|
||||
if (clamped && wid > mWidth) {
|
||||
wid = mWidth;
|
||||
}
|
||||
int left = getParagraphLeft(line);
|
||||
int right = getParagraphRight(line);
|
||||
|
||||
@@ -1256,6 +1277,23 @@ public abstract class Layout {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether we should clamp cursor position. Currently it's
|
||||
* only robust for left-aligned displays.
|
||||
* @hide
|
||||
*/
|
||||
public boolean shouldClampCursor(int line) {
|
||||
// Only clamp cursor position in left-aligned displays.
|
||||
switch (getParagraphAlignment(line)) {
|
||||
case ALIGN_LEFT:
|
||||
return true;
|
||||
case ALIGN_NORMAL:
|
||||
return getParagraphDirection(line) > 0;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Fills in the specified Path with a representation of a cursor
|
||||
* at the specified offset. This will often be a vertical line
|
||||
@@ -1270,8 +1308,9 @@ public abstract class Layout {
|
||||
int top = getLineTop(line);
|
||||
int bottom = getLineTop(line+1);
|
||||
|
||||
float h1 = getPrimaryHorizontal(point) - 0.5f;
|
||||
float h2 = isLevelBoundary(point) ? getSecondaryHorizontal(point) - 0.5f : h1;
|
||||
boolean clamped = shouldClampCursor(line);
|
||||
float h1 = getPrimaryHorizontal(point, clamped) - 0.5f;
|
||||
float h2 = isLevelBoundary(point) ? getSecondaryHorizontal(point, clamped) - 0.5f : h1;
|
||||
|
||||
int caps = TextKeyListener.getMetaState(editingBuffer, TextKeyListener.META_SHIFT_ON) |
|
||||
TextKeyListener.getMetaState(editingBuffer, TextKeyListener.META_SELECTING);
|
||||
@@ -1357,8 +1396,8 @@ public abstract class Layout {
|
||||
int en = Math.min(end, there);
|
||||
|
||||
if (st != en) {
|
||||
float h1 = getHorizontal(st, false, line);
|
||||
float h2 = getHorizontal(en, true, line);
|
||||
float h1 = getHorizontal(st, false, line, false /* not clamped */);
|
||||
float h2 = getHorizontal(en, true, line, false /* not clamped */);
|
||||
|
||||
float left = Math.min(h1, h2);
|
||||
float right = Math.max(h1, h2);
|
||||
|
||||
@@ -1468,20 +1468,24 @@ public class Editor {
|
||||
middle = (top + bottom) >> 1;
|
||||
}
|
||||
|
||||
updateCursorPosition(0, top, middle, getPrimaryHorizontal(layout, hintLayout, offset));
|
||||
boolean clamped = layout.shouldClampCursor(line);
|
||||
updateCursorPosition(0, top, middle,
|
||||
getPrimaryHorizontal(layout, hintLayout, offset, clamped));
|
||||
|
||||
if (mCursorCount == 2) {
|
||||
updateCursorPosition(1, middle, bottom, layout.getSecondaryHorizontal(offset));
|
||||
updateCursorPosition(1, middle, bottom,
|
||||
layout.getSecondaryHorizontal(offset, clamped));
|
||||
}
|
||||
}
|
||||
|
||||
private float getPrimaryHorizontal(Layout layout, Layout hintLayout, int offset) {
|
||||
private float getPrimaryHorizontal(Layout layout, Layout hintLayout, int offset,
|
||||
boolean clamped) {
|
||||
if (TextUtils.isEmpty(layout.getText()) &&
|
||||
hintLayout != null &&
|
||||
!TextUtils.isEmpty(hintLayout.getText())) {
|
||||
return hintLayout.getPrimaryHorizontal(offset);
|
||||
return hintLayout.getPrimaryHorizontal(offset, clamped);
|
||||
} else {
|
||||
return layout.getPrimaryHorizontal(offset);
|
||||
return layout.getPrimaryHorizontal(offset, clamped);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6553,15 +6553,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
|
||||
int line = layout.getLineForOffset(offset);
|
||||
|
||||
// FIXME: Is it okay to truncate this, or should we round?
|
||||
final int x = (int)layout.getPrimaryHorizontal(offset);
|
||||
final int top = layout.getLineTop(line);
|
||||
final int bottom = layout.getLineTop(line + 1);
|
||||
|
||||
int left = (int) FloatMath.floor(layout.getLineLeft(line));
|
||||
int right = (int) FloatMath.ceil(layout.getLineRight(line));
|
||||
int ht = layout.getHeight();
|
||||
|
||||
int grav;
|
||||
|
||||
switch (layout.getParagraphAlignment(line)) {
|
||||
@@ -6583,8 +6574,32 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
break;
|
||||
}
|
||||
|
||||
// We only want to clamp the cursor to fit within the layout width
|
||||
// in left-to-right modes, because in a right to left alignment,
|
||||
// we want to scroll to keep the line-right on the screen, as other
|
||||
// lines are likely to have text flush with the right margin, which
|
||||
// we want to keep visible.
|
||||
// A better long-term solution would probably be to measure both
|
||||
// the full line and a blank-trimmed version, and, for example, use
|
||||
// the latter measurement for centering and right alignment, but for
|
||||
// the time being we only implement the cursor clamping in left to
|
||||
// right where it is most likely to be annoying.
|
||||
final boolean clamped = grav > 0;
|
||||
// FIXME: Is it okay to truncate this, or should we round?
|
||||
final int x = (int)layout.getPrimaryHorizontal(offset, clamped);
|
||||
final int top = layout.getLineTop(line);
|
||||
final int bottom = layout.getLineTop(line + 1);
|
||||
|
||||
int left = (int) FloatMath.floor(layout.getLineLeft(line));
|
||||
int right = (int) FloatMath.ceil(layout.getLineRight(line));
|
||||
int ht = layout.getHeight();
|
||||
|
||||
int hspace = mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight();
|
||||
int vspace = mBottom - mTop - getExtendedPaddingTop() - getExtendedPaddingBottom();
|
||||
if (!mHorizontallyScrolling && right - left > hspace && right > x) {
|
||||
// If cursor has been clamped, make sure we don't scroll.
|
||||
right = Math.max(x, left + hspace);
|
||||
}
|
||||
|
||||
int hslack = (bottom - top) / 2;
|
||||
int vslack = hslack;
|
||||
|
||||
Reference in New Issue
Block a user