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

* commit 'aba62a5925e807f30e3abb1e348738eb342a9888':
  Added a touch up filter in text selection handles.
This commit is contained in:
Gilles Debunne
2011-01-18 08:35:44 -08:00
committed by Android Git Automerger

View File

@@ -7931,9 +7931,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
max = Math.max(0, Math.max(selStart, selEnd)); max = Math.max(0, Math.max(selStart, selEnd));
} }
ClipboardManager clipboard = (ClipboardManager)getContext()
.getSystemService(Context.CLIPBOARD_SERVICE);
switch (id) { switch (id) {
case ID_COPY_URL: case ID_COPY_URL:
URLSpan[] urls = ((Spanned) mText).getSpans(min, max, URLSpan.class); 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 updatePosition(HandleView handle, int x, int y);
public void updateOffset(HandleView handle, int offset);
public void updatePosition(); public void updatePosition();
public int getCurrentOffset(HandleView handle);
/** /**
* This method is called by {@link #onTouchEvent(MotionEvent)} and gives the controller * This method is called by {@link #onTouchEvent(MotionEvent)} and gives the controller
* a chance to become active and/or visible. * 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 class PastePopupMenu implements OnClickListener {
private PopupWindow mContainer; private final PopupWindow mContainer;
private int mPositionX; private int mPositionX;
private int mPositionY; private int mPositionY;
private View mPasteView, mNoPasteView; private View mPasteView, mNoPasteView;
@@ -8519,12 +8520,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
} }
private class HandleView extends View { private class HandleView extends View {
private boolean mPositionOnTop = false;
private Drawable mDrawable; private Drawable mDrawable;
private PopupWindow mContainer; private final PopupWindow mContainer;
private int mPositionX; private int mPositionX;
private int mPositionY; private int mPositionY;
private CursorController mController; private final CursorController mController;
private boolean mIsDragging; private boolean mIsDragging;
private float mTouchToWindowOffsetX; private float mTouchToWindowOffsetX;
private float mTouchToWindowOffsetY; private float mTouchToWindowOffsetY;
@@ -8541,6 +8541,46 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private PastePopupMenu mPastePopupWindow; private PastePopupMenu mPastePopupWindow;
private Runnable mLongPressCallback; 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 LEFT = 0;
public static final int CENTER = 1; public static final int CENTER = 1;
public static final int RIGHT = 2; public static final int RIGHT = 2;
@@ -8736,20 +8776,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override @Override
protected void onDraw(Canvas c) { protected void onDraw(Canvas c) {
mDrawable.setBounds(0, 0, mRight - mLeft, mBottom - mTop); mDrawable.setBounds(0, 0, mRight - mLeft, mBottom - mTop);
if (mPositionOnTop) { mDrawable.draw(c);
c.save();
c.rotate(180, (mRight - mLeft) / 2, (mBottom - mTop) / 2);
mDrawable.draw(c);
c.restore();
} else {
mDrawable.draw(c);
}
} }
@Override @Override
public boolean onTouchEvent(MotionEvent ev) { public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getActionMasked()) { switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN: { case MotionEvent.ACTION_DOWN: {
startTouchUpFilter(mController.getCurrentOffset(this));
mDownPositionX = ev.getRawX(); mDownPositionX = ev.getRawX();
mDownPositionY = ev.getRawY(); mDownPositionY = ev.getRawY();
mTouchToWindowOffsetX = mDownPositionX - mPositionX; mTouchToWindowOffsetX = mDownPositionX - mPositionX;
@@ -8806,6 +8840,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
} }
} }
} }
filterOnTouchUp();
mIsDragging = false; mIsDragging = false;
break; break;
@@ -8823,6 +8858,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
} }
void positionAtCursor(final int offset, boolean bottom) { void positionAtCursor(final int offset, boolean bottom) {
addPositionToTouchUpFilter(offset);
final int width = mDrawable.getIntrinsicWidth(); final int width = mDrawable.getIntrinsicWidth();
final int height = mDrawable.getIntrinsicHeight(); final int height = mDrawable.getIntrinsicHeight();
final int line = mLayout.getLineForOffset(offset); final int line = mLayout.getLineForOffset(offset);
@@ -8938,12 +8974,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
int offset = getHysteresisOffset(x, y, previousOffset); int offset = getHysteresisOffset(x, y, previousOffset);
if (offset != previousOffset) { if (offset != previousOffset) {
Selection.setSelection((Spannable) mText, offset); updateOffset(handle, offset);
updatePosition();
} }
hideDelayed(); hideDelayed();
} }
public void updateOffset(HandleView handle, int offset) {
Selection.setSelection((Spannable) mText, offset);
updatePosition();
}
public void updatePosition() { public void updatePosition() {
final int offset = getSelectionStart(); final int offset = getSelectionStart();
@@ -8957,6 +8997,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
getHandle().positionAtCursor(offset, true); getHandle().positionAtCursor(offset, true);
} }
public int getCurrentOffset(HandleView handle) {
return getSelectionStart();
}
public boolean onTouchEvent(MotionEvent ev) { public boolean onTouchEvent(MotionEvent ev) {
return false; return false;
} }
@@ -9067,6 +9111,20 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
updatePosition(); 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() { public void updatePosition() {
if (!isShowing()) { if (!isShowing()) {
return; return;
@@ -9087,6 +9145,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mEndHandle.positionAtCursor(selectionEnd, true); mEndHandle.positionAtCursor(selectionEnd, true);
} }
public int getCurrentOffset(HandleView handle) {
return mStartHandle == handle ? getSelectionStart() : getSelectionEnd();
}
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
// This is done even when the View does not have focus, so that long presses can start // 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. // selection and tap can move cursor from this tap position.