Hotseat.java revision 6c5891a9fce95eee3d87823d11d21889743e9c68
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
17package com.android.launcher3;
18
19import android.content.ComponentName;
20import android.content.Context;
21import android.content.res.Configuration;
22import android.content.res.Resources;
23import android.graphics.Rect;
24import android.graphics.drawable.Drawable;
25import android.util.AttributeSet;
26import android.util.Log;
27import android.view.LayoutInflater;
28import android.view.MotionEvent;
29import android.view.View;
30import android.widget.FrameLayout;
31import android.widget.TextView;
32
33import java.util.ArrayList;
34
35public class Hotseat extends FrameLayout {
36    private static final String TAG = "Hotseat";
37
38    private CellLayout mContent;
39
40    private Launcher mLauncher;
41
42    private int mAllAppsButtonRank;
43
44    private boolean mTransposeLayoutWithOrientation;
45    private boolean mIsLandscape;
46
47    public Hotseat(Context context) {
48        this(context, null);
49    }
50
51    public Hotseat(Context context, AttributeSet attrs) {
52        this(context, attrs, 0);
53    }
54
55    public Hotseat(Context context, AttributeSet attrs, int defStyle) {
56        super(context, attrs, defStyle);
57
58        Resources r = context.getResources();
59        mTransposeLayoutWithOrientation =
60                r.getBoolean(R.bool.hotseat_transpose_layout_with_orientation);
61        mIsLandscape = context.getResources().getConfiguration().orientation ==
62            Configuration.ORIENTATION_LANDSCAPE;
63    }
64
65    public void setup(Launcher launcher) {
66        mLauncher = launcher;
67        setOnKeyListener(new HotseatIconKeyEventListener());
68    }
69
70    CellLayout getLayout() {
71        return mContent;
72    }
73
74    /**
75     * Registers the specified listener on the cell layout of the hotseat.
76     */
77    @Override
78    public void setOnLongClickListener(OnLongClickListener l) {
79        mContent.setOnLongClickListener(l);
80    }
81
82    private boolean hasVerticalHotseat() {
83        return (mIsLandscape && mTransposeLayoutWithOrientation);
84    }
85
86    /* Get the orientation invariant order of the item in the hotseat for persistence. */
87    int getOrderInHotseat(int x, int y) {
88        return hasVerticalHotseat() ? (mContent.getCountY() - y - 1) : x;
89    }
90    /* Get the orientation specific coordinates given an invariant order in the hotseat. */
91    int getCellXFromOrder(int rank) {
92        return hasVerticalHotseat() ? 0 : rank;
93    }
94    int getCellYFromOrder(int rank) {
95        return hasVerticalHotseat() ? (mContent.getCountY() - (rank + 1)) : 0;
96    }
97    public boolean isAllAppsButtonRank(int rank) {
98        if (LauncherAppState.isDisableAllApps()) {
99            return false;
100        } else {
101            return rank == mAllAppsButtonRank;
102        }
103    }
104
105    /** This returns the coordinates of an app in a given cell, relative to the DragLayer */
106    Rect getCellCoordinates(int cellX, int cellY) {
107        Rect coords = new Rect();
108        mContent.cellToRect(cellX, cellY, 1, 1, coords);
109        int[] hotseatInParent = new int[2];
110        Utilities.getDescendantCoordRelativeToParent(this, mLauncher.getDragLayer(),
111                hotseatInParent, false);
112        coords.offset(hotseatInParent[0], hotseatInParent[1]);
113
114        // Center the icon
115        int cWidth = mContent.getShortcutsAndWidgets().getCellContentWidth();
116        int cHeight = mContent.getShortcutsAndWidgets().getCellContentHeight();
117        int cellPaddingX = (int) Math.max(0, ((coords.width() - cWidth) / 2f));
118        int cellPaddingY = (int) Math.max(0, ((coords.height() - cHeight) / 2f));
119        coords.offset(cellPaddingX, cellPaddingY);
120
121        return coords;
122    }
123
124    @Override
125    protected void onFinishInflate() {
126        super.onFinishInflate();
127        LauncherAppState app = LauncherAppState.getInstance();
128        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
129
130        mAllAppsButtonRank = grid.hotseatAllAppsRank;
131        mContent = (CellLayout) findViewById(R.id.layout);
132        if (grid.isLandscape && !grid.isLargeTablet()) {
133            mContent.setGridSize(1, (int) grid.numHotseatIcons);
134        } else {
135            mContent.setGridSize((int) grid.numHotseatIcons, 1);
136        }
137        mContent.setIsHotseat(true);
138
139        resetLayout();
140    }
141
142    void resetLayout() {
143        mContent.removeAllViewsInLayout();
144
145        if (!LauncherAppState.isDisableAllApps()) {
146            // Add the Apps button
147            Context context = getContext();
148
149            LayoutInflater inflater = LayoutInflater.from(context);
150            TextView allAppsButton = (TextView)
151                    inflater.inflate(R.layout.all_apps_button, mContent, false);
152            Drawable d = context.getResources().getDrawable(R.drawable.all_apps_button_icon);
153
154            Utilities.resizeIconDrawable(d);
155            allAppsButton.setCompoundDrawables(null, d, null, null);
156
157            allAppsButton.setContentDescription(context.getString(R.string.all_apps_button_label));
158            if (mLauncher != null) {
159                allAppsButton.setOnTouchListener(mLauncher.getHapticFeedbackTouchListener());
160                mLauncher.setAllAppsButton(allAppsButton);
161                allAppsButton.setOnClickListener(mLauncher);
162            }
163
164            // Note: We do this to ensure that the hotseat is always laid out in the orientation of
165            // the hotseat in order regardless of which orientation they were added
166            int x = getCellXFromOrder(mAllAppsButtonRank);
167            int y = getCellYFromOrder(mAllAppsButtonRank);
168            CellLayout.LayoutParams lp = new CellLayout.LayoutParams(x,y,1,1);
169            lp.canReorder = false;
170            mContent.addViewToCellLayout(allAppsButton, -1, 0, lp, true);
171        }
172    }
173
174    @Override
175    public boolean onInterceptTouchEvent(MotionEvent ev) {
176        // We don't want any clicks to go through to the hotseat unless the workspace is in
177        // the normal state.
178        if (mLauncher.getWorkspace().workspaceInModalState()) {
179            return true;
180        }
181        return false;
182    }
183
184    void addAllAppsFolder(IconCache iconCache,
185            ArrayList<AppInfo> allApps, ArrayList<ComponentName> onWorkspace,
186            Launcher launcher, Workspace workspace) {
187        if (LauncherAppState.isDisableAllApps()) {
188            FolderInfo fi = new FolderInfo();
189
190            fi.cellX = getCellXFromOrder(mAllAppsButtonRank);
191            fi.cellY = getCellYFromOrder(mAllAppsButtonRank);
192            fi.spanX = 1;
193            fi.spanY = 1;
194            fi.container = LauncherSettings.Favorites.CONTAINER_HOTSEAT;
195            fi.screenId = mAllAppsButtonRank;
196            fi.itemType = LauncherSettings.Favorites.ITEM_TYPE_FOLDER;
197            fi.title = "More Apps";
198            LauncherModel.addItemToDatabase(launcher, fi, fi.container, fi.screenId, fi.cellX,
199                    fi.cellY, false);
200            FolderIcon folder = FolderIcon.fromXml(R.layout.folder_icon, launcher,
201                    getLayout(), fi, iconCache);
202            workspace.addInScreen(folder, fi.container, fi.screenId, fi.cellX, fi.cellY,
203                    fi.spanX, fi.spanY);
204
205            for (AppInfo info: allApps) {
206                ComponentName cn = info.intent.getComponent();
207                if (!onWorkspace.contains(cn)) {
208                    Log.d(TAG, "Adding to 'more apps': " + info.intent);
209                    ShortcutInfo si = info.makeShortcut();
210                    fi.add(si);
211                }
212            }
213        }
214    }
215
216    void addAppsToAllAppsFolder(ArrayList<AppInfo> apps) {
217        if (LauncherAppState.isDisableAllApps()) {
218            View v = mContent.getChildAt(getCellXFromOrder(mAllAppsButtonRank), getCellYFromOrder(mAllAppsButtonRank));
219            FolderIcon fi = null;
220
221            if (v instanceof FolderIcon) {
222                fi = (FolderIcon) v;
223            } else {
224                return;
225            }
226
227            FolderInfo info = fi.getFolderInfo();
228            for (AppInfo a: apps) {
229                ShortcutInfo si = a.makeShortcut();
230                info.add(si);
231            }
232        }
233    }
234}
235