WindowInsets.java revision eba8782a1f8412a3510fc78a71b843ef6e89bdbb
1/*
2 * Copyright (C) 2014 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
18package android.view;
19
20import android.graphics.Rect;
21
22/**
23 * Describes a set of insets for window content.
24 *
25 * <p>WindowInsets are immutable and may be expanded to include more inset types in the future.
26 * To adjust insets, use one of the supplied clone methods to obtain a new WindowInsets instance
27 * with the adjusted properties.</p>
28 *
29 * @see View.OnApplyWindowInsetsListener
30 * @see View#onApplyWindowInsets(WindowInsets)
31 */
32public final class WindowInsets {
33    private Rect mSystemWindowInsets;
34    private Rect mWindowDecorInsets;
35    private Rect mTempRect;
36    private boolean mIsRound;
37
38    private static final Rect EMPTY_RECT = new Rect(0, 0, 0, 0);
39
40    /**
41     * Since new insets may be added in the future that existing apps couldn't
42     * know about, this fully empty constant shouldn't be made available to apps
43     * since it would allow them to inadvertently consume unknown insets by returning it.
44     * @hide
45     */
46    public static final WindowInsets EMPTY = new WindowInsets(EMPTY_RECT, EMPTY_RECT);
47
48    /** @hide */
49    public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets) {
50        this(systemWindowInsets, windowDecorInsets, false);
51    }
52
53    /** @hide */
54    public WindowInsets(Rect systemWindowInsets, boolean isRound) {
55        this(systemWindowInsets, EMPTY_RECT, isRound);
56    }
57
58    /** @hide */
59    public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets, boolean isRound) {
60        mSystemWindowInsets = systemWindowInsets;
61        mWindowDecorInsets = windowDecorInsets;
62        mIsRound = isRound;
63    }
64
65    /**
66     * Construct a new WindowInsets, copying all values from a source WindowInsets.
67     *
68     * @param src Source to copy insets from
69     */
70    public WindowInsets(WindowInsets src) {
71        mSystemWindowInsets = src.mSystemWindowInsets;
72        mWindowDecorInsets = src.mWindowDecorInsets;
73        mIsRound = src.mIsRound;
74    }
75
76    /** @hide */
77    public WindowInsets(Rect systemWindowInsets) {
78        this(systemWindowInsets, EMPTY_RECT);
79    }
80
81    /**
82     * Used to provide a safe copy of the system window insets to pass through
83     * to the existing fitSystemWindows method and other similar internals.
84     * @hide
85     */
86    public Rect getSystemWindowInsets() {
87        if (mTempRect == null) {
88            mTempRect = new Rect();
89        }
90        if (mSystemWindowInsets != null) {
91            mTempRect.set(mSystemWindowInsets);
92        } else {
93            // If there were no system window insets, this is just empty.
94            mTempRect.setEmpty();
95        }
96        return mTempRect;
97    }
98
99    /**
100     * Returns the left system window inset in pixels.
101     *
102     * <p>The system window inset represents the area of a full-screen window that is
103     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
104     * </p>
105     *
106     * @return The left system window inset
107     */
108    public int getSystemWindowInsetLeft() {
109        return mSystemWindowInsets.left;
110    }
111
112    /**
113     * Returns the top system window inset in pixels.
114     *
115     * <p>The system window inset represents the area of a full-screen window that is
116     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
117     * </p>
118     *
119     * @return The top system window inset
120     */
121    public int getSystemWindowInsetTop() {
122        return mSystemWindowInsets.top;
123    }
124
125    /**
126     * Returns the right system window inset in pixels.
127     *
128     * <p>The system window inset represents the area of a full-screen window that is
129     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
130     * </p>
131     *
132     * @return The right system window inset
133     */
134    public int getSystemWindowInsetRight() {
135        return mSystemWindowInsets.right;
136    }
137
138    /**
139     * Returns the bottom system window inset in pixels.
140     *
141     * <p>The system window inset represents the area of a full-screen window that is
142     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
143     * </p>
144     *
145     * @return The bottom system window inset
146     */
147    public int getSystemWindowInsetBottom() {
148        return mSystemWindowInsets.bottom;
149    }
150
151    /**
152     * Returns the left window decor inset in pixels.
153     *
154     * <p>The window decor inset represents the area of the window content area that is
155     * partially or fully obscured by decorations within the window provided by the framework.
156     * This can include action bars, title bars, toolbars, etc.</p>
157     *
158     * @return The left window decor inset
159     * @hide pending API
160     */
161    public int getWindowDecorInsetLeft() {
162        return mWindowDecorInsets.left;
163    }
164
165    /**
166     * Returns the top window decor inset in pixels.
167     *
168     * <p>The window decor inset represents the area of the window content area that is
169     * partially or fully obscured by decorations within the window provided by the framework.
170     * This can include action bars, title bars, toolbars, etc.</p>
171     *
172     * @return The top window decor inset
173     * @hide pending API
174     */
175    public int getWindowDecorInsetTop() {
176        return mWindowDecorInsets.top;
177    }
178
179    /**
180     * Returns the right window decor inset in pixels.
181     *
182     * <p>The window decor inset represents the area of the window content area that is
183     * partially or fully obscured by decorations within the window provided by the framework.
184     * This can include action bars, title bars, toolbars, etc.</p>
185     *
186     * @return The right window decor inset
187     * @hide pending API
188     */
189    public int getWindowDecorInsetRight() {
190        return mWindowDecorInsets.right;
191    }
192
193    /**
194     * Returns the bottom window decor inset in pixels.
195     *
196     * <p>The window decor inset represents the area of the window content area that is
197     * partially or fully obscured by decorations within the window provided by the framework.
198     * This can include action bars, title bars, toolbars, etc.</p>
199     *
200     * @return The bottom window decor inset
201     * @hide pending API
202     */
203    public int getWindowDecorInsetBottom() {
204        return mWindowDecorInsets.bottom;
205    }
206
207    /**
208     * Returns true if this WindowInsets has nonzero system window insets.
209     *
210     * <p>The system window inset represents the area of a full-screen window that is
211     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
212     * </p>
213     *
214     * @return true if any of the system window inset values are nonzero
215     */
216    public boolean hasSystemWindowInsets() {
217        return mSystemWindowInsets.left != 0 || mSystemWindowInsets.top != 0 ||
218                mSystemWindowInsets.right != 0 || mSystemWindowInsets.bottom != 0;
219    }
220
221    /**
222     * Returns true if this WindowInsets has nonzero window decor insets.
223     *
224     * <p>The window decor inset represents the area of the window content area that is
225     * partially or fully obscured by decorations within the window provided by the framework.
226     * This can include action bars, title bars, toolbars, etc.</p>
227     *
228     * @return true if any of the window decor inset values are nonzero
229     * @hide pending API
230     */
231    public boolean hasWindowDecorInsets() {
232        return mWindowDecorInsets.left != 0 || mWindowDecorInsets.top != 0 ||
233                mWindowDecorInsets.right != 0 || mWindowDecorInsets.bottom != 0;
234    }
235
236    /**
237     * Returns true if this WindowInsets has any nonzero insets.
238     *
239     * @return true if any inset values are nonzero
240     */
241    public boolean hasInsets() {
242        return hasSystemWindowInsets() || hasWindowDecorInsets();
243    }
244
245    /**
246     * Returns true if the associated window has a round shape.
247     *
248     * <p>A round window's left, top, right and bottom edges reach all the way to the
249     * associated edges of the window but the corners may not be visible. Views responding
250     * to round insets should take care to not lay out critical elements within the corners
251     * where they may not be accessible.</p>
252     *
253     * @return True if the window is round
254     */
255    public boolean isRound() {
256        return mIsRound;
257    }
258
259    /**
260     * Returns a copy of this WindowInsets with the system window insets fully consumed.
261     *
262     * @return A modified copy of this WindowInsets
263     */
264    public WindowInsets consumeSystemWindowInsets() {
265        final WindowInsets result = new WindowInsets(this);
266        result.mSystemWindowInsets = new Rect(0, 0, 0, 0);
267        return result;
268    }
269
270    /**
271     * Returns a copy of this WindowInsets with selected system window insets fully consumed.
272     *
273     * @param left true to consume the left system window inset
274     * @param top true to consume the top system window inset
275     * @param right true to consume the right system window inset
276     * @param bottom true to consume the bottom system window inset
277     * @return A modified copy of this WindowInsets
278     * @hide pending API
279     */
280    public WindowInsets consumeSystemWindowInsets(boolean left, boolean top,
281            boolean right, boolean bottom) {
282        if (left || top || right || bottom) {
283            final WindowInsets result = new WindowInsets(this);
284            result.mSystemWindowInsets = new Rect(left ? 0 : mSystemWindowInsets.left,
285                    top ? 0 : mSystemWindowInsets.top,
286                    right ? 0 : mSystemWindowInsets.right,
287                    bottom ? 0 : mSystemWindowInsets.bottom);
288            return result;
289        }
290        return this;
291    }
292
293    /**
294     * Returns a copy of this WindowInsets with selected system window insets replaced
295     * with new values.
296     *
297     * @param left New left inset in pixels
298     * @param top New top inset in pixels
299     * @param right New right inset in pixels
300     * @param bottom New bottom inset in pixels
301     * @return A modified copy of this WindowInsets
302     */
303    public WindowInsets replaceSystemWindowInsets(int left, int top,
304            int right, int bottom) {
305        final WindowInsets result = new WindowInsets(this);
306        result.mSystemWindowInsets = new Rect(left, top, right, bottom);
307        return result;
308    }
309
310    /**
311     * @hide
312     */
313    public WindowInsets consumeWindowDecorInsets() {
314        final WindowInsets result = new WindowInsets(this);
315        result.mWindowDecorInsets.set(0, 0, 0, 0);
316        return result;
317    }
318
319    /**
320     * @hide
321     */
322    public WindowInsets consumeWindowDecorInsets(boolean left, boolean top,
323            boolean right, boolean bottom) {
324        if (left || top || right || bottom) {
325            final WindowInsets result = new WindowInsets(this);
326            result.mWindowDecorInsets = new Rect(left ? 0 : mWindowDecorInsets.left,
327                    top ? 0 : mWindowDecorInsets.top,
328                    right ? 0 : mWindowDecorInsets.right,
329                    bottom ? 0 : mWindowDecorInsets.bottom);
330            return result;
331        }
332        return this;
333    }
334
335    /**
336     * @hide
337     */
338    public WindowInsets replaceWindowDecorInsets(int left, int top, int right, int bottom) {
339        final WindowInsets result = new WindowInsets(this);
340        result.mWindowDecorInsets = new Rect(left, top, right, bottom);
341        return result;
342    }
343
344    @Override
345    public String toString() {
346        return "WindowInsets{systemWindowInsets=" + mSystemWindowInsets + " windowDecorInsets=" +
347                mWindowDecorInsets + (isRound() ? "round}" : "}");
348    }
349}
350