• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.content.Context;
20 import android.graphics.Rect;
21 import android.util.AttributeSet;
22 import android.view.Gravity;
23 import android.view.LayoutInflater;
24 import android.view.MotionEvent;
25 import android.view.View;
26 import android.view.ViewDebug;
27 import android.view.ViewGroup;
28 import android.widget.FrameLayout;
29 
30 /**
31  * View class that represents the bottom row of the home screen.
32  */
33 public class Hotseat extends CellLayout implements Insettable {
34 
35     // Ratio of empty space, qsb should take up to appear visually centered.
36     public static final float QSB_CENTER_FACTOR = .325f;
37 
38     @ViewDebug.ExportedProperty(category = "launcher")
39     private boolean mHasVerticalHotseat;
40     private Workspace<?> mWorkspace;
41     private boolean mSendTouchToWorkspace;
42 
43     private final View mQsb;
44 
Hotseat(Context context)45     public Hotseat(Context context) {
46         this(context, null);
47     }
48 
Hotseat(Context context, AttributeSet attrs)49     public Hotseat(Context context, AttributeSet attrs) {
50         this(context, attrs, 0);
51     }
52 
Hotseat(Context context, AttributeSet attrs, int defStyle)53     public Hotseat(Context context, AttributeSet attrs, int defStyle) {
54         super(context, attrs, defStyle);
55 
56         mQsb = LayoutInflater.from(context).inflate(R.layout.search_container_hotseat, this, false);
57         addView(mQsb);
58     }
59 
60     /**
61      * Returns orientation specific cell X given invariant order in the hotseat
62      */
getCellXFromOrder(int rank)63     public int getCellXFromOrder(int rank) {
64         return mHasVerticalHotseat ? 0 : rank;
65     }
66 
67     /**
68      * Returns orientation specific cell Y given invariant order in the hotseat
69      */
getCellYFromOrder(int rank)70     public int getCellYFromOrder(int rank) {
71         return mHasVerticalHotseat ? (getCountY() - (rank + 1)) : 0;
72     }
73 
resetLayout(boolean hasVerticalHotseat)74     public void resetLayout(boolean hasVerticalHotseat) {
75         removeAllViewsInLayout();
76         mHasVerticalHotseat = hasVerticalHotseat;
77         DeviceProfile dp = mActivity.getDeviceProfile();
78         resetCellSize(dp);
79         if (hasVerticalHotseat) {
80             setGridSize(1, dp.numShownHotseatIcons);
81         } else {
82             setGridSize(dp.numShownHotseatIcons, 1);
83         }
84     }
85 
86     @Override
setInsets(Rect insets)87     public void setInsets(Rect insets) {
88         FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
89         DeviceProfile grid = mActivity.getDeviceProfile();
90 
91         if (grid.isVerticalBarLayout()) {
92             mQsb.setVisibility(View.GONE);
93             lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
94             if (grid.isSeascape()) {
95                 lp.gravity = Gravity.LEFT;
96                 lp.width = grid.hotseatBarSizePx + insets.left;
97             } else {
98                 lp.gravity = Gravity.RIGHT;
99                 lp.width = grid.hotseatBarSizePx + insets.right;
100             }
101         } else {
102             mQsb.setVisibility(View.VISIBLE);
103             lp.gravity = Gravity.BOTTOM;
104             lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
105             lp.height = grid.hotseatBarSizePx;
106         }
107 
108         Rect padding = grid.getHotseatLayoutPadding(getContext());
109         setPadding(padding.left, padding.top, padding.right, padding.bottom);
110         setLayoutParams(lp);
111         InsettableFrameLayout.dispatchInsets(this, insets);
112     }
113 
setWorkspace(Workspace<?> w)114     public void setWorkspace(Workspace<?> w) {
115         mWorkspace = w;
116     }
117 
118     @Override
onInterceptTouchEvent(MotionEvent ev)119     public boolean onInterceptTouchEvent(MotionEvent ev) {
120         // We allow horizontal workspace scrolling from within the Hotseat. We do this by delegating
121         // touch intercept the Workspace, and if it intercepts, delegating touch to the Workspace
122         // for the remainder of the this input stream.
123         int yThreshold = getMeasuredHeight() - getPaddingBottom();
124         if (mWorkspace != null && ev.getY() <= yThreshold) {
125             mSendTouchToWorkspace = mWorkspace.onInterceptTouchEvent(ev);
126             return mSendTouchToWorkspace;
127         }
128         return false;
129     }
130 
131     @Override
onTouchEvent(MotionEvent event)132     public boolean onTouchEvent(MotionEvent event) {
133         // See comment in #onInterceptTouchEvent
134         if (mSendTouchToWorkspace) {
135             final int action = event.getAction();
136             switch (action & MotionEvent.ACTION_MASK) {
137                 case MotionEvent.ACTION_UP:
138                 case MotionEvent.ACTION_CANCEL:
139                     mSendTouchToWorkspace = false;
140             }
141             return mWorkspace.onTouchEvent(event);
142         }
143         // Always let touch follow through to Workspace.
144         return false;
145     }
146 
147     @Override
onMeasure(int widthMeasureSpec, int heightMeasureSpec)148     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
149         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
150 
151         DeviceProfile dp = mActivity.getDeviceProfile();
152         mQsb.measure(MeasureSpec.makeMeasureSpec(dp.hotseatQsbWidth, MeasureSpec.EXACTLY),
153                 MeasureSpec.makeMeasureSpec(dp.hotseatQsbHeight, MeasureSpec.EXACTLY));
154     }
155 
156     @Override
onLayout(boolean changed, int l, int t, int r, int b)157     protected void onLayout(boolean changed, int l, int t, int r, int b) {
158         super.onLayout(changed, l, t, r, b);
159 
160         int qsbMeasuredWidth = mQsb.getMeasuredWidth();
161         int left;
162         DeviceProfile dp = mActivity.getDeviceProfile();
163         if (dp.isQsbInline) {
164             int qsbSpace = dp.hotseatBorderSpace;
165             left = Utilities.isRtl(getResources()) ? r - getPaddingRight() + qsbSpace
166                     : l + getPaddingLeft() - qsbMeasuredWidth - qsbSpace;
167         } else {
168             left = (r - l - qsbMeasuredWidth) / 2;
169         }
170         int right = left + qsbMeasuredWidth;
171 
172         int bottom = b - t - dp.getQsbOffsetY();
173         int top = bottom - dp.hotseatQsbHeight;
174         mQsb.layout(left, top, right, bottom);
175     }
176 
177     /**
178      * Sets the alpha value of just our ShortcutAndWidgetContainer.
179      */
setIconsAlpha(float alpha)180     public void setIconsAlpha(float alpha) {
181         getShortcutsAndWidgets().setAlpha(alpha);
182     }
183 
184     /**
185      * Sets the alpha value of just our QSB.
186      */
setQsbAlpha(float alpha)187     public void setQsbAlpha(float alpha) {
188         mQsb.setAlpha(alpha);
189     }
190 
getIconsAlpha()191     public float getIconsAlpha() {
192         return getShortcutsAndWidgets().getAlpha();
193     }
194 
195     /**
196      * Returns the QSB inside hotseat
197      */
getQsb()198     public View getQsb() {
199         return mQsb;
200     }
201 
202 }
203