Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44e537a8 authored by Maryam Garrett's avatar Maryam Garrett Committed by Android Git Automerger
Browse files

am 7c427030: Merge change I9088d29b into eclair-mr2

Merge commit '7c427030' into eclair-mr2-plus-aosp

* commit '7c427030':
  Improves the touch-based text selection UI in text boxes.
parents 0c15b889 7c427030
Loading
Loading
Loading
Loading
+93 −32
Original line number Diff line number Diff line
@@ -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);
@@ -213,7 +242,59 @@ implements MovementMethod
        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
@@ -226,29 +307,7 @@ implements MovementMethod

                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.

@@ -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;
}