diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java index 699ce9783c..5f62749590 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java @@ -66,9 +66,9 @@ public class OverviewState extends LauncherState { @Override public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) { RecentsView recentsView = launcher.getOverviewPanel(); - float workspacePageWidth = launcher.getDeviceProfile().getWorkspaceWidth(); + float workspacePageHeight = launcher.getDeviceProfile().getCellLayoutHeight(); recentsView.getTaskSize(sTempRect); - float scale = (float) sTempRect.width() / workspacePageWidth; + float scale = (float) sTempRect.height() / workspacePageHeight; float parallaxFactor = 0.5f; return new ScaleAndTranslation(scale, 0, -getDefaultSwipeHeight(launcher) * parallaxFactor); } diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 396b10e42c..be180a61cb 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -665,11 +665,10 @@ public class DeviceProfile { updateIconSize(1f, res); updateWorkspacePadding(); - Point workspacePadding = getTotalWorkspacePadding(); // Check to see if the icons fit within the available height. float usedHeight = getCellLayoutHeightSpecification(); - final int maxHeight = getWorkspaceHeight(workspacePadding); + final int maxHeight = getCellLayoutHeight(); float extraHeight = Math.max(0, maxHeight - usedHeight); float scaleY = maxHeight / usedHeight; boolean shouldScale = scaleY < 1f; @@ -702,7 +701,7 @@ public class DeviceProfile { } private int getCellLayoutWidthSpecification() { - int numColumns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns; + int numColumns = getPanelCount() * inv.numColumns; return (cellWidthPx * numColumns) + (cellLayoutBorderSpacePx.x * (numColumns - 1)) + cellLayoutPaddingPx.left + cellLayoutPaddingPx.right; } @@ -902,18 +901,24 @@ public class DeviceProfile { result = new Point(); } - // Since we are only concerned with the overall padding, layout direction does - // not matter. - Point padding = getTotalWorkspacePadding(); - - int numColumns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns; - int screenWidthPx = getWorkspaceWidth(padding); - result.x = calculateCellWidth(screenWidthPx, cellLayoutBorderSpacePx.x, numColumns); - int screenHeightPx = getWorkspaceHeight(padding); - result.y = calculateCellHeight(screenHeightPx, cellLayoutBorderSpacePx.y, inv.numRows); + int shortcutAndWidgetContainerWidth = + getCellLayoutWidth() - (cellLayoutPaddingPx.left + cellLayoutPaddingPx.right); + result.x = calculateCellWidth(shortcutAndWidgetContainerWidth, cellLayoutBorderSpacePx.x, + inv.numColumns); + int shortcutAndWidgetContainerHeight = + getCellLayoutHeight() - (cellLayoutPaddingPx.top + cellLayoutPaddingPx.bottom); + result.y = calculateCellHeight(shortcutAndWidgetContainerHeight, cellLayoutBorderSpacePx.y, + inv.numRows); return result; } + /** + * Gets the number of panels within the workspace. + */ + public int getPanelCount() { + return isTwoPanels ? 2 : 1; + } + /** * Gets the space in px from the bottom of last item in the vertical-bar hotseat to the * bottom of the screen. @@ -932,7 +937,7 @@ public class DeviceProfile { /** * Gets the scaled top of the workspace in px for the spring-loaded edit state. */ - public float getWorkspaceSpringLoadShrunkTop() { + public float getCellLayoutSpringLoadShrunkTop() { workspaceSpringLoadShrunkTop = mInsets.top + dropTargetBarTopMarginPx + dropTargetBarSizePx + dropTargetBarBottomMarginPx; return workspaceSpringLoadShrunkTop; @@ -941,7 +946,7 @@ public class DeviceProfile { /** * Gets the scaled bottom of the workspace in px for the spring-loaded edit state. */ - private float getWorkspaceSpringLoadShrunkBottom() { + private float getCellLayoutSpringLoadShrunkBottom() { int topOfHotseat = hotseatBarSizePx + springLoadedHotseatBarTopMarginPx; workspaceSpringLoadShrunkBottom = heightPx - (isVerticalBarLayout() ? getVerticalHotseatLastItemBottomOffset() @@ -960,13 +965,12 @@ public class DeviceProfile { * Gets the scale of the workspace for the spring-loaded edit state. */ public float getWorkspaceSpringLoadScale() { - float cellLayoutHeight = availableHeightPx - workspacePadding.top - workspacePadding.bottom; - float scale = (getWorkspaceSpringLoadShrunkBottom() - getWorkspaceSpringLoadShrunkTop()) - / cellLayoutHeight; + float scale = (getCellLayoutSpringLoadShrunkBottom() - getCellLayoutSpringLoadShrunkTop()) + / getCellLayoutHeight(); scale = Math.min(scale, 1f); // Reduce scale if next pages would not be visible after scaling the workspace - int workspaceWidth = getWorkspaceWidth(); + int workspaceWidth = availableWidthPx; float scaledWorkspaceWidth = workspaceWidth * scale; float maxAvailableWidth = workspaceWidth - (2 * getWorkspaceSpringLoadedMinimumNextPageVisible()); @@ -976,19 +980,23 @@ public class DeviceProfile { return scale; } - public int getWorkspaceWidth() { - return getWorkspaceWidth(getTotalWorkspacePadding()); + /** + * Gets the width of a single Cell Layout, aka a single panel within a Workspace. + * + *
This is the width of a Workspace, less its horizontal padding. Note that two-panel + * layouts have two Cell Layouts per workspace. + */ + public int getCellLayoutWidth() { + return (availableWidthPx - getTotalWorkspacePadding().x) / getPanelCount(); } - public int getWorkspaceWidth(Point workspacePadding) { - int cellLayoutTotalPadding = - (isTwoPanels ? 2 : 1) * (cellLayoutPaddingPx.left + cellLayoutPaddingPx.right); - return availableWidthPx - workspacePadding.x - cellLayoutTotalPadding; - } - - private int getWorkspaceHeight(Point workspacePadding) { - return availableHeightPx - workspacePadding.y - (cellLayoutPaddingPx.top - + cellLayoutPaddingPx.bottom); + /** + * Gets the height of a single Cell Layout, aka a single panel within a Workspace. + * + *
This is the height of a Workspace, less its vertical padding. + */ + public int getCellLayoutHeight() { + return availableHeightPx - getTotalWorkspacePadding().y; } public Point getTotalWorkspacePadding() { diff --git a/src/com/android/launcher3/states/SpringLoadedState.java b/src/com/android/launcher3/states/SpringLoadedState.java index 15cdc20cef..a205ab55ca 100644 --- a/src/com/android/launcher3/states/SpringLoadedState.java +++ b/src/com/android/launcher3/states/SpringLoadedState.java @@ -51,7 +51,7 @@ public class SpringLoadedState extends LauncherState { return super.getWorkspaceScaleAndTranslation(launcher); } - float shrunkTop = grid.getWorkspaceSpringLoadShrunkTop(); + float shrunkTop = grid.getCellLayoutSpringLoadShrunkTop(); float scale = grid.getWorkspaceSpringLoadScale(); float halfHeight = ws.getHeight() / 2; diff --git a/tests/src/com/android/launcher3/DeviceProfileGridDimensionsTest.kt b/tests/src/com/android/launcher3/DeviceProfileGridDimensionsTest.kt new file mode 100644 index 0000000000..80259a59b4 --- /dev/null +++ b/tests/src/com/android/launcher3/DeviceProfileGridDimensionsTest.kt @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3 + +import android.graphics.PointF +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.launcher3.util.WindowBounds +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers +import org.mockito.Mockito.`when` as whenever + +/** + * Test for [DeviceProfile] grid dimensions. + * + * This includes workspace, cell layout, shortcut and widget container, cell sizes, etc. + */ +@SmallTest +@RunWith(AndroidJUnit4::class) +class DeviceProfileGridDimensionsTest : DeviceProfileBaseTest() { + + @Test + fun getCellLayoutWidth_twoPanelLandscapeScalable4By4GridTablet_equalsSinglePanelWidth() { + val tabletWidth = 2560 + val tabletHeight = 1600 + val availableWidth = 2560 + val availableHeight = 1500 + windowBounds = WindowBounds(tabletWidth, tabletHeight, availableWidth, availableHeight, 0) + useTwoPanels = true + whenever(info.isTablet(ArgumentMatchers.any())).thenReturn(true) + whenever(info.densityDpi).thenReturn(320) + inv = newScalableInvariantDeviceProfile() + + val dp = newDP() + + val expectedWorkspaceWidth = availableWidth + val expectedCellLayoutWidth = + (expectedWorkspaceWidth - (dp.workspacePadding.right + dp.workspacePadding.left)) / + dp.panelCount + assertThat(dp.cellLayoutWidth).isEqualTo(expectedCellLayoutWidth) + } + + @Test + fun getCellLayoutHeight_twoPanelLandscapeScalable4By4GridTablet_equalsSinglePanelHeight() { + val tabletWidth = 2560 + val tabletHeight = 1600 + val availableWidth = 2560 + val availableHeight = 1500 + windowBounds = WindowBounds(tabletWidth, tabletHeight, availableWidth, availableHeight, 0) + useTwoPanels = true + whenever(info.isTablet(ArgumentMatchers.any())).thenReturn(true) + whenever(info.densityDpi).thenReturn(320) + inv = newScalableInvariantDeviceProfile() + + val dp = newDP() + + val expectedWorkspaceHeight = availableHeight + val expectedCellLayoutHeight = + expectedWorkspaceHeight - (dp.workspacePadding.top + dp.workspacePadding.bottom) + assertThat(dp.cellLayoutHeight).isEqualTo(expectedCellLayoutHeight) + } + + @Test + fun getCellSize_twoPanelLandscapeScalable4By4GridTablet_equalsSinglePanelWidth() { + val tabletWidth = 2560 + val tabletHeight = 1600 + val availableWidth = 2560 + val availableHeight = 1500 + windowBounds = WindowBounds(tabletWidth, tabletHeight, availableWidth, availableHeight, 0) + useTwoPanels = true + whenever(info.isTablet(ArgumentMatchers.any())).thenReturn(true) + whenever(info.densityDpi).thenReturn(320) + inv = newScalableInvariantDeviceProfile() + + val dp = newDP() + + val expectedWorkspaceWidth = availableWidth + val expectedCellLayoutWidth = + (expectedWorkspaceWidth - (dp.workspacePadding.right + dp.workspacePadding.left)) / + dp.panelCount + val expectedShortcutAndWidgetContainerWidth = + expectedCellLayoutWidth - + (dp.cellLayoutPaddingPx.left + dp.cellLayoutPaddingPx.right) + assertThat(dp.getCellSize().x).isEqualTo( + (expectedShortcutAndWidgetContainerWidth - + ((inv!!.numColumns - 1) * dp.cellLayoutBorderSpacePx.x)) / inv!!.numColumns) + val expectedWorkspaceHeight = availableHeight + val expectedCellLayoutHeight = + expectedWorkspaceHeight - (dp.workspacePadding.top + dp.workspacePadding.bottom) + val expectedShortcutAndWidgetContainerHeight = expectedCellLayoutHeight - + (dp.cellLayoutPaddingPx.top + dp.cellLayoutPaddingPx.bottom) + assertThat(dp.getCellSize().y).isEqualTo( + (expectedShortcutAndWidgetContainerHeight - + ((inv!!.numRows - 1) * dp.cellLayoutBorderSpacePx.y)) / inv!!.numRows) + } + + @Test + fun getPanelCount_twoPanelLandscapeScalable4By4GridTablet_equalsTwoPanels() { + val tabletWidth = 2560 + val tabletHeight = 1600 + val availableWidth = 2560 + val availableHeight = 1500 + windowBounds = WindowBounds(tabletWidth, tabletHeight, availableWidth, availableHeight, 0) + useTwoPanels = true + whenever(info.isTablet(ArgumentMatchers.any())).thenReturn(true) + whenever(info.densityDpi).thenReturn(320) + inv = newScalableInvariantDeviceProfile() + + val dp = newDP() + + assertThat(dp.panelCount).isEqualTo(2) + } +} \ No newline at end of file