blob: 8bb8c55fd628d707750807b3e55ca56e5c7699cc [file] [log] [blame]
Winson Chung94804152015-05-08 13:06:44 -07001/*
2 * Copyright (C) 2015 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
17package com.android.launcher3;
18
19import android.content.Context;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080020import android.content.res.TypedArray;
Winson Chung94804152015-05-08 13:06:44 -070021import android.graphics.Rect;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080022import android.graphics.drawable.Drawable;
23import android.graphics.drawable.InsetDrawable;
Winson Chung94804152015-05-08 13:06:44 -070024import android.util.AttributeSet;
Winson Chung73f0b9b2015-07-08 14:13:08 -070025import android.util.Log;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080026import android.view.View;
27import android.widget.FrameLayout;
Winson Chung94804152015-05-08 13:06:44 -070028
29/**
30 * A base container view, which supports resizing.
31 */
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080032public abstract class BaseContainerView extends FrameLayout implements Insettable {
Winson Chung94804152015-05-08 13:06:44 -070033
Winson Chung73f0b9b2015-07-08 14:13:08 -070034 private final static String TAG = "BaseContainerView";
35
Winson Chungef7f8742015-06-04 17:18:17 -070036 // The window insets
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080037 private final Rect mInsets = new Rect();
Winson Chungef7f8742015-06-04 17:18:17 -070038 // The bounds of the search bar. Only the left, top, right are used to inset the
39 // search bar and the height is determined by the measurement of the layout
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080040 private final Rect mFixedSearchBarBounds = new Rect();
Winsonb0ca1a22015-08-06 14:42:50 -070041 // The computed bounds of the container
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080042 protected final Rect mContentBounds = new Rect();
Winsonb0ca1a22015-08-06 14:42:50 -070043 // The computed padding to apply to the container to achieve the container bounds
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080044 private final Rect mContentPadding = new Rect();
Winson Chungef7f8742015-06-04 17:18:17 -070045 // The inset to apply to the edges and between the search bar and the container
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080046 private final int mContainerBoundsInset;
47
48 private final Drawable mRevealDrawable;
49
50 private View mRevealView;
51 private View mContent;
Winson Chung94804152015-05-08 13:06:44 -070052
53 public BaseContainerView(Context context) {
54 this(context, null);
55 }
56
57 public BaseContainerView(Context context, AttributeSet attrs) {
58 this(context, attrs, 0);
59 }
60
61 public BaseContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
62 super(context, attrs, defStyleAttr);
Winson Chungef7f8742015-06-04 17:18:17 -070063 mContainerBoundsInset = getResources().getDimensionPixelSize(R.dimen.container_bounds_inset);
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080064
65 TypedArray a = context.obtainStyledAttributes(attrs,
66 R.styleable.BaseContainerView, defStyleAttr, 0);
67 mRevealDrawable = a.getDrawable(R.styleable.BaseContainerView_revealBackground);
68 a.recycle();
69 }
70
71 @Override
72 protected void onFinishInflate() {
73 super.onFinishInflate();
74
75 mContent = findViewById(R.id.main_content);
76 mRevealView = findViewById(R.id.reveal_view);
Winson Chung94804152015-05-08 13:06:44 -070077 }
78
79 @Override
80 final public void setInsets(Rect insets) {
81 mInsets.set(insets);
Winson Chungef7f8742015-06-04 17:18:17 -070082 updateBackgroundAndPaddings();
83 }
84
Winson Chung94804152015-05-08 13:06:44 -070085 /**
Winson Chungef7f8742015-06-04 17:18:17 -070086 * Sets the search bar bounds for this container view to match.
Winson Chung94804152015-05-08 13:06:44 -070087 */
Winson Chungef7f8742015-06-04 17:18:17 -070088 final public void setSearchBarBounds(Rect bounds) {
Winson Chung73f0b9b2015-07-08 14:13:08 -070089 if (LauncherAppState.isDogfoodBuild() && !isValidSearchBarBounds(bounds)) {
90 Log.e(TAG, "Invalid search bar bounds: " + bounds);
91 }
92
93 mFixedSearchBarBounds.set(bounds);
Winson Chungef7f8742015-06-04 17:18:17 -070094
Winson Chung94804152015-05-08 13:06:44 -070095 // Post the updates since they can trigger a relayout, and this call can be triggered from
96 // a layout pass itself.
97 post(new Runnable() {
98 @Override
99 public void run() {
Winson Chungef7f8742015-06-04 17:18:17 -0700100 updateBackgroundAndPaddings();
Winson Chung94804152015-05-08 13:06:44 -0700101 }
102 });
103 }
104
105 /**
Winson Chungef7f8742015-06-04 17:18:17 -0700106 * Update the backgrounds and padding in response to a change in the bounds or insets.
Winson Chung94804152015-05-08 13:06:44 -0700107 */
Winson Chungef7f8742015-06-04 17:18:17 -0700108 protected void updateBackgroundAndPaddings() {
109 Rect padding;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800110 if (isValidSearchBarBounds(mFixedSearchBarBounds)) {
111 padding = new Rect(
112 mFixedSearchBarBounds.left,
Winson Chungef7f8742015-06-04 17:18:17 -0700113 mInsets.top + mContainerBoundsInset,
Winson Chung73f0b9b2015-07-08 14:13:08 -0700114 getMeasuredWidth() - mFixedSearchBarBounds.right,
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800115 mInsets.bottom + mContainerBoundsInset
116 );
117 } else {
118 padding = new Rect(
119 mInsets.left + mContainerBoundsInset,
120 mInsets.top + mContainerBoundsInset,
121 mInsets.right + mContainerBoundsInset,
122 mInsets.bottom + mContainerBoundsInset
123 );
Winson Chungef7f8742015-06-04 17:18:17 -0700124 }
Winsonb0ca1a22015-08-06 14:42:50 -0700125
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800126 // The container padding changed, notify the container.
127 if (!padding.equals(mContentPadding)) {
Winson Chungef7f8742015-06-04 17:18:17 -0700128 mContentPadding.set(padding);
129 mContentBounds.set(padding.left, padding.top,
130 getMeasuredWidth() - padding.right,
131 getMeasuredHeight() - padding.bottom);
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800132 onUpdateBackgroundAndPaddings(padding);
Winson Chungef7f8742015-06-04 17:18:17 -0700133 }
Winson Chung94804152015-05-08 13:06:44 -0700134 }
135
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800136 private void onUpdateBackgroundAndPaddings(Rect padding) {
137 // Apply the top-bottom padding to itself so that the launcher transition is
138 // clipped correctly
139 setPadding(0, padding.top, 0, padding.bottom);
140
141 InsetDrawable background = new InsetDrawable(mRevealDrawable,
142 padding.left, 0, padding.right, 0);
143 mRevealView.setBackground(background.getConstantState().newDrawable());
144 mContent.setBackground(background);
145
146 Rect bgPadding = new Rect();
147 background.getPadding(bgPadding);
148 onUpdateBgPadding(padding, bgPadding);
149 }
150
151 protected abstract void onUpdateBgPadding(Rect padding, Rect bgPadding);
Winson Chung73f0b9b2015-07-08 14:13:08 -0700152
153 /**
154 * Returns whether the search bar bounds we got are considered valid.
155 */
156 private boolean isValidSearchBarBounds(Rect searchBarBounds) {
157 return !searchBarBounds.isEmpty() &&
158 searchBarBounds.right <= getMeasuredWidth() &&
159 searchBarBounds.bottom <= getMeasuredHeight();
160 }
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800161
162 public final View getContentView() {
163 return mContent;
164 }
165
166 public final View getRevealView() {
167 return mRevealView;
168 }
Winson Chung94804152015-05-08 13:06:44 -0700169}