diff options
| author | Taran Singh <tarandeep@google.com> | 2022-01-14 21:52:01 +0000 |
|---|---|---|
| committer | Prabir Pradhan <prabirmsp@google.com> | 2022-01-18 02:24:15 -0800 |
| commit | 14d8e9450e97703e5a418f0fc44ea6c54b3847f2 (patch) | |
| tree | aac044a00e75a021b9b031e6099efb2ce3b804f0 /core/java | |
| parent | 2888d6598f72bb613a351c6290383413f265de94 (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.java | 23 | ||||
| -rw-r--r-- | core/java/android/view/inputmethod/CursorAnchorInfo.java | 36 | ||||
| -rw-r--r-- | core/java/android/view/inputmethod/EditorBoundsInfo.java | 177 | ||||
| -rw-r--r-- | core/java/android/widget/Editor.java | 7 |
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(); |
