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

Commit d9131a60 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Implement paragraph cursor movement and selection extension"

parents 85b360b9 c7053c65
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -45247,6 +45247,8 @@ package android.text {
    method public static boolean extendRight(android.text.Spannable, android.text.Layout);
    method public static final void extendSelection(android.text.Spannable, int);
    method public static boolean extendToLeftEdge(android.text.Spannable, android.text.Layout);
    method public static boolean extendToParagraphEnd(@NonNull android.text.Spannable);
    method public static boolean extendToParagraphStart(@NonNull android.text.Spannable);
    method public static boolean extendToRightEdge(android.text.Spannable, android.text.Layout);
    method public static boolean extendUp(android.text.Spannable, android.text.Layout);
    method public static final int getSelectionEnd(CharSequence);
@@ -45255,6 +45257,8 @@ package android.text {
    method public static boolean moveLeft(android.text.Spannable, android.text.Layout);
    method public static boolean moveRight(android.text.Spannable, android.text.Layout);
    method public static boolean moveToLeftEdge(android.text.Spannable, android.text.Layout);
    method public static boolean moveToParagraphEnd(@NonNull android.text.Spannable, @NonNull android.text.Layout);
    method public static boolean moveToParagraphStart(@NonNull android.text.Spannable, @NonNull android.text.Layout);
    method public static boolean moveToRightEdge(android.text.Spannable, android.text.Layout);
    method public static boolean moveUp(android.text.Spannable, android.text.Layout);
    method public static final void removeSelection(android.text.Spannable);
@@ -45703,6 +45707,7 @@ package android.text.method {
    method protected boolean left(android.widget.TextView, android.text.Spannable);
    method protected boolean lineEnd(android.widget.TextView, android.text.Spannable);
    method protected boolean lineStart(android.widget.TextView, android.text.Spannable);
    method public boolean nextParagraph(@NonNull android.widget.TextView, @NonNull android.text.Spannable);
    method public boolean onGenericMotionEvent(android.widget.TextView, android.text.Spannable, android.view.MotionEvent);
    method public boolean onKeyDown(android.widget.TextView, android.text.Spannable, int, android.view.KeyEvent);
    method public boolean onKeyOther(android.widget.TextView, android.text.Spannable, android.view.KeyEvent);
@@ -45712,6 +45717,7 @@ package android.text.method {
    method public boolean onTrackballEvent(android.widget.TextView, android.text.Spannable, android.view.MotionEvent);
    method protected boolean pageDown(android.widget.TextView, android.text.Spannable);
    method protected boolean pageUp(android.widget.TextView, android.text.Spannable);
    method public boolean previousParagraph(@NonNull android.widget.TextView, @NonNull android.text.Spannable);
    method protected boolean right(android.widget.TextView, android.text.Spannable);
    method protected boolean top(android.widget.TextView, android.text.Spannable);
    method protected boolean up(android.widget.TextView, android.text.Spannable);
+95 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.text;

import android.annotation.NonNull;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;

@@ -346,6 +347,100 @@ public class Selection {
        return false;
    }

    private static final char PARAGRAPH_SEPARATOR = '\n';

    /**
     * Move the cusrot to the closest paragraph start offset.
     *
     * @param text the spannable text
     * @param layout layout to be used for drawing.
     * @return true if the cursor is moved, otherwise false.
     */
    public static boolean moveToParagraphStart(@NonNull Spannable text, @NonNull Layout layout) {
        int start = getSelectionStart(text);
        int end = getSelectionEnd(text);

        if (start != end) {
            setSelection(text, chooseHorizontal(layout, -1, start, end));
            return true;
        } else {
            int to = TextUtils.lastIndexOf(text, PARAGRAPH_SEPARATOR, start - 1);
            if (to == -1) {
                to = 0;  // If not found, use the document start offset as a paragraph start.
            }
            if (to != end) {
                setSelection(text, to);
                return true;
            }
        }
        return false;
    }

    /**
     * Move the cursor to the closest paragraph end offset.
     *
     * @param text the spannable text
     * @param layout layout to be used for drawing.
     * @return true if the cursor is moved, otherwise false.
     */
    public static boolean moveToParagraphEnd(@NonNull Spannable text, @NonNull Layout layout) {
        int start = getSelectionStart(text);
        int end = getSelectionEnd(text);

        if (start != end) {
            setSelection(text, chooseHorizontal(layout, 1, start, end));
            return true;
        } else {
            int to = TextUtils.indexOf(text, PARAGRAPH_SEPARATOR, end + 1);
            if (to == -1) {
                to = text.length();
            }
            if (to != end) {
                setSelection(text, to);
                return true;
            }
        }
        return false;
    }

    /**
     * Extend the selection to the closest paragraph start offset.
     *
     * @param text the spannable text
     * @return true if the selection is extended, otherwise false
     */
    public static boolean extendToParagraphStart(@NonNull Spannable text) {
        int end = getSelectionEnd(text);
        int to = TextUtils.lastIndexOf(text, PARAGRAPH_SEPARATOR, end - 1);
        if (to == -1) {
            to = 0;  // If not found, use the document start offset as a paragraph start.
        }
        if (to != end) {
            extendSelection(text, to);
            return true;
        }
        return false;
    }

    /**
     * Extend the selection to the closest paragraph end offset.
     *
     * @param text the spannable text
     * @return true if the selection is extended, otherwise false
     */
    public static boolean extendToParagraphEnd(@NonNull Spannable text) {
        int end = getSelectionEnd(text);
        int to = TextUtils.indexOf(text, PARAGRAPH_SEPARATOR, end + 1);
        if (to == -1) {
            to = text.length();
        }
        if (to != end) {
            extendSelection(text, to);
            return true;
        }
        return false;
    }

    /**
     * Move the selection end to the buffer offset physically above
     * the current selection end.
+21 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.text.method;

import android.annotation.NonNull;
import android.graphics.Rect;
import android.text.Layout;
import android.text.Selection;
@@ -221,6 +222,26 @@ public class ArrowKeyMovementMethod extends BaseMovementMethod implements Moveme
        return lineEnd(widget, buffer);
    }

    @Override
    public boolean previousParagraph(@NonNull TextView widget, @NonNull Spannable buffer) {
        final Layout layout = widget.getLayout();
        if (isSelecting(buffer)) {
            return Selection.extendToParagraphStart(buffer);
        } else {
            return Selection.moveToParagraphStart(buffer, layout);
        }
    }

    @Override
    public boolean nextParagraph(@NonNull TextView widget, @NonNull  Spannable buffer) {
        final Layout layout = widget.getLayout();
        if (isSelecting(buffer)) {
            return Selection.extendToParagraphEnd(buffer);
        } else {
            return Selection.moveToParagraphEnd(buffer, layout);
        }
    }

    @Override
    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
        int initialScrollX = -1;
+29 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.text.method;

import android.annotation.NonNull;
import android.text.Layout;
import android.text.Spannable;
import android.view.InputDevice;
@@ -190,6 +191,9 @@ public class BaseMovementMethod implements MovementMethod {
                } else if (KeyEvent.metaStateHasModifiers(movementMetaState,
                        KeyEvent.META_ALT_ON)) {
                    return top(widget, buffer);
                } else if (KeyEvent.metaStateHasModifiers(movementMetaState,
                        KeyEvent.META_CTRL_ON)) {
                    return previousParagraph(widget, buffer);
                }
                break;

@@ -199,6 +203,9 @@ public class BaseMovementMethod implements MovementMethod {
                } else if (KeyEvent.metaStateHasModifiers(movementMetaState,
                        KeyEvent.META_ALT_ON)) {
                    return bottom(widget, buffer);
                } else if (KeyEvent.metaStateHasModifiers(movementMetaState,
                        KeyEvent.META_CTRL_ON)) {
                    return nextParagraph(widget, buffer);
                }
                break;

@@ -399,6 +406,28 @@ public class BaseMovementMethod implements MovementMethod {
        return false;
    }

    /**
     * Performs a previous paragraph movement action.
     *
     * @param widget the text view
     * @param buffer the text buffer
     * @return true if the event was handled, otherwise false.
     */
    public boolean previousParagraph(@NonNull TextView widget, @NonNull Spannable buffer) {
        return false;
    }

    /**
     * Performs a next paragraph movement action.
     *
     * @param widget the text view
     * @param buffer the text buffer
     * @return true if the event was handled, otherwise false.
     */
    public boolean nextParagraph(@NonNull TextView widget, @NonNull Spannable buffer) {
        return false;
    }

    private int getTopLine(TextView widget) {
        return widget.getLayout().getLineForVertical(widget.getScrollY());
    }