summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
authorGilles Debunne <debunne@google.com>2010-07-13 15:10:08 -0700
committerGilles Debunne <debunne@google.com>2010-07-13 15:10:08 -0700
commitd11f6e6460dcc41597e3a7f6cd3023f116f8c696 (patch)
tree7a89f6ceb9a178ceda3c4887c8cd43ed38a9f7c8 /core/java/android
parentf35c96bb498ffa7b3348b4bf17e9e7475f6bb324 (diff)
downloadframeworks_base-d11f6e6460dcc41597e3a7f6cd3023f116f8c696.zip
frameworks_base-d11f6e6460dcc41597e3a7f6cd3023f116f8c696.tar.gz
frameworks_base-d11f6e6460dcc41597e3a7f6cd3023f116f8c696.tar.bz2
Double and one and a half tap removed from TextView.
Text selection is now triggered by a long press. This behavior should be shared across applications and is already implemented in the browser. New UI guidelines say that double tap should be used for zooming only. Change-Id: I9fae692cf3f6e565350f666fa3d5a86884439349
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/text/method/ArrowKeyMovementMethod.java266
1 files changed, 35 insertions, 231 deletions
diff --git a/core/java/android/text/method/ArrowKeyMovementMethod.java b/core/java/android/text/method/ArrowKeyMovementMethod.java
index 55ec655..79a0c37 100644
--- a/core/java/android/text/method/ArrowKeyMovementMethod.java
+++ b/core/java/android/text/method/ArrowKeyMovementMethod.java
@@ -17,13 +17,11 @@
package android.text.method;
import android.text.Layout;
-import android.text.NoCopySpan;
import android.text.Selection;
import android.text.Spannable;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewConfiguration;
import android.widget.TextView;
import android.widget.TextView.CursorController;
@@ -38,13 +36,18 @@ public class ArrowKeyMovementMethod implements MovementMethod {
*/
protected CursorController mCursorController;
+ private boolean isCap(Spannable buffer) {
+ return ((MetaKeyKeyListener.getMetaState(buffer, KeyEvent.META_SHIFT_ON) == 1) ||
+ (MetaKeyKeyListener.getMetaState(buffer, MetaKeyKeyListener.META_SELECTING) != 0));
+ }
+
+ private boolean isAlt(Spannable buffer) {
+ return MetaKeyKeyListener.getMetaState(buffer, KeyEvent.META_ALT_ON) == 1;
+ }
+
private boolean up(TextView widget, Spannable buffer) {
- boolean cap = (MetaKeyKeyListener.getMetaState(buffer,
- KeyEvent.META_SHIFT_ON) == 1) ||
- (MetaKeyKeyListener.getMetaState(buffer,
- MetaKeyKeyListener.META_SELECTING) != 0);
- boolean alt = MetaKeyKeyListener.getMetaState(buffer,
- KeyEvent.META_ALT_ON) == 1;
+ boolean cap = isCap(buffer);
+ boolean alt = isAlt(buffer);
Layout layout = widget.getLayout();
if (cap) {
@@ -65,12 +68,8 @@ public class ArrowKeyMovementMethod implements MovementMethod {
}
private boolean down(TextView widget, Spannable buffer) {
- boolean cap = (MetaKeyKeyListener.getMetaState(buffer,
- KeyEvent.META_SHIFT_ON) == 1) ||
- (MetaKeyKeyListener.getMetaState(buffer,
- MetaKeyKeyListener.META_SELECTING) != 0);
- boolean alt = MetaKeyKeyListener.getMetaState(buffer,
- KeyEvent.META_ALT_ON) == 1;
+ boolean cap = isCap(buffer);
+ boolean alt = isAlt(buffer);
Layout layout = widget.getLayout();
if (cap) {
@@ -91,12 +90,8 @@ public class ArrowKeyMovementMethod implements MovementMethod {
}
private boolean left(TextView widget, Spannable buffer) {
- boolean cap = (MetaKeyKeyListener.getMetaState(buffer,
- KeyEvent.META_SHIFT_ON) == 1) ||
- (MetaKeyKeyListener.getMetaState(buffer,
- MetaKeyKeyListener.META_SELECTING) != 0);
- boolean alt = MetaKeyKeyListener.getMetaState(buffer,
- KeyEvent.META_ALT_ON) == 1;
+ boolean cap = isCap(buffer);
+ boolean alt = isAlt(buffer);
Layout layout = widget.getLayout();
if (cap) {
@@ -115,12 +110,8 @@ public class ArrowKeyMovementMethod implements MovementMethod {
}
private boolean right(TextView widget, Spannable buffer) {
- boolean cap = (MetaKeyKeyListener.getMetaState(buffer,
- KeyEvent.META_SHIFT_ON) == 1) ||
- (MetaKeyKeyListener.getMetaState(buffer,
- MetaKeyKeyListener.META_SELECTING) != 0);
- boolean alt = MetaKeyKeyListener.getMetaState(buffer,
- KeyEvent.META_ALT_ON) == 1;
+ boolean cap = isCap(buffer);
+ boolean alt = isAlt(buffer);
Layout layout = widget.getLayout();
if (cap) {
@@ -169,10 +160,9 @@ public class ArrowKeyMovementMethod implements MovementMethod {
break;
case KeyEvent.KEYCODE_DPAD_CENTER:
- if (MetaKeyKeyListener.getMetaState(buffer, MetaKeyKeyListener.META_SELECTING) != 0) {
- if (widget.showContextMenu()) {
+ if ((MetaKeyKeyListener.getMetaState(buffer, MetaKeyKeyListener.META_SELECTING) != 0) &&
+ (widget.showContextMenu())) {
handled = true;
- }
}
}
@@ -190,8 +180,7 @@ public class ArrowKeyMovementMethod implements MovementMethod {
public boolean onKeyOther(TextView view, Spannable text, KeyEvent event) {
int code = event.getKeyCode();
- if (code != KeyEvent.KEYCODE_UNKNOWN
- && event.getAction() == KeyEvent.ACTION_MULTIPLE) {
+ if (code != KeyEvent.KEYCODE_UNKNOWN && event.getAction() == KeyEvent.ACTION_MULTIPLE) {
int repeat = event.getRepeatCount();
boolean handled = false;
while ((--repeat) > 0) {
@@ -228,54 +217,20 @@ public class ArrowKeyMovementMethod implements MovementMethod {
if (widget.isFocused() && !widget.didTouchFocusSelect()) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
- boolean cap = (MetaKeyKeyListener.getMetaState(buffer,
- KeyEvent.META_SHIFT_ON) == 1) ||
- (MetaKeyKeyListener.getMetaState(buffer,
- MetaKeyKeyListener.META_SELECTING) != 0);
- int x = (int) event.getX();
- int y = (int) event.getY();
- int offset = widget.getOffset(x, y);
-
+ boolean cap = isCap(buffer);
if (cap) {
- buffer.setSpan(LAST_TAP_DOWN, offset, offset,
- Spannable.SPAN_POINT_POINT);
+ int offset = widget.getOffset((int) event.getX(), (int) event.getY());
+
+ buffer.setSpan(LAST_TAP_DOWN, offset, offset, Spannable.SPAN_POINT_POINT);
// Disallow intercepting of the touch events, so that
// users can scroll and select at the same time.
// without this, users would get booted out of select
// mode once the view detected it needed to scroll.
widget.getParent().requestDisallowInterceptTouchEvent(true);
- } else {
- OnePointFiveTapState[] tap = buffer.getSpans(0, buffer.length(),
- OnePointFiveTapState.class);
-
- if (tap.length > 0) {
- if (event.getEventTime() - tap[0].mWhen <=
- ViewConfiguration.getDoubleTapTimeout() &&
- sameWord(buffer, offset, Selection.getSelectionEnd(buffer))) {
-
- tap[0].active = true;
- MetaKeyKeyListener.startSelecting(widget, buffer);
- widget.getParent().requestDisallowInterceptTouchEvent(true);
- buffer.setSpan(LAST_TAP_DOWN, offset, offset,
- Spannable.SPAN_POINT_POINT);
- }
-
- tap[0].mWhen = event.getEventTime();
- } else {
- OnePointFiveTapState newtap = new OnePointFiveTapState();
- newtap.mWhen = event.getEventTime();
- newtap.active = false;
- buffer.setSpan(newtap, 0, buffer.length(),
- Spannable.SPAN_INCLUSIVE_INCLUSIVE);
- }
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
- boolean cap = (MetaKeyKeyListener.getMetaState(buffer,
- KeyEvent.META_SHIFT_ON) == 1) ||
- (MetaKeyKeyListener.getMetaState(buffer,
- MetaKeyKeyListener.META_SELECTING) != 0);
-
+ boolean cap = isCap(buffer);
if (cap && handled) {
// Before selecting, make sure we've moved out of the "slop".
@@ -289,39 +244,9 @@ public class ArrowKeyMovementMethod implements MovementMethod {
// Update selection as we're moving the selection area.
// Get the current touch position
- int x = (int) event.getX();
- int y = (int) event.getY();
- int offset = widget.getOffset(x, y);
-
- final OnePointFiveTapState[] tap = buffer.getSpans(0, buffer.length(),
- OnePointFiveTapState.class);
-
- if (tap.length > 0 && tap[0].active) {
- // Get the last down touch position (the position at which the
- // user started the selection)
- int lastDownOffset = buffer.getSpanStart(LAST_TAP_DOWN);
-
- // Compute the selection boundaries
- int spanstart;
- int spanend;
- if (offset >= lastDownOffset) {
- // Expand from word start of the original tap to new word
- // end, since we are selecting "forwards"
- spanstart = findWordStart(buffer, lastDownOffset);
- spanend = findWordEnd(buffer, offset);
- } else {
- // Expand to from new word start to word end of the original
- // tap since we are selecting "backwards".
- // The spanend will always need to be associated with the touch
- // up position, so that refining the selection with the
- // trackball will work as expected.
- spanstart = findWordEnd(buffer, lastDownOffset);
- spanend = findWordStart(buffer, offset);
- }
- Selection.setSelection(buffer, spanstart, spanend);
- } else {
- Selection.extendSelection(buffer, offset);
- }
+ int offset = widget.getOffset((int) event.getX(), (int) event.getY());
+
+ Selection.extendSelection(buffer, offset);
return true;
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
@@ -330,70 +255,17 @@ public class ArrowKeyMovementMethod implements MovementMethod {
// the current scroll offset to avoid the scroll jumping later
// to show it.
if ((initialScrollY >= 0 && initialScrollY != widget.getScrollY()) ||
- (initialScrollX >= 0 && initialScrollX != widget.getScrollX())) {
+ (initialScrollX >= 0 && initialScrollX != widget.getScrollX())) {
widget.moveCursorToVisibleOffset();
return true;
}
- int x = (int) event.getX();
- int y = (int) event.getY();
- int off = widget.getOffset(x, y);
-
- // XXX should do the same adjust for x as we do for the line.
-
- OnePointFiveTapState[] onepointfivetap = buffer.getSpans(0, buffer.length(),
- OnePointFiveTapState.class);
- if (onepointfivetap.length > 0 && onepointfivetap[0].active &&
- Selection.getSelectionStart(buffer) == Selection.getSelectionEnd(buffer)) {
- // If we've set select mode, because there was a onepointfivetap,
- // but there was no ensuing swipe gesture, undo the select mode
- // and remove reference to the last onepointfivetap.
- MetaKeyKeyListener.stopSelecting(widget, buffer);
- for (int i=0; i < onepointfivetap.length; i++) {
- buffer.removeSpan(onepointfivetap[i]);
- }
+ int offset = widget.getOffset((int) event.getX(), (int) event.getY());
+ if (isCap(buffer)) {
buffer.removeSpan(LAST_TAP_DOWN);
- }
- boolean cap = (MetaKeyKeyListener.getMetaState(buffer,
- KeyEvent.META_SHIFT_ON) == 1) ||
- (MetaKeyKeyListener.getMetaState(buffer,
- MetaKeyKeyListener.META_SELECTING) != 0);
-
- DoubleTapState[] tap = buffer.getSpans(0, buffer.length(),
- DoubleTapState.class);
- boolean doubletap = false;
-
- if (tap.length > 0) {
- if (event.getEventTime() - tap[0].mWhen <=
- ViewConfiguration.getDoubleTapTimeout() &&
- sameWord(buffer, off, Selection.getSelectionEnd(buffer))) {
-
- doubletap = true;
- }
-
- tap[0].mWhen = event.getEventTime();
+ Selection.extendSelection(buffer, offset);
} else {
- DoubleTapState newtap = new DoubleTapState();
- newtap.mWhen = event.getEventTime();
- buffer.setSpan(newtap, 0, buffer.length(),
- Spannable.SPAN_INCLUSIVE_INCLUSIVE);
- }
-
- if (cap) {
- buffer.removeSpan(LAST_TAP_DOWN);
- if (onepointfivetap.length > 0 && onepointfivetap[0].active) {
- // If we selecting something with the onepointfivetap-and
- // swipe gesture, stop it on finger up.
- MetaKeyKeyListener.stopSelecting(widget, buffer);
- } else {
- Selection.extendSelection(buffer, off);
- }
- } else if (doubletap) {
- Selection.setSelection(buffer,
- findWordStart(buffer, off),
- findWordEnd(buffer, off));
- } else {
- Selection.setSelection(buffer, off);
+ Selection.setSelection(buffer, offset);
}
MetaKeyKeyListener.adjustMetaAfterKeypress(buffer);
@@ -438,75 +310,6 @@ public class ArrowKeyMovementMethod implements MovementMethod {
mCursorController = cursorController;
}
- private static class DoubleTapState implements NoCopySpan {
- long mWhen;
- }
-
- /* We check for a onepointfive tap. This is similar to
- * doubletap gesture (where a finger goes down, up, down, up, in a short
- * time period), except in the onepointfive tap, a users finger only needs
- * to go down, up, down in a short time period. We detect this type of tap
- * to implement the onepointfivetap-and-swipe selection gesture.
- * This gesture allows users to select a segment of text without going
- * through the "select text" option in the context menu.
- */
- private static class OnePointFiveTapState implements NoCopySpan {
- long mWhen;
- boolean active;
- }
-
- private static boolean sameWord(CharSequence text, int one, int two) {
- int start = findWordStart(text, one);
- int end = findWordEnd(text, one);
-
- if (end == start) {
- return false;
- }
-
- return start == findWordStart(text, two) &&
- end == findWordEnd(text, two);
- }
-
- // TODO: Unify with TextView.getWordForDictionary()
- private static int findWordStart(CharSequence text, int start) {
- for (; start > 0; start--) {
- char c = text.charAt(start - 1);
- int type = Character.getType(c);
-
- if (c != '\'' &&
- type != Character.UPPERCASE_LETTER &&
- type != Character.LOWERCASE_LETTER &&
- type != Character.TITLECASE_LETTER &&
- type != Character.MODIFIER_LETTER &&
- type != Character.DECIMAL_DIGIT_NUMBER) {
- break;
- }
- }
-
- return start;
- }
-
- // TODO: Unify with TextView.getWordForDictionary()
- private static int findWordEnd(CharSequence text, int end) {
- int len = text.length();
-
- for (; end < len; end++) {
- char c = text.charAt(end);
- int type = Character.getType(c);
-
- if (c != '\'' &&
- type != Character.UPPERCASE_LETTER &&
- type != Character.LOWERCASE_LETTER &&
- type != Character.TITLECASE_LETTER &&
- type != Character.MODIFIER_LETTER &&
- type != Character.DECIMAL_DIGIT_NUMBER) {
- break;
- }
- }
-
- return end;
- }
-
public boolean canSelectArbitrarily() {
return true;
}
@@ -543,8 +346,9 @@ public class ArrowKeyMovementMethod implements MovementMethod {
}
public static MovementMethod getInstance() {
- if (sInstance == null)
+ if (sInstance == null) {
sInstance = new ArrowKeyMovementMethod();
+ }
return sInstance;
}