1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.view.inputmethod;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.graphics.RectF;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 import java.util.Objects;
26 
27 /**
28  * Container of rectangular position related info for the Editor.
29  */
30 public final class EditorBoundsInfo implements Parcelable {
31 
32     /**
33      * The bounding box of the of currently focused text editor in local coordinates.
34      */
35     private final RectF mEditorBounds;
36 
37     /**
38      * The bounding box of the of currently focused text editor with additional padding around it
39      * for initiating Stylus Handwriting in the current window.
40      */
41     private final RectF mHandwritingBounds;
42 
43     private final int mHashCode;
44 
EditorBoundsInfo(@onNull Parcel source)45     private EditorBoundsInfo(@NonNull Parcel source) {
46         mHashCode = source.readInt();
47         mEditorBounds = source.readTypedObject(RectF.CREATOR);
48         mHandwritingBounds = source.readTypedObject(RectF.CREATOR);
49     }
50 
51     /**
52      * Returns the bounds of the Editor in local coordinates.
53      *
54      * Screen coordinates can be obtained by transforming with the
55      * {@link CursorAnchorInfo#getMatrix} of the containing {@code CursorAnchorInfo}.
56      */
57     @Nullable
getEditorBounds()58     public RectF getEditorBounds() {
59         return mEditorBounds;
60     }
61 
62     /**
63      * Returns the bounds of the area that should be considered for initiating stylus handwriting
64      * in local coordinates.
65      *
66      * Screen coordinates can be obtained by transforming with the
67      * {@link CursorAnchorInfo#getMatrix} of the containing {@code CursorAnchorInfo}.
68      */
69     @Nullable
getHandwritingBounds()70     public RectF getHandwritingBounds() {
71         return mHandwritingBounds;
72     }
73 
74     @Override
hashCode()75     public int hashCode() {
76         return mHashCode;
77     }
78 
79     @Override
toString()80     public String toString() {
81         return "EditorBoundsInfo{mEditorBounds=" + mEditorBounds
82                 + " mHandwritingBounds=" + mHandwritingBounds
83                 + "}";
84     }
85 
86     @Override
equals(@ullable Object obj)87     public boolean equals(@Nullable Object obj) {
88         if (obj == null) {
89             return false;
90         }
91         EditorBoundsInfo bounds;
92         if (obj instanceof  EditorBoundsInfo) {
93             bounds = (EditorBoundsInfo) obj;
94         } else {
95             return false;
96         }
97         return Objects.equals(bounds.mEditorBounds, mEditorBounds)
98                 && Objects.equals(bounds.mHandwritingBounds, mHandwritingBounds);
99     }
100 
101     @Override
describeContents()102     public int describeContents() {
103         return 0;
104     }
105 
106     @Override
writeToParcel(@onNull Parcel dest, int flags)107     public void writeToParcel(@NonNull Parcel dest, int flags) {
108         dest.writeInt(mHashCode);
109         dest.writeTypedObject(mEditorBounds, flags);
110         dest.writeTypedObject(mHandwritingBounds, flags);
111     }
112 
113     /**
114      * Used to make this class parcelable.
115      */
116     public static final @android.annotation.NonNull Parcelable.Creator<EditorBoundsInfo> CREATOR
117             = new Parcelable.Creator<EditorBoundsInfo>() {
118         @Override
119         public EditorBoundsInfo createFromParcel(@NonNull Parcel source) {
120             return new EditorBoundsInfo(source);
121         }
122 
123         @Override
124         public EditorBoundsInfo[] newArray(int size) {
125             return new EditorBoundsInfo[size];
126         }
127     };
128 
129     /**
130      * Builder for {@link EditorBoundsInfo}.
131      */
132     public static final class Builder {
133         private RectF mEditorBounds = null;
134         private RectF mHandwritingBounds = null;
135 
136         /**
137          * Sets the bounding box of the current editor.
138          *
139          * @param bounds {@link RectF} in local coordinates.
140          */
141         @NonNull
setEditorBounds(@ullable RectF bounds)142         public EditorBoundsInfo.Builder setEditorBounds(@Nullable RectF bounds) {
143             mEditorBounds = bounds;
144             return this;
145         }
146 
147         /**
148          * Sets the current editor's bounds with padding for handwriting.
149          *
150          * @param bounds {@link RectF} in local coordinates.
151          */
152         @NonNull
setHandwritingBounds(@ullable RectF bounds)153         public EditorBoundsInfo.Builder setHandwritingBounds(@Nullable RectF bounds) {
154             mHandwritingBounds = bounds;
155             return this;
156         }
157 
158         /**
159          * Returns {@link EditorBoundsInfo} using parameters in this
160          *   {@link EditorBoundsInfo.Builder}.
161          */
162         @NonNull
build()163         public EditorBoundsInfo build() {
164             return new EditorBoundsInfo(this);
165         }
166     }
167 
EditorBoundsInfo(final EditorBoundsInfo.Builder builder)168     private EditorBoundsInfo(final EditorBoundsInfo.Builder builder) {
169         mEditorBounds = builder.mEditorBounds;
170         mHandwritingBounds = builder.mHandwritingBounds;
171 
172         int hash = Objects.hashCode(mEditorBounds);
173         hash *= 31;
174         hash += Objects.hashCode(mHandwritingBounds);
175         mHashCode = hash;
176     }
177 }
178