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.graphics.drawable.Drawable;
22 import android.os.Bundle;
23 import android.util.AttributeSet;
24 import android.view.LayoutInflater;
25 import android.view.MotionEvent;
26 import android.view.View;
27 import android.widget.FrameLayout;
28 import android.widget.TextView;
29 
30 public class Hotseat extends FrameLayout
31         implements Stats.LaunchSourceProvider{
32 
33     private CellLayout mContent;
34 
35     private Launcher mLauncher;
36 
37     private int mAllAppsButtonRank;
38 
39     private final boolean mHasVerticalHotseat;
40 
Hotseat(Context context)41     public Hotseat(Context context) {
42         this(context, null);
43     }
44 
Hotseat(Context context, AttributeSet attrs)45     public Hotseat(Context context, AttributeSet attrs) {
46         this(context, attrs, 0);
47     }
48 
Hotseat(Context context, AttributeSet attrs, int defStyle)49     public Hotseat(Context context, AttributeSet attrs, int defStyle) {
50         super(context, attrs, defStyle);
51         mLauncher = (Launcher) context;
52         mHasVerticalHotseat = mLauncher.getDeviceProfile().isVerticalBarLayout();
53     }
54 
getLayout()55     CellLayout getLayout() {
56         return mContent;
57     }
58 
59     /**
60      * Returns whether there are other icons than the all apps button in the hotseat.
61      */
hasIcons()62     public boolean hasIcons() {
63         return mContent.getShortcutsAndWidgets().getChildCount() > 1;
64     }
65 
66     /**
67      * Registers the specified listener on the cell layout of the hotseat.
68      */
69     @Override
setOnLongClickListener(OnLongClickListener l)70     public void setOnLongClickListener(OnLongClickListener l) {
71         mContent.setOnLongClickListener(l);
72     }
73 
74     /* Get the orientation invariant order of the item in the hotseat for persistence. */
getOrderInHotseat(int x, int y)75     int getOrderInHotseat(int x, int y) {
76         return mHasVerticalHotseat ? (mContent.getCountY() - y - 1) : x;
77     }
78 
79     /* Get the orientation specific coordinates given an invariant order in the hotseat. */
getCellXFromOrder(int rank)80     int getCellXFromOrder(int rank) {
81         return mHasVerticalHotseat ? 0 : rank;
82     }
83 
getCellYFromOrder(int rank)84     int getCellYFromOrder(int rank) {
85         return mHasVerticalHotseat ? (mContent.getCountY() - (rank + 1)) : 0;
86     }
87 
isAllAppsButtonRank(int rank)88     public boolean isAllAppsButtonRank(int rank) {
89         return rank == mAllAppsButtonRank;
90     }
91 
92     @Override
onFinishInflate()93     protected void onFinishInflate() {
94         super.onFinishInflate();
95         DeviceProfile grid = mLauncher.getDeviceProfile();
96 
97         mAllAppsButtonRank = grid.inv.hotseatAllAppsRank;
98         mContent = (CellLayout) findViewById(R.id.layout);
99         if (grid.isLandscape && !grid.isLargeTablet) {
100             mContent.setGridSize(1, (int) grid.inv.numHotseatIcons);
101         } else {
102             mContent.setGridSize((int) grid.inv.numHotseatIcons, 1);
103         }
104         mContent.setIsHotseat(true);
105 
106         resetLayout();
107     }
108 
resetLayout()109     void resetLayout() {
110         mContent.removeAllViewsInLayout();
111 
112         // Add the Apps button
113         Context context = getContext();
114 
115         LayoutInflater inflater = LayoutInflater.from(context);
116         TextView allAppsButton = (TextView)
117                 inflater.inflate(R.layout.all_apps_button, mContent, false);
118         Drawable d = context.getResources().getDrawable(R.drawable.all_apps_button_icon);
119 
120         mLauncher.resizeIconDrawable(d);
121         int scaleDownPx = getResources().getDimensionPixelSize(R.dimen.all_apps_button_scale_down);
122         Rect bounds = d.getBounds();
123         d.setBounds(bounds.left, bounds.top + scaleDownPx / 2, bounds.right - scaleDownPx,
124                 bounds.bottom - scaleDownPx / 2);
125         allAppsButton.setCompoundDrawables(null, d, null, null);
126 
127         allAppsButton.setContentDescription(context.getString(R.string.all_apps_button_label));
128         allAppsButton.setOnKeyListener(new HotseatIconKeyEventListener());
129         if (mLauncher != null) {
130             mLauncher.setAllAppsButton(allAppsButton);
131             allAppsButton.setOnTouchListener(mLauncher.getHapticFeedbackTouchListener());
132             allAppsButton.setOnClickListener(mLauncher);
133             allAppsButton.setOnLongClickListener(mLauncher);
134             allAppsButton.setOnFocusChangeListener(mLauncher.mFocusHandler);
135         }
136 
137         // Note: We do this to ensure that the hotseat is always laid out in the orientation of
138         // the hotseat in order regardless of which orientation they were added
139         int x = getCellXFromOrder(mAllAppsButtonRank);
140         int y = getCellYFromOrder(mAllAppsButtonRank);
141         CellLayout.LayoutParams lp = new CellLayout.LayoutParams(x,y,1,1);
142         lp.canReorder = false;
143         mContent.addViewToCellLayout(allAppsButton, -1, allAppsButton.getId(), lp, true);
144     }
145 
146     @Override
onInterceptTouchEvent(MotionEvent ev)147     public boolean onInterceptTouchEvent(MotionEvent ev) {
148         // We don't want any clicks to go through to the hotseat unless the workspace is in
149         // the normal state.
150         if (mLauncher.getWorkspace().workspaceInModalState()) {
151             return true;
152         }
153         return false;
154     }
155 
156     @Override
fillInLaunchSourceData(View v, Bundle sourceData)157     public void fillInLaunchSourceData(View v, Bundle sourceData) {
158         sourceData.putString(Stats.SOURCE_EXTRA_CONTAINER, Stats.CONTAINER_HOTSEAT);
159     }
160 }
161