Merge "Added a touch up filter in text selection handles." into honeycomb

This commit is contained in:
Gilles Debunne
2011-01-18 08:33:42 -08:00
committed by Android (Google) Code Review

View File

@ -7931,9 +7931,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
max = Math.max(0, Math.max(selStart, selEnd));
}
ClipboardManager clipboard = (ClipboardManager)getContext()
.getSystemService(Context.CLIPBOARD_SERVICE);
switch (id) {
case ID_COPY_URL:
URLSpan[] urls = ((Spanned) mText).getSpans(min, max, URLSpan.class);
@ -8402,8 +8399,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
public void updatePosition(HandleView handle, int x, int y);
public void updateOffset(HandleView handle, int offset);
public void updatePosition();
public int getCurrentOffset(HandleView handle);
/**
* This method is called by {@link #onTouchEvent(MotionEvent)} and gives the controller
* a chance to become active and/or visible.
@ -8420,7 +8421,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private class PastePopupMenu implements OnClickListener {
private PopupWindow mContainer;
private final PopupWindow mContainer;
private int mPositionX;
private int mPositionY;
private View mPasteView, mNoPasteView;
@ -8519,12 +8520,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private class HandleView extends View {
private boolean mPositionOnTop = false;
private Drawable mDrawable;
private PopupWindow mContainer;
private final PopupWindow mContainer;
private int mPositionX;
private int mPositionY;
private CursorController mController;
private final CursorController mController;
private boolean mIsDragging;
private float mTouchToWindowOffsetX;
private float mTouchToWindowOffsetY;
@ -8541,6 +8541,46 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private PastePopupMenu mPastePopupWindow;
private Runnable mLongPressCallback;
// Touch-up filter: number of previous positions remembered
private static final int HISTORY_SIZE = 5;
private static final int TOUCH_UP_FILTER_DELAY = 150;
private final long[] mPreviousOffsetsTimes = new long[HISTORY_SIZE];
private final int[] mPreviousOffsets = new int[HISTORY_SIZE];
private int mPreviousOffsetIndex = 0;
private int mNumberPreviousOffsets = 0;
public void startTouchUpFilter(int offset) {
mNumberPreviousOffsets = 0;
addPositionToTouchUpFilter(offset);
}
public void addPositionToTouchUpFilter(int offset) {
if (mNumberPreviousOffsets > 0 &&
mPreviousOffsets[mPreviousOffsetIndex] == offset) {
// Make sure only actual changes of position are recorded.
return;
}
mPreviousOffsetIndex = (mPreviousOffsetIndex + 1) % HISTORY_SIZE;
mPreviousOffsets[mPreviousOffsetIndex] = offset;
mPreviousOffsetsTimes[mPreviousOffsetIndex] = SystemClock.uptimeMillis();
mNumberPreviousOffsets++;
}
public void filterOnTouchUp() {
final long now = SystemClock.uptimeMillis();
int i = 0;
int index = 0;
final int iMax = Math.min(mNumberPreviousOffsets, HISTORY_SIZE);
while (i < iMax) {
index = (mPreviousOffsetIndex - i + HISTORY_SIZE) % HISTORY_SIZE;
if ((now - mPreviousOffsetsTimes[index]) >= TOUCH_UP_FILTER_DELAY) break;
i++;
}
mController.updateOffset(this, mPreviousOffsets[index]);
}
public static final int LEFT = 0;
public static final int CENTER = 1;
public static final int RIGHT = 2;
@ -8736,20 +8776,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
protected void onDraw(Canvas c) {
mDrawable.setBounds(0, 0, mRight - mLeft, mBottom - mTop);
if (mPositionOnTop) {
c.save();
c.rotate(180, (mRight - mLeft) / 2, (mBottom - mTop) / 2);
mDrawable.draw(c);
c.restore();
} else {
mDrawable.draw(c);
}
mDrawable.draw(c);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
startTouchUpFilter(mController.getCurrentOffset(this));
mDownPositionX = ev.getRawX();
mDownPositionY = ev.getRawY();
mTouchToWindowOffsetX = mDownPositionX - mPositionX;
@ -8806,6 +8840,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
}
filterOnTouchUp();
mIsDragging = false;
break;
@ -8823,6 +8858,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
void positionAtCursor(final int offset, boolean bottom) {
addPositionToTouchUpFilter(offset);
final int width = mDrawable.getIntrinsicWidth();
final int height = mDrawable.getIntrinsicHeight();
final int line = mLayout.getLineForOffset(offset);
@ -8938,12 +8974,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
int offset = getHysteresisOffset(x, y, previousOffset);
if (offset != previousOffset) {
Selection.setSelection((Spannable) mText, offset);
updatePosition();
updateOffset(handle, offset);
}
hideDelayed();
}
public void updateOffset(HandleView handle, int offset) {
Selection.setSelection((Spannable) mText, offset);
updatePosition();
}
public void updatePosition() {
final int offset = getSelectionStart();
@ -8957,6 +8997,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
getHandle().positionAtCursor(offset, true);
}
public int getCurrentOffset(HandleView handle) {
return getSelectionStart();
}
public boolean onTouchEvent(MotionEvent ev) {
return false;
}
@ -9067,6 +9111,20 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
updatePosition();
}
public void updateOffset(HandleView handle, int offset) {
int start = getSelectionStart();
int end = getSelectionEnd();
if (mStartHandle == handle) {
start = offset;
} else {
end = offset;
}
Selection.setSelection((Spannable) mText, start, end);
updatePosition();
}
public void updatePosition() {
if (!isShowing()) {
return;
@ -9087,6 +9145,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mEndHandle.positionAtCursor(selectionEnd, true);
}
public int getCurrentOffset(HandleView handle) {
return mStartHandle == handle ? getSelectionStart() : getSelectionEnd();
}
public boolean onTouchEvent(MotionEvent event) {
// 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.