• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.graphics.Point;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 import com.android.internal.annotations.VisibleForTesting;
26 
27 import java.lang.annotation.Retention;
28 import java.lang.annotation.RetentionPolicy;
29 
30 /**
31  * Represents a rounded corner of the display.
32  * <p>
33  * <img src="{@docRoot}reference/android/images/rounded_corner/rounded-corner-info.png" height="120"
34  * alt="A figure to describe what the rounded corner radius and the center point are. "/>
35  * </p>
36  *
37  * <p>Note: The rounded corner formed by the radius and the center is an approximation.</p>
38  *
39  * <p>{@link RoundedCorner} is immutable.</p>
40  */
41 public final class RoundedCorner implements Parcelable {
42 
43     /**
44      * The rounded corner is at the top-left of the screen.
45      */
46     public static final int POSITION_TOP_LEFT = 0;
47     /**
48      * The rounded corner is at the top-right of the screen.
49      */
50     public static final int POSITION_TOP_RIGHT = 1;
51     /**
52      * The rounded corner is at the bottom-right of the screen.
53      */
54     public static final int POSITION_BOTTOM_RIGHT = 2;
55     /**
56      * The rounded corner is at the bottom-left of the screen.
57      */
58     public static final int POSITION_BOTTOM_LEFT = 3;
59 
60     /**
61      * @hide
62      */
63     @IntDef(prefix = { "POSITION_" }, value = {
64             POSITION_TOP_LEFT,
65             POSITION_TOP_RIGHT,
66             POSITION_BOTTOM_RIGHT,
67             POSITION_BOTTOM_LEFT
68     })
69     @Retention(RetentionPolicy.SOURCE)
70     public @interface Position {}
71 
72     private final @Position int mPosition;
73     private final int mRadius;
74     @NonNull
75     private final Point mCenter;
76 
77     /**
78      * Creates an empty {@link RoundedCorner} on the given position.
79      * @hide
80      */
81     @VisibleForTesting
RoundedCorner(@osition int position)82     public RoundedCorner(@Position int position) {
83         mPosition = position;
84         mRadius = 0;
85         mCenter = new Point(0, 0);
86     }
87 
88     /**
89      * Creates a {@link RoundedCorner}.
90      *
91      * <p>Note that this is only useful for tests. For production code, developers should always
92      * use a {@link RoundedCorner} obtained from the system via
93      * {@link WindowInsets#getRoundedCorner} or {@link Display#getRoundedCorner}.</p>
94      *
95      * @param position the position of the rounded corner.
96      * @param radius the radius of the rounded corner.
97      * @param centerX the x of center point of the rounded corner.
98      * @param centerY the y of center point of the rounded corner.
99      *
100      */
RoundedCorner(@osition int position, int radius, int centerX, int centerY)101     public RoundedCorner(@Position int position, int radius, int centerX,
102             int centerY) {
103         mPosition = position;
104         mRadius = radius;
105         mCenter = new Point(centerX, centerY);
106     }
107 
108     /**
109      * Creates a {@link RoundedCorner} from a passed in {@link RoundedCorner}.
110      *
111      * @hide
112      */
RoundedCorner(RoundedCorner rc)113     RoundedCorner(RoundedCorner rc) {
114         mPosition = rc.getPosition();
115         mRadius = rc.getRadius();
116         mCenter = new Point(rc.getCenter());
117     }
118 
119     /**
120      * Get the position of this {@link RoundedCorner}.
121      *
122      * @see #POSITION_TOP_LEFT
123      * @see #POSITION_TOP_RIGHT
124      * @see #POSITION_BOTTOM_RIGHT
125      * @see #POSITION_BOTTOM_LEFT
126      */
getPosition()127     public @Position int getPosition() {
128         return mPosition;
129     }
130 
131     /**
132      * Returns the radius of a quarter circle approximation of this {@link RoundedCorner}.
133      *
134      * @return the rounded corner radius of this {@link RoundedCorner}. Returns 0 if there is no
135      * rounded corner.
136      */
getRadius()137     public int getRadius() {
138         return mRadius;
139     }
140 
141     /**
142      * Returns the circle center of a quarter circle approximation of this {@link RoundedCorner}.
143      *
144      * @return the center point of this {@link RoundedCorner} in the application's coordinate.
145      */
146     @NonNull
getCenter()147     public Point getCenter() {
148         return new Point(mCenter);
149     }
150 
151     /**
152      * Checks whether this {@link RoundedCorner} exists and is inside the application's bounds.
153      *
154      * @return {@code false} if there is a rounded corner and is contained in the application's
155      *                       bounds. Otherwise return {@code true}.
156      *
157      * @hide
158      */
isEmpty()159     public boolean isEmpty() {
160         return mRadius == 0 || mCenter.x <= 0 || mCenter.y <= 0;
161     }
162 
getPositionString(@osition int position)163     private String getPositionString(@Position int position) {
164         switch (position) {
165             case POSITION_TOP_LEFT:
166                 return "TopLeft";
167             case POSITION_TOP_RIGHT:
168                 return "TopRight";
169             case POSITION_BOTTOM_RIGHT:
170                 return "BottomRight";
171             case POSITION_BOTTOM_LEFT:
172                 return "BottomLeft";
173             default:
174                 return "Invalid";
175         }
176     }
177 
178     @Override
equals(Object o)179     public boolean equals(Object o) {
180         if (o == this) {
181             return true;
182         }
183         if (o instanceof RoundedCorner) {
184             RoundedCorner r = (RoundedCorner) o;
185             return mPosition == r.mPosition && mRadius == r.mRadius
186                     && mCenter.equals(r.mCenter);
187         }
188         return false;
189     }
190 
191     @Override
hashCode()192     public int hashCode() {
193         int result = 0;
194         result = 31 * result + mPosition;
195         result = 31 * result + mRadius;
196         result = 31 * result + mCenter.hashCode();
197         return result;
198     }
199 
200     @Override
toString()201     public String toString() {
202         return "RoundedCorner{"
203                 + "position=" + getPositionString(mPosition)
204                 + ", radius=" + mRadius
205                 + ", center=" + mCenter
206                 + '}';
207     }
208 
209     @Override
describeContents()210     public int describeContents() {
211         return 0;
212     }
213 
214     @Override
writeToParcel(@onNull Parcel out, int flags)215     public void writeToParcel(@NonNull Parcel out, int flags) {
216         out.writeInt(mPosition);
217         out.writeInt(mRadius);
218         out.writeInt(mCenter.x);
219         out.writeInt(mCenter.y);
220     }
221 
222     public static final @NonNull Creator<RoundedCorner> CREATOR = new Creator<RoundedCorner>() {
223         @Override
224         public RoundedCorner createFromParcel(Parcel in) {
225             return new RoundedCorner(in.readInt(), in.readInt(), in.readInt(), in.readInt());
226         }
227 
228         @Override
229         public RoundedCorner[] newArray(int size) {
230             return new RoundedCorner[size];
231         }
232     };
233 }
234