1 /*
2  * Copyright (C) 2011 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 com.android.launcher3;
18 
19 import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
20 
21 import android.content.Context;
22 import android.graphics.Rect;
23 import android.util.AttributeSet;
24 import android.view.Gravity;
25 import android.view.MotionEvent;
26 import android.view.ViewDebug;
27 import android.view.ViewGroup;
28 import android.widget.FrameLayout;
29 
30 import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
31 import com.android.launcher3.model.data.ItemInfo;
32 import com.android.launcher3.userevent.nano.LauncherLogProto;
33 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
34 
35 import java.util.ArrayList;
36 
37 public class Hotseat extends CellLayout implements LogContainerProvider, Insettable {
38 
39     @ViewDebug.ExportedProperty(category = "launcher")
40     private boolean mHasVerticalHotseat;
41     private Workspace mWorkspace;
42     private boolean mSendTouchToWorkspace;
43 
Hotseat(Context context)44     public Hotseat(Context context) {
45         this(context, null);
46     }
47 
Hotseat(Context context, AttributeSet attrs)48     public Hotseat(Context context, AttributeSet attrs) {
49         this(context, attrs, 0);
50     }
51 
Hotseat(Context context, AttributeSet attrs, int defStyle)52     public Hotseat(Context context, AttributeSet attrs, int defStyle) {
53         super(context, attrs, defStyle);
54     }
55 
56     /**
57      * Returns orientation specific cell X given invariant order in the hotseat
58      */
getCellXFromOrder(int rank)59     public int getCellXFromOrder(int rank) {
60         return mHasVerticalHotseat ? 0 : rank;
61     }
62 
63     /**
64      * Returns orientation specific cell Y given invariant order in the hotseat
65      */
getCellYFromOrder(int rank)66     public int getCellYFromOrder(int rank) {
67         return mHasVerticalHotseat ? (getCountY() - (rank + 1)) : 0;
68     }
69 
resetLayout(boolean hasVerticalHotseat)70     public void resetLayout(boolean hasVerticalHotseat) {
71         removeAllViewsInLayout();
72         mHasVerticalHotseat = hasVerticalHotseat;
73         InvariantDeviceProfile idp = mActivity.getDeviceProfile().inv;
74         if (hasVerticalHotseat) {
75             setGridSize(1, idp.numHotseatIcons);
76         } else {
77             setGridSize(idp.numHotseatIcons, 1);
78         }
79     }
80 
81     @Override
fillInLogContainerData(ItemInfo childInfo, Target child, ArrayList<Target> parents)82     public void fillInLogContainerData(ItemInfo childInfo, Target child,
83             ArrayList<Target> parents) {
84         child.rank = childInfo.rank;
85         child.gridX = childInfo.cellX;
86         child.gridY = childInfo.cellY;
87         parents.add(newContainerTarget(LauncherLogProto.ContainerType.HOTSEAT));
88     }
89 
90     @Override
setInsets(Rect insets)91     public void setInsets(Rect insets) {
92         FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
93         DeviceProfile grid = mActivity.getDeviceProfile();
94 
95         if (grid.isVerticalBarLayout()) {
96             lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
97             if (grid.isSeascape()) {
98                 lp.gravity = Gravity.LEFT;
99                 lp.width = grid.hotseatBarSizePx + insets.left;
100             } else {
101                 lp.gravity = Gravity.RIGHT;
102                 lp.width = grid.hotseatBarSizePx + insets.right;
103             }
104         } else {
105             lp.gravity = Gravity.BOTTOM;
106             lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
107             lp.height = grid.hotseatBarSizePx + insets.bottom;
108         }
109         Rect padding = grid.getHotseatLayoutPadding();
110         setPadding(padding.left, padding.top, padding.right, padding.bottom);
111 
112         setLayoutParams(lp);
113         InsettableFrameLayout.dispatchInsets(this, insets);
114     }
115 
setWorkspace(Workspace w)116     public void setWorkspace(Workspace w) {
117         mWorkspace = w;
118     }
119 
120     @Override
onInterceptTouchEvent(MotionEvent ev)121     public boolean onInterceptTouchEvent(MotionEvent ev) {
122         // We allow horizontal workspace scrolling from within the Hotseat. We do this by delegating
123         // touch intercept the Workspace, and if it intercepts, delegating touch to the Workspace
124         // for the remainder of the this input stream.
125         int yThreshold = getMeasuredHeight() - getPaddingBottom();
126         if (mWorkspace != null && ev.getY() <= yThreshold) {
127             mSendTouchToWorkspace = mWorkspace.onInterceptTouchEvent(ev);
128             return mSendTouchToWorkspace;
129         }
130         return false;
131     }
132 
133     @Override
onTouchEvent(MotionEvent event)134     public boolean onTouchEvent(MotionEvent event) {
135         // See comment in #onInterceptTouchEvent
136         if (mSendTouchToWorkspace) {
137             final int action = event.getAction();
138             switch (action & MotionEvent.ACTION_MASK) {
139                 case MotionEvent.ACTION_UP:
140                 case MotionEvent.ACTION_CANCEL:
141                     mSendTouchToWorkspace = false;
142             }
143             return mWorkspace.onTouchEvent(event);
144         }
145         return event.getY() > getCellHeight();
146     }
147 }
148