summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Justin Ghan <justinghan@google.com> 2022-11-11 16:13:29 -0800
committer Justin Ghan <justinghan@google.com> 2022-12-02 15:26:49 -0800
commitedff783dee2060a8f49e13df47a101b15b4f547c (patch)
tree4f44666c80f38493935942c5e4f74144a168f59d
parent7c5817e876c62f3237a2b94622c55b21340e846e (diff)
Text highlighting for select and delete gesture previews
If there is a selection or deletion preview range set, then the corresponding highlight will be displayed, and the cursor or regular selection highlight will be hidden. Once the selection or deletion preview range is cleared, then the cursor or regular selection highlight will be displayed again. Bug: 240436893 Test: atest android.widget.cts.TextViewHandwritingGestureTest Change-Id: I30285942396a11b5b38a9e83ee13e7c0485baa7d
-rw-r--r--core/java/android/widget/Editor.java5
-rw-r--r--core/java/android/widget/TextView.java80
2 files changed, 82 insertions, 3 deletions
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 558d96089bb7..0a3ea8a9f356 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -2082,7 +2082,8 @@ public class Editor {
}
if (selectionHighlight != null && selectionStart == selectionEnd
- && mDrawableForCursor != null) {
+ && mDrawableForCursor != null
+ && !mTextView.hasGesturePreviewHighlight()) {
drawCursor(canvas, cursorOffsetVertical);
// Rely on the drawable entirely, do not draw the cursor line.
// Has to be done after the IMM related code above which relies on the highlight.
@@ -2714,7 +2715,7 @@ public class Editor {
unregisterOnBackInvokedCallback();
}
- private void stopTextActionModeWithPreservingSelection() {
+ void stopTextActionModeWithPreservingSelection() {
if (mTextActionMode != null) {
mRestartActionModeOnNextRefresh = true;
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 475a8491de4d..7e7f9c99b948 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -68,6 +68,7 @@ import android.content.res.XmlResourceParser;
import android.graphics.BaseCanvas;
import android.graphics.BlendMode;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Paint;
@@ -222,6 +223,7 @@ import android.widget.RemoteViews.RemoteView;
import com.android.internal.accessibility.util.AccessibilityUtils;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.graphics.ColorUtils;
import com.android.internal.inputmethod.EditableInputConnection;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -931,6 +933,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private List<Path> mHighlightPaths;
private List<Paint> mHighlightPaints;
private Highlights mHighlights;
+ private int mGesturePreviewHighlightStart = -1;
+ private int mGesturePreviewHighlightEnd = -1;
+ private Paint mGesturePreviewHighlightPaint;
private final List<Path> mPathRecyclePool = new ArrayList<>();
private boolean mHighlightPathsBogus = true;
@@ -6167,6 +6172,59 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
+ * Highlights the text range (from inclusive start offset to exclusive end offset) to show what
+ * will be selected by the ongoing select handwriting gesture. While the gesture preview
+ * highlight is shown, the selection or cursor is hidden. If the text or selection is changed,
+ * the gesture preview highlight will be cleared.
+ */
+ private void setSelectGesturePreviewHighlight(int start, int end) {
+ // Selection preview highlight color is the same as selection highlight color.
+ setGesturePreviewHighlight(start, end, mHighlightColor);
+ }
+
+ /**
+ * Highlights the text range (from inclusive start offset to exclusive end offset) to show what
+ * will be deleted by the ongoing delete handwriting gesture. While the gesture preview
+ * highlight is shown, the selection or cursor is hidden. If the text or selection is changed,
+ * the gesture preview highlight will be cleared.
+ */
+ private void setDeleteGesturePreviewHighlight(int start, int end) {
+ // Deletion preview highlight color is 20% opacity of the default text color.
+ int color = mTextColor.getDefaultColor();
+ color = ColorUtils.setAlphaComponent(color, (int) (0.2f * Color.alpha(color)));
+ setGesturePreviewHighlight(start, end, color);
+ }
+
+ private void setGesturePreviewHighlight(int start, int end, int color) {
+ mGesturePreviewHighlightStart = start;
+ mGesturePreviewHighlightEnd = end;
+ if (mGesturePreviewHighlightPaint == null) {
+ mGesturePreviewHighlightPaint = new Paint();
+ mGesturePreviewHighlightPaint.setStyle(Paint.Style.FILL);
+ }
+ mGesturePreviewHighlightPaint.setColor(color);
+
+ if (mEditor != null) {
+ mEditor.hideCursorAndSpanControllers();
+ mEditor.stopTextActionModeWithPreservingSelection();
+ }
+
+ mHighlightPathsBogus = true;
+ invalidate();
+ }
+
+ private void clearGesturePreviewHighlight() {
+ mGesturePreviewHighlightStart = -1;
+ mGesturePreviewHighlightEnd = -1;
+ mHighlightPathsBogus = true;
+ invalidate();
+ }
+
+ boolean hasGesturePreviewHighlight() {
+ return mGesturePreviewHighlightStart > 0;
+ }
+
+ /**
* Convenience method to append the specified text to the TextView's
* display buffer, upgrading it to {@link android.widget.TextView.BufferType#EDITABLE}
* if it was not already editable.
@@ -8300,6 +8358,22 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
}
+
+ if (hasGesturePreviewHighlight()) {
+ final Path path;
+ if (mPathRecyclePool.isEmpty()) {
+ path = new Path();
+ } else {
+ path = mPathRecyclePool.get(mPathRecyclePool.size() - 1);
+ mPathRecyclePool.remove(mPathRecyclePool.size() - 1);
+ path.reset();
+ }
+ mLayout.getSelectionPath(
+ mGesturePreviewHighlightStart, mGesturePreviewHighlightEnd, path);
+ mHighlightPaths.add(path);
+ mHighlightPaints.add(mGesturePreviewHighlightPaint);
+ }
+
mHighlightPathsBogus = false;
}
@@ -8503,7 +8577,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final int cursorOffsetVertical = voffsetCursor - voffsetText;
maybeUpdateHighlightPaths();
- Path highlight = getUpdatedHighlightPath();
+ // If there is a gesture preview highlight, then the selection or cursor is not drawn.
+ Path highlight = hasGesturePreviewHighlight() ? null : getUpdatedHighlightPath();
if (mEditor != null) {
mEditor.onDraw(canvas, layout, mHighlightPaths, mHighlightPaints, highlight,
mHighlightPaint, cursorOffsetVertical);
@@ -11699,6 +11774,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
resetErrorChangedFlag();
sendOnTextChanged(buffer, start, before, after);
onTextChanged(buffer, start, before, after);
+
+ clearGesturePreviewHighlight();
}
/**
@@ -11737,6 +11814,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
if (selChanged) {
+ clearGesturePreviewHighlight();
mHighlightPathBogus = true;
if (mEditor != null && !isFocused()) mEditor.mSelectionMoved = true;