From 3bca69b09fb51116b5eb18fb91cb991c1450e384 Mon Sep 17 00:00:00 2001 From: Gilles Debunne Date: Mon, 23 May 2011 18:20:22 -0700 Subject: [PATCH] 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 --- .../text/method/ArrowKeyMovementMethod.java | 6 +- core/java/android/widget/TextView.java | 102 ++++++++---------- 2 files changed, 48 insertions(+), 60 deletions(-) diff --git a/core/java/android/text/method/ArrowKeyMovementMethod.java b/core/java/android/text/method/ArrowKeyMovementMethod.java index d432deef44bb4..fe965651f70e5 100644 --- a/core/java/android/text/method/ArrowKeyMovementMethod.java +++ b/core/java/android/text/method/ArrowKeyMovementMethod.java @@ -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); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index d58c72b4a846a..d6c8b2b8d2c1d 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -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;