TextView uses floats for touch event positions.

This is the type returned by event.getX/Y methods. Conversion
to ints is only performed when needed. Low performance impact
since there is only a minimal amount of computations on these
values.

Change-Id: I53a56efe5e3a1a96911adc25fedaab7f40f1ba8e
This commit is contained in:
Gilles Debunne
2011-05-23 18:20:22 -07:00
parent 37cd57772b
commit 3bca69b09f
2 changed files with 48 additions and 60 deletions

View File

@@ -234,7 +234,7 @@ public class ArrowKeyMovementMethod extends BaseMovementMethod implements Moveme
if (action == MotionEvent.ACTION_DOWN) {
boolean cap = isSelecting(buffer);
if (cap) {
int offset = widget.getOffset((int) event.getX(), (int) event.getY());
int offset = widget.getOffsetForPosition(event.getX(), event.getY());
buffer.setSpan(LAST_TAP_DOWN, offset, offset, Spannable.SPAN_POINT_POINT);
@@ -259,7 +259,7 @@ public class ArrowKeyMovementMethod extends BaseMovementMethod implements Moveme
// Update selection as we're moving the selection area.
// Get the current touch position
int offset = widget.getOffset((int) event.getX(), (int) event.getY());
int offset = widget.getOffsetForPosition(event.getX(), event.getY());
Selection.extendSelection(buffer, offset);
return true;
@@ -275,7 +275,7 @@ public class ArrowKeyMovementMethod extends BaseMovementMethod implements Moveme
return true;
}
int offset = widget.getOffset((int) event.getX(), (int) event.getY());
int offset = widget.getOffsetForPosition(event.getX(), event.getY());
if (isSelecting(buffer)) {
buffer.removeSpan(LAST_TAP_DOWN);
Selection.extendSelection(buffer, offset);

View File

@@ -16,11 +16,6 @@
package android.widget;
import com.android.internal.util.FastMath;
import com.android.internal.widget.EditableInputConnection;
import org.xmlpull.v1.XmlPullParserException;
import android.R;
import android.content.ClipData;
import android.content.ClipData.Item;
@@ -129,6 +124,11 @@ import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.RemoteViews.RemoteView;
import com.android.internal.util.FastMath;
import com.android.internal.widget.EditableInputConnection;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.text.BreakIterator;
@@ -329,7 +329,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private Drawable mSelectHandleRight;
private Drawable mSelectHandleCenter;
private int mLastDownPositionX, mLastDownPositionY;
private float mLastDownPositionX, mLastDownPositionY;
private Callback mCustomSelectionActionModeCallback;
private final int mSquaredTouchSlopDistance;
@@ -2898,8 +2898,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
setText(mCharWrapper, mBufferType, false, oldlen);
}
private static class CharWrapper
implements CharSequence, GetChars, GraphicsOperations {
private static class CharWrapper implements CharSequence, GetChars, GraphicsOperations {
private char[] mChars;
private int mStart, mLength;
@@ -7323,8 +7322,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
if (action == MotionEvent.ACTION_DOWN) {
mLastDownPositionX = (int) event.getX();
mLastDownPositionY = (int) event.getY();
mLastDownPositionX = event.getX();
mLastDownPositionY = event.getY();
// Reset this state; it will be re-set if super.onTouchEvent
// causes focus to move to the view.
@@ -7758,16 +7757,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
hasPrimaryClip());
}
private boolean isWordCharacter(int c, int type) {
return (c == '\'' || c == '"' ||
type == Character.UPPERCASE_LETTER ||
type == Character.LOWERCASE_LETTER ||
type == Character.TITLECASE_LETTER ||
type == Character.MODIFIER_LETTER ||
type == Character.OTHER_LETTER || // Should handle asian characters
type == Character.DECIMAL_DIGIT_NUMBER);
}
private static long packRangeInLong(int start, int end) {
return (((long) start) << 32) | end;
}
@@ -8140,7 +8129,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Long press in empty space moves cursor and shows the Paste affordance if available.
if (!isPositionOnText(mLastDownPositionX, mLastDownPositionY) &&
mInsertionControllerEnabled) {
final int offset = getOffset(mLastDownPositionX, mLastDownPositionY);
final int offset = getOffsetForPosition(mLastDownPositionX, mLastDownPositionY);
stopSelectionActionMode();
Selection.setSelection((Spannable) mText, offset);
getInsertionController().showWithPaste();
@@ -8208,7 +8197,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private final ViewGroup[] mSuggestionViews = new ViewGroup[2];
private final int[] mSuggestionViewLayouts = new int[] {
mTextEditSuggestionsBottomWindowLayout, mTextEditSuggestionsTopWindowLayout};
private WordIterator mWordIterator;
private WordIterator mSuggestionWordIterator;
private TextAppearanceSpan[] mHighlightSpans = new TextAppearanceSpan[0];
public SuggestionsPopupWindow() {
@@ -8344,26 +8333,27 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private long[] getWordLimits(CharSequence text) {
if (mWordIterator == null) mWordIterator = new WordIterator(); // TODO locale
mWordIterator.setCharSequence(text);
// TODO locale for mSuggestionWordIterator
if (mSuggestionWordIterator == null) mSuggestionWordIterator = new WordIterator();
mSuggestionWordIterator.setCharSequence(text);
// First pass will simply count the number of words to be able to create an array
// Not too expensive since previous break positions are cached by the BreakIterator
int nbWords = 0;
int position = mWordIterator.following(0);
int position = mSuggestionWordIterator.following(0);
while (position != BreakIterator.DONE) {
nbWords++;
position = mWordIterator.following(position);
position = mSuggestionWordIterator.following(position);
}
int index = 0;
long[] result = new long[nbWords];
position = mWordIterator.following(0);
position = mSuggestionWordIterator.following(0);
while (position != BreakIterator.DONE) {
int wordStart = mWordIterator.getBeginning(position);
int wordStart = mSuggestionWordIterator.getBeginning(position);
result[index++] = packRangeInLong(wordStart, position);
position = mWordIterator.following(position);
position = mSuggestionWordIterator.following(position);
}
return result;
@@ -9115,7 +9105,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public abstract void updateOffset(int offset);
public abstract void updatePosition(int x, int y);
public abstract void updatePosition(float x, float y);
protected void positionAtCursorOffset(int offset) {
addPositionToTouchUpFilter(offset);
@@ -9215,7 +9205,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final float newPosX = rawX - mTouchToWindowOffsetX + mHotspotX;
final float newPosY = rawY - mTouchToWindowOffsetY + mTouchOffsetY;
updatePosition(Math.round(newPosX), Math.round(newPosY));
updatePosition(newPosX, newPosY);
break;
}
@@ -9366,8 +9356,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
@Override
public void updatePosition(int x, int y) {
updateOffset(getOffset(x, y));
public void updatePosition(float x, float y) {
updateOffset(getOffsetForPosition(x, y));
}
void showPastePopupWindow() {
@@ -9421,11 +9411,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
@Override
public void updatePosition(int x, int y) {
public void updatePosition(float x, float y) {
final int selectionStart = getSelectionStart();
final int selectionEnd = getSelectionEnd();
int offset = getOffset(x, y);
int offset = getOffsetForPosition(x, y);
// No need to redraw when the offset is unchanged
if (offset == selectionStart) return;
@@ -9458,11 +9448,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
@Override
public void updatePosition(int x, int y) {
public void updatePosition(float x, float y) {
final int selectionStart = getSelectionStart();
final int selectionEnd = getSelectionEnd();
int offset = getOffset(x, y);
int offset = getOffsetForPosition(x, y);
// No need to redraw when the offset is unchanged
if (offset == selectionEnd) return;
@@ -9560,7 +9550,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Double tap detection
private long mPreviousTapUpTime = 0;
private int mPreviousTapPositionX, mPreviousTapPositionY;
private float mPreviousTapPositionX, mPreviousTapPositionY;
SelectionModifierCursorController() {
resetTouchOffsets();
@@ -9593,19 +9583,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (isTextEditable() || mTextIsSelectable) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
final int x = (int) event.getX();
final int y = (int) event.getY();
final float x = event.getX();
final float y = event.getY();
// Remember finger down position, to be able to start selection from there
mMinTouchOffset = mMaxTouchOffset = getOffset(x, y);
mMinTouchOffset = mMaxTouchOffset = getOffsetForPosition(x, y);
// Double tap detection
long duration = SystemClock.uptimeMillis() - mPreviousTapUpTime;
if (duration <= ViewConfiguration.getDoubleTapTimeout() &&
isPositionOnText(x, y)) {
final int deltaX = x - mPreviousTapPositionX;
final int deltaY = y - mPreviousTapPositionY;
final int distanceSquared = deltaX * deltaX + deltaY * deltaY;
final float deltaX = x - mPreviousTapPositionX;
final float deltaY = y - mPreviousTapPositionY;
final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
if (distanceSquared < mSquaredTouchSlopDistance) {
showSuggestions();
mDiscardNextActionUp = true;
@@ -9641,9 +9631,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private void updateMinAndMaxOffsets(MotionEvent event) {
int pointerCount = event.getPointerCount();
for (int index = 0; index < pointerCount; index++) {
final int x = (int) event.getX(index);
final int y = (int) event.getY(index);
int offset = getOffset(x, y);
int offset = getOffsetForPosition(event.getX(index), event.getY(index));
if (offset < mMinTouchOffset) mMinTouchOffset = offset;
if (offset > mMaxTouchOffset) mMaxTouchOffset = offset;
}
@@ -9710,32 +9698,32 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @hide
*/
public int getOffset(int x, int y) {
public int getOffsetForPosition(float x, float y) {
if (getLayout() == null) return -1;
final int line = getLineAtCoordinate(y);
final int offset = getOffsetAtCoordinate(line, x);
return offset;
}
private int convertToLocalHorizontalCoordinate(int x) {
private float convertToLocalHorizontalCoordinate(float x) {
x -= getTotalPaddingLeft();
// Clamp the position to inside of the view.
x = Math.max(0, x);
x = Math.max(0.0f, x);
x = Math.min(getWidth() - getTotalPaddingRight() - 1, x);
x += getScrollX();
return x;
}
private int getLineAtCoordinate(int y) {
private int getLineAtCoordinate(float y) {
y -= getTotalPaddingTop();
// Clamp the position to inside of the view.
y = Math.max(0, y);
y = Math.max(0.0f, y);
y = Math.min(getHeight() - getTotalPaddingBottom() - 1, y);
y += getScrollY();
return getLayout().getLineForVertical(y);
return getLayout().getLineForVertical((int) y);
}
private int getOffsetAtCoordinate(int line, int x) {
private int getOffsetAtCoordinate(int line, float x) {
x = convertToLocalHorizontalCoordinate(x);
return getLayout().getOffsetForHorizontal(line, x);
}
@@ -9743,7 +9731,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
/** Returns true if the screen coordinates position (x,y) corresponds to a character displayed
* in the view. Returns false when the position is in the empty space of left/right of text.
*/
private boolean isPositionOnText(int x, int y) {
private boolean isPositionOnText(float x, float y) {
if (getLayout() == null) return false;
final int line = getLineAtCoordinate(y);
@@ -9765,7 +9753,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return true;
case DragEvent.ACTION_DRAG_LOCATION:
final int offset = getOffset((int) event.getX(), (int) event.getY());
final int offset = getOffsetForPosition(event.getX(), event.getY());
Selection.setSelection((Spannable)mText, offset);
return true;
@@ -9789,7 +9777,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
content.append(item.coerceToText(TextView.this.mContext));
}
final int offset = getOffset((int) event.getX(), (int) event.getY());
final int offset = getOffsetForPosition(event.getX(), event.getY());
Object localState = event.getLocalState();
DragLocalState dragLocalState = null;