1b38002419dcb456b51f5d320b224737f16a07088Winson Chung/* 2b38002419dcb456b51f5d320b224737f16a07088Winson Chung * Copyright (C) 2008 The Android Open Source Project 3b38002419dcb456b51f5d320b224737f16a07088Winson Chung * 4b38002419dcb456b51f5d320b224737f16a07088Winson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 5b38002419dcb456b51f5d320b224737f16a07088Winson Chung * you may not use this file except in compliance with the License. 6b38002419dcb456b51f5d320b224737f16a07088Winson Chung * You may obtain a copy of the License at 7b38002419dcb456b51f5d320b224737f16a07088Winson Chung * 8b38002419dcb456b51f5d320b224737f16a07088Winson Chung * http://www.apache.org/licenses/LICENSE-2.0 9b38002419dcb456b51f5d320b224737f16a07088Winson Chung * 10b38002419dcb456b51f5d320b224737f16a07088Winson Chung * Unless required by applicable law or agreed to in writing, software 11b38002419dcb456b51f5d320b224737f16a07088Winson Chung * distributed under the License is distributed on an "AS IS" BASIS, 12b38002419dcb456b51f5d320b224737f16a07088Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b38002419dcb456b51f5d320b224737f16a07088Winson Chung * See the License for the specific language governing permissions and 14b38002419dcb456b51f5d320b224737f16a07088Winson Chung * limitations under the License. 15b38002419dcb456b51f5d320b224737f16a07088Winson Chung */ 16b38002419dcb456b51f5d320b224737f16a07088Winson Chung 17b38002419dcb456b51f5d320b224737f16a07088Winson Chungpackage com.android.launcher3; 18b38002419dcb456b51f5d320b224737f16a07088Winson Chung 19b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.appwidget.AppWidgetHostView; 20b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.content.ComponentName; 21b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.content.Context; 22b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.content.res.Resources; 23b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.graphics.Paint; 24b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.graphics.Paint.FontMetrics; 25b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.graphics.Point; 26b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.graphics.Rect; 27b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.util.DisplayMetrics; 28b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.view.Gravity; 29b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.view.View; 30d017f882eb67b630adb082dd2227e20f5bc77b05Jorim Jaggiimport android.view.ViewGroup; 31b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.view.ViewGroup.LayoutParams; 328dfe2da6985d38f23fd3426101574c093f509907Sunny Goyalimport android.view.ViewGroup.MarginLayoutParams; 33b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.widget.FrameLayout; 3424ce0b3708b44e738d6ee52477aa4dd917b547e7Adam Cohenimport android.widget.LinearLayout; 35b38002419dcb456b51f5d320b224737f16a07088Winson Chung 36b38002419dcb456b51f5d320b224737f16a07088Winson Chungpublic class DeviceProfile { 372e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen 382e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen public final InvariantDeviceProfile inv; 39b38002419dcb456b51f5d320b224737f16a07088Winson Chung 40c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal // Device properties 41c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public final boolean isTablet; 42c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public final boolean isLargeTablet; 43c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public final boolean isPhone; 44c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public final boolean transposeLayoutWithOrientation; 45c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal 46c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal // Device properties in current orientation 47c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public final boolean isLandscape; 48c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public final int widthPx; 49c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public final int heightPx; 50c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public final int availableWidthPx; 51c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public final int availableHeightPx; 52c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal 53c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal // Overview mode 54c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private final int overviewModeMinIconZoneHeightPx; 55c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private final int overviewModeMaxIconZoneHeightPx; 56c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private final int overviewModeBarItemWidthPx; 57c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private final int overviewModeBarSpacerWidthPx; 58c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private final float overviewModeIconZoneRatio; 59c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal 60c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal // Workspace 61c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private int desiredWorkspaceLeftRightMarginPx; 62c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public final int edgeMarginPx; 63c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public final Rect defaultWidgetPadding; 64c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private final int pageIndicatorHeightPx; 65c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private final int defaultPageSpacingPx; 66c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private float dragViewScale; 67c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal 68c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal // Workspace icons 69c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public int iconSizePx; 702e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen public int iconTextSizePx; 71c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public int iconDrawablePaddingPx; 725f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung public int iconDrawablePaddingOriginalPx; 7359a488ac03aa122b75e9a358db74acf7bb4d2508Winson Chung 74c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public int cellWidthPx; 75c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public int cellHeightPx; 76fee35bbfac29a55382880f846fff86003e615ccbSunny Goyal 77c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal // Folder 78c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public int folderBackgroundOffset; 79c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public int folderIconSizePx; 80c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public int folderCellWidthPx; 81c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public int folderCellHeightPx; 82c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal 83c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal // Hotseat 84c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public int hotseatCellWidthPx; 85c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public int hotseatCellHeightPx; 86c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public int hotseatIconSizePx; 87c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private int hotseatBarHeightPx; 88c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal 89c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal // All apps 905f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung public int allAppsNumCols; 915f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung public int allAppsNumPredictiveCols; 92c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public int allAppsButtonVisualSize; 93c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public final int allAppsIconSizePx; 94c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public final int allAppsIconTextSizePx; 95c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal 96c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal // QSB 97c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private int searchBarSpaceWidthPx; 98c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private int searchBarSpaceHeightPx; 99c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal 100c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public DeviceProfile(Context context, InvariantDeviceProfile inv, 101c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal Point minSize, Point maxSize, 102c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal int width, int height, boolean isLandscape) { 103fee35bbfac29a55382880f846fff86003e615ccbSunny Goyal 1042e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen this.inv = inv; 105c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal this.isLandscape = isLandscape; 106b38002419dcb456b51f5d320b224737f16a07088Winson Chung 1072e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen Resources res = context.getResources(); 108b38002419dcb456b51f5d320b224737f16a07088Winson Chung DisplayMetrics dm = res.getDisplayMetrics(); 1092e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen 110c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal // Constants from resources 111c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal isTablet = res.getBoolean(R.bool.is_tablet); 112c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal isLargeTablet = res.getBoolean(R.bool.is_large_tablet); 113c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal isPhone = !isTablet && !isLargeTablet; 114c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal 115c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal // Some more constants 116b38002419dcb456b51f5d320b224737f16a07088Winson Chung transposeLayoutWithOrientation = 117b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getBoolean(R.bool.hotseat_transpose_layout_with_orientation); 118b38002419dcb456b51f5d320b224737f16a07088Winson Chung 119b38002419dcb456b51f5d320b224737f16a07088Winson Chung ComponentName cn = new ComponentName(context.getPackageName(), 120b38002419dcb456b51f5d320b224737f16a07088Winson Chung this.getClass().getName()); 121b38002419dcb456b51f5d320b224737f16a07088Winson Chung defaultWidgetPadding = AppWidgetHostView.getDefaultPaddingForWidget(context, cn, null); 122b38002419dcb456b51f5d320b224737f16a07088Winson Chung edgeMarginPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin); 123b38002419dcb456b51f5d320b224737f16a07088Winson Chung desiredWorkspaceLeftRightMarginPx = 2 * edgeMarginPx; 124b38002419dcb456b51f5d320b224737f16a07088Winson Chung pageIndicatorHeightPx = 125b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getDimensionPixelSize(R.dimen.dynamic_grid_page_indicator_height); 126b38002419dcb456b51f5d320b224737f16a07088Winson Chung defaultPageSpacingPx = 127b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getDimensionPixelSize(R.dimen.dynamic_grid_workspace_page_spacing); 128b38002419dcb456b51f5d320b224737f16a07088Winson Chung overviewModeMinIconZoneHeightPx = 129b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getDimensionPixelSize(R.dimen.dynamic_grid_overview_min_icon_zone_height); 130b38002419dcb456b51f5d320b224737f16a07088Winson Chung overviewModeMaxIconZoneHeightPx = 131b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getDimensionPixelSize(R.dimen.dynamic_grid_overview_max_icon_zone_height); 132d017f882eb67b630adb082dd2227e20f5bc77b05Jorim Jaggi overviewModeBarItemWidthPx = 133d017f882eb67b630adb082dd2227e20f5bc77b05Jorim Jaggi res.getDimensionPixelSize(R.dimen.dynamic_grid_overview_bar_item_width); 134d017f882eb67b630adb082dd2227e20f5bc77b05Jorim Jaggi overviewModeBarSpacerWidthPx = 135d017f882eb67b630adb082dd2227e20f5bc77b05Jorim Jaggi res.getDimensionPixelSize(R.dimen.dynamic_grid_overview_bar_spacer_width); 136b38002419dcb456b51f5d320b224737f16a07088Winson Chung overviewModeIconZoneRatio = 137b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getInteger(R.integer.config_dynamic_grid_overview_icon_zone_percentage) / 100f; 138b38002419dcb456b51f5d320b224737f16a07088Winson Chung iconDrawablePaddingOriginalPx = 139b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getDimensionPixelSize(R.dimen.dynamic_grid_icon_drawable_padding); 1402e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen 141b38002419dcb456b51f5d320b224737f16a07088Winson Chung // AllApps uses the original non-scaled icon text size 1422e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen allAppsIconTextSizePx = Utilities.pxFromDp(inv.iconTextSize, dm); 143b38002419dcb456b51f5d320b224737f16a07088Winson Chung 1442e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen // AllApps uses the original non-scaled icon size 1452e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen allAppsIconSizePx = Utilities.pxFromDp(inv.iconSize, dm); 146b38002419dcb456b51f5d320b224737f16a07088Winson Chung 147c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal // Determine sizes. 148c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal widthPx = width; 149c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal heightPx = height; 150c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal if (isLandscape) { 151c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal availableWidthPx = maxSize.x; 152c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal availableHeightPx = minSize.y; 153c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal } else { 154c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal availableWidthPx = minSize.x; 155c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal availableHeightPx = maxSize.y; 156c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal } 1574ae96ce92df7aad3c767c68b8795b80734e01829Adam Cohen 158b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Calculate the remaining vars 159c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal updateAvailableDimensions(dm, res); 16063f1ec00fbbd109130d1e476371dbc9a87bb544dAdam Cohen computeAllAppsButtonSize(context); 16163f1ec00fbbd109130d1e476371dbc9a87bb544dAdam Cohen } 16263f1ec00fbbd109130d1e476371dbc9a87bb544dAdam Cohen 16363f1ec00fbbd109130d1e476371dbc9a87bb544dAdam Cohen /** 16463f1ec00fbbd109130d1e476371dbc9a87bb544dAdam Cohen * Determine the exact visual footprint of the all apps button, taking into account scaling 16563f1ec00fbbd109130d1e476371dbc9a87bb544dAdam Cohen * and internal padding of the drawable. 16663f1ec00fbbd109130d1e476371dbc9a87bb544dAdam Cohen */ 16763f1ec00fbbd109130d1e476371dbc9a87bb544dAdam Cohen private void computeAllAppsButtonSize(Context context) { 16863f1ec00fbbd109130d1e476371dbc9a87bb544dAdam Cohen Resources res = context.getResources(); 16963f1ec00fbbd109130d1e476371dbc9a87bb544dAdam Cohen float padding = res.getInteger(R.integer.config_allAppsButtonPaddingPercent) / 100f; 17063f1ec00fbbd109130d1e476371dbc9a87bb544dAdam Cohen allAppsButtonVisualSize = (int) (hotseatIconSizePx * (1 - padding)); 171b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 172b38002419dcb456b51f5d320b224737f16a07088Winson Chung 173c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private void updateAvailableDimensions(DisplayMetrics dm, Resources res) { 174b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Check to see if the icons fit in the new available height. If not, then we need to 175b38002419dcb456b51f5d320b224737f16a07088Winson Chung // shrink the icon size. 176b38002419dcb456b51f5d320b224737f16a07088Winson Chung float scale = 1f; 177b38002419dcb456b51f5d320b224737f16a07088Winson Chung int drawablePadding = iconDrawablePaddingOriginalPx; 178c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal updateIconSize(1f, drawablePadding, res, dm); 1792e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen float usedHeight = (cellHeightPx * inv.numRows); 18059a488ac03aa122b75e9a358db74acf7bb4d2508Winson Chung 181c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal // We only care about the top and bottom workspace padding, which is not affected by RTL. 182c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal Rect workspacePadding = getWorkspacePadding(false /* isLayoutRtl */); 183b38002419dcb456b51f5d320b224737f16a07088Winson Chung int maxHeight = (availableHeightPx - workspacePadding.top - workspacePadding.bottom); 184b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (usedHeight > maxHeight) { 185b38002419dcb456b51f5d320b224737f16a07088Winson Chung scale = maxHeight / usedHeight; 186b38002419dcb456b51f5d320b224737f16a07088Winson Chung drawablePadding = 0; 187b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 188c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal updateIconSize(scale, drawablePadding, res, dm); 189b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 190b38002419dcb456b51f5d320b224737f16a07088Winson Chung 19193f98eaf1800024cb2f28379bdd997f3debae63aWinson Chung private void updateIconSize(float scale, int drawablePadding, Resources res, 192b38002419dcb456b51f5d320b224737f16a07088Winson Chung DisplayMetrics dm) { 1932e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen iconSizePx = (int) (Utilities.pxFromDp(inv.iconSize, dm) * scale); 1942e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen iconTextSizePx = (int) (Utilities.pxFromSp(inv.iconTextSize, dm) * scale); 195b38002419dcb456b51f5d320b224737f16a07088Winson Chung iconDrawablePaddingPx = drawablePadding; 1962e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen hotseatIconSizePx = (int) (Utilities.pxFromDp(inv.hotseatIconSize, dm) * scale); 197b38002419dcb456b51f5d320b224737f16a07088Winson Chung 198b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Search Bar 199594d76dc66cb5666830b62594909fed187987d42Sunny Goyal searchBarSpaceWidthPx = Math.min(widthPx, 20093f98eaf1800024cb2f28379bdd997f3debae63aWinson Chung res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width)); 201594d76dc66cb5666830b62594909fed187987d42Sunny Goyal searchBarSpaceHeightPx = getSearchBarTopOffset() 20293f98eaf1800024cb2f28379bdd997f3debae63aWinson Chung + res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height); 203b38002419dcb456b51f5d320b224737f16a07088Winson Chung 204b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Calculate the actual text height 205b38002419dcb456b51f5d320b224737f16a07088Winson Chung Paint textPaint = new Paint(); 206b38002419dcb456b51f5d320b224737f16a07088Winson Chung textPaint.setTextSize(iconTextSizePx); 207b38002419dcb456b51f5d320b224737f16a07088Winson Chung FontMetrics fm = textPaint.getFontMetrics(); 208b38002419dcb456b51f5d320b224737f16a07088Winson Chung cellWidthPx = iconSizePx; 209b38002419dcb456b51f5d320b224737f16a07088Winson Chung cellHeightPx = iconSizePx + iconDrawablePaddingPx + (int) Math.ceil(fm.bottom - fm.top); 21093f98eaf1800024cb2f28379bdd997f3debae63aWinson Chung final float scaleDps = res.getDimensionPixelSize(R.dimen.dragViewScale); 21159a488ac03aa122b75e9a358db74acf7bb4d2508Winson Chung dragViewScale = (iconSizePx + scaleDps) / iconSizePx; 212b38002419dcb456b51f5d320b224737f16a07088Winson Chung 213b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Hotseat 214b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseatBarHeightPx = iconSizePx + 4 * edgeMarginPx; 215b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseatCellWidthPx = iconSizePx; 216b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseatCellHeightPx = iconSizePx; 217b38002419dcb456b51f5d320b224737f16a07088Winson Chung 218b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Folder 219b38002419dcb456b51f5d320b224737f16a07088Winson Chung folderCellWidthPx = cellWidthPx + 3 * edgeMarginPx; 220b38002419dcb456b51f5d320b224737f16a07088Winson Chung folderCellHeightPx = cellHeightPx + edgeMarginPx; 221b38002419dcb456b51f5d320b224737f16a07088Winson Chung folderBackgroundOffset = -edgeMarginPx; 222b38002419dcb456b51f5d320b224737f16a07088Winson Chung folderIconSizePx = iconSizePx + 2 * -folderBackgroundOffset; 2230f785720667ab8afe4b4620a6c333d382d8659edWinson Chung } 2240f785720667ab8afe4b4620a6c333d382d8659edWinson Chung 225ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung /** 226ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * @param recyclerViewWidth the available width of the AllAppsRecyclerView 227ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung */ 228ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung public void updateAppsViewNumCols(Resources res, int recyclerViewWidth) { 22993f98eaf1800024cb2f28379bdd997f3debae63aWinson Chung int appsViewLeftMarginPx = 2305f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung res.getDimensionPixelSize(R.dimen.all_apps_grid_view_start_margin); 2312c6e5ccbcd7c3f87e7e85029782440600dc0a3d8Winson Chung int allAppsCellWidthGap = 2322c6e5ccbcd7c3f87e7e85029782440600dc0a3d8Winson Chung res.getDimensionPixelSize(R.dimen.all_apps_icon_width_gap); 233ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung int availableAppsWidthPx = (recyclerViewWidth > 0) ? recyclerViewWidth : availableWidthPx; 234208ed75cfdb02e571273d73d056d8ed7f6f756ebWinson Chung int numAppsCols = (availableAppsWidthPx - appsViewLeftMarginPx) / 2352c6e5ccbcd7c3f87e7e85029782440600dc0a3d8Winson Chung (allAppsIconSizePx + allAppsCellWidthGap); 2362c6e5ccbcd7c3f87e7e85029782440600dc0a3d8Winson Chung int numPredictiveAppCols = Math.max(inv.minAllAppsPredictionColumns, numAppsCols); 237ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung allAppsNumCols = numAppsCols; 238ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung allAppsNumPredictiveCols = numPredictiveAppCols; 239b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 240b38002419dcb456b51f5d320b224737f16a07088Winson Chung 24169e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung /** Returns the search bar top offset */ 242c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private int getSearchBarTopOffset() { 243c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal if (isTablet && !isVerticalBarLayout()) { 24469e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung return 4 * edgeMarginPx; 24569e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung } else { 24669e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung return 2 * edgeMarginPx; 24769e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung } 24869e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung } 24969e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung 250b38002419dcb456b51f5d320b224737f16a07088Winson Chung /** Returns the search bar bounds in the current orientation */ 251c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal public Rect getSearchBarBounds(boolean isLayoutRtl) { 252b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect bounds = new Rect(); 253c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal if (isLandscape && transposeLayoutWithOrientation) { 25442b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung if (isLayoutRtl) { 25542b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung bounds.set(availableWidthPx - searchBarSpaceHeightPx, edgeMarginPx, 25642b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung availableWidthPx, availableHeightPx - edgeMarginPx); 25742b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung } else { 25842b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung bounds.set(0, edgeMarginPx, searchBarSpaceHeightPx, 25942b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung availableHeightPx - edgeMarginPx); 26042b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung } 261b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 262c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal if (isTablet) { 263b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Pad the left and right of the workspace to ensure consistent spacing 264b38002419dcb456b51f5d320b224737f16a07088Winson Chung // between all icons 2654f3bfadbf472665ea8431cf2616d56a9445df466Winson Chung int width = getCurrentWidth(); 266b38002419dcb456b51f5d320b224737f16a07088Winson Chung // XXX: If the icon size changes across orientations, we will have to take 267b38002419dcb456b51f5d320b224737f16a07088Winson Chung // that into account here too. 268b38002419dcb456b51f5d320b224737f16a07088Winson Chung int gap = (int) ((width - 2 * edgeMarginPx - 2692e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen (inv.numColumns * cellWidthPx)) / (2 * (inv.numColumns + 1))); 2702cb2471e7fbade9a785c523df5941f2855e99041Winson Chung bounds.set(edgeMarginPx + gap, getSearchBarTopOffset(), 2712cb2471e7fbade9a785c523df5941f2855e99041Winson Chung availableWidthPx - (edgeMarginPx + gap), 272b38002419dcb456b51f5d320b224737f16a07088Winson Chung searchBarSpaceHeightPx); 273b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 2742cb2471e7fbade9a785c523df5941f2855e99041Winson Chung bounds.set(desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.left, 2752cb2471e7fbade9a785c523df5941f2855e99041Winson Chung getSearchBarTopOffset(), 276b38002419dcb456b51f5d320b224737f16a07088Winson Chung availableWidthPx - (desiredWorkspaceLeftRightMarginPx - 277b38002419dcb456b51f5d320b224737f16a07088Winson Chung defaultWidgetPadding.right), searchBarSpaceHeightPx); 278b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 279b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 280b38002419dcb456b51f5d320b224737f16a07088Winson Chung return bounds; 281b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 282b38002419dcb456b51f5d320b224737f16a07088Winson Chung 283b38002419dcb456b51f5d320b224737f16a07088Winson Chung /** Returns the workspace padding in the specified orientation */ 284c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal Rect getWorkspacePadding(boolean isLayoutRtl) { 285c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal Rect searchBarBounds = getSearchBarBounds(isLayoutRtl); 286b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect padding = new Rect(); 287c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal if (isLandscape && transposeLayoutWithOrientation) { 288b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Pad the left and right of the workspace with search/hotseat bar sizes 28942b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung if (isLayoutRtl) { 29042b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung padding.set(hotseatBarHeightPx, edgeMarginPx, 29142b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung searchBarBounds.width(), edgeMarginPx); 29242b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung } else { 29342b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung padding.set(searchBarBounds.width(), edgeMarginPx, 29442b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung hotseatBarHeightPx, edgeMarginPx); 29542b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung } 296b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 297c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal if (isTablet) { 298b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Pad the left and right of the workspace to ensure consistent spacing 299b38002419dcb456b51f5d320b224737f16a07088Winson Chung // between all icons 30059a488ac03aa122b75e9a358db74acf7bb4d2508Winson Chung float gapScale = 1f + (dragViewScale - 1f) / 2f; 3014f3bfadbf472665ea8431cf2616d56a9445df466Winson Chung int width = getCurrentWidth(); 3024f3bfadbf472665ea8431cf2616d56a9445df466Winson Chung int height = getCurrentHeight(); 30359a488ac03aa122b75e9a358db74acf7bb4d2508Winson Chung int paddingTop = searchBarBounds.bottom; 30459a488ac03aa122b75e9a358db74acf7bb4d2508Winson Chung int paddingBottom = hotseatBarHeightPx + pageIndicatorHeightPx; 3052e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int availableWidth = Math.max(0, width - (int) ((inv.numColumns * cellWidthPx) + 3062e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen (inv.numColumns * gapScale * cellWidthPx))); 30759a488ac03aa122b75e9a358db74acf7bb4d2508Winson Chung int availableHeight = Math.max(0, height - paddingTop - paddingBottom 3082e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen - (int) (2 * inv.numRows * cellHeightPx)); 30959a488ac03aa122b75e9a358db74acf7bb4d2508Winson Chung padding.set(availableWidth / 2, paddingTop + availableHeight / 2, 31059a488ac03aa122b75e9a358db74acf7bb4d2508Winson Chung availableWidth / 2, paddingBottom + availableHeight / 2); 311b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 312b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Pad the top and bottom of the workspace with search/hotseat bar sizes 313b38002419dcb456b51f5d320b224737f16a07088Winson Chung padding.set(desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.left, 314b38002419dcb456b51f5d320b224737f16a07088Winson Chung searchBarBounds.bottom, 315b38002419dcb456b51f5d320b224737f16a07088Winson Chung desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.right, 316b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseatBarHeightPx + pageIndicatorHeightPx); 317b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 318b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 319b38002419dcb456b51f5d320b224737f16a07088Winson Chung return padding; 320b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 321b38002419dcb456b51f5d320b224737f16a07088Winson Chung 322c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private int getWorkspacePageSpacing(boolean isLayoutRtl) { 323c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal if ((isLandscape && transposeLayoutWithOrientation) || isLargeTablet) { 324b38002419dcb456b51f5d320b224737f16a07088Winson Chung // In landscape mode the page spacing is set to the default. 325b38002419dcb456b51f5d320b224737f16a07088Winson Chung return defaultPageSpacingPx; 326b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 327b38002419dcb456b51f5d320b224737f16a07088Winson Chung // In portrait, we want the pages spaced such that there is no 328b38002419dcb456b51f5d320b224737f16a07088Winson Chung // overhang of the previous / next page into the current page viewport. 329b38002419dcb456b51f5d320b224737f16a07088Winson Chung // We assume symmetrical padding in portrait mode. 330c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal return Math.max(defaultPageSpacingPx, 2 * getWorkspacePadding(isLayoutRtl).left); 331b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 332b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 333b38002419dcb456b51f5d320b224737f16a07088Winson Chung 3344f7eb4077e901a28b2b698060079292b56e991bdWinson Chung int getOverviewModeButtonBarHeight() { 335b38002419dcb456b51f5d320b224737f16a07088Winson Chung int zoneHeight = (int) (overviewModeIconZoneRatio * availableHeightPx); 336b38002419dcb456b51f5d320b224737f16a07088Winson Chung zoneHeight = Math.min(overviewModeMaxIconZoneHeightPx, 337b38002419dcb456b51f5d320b224737f16a07088Winson Chung Math.max(overviewModeMinIconZoneHeightPx, zoneHeight)); 3384f7eb4077e901a28b2b698060079292b56e991bdWinson Chung return zoneHeight; 339b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 340b38002419dcb456b51f5d320b224737f16a07088Winson Chung 341b38002419dcb456b51f5d320b224737f16a07088Winson Chung // The rect returned will be extended to below the system ui that covers the workspace 342b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect getHotseatRect() { 343b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (isVerticalBarLayout()) { 344b38002419dcb456b51f5d320b224737f16a07088Winson Chung return new Rect(availableWidthPx - hotseatBarHeightPx, 0, 345b38002419dcb456b51f5d320b224737f16a07088Winson Chung Integer.MAX_VALUE, availableHeightPx); 346b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 347b38002419dcb456b51f5d320b224737f16a07088Winson Chung return new Rect(0, availableHeightPx - hotseatBarHeightPx, 348b38002419dcb456b51f5d320b224737f16a07088Winson Chung availableWidthPx, Integer.MAX_VALUE); 349b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 350b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 351b38002419dcb456b51f5d320b224737f16a07088Winson Chung 3522e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen public static int calculateCellWidth(int width, int countX) { 353b38002419dcb456b51f5d320b224737f16a07088Winson Chung return width / countX; 354b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 3552e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen public static int calculateCellHeight(int height, int countY) { 356b38002419dcb456b51f5d320b224737f16a07088Winson Chung return height / countY; 357b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 358b38002419dcb456b51f5d320b224737f16a07088Winson Chung 35918bfaafd3da45dce7b5f73eaa1665f228353338cHyunyoung Song /** 36018bfaafd3da45dce7b5f73eaa1665f228353338cHyunyoung Song * When {@code true}, hotseat is on the bottom row when in landscape mode. 36118bfaafd3da45dce7b5f73eaa1665f228353338cHyunyoung Song * If {@code false}, hotseat is on the right column when in landscape mode. 36218bfaafd3da45dce7b5f73eaa1665f228353338cHyunyoung Song */ 363b38002419dcb456b51f5d320b224737f16a07088Winson Chung boolean isVerticalBarLayout() { 364b38002419dcb456b51f5d320b224737f16a07088Winson Chung return isLandscape && transposeLayoutWithOrientation; 365b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 366b38002419dcb456b51f5d320b224737f16a07088Winson Chung 367b38002419dcb456b51f5d320b224737f16a07088Winson Chung boolean shouldFadeAdjacentWorkspaceScreens() { 368c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal return isVerticalBarLayout() || isLargeTablet; 369b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 370b38002419dcb456b51f5d320b224737f16a07088Winson Chung 371c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal private int getVisibleChildCount(ViewGroup parent) { 372d017f882eb67b630adb082dd2227e20f5bc77b05Jorim Jaggi int visibleChildren = 0; 373d017f882eb67b630adb082dd2227e20f5bc77b05Jorim Jaggi for (int i = 0; i < parent.getChildCount(); i++) { 374d017f882eb67b630adb082dd2227e20f5bc77b05Jorim Jaggi if (parent.getChildAt(i).getVisibility() != View.GONE) { 375d017f882eb67b630adb082dd2227e20f5bc77b05Jorim Jaggi visibleChildren++; 376d017f882eb67b630adb082dd2227e20f5bc77b05Jorim Jaggi } 377d017f882eb67b630adb082dd2227e20f5bc77b05Jorim Jaggi } 378d017f882eb67b630adb082dd2227e20f5bc77b05Jorim Jaggi return visibleChildren; 379d017f882eb67b630adb082dd2227e20f5bc77b05Jorim Jaggi } 380d017f882eb67b630adb082dd2227e20f5bc77b05Jorim Jaggi 381b38002419dcb456b51f5d320b224737f16a07088Winson Chung public void layout(Launcher launcher) { 382b38002419dcb456b51f5d320b224737f16a07088Winson Chung FrameLayout.LayoutParams lp; 383b38002419dcb456b51f5d320b224737f16a07088Winson Chung boolean hasVerticalBarLayout = isVerticalBarLayout(); 384c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal final boolean isLayoutRtl = Utilities.isRtl(launcher.getResources()); 385b38002419dcb456b51f5d320b224737f16a07088Winson Chung 386b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Layout the search bar space 387006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung View searchBar = launcher.getSearchDropTargetBar(); 388b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp = (FrameLayout.LayoutParams) searchBar.getLayoutParams(); 389b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (hasVerticalBarLayout) { 390f8c6f885f032dad4e6b09e02ca97545783bccb70Winson Chung // Vertical search bar space -- The search bar is fixed in the layout to be on the left 391f8c6f885f032dad4e6b09e02ca97545783bccb70Winson Chung // of the screen regardless of RTL 392d9cc780fade7a078d127c7e5b8209d414a46f0a5Sunny Goyal lp.gravity = Gravity.LEFT; 393b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.width = searchBarSpaceHeightPx; 39424ce0b3708b44e738d6ee52477aa4dd917b547e7Adam Cohen 39524ce0b3708b44e738d6ee52477aa4dd917b547e7Adam Cohen LinearLayout targets = (LinearLayout) searchBar.findViewById(R.id.drag_target_bar); 39624ce0b3708b44e738d6ee52477aa4dd917b547e7Adam Cohen targets.setOrientation(LinearLayout.VERTICAL); 397d9cc780fade7a078d127c7e5b8209d414a46f0a5Sunny Goyal FrameLayout.LayoutParams targetsLp = (FrameLayout.LayoutParams) targets.getLayoutParams(); 398d9cc780fade7a078d127c7e5b8209d414a46f0a5Sunny Goyal targetsLp.gravity = Gravity.TOP; 399d9cc780fade7a078d127c7e5b8209d414a46f0a5Sunny Goyal targetsLp.height = LayoutParams.WRAP_CONTENT; 400d9cc780fade7a078d127c7e5b8209d414a46f0a5Sunny Goyal 401b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 40269e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung // Horizontal search bar space 403d9cc780fade7a078d127c7e5b8209d414a46f0a5Sunny Goyal lp.gravity = Gravity.TOP; 404b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.height = searchBarSpaceHeightPx; 405d9cc780fade7a078d127c7e5b8209d414a46f0a5Sunny Goyal 406d9cc780fade7a078d127c7e5b8209d414a46f0a5Sunny Goyal LinearLayout targets = (LinearLayout) searchBar.findViewById(R.id.drag_target_bar); 407d9cc780fade7a078d127c7e5b8209d414a46f0a5Sunny Goyal targets.getLayoutParams().width = searchBarSpaceWidthPx; 408b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 409b38002419dcb456b51f5d320b224737f16a07088Winson Chung searchBar.setLayoutParams(lp); 410b38002419dcb456b51f5d320b224737f16a07088Winson Chung 411b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Layout the workspace 412b38002419dcb456b51f5d320b224737f16a07088Winson Chung PagedView workspace = (PagedView) launcher.findViewById(R.id.workspace); 413b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp = (FrameLayout.LayoutParams) workspace.getLayoutParams(); 414b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.gravity = Gravity.CENTER; 415c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal Rect padding = getWorkspacePadding(isLayoutRtl); 416b38002419dcb456b51f5d320b224737f16a07088Winson Chung workspace.setLayoutParams(lp); 417b38002419dcb456b51f5d320b224737f16a07088Winson Chung workspace.setPadding(padding.left, padding.top, padding.right, padding.bottom); 418c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal workspace.setPageSpacing(getWorkspacePageSpacing(isLayoutRtl)); 419b38002419dcb456b51f5d320b224737f16a07088Winson Chung 420b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Layout the hotseat 421b38002419dcb456b51f5d320b224737f16a07088Winson Chung View hotseat = launcher.findViewById(R.id.hotseat); 422b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp = (FrameLayout.LayoutParams) hotseat.getLayoutParams(); 423b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (hasVerticalBarLayout) { 424f8c6f885f032dad4e6b09e02ca97545783bccb70Winson Chung // Vertical hotseat -- The hotseat is fixed in the layout to be on the right of the 425f8c6f885f032dad4e6b09e02ca97545783bccb70Winson Chung // screen regardless of RTL 426f8c6f885f032dad4e6b09e02ca97545783bccb70Winson Chung lp.gravity = Gravity.RIGHT; 427b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.width = hotseatBarHeightPx; 428b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.height = LayoutParams.MATCH_PARENT; 429b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseat.findViewById(R.id.layout).setPadding(0, 2 * edgeMarginPx, 0, 2 * edgeMarginPx); 430c6205603efe1f2987caf96504c87d720a25b5a94Sunny Goyal } else if (isTablet) { 43159a488ac03aa122b75e9a358db74acf7bb4d2508Winson Chung // Pad the hotseat with the workspace padding calculated above 432b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.gravity = Gravity.BOTTOM; 433b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.width = LayoutParams.MATCH_PARENT; 434b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.height = hotseatBarHeightPx; 43559a488ac03aa122b75e9a358db74acf7bb4d2508Winson Chung hotseat.setPadding(edgeMarginPx + padding.left, 0, 43659a488ac03aa122b75e9a358db74acf7bb4d2508Winson Chung edgeMarginPx + padding.right, 437b38002419dcb456b51f5d320b224737f16a07088Winson Chung 2 * edgeMarginPx); 438b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 439b38002419dcb456b51f5d320b224737f16a07088Winson Chung // For phones, layout the hotseat without any bottom margin 440b38002419dcb456b51f5d320b224737f16a07088Winson Chung // to ensure that we have space for the folders 441b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.gravity = Gravity.BOTTOM; 442b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.width = LayoutParams.MATCH_PARENT; 443b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.height = hotseatBarHeightPx; 444e0bca386247024728b1e71e9ae530fac7e5b3171Sunny Goyal hotseat.findViewById(R.id.layout).setPadding(2 * edgeMarginPx, 0, 445e0bca386247024728b1e71e9ae530fac7e5b3171Sunny Goyal 2 * edgeMarginPx, 0); 446b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 447b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseat.setLayoutParams(lp); 448b38002419dcb456b51f5d320b224737f16a07088Winson Chung 449b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Layout the page indicators 450b38002419dcb456b51f5d320b224737f16a07088Winson Chung View pageIndicator = launcher.findViewById(R.id.page_indicator); 451b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (pageIndicator != null) { 452b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (hasVerticalBarLayout) { 453b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Hide the page indicators when we have vertical search/hotseat 454b38002419dcb456b51f5d320b224737f16a07088Winson Chung pageIndicator.setVisibility(View.GONE); 455b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 456b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Put the page indicators above the hotseat 457b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp = (FrameLayout.LayoutParams) pageIndicator.getLayoutParams(); 458b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; 459b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.width = LayoutParams.WRAP_CONTENT; 460b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.height = LayoutParams.WRAP_CONTENT; 461b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.bottomMargin = hotseatBarHeightPx; 462b38002419dcb456b51f5d320b224737f16a07088Winson Chung pageIndicator.setLayoutParams(lp); 463b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 464b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 465b38002419dcb456b51f5d320b224737f16a07088Winson Chung 466b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Layout the Overview Mode 467d017f882eb67b630adb082dd2227e20f5bc77b05Jorim Jaggi ViewGroup overviewMode = launcher.getOverviewPanel(); 468b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (overviewMode != null) { 4694f7eb4077e901a28b2b698060079292b56e991bdWinson Chung int overviewButtonBarHeight = getOverviewModeButtonBarHeight(); 470b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp = (FrameLayout.LayoutParams) overviewMode.getLayoutParams(); 471b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; 4728dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal 4738dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal int visibleChildCount = getVisibleChildCount(overviewMode); 4748dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal int totalItemWidth = visibleChildCount * overviewModeBarItemWidthPx; 4758dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal int maxWidth = totalItemWidth + (visibleChildCount-1) * overviewModeBarSpacerWidthPx; 4768dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal 4778dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal lp.width = Math.min(availableWidthPx, maxWidth); 4784f7eb4077e901a28b2b698060079292b56e991bdWinson Chung lp.height = overviewButtonBarHeight; 479b38002419dcb456b51f5d320b224737f16a07088Winson Chung overviewMode.setLayoutParams(lp); 4808dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal 4818dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal if (lp.width > totalItemWidth && visibleChildCount > 1) { 4828dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal // We have enough space. Lets add some margin too. 4838dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal int margin = (lp.width - totalItemWidth) / (visibleChildCount-1); 4848dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal View lastChild = null; 4858dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal 4868dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal // Set margin of all visible children except the last visible child 4878dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal for (int i = 0; i < visibleChildCount; i++) { 4888dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal if (lastChild != null) { 4898dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal MarginLayoutParams clp = (MarginLayoutParams) lastChild.getLayoutParams(); 4908dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal if (isLayoutRtl) { 4918dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal clp.leftMargin = margin; 4928dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal } else { 4938dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal clp.rightMargin = margin; 4948dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal } 4958dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal lastChild.setLayoutParams(clp); 4968dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal lastChild = null; 4978dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal } 4988dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal View thisChild = overviewMode.getChildAt(i); 4998dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal if (thisChild.getVisibility() != View.GONE) { 5008dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal lastChild = thisChild; 5018dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal } 5028dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal } 5038dfe2da6985d38f23fd3426101574c093f509907Sunny Goyal } 504b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 505b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 5064f3bfadbf472665ea8431cf2616d56a9445df466Winson Chung 5074f3bfadbf472665ea8431cf2616d56a9445df466Winson Chung private int getCurrentWidth() { 5084f3bfadbf472665ea8431cf2616d56a9445df466Winson Chung return isLandscape 5094f3bfadbf472665ea8431cf2616d56a9445df466Winson Chung ? Math.max(widthPx, heightPx) 5104f3bfadbf472665ea8431cf2616d56a9445df466Winson Chung : Math.min(widthPx, heightPx); 5114f3bfadbf472665ea8431cf2616d56a9445df466Winson Chung } 5124f3bfadbf472665ea8431cf2616d56a9445df466Winson Chung 5134f3bfadbf472665ea8431cf2616d56a9445df466Winson Chung private int getCurrentHeight() { 5144f3bfadbf472665ea8431cf2616d56a9445df466Winson Chung return isLandscape 5154f3bfadbf472665ea8431cf2616d56a9445df466Winson Chung ? Math.min(widthPx, heightPx) 5164f3bfadbf472665ea8431cf2616d56a9445df466Winson Chung : Math.max(widthPx, heightPx); 5174f3bfadbf472665ea8431cf2616d56a9445df466Winson Chung } 518b38002419dcb456b51f5d320b224737f16a07088Winson Chung} 519