summaryrefslogtreecommitdiffstats
path: root/core/java/android/text/method
diff options
context:
space:
mode:
authorAndroid (Google) Code Review <android-gerrit@google.com>2009-12-07 07:14:41 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2009-12-07 07:14:41 -0800
commit7c42703082574638ecaa88ea18b0cc94bfabea2d (patch)
tree5cb556a7904a4e83469a7a3f1c1d3516360d4d4f /core/java/android/text/method
parent401f422078581ae741b68d879609e57a4b227455 (diff)
parentce08379e22609415971ece6ba3417d6d3fd338d2 (diff)
downloadframeworks_base-7c42703082574638ecaa88ea18b0cc94bfabea2d.zip
frameworks_base-7c42703082574638ecaa88ea18b0cc94bfabea2d.tar.gz
frameworks_base-7c42703082574638ecaa88ea18b0cc94bfabea2d.tar.bz2
Merge change I9088d29b into eclair-mr2
* changes: Improves the touch-based text selection UI in text boxes.
Diffstat (limited to 'core/java/android/text/method')
-rw-r--r--core/java/android/text/method/ArrowKeyMovementMethod.java125
1 files changed, 93 insertions, 32 deletions
diff --git a/core/java/android/text/method/ArrowKeyMovementMethod.java b/core/java/android/text/method/ArrowKeyMovementMethod.java
index ab33cb3..789172f 100644
--- a/core/java/android/text/method/ArrowKeyMovementMethod.java
+++ b/core/java/android/text/method/ArrowKeyMovementMethod.java
@@ -54,7 +54,7 @@ implements MovementMethod
Selection.setSelection(buffer, 0);
return true;
} else {
- return Selection.moveUp(buffer, layout);
+ return Selection.moveUp(buffer, layout);
}
}
}
@@ -80,7 +80,7 @@ implements MovementMethod
Selection.setSelection(buffer, buffer.length());
return true;
} else {
- return Selection.moveDown(buffer, layout);
+ return Selection.moveDown(buffer, layout);
}
}
}
@@ -133,6 +133,35 @@ implements MovementMethod
}
}
+ private int getOffset(int x, int y, TextView widget){
+ // Converts the absolute X,Y coordinates to the character offset for the
+ // character whose position is closest to the specified
+ // horizontal position.
+ x -= widget.getTotalPaddingLeft();
+ y -= widget.getTotalPaddingTop();
+
+ // Clamp the position to inside of the view.
+ if (x < 0) {
+ x = 0;
+ } else if (x >= (widget.getWidth()-widget.getTotalPaddingRight())) {
+ x = widget.getWidth()-widget.getTotalPaddingRight() - 1;
+ }
+ if (y < 0) {
+ y = 0;
+ } else if (y >= (widget.getHeight()-widget.getTotalPaddingBottom())) {
+ y = widget.getHeight()-widget.getTotalPaddingBottom() - 1;
+ }
+
+ x += widget.getScrollX();
+ y += widget.getScrollY();
+
+ Layout layout = widget.getLayout();
+ int line = layout.getLineForVertical(y);
+
+ int offset = layout.getOffsetForHorizontal(line, x);
+ return offset;
+ }
+
public boolean onKeyDown(TextView widget, Spannable buffer, int keyCode, KeyEvent event) {
if (executeDown(widget, buffer, keyCode)) {
MetaKeyKeyListener.adjustMetaAfterKeypress(buffer);
@@ -196,12 +225,12 @@ implements MovementMethod
}
return false;
}
-
+
public boolean onTrackballEvent(TextView widget, Spannable text,
MotionEvent event) {
return false;
}
-
+
public boolean onTouchEvent(TextView widget, Spannable buffer,
MotionEvent event) {
int initialScrollX = -1, initialScrollY = -1;
@@ -209,11 +238,63 @@ implements MovementMethod
initialScrollX = Touch.getInitialScrollX(widget, buffer);
initialScrollY = Touch.getInitialScrollY(widget, buffer);
}
-
+
boolean handled = Touch.onTouchEvent(widget, buffer, event);
if (widget.isFocused() && !widget.didTouchFocusSelect()) {
- if (event.getAction() == MotionEvent.ACTION_UP) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ boolean cap = (MetaKeyKeyListener.getMetaState(buffer,
+ KeyEvent.META_SHIFT_ON) == 1) ||
+ (MetaKeyKeyListener.getMetaState(buffer,
+ MetaKeyKeyListener.META_SELECTING) != 0);
+ if (cap) {
+ int x = (int) event.getX();
+ int y = (int) event.getY();
+ int offset = getOffset(x, y, widget);
+
+ buffer.setSpan(LAST_TAP_DOWN, offset, offset,
+ Spannable.SPAN_POINT_POINT);
+ }
+ } else if (event.getAction() == MotionEvent.ACTION_MOVE ) {
+ boolean cap = (MetaKeyKeyListener.getMetaState(buffer,
+ KeyEvent.META_SHIFT_ON) == 1) ||
+ (MetaKeyKeyListener.getMetaState(buffer,
+ MetaKeyKeyListener.META_SELECTING) != 0);
+
+ if (cap) {
+ // 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 = getOffset(x, y, widget);
+
+ // 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 boundries
+ int spanstart;
+ int spanend;
+ if (offset >= lastDownOffset) {
+ // expand to 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);
+ return true;
+ }
+ } else if (event.getAction() == MotionEvent.ACTION_UP) {
// If we have scrolled, then the up shouldn't move the cursor,
// but we do need to make sure the cursor is still visible at
// the current scroll offset to avoid the scroll jumping later
@@ -223,35 +304,13 @@ implements MovementMethod
widget.moveCursorToVisibleOffset();
return true;
}
-
+
int x = (int) event.getX();
int y = (int) event.getY();
-
- x -= widget.getTotalPaddingLeft();
- y -= widget.getTotalPaddingTop();
-
- // Clamp the position to inside of the view.
- if (x < 0) {
- x = 0;
- } else if (x >= (widget.getWidth()-widget.getTotalPaddingRight())) {
- x = widget.getWidth()-widget.getTotalPaddingRight() - 1;
- }
- if (y < 0) {
- y = 0;
- } else if (y >= (widget.getHeight()-widget.getTotalPaddingBottom())) {
- y = widget.getHeight()-widget.getTotalPaddingBottom() - 1;
- }
-
- x += widget.getScrollX();
- y += widget.getScrollY();
-
- Layout layout = widget.getLayout();
- int line = layout.getLineForVertical(y);
-
- int off = layout.getOffsetForHorizontal(line, x);
+ int off = getOffset(x, y, widget);
// XXX should do the same adjust for x as we do for the line.
-
+
boolean cap = (MetaKeyKeyListener.getMetaState(buffer,
KeyEvent.META_SHIFT_ON) == 1) ||
(MetaKeyKeyListener.getMetaState(buffer,
@@ -278,7 +337,7 @@ implements MovementMethod
}
if (cap) {
- Selection.extendSelection(buffer, off);
+ buffer.removeSpan(LAST_TAP_DOWN);
} else if (doubletap) {
Selection.setSelection(buffer,
findWordStart(buffer, off),
@@ -395,5 +454,7 @@ implements MovementMethod
return sInstance;
}
+
+ private static final Object LAST_TAP_DOWN = new Object();
private static ArrowKeyMovementMethod sInstance;
}