diff --git a/res/layout/user_folder_icon_normalized.xml b/res/layout/user_folder_icon_normalized.xml index 39f93d939b..5518dc88a3 100644 --- a/res/layout/user_folder_icon_normalized.xml +++ b/res/layout/user_folder_icon_normalized.xml @@ -30,11 +30,11 @@ + android:paddingLeft="@dimen/folder_footer_horiz_padding" + android:paddingRight="@dimen/folder_footer_horiz_padding"> 300dp + + + 24dp diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 283c793e26..f270b1047a 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -141,9 +141,12 @@ + + + - - - - - - - - - - - - @@ -394,6 +384,22 @@ + + + + + + + + + + + + + + diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 8f48ec8b2a..033346afdb 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -255,7 +255,7 @@ 6dp 1.14 - 56dp + 56dp 8dp 16dp @@ -441,4 +441,8 @@ 0.97 + + + 24dp + 20dp diff --git a/res/values/styles.xml b/res/values/styles.xml index d0be420a1a..9e75a31804 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -309,4 +309,13 @@ true true + + + diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index de2a1f91ed..2103593873 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -373,7 +373,8 @@ public class CellLayout extends ViewGroup { private void resetCellSizeInternal(DeviceProfile deviceProfile) { switch (mContainerType) { case FOLDER: - mBorderSpace = new Point(deviceProfile.folderCellLayoutBorderSpacePx); + mBorderSpace = new Point(deviceProfile.folderCellLayoutBorderSpacePx, + deviceProfile.folderCellLayoutBorderSpacePx); break; case HOTSEAT: mBorderSpace = new Point(deviceProfile.hotseatBorderSpace, diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 2b9eb29051..c91e3ebcf4 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -25,12 +25,14 @@ import static com.android.launcher3.Utilities.pxFromSp; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR; import static com.android.launcher3.icons.GraphicsUtils.getShapePath; +import static com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE; import static com.android.launcher3.testing.shared.ResourceUtils.pxFromDp; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; +import android.content.res.TypedArray; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; @@ -61,6 +63,7 @@ public class DeviceProfile { private static final int DEFAULT_DOT_SIZE = 100; private static final float ALL_APPS_TABLET_MAX_ROWS = 5.5f; + private static final float MIN_FOLDER_TEXT_SIZE_SP = 16f; public static final PointF DEFAULT_SCALE = new PointF(1.0f, 1.0f); public static final ViewScaleProvider DEFAULT_PROVIDER = itemInfo -> DEFAULT_SCALE; @@ -147,11 +150,12 @@ public class DeviceProfile { // Folder public float folderLabelTextScale; public int folderLabelTextSizePx; + public int folderFooterHeightPx; public int folderIconSizePx; public int folderIconOffsetYPx; // Folder content - public Point folderCellLayoutBorderSpacePx; + public int folderCellLayoutBorderSpacePx; public int folderContentPaddingLeftRight; public int folderContentPaddingTop; @@ -352,17 +356,34 @@ public class DeviceProfile { } 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); + + if (inv.folderStyle != INVALID_RESOURCE_HANDLE) { + TypedArray folderStyle = context.obtainStyledAttributes(inv.folderStyle, + R.styleable.FolderDisplayStyle); + // These are re-set in #updateFolderCellSize if the grid is not scalable + folderCellHeightPx = folderStyle.getDimensionPixelSize( + R.styleable.FolderDisplayStyle_folderCellHeight, 0); + folderCellWidthPx = folderStyle.getDimensionPixelSize( + R.styleable.FolderDisplayStyle_folderCellWidth, 0); + + folderContentPaddingTop = folderStyle.getDimensionPixelSize( + R.styleable.FolderDisplayStyle_folderTopPadding, 0); + folderCellLayoutBorderSpacePx = folderStyle.getDimensionPixelSize( + R.styleable.FolderDisplayStyle_folderBorderSpace, 0); + folderFooterHeightPx = folderStyle.getDimensionPixelSize( + R.styleable.FolderDisplayStyle_folderFooterHeight, 0); + folderStyle.recycle(); + } else { + folderCellLayoutBorderSpacePx = 0; + folderFooterHeightPx = 0; + folderContentPaddingTop = res.getDimensionPixelSize(R.dimen.folder_top_padding_default); + } cellLayoutBorderSpacePx = getCellLayoutBorderSpace(inv); + cellLayoutBorderSpaceOriginalPx = new Point(cellLayoutBorderSpacePx); allAppsBorderSpacePx = new Point( pxFromDp(inv.allAppsBorderSpaces[mTypeIndex].x, mMetrics), pxFromDp(inv.allAppsBorderSpaces[mTypeIndex].y, mMetrics)); - cellLayoutBorderSpaceOriginalPx = new Point(cellLayoutBorderSpacePx); - folderCellLayoutBorderSpacePx = new Point(pxFromDp(inv.folderBorderSpaces.x, mMetrics), - pxFromDp(inv.folderBorderSpaces.y, mMetrics)); workspacePageIndicatorHeight = res.getDimensionPixelSize( R.dimen.workspace_page_indicator_height); @@ -931,22 +952,20 @@ public class DeviceProfile { private void updateAvailableFolderCellDimensions(Resources res) { 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(); // Check if the icons fit within the available height. float contentUsedHeight = folderCellHeightPx * inv.numFolderRows - + ((inv.numFolderRows - 1) * folderCellLayoutBorderSpacePx.y); - int contentMaxHeight = availableHeightPx - totalWorkspacePadding.y - folderBottomPanelSize + + ((inv.numFolderRows - 1) * folderCellLayoutBorderSpacePx); + int contentMaxHeight = availableHeightPx - totalWorkspacePadding.y - folderFooterHeightPx - folderMargin - folderContentPaddingTop; float scaleY = contentMaxHeight / contentUsedHeight; // Check if the icons fit within the available width. float contentUsedWidth = folderCellWidthPx * inv.numFolderColumns - + ((inv.numFolderColumns - 1) * folderCellLayoutBorderSpacePx.x); + + ((inv.numFolderColumns - 1) * folderCellLayoutBorderSpacePx); int contentMaxWidth = availableWidthPx - totalWorkspacePadding.x - folderMargin - folderContentPaddingLeftRight * 2; float scaleX = contentMaxWidth / contentUsedWidth; @@ -964,19 +983,18 @@ public class DeviceProfile { folderChildIconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, scale)); folderChildTextSizePx = pxFromSp(inv.iconTextSize[INDEX_DEFAULT], mMetrics, scale); - folderLabelTextSizePx = (int) (folderChildTextSizePx * folderLabelTextScale); + folderLabelTextSizePx = Math.max(pxFromSp(MIN_FOLDER_TEXT_SIZE_SP, mMetrics), + (int) (folderChildTextSizePx * folderLabelTextScale)); int textHeight = Utilities.calculateTextHeight(folderChildTextSizePx); if (isScalableGrid) { - folderCellWidthPx = pxFromDp(inv.folderCellSize.x, mMetrics, scale); - folderCellHeightPx = pxFromDp(inv.folderCellSize.y, mMetrics, scale); + if (inv.folderStyle == INVALID_RESOURCE_HANDLE) { + folderCellWidthPx = pxFromDp(getCellSize().x, mMetrics, scale); + folderCellHeightPx = pxFromDp(getCellSize().y, mMetrics, scale); + } - folderCellLayoutBorderSpacePx = new Point( - pxFromDp(inv.folderBorderSpaces.x, mMetrics, scale), - pxFromDp(inv.folderBorderSpaces.y, mMetrics, scale)); - folderContentPaddingLeftRight = folderCellLayoutBorderSpacePx.x; - folderContentPaddingTop = pxFromDp(inv.folderTopPadding, mMetrics, scale); + folderContentPaddingLeftRight = folderCellLayoutBorderSpacePx; } else { int cellPaddingX = (int) (res.getDimensionPixelSize(R.dimen.folder_cell_x_padding) * scale); @@ -985,6 +1003,10 @@ public class DeviceProfile { folderCellWidthPx = folderChildIconSizePx + 2 * cellPaddingX; folderCellHeightPx = folderChildIconSizePx + 2 * cellPaddingY + textHeight; + folderContentPaddingLeftRight = + res.getDimensionPixelSize(R.dimen.folder_content_padding_left_right); + folderFooterHeightPx = + res.getDimensionPixelSize(R.dimen.folder_footer_height_default); } folderChildDrawablePaddingPx = Math.max(0, @@ -1468,13 +1490,12 @@ public class DeviceProfile { writer.println(prefix + pxToDpStr("folderChildTextSizePx", folderChildTextSizePx)); writer.println(prefix + pxToDpStr("folderChildDrawablePaddingPx", folderChildDrawablePaddingPx)); - writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacePx Horizontal", - folderCellLayoutBorderSpacePx.x)); - writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacePx Vertical", - folderCellLayoutBorderSpacePx.y)); + writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacePx", + folderCellLayoutBorderSpacePx)); writer.println(prefix + pxToDpStr("folderContentPaddingLeftRight", folderContentPaddingLeftRight)); writer.println(prefix + pxToDpStr("folderTopPadding", folderContentPaddingTop)); + writer.println(prefix + pxToDpStr("folderFooterHeight", folderFooterHeightPx)); writer.println(prefix + pxToDpStr("bottomSheetTopPadding", bottomSheetTopPadding)); writer.println(prefix + "\tbottomSheetOpenDuration: " + bottomSheetOpenDuration); diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 635f4007cb..0c6f340cb1 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -18,6 +18,7 @@ package com.android.launcher3; import static com.android.launcher3.Utilities.dpiFromPx; import static com.android.launcher3.config.FeatureFlags.ENABLE_TWO_PANEL_HOME; +import static com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE; import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY; import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE; import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS; @@ -43,8 +44,10 @@ import android.util.TypedValue; import android.util.Xml; import android.view.Display; +import androidx.annotation.DimenRes; import androidx.annotation.IntDef; import androidx.annotation.Nullable; +import androidx.annotation.StyleRes; import androidx.annotation.VisibleForTesting; import androidx.core.content.res.ResourcesCompat; @@ -129,11 +132,9 @@ public class InvariantDeviceProfile { public PointF[] minCellSize; public PointF[] borderSpaces; - public int inlineNavButtonsEndSpacing; + public @DimenRes int inlineNavButtonsEndSpacing; - public PointF folderBorderSpaces; - public PointF folderCellSize; - public float folderTopPadding; + public @StyleRes int folderStyle; public float[] horizontalMargin; @@ -333,8 +334,11 @@ public class InvariantDeviceProfile { dbFile = closestProfile.dbFile; defaultLayoutId = closestProfile.defaultLayoutId; demoModeLayoutId = closestProfile.demoModeLayoutId; + numFolderRows = closestProfile.numFolderRows; numFolderColumns = closestProfile.numFolderColumns; + folderStyle = closestProfile.folderStyle; + isScalable = closestProfile.isScalable; devicePaddingId = closestProfile.devicePaddingId; this.deviceType = deviceType; @@ -357,10 +361,6 @@ public class InvariantDeviceProfile { borderSpaces = displayOption.borderSpaces; - folderBorderSpaces = displayOption.folderBorderSpaces; - folderCellSize = displayOption.folderCellSize; - folderTopPadding = displayOption.folderTopPadding; - horizontalMargin = displayOption.horizontalMargin; numShownHotseatIcons = closestProfile.numHotseatIcons; @@ -749,6 +749,7 @@ public class InvariantDeviceProfile { private final int numFolderRows; private final int numFolderColumns; + private final @StyleRes int folderStyle; private final int numAllAppsColumns; private final int numDatabaseAllAppsColumns; @@ -759,7 +760,7 @@ public class InvariantDeviceProfile { private final boolean[] inlineQsb = new boolean[COUNT_SIZES]; - private int inlineNavButtonsEndSpacing; + private @DimenRes int inlineNavButtonsEndSpacing; private final String dbFile; private final int defaultLayoutId; @@ -811,11 +812,15 @@ public class InvariantDeviceProfile { inlineNavButtonsEndSpacing = a.getResourceId(R.styleable.GridDisplayOption_inlineNavButtonsEndSpacing, R.dimen.taskbar_button_margin_default); + numFolderRows = a.getInt( R.styleable.GridDisplayOption_numFolderRows, numRows); numFolderColumns = a.getInt( R.styleable.GridDisplayOption_numFolderColumns, numColumns); + folderStyle = a.getResourceId(R.styleable.GridDisplayOption_folderStyle, + INVALID_RESOURCE_HANDLE); + isScalable = a.getBoolean( R.styleable.GridDisplayOption_isScalable, false); devicePaddingId = a.getResourceId( @@ -860,10 +865,6 @@ public class InvariantDeviceProfile { private final PointF[] minCellSize = new PointF[COUNT_SIZES]; - private final PointF folderCellSize; - private final PointF folderBorderSpaces; - private float folderTopPadding; - private final PointF[] borderSpaces = new PointF[COUNT_SIZES]; private final float[] horizontalMargin = new float[COUNT_SIZES]; private final float[] hotseatBarBottomSpace = new float[COUNT_SIZES]; @@ -946,21 +947,6 @@ public class InvariantDeviceProfile { borderSpaceTwoPanelLandscape); borderSpaces[INDEX_TWO_PANEL_LANDSCAPE] = new PointF(x, y); - x = a.getFloat(R.styleable.ProfileDisplayOption_folderCellWidth, - minCellSize[INDEX_DEFAULT].x); - y = a.getFloat(R.styleable.ProfileDisplayOption_folderCellHeight, - minCellSize[INDEX_DEFAULT].y); - folderCellSize = new PointF(x, y); - - float folderBorderSpace = a.getFloat(R.styleable.ProfileDisplayOption_folderBorderSpace, - borderSpace); - - x = y = folderBorderSpace; - folderBorderSpaces = new PointF(x, y); - - folderTopPadding = a.getFloat(R.styleable.ProfileDisplayOption_folderTopPadding, - folderBorderSpaces.y); - x = a.getFloat(R.styleable.ProfileDisplayOption_allAppsCellWidth, minCellSize[INDEX_DEFAULT].x); y = a.getFloat(R.styleable.ProfileDisplayOption_allAppsCellHeight, @@ -1133,9 +1119,6 @@ public class InvariantDeviceProfile { allAppsIconTextSizes[i] = 0; allAppsBorderSpaces[i] = new PointF(); } - folderBorderSpaces = new PointF(); - folderCellSize = new PointF(); - folderTopPadding = 0f; } private DisplayOption multiply(float w) { @@ -1156,11 +1139,6 @@ public class InvariantDeviceProfile { allAppsBorderSpaces[i].x *= w; allAppsBorderSpaces[i].y *= w; } - folderBorderSpaces.x *= w; - folderBorderSpaces.y *= w; - folderCellSize.x *= w; - folderCellSize.y *= w; - folderTopPadding *= w; return this; } @@ -1183,11 +1161,6 @@ public class InvariantDeviceProfile { allAppsBorderSpaces[i].x += p.allAppsBorderSpaces[i].x; allAppsBorderSpaces[i].y += p.allAppsBorderSpaces[i].y; } - folderBorderSpaces.x += p.folderBorderSpaces.x; - folderBorderSpaces.y += p.folderBorderSpaces.y; - folderCellSize.x += p.folderCellSize.x; - folderCellSize.y += p.folderCellSize.y; - folderTopPadding += p.folderTopPadding; return this; } diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java index 8b342ea3ee..7a74d7ed1b 100644 --- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java +++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java @@ -152,7 +152,7 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon. // No need to add padding when cell layout border spacing is present. boolean noPaddingX = (dp.cellLayoutBorderSpacePx.x > 0 && mContainerType == WORKSPACE) - || (dp.folderCellLayoutBorderSpacePx.x > 0 && mContainerType == FOLDER) + || (dp.folderCellLayoutBorderSpacePx > 0 && mContainerType == FOLDER) || (dp.hotseatBorderSpace > 0 && mContainerType == HOTSEAT); int cellPaddingX = noPaddingX ? 0 diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index 7e1491287f..99822da4a4 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -292,7 +292,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo mFolderName.forceDisableSuggestions(true); mFooter = findViewById(R.id.folder_footer); - mFooterHeight = getResources().getDimensionPixelSize(R.dimen.folder_label_height); + mFooterHeight = dp.folderFooterHeightPx; if (Utilities.ATLEAST_R) { mKeyboardInsetAnimationCallback = new KeyboardInsetAnimationCallback(this); @@ -1167,14 +1167,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo mContent.setFixedSize(contentWidth, contentHeight); mContent.measure(contentAreaWidthSpec, contentAreaHeightSpec); - if (mContent.getChildCount() > 0) { - int cellIconGap = (mContent.getPageAt(0).getCellWidth() - - mActivityContext.getDeviceProfile().iconSizePx) / 2; - mFooter.setPadding(mContent.getPaddingLeft() + cellIconGap, - mFooter.getPaddingTop(), - mContent.getPaddingRight() + cellIconGap, - mFooter.getPaddingBottom()); - } mFooter.measure(contentAreaWidthSpec, MeasureSpec.makeMeasureSpec(mFooterHeight, MeasureSpec.EXACTLY)); diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java index d5ef9df111..4829c4275e 100644 --- a/src/com/android/launcher3/folder/FolderAnimationManager.java +++ b/src/com/android/launcher3/folder/FolderAnimationManager.java @@ -234,9 +234,9 @@ public class FolderAnimationManager { mFolder, startRect, endRect, finalRadius, !mIsOpening)); // Create reveal animator for the folder content (capture the top 4 icons 2x2) - int width = mDeviceProfile.folderCellLayoutBorderSpacePx.x + int width = mDeviceProfile.folderCellLayoutBorderSpacePx + mDeviceProfile.folderCellWidthPx * 2; - int height = mDeviceProfile.folderCellLayoutBorderSpacePx.y + int height = mDeviceProfile.folderCellLayoutBorderSpacePx + mDeviceProfile.folderCellHeightPx * 2; int page = mIsOpening ? mContent.getCurrentPage() : mContent.getDestinationPage(); int left = mContent.getPaddingLeft() + page * lp.width; diff --git a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt index 2c1cbdf0ce..fe30fdc81d 100644 --- a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt +++ b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt @@ -16,11 +16,12 @@ package com.android.launcher3 import android.content.Context +import android.graphics.Point import android.graphics.PointF import android.graphics.Rect import android.util.SparseArray import androidx.test.core.app.ApplicationProvider -import com.android.launcher3.DeviceProfile.DEFAULT_PROVIDER; +import com.android.launcher3.DeviceProfile.DEFAULT_PROVIDER import com.android.launcher3.util.DisplayController.Info import com.android.launcher3.util.WindowBounds import org.junit.Before @@ -116,10 +117,7 @@ abstract class DeviceProfileBaseTest { numFolderRows = 3 numFolderColumns = 3 - folderBorderSpaces = PointF(16f, 16f) - folderTopPadding = 24f - folderCellSize = PointF(80f, 94f) - + folderStyle = R.style.FolderDefaultStyle inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_4_5 @@ -207,9 +205,7 @@ abstract class DeviceProfileBaseTest { numFolderRows = 3 numFolderColumns = 3 - folderBorderSpaces = PointF(16f, 16f) - folderTopPadding = 24f - folderCellSize = PointF(120f, 104f) + folderStyle = R.style.FolderDefaultStyle inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_6_5 @@ -241,7 +237,7 @@ abstract class DeviceProfileBaseTest { numAllAppsColumns = 6 isScalable = true - devicePaddingId = 2132148242 // "@xml/paddings_6x5" + devicePaddingId = R.xml.paddings_6x5 inlineQsb = booleanArrayOf( false, @@ -305,9 +301,7 @@ abstract class DeviceProfileBaseTest { numFolderRows = 3 numFolderColumns = 3 - folderBorderSpaces = PointF(16f, 16f) - folderTopPadding = 24f - folderCellSize = PointF(80f, 94f) + folderStyle = R.style.FolderDefaultStyle inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_4_4