Loading core/java/android/view/inputmethod/EditorInfo.java +8 −0 Original line number Diff line number Diff line Loading @@ -595,6 +595,10 @@ public class EditorInfo implements InputType, Parcelable { == HandwritingGesture.GESTURE_TYPE_SELECT) { list.add(SelectGesture.class); } if ((mSupportedHandwritingGestureTypes & HandwritingGesture.GESTURE_TYPE_SELECT_RANGE) == HandwritingGesture.GESTURE_TYPE_SELECT_RANGE) { list.add(SelectRangeGesture.class); } if ((mSupportedHandwritingGestureTypes & HandwritingGesture.GESTURE_TYPE_INSERT) == HandwritingGesture.GESTURE_TYPE_INSERT) { list.add(InsertGesture.class); Loading @@ -603,6 +607,10 @@ public class EditorInfo implements InputType, Parcelable { == HandwritingGesture.GESTURE_TYPE_DELETE) { list.add(DeleteGesture.class); } if ((mSupportedHandwritingGestureTypes & HandwritingGesture.GESTURE_TYPE_DELETE_RANGE) == HandwritingGesture.GESTURE_TYPE_DELETE_RANGE) { list.add(DeleteRangeGesture.class); } if ((mSupportedHandwritingGestureTypes & HandwritingGesture.GESTURE_TYPE_REMOVE_SPACE) == HandwritingGesture.GESTURE_TYPE_REMOVE_SPACE) { list.add(RemoveSpaceGesture.class); Loading core/java/android/widget/TextView.java +114 −51 Original line number Diff line number Diff line Loading @@ -189,6 +189,7 @@ import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.CorrectionInfo; import android.view.inputmethod.CursorAnchorInfo; import android.view.inputmethod.DeleteGesture; import android.view.inputmethod.DeleteRangeGesture; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; Loading @@ -199,6 +200,7 @@ import android.view.inputmethod.InsertGesture; import android.view.inputmethod.JoinOrSplitGesture; import android.view.inputmethod.RemoveSpaceGesture; import android.view.inputmethod.SelectGesture; import android.view.inputmethod.SelectRangeGesture; import android.view.inspector.InspectableProperty; import android.view.inspector.InspectableProperty.EnumEntry; import android.view.inspector.InspectableProperty.FlagEntry; Loading Loading @@ -9096,7 +9098,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener ArrayList<Class<? extends HandwritingGesture>> gestures = new ArrayList<>(); gestures.add(SelectGesture.class); gestures.add(SelectRangeGesture.class); gestures.add(DeleteGesture.class); gestures.add(DeleteRangeGesture.class); gestures.add(InsertGesture.class); gestures.add(RemoveSpaceGesture.class); gestures.add(JoinOrSplitGesture.class); Loading Loading @@ -9324,6 +9328,26 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return InputConnection.HANDWRITING_GESTURE_RESULT_SUCCESS; } /** @hide */ public int performHandwritingSelectRangeGesture(@NonNull SelectRangeGesture gesture) { Range<Integer> startRange = getRangeForRect( convertFromScreenToContentCoordinates(gesture.getSelectionStartArea()), gesture.getGranularity()); if (startRange == null) { return handleGestureFailure(gesture); } Range<Integer> endRange = getRangeForRect( convertFromScreenToContentCoordinates(gesture.getSelectionEndArea()), gesture.getGranularity()); if (endRange == null || endRange.getUpper() <= startRange.getLower()) { return handleGestureFailure(gesture); } Range<Integer> range = startRange.extend(endRange); Selection.setSelection(getEditableText(), range.getLower(), range.getUpper()); mEditor.startSelectionActionModeAsync(/* adjustSelection= */ false); return InputConnection.HANDWRITING_GESTURE_RESULT_SUCCESS; } /** @hide */ public int performHandwritingDeleteGesture(@NonNull DeleteGesture gesture) { Range<Integer> range = getRangeForRect( Loading @@ -9332,20 +9356,57 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (range == null) { return handleGestureFailure(gesture); } if (gesture.getGranularity() == HandwritingGesture.GRANULARITY_WORD) { range = adjustHandwritingDeleteGestureRange(range); } getEditableText().delete(range.getLower(), range.getUpper()); Selection.setSelection(getEditableText(), range.getLower()); return InputConnection.HANDWRITING_GESTURE_RESULT_SUCCESS; } /** @hide */ public int performHandwritingDeleteRangeGesture(@NonNull DeleteRangeGesture gesture) { Range<Integer> startRange = getRangeForRect( convertFromScreenToContentCoordinates(gesture.getDeletionStartArea()), gesture.getGranularity()); if (startRange == null) { return handleGestureFailure(gesture); } Range<Integer> endRange = getRangeForRect( convertFromScreenToContentCoordinates(gesture.getDeletionEndArea()), gesture.getGranularity()); if (endRange == null) { return handleGestureFailure(gesture); } Range<Integer> range = startRange.extend(endRange); if (gesture.getGranularity() == HandwritingGesture.GRANULARITY_WORD) { range = adjustHandwritingDeleteGestureRange(range); } getEditableText().delete(range.getLower(), range.getUpper()); Selection.setSelection(getEditableText(), range.getLower()); return InputConnection.HANDWRITING_GESTURE_RESULT_SUCCESS; } private Range<Integer> adjustHandwritingDeleteGestureRange(Range<Integer> range) { // For handwriting delete gestures with word granularity, adjust the start and end offsets // to remove extra whitespace around the deleted text. int start = range.getLower(); int end = range.getUpper(); // For word granularity, adjust the start and end offsets to remove extra whitespace around // the deleted text. if (gesture.getGranularity() == HandwritingGesture.GRANULARITY_WORD) { // If the deleted text is at the start of the text, the behavior is the same as the case // where the deleted text follows a new line character. int codePointBeforeStart = start > 0 ? Character.codePointBefore(mText, start) : TextUtils.LINE_FEED_CODE_POINT; // If the deleted text is at the end of the text, the behavior is the same as the case // where the deleted text precedes a new line character. // If the deleted text is at the end of the text, the behavior is the same as the case where // the deleted text precedes a new line character. int codePointAtEnd = end < mText.length() ? Character.codePointAt(mText, end) : TextUtils.LINE_FEED_CODE_POINT; if (TextUtils.isWhitespaceExceptNewline(codePointBeforeStart) && (TextUtils.isWhitespace(codePointAtEnd) || TextUtils.isPunctuation(codePointAtEnd))) { Loading @@ -9364,7 +9425,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (start == 0) break; codePointBeforeStart = Character.codePointBefore(mText, start); } while (TextUtils.isWhitespaceExceptNewline(codePointBeforeStart)); } else if (TextUtils.isWhitespaceExceptNewline(codePointAtEnd) return new Range(start, end); } if (TextUtils.isWhitespaceExceptNewline(codePointAtEnd) && (TextUtils.isWhitespace(codePointBeforeStart) || TextUtils.isPunctuation(codePointBeforeStart))) { // Remove whitespace (except new lines) after the deleted text, in these cases: Loading @@ -9380,12 +9444,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (end == mText.length()) break; codePointAtEnd = Character.codePointAt(mText, end); } while (TextUtils.isWhitespaceExceptNewline(codePointAtEnd)); } return new Range(start, end); } getEditableText().delete(start, end); Selection.setSelection(getEditableText(), start); return InputConnection.HANDWRITING_GESTURE_RESULT_SUCCESS; // Return the original range. return range; } /** @hide */ Loading core/java/com/android/internal/inputmethod/EditableInputConnection.java +6 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.view.inputmethod.BaseInputConnection; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.CorrectionInfo; import android.view.inputmethod.DeleteGesture; import android.view.inputmethod.DeleteRangeGesture; import android.view.inputmethod.DumpableInputConnection; import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; Loading @@ -44,6 +45,7 @@ import android.view.inputmethod.InsertGesture; import android.view.inputmethod.JoinOrSplitGesture; import android.view.inputmethod.RemoveSpaceGesture; import android.view.inputmethod.SelectGesture; import android.view.inputmethod.SelectRangeGesture; import android.widget.TextView; import java.util.concurrent.Executor; Loading Loading @@ -275,8 +277,12 @@ public final class EditableInputConnection extends BaseInputConnection int result; if (gesture instanceof SelectGesture) { result = mTextView.performHandwritingSelectGesture((SelectGesture) gesture); } else if (gesture instanceof SelectRangeGesture) { result = mTextView.performHandwritingSelectRangeGesture((SelectRangeGesture) gesture); } else if (gesture instanceof DeleteGesture) { result = mTextView.performHandwritingDeleteGesture((DeleteGesture) gesture); } else if (gesture instanceof DeleteRangeGesture) { result = mTextView.performHandwritingDeleteRangeGesture((DeleteRangeGesture) gesture); } else if (gesture instanceof InsertGesture) { result = mTextView.performHandwritingInsertGesture((InsertGesture) gesture); } else if (gesture instanceof RemoveSpaceGesture) { Loading Loading
core/java/android/view/inputmethod/EditorInfo.java +8 −0 Original line number Diff line number Diff line Loading @@ -595,6 +595,10 @@ public class EditorInfo implements InputType, Parcelable { == HandwritingGesture.GESTURE_TYPE_SELECT) { list.add(SelectGesture.class); } if ((mSupportedHandwritingGestureTypes & HandwritingGesture.GESTURE_TYPE_SELECT_RANGE) == HandwritingGesture.GESTURE_TYPE_SELECT_RANGE) { list.add(SelectRangeGesture.class); } if ((mSupportedHandwritingGestureTypes & HandwritingGesture.GESTURE_TYPE_INSERT) == HandwritingGesture.GESTURE_TYPE_INSERT) { list.add(InsertGesture.class); Loading @@ -603,6 +607,10 @@ public class EditorInfo implements InputType, Parcelable { == HandwritingGesture.GESTURE_TYPE_DELETE) { list.add(DeleteGesture.class); } if ((mSupportedHandwritingGestureTypes & HandwritingGesture.GESTURE_TYPE_DELETE_RANGE) == HandwritingGesture.GESTURE_TYPE_DELETE_RANGE) { list.add(DeleteRangeGesture.class); } if ((mSupportedHandwritingGestureTypes & HandwritingGesture.GESTURE_TYPE_REMOVE_SPACE) == HandwritingGesture.GESTURE_TYPE_REMOVE_SPACE) { list.add(RemoveSpaceGesture.class); Loading
core/java/android/widget/TextView.java +114 −51 Original line number Diff line number Diff line Loading @@ -189,6 +189,7 @@ import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.CorrectionInfo; import android.view.inputmethod.CursorAnchorInfo; import android.view.inputmethod.DeleteGesture; import android.view.inputmethod.DeleteRangeGesture; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; Loading @@ -199,6 +200,7 @@ import android.view.inputmethod.InsertGesture; import android.view.inputmethod.JoinOrSplitGesture; import android.view.inputmethod.RemoveSpaceGesture; import android.view.inputmethod.SelectGesture; import android.view.inputmethod.SelectRangeGesture; import android.view.inspector.InspectableProperty; import android.view.inspector.InspectableProperty.EnumEntry; import android.view.inspector.InspectableProperty.FlagEntry; Loading Loading @@ -9096,7 +9098,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener ArrayList<Class<? extends HandwritingGesture>> gestures = new ArrayList<>(); gestures.add(SelectGesture.class); gestures.add(SelectRangeGesture.class); gestures.add(DeleteGesture.class); gestures.add(DeleteRangeGesture.class); gestures.add(InsertGesture.class); gestures.add(RemoveSpaceGesture.class); gestures.add(JoinOrSplitGesture.class); Loading Loading @@ -9324,6 +9328,26 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return InputConnection.HANDWRITING_GESTURE_RESULT_SUCCESS; } /** @hide */ public int performHandwritingSelectRangeGesture(@NonNull SelectRangeGesture gesture) { Range<Integer> startRange = getRangeForRect( convertFromScreenToContentCoordinates(gesture.getSelectionStartArea()), gesture.getGranularity()); if (startRange == null) { return handleGestureFailure(gesture); } Range<Integer> endRange = getRangeForRect( convertFromScreenToContentCoordinates(gesture.getSelectionEndArea()), gesture.getGranularity()); if (endRange == null || endRange.getUpper() <= startRange.getLower()) { return handleGestureFailure(gesture); } Range<Integer> range = startRange.extend(endRange); Selection.setSelection(getEditableText(), range.getLower(), range.getUpper()); mEditor.startSelectionActionModeAsync(/* adjustSelection= */ false); return InputConnection.HANDWRITING_GESTURE_RESULT_SUCCESS; } /** @hide */ public int performHandwritingDeleteGesture(@NonNull DeleteGesture gesture) { Range<Integer> range = getRangeForRect( Loading @@ -9332,20 +9356,57 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (range == null) { return handleGestureFailure(gesture); } if (gesture.getGranularity() == HandwritingGesture.GRANULARITY_WORD) { range = adjustHandwritingDeleteGestureRange(range); } getEditableText().delete(range.getLower(), range.getUpper()); Selection.setSelection(getEditableText(), range.getLower()); return InputConnection.HANDWRITING_GESTURE_RESULT_SUCCESS; } /** @hide */ public int performHandwritingDeleteRangeGesture(@NonNull DeleteRangeGesture gesture) { Range<Integer> startRange = getRangeForRect( convertFromScreenToContentCoordinates(gesture.getDeletionStartArea()), gesture.getGranularity()); if (startRange == null) { return handleGestureFailure(gesture); } Range<Integer> endRange = getRangeForRect( convertFromScreenToContentCoordinates(gesture.getDeletionEndArea()), gesture.getGranularity()); if (endRange == null) { return handleGestureFailure(gesture); } Range<Integer> range = startRange.extend(endRange); if (gesture.getGranularity() == HandwritingGesture.GRANULARITY_WORD) { range = adjustHandwritingDeleteGestureRange(range); } getEditableText().delete(range.getLower(), range.getUpper()); Selection.setSelection(getEditableText(), range.getLower()); return InputConnection.HANDWRITING_GESTURE_RESULT_SUCCESS; } private Range<Integer> adjustHandwritingDeleteGestureRange(Range<Integer> range) { // For handwriting delete gestures with word granularity, adjust the start and end offsets // to remove extra whitespace around the deleted text. int start = range.getLower(); int end = range.getUpper(); // For word granularity, adjust the start and end offsets to remove extra whitespace around // the deleted text. if (gesture.getGranularity() == HandwritingGesture.GRANULARITY_WORD) { // If the deleted text is at the start of the text, the behavior is the same as the case // where the deleted text follows a new line character. int codePointBeforeStart = start > 0 ? Character.codePointBefore(mText, start) : TextUtils.LINE_FEED_CODE_POINT; // If the deleted text is at the end of the text, the behavior is the same as the case // where the deleted text precedes a new line character. // If the deleted text is at the end of the text, the behavior is the same as the case where // the deleted text precedes a new line character. int codePointAtEnd = end < mText.length() ? Character.codePointAt(mText, end) : TextUtils.LINE_FEED_CODE_POINT; if (TextUtils.isWhitespaceExceptNewline(codePointBeforeStart) && (TextUtils.isWhitespace(codePointAtEnd) || TextUtils.isPunctuation(codePointAtEnd))) { Loading @@ -9364,7 +9425,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (start == 0) break; codePointBeforeStart = Character.codePointBefore(mText, start); } while (TextUtils.isWhitespaceExceptNewline(codePointBeforeStart)); } else if (TextUtils.isWhitespaceExceptNewline(codePointAtEnd) return new Range(start, end); } if (TextUtils.isWhitespaceExceptNewline(codePointAtEnd) && (TextUtils.isWhitespace(codePointBeforeStart) || TextUtils.isPunctuation(codePointBeforeStart))) { // Remove whitespace (except new lines) after the deleted text, in these cases: Loading @@ -9380,12 +9444,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (end == mText.length()) break; codePointAtEnd = Character.codePointAt(mText, end); } while (TextUtils.isWhitespaceExceptNewline(codePointAtEnd)); } return new Range(start, end); } getEditableText().delete(start, end); Selection.setSelection(getEditableText(), start); return InputConnection.HANDWRITING_GESTURE_RESULT_SUCCESS; // Return the original range. return range; } /** @hide */ Loading
core/java/com/android/internal/inputmethod/EditableInputConnection.java +6 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.view.inputmethod.BaseInputConnection; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.CorrectionInfo; import android.view.inputmethod.DeleteGesture; import android.view.inputmethod.DeleteRangeGesture; import android.view.inputmethod.DumpableInputConnection; import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; Loading @@ -44,6 +45,7 @@ import android.view.inputmethod.InsertGesture; import android.view.inputmethod.JoinOrSplitGesture; import android.view.inputmethod.RemoveSpaceGesture; import android.view.inputmethod.SelectGesture; import android.view.inputmethod.SelectRangeGesture; import android.widget.TextView; import java.util.concurrent.Executor; Loading Loading @@ -275,8 +277,12 @@ public final class EditableInputConnection extends BaseInputConnection int result; if (gesture instanceof SelectGesture) { result = mTextView.performHandwritingSelectGesture((SelectGesture) gesture); } else if (gesture instanceof SelectRangeGesture) { result = mTextView.performHandwritingSelectRangeGesture((SelectRangeGesture) gesture); } else if (gesture instanceof DeleteGesture) { result = mTextView.performHandwritingDeleteGesture((DeleteGesture) gesture); } else if (gesture instanceof DeleteRangeGesture) { result = mTextView.performHandwritingDeleteRangeGesture((DeleteRangeGesture) gesture); } else if (gesture instanceof InsertGesture) { result = mTextView.performHandwritingInsertGesture((InsertGesture) gesture); } else if (gesture instanceof RemoveSpaceGesture) { Loading