From 92c1b5d3abaddb040888564c894aa9da29f53df8 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 20 Jul 2021 13:57:16 -0700 Subject: [PATCH] Folder icon polish. - Increase the overlap between the preview items and the background so that it appears more intentional (lots of reports of users thinking that its a bug) - Fix bug where clip path was still clipping icons when dragging and swiping to home. Bug: 193701705 Bug: 191225536 Test: test 2 icon, 3 icon, and 4 icon folders close folder on 2nd page, ensure clipping ensure no preview items are clipped in drag view ensure no preview items are clipped in swipe up to home test 2x2, 3x3, 4x4, 4x5, and 5x5 grids to ensure no clipping of folder icons drag and drop folder in and out of hotseat create folders (2 icon, 3 icon, 4 icon) Merged-In: Id49bae33438e10248bef05450d7e2c92c2140748 Change-Id: Ic3708bd402704f0a6f57ae5315ef602e2bbc6d82 --- src/com/android/launcher3/DeviceProfile.java | 15 ++++++++++----- src/com/android/launcher3/Hotseat.java | 4 ++-- .../launcher3/ShortcutAndWidgetContainer.java | 2 +- .../launcher3/dragndrop/FolderAdaptiveIcon.java | 13 +++++++++++-- .../folder/ClippedFolderIconLayoutRule.java | 4 +++- src/com/android/launcher3/folder/FolderIcon.java | 3 +++ .../launcher3/folder/PreviewBackground.java | 10 ++++++++-- 7 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 88e817111e..5a3e7dd3cc 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -22,6 +22,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static com.android.launcher3.ResourceUtils.pxFromDp; import static com.android.launcher3.Utilities.dpiFromPx; import static com.android.launcher3.Utilities.pxFromSp; +import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR; import static com.android.launcher3.util.WindowManagerCompat.MIN_TABLET_WIDTH; import android.annotation.SuppressLint; @@ -394,7 +395,8 @@ public class DeviceProfile { } private void updateHotseatIconSize(int hotseatIconSizePx) { - hotseatCellHeightPx = hotseatIconSizePx; + // Ensure there is enough space for folder icons, which have a slightly larger radius. + hotseatCellHeightPx = (int) Math.ceil(hotseatIconSizePx * ICON_OVERLAP_FACTOR); if (isVerticalBarLayout()) { hotseatBarSizePx = hotseatIconSizePx + hotseatBarSidePaddingStartPx + hotseatBarSidePaddingEndPx; @@ -473,7 +475,7 @@ public class DeviceProfile { if (workspaceCellPaddingY < iconTextHeight) { iconTextSizePx = 0; iconDrawablePaddingPx = 0; - cellHeightPx = iconSizePx; + cellHeightPx = (int) Math.ceil(iconSizePx * ICON_OVERLAP_FACTOR); autoResizeAllAppsCells(); } } @@ -560,7 +562,8 @@ public class DeviceProfile { desiredWorkspaceLeftRightMarginPx = (int) (desiredWorkspaceLeftRightOriginalPx * scale); } else { cellWidthPx = iconSizePx + iconDrawablePaddingPx; - cellHeightPx = iconSizePx + iconDrawablePaddingPx + cellHeightPx = (int) Math.ceil(iconSizePx * ICON_OVERLAP_FACTOR) + + iconDrawablePaddingPx + Utilities.calculateTextHeight(iconTextSizePx); int cellPaddingY = (getCellSize().y - cellHeightPx) / 2; if (iconDrawablePaddingPx > cellPaddingY && !isVerticalLayout @@ -844,14 +847,16 @@ public class DeviceProfile { return isVerticalBarLayout(); } - public int getCellHeight(@ContainerType int containerType) { + public int getCellContentHeight(@ContainerType int containerType) { switch (containerType) { case CellLayout.WORKSPACE: return cellHeightPx; case CellLayout.FOLDER: return folderCellHeightPx; case CellLayout.HOTSEAT: - return hotseatCellHeightPx; + // The hotseat is the only container where the cell height is going to be + // different from the content within that cell. + return iconSizePx; default: // ?? return 0; diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java index 42b4e89c13..0a6f06c260 100644 --- a/src/com/android/launcher3/Hotseat.java +++ b/src/com/android/launcher3/Hotseat.java @@ -207,8 +207,8 @@ public class Hotseat extends CellLayout implements Insettable { ? dp.workspacePadding.bottom : dp.hotseatBarSizePx - dp.hotseatCellHeightPx - mQsbHeight; - if (dp.isScalableGrid && dp.qsbBottomMarginPx <= freeSpace) { - return dp.qsbBottomMarginPx; + if (dp.isScalableGrid) { + return Math.min(dp.qsbBottomMarginPx, freeSpace); } else { return (int) (freeSpace * QSB_CENTER_FACTOR) + (dp.isTaskbarPresent ? dp.taskbarSize diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java index 2a5187d025..519b63d58e 100644 --- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java +++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java @@ -122,7 +122,7 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon. public int getCellContentHeight() { return Math.min(getMeasuredHeight(), - mActivity.getDeviceProfile().getCellHeight(mContainerType)); + mActivity.getDeviceProfile().getCellContentHeight(mContainerType)); } public void measureChild(View child) { diff --git a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java index ea1fbdb583..98c0cfc3a6 100644 --- a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java +++ b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java @@ -21,11 +21,11 @@ import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import android.annotation.TargetApi; import android.graphics.Bitmap; import android.graphics.Matrix; +import android.graphics.Paint; import android.graphics.Path; import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.AdaptiveIconDrawable; -import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Build; import android.util.Log; @@ -129,10 +129,19 @@ public class FolderAdaptiveIcon extends AdaptiveIconDrawable { canvas.restore(); }); + Bitmap bgBitmap = BitmapRenderer.createHardwareBitmap(dragViewSize.x, dragViewSize.y, + (canvas) -> { + Paint p = new Paint(); + p.setColor(bg.getBgColor()); + + canvas.drawCircle(dragViewSize.x / 2f, dragViewSize.y / 2f, bg.getRadius(), p); + }); + ShiftedBitmapDrawable badge = new ShiftedBitmapDrawable(badgeBmp, 0, 0); ShiftedBitmapDrawable foreground = new ShiftedBitmapDrawable(previewBitmap, 0, 0); + ShiftedBitmapDrawable background = new ShiftedBitmapDrawable(bgBitmap, 0, 0); - return new FolderAdaptiveIcon(new ColorDrawable(bg.getBgColor()), foreground, badge, mask); + return new FolderAdaptiveIcon(background, foreground, badge, mask); } @Override diff --git a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java index 54967a9915..8cd91d3a43 100644 --- a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java +++ b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java @@ -7,7 +7,9 @@ public class ClippedFolderIconLayoutRule { private static final float MIN_SCALE = 0.44f; private static final float MAX_SCALE = 0.51f; - private static final float MAX_RADIUS_DILATION = 0.1f; + private static final float MAX_RADIUS_DILATION = 0.25f; + // The max amount of overlap the preview items can go outside of the background bounds. + public static final float ICON_OVERLAP_FACTOR = 1 + (MAX_RADIUS_DILATION / 2f); private static final float ITEM_RADIUS_SCALE_FACTOR = 1.15f; public static final int EXIT_INDEX = -2; diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index e704957d32..96030f924e 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -16,6 +16,7 @@ package com.android.launcher3.folder; +import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR; import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW; import static com.android.launcher3.folder.PreviewItemManager.INITIAL_ITEM_ANIMATION_DURATION; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_AUTO_LABELED; @@ -236,6 +237,8 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel public void getPreviewBounds(Rect outBounds) { mPreviewItemManager.recomputePreviewDrawingParams(); mBackground.getBounds(outBounds); + // The preview items go outside of the bounds of the background. + Utilities.scaleRectAboutCenter(outBounds, ICON_OVERLAP_FACTOR); } public float getBackgroundStrokeWidth() { diff --git a/src/com/android/launcher3/folder/PreviewBackground.java b/src/com/android/launcher3/folder/PreviewBackground.java index 460521f1a4..18d0b10528 100644 --- a/src/com/android/launcher3/folder/PreviewBackground.java +++ b/src/com/android/launcher3/folder/PreviewBackground.java @@ -16,6 +16,7 @@ package com.android.launcher3.folder; +import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR; import static com.android.launcher3.graphics.IconShape.getShape; import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; @@ -186,7 +187,7 @@ public class PreviewBackground extends CellLayout.DelegatedCellDrawing { outBounds.set(left, top, right, bottom); } - int getRadius() { + public int getRadius() { return previewSize / 2; } @@ -348,7 +349,12 @@ public class PreviewBackground extends CellLayout.DelegatedCellDrawing { public Path getClipPath() { mPath.reset(); - getShape().addToPath(mPath, getOffsetX(), getOffsetY(), getScaledRadius()); + float radius = getScaledRadius() * ICON_OVERLAP_FACTOR; + // Find the difference in radius so that the clip path remains centered. + float radiusDifference = radius - getRadius(); + float offsetX = basePreviewOffsetX - radiusDifference; + float offsetY = basePreviewOffsetY - radiusDifference; + getShape().addToPath(mPath, offsetX, offsetY, radius); return mPath; }