diff --git a/res/layout/folder_application.xml b/res/layout/folder_application.xml index 32a5419b8e..1cdee08c25 100644 --- a/res/layout/folder_application.xml +++ b/res/layout/folder_application.xml @@ -21,4 +21,5 @@ android:textColor="?attr/folderTextColor" android:includeFontPadding="false" android:hapticFeedbackEnabled="false" - launcher:iconDisplay="folder" /> + launcher:iconDisplay="folder" + launcher:centerVertically="true" /> diff --git a/res/layout/user_folder_icon_normalized.xml b/res/layout/user_folder_icon_normalized.xml index c230dadd8f..d38a77a623 100644 --- a/res/layout/user_folder_icon_normalized.xml +++ b/res/layout/user_folder_icon_normalized.xml @@ -27,15 +27,12 @@ android:clipToPadding="false" android:layout_width="match_parent" android:layout_height="match_parent" - android:paddingLeft="16dp" - android:paddingRight="16dp" - android:paddingTop="16dp" launcher:pageIndicator="@+id/folder_page_indicator" /> + android:textColorHint="?attr/folderHintColor"/> + + @@ -150,6 +152,12 @@ + + + + + + diff --git a/res/values/config.xml b/res/values/config.xml index 41d1a12059..89415b89a3 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -24,7 +24,7 @@ - 90 + 85 50 diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 5f78192f28..3b171c6918 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -20,6 +20,7 @@ 8dp + 8dp 7dp 8dp @@ -27,7 +28,6 @@ 16dp 5.5dp 8dp - 7dp 8dp @@ -37,6 +37,9 @@ 34dp 0dp + + 22dp + 24dp 1dp @@ -90,7 +93,6 @@ 2dp - 3dp 16dp @@ -148,10 +150,12 @@ 9dp 6dp - 13sp - 12dp - 12dp - 16sp + + 1.14 + 48dp + + 8dp + 16dp 24dp diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java index 20c9ad366c..a8132755b2 100644 --- a/src/com/android/launcher3/AppWidgetResizeFrame.java +++ b/src/com/android/launcher3/AppWidgetResizeFrame.java @@ -3,7 +3,6 @@ package com.android.launcher3; import static com.android.launcher3.LauncherAnimUtils.LAYOUT_HEIGHT; import static com.android.launcher3.LauncherAnimUtils.LAYOUT_WIDTH; import static com.android.launcher3.Utilities.ATLEAST_S; -import static com.android.launcher3.config.FeatureFlags.ENABLE_FOUR_COLUMNS; import static com.android.launcher3.views.BaseDragLayer.LAYOUT_X; import static com.android.launcher3.views.BaseDragLayer.LAYOUT_Y; @@ -51,6 +50,14 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O inv.portraitProfile.getCellSize()}; }); + // Represents the border spacing size on the grid in the two orientations. + public static final MainThreadInitializedObject BORDER_SPACING_SIZE = + new MainThreadInitializedObject<>(c -> { + InvariantDeviceProfile inv = LauncherAppState.getIDP(c); + return new int[] {inv.landscapeProfile.cellLayoutBorderSpacingPx, + inv.portraitProfile.cellLayoutBorderSpacingPx}; + }); + private static final int HANDLE_COUNT = 4; private static final int INDEX_LEFT = 0; private static final int INDEX_TOP = 1; @@ -371,16 +378,12 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O } } - private static PointF getWidgetSize(Context context, Point cellSize, int spanX, int spanY) { + private static PointF getWidgetSize(Context context, Point cellSize, int spanX, int spanY, + int borderSpacing) { final float density = context.getResources().getDisplayMetrics().density; - float hBorderSpacing = 0; - float vBorderSpacing = 0; - if (ENABLE_FOUR_COLUMNS.get()) { - final int borderSpacing = context.getResources() - .getDimensionPixelSize(R.dimen.dynamic_grid_cell_border_spacing); - hBorderSpacing = (spanX - 1) * borderSpacing; - vBorderSpacing = (spanY - 1) * borderSpacing; - } + final float hBorderSpacing = (spanX - 1) * borderSpacing; + final float vBorderSpacing = (spanY - 1) * borderSpacing; + PointF widgetSize = new PointF(); widgetSize.x = ((spanX * cellSize.x) + hBorderSpacing) / density; widgetSize.y = ((spanY * cellSize.y) + vBorderSpacing) / density; @@ -390,10 +393,11 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O /** Returns the actual widget size given its span. */ public static PointF getWidgetSize(Context context, int spanX, int spanY) { final Point[] cellSize = CELL_SIZE.get(context); + final int[] borderSpacing = BORDER_SPACING_SIZE.get(context); if (isLandscape(context)) { - return getWidgetSize(context, cellSize[0], spanX, spanY); + return getWidgetSize(context, cellSize[0], spanX, spanY, borderSpacing[0]); } - return getWidgetSize(context, cellSize[1], spanX, spanY); + return getWidgetSize(context, cellSize[1], spanX, spanY, borderSpacing[1]); } /** Returns true if the screen is in landscape mode. */ @@ -405,9 +409,10 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O /** Returns the list of sizes for a widget of given span, in dp. */ public static ArrayList getWidgetSizes(Context context, int spanX, int spanY) { final Point[] cellSize = CELL_SIZE.get(context); + final int[] borderSpacing = BORDER_SPACING_SIZE.get(context); - PointF landSize = getWidgetSize(context, cellSize[0], spanX, spanY); - PointF portSize = getWidgetSize(context, cellSize[1], spanX, spanY); + PointF landSize = getWidgetSize(context, cellSize[0], spanX, spanY, borderSpacing[0]); + PointF portSize = getWidgetSize(context, cellSize[1], spanX, spanY, borderSpacing[1]); ArrayList sizes = new ArrayList<>(2); sizes.add(landSize); diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index ee4d7ecb55..e0be6de793 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -17,7 +17,6 @@ package com.android.launcher3; import static com.android.launcher3.FastBitmapDrawable.newIcon; -import static com.android.launcher3.config.FeatureFlags.ENABLE_FOUR_COLUMNS; import static com.android.launcher3.graphics.IconShape.getShape; import static com.android.launcher3.graphics.PreloadIconDrawable.newPendingIcon; import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; @@ -194,7 +193,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.iconTextSizePx); setCompoundDrawablePadding(grid.iconDrawablePaddingPx); defaultIconSize = grid.iconSizePx; - setCenterVertically(ENABLE_FOUR_COLUMNS.get()); + setCenterVertically(grid.isScalableGrid); } else if (mDisplay == DISPLAY_ALL_APPS) { setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx); setCompoundDrawablePadding(grid.allAppsIconDrawablePaddingPx); diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 634093c141..7a9f852960 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -16,7 +16,7 @@ package com.android.launcher3; -import static com.android.launcher3.config.FeatureFlags.ENABLE_FOUR_COLUMNS; +import static com.android.launcher3.ResourceUtils.pxFromDp; import android.content.Context; import android.content.res.Configuration; @@ -66,6 +66,8 @@ public class DeviceProfile { public final float aspectRatio; + public final boolean isScalableGrid; + /** * The maximum amount of left/right workspace padding as a percentage of the screen width. * To be clear, this means that up to 7% of the screen width can be used as left padding, and @@ -79,8 +81,10 @@ public class DeviceProfile { private static final int PORTRAIT_TABLET_LEFT_RIGHT_PADDING_MULTIPLIER = 4; // Workspace - public final int desiredWorkspaceLeftRightMarginPx; - public final int cellLayoutBorderSpacingPx; + public final int desiredWorkspaceLeftRightOriginalPx; + public int desiredWorkspaceLeftRightMarginPx; + public final int cellLayoutBorderSpacingOriginalPx; + public int cellLayoutBorderSpacingPx; public final int cellLayoutPaddingLeftRightPx; public final int cellLayoutBottomPaddingPx; public final int edgeMarginPx; @@ -102,13 +106,21 @@ public class DeviceProfile { public int cellWidthPx; public int cellHeightPx; - public int cellYPaddingPx; public int workspaceCellPaddingXPx; + public int cellYPaddingPx; + public int cellYPaddingOriginalPx; + // Folder + public float folderLabelTextScale; + public int folderLabelTextSizePx; public int folderIconSizePx; public int folderIconOffsetYPx; + // Folder content + public int folderContentPaddingLeftRight; + public int folderContentPaddingTop; + // Folder cell public int folderCellWidthPx; public int folderCellHeightPx; @@ -164,9 +176,12 @@ public class DeviceProfile { this.inv = inv; this.isLandscape = isLandscape; this.isMultiWindowMode = isMultiWindowMode; + this.transposeLayoutWithOrientation = transposeLayoutWithOrientation; windowX = windowPosition.x; windowY = windowPosition.y; + isScalableGrid = inv.isScalable && !isVerticalBarLayout() && !isMultiWindowMode; + // Determine sizes. widthPx = width; heightPx = height; @@ -193,8 +208,6 @@ public class DeviceProfile { boolean isTallDevice = Float.compare(aspectRatio, TALL_DEVICE_ASPECT_RATIO_THRESHOLD) >= 0; // Some more constants - this.transposeLayoutWithOrientation = transposeLayoutWithOrientation; - context = getContext(context, info, isVerticalBarLayout() ? Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT); @@ -217,16 +230,25 @@ public class DeviceProfile { availableHeightPx = nonFinalAvailableHeightPx; edgeMarginPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin); - desiredWorkspaceLeftRightMarginPx = isVerticalBarLayout() ? 0 : edgeMarginPx; - cellYPaddingPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_y); - cellLayoutBorderSpacingPx = isVerticalBarLayout() - || isMultiWindowMode - || !ENABLE_FOUR_COLUMNS.get() - ? 0 : res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_border_spacing); + desiredWorkspaceLeftRightMarginPx = isVerticalBarLayout() ? 0 : isScalableGrid + ? res.getDimensionPixelSize(R.dimen.scalable_grid_left_right_margin) + : res.getDimensionPixelSize(R.dimen.dynamic_grid_left_right_margin); + desiredWorkspaceLeftRightOriginalPx = desiredWorkspaceLeftRightMarginPx; + + folderLabelTextScale = res.getFloat(R.dimen.folder_label_text_scale); + folderContentPaddingLeftRight = + res.getDimensionPixelSize(R.dimen.folder_content_padding_left_right); + folderContentPaddingTop = res.getDimensionPixelSize(R.dimen.folder_content_padding_top); + + setCellLayoutBorderSpacing(pxFromDp(inv.borderSpacing, mInfo.metrics, 1f)); + cellLayoutBorderSpacingOriginalPx = cellLayoutBorderSpacingPx; + int cellLayoutPaddingLeftRightMultiplier = !isVerticalBarLayout() && isTablet ? PORTRAIT_TABLET_LEFT_RIGHT_PADDING_MULTIPLIER : 1; - int cellLayoutPadding = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_layout_padding); + int cellLayoutPadding = isScalableGrid + ? 0 + : res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_layout_padding); if (isLandscape) { cellLayoutPaddingLeftRightPx = 0; cellLayoutBottomPaddingPx = cellLayoutPadding; @@ -259,16 +281,16 @@ public class DeviceProfile { hotseatBarSidePaddingStartPx = isVerticalBarLayout() ? workspacePageIndicatorHeight : 0; int hotseatExtraVerticalSize = res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_extra_vertical_size); - hotseatBarSizePx = ResourceUtils.pxFromDp(inv.iconSize, mInfo.metrics) + hotseatBarSizePx = pxFromDp(inv.iconSize, mInfo.metrics, 1f) + (isVerticalBarLayout() ? (hotseatBarSidePaddingStartPx + hotseatBarSidePaddingEndPx) : (hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx - + (ENABLE_FOUR_COLUMNS.get() ? 0 : hotseatExtraVerticalSize))); + + (isScalableGrid ? 0 : hotseatExtraVerticalSize))); // Calculate all of the remaining variables. int extraSpace = updateAvailableDimensions(res); // Now that we have all of the variables calculated, we can tune certain sizes. - if (ENABLE_FOUR_COLUMNS.get()) { + if (isScalableGrid) { DevicePadding padding = inv.devicePaddings.getDevicePadding(extraSpace); workspaceTopPadding = padding.getWorkspaceTopPadding(extraSpace); workspaceBottomPadding = padding.getWorkspaceBottomPadding(extraSpace); @@ -299,6 +321,17 @@ public class DeviceProfile { IconShape.DEFAULT_PATH_SIZE); } + private void setCellLayoutBorderSpacing(int borderSpacing) { + if (isScalableGrid) { + cellLayoutBorderSpacingPx = borderSpacing; + folderContentPaddingLeftRight = borderSpacing; + folderContentPaddingTop = borderSpacing; + } else { + cellLayoutBorderSpacingPx = 0; + } + } + + public Builder toBuilder(Context context) { Point size = new Point(availableWidthPx, availableHeightPx); return new Builder(context, inv, mInfo) @@ -380,20 +413,42 @@ public class DeviceProfile { private int updateAvailableDimensions(Resources res) { updateIconSize(1f, res); - // Check to see if the icons fit within the available height. If not, then scale down. - float usedHeight = (cellHeightPx * inv.numRows) - + (cellLayoutBorderSpacingPx * (inv.numRows - 1)); - int maxHeight = (availableHeightPx - getTotalWorkspacePadding().y); + Point workspacePadding = getTotalWorkspacePadding(); + + // Check to see if the icons fit within the available height. + float usedHeight = getCellLayoutHeight(); + final int maxHeight = availableHeightPx - workspacePadding.y; float extraHeight = Math.max(0, maxHeight - usedHeight); - if (usedHeight > maxHeight) { - float scale = maxHeight / usedHeight; - updateIconSize(scale, res); - extraHeight = 0; + float scaleY = maxHeight / usedHeight; + boolean shouldScale = scaleY < 1f; + + float scaleX = 1f; + if (isScalableGrid) { + // We scale to fit the cellWidth and cellHeight in the available space. + // The benefit of scalable grids is that we can get consistent aspect ratios between + // devices. + float usedWidth = (cellWidthPx * inv.numColumns) + + (cellLayoutBorderSpacingPx * (inv.numColumns - 1)) + + (desiredWorkspaceLeftRightMarginPx * 2); + // We do not subtract padding here, as we also scale the workspace padding if needed. + scaleX = availableWidthPx / usedWidth; + shouldScale = true; } + + if (shouldScale) { + float scale = Math.min(scaleX, scaleY); + updateIconSize(scale, res); + extraHeight = Math.max(0, maxHeight - getCellLayoutHeight()); + } + updateAvailableFolderCellDimensions(res); return Math.round(extraHeight); } + private int getCellLayoutHeight() { + return (cellHeightPx * inv.numRows) + (cellLayoutBorderSpacingPx * (inv.numRows - 1)); + } + /** * Updating the iconSize affects many aspects of the launcher layout, such as: iconSizePx, * iconTextSizePx, iconDrawablePaddingPx, cellWidth/Height, allApps* variants, @@ -403,17 +458,21 @@ public class DeviceProfile { // Workspace final boolean isVerticalLayout = isVerticalBarLayout(); float invIconSizeDp = isVerticalLayout ? inv.landscapeIconSize : inv.iconSize; - iconSizePx = Math.max(1, (int) (ResourceUtils.pxFromDp(invIconSizeDp, mInfo.metrics) - * scale)); - iconTextSizePx = (int) (Utilities.pxFromSp(inv.iconTextSize, mInfo.metrics) * scale); + iconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mInfo.metrics, scale)); + iconTextSizePx = pxFromDp(inv.iconTextSize, mInfo.metrics, scale); iconDrawablePaddingPx = (int) (iconDrawablePaddingOriginalPx * scale); - if (ENABLE_FOUR_COLUMNS.get()) { - cellHeightPx = iconSizePx + iconDrawablePaddingPx - + Utilities.calculateTextHeight(iconTextSizePx) - + (cellYPaddingPx * 2); + setCellLayoutBorderSpacing((int) (cellLayoutBorderSpacingOriginalPx * scale)); + + if (isScalableGrid) { + cellWidthPx = pxFromDp(inv.minCellWidth, mInfo.metrics, scale); + cellHeightPx = pxFromDp(inv.minCellHeight, mInfo.metrics, scale); + int cellContentHeight = iconSizePx + iconDrawablePaddingPx + + Utilities.calculateTextHeight(iconTextSizePx); + cellYPaddingPx = Math.max(0, cellHeightPx - cellContentHeight) / 2; + desiredWorkspaceLeftRightMarginPx = (int) (desiredWorkspaceLeftRightOriginalPx * scale); } else { - cellYPaddingPx = 0; + cellWidthPx = iconSizePx + iconDrawablePaddingPx; cellHeightPx = iconSizePx + iconDrawablePaddingPx + Utilities.calculateTextHeight(iconTextSizePx); int cellPaddingY = (getCellSize().y - cellHeightPx) / 2; @@ -426,11 +485,10 @@ public class DeviceProfile { iconDrawablePaddingPx = cellPaddingY; } } - cellWidthPx = iconSizePx + iconDrawablePaddingPx; // All apps if (allAppsHasDifferentNumColumns()) { - allAppsIconSizePx = ResourceUtils.pxFromDp(inv.allAppsIconSize, mInfo.metrics); + allAppsIconSizePx = pxFromDp(inv.allAppsIconSize, mInfo.metrics); allAppsIconTextSizePx = Utilities.pxFromSp(inv.allAppsIconTextSize, mInfo.metrics); allAppsIconDrawablePaddingPx = iconDrawablePaddingOriginalPx; // We use 4 below to ensure labels are closer to their corresponding icon. @@ -474,12 +532,10 @@ public class DeviceProfile { } private void updateAvailableFolderCellDimensions(Resources res) { - int folderBottomPanelSize = res.getDimensionPixelSize(R.dimen.folder_label_padding_top) - + res.getDimensionPixelSize(R.dimen.folder_label_padding_bottom) - + Utilities.calculateTextHeight(res.getDimension(R.dimen.folder_label_text_size)); - updateFolderCellSize(1f, res); + final int folderBottomPanelSize = res.getDimensionPixelSize(R.dimen.folder_label_height); + // Don't let the folder get too close to the edges of the screen. int folderMargin = edgeMarginPx * 2; Point totalWorkspacePadding = getTotalWorkspacePadding(); @@ -488,13 +544,14 @@ public class DeviceProfile { float contentUsedHeight = folderCellHeightPx * inv.numFolderRows + ((inv.numFolderRows - 1) * cellLayoutBorderSpacingPx); int contentMaxHeight = availableHeightPx - totalWorkspacePadding.y - folderBottomPanelSize - - folderMargin; + - folderMargin - folderContentPaddingTop; float scaleY = contentMaxHeight / contentUsedHeight; // Check if the icons fit within the available width. float contentUsedWidth = folderCellWidthPx * inv.numFolderColumns + ((inv.numFolderColumns - 1) * cellLayoutBorderSpacingPx); - int contentMaxWidth = availableWidthPx - totalWorkspacePadding.x - folderMargin; + int contentMaxWidth = availableWidthPx - totalWorkspacePadding.x - folderMargin + - folderContentPaddingLeftRight * 2; float scaleX = contentMaxWidth / contentUsedWidth; float scale = Math.min(scaleX, scaleY); @@ -504,9 +561,10 @@ public class DeviceProfile { } private void updateFolderCellSize(float scale, Resources res) { - folderChildIconSizePx = (int) (ResourceUtils.pxFromDp(inv.iconSize, mInfo.metrics) * scale); - folderChildTextSizePx = - (int) (res.getDimensionPixelSize(R.dimen.folder_child_text_size) * scale); + float invIconSizeDp = isVerticalBarLayout() ? inv.landscapeIconSize : inv.iconSize; + folderChildIconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mInfo.metrics, scale)); + folderChildTextSizePx = pxFromDp(inv.iconTextSize, mInfo.metrics, scale); + folderLabelTextSizePx = (int) (folderChildTextSizePx * folderLabelTextScale); int textHeight = Utilities.calculateTextHeight(folderChildTextSizePx); int cellPaddingX = (int) (res.getDimensionPixelSize(R.dimen.folder_cell_x_padding) * scale); @@ -588,7 +646,7 @@ public class DeviceProfile { } else { // Pad the top and bottom of the workspace with search/hotseat bar sizes padding.set(desiredWorkspaceLeftRightMarginPx, - workspaceTopPadding + edgeMarginPx, + workspaceTopPadding + (isScalableGrid ? 0 : edgeMarginPx), desiredWorkspaceLeftRightMarginPx, paddingBottom); } diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 2a08c50008..bb60557122 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -111,6 +111,10 @@ public class InvariantDeviceProfile { public float allAppsIconSize; public float allAppsIconTextSize; + public float minCellHeight; + public float minCellWidth; + public float borderSpacing; + private SparseArray mExtraAttrs; /** @@ -123,6 +127,11 @@ public class InvariantDeviceProfile { */ public int numAllAppsColumns; + /** + * Do not query directly. see {@link DeviceProfile#isScalableGrid}. + */ + protected boolean isScalable; + public String dbFile; public int defaultLayoutId; int demoModeLayoutId; @@ -154,6 +163,10 @@ public class InvariantDeviceProfile { iconTextSize = p.iconTextSize; numHotseatIcons = p.numHotseatIcons; numAllAppsColumns = p.numAllAppsColumns; + isScalable = p.isScalable; + minCellHeight = p.minCellHeight; + minCellWidth = p.minCellWidth; + borderSpacing = p.borderSpacing; dbFile = p.dbFile; allAppsIconSize = p.allAppsIconSize; allAppsIconTextSize = p.allAppsIconTextSize; @@ -213,6 +226,9 @@ public class InvariantDeviceProfile { result.landscapeIconSize = defaultDisplayOption.landscapeIconSize; result.allAppsIconSize = Math.min( defaultDisplayOption.allAppsIconSize, myDisplayOption.allAppsIconSize); + result.minCellHeight = defaultDisplayOption.minCellHeight; + result.minCellWidth = defaultDisplayOption.minCellWidth; + result.borderSpacing = defaultDisplayOption.borderSpacing; devicePaddings = new DevicePaddings(context); initGrid(context, myInfo, result); @@ -259,6 +275,7 @@ public class InvariantDeviceProfile { numFolderRows = closestProfile.numFolderRows; numFolderColumns = closestProfile.numFolderColumns; numAllAppsColumns = closestProfile.numAllAppsColumns; + isScalable = closestProfile.isScalable; mExtraAttrs = closestProfile.extraAttrs; @@ -269,6 +286,10 @@ public class InvariantDeviceProfile { iconTextSize = displayOption.iconTextSize; fillResIconDpi = getLauncherIconDensity(iconBitmapSize); + minCellHeight = displayOption.minCellHeight; + minCellWidth = displayOption.minCellWidth; + borderSpacing = displayOption.borderSpacing; + if (Utilities.isGridOptionsEnabled(context)) { allAppsIconSize = displayOption.allAppsIconSize; allAppsIconTextSize = displayOption.allAppsIconTextSize; @@ -589,6 +610,8 @@ public class InvariantDeviceProfile { private final int defaultLayoutId; private final int demoModeLayoutId; + private final boolean isScalable; + private final SparseArray extraAttrs; public GridOption(Context context, AttributeSet attrs) { @@ -612,6 +635,9 @@ public class InvariantDeviceProfile { numAllAppsColumns = a.getInt( R.styleable.GridDisplayOption_numAllAppsColumns, numColumns); + isScalable = a.getBoolean( + R.styleable.GridDisplayOption_isScalable, false); + a.recycle(); extraAttrs = Themes.createValueMap(context, attrs, @@ -626,6 +652,10 @@ public class InvariantDeviceProfile { private final float minHeightDps; private final boolean canBeDefault; + private float minCellHeight; + private float minCellWidth; + private float borderSpacing; + private float iconSize; private float iconTextSize; private float landscapeIconSize; @@ -643,6 +673,10 @@ public class InvariantDeviceProfile { canBeDefault = a.getBoolean( R.styleable.ProfileDisplayOption_canBeDefault, false); + minCellHeight = a.getFloat(R.styleable.ProfileDisplayOption_minCellHeightDps, 0); + minCellWidth = a.getFloat(R.styleable.ProfileDisplayOption_minCellWidthDps, 0); + borderSpacing = a.getFloat(R.styleable.ProfileDisplayOption_borderSpacingDps, 0); + iconSize = a.getFloat(R.styleable.ProfileDisplayOption_iconImageSize, 0); landscapeIconSize = a.getFloat(R.styleable.ProfileDisplayOption_landscapeIconSize, iconSize); @@ -664,6 +698,9 @@ public class InvariantDeviceProfile { minWidthDps = 0; minHeightDps = 0; canBeDefault = false; + minCellHeight = 0; + minCellWidth = 0; + borderSpacing = 0; } private DisplayOption multiply(float w) { @@ -672,6 +709,9 @@ public class InvariantDeviceProfile { allAppsIconSize *= w; iconTextSize *= w; allAppsIconTextSize *= w; + minCellHeight *= w; + minCellWidth *= w; + borderSpacing *= w; return this; } @@ -681,6 +721,9 @@ public class InvariantDeviceProfile { allAppsIconSize += p.allAppsIconSize; iconTextSize += p.iconTextSize; allAppsIconTextSize += p.allAppsIconTextSize; + minCellHeight += p.minCellHeight; + minCellWidth += p.minCellWidth; + borderSpacing += p.borderSpacing; return this; } } diff --git a/src/com/android/launcher3/ResourceUtils.java b/src/com/android/launcher3/ResourceUtils.java index f60e1f8137..ece123dc62 100644 --- a/src/com/android/launcher3/ResourceUtils.java +++ b/src/com/android/launcher3/ResourceUtils.java @@ -60,7 +60,11 @@ public class ResourceUtils { } public static int pxFromDp(float size, DisplayMetrics metrics) { - return size < 0 ? INVALID_RESOURCE_HANDLE : Math.round( - TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, size, metrics)); + return pxFromDp(size, metrics, 1f); + } + + public static int pxFromDp(float size, DisplayMetrics metrics, float scale) { + return size < 0 ? INVALID_RESOURCE_HANDLE : Math.round(scale + * TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, size, metrics)); } } diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index 504b29e75a..bcb3a54ef3 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -44,6 +44,7 @@ import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; import android.util.Pair; +import android.util.TypedValue; import android.view.FocusFinder; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -246,11 +247,16 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo @Override protected void onFinishInflate() { super.onFinishInflate(); + final DeviceProfile dp = mLauncher.getDeviceProfile(); + final int paddingLeftRight = dp.folderContentPaddingLeftRight; + mContent = findViewById(R.id.folder_content); + mContent.setPadding(paddingLeftRight, dp.folderContentPaddingTop, paddingLeftRight, 0); mContent.setFolder(this); mPageIndicator = findViewById(R.id.folder_page_indicator); mFolderName = findViewById(R.id.folder_name); + mFolderName.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp.folderLabelTextSizePx); mFolderName.setOnBackKeyListener(this); mFolderName.setOnFocusChangeListener(this); mFolderName.setOnEditorActionListener(this); @@ -262,12 +268,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo mFolderName.forceDisableSuggestions(true); mFooter = findViewById(R.id.folder_footer); - - // We find out how tall footer wants to be (it is set to wrap_content), so that - // we can allocate the appropriate amount of space for it. - int measureSpec = MeasureSpec.UNSPECIFIED; - mFooter.measure(measureSpec, measureSpec); - mFooterHeight = mFooter.getMeasuredHeight(); + mFooterHeight = getResources().getDimensionPixelSize(R.dimen.folder_label_height); if (Utilities.ATLEAST_R) { mFolderWindowInsetsAnimationCallback = diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java index 1cac31eb18..feb528c96f 100644 --- a/src/com/android/launcher3/folder/FolderAnimationManager.java +++ b/src/com/android/launcher3/folder/FolderAnimationManager.java @@ -324,7 +324,9 @@ public class FolderAnimationManager { final int previewPosX = (int) ((mTmpParams.transX - iconOffsetX + previewItemOffsetX) / folderScale); - final int previewPosY = (int) ((mTmpParams.transY + previewItemOffsetY) / folderScale); + final float paddingTop = btv.getPaddingTop() * iconScale; + final int previewPosY = (int) ((mTmpParams.transY + previewItemOffsetY - paddingTop) + / folderScale); final float xDistance = previewPosX - btvLp.x; final float yDistance = previewPosY - btvLp.y;