From b8c0595d4220aea479e09094679a1e32fe35b479 Mon Sep 17 00:00:00 2001 From: Thales Lima Date: Mon, 23 May 2022 16:58:38 +0100 Subject: [PATCH] Add new hotseat bottom margin options This changes how the hotseat height is calculated and by consequence how spaces are distributed in the workspace as well. This is the first of a series of changes that will improve and streamline workspace calculations. Bug: 228998463 Fix: 234023782 Fix: 230191631 Fix: 232914299 Fix: 236238226 Test: manual, HSV and comparing to mocks Change-Id: If021e8ba2c7c24c0bf9f27a1aa7aa946792ed04f --- .../taskbar/TaskbarViewController.java | 4 +- .../quickstep/DeviceProfileQuickstepTest.kt | 10 +- res/values/attrs.xml | 18 ++ res/values/config.xml | 5 + res/values/dimens.xml | 9 +- res/xml/device_profiles.xml | 2 + res/xml/paddings_6x5.xml | 49 +--- src/com/android/launcher3/DeviceProfile.java | 209 ++++++++---------- src/com/android/launcher3/Hotseat.java | 4 +- .../launcher3/InvariantDeviceProfile.java | 44 +++- .../WorkspacePageIndicator.java | 2 +- .../launcher3/DeviceProfileBaseTest.kt | 2 + 12 files changed, 180 insertions(+), 178 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 23a03341d3..db7dc78f7b 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -298,9 +298,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar isRtl ? -halfQsbIconWidthDiff : halfQsbIconWidthDiff, hotseatIconCenter - childCenter, LINEAR); - int qsbContentHeight = child.getHeight() - child.getPaddingTop() - - child.getPaddingBottom(); - float scale = ((float) taskbarDp.iconSizePx) / qsbContentHeight; + float scale = ((float) taskbarDp.iconSizePx) / launcherDp.hotseatQsbVisualHeight; setter.addFloat(child, SCALE_PROPERTY, scale, 1f, LINEAR); setter.addFloat(child, VIEW_ALPHA, 0f, 1f, diff --git a/quickstep/tests/src/com/android/quickstep/DeviceProfileQuickstepTest.kt b/quickstep/tests/src/com/android/quickstep/DeviceProfileQuickstepTest.kt index 368dc2ac0c..20b5a64e50 100644 --- a/quickstep/tests/src/com/android/quickstep/DeviceProfileQuickstepTest.kt +++ b/quickstep/tests/src/com/android/quickstep/DeviceProfileQuickstepTest.kt @@ -48,8 +48,8 @@ class DeviceProfileQuickstepTest : DeviceProfileBaseTest() { val dp = newDP() - assertThat(dp.cellLayoutWidth).isEqualTo(1235) - assertThat(dp.cellLayoutHeight).isEqualTo(1235) + assertThat(dp.cellLayoutWidth).isEqualTo(1237) + assertThat(dp.cellLayoutHeight).isEqualTo(1215) } @Test @@ -67,8 +67,8 @@ class DeviceProfileQuickstepTest : DeviceProfileBaseTest() { val dp = newDP() - assertThat(dp.getCellSize().y).isEqualTo(264) - assertThat(dp.getCellSize().x).isEqualTo(258) + assertThat(dp.getCellSize().y).isEqualTo(260) + assertThat(dp.getCellSize().x).isEqualTo(259) } @Test @@ -117,6 +117,6 @@ class DeviceProfileQuickstepTest : DeviceProfileBaseTest() { assertThat(dp.isVerticalBarLayout).isEqualTo(false) assertThat(dp.cellLayoutSpringLoadShrunkTop).isEqualTo(364) - assertThat(dp.cellLayoutSpringLoadShrunkBottom).isEqualTo(2199) + assertThat(dp.cellLayoutSpringLoadShrunkBottom).isEqualTo(2185) } } \ No newline at end of file diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 9f25905514..af8d8eb86a 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -329,6 +329,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/res/values/config.xml b/res/values/config.xml index 9aa1f03734..3f94c34ad8 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -130,6 +130,11 @@ + + + 48 + 0 + diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 39f0a2bc00..5e33de8012 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -32,10 +32,7 @@ 8dp - 8dp - 2dp 0dp - 0dp 76dp @@ -44,13 +41,10 @@ it is close to the bottom of the screen --> 0.325 - - 0dp - 34dp 0dp - 42dp + 8dp 24dp @@ -364,6 +358,7 @@ 0dp 0dp 0dp + 0dp 44dp 8dp diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml index 08025528ce..5ee291b08e 100644 --- a/res/xml/device_profiles.xml +++ b/res/xml/device_profiles.xml @@ -199,6 +199,8 @@ launcher:allAppsBorderSpaceLandscape="16" launcher:hotseatBorderSpace="58" launcher:hotseatBorderSpaceLandscape="50.4" + launcher:hotseatBarBottomSpace="76" + launcher:hotseatBarBottomSpaceLandscape="40" launcher:canBeDefault="true" /> diff --git a/res/xml/paddings_6x5.xml b/res/xml/paddings_6x5.xml index a72f55412c..2f421b78e3 100644 --- a/res/xml/paddings_6x5.xml +++ b/res/xml/paddings_6x5.xml @@ -17,60 +17,29 @@ - + launcher:maxEmptySpace="100dp"> - - - - - - - - - - - - + launcher:b="0"/> + launcher:a="0.48" + launcher:b="0"/> + launcher:a="0.52" + launcher:b="0"/> + launcher:b="0"/> \ No newline at end of file diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 60af347585..1bc269d9c3 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -115,7 +115,6 @@ public class DeviceProfile { private final int extraSpace; public int workspaceTopPadding; public int workspaceBottomPadding; - public int extraHotseatBottomPadding; // Workspace page indicator public final int workspacePageIndicatorHeight; @@ -157,24 +156,22 @@ public class DeviceProfile { public int folderChildDrawablePaddingPx; // Hotseat - public int hotseatBarSizeExtraSpacePx; public final int numShownHotseatIcons; public int hotseatCellHeightPx; - private final int hotseatExtraVerticalSize; private final boolean areNavButtonsInline; // In portrait: size = height, in landscape: size = width public int hotseatBarSizePx; - public int hotseatBarTopPaddingPx; - public final int hotseatBarBottomPaddingPx; + public int hotseatBarBottomSpacePx; + public int hotseatQsbSpace; public int springLoadedHotseatBarTopMarginPx; // Start is the side next to the nav bar, end is the side next to the workspace public final int hotseatBarSidePaddingStartPx; public final int hotseatBarSidePaddingEndPx; public final int hotseatQsbHeight; + public final int hotseatQsbVisualHeight; + private final int hotseatQsbShadowHeight; public int hotseatBorderSpace; - public final float qsbBottomMarginOriginalPx; - public int qsbBottomMarginPx; public int qsbWidth; // only used when isQsbInline // All apps @@ -222,7 +219,7 @@ public class DeviceProfile { // Insets private final Rect mInsets = new Rect(); public final Rect workspacePadding = new Rect(); - private final Rect mHotseatPadding = new Rect(); + private final Rect mHotseatBarPadding = new Rect(); // When true, nav bar is on the left side of the screen. private boolean mIsSeascape; @@ -275,7 +272,7 @@ public class DeviceProfile { widthPx = windowBounds.bounds.width(); heightPx = windowBounds.bounds.height(); availableWidthPx = windowBounds.availableSize.x; - availableHeightPx = windowBounds.availableSize.y; + availableHeightPx = windowBounds.availableSize.y; aspectRatio = ((float) Math.max(widthPx, heightPx)) / Math.min(widthPx, heightPx); boolean isTallDevice = Float.compare(aspectRatio, TALL_DEVICE_ASPECT_RATIO_THRESHOLD) >= 0; @@ -360,6 +357,9 @@ public class DeviceProfile { workspaceCellPaddingXPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_x); hotseatQsbHeight = res.getDimensionPixelSize(R.dimen.qsb_widget_height); + hotseatQsbShadowHeight = res.getDimensionPixelSize(R.dimen.qsb_shadow_height); + hotseatQsbVisualHeight = hotseatQsbHeight - 2 * hotseatQsbShadowHeight; + // Whether QSB might be inline in appropriate orientation (e.g. landscape). boolean canQsbInline = (isTwoPanels ? inv.inlineQsb[INDEX_TWO_PANEL_PORTRAIT] || inv.inlineQsb[INDEX_TWO_PANEL_LANDSCAPE] @@ -379,17 +379,28 @@ public class DeviceProfile { numShownAllAppsColumns = isTwoPanels ? inv.numDatabaseAllAppsColumns : inv.numAllAppsColumns; - hotseatBarSizeExtraSpacePx = 0; - hotseatBarTopPaddingPx = - res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding); - if (isQsbInline) { - hotseatBarBottomPaddingPx = res.getDimensionPixelSize(R.dimen.inline_qsb_bottom_margin); + + int hotseatBarBottomSpace = pxFromDp(inv.hotseatBarBottomSpace[mTypeIndex], mMetrics); + int minQsbMargin = res.getDimensionPixelSize(R.dimen.min_qsb_margin); + hotseatQsbSpace = pxFromDp(inv.hotseatQsbSpace[mTypeIndex], mMetrics); + // Have a little space between the inset and the QSB + if (mInsets.bottom + minQsbMargin > hotseatBarBottomSpace) { + int availableSpace = hotseatQsbSpace - (mInsets.bottom - hotseatBarBottomSpace); + + // Only change the spaces if there is space + if (availableSpace > 0) { + // Make sure there is enough space between hotseat/QSB and QSB/navBar + if (availableSpace < minQsbMargin * 2) { + minQsbMargin = availableSpace / 2; + hotseatQsbSpace = minQsbMargin; + } else { + hotseatQsbSpace -= minQsbMargin; + } + } + hotseatBarBottomSpacePx = mInsets.bottom + minQsbMargin; + } else { - hotseatBarBottomPaddingPx = (isTallDevice ? res.getDimensionPixelSize( - R.dimen.dynamic_grid_hotseat_bottom_tall_padding) - : res.getDimensionPixelSize( - R.dimen.dynamic_grid_hotseat_bottom_non_tall_padding)) - + res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_bottom_padding); + hotseatBarBottomSpacePx = hotseatBarBottomSpace; } springLoadedHotseatBarTopMarginPx = res.getDimensionPixelSize( @@ -398,13 +409,7 @@ public class DeviceProfile { res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_side_padding); // Add a bit of space between nav bar and hotseat in vertical bar layout. hotseatBarSidePaddingStartPx = isVerticalBarLayout() ? workspacePageIndicatorHeight : 0; - hotseatExtraVerticalSize = - res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_extra_vertical_size); - updateHotseatIconSize(pxFromDp(inv.iconSize[INDEX_DEFAULT], mMetrics)); - - qsbBottomMarginOriginalPx = isScalableGrid - ? res.getDimensionPixelSize(R.dimen.scalable_grid_qsb_bottom_margin) - : 0; + updateHotseatSizes(pxFromDp(inv.iconSize[INDEX_DEFAULT], mMetrics)); overviewTaskMarginPx = res.getDimensionPixelSize(R.dimen.overview_task_margin); overviewTaskMarginGridPx = res.getDimensionPixelSize(R.dimen.overview_task_margin_grid); @@ -443,42 +448,6 @@ public class DeviceProfile { workspaceTopPadding = Math.round(paddingWorkspaceTop * cellScaleToFit); workspaceBottomPadding = Math.round(paddingWorkspaceBottom * cellScaleToFit); - extraHotseatBottomPadding = Math.round(paddingHotseatBottom * cellScaleToFit); - - hotseatBarSizePx += extraHotseatBottomPadding; - - qsbBottomMarginPx = Math.round(qsbBottomMarginOriginalPx * cellScaleToFit); - } else if (!isVerticalBarLayout() && isPhone && isTallDevice) { - // We increase the hotseat size when there is extra space. - - if (Float.compare(aspectRatio, TALLER_DEVICE_ASPECT_RATIO_THRESHOLD) >= 0 - && extraSpace >= Utilities.dpToPx(TALL_DEVICE_EXTRA_SPACE_THRESHOLD_DP)) { - // For taller devices, we will take a piece of the extra space from each row, - // and add it to the space above and below the hotseat. - - // For devices with more extra space, we take a larger piece from each cell. - int piece = extraSpace < Utilities.dpToPx(TALL_DEVICE_MORE_EXTRA_SPACE_THRESHOLD_DP) - ? 7 : 5; - - int extraSpace = ((getCellSize().y - iconSizePx - iconDrawablePaddingPx * 2) - * inv.numRows) / piece; - - workspaceTopPadding = extraSpace / 8; - int halfLeftOver = (extraSpace - workspaceTopPadding) / 2; - hotseatBarTopPaddingPx += halfLeftOver; - hotseatBarSizeExtraSpacePx = halfLeftOver; - } else { - // ie. For a display with a large aspect ratio, we can keep the icons on the - // workspace in portrait mode closer together by adding more height to the hotseat. - // Note: This calculation was created after noticing a pattern in the design spec. - hotseatBarSizeExtraSpacePx = getCellSize().y - iconSizePx - - iconDrawablePaddingPx * 2 - workspacePageIndicatorHeight; - } - - updateHotseatIconSize(iconSizePx); - - // Recalculate the available dimensions using the new hotseat size. - updateAvailableDimensions(res); } int cellLayoutPadding = @@ -534,22 +503,27 @@ public class DeviceProfile { : res.getDimensionPixelSize(R.dimen.dynamic_grid_left_right_margin); } - private void updateHotseatIconSize(int hotseatIconSizePx) { + /** Updates hotseatCellHeightPx and hotseatBarSizePx */ + private void updateHotseatSizes(int 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; + } else if (isQsbInline) { + hotseatBarSizePx = Math.max(hotseatIconSizePx, hotseatQsbVisualHeight) + + hotseatBarBottomSpacePx; } else { - hotseatBarSizePx = hotseatIconSizePx + hotseatBarTopPaddingPx - + hotseatBarBottomPaddingPx + (isScalableGrid ? 0 : hotseatExtraVerticalSize) - + hotseatBarSizeExtraSpacePx; + hotseatBarSizePx = hotseatIconSizePx + + hotseatQsbSpace + + hotseatQsbVisualHeight + + hotseatBarBottomSpacePx; } } private Point getCellLayoutBorderSpace(InvariantDeviceProfile idp) { return getCellLayoutBorderSpace(idp, 1f); - } private Point getCellLayoutBorderSpace(InvariantDeviceProfile idp, float scale) { @@ -761,7 +735,7 @@ public class DeviceProfile { // All apps updateAllAppsIconSize(scale, res); - updateHotseatIconSize(iconSizePx); + updateHotseatSizes(iconSizePx); // Folder icon folderIconSizePx = IconNormalizer.getNormalizedCircleSize(iconSizePx); @@ -932,10 +906,10 @@ public class DeviceProfile { */ private int getVerticalHotseatLastItemBottomOffset() { int cellHeight = calculateCellHeight( - heightPx - mHotseatPadding.top - mHotseatPadding.bottom, hotseatBorderSpace, + heightPx - mHotseatBarPadding.top - mHotseatBarPadding.bottom, hotseatBorderSpace, numShownHotseatIcons); int extraIconEndSpacing = (cellHeight - iconSizePx) / 2; - return extraIconEndSpacing + mHotseatPadding.bottom; + return extraIconEndSpacing + mHotseatBarPadding.bottom; } /** @@ -1017,10 +991,11 @@ public class DeviceProfile { padding.right = hotseatBarSizePx; } } else { - // Pad the bottom of the workspace with search/hotseat bar sizes - int hotseatTop = hotseatBarSizePx; - int paddingBottom = hotseatTop + workspacePageIndicatorHeight - + workspaceBottomPadding - mWorkspacePageIndicatorOverlapWorkspace; + // Pad the bottom of the workspace with hotseat bar + // and leave a bit of space in case a widget go all the way down + int paddingBottom = hotseatBarSizePx + workspaceBottomPadding + + workspacePageIndicatorHeight - mWorkspacePageIndicatorOverlapWorkspace + - mInsets.bottom; int paddingTop = workspaceTopPadding + (isScalableGrid ? 0 : edgeMarginPx); int paddingSide = desiredWorkspaceHorizontalMarginPx; @@ -1060,17 +1035,17 @@ public class DeviceProfile { + diffOverlapFactor), 0); if (isSeascape()) { - mHotseatPadding.set(mInsets.left + hotseatBarSidePaddingStartPx, paddingTop, + mHotseatBarPadding.set(mInsets.left + hotseatBarSidePaddingStartPx, paddingTop, hotseatBarSidePaddingEndPx, paddingBottom); } else { - mHotseatPadding.set(hotseatBarSidePaddingEndPx, paddingTop, + mHotseatBarPadding.set(hotseatBarSidePaddingEndPx, paddingTop, mInsets.right + hotseatBarSidePaddingStartPx, paddingBottom); } } else if (isTaskbarPresent) { // Center the QSB vertically with hotseat - int hotseatBottomPadding = getHotseatBottomPadding(); - int hotseatTopPadding = - workspacePadding.bottom - hotseatBottomPadding - hotseatCellHeightPx; + int hotseatBarBottomPadding = getHotseatBarBottomPadding(); + int hotseatBarTopPadding = + hotseatBarSizePx - hotseatBarBottomPadding - hotseatCellHeightPx; // Push icons to the side int additionalQsbSpace = isQsbInline ? qsbWidth + hotseatBorderSpace : 0; @@ -1081,29 +1056,29 @@ public class DeviceProfile { int hotseatWidth = Math.min(requiredWidth, availableWidthPx - endOffset); int sideSpacing = (availableWidthPx - hotseatWidth) / 2; - mHotseatPadding.set(sideSpacing, hotseatTopPadding, sideSpacing, hotseatBottomPadding); + mHotseatBarPadding.set(sideSpacing, hotseatBarTopPadding, sideSpacing, + hotseatBarBottomPadding); boolean isRtl = Utilities.isRtl(context.getResources()); if (isRtl) { - mHotseatPadding.right += additionalQsbSpace; + mHotseatBarPadding.right += additionalQsbSpace; } else { - mHotseatPadding.left += additionalQsbSpace; + mHotseatBarPadding.left += additionalQsbSpace; } if (endOffset > sideSpacing) { int diff = isRtl ? sideSpacing - endOffset : endOffset - sideSpacing; - mHotseatPadding.left -= diff; - mHotseatPadding.right += diff; + mHotseatBarPadding.left -= diff; + mHotseatBarPadding.right += diff; } } else if (isScalableGrid) { int sideSpacing = (availableWidthPx - qsbWidth) / 2; - mHotseatPadding.set(sideSpacing, - hotseatBarTopPaddingPx, + mHotseatBarPadding.set(sideSpacing, + 0, sideSpacing, - hotseatBarSizePx - hotseatCellHeightPx - hotseatBarTopPaddingPx - + mInsets.bottom); + getHotseatBarBottomPadding()); } else { // We want the edges of the hotseat to line up with the edges of the workspace, but the // icons in the hotseat are a different size, and so don't line up perfectly. To account @@ -1112,14 +1087,15 @@ public class DeviceProfile { float workspaceCellWidth = (float) widthPx / inv.numColumns; float hotseatCellWidth = (float) widthPx / numShownHotseatIcons; int hotseatAdjustment = Math.round((workspaceCellWidth - hotseatCellWidth) / 2); - mHotseatPadding.set(hotseatAdjustment + workspacePadding.left + cellLayoutPaddingPx.left - + mInsets.left, hotseatBarTopPaddingPx, + mHotseatBarPadding.set( + hotseatAdjustment + workspacePadding.left + cellLayoutPaddingPx.left + + mInsets.left, + 0, hotseatAdjustment + workspacePadding.right + cellLayoutPaddingPx.right + mInsets.right, - hotseatBarSizePx - hotseatCellHeightPx - hotseatBarTopPaddingPx - + mInsets.bottom); + getHotseatBarBottomPadding()); } - return mHotseatPadding; + return mHotseatBarPadding; } /** @@ -1127,27 +1103,22 @@ public class DeviceProfile { */ public int getQsbOffsetY() { if (isQsbInline) { - return hotseatBarBottomPaddingPx; - } - - int freeSpace = isTaskbarPresent - ? workspacePadding.bottom - : hotseatBarSizePx - hotseatCellHeightPx - hotseatQsbHeight; - - if (isScalableGrid && qsbBottomMarginPx > mInsets.bottom) { - // Note that taskbarSize = 0 unless isTaskbarPresent. - return Math.min(qsbBottomMarginPx + taskbarSize, freeSpace); + return getHotseatBarBottomPadding() - ((hotseatQsbHeight - hotseatCellHeightPx) / 2); + } else if (isTaskbarPresent) { // QSB on top + return hotseatBarSizePx - hotseatQsbHeight + hotseatQsbShadowHeight; } else { - return (int) (freeSpace * mQsbCenterFactor) - + (isTaskbarPresent ? taskbarSize : mInsets.bottom); + return hotseatBarBottomSpacePx - hotseatQsbShadowHeight; } } - private int getHotseatBottomPadding() { - if (isQsbInline) { - return getQsbOffsetY() + ((hotseatQsbHeight - hotseatCellHeightPx) / 2); + /** + * Returns the number of pixels the hotseat is translated from the bottom of the screen. + */ + private int getHotseatBarBottomPadding() { + if (isTaskbarPresent) { // QSB on top or inline + return hotseatBarBottomSpacePx - (Math.abs(hotseatCellHeightPx - iconSizePx) / 2); } else { - return (getQsbOffsetY() - taskbarSize) / 2; + return hotseatBarSizePx - hotseatCellHeightPx; } } @@ -1158,7 +1129,7 @@ public class DeviceProfile { int taskbarIconBottomSpace = (taskbarSize - iconSizePx) / 2; int launcherIconBottomSpace = Math.min((hotseatCellHeightPx - iconSizePx) / 2, gridVisualizationPaddingY); - return getHotseatBottomPadding() + launcherIconBottomSpace - taskbarIconBottomSpace; + return getHotseatBarBottomPadding() + launcherIconBottomSpace - taskbarIconBottomSpace; } /** @@ -1167,7 +1138,7 @@ public class DeviceProfile { public int getOverviewActionsClaimedSpaceBelow() { if (isTaskbarPresent && !isGestureMode) { // Align vertically to where nav buttons are. - return ((taskbarSize - overviewActionsHeight) / 2) + getTaskbarOffsetY(); + return ((taskbarSize - overviewActionsHeight) / 2) + getTaskbarOffsetY(); } return isTaskbarPresent ? stashedTaskbarSize : mInsets.bottom; @@ -1349,18 +1320,19 @@ public class DeviceProfile { writer.println(prefix + pxToDpStr("hotseatBarSizePx", hotseatBarSizePx)); writer.println(prefix + "\tinv.hotseatColumnSpan: " + inv.hotseatColumnSpan[mTypeIndex]); writer.println(prefix + pxToDpStr("hotseatCellHeightPx", hotseatCellHeightPx)); - writer.println(prefix + pxToDpStr("hotseatBarTopPaddingPx", hotseatBarTopPaddingPx)); - writer.println(prefix + pxToDpStr("hotseatBarBottomPaddingPx", hotseatBarBottomPaddingPx)); + writer.println(prefix + pxToDpStr("hotseatBarBottomPaddingPx", hotseatBarBottomSpacePx)); writer.println(prefix + pxToDpStr("hotseatBarSidePaddingStartPx", hotseatBarSidePaddingStartPx)); writer.println(prefix + pxToDpStr("hotseatBarSidePaddingEndPx", hotseatBarSidePaddingEndPx)); + writer.println(prefix + pxToDpStr("hotseatQsbSpace", hotseatQsbSpace)); + writer.println(prefix + pxToDpStr("hotseatQsbHeight", hotseatQsbHeight)); writer.println(prefix + pxToDpStr("springLoadedHotseatBarTopMarginPx", springLoadedHotseatBarTopMarginPx)); - writer.println(prefix + pxToDpStr("mHotseatPadding.top", mHotseatPadding.top)); - writer.println(prefix + pxToDpStr("mHotseatPadding.bottom", mHotseatPadding.bottom)); - writer.println(prefix + pxToDpStr("mHotseatPadding.left", mHotseatPadding.left)); - writer.println(prefix + pxToDpStr("mHotseatPadding.right", mHotseatPadding.right)); + writer.println(prefix + pxToDpStr("mHotseatBarPadding.top", mHotseatBarPadding.top)); + writer.println(prefix + pxToDpStr("mHotseatBarPadding.bottom", mHotseatBarPadding.bottom)); + writer.println(prefix + pxToDpStr("mHotseatBarPadding.left", mHotseatBarPadding.left)); + writer.println(prefix + pxToDpStr("mHotseatBarPadding.right", mHotseatBarPadding.right)); writer.println(prefix + "\tnumShownHotseatIcons: " + numShownHotseatIcons); writer.println(prefix + pxToDpStr("hotseatBorderSpace", hotseatBorderSpace)); writer.println(prefix + "\tisQsbInline: " + isQsbInline); @@ -1389,7 +1361,6 @@ public class DeviceProfile { } writer.println(prefix + pxToDpStr("workspaceTopPadding", workspaceTopPadding)); writer.println(prefix + pxToDpStr("workspaceBottomPadding", workspaceBottomPadding)); - writer.println(prefix + pxToDpStr("extraHotseatBottomPadding", extraHotseatBottomPadding)); writer.println(prefix + pxToDpStr("overviewTaskMarginPx", overviewTaskMarginPx)); writer.println(prefix + pxToDpStr("overviewTaskMarginGridPx", overviewTaskMarginGridPx)); @@ -1425,6 +1396,8 @@ public class DeviceProfile { workspaceSpringLoadedMinNextPageVisiblePx)); writer.println( prefix + pxToDpStr("getWorkspaceSpringLoadScale()", getWorkspaceSpringLoadScale())); + writer.println(prefix + pxToDpStr("getCellLayoutHeight()", getCellLayoutHeight())); + writer.println(prefix + pxToDpStr("getCellLayoutWidth()", getCellLayoutWidth())); } private static Context getContext(Context c, Info info, int orientation, WindowBounds bounds) { diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java index 8c4c66277c..05ed3198cb 100644 --- a/src/com/android/launcher3/Hotseat.java +++ b/src/com/android/launcher3/Hotseat.java @@ -111,9 +111,7 @@ public class Hotseat extends CellLayout implements Insettable { mQsb.setVisibility(View.VISIBLE); lp.gravity = Gravity.BOTTOM; lp.width = ViewGroup.LayoutParams.MATCH_PARENT; - lp.height = grid.isTaskbarPresent - ? grid.workspacePadding.bottom - : grid.hotseatBarSizePx + insets.bottom; + lp.height = grid.hotseatBarSizePx; } Rect padding = grid.getHotseatLayoutPadding(getContext()); diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index dacbe9254a..2085b84ac5 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -46,6 +46,7 @@ import android.view.Display; import androidx.annotation.IntDef; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import androidx.core.content.res.ResourcesCompat; import com.android.launcher3.model.DeviceGridState; import com.android.launcher3.provider.RestoreDbTask; @@ -77,7 +78,8 @@ public class InvariantDeviceProfile { @Retention(RetentionPolicy.SOURCE) @IntDef({TYPE_PHONE, TYPE_MULTI_DISPLAY, TYPE_TABLET}) - public @interface DeviceType{} + public @interface DeviceType {} + public static final int TYPE_PHONE = 0; public static final int TYPE_MULTI_DISPLAY = 1; public static final int TYPE_TABLET = 2; @@ -153,6 +155,8 @@ public class InvariantDeviceProfile { public int numDatabaseHotseatIcons; public int[] hotseatColumnSpan; + public float[] hotseatBarBottomSpace; + public float[] hotseatQsbSpace; /** * Number of columns in the all apps list. @@ -360,6 +364,8 @@ public class InvariantDeviceProfile { ? closestProfile.numDatabaseHotseatIcons : closestProfile.numHotseatIcons; hotseatColumnSpan = closestProfile.hotseatColumnSpan; hotseatBorderSpaces = displayOption.hotseatBorderSpaces; + hotseatBarBottomSpace = displayOption.hotseatBarBottomSpace; + hotseatQsbSpace = displayOption.hotseatQsbSpace; numAllAppsColumns = closestProfile.numAllAppsColumns; numDatabaseAllAppsColumns = deviceType == TYPE_MULTI_DISPLAY @@ -726,6 +732,7 @@ public class InvariantDeviceProfile { private final int numHotseatIcons; private final int numShrunkenHotseatIcons; private final int numDatabaseHotseatIcons; + private final int[] hotseatColumnSpan = new int[COUNT_SIZES]; private final String dbFile; @@ -766,6 +773,7 @@ public class InvariantDeviceProfile { R.styleable.GridDisplayOption_numShrunkenHotseatIcons, numHotseatIcons / 2); numDatabaseHotseatIcons = a.getInt( R.styleable.GridDisplayOption_numExtendedHotseatIcons, 2 * numHotseatIcons); + hotseatColumnSpan[INDEX_DEFAULT] = a.getInt( R.styleable.GridDisplayOption_hotseatColumnSpan, numColumns); hotseatColumnSpan[INDEX_LANDSCAPE] = a.getInt( @@ -825,6 +833,8 @@ public class InvariantDeviceProfile { private final float[] horizontalMargin = new float[COUNT_SIZES]; //TODO(http://b/228998082) remove this when 3 button spaces are fixed private final float[] hotseatBorderSpaces = new float[COUNT_SIZES]; + private final float[] hotseatBarBottomSpace = new float[COUNT_SIZES]; + private final float[] hotseatQsbSpace = new float[COUNT_SIZES]; private final float[] iconSizes = new float[COUNT_SIZES]; private final float[] textSizes = new float[COUNT_SIZES]; @@ -1050,6 +1060,34 @@ public class InvariantDeviceProfile { R.styleable.ProfileDisplayOption_hotseatBorderSpaceTwoPanelPortrait, hotseatBorderSpaces[INDEX_DEFAULT]); + hotseatBarBottomSpace[INDEX_DEFAULT] = a.getFloat( + R.styleable.ProfileDisplayOption_hotseatBarBottomSpace, + ResourcesCompat.getFloat(context.getResources(), + R.dimen.hotseat_bar_bottom_space_default)); + hotseatBarBottomSpace[INDEX_LANDSCAPE] = a.getFloat( + R.styleable.ProfileDisplayOption_hotseatBarBottomSpaceLandscape, + hotseatBarBottomSpace[INDEX_DEFAULT]); + hotseatBarBottomSpace[INDEX_TWO_PANEL_LANDSCAPE] = a.getFloat( + R.styleable.ProfileDisplayOption_hotseatBarBottomSpaceTwoPanelLandscape, + hotseatBarBottomSpace[INDEX_DEFAULT]); + hotseatBarBottomSpace[INDEX_TWO_PANEL_PORTRAIT] = a.getFloat( + R.styleable.ProfileDisplayOption_hotseatBarBottomSpaceTwoPanelPortrait, + hotseatBarBottomSpace[INDEX_DEFAULT]); + + hotseatQsbSpace[INDEX_DEFAULT] = a.getFloat( + R.styleable.ProfileDisplayOption_hotseatQsbSpace, + ResourcesCompat.getFloat(context.getResources(), + R.dimen.hotseat_qsb_space_default)); + hotseatQsbSpace[INDEX_LANDSCAPE] = a.getFloat( + R.styleable.ProfileDisplayOption_hotseatQsbSpaceLandscape, + hotseatQsbSpace[INDEX_DEFAULT]); + hotseatQsbSpace[INDEX_TWO_PANEL_LANDSCAPE] = a.getFloat( + R.styleable.ProfileDisplayOption_hotseatQsbSpaceTwoPanelLandscape, + hotseatQsbSpace[INDEX_DEFAULT]); + hotseatQsbSpace[INDEX_TWO_PANEL_PORTRAIT] = a.getFloat( + R.styleable.ProfileDisplayOption_hotseatQsbSpaceTwoPanelPortrait, + hotseatQsbSpace[INDEX_DEFAULT]); + a.recycle(); } @@ -1085,6 +1123,8 @@ public class InvariantDeviceProfile { minCellSize[i].y *= w; horizontalMargin[i] *= w; hotseatBorderSpaces[i] *= w; + hotseatBarBottomSpace[i] *= w; + hotseatQsbSpace[i] *= w; allAppsCellSize[i].x *= w; allAppsCellSize[i].y *= w; allAppsIconSizes[i] *= w; @@ -1108,6 +1148,8 @@ public class InvariantDeviceProfile { minCellSize[i].y += p.minCellSize[i].y; horizontalMargin[i] += p.horizontalMargin[i]; hotseatBorderSpaces[i] += p.hotseatBorderSpaces[i]; + hotseatBarBottomSpace[i] += p.hotseatBarBottomSpace[i]; + hotseatQsbSpace[i] += p.hotseatQsbSpace[i]; allAppsCellSize[i].x += p.allAppsCellSize[i].x; allAppsCellSize[i].y += p.allAppsCellSize[i].y; allAppsIconSizes[i] += p.allAppsIconSizes[i]; diff --git a/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java b/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java index 1681ea5758..87ae890894 100644 --- a/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java +++ b/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java @@ -271,7 +271,7 @@ public class WorkspacePageIndicator extends View implements Insettable, PageIndi } else { lp.leftMargin = lp.rightMargin = 0; lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; - lp.bottomMargin = grid.hotseatBarSizePx + insets.bottom; + lp.bottomMargin = grid.hotseatBarSizePx; } setLayoutParams(lp); } diff --git a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt index 6a6c40f24a..0635d84ca5 100644 --- a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt +++ b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt @@ -112,6 +112,8 @@ abstract class DeviceProfileBaseTest { ).toTypedArray() hotseatBorderSpaces = FloatArray(4) { 16f } hotseatColumnSpan = IntArray(4) { 4 } + hotseatBarBottomSpace = FloatArray(4) { 48f } + hotseatQsbSpace = FloatArray(4) { 36f } iconSize = FloatArray(4) { 56f } allAppsIconSize = FloatArray(4) { 56f } iconTextSize = FloatArray(4) { 14f }