Merge "Popup windows positions are updated when a TextView is scrolled"

This commit is contained in:
Gilles Debunne
2011-09-02 13:24:20 -07:00
committed by Android (Google) Code Review

View File

@@ -9162,6 +9162,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
startDrag(data, getTextThumbnailBuilder(selectedText), localState, 0); startDrag(data, getTextThumbnailBuilder(selectedText), localState, 0);
stopSelectionActionMode(); stopSelectionActionMode();
} else { } else {
getSelectionController().hide();
selectCurrentWord(); selectCurrentWord();
getSelectionController().show(); getSelectionController().show();
} }
@@ -9209,7 +9210,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
} }
private interface TextViewPositionListener { private interface TextViewPositionListener {
public void updatePosition(int parentPositionX, int parentPositionY, boolean modified); public void updatePosition(int parentPositionX, int parentPositionY,
boolean parentPositionChanged, boolean parentScrolled);
} }
private class PositionListener implements ViewTreeObserver.OnPreDrawListener { private class PositionListener implements ViewTreeObserver.OnPreDrawListener {
@@ -9222,6 +9224,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Absolute position of the TextView with respect to its parent window // Absolute position of the TextView with respect to its parent window
private int mPositionX, mPositionY; private int mPositionX, mPositionY;
private int mNumberOfListeners; private int mNumberOfListeners;
private boolean mScrollHasChanged;
public void addSubscriber(TextViewPositionListener positionListener, boolean canMove) { public void addSubscriber(TextViewPositionListener positionListener, boolean canMove) {
if (mNumberOfListeners == 0) { if (mNumberOfListeners == 0) {
@@ -9273,15 +9276,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
updatePosition(); updatePosition();
for (int i = 0; i < MAXIMUM_NUMBER_OF_LISTENERS; i++) { for (int i = 0; i < MAXIMUM_NUMBER_OF_LISTENERS; i++) {
if (mPositionHasChanged || mCanMove[i]) { if (mPositionHasChanged || mScrollHasChanged || mCanMove[i]) {
TextViewPositionListener positionListener = mPositionListeners[i]; TextViewPositionListener positionListener = mPositionListeners[i];
if (positionListener != null) { if (positionListener != null) {
positionListener.updatePosition(mPositionX, mPositionY, positionListener.updatePosition(mPositionX, mPositionY,
mPositionHasChanged); mPositionHasChanged, mScrollHasChanged);
} }
} }
} }
mScrollHasChanged = false;
return true; return true;
} }
@@ -9323,6 +9327,18 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final int primaryHorizontal = (int) mLayout.getPrimaryHorizontal(offset); final int primaryHorizontal = (int) mLayout.getPrimaryHorizontal(offset);
return isVisible(primaryHorizontal, lineBottom); return isVisible(primaryHorizontal, lineBottom);
} }
public void onScrollChanged() {
mScrollHasChanged = true;
}
}
@Override
protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) {
super.onScrollChanged(horiz, vert, oldHoriz, oldVert);
if (mPositionListener != null) {
mPositionListener.onScrollChanged();
}
} }
private abstract class PinnedPopupWindow implements TextViewPositionListener { private abstract class PinnedPopupWindow implements TextViewPositionListener {
@@ -9353,7 +9369,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
} }
public void show() { public void show() {
TextView.this.getPositionListener().addSubscriber(this, false); TextView.this.getPositionListener().addSubscriber(this, false /* offset is fixed */);
computeLocalPosition(); computeLocalPosition();
@@ -9412,8 +9428,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
} }
@Override @Override
public void updatePosition(int parentPositionX, int parentPositionY, boolean modified) { public void updatePosition(int parentPositionX, int parentPositionY,
boolean parentPositionChanged, boolean parentScrolled) {
// Either parentPositionChanged or parentScrolled is true, check if still visible
if (isShowing() && getPositionListener().isOffsetVisible(getTextOffset())) { if (isShowing() && getPositionListener().isOffsetVisible(getTextOffset())) {
if (parentScrolled) computeLocalPosition();
updatePosition(parentPositionX, parentPositionY); updatePosition(parentPositionX, parentPositionY);
} else { } else {
hide(); hide();
@@ -10366,7 +10385,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (i > 0 && i < iMax && if (i > 0 && i < iMax &&
(now - mPreviousOffsetsTimes[index]) > TOUCH_UP_FILTER_DELAY_BEFORE) { (now - mPreviousOffsetsTimes[index]) > TOUCH_UP_FILTER_DELAY_BEFORE) {
positionAtCursorOffset(mPreviousOffsets[index]); positionAtCursorOffset(mPreviousOffsets[index], false);
} }
} }
@@ -10382,11 +10401,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public void show() { public void show() {
if (isShowing()) return; if (isShowing()) return;
getPositionListener().addSubscriber(this, true); getPositionListener().addSubscriber(this, true /* local position may change */);
// Make sure the offset is always considered new, even when focusing at same position // Make sure the offset is always considered new, even when focusing at same position
mPreviousOffset = -1; mPreviousOffset = -1;
positionAtCursorOffset(getCurrentCursorOffset()); positionAtCursorOffset(getCurrentCursorOffset(), false);
hideActionPopupWindow(); hideActionPopupWindow();
} }
@@ -10451,7 +10470,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public abstract void updatePosition(float x, float y); public abstract void updatePosition(float x, float y);
protected void positionAtCursorOffset(int offset) { protected void positionAtCursorOffset(int offset, boolean parentScrolled) {
// A HandleView relies on the layout, which may be nulled by external methods // A HandleView relies on the layout, which may be nulled by external methods
if (mLayout == null) { if (mLayout == null) {
// Will update controllers' state, hiding them and stopping selection mode if needed // Will update controllers' state, hiding them and stopping selection mode if needed
@@ -10459,7 +10478,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return; return;
} }
if (offset != mPreviousOffset) { if (offset != mPreviousOffset || parentScrolled) {
updateSelection(offset); updateSelection(offset);
addPositionToTouchUpFilter(offset); addPositionToTouchUpFilter(offset);
final int line = mLayout.getLineForOffset(offset); final int line = mLayout.getLineForOffset(offset);
@@ -10476,9 +10495,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
} }
} }
public void updatePosition(int parentPositionX, int parentPositionY, boolean modified) { public void updatePosition(int parentPositionX, int parentPositionY,
positionAtCursorOffset(getCurrentCursorOffset()); boolean parentPositionChanged, boolean parentScrolled) {
if (modified || mPositionHasChanged) { positionAtCursorOffset(getCurrentCursorOffset(), parentScrolled);
if (parentPositionChanged || mPositionHasChanged) {
if (mIsDragging) { if (mIsDragging) {
// Update touchToWindow offset in case of parent scrolling while dragging // Update touchToWindow offset in case of parent scrolling while dragging
if (parentPositionX != mLastParentX || parentPositionY != mLastParentY) { if (parentPositionX != mLastParentX || parentPositionY != mLastParentY) {
@@ -10683,7 +10703,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override @Override
public void updatePosition(float x, float y) { public void updatePosition(float x, float y) {
positionAtCursorOffset(getOffsetForPosition(x, y)); positionAtCursorOffset(getOffsetForPosition(x, y), false);
} }
@Override @Override
@@ -10722,17 +10742,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override @Override
public void updatePosition(float x, float y) { public void updatePosition(float x, float y) {
final int selectionStart = getSelectionStart();
final int selectionEnd = getSelectionEnd();
int offset = getOffsetForPosition(x, y); int offset = getOffsetForPosition(x, y);
// No need to redraw when the offset is unchanged
if (offset == selectionStart) return;
// Handles can not cross and selection is at least one character // Handles can not cross and selection is at least one character
final int selectionEnd = getSelectionEnd();
if (offset >= selectionEnd) offset = selectionEnd - 1; if (offset >= selectionEnd) offset = selectionEnd - 1;
positionAtCursorOffset(offset); positionAtCursorOffset(offset, false);
} }
public ActionPopupWindow getActionPopupWindow() { public ActionPopupWindow getActionPopupWindow() {
@@ -10763,17 +10779,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override @Override
public void updatePosition(float x, float y) { public void updatePosition(float x, float y) {
final int selectionStart = getSelectionStart();
final int selectionEnd = getSelectionEnd();
int offset = getOffsetForPosition(x, y); int offset = getOffsetForPosition(x, y);
// No need to redraw when the offset is unchanged
if (offset == selectionEnd) return;
// Handles can not cross and selection is at least one character // Handles can not cross and selection is at least one character
final int selectionStart = getSelectionStart();
if (offset <= selectionStart) offset = selectionStart + 1; if (offset <= selectionStart) offset = selectionStart + 1;
positionAtCursorOffset(offset); positionAtCursorOffset(offset, false);
} }
public void setActionPopupWindow(ActionPopupWindow actionPopupWindow) { public void setActionPopupWindow(ActionPopupWindow actionPopupWindow) {