blob: 82175b721df061a470341e2f8dc3d42254c5aaa0 [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
Jon Miranda3298d0f2016-09-22 16:50:17 -070019import android.annotation.SuppressLint;
Winson Chung94804152015-05-08 13:06:44 -070020import android.content.Context;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080021import android.content.res.TypedArray;
Jon Miranda3298d0f2016-09-22 16:50:17 -070022import android.graphics.PointF;
Jon Miranda177ad2b2016-09-21 14:27:41 -070023import android.graphics.Rect;
Hyunyoung Songa97c64b2016-06-30 11:53:44 -070024import android.graphics.drawable.ColorDrawable;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080025import android.graphics.drawable.Drawable;
26import android.graphics.drawable.InsetDrawable;
Winson Chung94804152015-05-08 13:06:44 -070027import android.util.AttributeSet;
Jon Miranda3298d0f2016-09-22 16:50:17 -070028import android.view.MotionEvent;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080029import android.view.View;
Jon Miranda3298d0f2016-09-22 16:50:17 -070030import android.view.ViewConfiguration;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080031import android.widget.FrameLayout;
Winson Chung94804152015-05-08 13:06:44 -070032
Hyunyoung Song645764e2016-06-06 14:19:02 -070033import com.android.launcher3.allapps.AllAppsContainerView;
34import com.android.launcher3.config.FeatureFlags;
Jon Miranda177ad2b2016-09-21 14:27:41 -070035import com.android.launcher3.util.TransformingTouchDelegate;
Hyunyoung Song645764e2016-06-06 14:19:02 -070036
Winson Chung94804152015-05-08 13:06:44 -070037/**
38 * A base container view, which supports resizing.
39 */
Winson1f064272016-07-18 17:18:02 -070040public abstract class BaseContainerView extends FrameLayout
41 implements DeviceProfile.LauncherLayoutChangeListener {
Winson Chung94804152015-05-08 13:06:44 -070042
Sunny Goyal8b16b962016-11-01 13:42:23 -070043 private static final Rect sBgPaddingRect = new Rect();
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080044
Winson1f064272016-07-18 17:18:02 -070045 protected final Drawable mBaseDrawable;
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080046
47 private View mRevealView;
48 private View mContent;
Winson Chung94804152015-05-08 13:06:44 -070049
Jon Miranda177ad2b2016-09-21 14:27:41 -070050 private TransformingTouchDelegate mTouchDelegate;
51
Jon Miranda3298d0f2016-09-22 16:50:17 -070052 private final PointF mLastTouchDownPosPx = new PointF(-1.0f, -1.0f);
53
Winson Chung94804152015-05-08 13:06:44 -070054 public BaseContainerView(Context context) {
55 this(context, null);
56 }
57
58 public BaseContainerView(Context context, AttributeSet attrs) {
59 this(context, attrs, 0);
60 }
61
62 public BaseContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
63 super(context, attrs, defStyleAttr);
Sunny Goyal05c8c572016-03-17 11:57:24 -070064
Hyunyoung Songd725f642017-08-17 22:26:35 -070065 if (this instanceof AllAppsContainerView) {
Winson1f064272016-07-18 17:18:02 -070066 mBaseDrawable = new ColorDrawable();
Hyunyoung Songa97c64b2016-06-30 11:53:44 -070067 } else {
68 TypedArray a = context.obtainStyledAttributes(attrs,
69 R.styleable.BaseContainerView, defStyleAttr, 0);
Winson1f064272016-07-18 17:18:02 -070070 mBaseDrawable = a.getDrawable(R.styleable.BaseContainerView_revealBackground);
Hyunyoung Songa97c64b2016-06-30 11:53:44 -070071 a.recycle();
72 }
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080073 }
74
75 @Override
Winson1f064272016-07-18 17:18:02 -070076 protected void onAttachedToWindow() {
77 super.onAttachedToWindow();
78
79 DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile();
80 grid.addLauncherLayoutChangedListener(this);
Jon Miranda177ad2b2016-09-21 14:27:41 -070081
82 View touchDelegateTargetView = getTouchDelegateTargetView();
83 if (touchDelegateTargetView != null) {
84 mTouchDelegate = new TransformingTouchDelegate(touchDelegateTargetView);
85 ((View) touchDelegateTargetView.getParent()).setTouchDelegate(mTouchDelegate);
86 }
Winson1f064272016-07-18 17:18:02 -070087 }
88
89 @Override
90 protected void onDetachedFromWindow() {
91 super.onDetachedFromWindow();
92
93 DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile();
94 grid.removeLauncherLayoutChangedListener(this);
95 }
96
97 @Override
Sunny Goyal0ac7ede2016-01-29 13:14:14 -080098 protected void onFinishInflate() {
99 super.onFinishInflate();
100
101 mContent = findViewById(R.id.main_content);
102 mRevealView = findViewById(R.id.reveal_view);
Winson Chung94804152015-05-08 13:06:44 -0700103
Winson1f064272016-07-18 17:18:02 -0700104 updatePaddings();
105 }
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800106
Winson1f064272016-07-18 17:18:02 -0700107 @Override
Sunny Goyal8b16b962016-11-01 13:42:23 -0700108 public void onLauncherLayoutChanged() {
109 updatePaddings();
110 }
Jon Miranda177ad2b2016-09-21 14:27:41 -0700111
Sunny Goyal8b16b962016-11-01 13:42:23 -0700112 /**
113 * Calculate the background padding as it can change due to insets/content padding change.
114 */
115 private void updatePaddings() {
Jon Mirandab28c4fc2017-06-20 10:58:36 -0700116 DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile();
Jon Mirandac3e4e222016-11-02 16:56:52 -0700117 int[] padding = grid.getContainerPadding();
Jon Mirandab28c4fc2017-06-20 10:58:36 -0700118
119 int paddingLeft = padding[0];
120 int paddingRight = padding[1];
121 int paddingTop = 0;
122 int paddingBottom = 0;
123
Sunny Goyal8b16b962016-11-01 13:42:23 -0700124 if (!grid.isVerticalBarLayout()) {
Jon Mirandab28c4fc2017-06-20 10:58:36 -0700125 paddingLeft += grid.edgeMarginPx;
126 paddingRight += grid.edgeMarginPx;
Sunny Goyal8b16b962016-11-01 13:42:23 -0700127 paddingTop = paddingBottom = grid.edgeMarginPx;
Jon Miranda177ad2b2016-09-21 14:27:41 -0700128 }
Sunny Goyal8b16b962016-11-01 13:42:23 -0700129 updateBackground(paddingLeft, paddingTop, paddingRight, paddingBottom);
130 }
131
132 /**
133 * Update the background for the reveal view and content view based on the background padding.
134 */
135 protected void updateBackground(int paddingLeft, int paddingTop,
136 int paddingRight, int paddingBottom) {
137 mRevealView.setBackground(new InsetDrawable(mBaseDrawable,
138 paddingLeft, paddingTop, paddingRight, paddingBottom));
139 mContent.setBackground(new InsetDrawable(mBaseDrawable,
140 paddingLeft, paddingTop, paddingRight, paddingBottom));
Jon Miranda177ad2b2016-09-21 14:27:41 -0700141 }
142
143 @Override
Sunny Goyal8b16b962016-11-01 13:42:23 -0700144 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
145 super.onLayout(changed, left, top, right, bottom);
146
147 View touchDelegateTargetView = getTouchDelegateTargetView();
148 if (touchDelegateTargetView != null) {
149 getRevealView().getBackground().getPadding(sBgPaddingRect);
150 mTouchDelegate.setBounds(
151 touchDelegateTargetView.getLeft() - sBgPaddingRect.left,
152 touchDelegateTargetView.getTop() - sBgPaddingRect.top,
153 touchDelegateTargetView.getRight() + sBgPaddingRect.right,
154 touchDelegateTargetView.getBottom() + sBgPaddingRect.bottom);
155 }
Winson1f064272016-07-18 17:18:02 -0700156 }
157
Jon Miranda3298d0f2016-09-22 16:50:17 -0700158 @Override
159 public boolean onInterceptTouchEvent(MotionEvent ev) {
160 return handleTouchEvent(ev);
161 }
162
163 @SuppressLint("ClickableViewAccessibility")
164 @Override
165 public boolean onTouchEvent(MotionEvent ev) {
166 return handleTouchEvent(ev);
167 }
168
Winson1f064272016-07-18 17:18:02 -0700169 public void setRevealDrawableColor(int color) {
170 ((ColorDrawable) mBaseDrawable).setColor(color);
Winson Chung73f0b9b2015-07-08 14:13:08 -0700171 }
Sunny Goyal0ac7ede2016-01-29 13:14:14 -0800172
173 public final View getContentView() {
174 return mContent;
175 }
176
177 public final View getRevealView() {
178 return mRevealView;
179 }
Hyunyoung Songe4be3b32016-07-18 16:35:10 -0700180
Jon Miranda177ad2b2016-09-21 14:27:41 -0700181
Jon Miranda3298d0f2016-09-22 16:50:17 -0700182 /**
183 * Handles the touch events that shows the workspace when clicking outside the bounds of the
184 * touch delegate target view.
185 */
186 private boolean handleTouchEvent(MotionEvent ev) {
187 switch (ev.getAction()) {
188 case MotionEvent.ACTION_DOWN:
189 // Check if the touch is outside touch delegate target view
190 View touchDelegateTargetView = getTouchDelegateTargetView();
191 float leftBoundPx = touchDelegateTargetView.getLeft();
192 if (ev.getX() < leftBoundPx ||
193 ev.getX() > (touchDelegateTargetView.getWidth() + leftBoundPx)) {
194 mLastTouchDownPosPx.set((int) ev.getX(), (int) ev.getY());
195 }
196 break;
197 case MotionEvent.ACTION_UP:
198 if (mLastTouchDownPosPx.x > -1) {
199 ViewConfiguration viewConfig = ViewConfiguration.get(getContext());
200 float dx = ev.getX() - mLastTouchDownPosPx.x;
201 float dy = ev.getY() - mLastTouchDownPosPx.y;
202 float distance = PointF.length(dx, dy);
203 if (distance < viewConfig.getScaledTouchSlop()) {
204 // The background was clicked, so just go home
205 Launcher.getLauncher(getContext()).showWorkspace(true);
206 return true;
207 }
208 }
209 // Fall through
210 case MotionEvent.ACTION_CANCEL:
211 mLastTouchDownPosPx.set(-1, -1);
212 break;
213 }
214 return false;
215 }
216
Jon Miranda177ad2b2016-09-21 14:27:41 -0700217 public abstract View getTouchDelegateTargetView();
Andrew Sappersteinabef55a2016-06-19 12:49:00 -0700218}