DeviceProfile.java revision 42b3c06849331aa5ba1f07f8c58915190d386aac
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.Configuration; 23b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.content.res.Resources; 24b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.graphics.Paint; 25b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.graphics.Paint.FontMetrics; 26b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.graphics.Point; 27b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.graphics.PointF; 28b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.graphics.Rect; 29b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.util.DisplayMetrics; 30b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.view.Display; 31b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.view.Gravity; 32b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.view.Surface; 33b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.view.View; 34b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.view.ViewGroup.LayoutParams; 35b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.view.WindowManager; 36b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport android.widget.FrameLayout; 37b38002419dcb456b51f5d320b224737f16a07088Winson Chung 38b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport java.util.ArrayList; 39b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport java.util.Collections; 40b38002419dcb456b51f5d320b224737f16a07088Winson Chungimport java.util.Comparator; 41b38002419dcb456b51f5d320b224737f16a07088Winson Chung 42b38002419dcb456b51f5d320b224737f16a07088Winson Chung 43b38002419dcb456b51f5d320b224737f16a07088Winson Chungclass DeviceProfileQuery { 44b38002419dcb456b51f5d320b224737f16a07088Winson Chung float widthDps; 45b38002419dcb456b51f5d320b224737f16a07088Winson Chung float heightDps; 46b38002419dcb456b51f5d320b224737f16a07088Winson Chung float value; 47b38002419dcb456b51f5d320b224737f16a07088Winson Chung PointF dimens; 48b38002419dcb456b51f5d320b224737f16a07088Winson Chung 49b38002419dcb456b51f5d320b224737f16a07088Winson Chung DeviceProfileQuery(float w, float h, float v) { 50b38002419dcb456b51f5d320b224737f16a07088Winson Chung widthDps = w; 51b38002419dcb456b51f5d320b224737f16a07088Winson Chung heightDps = h; 52b38002419dcb456b51f5d320b224737f16a07088Winson Chung value = v; 53b38002419dcb456b51f5d320b224737f16a07088Winson Chung dimens = new PointF(w, h); 54b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 55b38002419dcb456b51f5d320b224737f16a07088Winson Chung} 56b38002419dcb456b51f5d320b224737f16a07088Winson Chung 57b38002419dcb456b51f5d320b224737f16a07088Winson Chungpublic class DeviceProfile { 58b38002419dcb456b51f5d320b224737f16a07088Winson Chung public static interface DeviceProfileCallbacks { 59b38002419dcb456b51f5d320b224737f16a07088Winson Chung public void onAvailableSizeChanged(DeviceProfile grid); 60b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 61b38002419dcb456b51f5d320b224737f16a07088Winson Chung 62b38002419dcb456b51f5d320b224737f16a07088Winson Chung String name; 63b38002419dcb456b51f5d320b224737f16a07088Winson Chung float minWidthDps; 64b38002419dcb456b51f5d320b224737f16a07088Winson Chung float minHeightDps; 65b38002419dcb456b51f5d320b224737f16a07088Winson Chung float numRows; 66b38002419dcb456b51f5d320b224737f16a07088Winson Chung float numColumns; 67b38002419dcb456b51f5d320b224737f16a07088Winson Chung float numHotseatIcons; 68b38002419dcb456b51f5d320b224737f16a07088Winson Chung private float iconSize; 69b38002419dcb456b51f5d320b224737f16a07088Winson Chung private float iconTextSize; 70b38002419dcb456b51f5d320b224737f16a07088Winson Chung private int iconDrawablePaddingOriginalPx; 71b38002419dcb456b51f5d320b224737f16a07088Winson Chung private float hotseatIconSize; 72b38002419dcb456b51f5d320b224737f16a07088Winson Chung 73b38002419dcb456b51f5d320b224737f16a07088Winson Chung boolean isLandscape; 74b38002419dcb456b51f5d320b224737f16a07088Winson Chung boolean isTablet; 75b38002419dcb456b51f5d320b224737f16a07088Winson Chung boolean isLargeTablet; 7642b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung boolean isLayoutRtl; 77b38002419dcb456b51f5d320b224737f16a07088Winson Chung boolean transposeLayoutWithOrientation; 78b38002419dcb456b51f5d320b224737f16a07088Winson Chung 79b38002419dcb456b51f5d320b224737f16a07088Winson Chung int desiredWorkspaceLeftRightMarginPx; 80b38002419dcb456b51f5d320b224737f16a07088Winson Chung int edgeMarginPx; 81b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect defaultWidgetPadding; 82b38002419dcb456b51f5d320b224737f16a07088Winson Chung 83b38002419dcb456b51f5d320b224737f16a07088Winson Chung int widthPx; 84b38002419dcb456b51f5d320b224737f16a07088Winson Chung int heightPx; 85b38002419dcb456b51f5d320b224737f16a07088Winson Chung int availableWidthPx; 86b38002419dcb456b51f5d320b224737f16a07088Winson Chung int availableHeightPx; 87b38002419dcb456b51f5d320b224737f16a07088Winson Chung int defaultPageSpacingPx; 88b38002419dcb456b51f5d320b224737f16a07088Winson Chung 89b38002419dcb456b51f5d320b224737f16a07088Winson Chung int overviewModeMinIconZoneHeightPx; 90b38002419dcb456b51f5d320b224737f16a07088Winson Chung int overviewModeMaxIconZoneHeightPx; 91b38002419dcb456b51f5d320b224737f16a07088Winson Chung int overviewModeMaxBarWidthPx; 92b38002419dcb456b51f5d320b224737f16a07088Winson Chung float overviewModeIconZoneRatio; 93b38002419dcb456b51f5d320b224737f16a07088Winson Chung float overviewModeScaleFactor; 94b38002419dcb456b51f5d320b224737f16a07088Winson Chung 95b38002419dcb456b51f5d320b224737f16a07088Winson Chung int iconSizePx; 96b38002419dcb456b51f5d320b224737f16a07088Winson Chung int iconTextSizePx; 97b38002419dcb456b51f5d320b224737f16a07088Winson Chung int iconDrawablePaddingPx; 98b38002419dcb456b51f5d320b224737f16a07088Winson Chung int cellWidthPx; 99b38002419dcb456b51f5d320b224737f16a07088Winson Chung int cellHeightPx; 100b38002419dcb456b51f5d320b224737f16a07088Winson Chung int allAppsIconSizePx; 101b38002419dcb456b51f5d320b224737f16a07088Winson Chung int allAppsIconTextSizePx; 102b38002419dcb456b51f5d320b224737f16a07088Winson Chung int allAppsCellWidthPx; 103b38002419dcb456b51f5d320b224737f16a07088Winson Chung int allAppsCellHeightPx; 104b38002419dcb456b51f5d320b224737f16a07088Winson Chung int allAppsCellPaddingPx; 105b38002419dcb456b51f5d320b224737f16a07088Winson Chung int folderBackgroundOffset; 106b38002419dcb456b51f5d320b224737f16a07088Winson Chung int folderIconSizePx; 107b38002419dcb456b51f5d320b224737f16a07088Winson Chung int folderCellWidthPx; 108b38002419dcb456b51f5d320b224737f16a07088Winson Chung int folderCellHeightPx; 109b38002419dcb456b51f5d320b224737f16a07088Winson Chung int hotseatCellWidthPx; 110b38002419dcb456b51f5d320b224737f16a07088Winson Chung int hotseatCellHeightPx; 111b38002419dcb456b51f5d320b224737f16a07088Winson Chung int hotseatIconSizePx; 112b38002419dcb456b51f5d320b224737f16a07088Winson Chung int hotseatBarHeightPx; 113b38002419dcb456b51f5d320b224737f16a07088Winson Chung int hotseatAllAppsRank; 114b38002419dcb456b51f5d320b224737f16a07088Winson Chung int allAppsNumRows; 115b38002419dcb456b51f5d320b224737f16a07088Winson Chung int allAppsNumCols; 116b38002419dcb456b51f5d320b224737f16a07088Winson Chung int searchBarSpaceWidthPx; 117b38002419dcb456b51f5d320b224737f16a07088Winson Chung int searchBarSpaceMaxWidthPx; 118b38002419dcb456b51f5d320b224737f16a07088Winson Chung int searchBarSpaceHeightPx; 119b38002419dcb456b51f5d320b224737f16a07088Winson Chung int searchBarHeightPx; 120b38002419dcb456b51f5d320b224737f16a07088Winson Chung int pageIndicatorHeightPx; 121b38002419dcb456b51f5d320b224737f16a07088Winson Chung 122b38002419dcb456b51f5d320b224737f16a07088Winson Chung private ArrayList<DeviceProfileCallbacks> mCallbacks = new ArrayList<DeviceProfileCallbacks>(); 123b38002419dcb456b51f5d320b224737f16a07088Winson Chung 124b38002419dcb456b51f5d320b224737f16a07088Winson Chung DeviceProfile(String n, float w, float h, float r, float c, 125b38002419dcb456b51f5d320b224737f16a07088Winson Chung float is, float its, float hs, float his) { 126b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Ensure that we have an odd number of hotseat items (since we need to place all apps) 127b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (!AppsCustomizePagedView.DISABLE_ALL_APPS && hs % 2 == 0) { 128b38002419dcb456b51f5d320b224737f16a07088Winson Chung throw new RuntimeException("All Device Profiles must have an odd number of hotseat spaces"); 129b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 130b38002419dcb456b51f5d320b224737f16a07088Winson Chung 131b38002419dcb456b51f5d320b224737f16a07088Winson Chung name = n; 132b38002419dcb456b51f5d320b224737f16a07088Winson Chung minWidthDps = w; 133b38002419dcb456b51f5d320b224737f16a07088Winson Chung minHeightDps = h; 134b38002419dcb456b51f5d320b224737f16a07088Winson Chung numRows = r; 135b38002419dcb456b51f5d320b224737f16a07088Winson Chung numColumns = c; 136b38002419dcb456b51f5d320b224737f16a07088Winson Chung iconSize = is; 137b38002419dcb456b51f5d320b224737f16a07088Winson Chung iconTextSize = its; 138b38002419dcb456b51f5d320b224737f16a07088Winson Chung numHotseatIcons = hs; 139b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseatIconSize = his; 140b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 141b38002419dcb456b51f5d320b224737f16a07088Winson Chung 142b38002419dcb456b51f5d320b224737f16a07088Winson Chung DeviceProfile(Context context, 143b38002419dcb456b51f5d320b224737f16a07088Winson Chung ArrayList<DeviceProfile> profiles, 144b38002419dcb456b51f5d320b224737f16a07088Winson Chung float minWidth, float minHeight, 145b38002419dcb456b51f5d320b224737f16a07088Winson Chung int wPx, int hPx, 146b38002419dcb456b51f5d320b224737f16a07088Winson Chung int awPx, int ahPx, 147b38002419dcb456b51f5d320b224737f16a07088Winson Chung Resources res) { 148b38002419dcb456b51f5d320b224737f16a07088Winson Chung DisplayMetrics dm = res.getDisplayMetrics(); 149b38002419dcb456b51f5d320b224737f16a07088Winson Chung ArrayList<DeviceProfileQuery> points = 150b38002419dcb456b51f5d320b224737f16a07088Winson Chung new ArrayList<DeviceProfileQuery>(); 151b38002419dcb456b51f5d320b224737f16a07088Winson Chung transposeLayoutWithOrientation = 152b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getBoolean(R.bool.hotseat_transpose_layout_with_orientation); 153b38002419dcb456b51f5d320b224737f16a07088Winson Chung minWidthDps = minWidth; 154b38002419dcb456b51f5d320b224737f16a07088Winson Chung minHeightDps = minHeight; 155b38002419dcb456b51f5d320b224737f16a07088Winson Chung 156b38002419dcb456b51f5d320b224737f16a07088Winson Chung ComponentName cn = new ComponentName(context.getPackageName(), 157b38002419dcb456b51f5d320b224737f16a07088Winson Chung this.getClass().getName()); 158b38002419dcb456b51f5d320b224737f16a07088Winson Chung defaultWidgetPadding = AppWidgetHostView.getDefaultPaddingForWidget(context, cn, null); 159b38002419dcb456b51f5d320b224737f16a07088Winson Chung edgeMarginPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin); 160b38002419dcb456b51f5d320b224737f16a07088Winson Chung desiredWorkspaceLeftRightMarginPx = 2 * edgeMarginPx; 161b38002419dcb456b51f5d320b224737f16a07088Winson Chung pageIndicatorHeightPx = 162b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getDimensionPixelSize(R.dimen.dynamic_grid_page_indicator_height); 163b38002419dcb456b51f5d320b224737f16a07088Winson Chung defaultPageSpacingPx = 164b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getDimensionPixelSize(R.dimen.dynamic_grid_workspace_page_spacing); 165b38002419dcb456b51f5d320b224737f16a07088Winson Chung allAppsCellPaddingPx = 166b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getDimensionPixelSize(R.dimen.dynamic_grid_all_apps_cell_padding); 167b38002419dcb456b51f5d320b224737f16a07088Winson Chung overviewModeMinIconZoneHeightPx = 168b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getDimensionPixelSize(R.dimen.dynamic_grid_overview_min_icon_zone_height); 169b38002419dcb456b51f5d320b224737f16a07088Winson Chung overviewModeMaxIconZoneHeightPx = 170b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getDimensionPixelSize(R.dimen.dynamic_grid_overview_max_icon_zone_height); 171b38002419dcb456b51f5d320b224737f16a07088Winson Chung overviewModeMaxBarWidthPx = 172b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getDimensionPixelSize(R.dimen.dynamic_grid_overview_bar_max_width); 173b38002419dcb456b51f5d320b224737f16a07088Winson Chung overviewModeIconZoneRatio = 174b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getInteger(R.integer.config_dynamic_grid_overview_icon_zone_percentage) / 100f; 175b38002419dcb456b51f5d320b224737f16a07088Winson Chung overviewModeScaleFactor = 176b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getInteger(R.integer.config_dynamic_grid_overview_scale_percentage) / 100f; 177b38002419dcb456b51f5d320b224737f16a07088Winson Chung 178b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Interpolate the rows 179b38002419dcb456b51f5d320b224737f16a07088Winson Chung for (DeviceProfile p : profiles) { 180b38002419dcb456b51f5d320b224737f16a07088Winson Chung points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.numRows)); 181b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 182b38002419dcb456b51f5d320b224737f16a07088Winson Chung numRows = Math.round(invDistWeightedInterpolate(minWidth, minHeight, points)); 183b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Interpolate the columns 184b38002419dcb456b51f5d320b224737f16a07088Winson Chung points.clear(); 185b38002419dcb456b51f5d320b224737f16a07088Winson Chung for (DeviceProfile p : profiles) { 186b38002419dcb456b51f5d320b224737f16a07088Winson Chung points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.numColumns)); 187b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 188b38002419dcb456b51f5d320b224737f16a07088Winson Chung numColumns = Math.round(invDistWeightedInterpolate(minWidth, minHeight, points)); 189b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Interpolate the hotseat length 190b38002419dcb456b51f5d320b224737f16a07088Winson Chung points.clear(); 191b38002419dcb456b51f5d320b224737f16a07088Winson Chung for (DeviceProfile p : profiles) { 192b38002419dcb456b51f5d320b224737f16a07088Winson Chung points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.numHotseatIcons)); 193b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 194b38002419dcb456b51f5d320b224737f16a07088Winson Chung numHotseatIcons = Math.round(invDistWeightedInterpolate(minWidth, minHeight, points)); 195b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseatAllAppsRank = (int) (numHotseatIcons / 2); 196b38002419dcb456b51f5d320b224737f16a07088Winson Chung 197b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Interpolate the icon size 198b38002419dcb456b51f5d320b224737f16a07088Winson Chung points.clear(); 199b38002419dcb456b51f5d320b224737f16a07088Winson Chung for (DeviceProfile p : profiles) { 200b38002419dcb456b51f5d320b224737f16a07088Winson Chung points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.iconSize)); 201b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 202b38002419dcb456b51f5d320b224737f16a07088Winson Chung iconSize = invDistWeightedInterpolate(minWidth, minHeight, points); 203b38002419dcb456b51f5d320b224737f16a07088Winson Chung // AllApps uses the original non-scaled icon size 204b38002419dcb456b51f5d320b224737f16a07088Winson Chung allAppsIconSizePx = DynamicGrid.pxFromDp(iconSize, dm); 205b38002419dcb456b51f5d320b224737f16a07088Winson Chung 206b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Interpolate the icon text size 207b38002419dcb456b51f5d320b224737f16a07088Winson Chung points.clear(); 208b38002419dcb456b51f5d320b224737f16a07088Winson Chung for (DeviceProfile p : profiles) { 209b38002419dcb456b51f5d320b224737f16a07088Winson Chung points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.iconTextSize)); 210b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 211b38002419dcb456b51f5d320b224737f16a07088Winson Chung iconTextSize = invDistWeightedInterpolate(minWidth, minHeight, points); 212b38002419dcb456b51f5d320b224737f16a07088Winson Chung iconDrawablePaddingOriginalPx = 213b38002419dcb456b51f5d320b224737f16a07088Winson Chung res.getDimensionPixelSize(R.dimen.dynamic_grid_icon_drawable_padding); 214b38002419dcb456b51f5d320b224737f16a07088Winson Chung // AllApps uses the original non-scaled icon text size 215b38002419dcb456b51f5d320b224737f16a07088Winson Chung allAppsIconTextSizePx = DynamicGrid.pxFromDp(iconTextSize, dm); 216b38002419dcb456b51f5d320b224737f16a07088Winson Chung 217b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Interpolate the hotseat icon size 218b38002419dcb456b51f5d320b224737f16a07088Winson Chung points.clear(); 219b38002419dcb456b51f5d320b224737f16a07088Winson Chung for (DeviceProfile p : profiles) { 220b38002419dcb456b51f5d320b224737f16a07088Winson Chung points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.hotseatIconSize)); 221b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 222b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Hotseat 223b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseatIconSize = invDistWeightedInterpolate(minWidth, minHeight, points); 224b38002419dcb456b51f5d320b224737f16a07088Winson Chung 225b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Calculate the remaining vars 226b38002419dcb456b51f5d320b224737f16a07088Winson Chung updateFromConfiguration(context, res, wPx, hPx, awPx, ahPx); 227b38002419dcb456b51f5d320b224737f16a07088Winson Chung updateAvailableDimensions(context); 228b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 229b38002419dcb456b51f5d320b224737f16a07088Winson Chung 230b38002419dcb456b51f5d320b224737f16a07088Winson Chung void addCallback(DeviceProfileCallbacks cb) { 231b38002419dcb456b51f5d320b224737f16a07088Winson Chung mCallbacks.add(cb); 232b38002419dcb456b51f5d320b224737f16a07088Winson Chung cb.onAvailableSizeChanged(this); 233b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 234b38002419dcb456b51f5d320b224737f16a07088Winson Chung void removeCallback(DeviceProfileCallbacks cb) { 235b38002419dcb456b51f5d320b224737f16a07088Winson Chung mCallbacks.remove(cb); 236b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 237b38002419dcb456b51f5d320b224737f16a07088Winson Chung 238b38002419dcb456b51f5d320b224737f16a07088Winson Chung private int getDeviceOrientation(Context context) { 239b38002419dcb456b51f5d320b224737f16a07088Winson Chung WindowManager windowManager = (WindowManager) 240b38002419dcb456b51f5d320b224737f16a07088Winson Chung context.getSystemService(Context.WINDOW_SERVICE); 241b38002419dcb456b51f5d320b224737f16a07088Winson Chung Resources resources = context.getResources(); 242b38002419dcb456b51f5d320b224737f16a07088Winson Chung DisplayMetrics dm = resources.getDisplayMetrics(); 243b38002419dcb456b51f5d320b224737f16a07088Winson Chung Configuration config = resources.getConfiguration(); 244b38002419dcb456b51f5d320b224737f16a07088Winson Chung int rotation = windowManager.getDefaultDisplay().getRotation(); 245b38002419dcb456b51f5d320b224737f16a07088Winson Chung 246b38002419dcb456b51f5d320b224737f16a07088Winson Chung boolean isLandscape = (config.orientation == Configuration.ORIENTATION_LANDSCAPE) && 247b38002419dcb456b51f5d320b224737f16a07088Winson Chung (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180); 248b38002419dcb456b51f5d320b224737f16a07088Winson Chung boolean isRotatedPortrait = (config.orientation == Configuration.ORIENTATION_PORTRAIT) && 249b38002419dcb456b51f5d320b224737f16a07088Winson Chung (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270); 250b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (isLandscape || isRotatedPortrait) { 251b38002419dcb456b51f5d320b224737f16a07088Winson Chung return CellLayout.LANDSCAPE; 252b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 253b38002419dcb456b51f5d320b224737f16a07088Winson Chung return CellLayout.PORTRAIT; 254b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 255b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 256b38002419dcb456b51f5d320b224737f16a07088Winson Chung 257b38002419dcb456b51f5d320b224737f16a07088Winson Chung private void updateAvailableDimensions(Context context) { 258b38002419dcb456b51f5d320b224737f16a07088Winson Chung WindowManager windowManager = (WindowManager) 259b38002419dcb456b51f5d320b224737f16a07088Winson Chung context.getSystemService(Context.WINDOW_SERVICE); 260b38002419dcb456b51f5d320b224737f16a07088Winson Chung Display display = windowManager.getDefaultDisplay(); 261b38002419dcb456b51f5d320b224737f16a07088Winson Chung Resources resources = context.getResources(); 262b38002419dcb456b51f5d320b224737f16a07088Winson Chung DisplayMetrics dm = resources.getDisplayMetrics(); 263b38002419dcb456b51f5d320b224737f16a07088Winson Chung Configuration config = resources.getConfiguration(); 264b38002419dcb456b51f5d320b224737f16a07088Winson Chung 265b38002419dcb456b51f5d320b224737f16a07088Winson Chung // There are three possible configurations that the dynamic grid accounts for, portrait, 266b38002419dcb456b51f5d320b224737f16a07088Winson Chung // landscape with the nav bar at the bottom, and landscape with the nav bar at the side. 267b38002419dcb456b51f5d320b224737f16a07088Winson Chung // To prevent waiting for fitSystemWindows(), we make the observation that in landscape, 268b38002419dcb456b51f5d320b224737f16a07088Winson Chung // the height is the smallest height (either with the nav bar at the bottom or to the 269b38002419dcb456b51f5d320b224737f16a07088Winson Chung // side) and otherwise, the height is simply the largest possible height for a portrait 270b38002419dcb456b51f5d320b224737f16a07088Winson Chung // device. 271b38002419dcb456b51f5d320b224737f16a07088Winson Chung Point size = new Point(); 272b38002419dcb456b51f5d320b224737f16a07088Winson Chung Point smallestSize = new Point(); 273b38002419dcb456b51f5d320b224737f16a07088Winson Chung Point largestSize = new Point(); 274b38002419dcb456b51f5d320b224737f16a07088Winson Chung display.getSize(size); 275b38002419dcb456b51f5d320b224737f16a07088Winson Chung display.getCurrentSizeRange(smallestSize, largestSize); 276b38002419dcb456b51f5d320b224737f16a07088Winson Chung availableWidthPx = size.x; 277b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) { 278b38002419dcb456b51f5d320b224737f16a07088Winson Chung availableHeightPx = smallestSize.y; 279b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 280b38002419dcb456b51f5d320b224737f16a07088Winson Chung availableHeightPx = largestSize.y; 281b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 282b38002419dcb456b51f5d320b224737f16a07088Winson Chung 283b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Check to see if the icons fit in the new available height. If not, then we need to 284b38002419dcb456b51f5d320b224737f16a07088Winson Chung // shrink the icon size. 285b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect workspacePadding = getWorkspacePadding(); 286b38002419dcb456b51f5d320b224737f16a07088Winson Chung float scale = 1f; 287b38002419dcb456b51f5d320b224737f16a07088Winson Chung int drawablePadding = iconDrawablePaddingOriginalPx; 288b38002419dcb456b51f5d320b224737f16a07088Winson Chung updateIconSize(1f, drawablePadding, resources, dm); 289b38002419dcb456b51f5d320b224737f16a07088Winson Chung float usedHeight = (cellHeightPx * numRows); 290b38002419dcb456b51f5d320b224737f16a07088Winson Chung int maxHeight = (availableHeightPx - workspacePadding.top - workspacePadding.bottom); 291b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (usedHeight > maxHeight) { 292b38002419dcb456b51f5d320b224737f16a07088Winson Chung scale = maxHeight / usedHeight; 293b38002419dcb456b51f5d320b224737f16a07088Winson Chung drawablePadding = 0; 294b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 295b38002419dcb456b51f5d320b224737f16a07088Winson Chung updateIconSize(scale, drawablePadding, resources, dm); 296b38002419dcb456b51f5d320b224737f16a07088Winson Chung 297b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Make the callbacks 298b38002419dcb456b51f5d320b224737f16a07088Winson Chung for (DeviceProfileCallbacks cb : mCallbacks) { 299b38002419dcb456b51f5d320b224737f16a07088Winson Chung cb.onAvailableSizeChanged(this); 300b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 301b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 302b38002419dcb456b51f5d320b224737f16a07088Winson Chung 303b38002419dcb456b51f5d320b224737f16a07088Winson Chung private void updateIconSize(float scale, int drawablePadding, Resources resources, 304b38002419dcb456b51f5d320b224737f16a07088Winson Chung DisplayMetrics dm) { 305b38002419dcb456b51f5d320b224737f16a07088Winson Chung iconSizePx = (int) (DynamicGrid.pxFromDp(iconSize, dm) * scale); 306b38002419dcb456b51f5d320b224737f16a07088Winson Chung iconTextSizePx = (int) (DynamicGrid.pxFromSp(iconTextSize, dm) * scale); 307b38002419dcb456b51f5d320b224737f16a07088Winson Chung iconDrawablePaddingPx = drawablePadding; 308b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseatIconSizePx = (int) (DynamicGrid.pxFromDp(hotseatIconSize, dm) * scale); 309b38002419dcb456b51f5d320b224737f16a07088Winson Chung 310b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Search Bar 311b38002419dcb456b51f5d320b224737f16a07088Winson Chung searchBarSpaceMaxWidthPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width); 312b38002419dcb456b51f5d320b224737f16a07088Winson Chung searchBarHeightPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height); 313b38002419dcb456b51f5d320b224737f16a07088Winson Chung searchBarSpaceWidthPx = Math.min(searchBarSpaceMaxWidthPx, widthPx); 31469e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung searchBarSpaceHeightPx = searchBarHeightPx + getSearchBarTopOffset(); 315b38002419dcb456b51f5d320b224737f16a07088Winson Chung 316b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Calculate the actual text height 317b38002419dcb456b51f5d320b224737f16a07088Winson Chung Paint textPaint = new Paint(); 318b38002419dcb456b51f5d320b224737f16a07088Winson Chung textPaint.setTextSize(iconTextSizePx); 319b38002419dcb456b51f5d320b224737f16a07088Winson Chung FontMetrics fm = textPaint.getFontMetrics(); 320b38002419dcb456b51f5d320b224737f16a07088Winson Chung cellWidthPx = iconSizePx; 321b38002419dcb456b51f5d320b224737f16a07088Winson Chung cellHeightPx = iconSizePx + iconDrawablePaddingPx + (int) Math.ceil(fm.bottom - fm.top); 322b38002419dcb456b51f5d320b224737f16a07088Winson Chung 323b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Hotseat 324b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseatBarHeightPx = iconSizePx + 4 * edgeMarginPx; 325b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseatCellWidthPx = iconSizePx; 326b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseatCellHeightPx = iconSizePx; 327b38002419dcb456b51f5d320b224737f16a07088Winson Chung 328b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Folder 329b38002419dcb456b51f5d320b224737f16a07088Winson Chung folderCellWidthPx = cellWidthPx + 3 * edgeMarginPx; 330b38002419dcb456b51f5d320b224737f16a07088Winson Chung folderCellHeightPx = cellHeightPx + edgeMarginPx; 331b38002419dcb456b51f5d320b224737f16a07088Winson Chung folderBackgroundOffset = -edgeMarginPx; 332b38002419dcb456b51f5d320b224737f16a07088Winson Chung folderIconSizePx = iconSizePx + 2 * -folderBackgroundOffset; 333b38002419dcb456b51f5d320b224737f16a07088Winson Chung 334b38002419dcb456b51f5d320b224737f16a07088Winson Chung // All Apps 335b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect padding = getWorkspacePadding(isLandscape ? 336b38002419dcb456b51f5d320b224737f16a07088Winson Chung CellLayout.LANDSCAPE : CellLayout.PORTRAIT); 337b38002419dcb456b51f5d320b224737f16a07088Winson Chung int pageIndicatorOffset = 338b38002419dcb456b51f5d320b224737f16a07088Winson Chung resources.getDimensionPixelSize(R.dimen.apps_customize_page_indicator_offset); 339b38002419dcb456b51f5d320b224737f16a07088Winson Chung allAppsCellWidthPx = allAppsIconSizePx; 340b38002419dcb456b51f5d320b224737f16a07088Winson Chung allAppsCellHeightPx = allAppsIconSizePx + drawablePadding + iconTextSizePx; 341b38002419dcb456b51f5d320b224737f16a07088Winson Chung int maxLongEdgeCellCount = 342b38002419dcb456b51f5d320b224737f16a07088Winson Chung resources.getInteger(R.integer.config_dynamic_grid_max_long_edge_cell_count); 343b38002419dcb456b51f5d320b224737f16a07088Winson Chung int maxShortEdgeCellCount = 344b38002419dcb456b51f5d320b224737f16a07088Winson Chung resources.getInteger(R.integer.config_dynamic_grid_max_short_edge_cell_count); 345b38002419dcb456b51f5d320b224737f16a07088Winson Chung int minEdgeCellCount = 346b38002419dcb456b51f5d320b224737f16a07088Winson Chung resources.getInteger(R.integer.config_dynamic_grid_min_edge_cell_count); 347b38002419dcb456b51f5d320b224737f16a07088Winson Chung int maxRows = (isLandscape ? maxShortEdgeCellCount : maxLongEdgeCellCount); 348b38002419dcb456b51f5d320b224737f16a07088Winson Chung int maxCols = (isLandscape ? maxLongEdgeCellCount : maxShortEdgeCellCount); 349b38002419dcb456b51f5d320b224737f16a07088Winson Chung 350b38002419dcb456b51f5d320b224737f16a07088Winson Chung allAppsNumRows = (availableHeightPx - pageIndicatorHeightPx) / 351b38002419dcb456b51f5d320b224737f16a07088Winson Chung (allAppsCellHeightPx + allAppsCellPaddingPx); 352b38002419dcb456b51f5d320b224737f16a07088Winson Chung allAppsNumRows = Math.max(minEdgeCellCount, Math.min(maxRows, allAppsNumRows)); 353b38002419dcb456b51f5d320b224737f16a07088Winson Chung allAppsNumCols = (availableWidthPx) / 354b38002419dcb456b51f5d320b224737f16a07088Winson Chung (allAppsCellWidthPx + allAppsCellPaddingPx); 355b38002419dcb456b51f5d320b224737f16a07088Winson Chung allAppsNumCols = Math.max(minEdgeCellCount, Math.min(maxCols, allAppsNumCols)); 356b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 357b38002419dcb456b51f5d320b224737f16a07088Winson Chung 358b38002419dcb456b51f5d320b224737f16a07088Winson Chung void updateFromConfiguration(Context context, Resources resources, int wPx, int hPx, 359b38002419dcb456b51f5d320b224737f16a07088Winson Chung int awPx, int ahPx) { 36042b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung Configuration configuration = resources.getConfiguration(); 36142b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung isLandscape = (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE); 362b38002419dcb456b51f5d320b224737f16a07088Winson Chung isTablet = resources.getBoolean(R.bool.is_tablet); 363b38002419dcb456b51f5d320b224737f16a07088Winson Chung isLargeTablet = resources.getBoolean(R.bool.is_large_tablet); 36442b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung isLayoutRtl = (configuration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL); 365b38002419dcb456b51f5d320b224737f16a07088Winson Chung widthPx = wPx; 366b38002419dcb456b51f5d320b224737f16a07088Winson Chung heightPx = hPx; 367b38002419dcb456b51f5d320b224737f16a07088Winson Chung availableWidthPx = awPx; 368b38002419dcb456b51f5d320b224737f16a07088Winson Chung availableHeightPx = ahPx; 369b38002419dcb456b51f5d320b224737f16a07088Winson Chung 370b38002419dcb456b51f5d320b224737f16a07088Winson Chung updateAvailableDimensions(context); 371b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 372b38002419dcb456b51f5d320b224737f16a07088Winson Chung 373b38002419dcb456b51f5d320b224737f16a07088Winson Chung private float dist(PointF p0, PointF p1) { 374b38002419dcb456b51f5d320b224737f16a07088Winson Chung return (float) Math.sqrt((p1.x - p0.x)*(p1.x-p0.x) + 375b38002419dcb456b51f5d320b224737f16a07088Winson Chung (p1.y-p0.y)*(p1.y-p0.y)); 376b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 377b38002419dcb456b51f5d320b224737f16a07088Winson Chung 378b38002419dcb456b51f5d320b224737f16a07088Winson Chung private float weight(PointF a, PointF b, 379b38002419dcb456b51f5d320b224737f16a07088Winson Chung float pow) { 380b38002419dcb456b51f5d320b224737f16a07088Winson Chung float d = dist(a, b); 381b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (d == 0f) { 382b38002419dcb456b51f5d320b224737f16a07088Winson Chung return Float.POSITIVE_INFINITY; 383b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 384b38002419dcb456b51f5d320b224737f16a07088Winson Chung return (float) (1f / Math.pow(d, pow)); 385b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 386b38002419dcb456b51f5d320b224737f16a07088Winson Chung 387b38002419dcb456b51f5d320b224737f16a07088Winson Chung private float invDistWeightedInterpolate(float width, float height, 388b38002419dcb456b51f5d320b224737f16a07088Winson Chung ArrayList<DeviceProfileQuery> points) { 389b38002419dcb456b51f5d320b224737f16a07088Winson Chung float sum = 0; 390b38002419dcb456b51f5d320b224737f16a07088Winson Chung float weights = 0; 391b38002419dcb456b51f5d320b224737f16a07088Winson Chung float pow = 5; 392b38002419dcb456b51f5d320b224737f16a07088Winson Chung float kNearestNeighbors = 3; 393b38002419dcb456b51f5d320b224737f16a07088Winson Chung final PointF xy = new PointF(width, height); 394b38002419dcb456b51f5d320b224737f16a07088Winson Chung 395b38002419dcb456b51f5d320b224737f16a07088Winson Chung ArrayList<DeviceProfileQuery> pointsByNearness = points; 396b38002419dcb456b51f5d320b224737f16a07088Winson Chung Collections.sort(pointsByNearness, new Comparator<DeviceProfileQuery>() { 397b38002419dcb456b51f5d320b224737f16a07088Winson Chung public int compare(DeviceProfileQuery a, DeviceProfileQuery b) { 398b38002419dcb456b51f5d320b224737f16a07088Winson Chung return (int) (dist(xy, a.dimens) - dist(xy, b.dimens)); 399b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 400b38002419dcb456b51f5d320b224737f16a07088Winson Chung }); 401b38002419dcb456b51f5d320b224737f16a07088Winson Chung 402b38002419dcb456b51f5d320b224737f16a07088Winson Chung for (int i = 0; i < pointsByNearness.size(); ++i) { 403b38002419dcb456b51f5d320b224737f16a07088Winson Chung DeviceProfileQuery p = pointsByNearness.get(i); 404b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (i < kNearestNeighbors) { 405b38002419dcb456b51f5d320b224737f16a07088Winson Chung float w = weight(xy, p.dimens, pow); 406b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (w == Float.POSITIVE_INFINITY) { 407b38002419dcb456b51f5d320b224737f16a07088Winson Chung return p.value; 408b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 409b38002419dcb456b51f5d320b224737f16a07088Winson Chung weights += w; 410b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 411b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 412b38002419dcb456b51f5d320b224737f16a07088Winson Chung 413b38002419dcb456b51f5d320b224737f16a07088Winson Chung for (int i = 0; i < pointsByNearness.size(); ++i) { 414b38002419dcb456b51f5d320b224737f16a07088Winson Chung DeviceProfileQuery p = pointsByNearness.get(i); 415b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (i < kNearestNeighbors) { 416b38002419dcb456b51f5d320b224737f16a07088Winson Chung float w = weight(xy, p.dimens, pow); 417b38002419dcb456b51f5d320b224737f16a07088Winson Chung sum += w * p.value / weights; 418b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 419b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 420b38002419dcb456b51f5d320b224737f16a07088Winson Chung 421b38002419dcb456b51f5d320b224737f16a07088Winson Chung return sum; 422b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 423b38002419dcb456b51f5d320b224737f16a07088Winson Chung 42469e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung /** Returns the search bar top offset */ 42569e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung int getSearchBarTopOffset() { 42669e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung if (isTablet() && !isVerticalBarLayout()) { 42769e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung return 4 * edgeMarginPx; 42869e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung } else { 42969e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung return 2 * edgeMarginPx; 43069e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung } 43169e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung } 43269e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung 433b38002419dcb456b51f5d320b224737f16a07088Winson Chung /** Returns the search bar bounds in the current orientation */ 434b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect getSearchBarBounds() { 435b38002419dcb456b51f5d320b224737f16a07088Winson Chung return getSearchBarBounds(isLandscape ? CellLayout.LANDSCAPE : CellLayout.PORTRAIT); 436b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 437b38002419dcb456b51f5d320b224737f16a07088Winson Chung /** Returns the search bar bounds in the specified orientation */ 438b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect getSearchBarBounds(int orientation) { 439b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect bounds = new Rect(); 440b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (orientation == CellLayout.LANDSCAPE && 441b38002419dcb456b51f5d320b224737f16a07088Winson Chung transposeLayoutWithOrientation) { 44242b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung if (isLayoutRtl) { 44342b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung bounds.set(availableWidthPx - searchBarSpaceHeightPx, edgeMarginPx, 44442b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung availableWidthPx, availableHeightPx - edgeMarginPx); 44542b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung } else { 44642b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung bounds.set(0, edgeMarginPx, searchBarSpaceHeightPx, 44742b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung availableHeightPx - edgeMarginPx); 44842b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung } 449b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 450b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (isTablet()) { 451b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Pad the left and right of the workspace to ensure consistent spacing 452b38002419dcb456b51f5d320b224737f16a07088Winson Chung // between all icons 453b38002419dcb456b51f5d320b224737f16a07088Winson Chung int width = (orientation == CellLayout.LANDSCAPE) 454b38002419dcb456b51f5d320b224737f16a07088Winson Chung ? Math.max(widthPx, heightPx) 455b38002419dcb456b51f5d320b224737f16a07088Winson Chung : Math.min(widthPx, heightPx); 456b38002419dcb456b51f5d320b224737f16a07088Winson Chung // XXX: If the icon size changes across orientations, we will have to take 457b38002419dcb456b51f5d320b224737f16a07088Winson Chung // that into account here too. 458b38002419dcb456b51f5d320b224737f16a07088Winson Chung int gap = (int) ((width - 2 * edgeMarginPx - 459b38002419dcb456b51f5d320b224737f16a07088Winson Chung (numColumns * cellWidthPx)) / (2 * (numColumns + 1))); 4602cb2471e7fbade9a785c523df5941f2855e99041Winson Chung bounds.set(edgeMarginPx + gap, getSearchBarTopOffset(), 4612cb2471e7fbade9a785c523df5941f2855e99041Winson Chung availableWidthPx - (edgeMarginPx + gap), 462b38002419dcb456b51f5d320b224737f16a07088Winson Chung searchBarSpaceHeightPx); 463b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 4642cb2471e7fbade9a785c523df5941f2855e99041Winson Chung bounds.set(desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.left, 4652cb2471e7fbade9a785c523df5941f2855e99041Winson Chung getSearchBarTopOffset(), 466b38002419dcb456b51f5d320b224737f16a07088Winson Chung availableWidthPx - (desiredWorkspaceLeftRightMarginPx - 467b38002419dcb456b51f5d320b224737f16a07088Winson Chung defaultWidgetPadding.right), searchBarSpaceHeightPx); 468b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 469b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 470b38002419dcb456b51f5d320b224737f16a07088Winson Chung return bounds; 471b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 472b38002419dcb456b51f5d320b224737f16a07088Winson Chung 473b38002419dcb456b51f5d320b224737f16a07088Winson Chung /** Returns the workspace padding in the specified orientation */ 474b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect getWorkspacePadding() { 475b38002419dcb456b51f5d320b224737f16a07088Winson Chung return getWorkspacePadding(isLandscape ? CellLayout.LANDSCAPE : CellLayout.PORTRAIT); 476b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 477b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect getWorkspacePadding(int orientation) { 478b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect searchBarBounds = getSearchBarBounds(orientation); 479b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect padding = new Rect(); 480b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (orientation == CellLayout.LANDSCAPE && 481b38002419dcb456b51f5d320b224737f16a07088Winson Chung transposeLayoutWithOrientation) { 482b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Pad the left and right of the workspace with search/hotseat bar sizes 48342b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung if (isLayoutRtl) { 48442b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung padding.set(hotseatBarHeightPx, edgeMarginPx, 48542b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung searchBarBounds.width(), edgeMarginPx); 48642b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung } else { 48742b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung padding.set(searchBarBounds.width(), edgeMarginPx, 48842b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung hotseatBarHeightPx, edgeMarginPx); 48942b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung } 490b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 491b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (isTablet()) { 492b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Pad the left and right of the workspace to ensure consistent spacing 493b38002419dcb456b51f5d320b224737f16a07088Winson Chung // between all icons 494b38002419dcb456b51f5d320b224737f16a07088Winson Chung int width = (orientation == CellLayout.LANDSCAPE) 495b38002419dcb456b51f5d320b224737f16a07088Winson Chung ? Math.max(widthPx, heightPx) 496b38002419dcb456b51f5d320b224737f16a07088Winson Chung : Math.min(widthPx, heightPx); 497b38002419dcb456b51f5d320b224737f16a07088Winson Chung // XXX: If the icon size changes across orientations, we will have to take 498b38002419dcb456b51f5d320b224737f16a07088Winson Chung // that into account here too. 499b38002419dcb456b51f5d320b224737f16a07088Winson Chung int gap = (int) ((width - 2 * edgeMarginPx - 500b38002419dcb456b51f5d320b224737f16a07088Winson Chung (numColumns * cellWidthPx)) / (2 * (numColumns + 1))); 501b38002419dcb456b51f5d320b224737f16a07088Winson Chung padding.set(edgeMarginPx + gap, 502b38002419dcb456b51f5d320b224737f16a07088Winson Chung searchBarBounds.bottom, 503b38002419dcb456b51f5d320b224737f16a07088Winson Chung edgeMarginPx + gap, 504b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseatBarHeightPx + pageIndicatorHeightPx); 505b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 506b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Pad the top and bottom of the workspace with search/hotseat bar sizes 507b38002419dcb456b51f5d320b224737f16a07088Winson Chung padding.set(desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.left, 508b38002419dcb456b51f5d320b224737f16a07088Winson Chung searchBarBounds.bottom, 509b38002419dcb456b51f5d320b224737f16a07088Winson Chung desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.right, 510b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseatBarHeightPx + pageIndicatorHeightPx); 511b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 512b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 513b38002419dcb456b51f5d320b224737f16a07088Winson Chung return padding; 514b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 515b38002419dcb456b51f5d320b224737f16a07088Winson Chung 516b38002419dcb456b51f5d320b224737f16a07088Winson Chung int getWorkspacePageSpacing(int orientation) { 517b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (orientation == CellLayout.LANDSCAPE && 518b38002419dcb456b51f5d320b224737f16a07088Winson Chung transposeLayoutWithOrientation) { 519b38002419dcb456b51f5d320b224737f16a07088Winson Chung // In landscape mode the page spacing is set to the default. 520b38002419dcb456b51f5d320b224737f16a07088Winson Chung return defaultPageSpacingPx; 521b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 522b38002419dcb456b51f5d320b224737f16a07088Winson Chung // In portrait, we want the pages spaced such that there is no 523b38002419dcb456b51f5d320b224737f16a07088Winson Chung // overhang of the previous / next page into the current page viewport. 524b38002419dcb456b51f5d320b224737f16a07088Winson Chung // We assume symmetrical padding in portrait mode. 525b38002419dcb456b51f5d320b224737f16a07088Winson Chung return 2 * getWorkspacePadding().left; 526b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 527b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 528b38002419dcb456b51f5d320b224737f16a07088Winson Chung 529b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect getOverviewModeButtonBarRect() { 530b38002419dcb456b51f5d320b224737f16a07088Winson Chung int zoneHeight = (int) (overviewModeIconZoneRatio * availableHeightPx); 531b38002419dcb456b51f5d320b224737f16a07088Winson Chung zoneHeight = Math.min(overviewModeMaxIconZoneHeightPx, 532b38002419dcb456b51f5d320b224737f16a07088Winson Chung Math.max(overviewModeMinIconZoneHeightPx, zoneHeight)); 533b38002419dcb456b51f5d320b224737f16a07088Winson Chung return new Rect(0, availableHeightPx - zoneHeight, 0, availableHeightPx); 534b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 535b38002419dcb456b51f5d320b224737f16a07088Winson Chung 536b38002419dcb456b51f5d320b224737f16a07088Winson Chung float getOverviewModeScale() { 537b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect workspacePadding = getWorkspacePadding(); 538b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect overviewBar = getOverviewModeButtonBarRect(); 539b38002419dcb456b51f5d320b224737f16a07088Winson Chung int pageSpace = availableHeightPx - workspacePadding.top - workspacePadding.bottom; 540b38002419dcb456b51f5d320b224737f16a07088Winson Chung return (overviewModeScaleFactor * (pageSpace - overviewBar.height())) / pageSpace; 541b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 542b38002419dcb456b51f5d320b224737f16a07088Winson Chung 543b38002419dcb456b51f5d320b224737f16a07088Winson Chung // The rect returned will be extended to below the system ui that covers the workspace 544b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect getHotseatRect() { 545b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (isVerticalBarLayout()) { 546b38002419dcb456b51f5d320b224737f16a07088Winson Chung return new Rect(availableWidthPx - hotseatBarHeightPx, 0, 547b38002419dcb456b51f5d320b224737f16a07088Winson Chung Integer.MAX_VALUE, availableHeightPx); 548b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 549b38002419dcb456b51f5d320b224737f16a07088Winson Chung return new Rect(0, availableHeightPx - hotseatBarHeightPx, 550b38002419dcb456b51f5d320b224737f16a07088Winson Chung availableWidthPx, Integer.MAX_VALUE); 551b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 552b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 553b38002419dcb456b51f5d320b224737f16a07088Winson Chung 554b38002419dcb456b51f5d320b224737f16a07088Winson Chung int calculateCellWidth(int width, int countX) { 555b38002419dcb456b51f5d320b224737f16a07088Winson Chung return width / countX; 556b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 557b38002419dcb456b51f5d320b224737f16a07088Winson Chung int calculateCellHeight(int height, int countY) { 558b38002419dcb456b51f5d320b224737f16a07088Winson Chung return height / countY; 559b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 560b38002419dcb456b51f5d320b224737f16a07088Winson Chung 561b38002419dcb456b51f5d320b224737f16a07088Winson Chung boolean isPhone() { 562b38002419dcb456b51f5d320b224737f16a07088Winson Chung return !isTablet && !isLargeTablet; 563b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 564b38002419dcb456b51f5d320b224737f16a07088Winson Chung boolean isTablet() { 565b38002419dcb456b51f5d320b224737f16a07088Winson Chung return isTablet; 566b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 567b38002419dcb456b51f5d320b224737f16a07088Winson Chung boolean isLargeTablet() { 568b38002419dcb456b51f5d320b224737f16a07088Winson Chung return isLargeTablet; 569b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 570b38002419dcb456b51f5d320b224737f16a07088Winson Chung 571b38002419dcb456b51f5d320b224737f16a07088Winson Chung boolean isVerticalBarLayout() { 572b38002419dcb456b51f5d320b224737f16a07088Winson Chung return isLandscape && transposeLayoutWithOrientation; 573b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 574b38002419dcb456b51f5d320b224737f16a07088Winson Chung 575b38002419dcb456b51f5d320b224737f16a07088Winson Chung boolean shouldFadeAdjacentWorkspaceScreens() { 576b38002419dcb456b51f5d320b224737f16a07088Winson Chung return isVerticalBarLayout() || isLargeTablet(); 577b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 578b38002419dcb456b51f5d320b224737f16a07088Winson Chung 579b38002419dcb456b51f5d320b224737f16a07088Winson Chung public void layout(Launcher launcher) { 580b38002419dcb456b51f5d320b224737f16a07088Winson Chung FrameLayout.LayoutParams lp; 581b38002419dcb456b51f5d320b224737f16a07088Winson Chung Resources res = launcher.getResources(); 582b38002419dcb456b51f5d320b224737f16a07088Winson Chung boolean hasVerticalBarLayout = isVerticalBarLayout(); 583b38002419dcb456b51f5d320b224737f16a07088Winson Chung 584b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Layout the search bar space 585b38002419dcb456b51f5d320b224737f16a07088Winson Chung View searchBar = launcher.getSearchBar(); 586b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp = (FrameLayout.LayoutParams) searchBar.getLayoutParams(); 587b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (hasVerticalBarLayout) { 58869e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung // Vertical search bar space 589b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.gravity = Gravity.TOP | Gravity.LEFT; 590b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.width = searchBarSpaceHeightPx; 591b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.height = LayoutParams.MATCH_PARENT; 592b38002419dcb456b51f5d320b224737f16a07088Winson Chung searchBar.setPadding( 593b38002419dcb456b51f5d320b224737f16a07088Winson Chung 0, 2 * edgeMarginPx, 0, 594b38002419dcb456b51f5d320b224737f16a07088Winson Chung 2 * edgeMarginPx); 595b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 59669e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung // Horizontal search bar space 597b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; 598b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.width = searchBarSpaceWidthPx; 599b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.height = searchBarSpaceHeightPx; 600b38002419dcb456b51f5d320b224737f16a07088Winson Chung searchBar.setPadding( 601b38002419dcb456b51f5d320b224737f16a07088Winson Chung 2 * edgeMarginPx, 60269e04ea5ab08ae923d5c8de079c7a36998e5e46aWinson Chung getSearchBarTopOffset(), 603b38002419dcb456b51f5d320b224737f16a07088Winson Chung 2 * edgeMarginPx, 0); 604b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 605b38002419dcb456b51f5d320b224737f16a07088Winson Chung searchBar.setLayoutParams(lp); 606b38002419dcb456b51f5d320b224737f16a07088Winson Chung 607b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Layout the search bar 608b38002419dcb456b51f5d320b224737f16a07088Winson Chung View qsbBar = launcher.getQsbBar(); 609b38002419dcb456b51f5d320b224737f16a07088Winson Chung LayoutParams vglp = qsbBar.getLayoutParams(); 610b38002419dcb456b51f5d320b224737f16a07088Winson Chung vglp.width = LayoutParams.MATCH_PARENT; 611b38002419dcb456b51f5d320b224737f16a07088Winson Chung vglp.height = LayoutParams.MATCH_PARENT; 612b38002419dcb456b51f5d320b224737f16a07088Winson Chung qsbBar.setLayoutParams(vglp); 613b38002419dcb456b51f5d320b224737f16a07088Winson Chung 614b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Layout the voice proxy 615b38002419dcb456b51f5d320b224737f16a07088Winson Chung View voiceButtonProxy = launcher.findViewById(R.id.voice_button_proxy); 616b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (voiceButtonProxy != null) { 617b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (hasVerticalBarLayout) { 618b38002419dcb456b51f5d320b224737f16a07088Winson Chung // TODO: MOVE THIS INTO SEARCH BAR MEASURE 619b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 620b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp = (FrameLayout.LayoutParams) voiceButtonProxy.getLayoutParams(); 621b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.gravity = Gravity.TOP | Gravity.END; 622b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.width = (widthPx - searchBarSpaceWidthPx) / 2 + 623b38002419dcb456b51f5d320b224737f16a07088Winson Chung 2 * iconSizePx; 624b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.height = searchBarSpaceHeightPx; 625b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 626b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 627b38002419dcb456b51f5d320b224737f16a07088Winson Chung 628b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Layout the workspace 629b38002419dcb456b51f5d320b224737f16a07088Winson Chung PagedView workspace = (PagedView) launcher.findViewById(R.id.workspace); 630b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp = (FrameLayout.LayoutParams) workspace.getLayoutParams(); 631b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.gravity = Gravity.CENTER; 632b38002419dcb456b51f5d320b224737f16a07088Winson Chung int orientation = isLandscape ? CellLayout.LANDSCAPE : CellLayout.PORTRAIT; 633b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect padding = getWorkspacePadding(orientation); 634b38002419dcb456b51f5d320b224737f16a07088Winson Chung workspace.setLayoutParams(lp); 635b38002419dcb456b51f5d320b224737f16a07088Winson Chung workspace.setPadding(padding.left, padding.top, padding.right, padding.bottom); 636b38002419dcb456b51f5d320b224737f16a07088Winson Chung workspace.setPageSpacing(getWorkspacePageSpacing(orientation)); 637b38002419dcb456b51f5d320b224737f16a07088Winson Chung 638b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Layout the hotseat 639b38002419dcb456b51f5d320b224737f16a07088Winson Chung View hotseat = launcher.findViewById(R.id.hotseat); 640b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp = (FrameLayout.LayoutParams) hotseat.getLayoutParams(); 641b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (hasVerticalBarLayout) { 642b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Vertical hotseat 64342b3c06849331aa5ba1f07f8c58915190d386aacWinson Chung lp.gravity = Gravity.END; 644b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.width = hotseatBarHeightPx; 645b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.height = LayoutParams.MATCH_PARENT; 646b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseat.findViewById(R.id.layout).setPadding(0, 2 * edgeMarginPx, 0, 2 * edgeMarginPx); 647b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else if (isTablet()) { 648b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Pad the hotseat with the grid gap calculated above 649b38002419dcb456b51f5d320b224737f16a07088Winson Chung int gridGap = (int) ((widthPx - 2 * edgeMarginPx - 650b38002419dcb456b51f5d320b224737f16a07088Winson Chung (numColumns * cellWidthPx)) / (2 * (numColumns + 1))); 651b38002419dcb456b51f5d320b224737f16a07088Winson Chung int gridWidth = (int) ((numColumns * cellWidthPx) + 652b38002419dcb456b51f5d320b224737f16a07088Winson Chung ((numColumns - 1) * gridGap)); 653b38002419dcb456b51f5d320b224737f16a07088Winson Chung int hotseatGap = (int) Math.max(0, 654b38002419dcb456b51f5d320b224737f16a07088Winson Chung (gridWidth - (numHotseatIcons * hotseatCellWidthPx)) 655b38002419dcb456b51f5d320b224737f16a07088Winson Chung / (numHotseatIcons - 1)); 656b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.gravity = Gravity.BOTTOM; 657b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.width = LayoutParams.MATCH_PARENT; 658b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.height = hotseatBarHeightPx; 659b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseat.setPadding(2 * edgeMarginPx + gridGap + hotseatGap, 0, 660b38002419dcb456b51f5d320b224737f16a07088Winson Chung 2 * edgeMarginPx + gridGap + hotseatGap, 661b38002419dcb456b51f5d320b224737f16a07088Winson Chung 2 * edgeMarginPx); 662b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 663b38002419dcb456b51f5d320b224737f16a07088Winson Chung // For phones, layout the hotseat without any bottom margin 664b38002419dcb456b51f5d320b224737f16a07088Winson Chung // to ensure that we have space for the folders 665b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.gravity = Gravity.BOTTOM; 666b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.width = LayoutParams.MATCH_PARENT; 667b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.height = hotseatBarHeightPx; 668b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseat.findViewById(R.id.layout).setPadding(2 * edgeMarginPx, 0, 669b38002419dcb456b51f5d320b224737f16a07088Winson Chung 2 * edgeMarginPx, 0); 670b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 671b38002419dcb456b51f5d320b224737f16a07088Winson Chung hotseat.setLayoutParams(lp); 672b38002419dcb456b51f5d320b224737f16a07088Winson Chung 673b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Layout the page indicators 674b38002419dcb456b51f5d320b224737f16a07088Winson Chung View pageIndicator = launcher.findViewById(R.id.page_indicator); 675b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (pageIndicator != null) { 676b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (hasVerticalBarLayout) { 677b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Hide the page indicators when we have vertical search/hotseat 678b38002419dcb456b51f5d320b224737f16a07088Winson Chung pageIndicator.setVisibility(View.GONE); 679b38002419dcb456b51f5d320b224737f16a07088Winson Chung } else { 680b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Put the page indicators above the hotseat 681b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp = (FrameLayout.LayoutParams) pageIndicator.getLayoutParams(); 682b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; 683b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.width = LayoutParams.WRAP_CONTENT; 684b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.height = LayoutParams.WRAP_CONTENT; 685b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.bottomMargin = hotseatBarHeightPx; 686b38002419dcb456b51f5d320b224737f16a07088Winson Chung pageIndicator.setLayoutParams(lp); 687b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 688b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 689b38002419dcb456b51f5d320b224737f16a07088Winson Chung 690b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Layout AllApps 691b38002419dcb456b51f5d320b224737f16a07088Winson Chung AppsCustomizeTabHost host = (AppsCustomizeTabHost) 692b38002419dcb456b51f5d320b224737f16a07088Winson Chung launcher.findViewById(R.id.apps_customize_pane); 693b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (host != null) { 694b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Center the all apps page indicator 695b38002419dcb456b51f5d320b224737f16a07088Winson Chung int pageIndicatorHeight = (int) (pageIndicatorHeightPx * Math.min(1f, 696b38002419dcb456b51f5d320b224737f16a07088Winson Chung (allAppsIconSizePx / DynamicGrid.DEFAULT_ICON_SIZE_PX))); 697b38002419dcb456b51f5d320b224737f16a07088Winson Chung pageIndicator = host.findViewById(R.id.apps_customize_page_indicator); 698b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (pageIndicator != null) { 699b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp = (FrameLayout.LayoutParams) pageIndicator.getLayoutParams(); 700b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; 701b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.width = LayoutParams.WRAP_CONTENT; 702b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.height = pageIndicatorHeight; 703b38002419dcb456b51f5d320b224737f16a07088Winson Chung pageIndicator.setLayoutParams(lp); 704b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 705b38002419dcb456b51f5d320b224737f16a07088Winson Chung 706b38002419dcb456b51f5d320b224737f16a07088Winson Chung AppsCustomizePagedView pagedView = (AppsCustomizePagedView) 707b38002419dcb456b51f5d320b224737f16a07088Winson Chung host.findViewById(R.id.apps_customize_pane_content); 708b38002419dcb456b51f5d320b224737f16a07088Winson Chung padding = new Rect(); 709b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (pagedView != null) { 710b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Constrain the dimensions of all apps so that it does not span the full width 711b38002419dcb456b51f5d320b224737f16a07088Winson Chung int paddingLR = (availableWidthPx - (allAppsCellWidthPx * allAppsNumCols)) / 712b38002419dcb456b51f5d320b224737f16a07088Winson Chung (2 * (allAppsNumCols + 1)); 713b38002419dcb456b51f5d320b224737f16a07088Winson Chung int paddingTB = (availableHeightPx - (allAppsCellHeightPx * allAppsNumRows)) / 714b38002419dcb456b51f5d320b224737f16a07088Winson Chung (2 * (allAppsNumRows + 1)); 715b38002419dcb456b51f5d320b224737f16a07088Winson Chung paddingLR = Math.min(paddingLR, (int)((paddingLR + paddingTB) * 0.75f)); 716b38002419dcb456b51f5d320b224737f16a07088Winson Chung paddingTB = Math.min(paddingTB, (int)((paddingLR + paddingTB) * 0.75f)); 717b38002419dcb456b51f5d320b224737f16a07088Winson Chung int maxAllAppsWidth = (allAppsNumCols * (allAppsCellWidthPx + 2 * paddingLR)); 718b38002419dcb456b51f5d320b224737f16a07088Winson Chung int gridPaddingLR = (availableWidthPx - maxAllAppsWidth) / 2; 719b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (gridPaddingLR > (allAppsCellWidthPx / 4)) { 720b38002419dcb456b51f5d320b224737f16a07088Winson Chung padding.left = padding.right = gridPaddingLR; 721b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 722b38002419dcb456b51f5d320b224737f16a07088Winson Chung // The icons are centered, so we can't just offset by the page indicator height 723b38002419dcb456b51f5d320b224737f16a07088Winson Chung // because the empty space will actually be pageIndicatorHeight + paddingTB 724b38002419dcb456b51f5d320b224737f16a07088Winson Chung padding.bottom = Math.max(0, pageIndicatorHeight - paddingTB); 725b38002419dcb456b51f5d320b224737f16a07088Winson Chung pagedView.setAllAppsPadding(padding); 726b38002419dcb456b51f5d320b224737f16a07088Winson Chung pagedView.setWidgetsPageIndicatorPadding(pageIndicatorHeight); 727b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 728b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 729b38002419dcb456b51f5d320b224737f16a07088Winson Chung 730b38002419dcb456b51f5d320b224737f16a07088Winson Chung // Layout the Overview Mode 731b38002419dcb456b51f5d320b224737f16a07088Winson Chung View overviewMode = launcher.getOverviewPanel(); 732b38002419dcb456b51f5d320b224737f16a07088Winson Chung if (overviewMode != null) { 733b38002419dcb456b51f5d320b224737f16a07088Winson Chung Rect r = getOverviewModeButtonBarRect(); 734b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp = (FrameLayout.LayoutParams) overviewMode.getLayoutParams(); 735b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; 736b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.width = Math.min(availableWidthPx, overviewModeMaxBarWidthPx); 737b38002419dcb456b51f5d320b224737f16a07088Winson Chung lp.height = r.height(); 738b38002419dcb456b51f5d320b224737f16a07088Winson Chung overviewMode.setLayoutParams(lp); 739b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 740b38002419dcb456b51f5d320b224737f16a07088Winson Chung } 741b38002419dcb456b51f5d320b224737f16a07088Winson Chung} 742