summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorTaran Singh <tarandeep@google.com>2022-01-14 21:52:01 +0000
committerPrabir Pradhan <prabirmsp@google.com>2022-01-18 02:24:15 -0800
commit14d8e9450e97703e5a418f0fc44ea6c54b3847f2 (patch)
treeaac044a00e75a021b9b031e6099efb2ce3b804f0 /core/java
parent2888d6598f72bb613a351c6290383413f265de94 (diff)
Scribe in IMF: CursorAnchorInfo#getEditorBoundsInfo 3/N
Add a new field EditorBoundsInfo in CursorAnchorInfo and implement it. Bug: 203086136 Test: atest CurosrAnchorInfoTest Change-Id: I7f225fa1236534bbd18920f8ce8293df23ea2ce7
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/view/View.java23
-rw-r--r--core/java/android/view/inputmethod/CursorAnchorInfo.java36
-rw-r--r--core/java/android/view/inputmethod/EditorBoundsInfo.java177
-rw-r--r--core/java/android/widget/Editor.java7
4 files changed, 241 insertions, 2 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 9ce59bb8823a..41a31e1011f2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8663,12 +8663,31 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mAttachInfo == null) {
return;
}
+ RectF position = mAttachInfo.mTmpTransformRect;
+ getBoundsToScreenInternal(position, clipToParent);
+ outRect.set(Math.round(position.left), Math.round(position.top),
+ Math.round(position.right), Math.round(position.bottom));
+ }
+ /**
+ * Gets the location of this view in screen coordinates.
+ *
+ * @param outRect The output location
+ * @param clipToParent Whether to clip child bounds to the parent ones.
+ * @hide
+ */
+ public void getBoundsOnScreen(RectF outRect, boolean clipToParent) {
+ if (mAttachInfo == null) {
+ return;
+ }
RectF position = mAttachInfo.mTmpTransformRect;
+ getBoundsToScreenInternal(position, clipToParent);
+ outRect.set(position.left, position.top, position.right, position.bottom);
+ }
+
+ private void getBoundsToScreenInternal(RectF position, boolean clipToParent) {
position.set(0, 0, mRight - mLeft, mBottom - mTop);
mapRectFromViewToScreenCoords(position, clipToParent);
- outRect.set(Math.round(position.left), Math.round(position.top),
- Math.round(position.right), Math.round(position.bottom));
}
/**
diff --git a/core/java/android/view/inputmethod/CursorAnchorInfo.java b/core/java/android/view/inputmethod/CursorAnchorInfo.java
index fbc947071c99..e3d3bfd30b9c 100644
--- a/core/java/android/view/inputmethod/CursorAnchorInfo.java
+++ b/core/java/android/view/inputmethod/CursorAnchorInfo.java
@@ -105,6 +105,13 @@ public final class CursorAnchorInfo implements Parcelable {
private final SparseRectFArray mCharacterBoundsArray;
/**
+ * Container of rectangular position of Editor in the local coordinates that will be transformed
+ * with the transformation matrix when rendered on the screen.
+ * @see {@link EditorBoundsInfo}.
+ */
+ private final EditorBoundsInfo mEditorBoundsInfo;
+
+ /**
* Transformation matrix that is applied to any positional information of this class to
* transform local coordinates into screen coordinates.
*/
@@ -141,6 +148,7 @@ public final class CursorAnchorInfo implements Parcelable {
mInsertionMarkerBaseline = source.readFloat();
mInsertionMarkerBottom = source.readFloat();
mCharacterBoundsArray = source.readParcelable(SparseRectFArray.class.getClassLoader());
+ mEditorBoundsInfo = source.readTypedObject(EditorBoundsInfo.CREATOR);
mMatrixValues = source.createFloatArray();
}
@@ -163,6 +171,7 @@ public final class CursorAnchorInfo implements Parcelable {
dest.writeFloat(mInsertionMarkerBaseline);
dest.writeFloat(mInsertionMarkerBottom);
dest.writeParcelable(mCharacterBoundsArray, flags);
+ dest.writeTypedObject(mEditorBoundsInfo, flags);
dest.writeFloatArray(mMatrixValues);
}
@@ -216,6 +225,10 @@ public final class CursorAnchorInfo implements Parcelable {
return false;
}
+ if (!Objects.equals(mEditorBoundsInfo, that.mEditorBoundsInfo)) {
+ return false;
+ }
+
// Following fields are (partially) covered by hashCode().
if (mComposingTextStart != that.mComposingTextStart
@@ -248,6 +261,7 @@ public final class CursorAnchorInfo implements Parcelable {
+ " mInsertionMarkerBaseline=" + mInsertionMarkerBaseline
+ " mInsertionMarkerBottom=" + mInsertionMarkerBottom
+ " mCharacterBoundsArray=" + Objects.toString(mCharacterBoundsArray)
+ + " mEditorBoundsInfo=" + mEditorBoundsInfo
+ " mMatrix=" + Arrays.toString(mMatrixValues)
+ "}";
}
@@ -266,6 +280,7 @@ public final class CursorAnchorInfo implements Parcelable {
private float mInsertionMarkerBottom = Float.NaN;
private int mInsertionMarkerFlags = 0;
private SparseRectFArrayBuilder mCharacterBoundsArrayBuilder = null;
+ private EditorBoundsInfo mEditorBoundsInfo = null;
private float[] mMatrixValues = null;
private boolean mMatrixInitialized = false;
@@ -356,6 +371,17 @@ public final class CursorAnchorInfo implements Parcelable {
}
/**
+ * Sets the current editor related bounds.
+ *
+ * @param bounds {@link EditorBoundsInfo} in local coordinates.
+ */
+ @NonNull
+ public Builder setEditorBoundsInfo(@Nullable EditorBoundsInfo bounds) {
+ mEditorBoundsInfo = bounds;
+ return this;
+ }
+
+ /**
* Sets the matrix that transforms local coordinates into screen coordinates.
* @param matrix transformation matrix from local coordinates into screen coordinates. null
* is interpreted as an identity matrix.
@@ -410,6 +436,7 @@ public final class CursorAnchorInfo implements Parcelable {
if (mCharacterBoundsArrayBuilder != null) {
mCharacterBoundsArrayBuilder.reset();
}
+ mEditorBoundsInfo = null;
}
}
@@ -425,6 +452,7 @@ public final class CursorAnchorInfo implements Parcelable {
mInsertionMarkerBottom = builder.mInsertionMarkerBottom;
mCharacterBoundsArray = builder.mCharacterBoundsArrayBuilder != null
? builder.mCharacterBoundsArrayBuilder.build() : null;
+ mEditorBoundsInfo = builder.mEditorBoundsInfo;
mMatrixValues = new float[9];
if (builder.mMatrixInitialized) {
System.arraycopy(builder.mMatrixValues, 0, mMatrixValues, 0, 9);
@@ -547,6 +575,14 @@ public final class CursorAnchorInfo implements Parcelable {
}
/**
+ * Returns {@link EditorBoundsInfo} editor related bounds.
+ */
+ @Nullable
+ public EditorBoundsInfo getEditorBoundsInfo() {
+ return mEditorBoundsInfo;
+ }
+
+ /**
* Returns a new instance of {@link android.graphics.Matrix} that indicates the transformation
* matrix that is to be applied other positional data in this class.
* @return a new instance (copy) of the transformation matrix.
diff --git a/core/java/android/view/inputmethod/EditorBoundsInfo.java b/core/java/android/view/inputmethod/EditorBoundsInfo.java
new file mode 100644
index 000000000000..081dc819f10b
--- /dev/null
+++ b/core/java/android/view/inputmethod/EditorBoundsInfo.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inputmethod;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.graphics.RectF;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Container of rectangular position related info for the Editor.
+ */
+public final class EditorBoundsInfo implements Parcelable {
+
+ /**
+ * Container of rectangular position of Editor in the current window.
+ */
+ private final RectF mEditorBounds;
+
+ /**
+ * Container of rectangular position of Editor with additional padding around for initiating
+ * Stylus Handwriting in the current window.
+ */
+ private final RectF mHandwritingBounds;
+
+ private final int mHashCode;
+
+ private EditorBoundsInfo(@NonNull Parcel source) {
+ mHashCode = source.readInt();
+ mEditorBounds = source.readTypedObject(RectF.CREATOR);
+ mHandwritingBounds = source.readTypedObject(RectF.CREATOR);
+ }
+
+ /**
+ * Returns the bounds of the Editor in local coordinates.
+ *
+ * Screen coordinates can be obtained by transforming with the
+ * {@link CursorAnchorInfo#getMatrix} of the containing {@code CursorAnchorInfo}.
+ */
+ @Nullable
+ public RectF getEditorBounds() {
+ return mEditorBounds;
+ }
+
+ /**
+ * Returns the bounds of the area that should be considered for initiating stylus handwriting
+ * in local coordinates.
+ *
+ * Screen coordinates can be obtained by transforming with the
+ * {@link CursorAnchorInfo#getMatrix} of the containing {@code CursorAnchorInfo}.
+ */
+ @Nullable
+ public RectF getHandwritingBounds() {
+ return mHandwritingBounds;
+ }
+
+ @Override
+ public int hashCode() {
+ return mHashCode;
+ }
+
+ @Override
+ public String toString() {
+ return "EditorBoundsInfo{mEditorBounds=" + mEditorBounds
+ + " mHandwritingBounds=" + mHandwritingBounds
+ + "}";
+ }
+
+ @Override
+ public boolean equals(@Nullable Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ EditorBoundsInfo bounds;
+ if (obj instanceof EditorBoundsInfo) {
+ bounds = (EditorBoundsInfo) obj;
+ } else {
+ return false;
+ }
+ return Objects.equals(bounds.mEditorBounds, mEditorBounds)
+ && Objects.equals(bounds.mHandwritingBounds, mHandwritingBounds);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mHashCode);
+ dest.writeTypedObject(mEditorBounds, flags);
+ dest.writeTypedObject(mHandwritingBounds, flags);
+ }
+
+ /**
+ * Used to make this class parcelable.
+ */
+ public static final @android.annotation.NonNull Parcelable.Creator<EditorBoundsInfo> CREATOR
+ = new Parcelable.Creator<EditorBoundsInfo>() {
+ @Override
+ public EditorBoundsInfo createFromParcel(@NonNull Parcel source) {
+ return new EditorBoundsInfo(source);
+ }
+
+ @Override
+ public EditorBoundsInfo[] newArray(int size) {
+ return new EditorBoundsInfo[size];
+ }
+ };
+
+ /**
+ * Builder for {@link CursorAnchorInfo}.
+ */
+ public static final class Builder {
+ private RectF mEditorBounds = null;
+ private RectF mHandwritingBounds = null;
+
+ /**
+ * Sets the bounding box of the current editor.
+ *
+ * @param bounds {@link RectF} in local coordinates.
+ */
+ @NonNull
+ public EditorBoundsInfo.Builder setEditorBounds(@Nullable RectF bounds) {
+ mEditorBounds = bounds;
+ return this;
+ }
+
+ /**
+ * Sets the current editor's bounds with padding for handwriting.
+ *
+ * @param bounds {@link RectF} in local coordinates.
+ */
+ @NonNull
+ public EditorBoundsInfo.Builder setHandwritingBounds(@Nullable RectF bounds) {
+ mHandwritingBounds = bounds;
+ return this;
+ }
+
+ /**
+ * Returns {@link EditorBoundsInfo} using parameters in this
+ * {@link EditorBoundsInfo.Builder}.
+ */
+ @NonNull
+ public EditorBoundsInfo build() {
+ return new EditorBoundsInfo(this);
+ }
+ }
+
+ private EditorBoundsInfo(final EditorBoundsInfo.Builder builder) {
+ mEditorBounds = builder.mEditorBounds;
+ mHandwritingBounds = builder.mHandwritingBounds;
+
+ int hash = Objects.hashCode(mEditorBounds);
+ hash *= 31;
+ hash += Objects.hashCode(mHandwritingBounds);
+ mHashCode = hash;
+ }
+}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 6284bc2f3513..ac28c31ecf49 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -115,6 +115,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.LinearInterpolator;
import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.CursorAnchorInfo;
+import android.view.inputmethod.EditorBoundsInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
@@ -4570,6 +4571,12 @@ public class Editor {
mTextView.getLocationOnScreen(mTmpIntOffset);
mViewToScreenMatrix.postTranslate(mTmpIntOffset[0], mTmpIntOffset[1]);
builder.setMatrix(mViewToScreenMatrix);
+ final RectF bounds = new RectF();
+ mTextView.getBoundsOnScreen(bounds, false /* clipToParent */);
+ EditorBoundsInfo.Builder boundsBuilder = new EditorBoundsInfo.Builder();
+ //TODO(b/210039666): add Handwriting bounds once they're available.
+ builder.setEditorBoundsInfo(
+ boundsBuilder.setEditorBounds(bounds).build());
final float viewportToContentHorizontalOffset =
mTextView.viewportToContentHorizontalOffset();