From d1df5fcaac96fbd0cb1d990bde988110d3a59871 Mon Sep 17 00:00:00 2001 From: Thales Lima Date: Fri, 3 Sep 2021 18:37:19 +0100 Subject: [PATCH] launcher: use scalable grid in 4x4 Many changes are required to make scalable displays work correctly on foldables. This first one is making sure that the correct number of columns is used when calculating the used width for scalable grid. The spaces around the workspace are not final yet. Bug: 191879424 Test: manual Change-Id: Idc41ed004580f1f86d8f9595d005abc72301b1e3 --- res/values/attrs.xml | 10 ++++ src/com/android/launcher3/DevicePaddings.java | 10 ++-- src/com/android/launcher3/DeviceProfile.java | 54 ++++++++++++++----- .../launcher3/InvariantDeviceProfile.java | 31 +++++++++++ src/com/android/launcher3/Workspace.java | 10 ++-- .../graphics/LauncherPreviewRenderer.java | 4 +- 6 files changed, 95 insertions(+), 24 deletions(-) diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 65b46cf59f..720d73622e 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -180,6 +180,16 @@ + + + + + + + + diff --git a/src/com/android/launcher3/DevicePaddings.java b/src/com/android/launcher3/DevicePaddings.java index 7c387b1efe..08fb47b2cf 100644 --- a/src/com/android/launcher3/DevicePaddings.java +++ b/src/com/android/launcher3/DevicePaddings.java @@ -36,12 +36,12 @@ import java.util.ArrayList; * The unused or "extra" height is allocated to three different variable heights: * - The space above the workspace * - The space between the workspace and hotseat - * - The espace below the hotseat + * - The space below the hotseat */ public class DevicePaddings { - private static final String DEVICE_PADDING = "device-paddings"; - private static final String DEVICE_PADDINGS = "device-padding"; + private static final String DEVICE_PADDINGS = "device-paddings"; + private static final String DEVICE_PADDING = "device-padding"; private static final String WORKSPACE_TOP_PADDING = "workspaceTopPadding"; private static final String WORKSPACE_BOTTOM_PADDING = "workspaceBottomPadding"; @@ -58,13 +58,13 @@ public class DevicePaddings { int type; while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { - if ((type == XmlPullParser.START_TAG) && DEVICE_PADDING.equals(parser.getName())) { + if ((type == XmlPullParser.START_TAG) && DEVICE_PADDINGS.equals(parser.getName())) { final int displayDepth = parser.getDepth(); while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > displayDepth) && type != XmlPullParser.END_DOCUMENT) { if ((type == XmlPullParser.START_TAG) - && DEVICE_PADDINGS.equals(parser.getName())) { + && DEVICE_PADDING.equals(parser.getName())) { TypedArray a = context.obtainStyledAttributes( Xml.asAttributeSet(parser), R.styleable.DevicePadding); int maxWidthPx = a.getDimensionPixelSize( diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index b7d0481c96..3121bfc9ee 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -33,6 +33,7 @@ import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.util.DisplayMetrics; +import android.util.Pair; import android.view.Surface; import com.android.launcher3.CellLayout.ContainerType; @@ -576,8 +577,9 @@ public class DeviceProfile { // 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)) + int numColumns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns; + float usedWidth = (cellWidthPx * numColumns) + + (cellLayoutBorderSpacingPx * (numColumns - 1)) + (desiredWorkspaceLeftRightMarginPx * 2); // We do not subtract padding here, as we also scale the workspace padding if needed. scaleX = availableWidthPx / usedWidth; @@ -638,8 +640,9 @@ public class DeviceProfile { setCellLayoutBorderSpacing((int) (cellLayoutBorderSpacingOriginalPx * scale)); if (isScalableGrid) { - cellWidthPx = pxFromDp(inv.minCellWidth, mMetrics, scale); - cellHeightPx = pxFromDp(inv.minCellHeight, mMetrics, scale); + PointF minCellHeightAndWidth = getMinCellHeightAndWidth(); + cellWidthPx = pxFromDp(minCellHeightAndWidth.x, mMetrics, scale); + cellHeightPx = pxFromDp(minCellHeightAndWidth.y, mMetrics, scale); int cellContentHeight = iconSizePx + iconDrawablePaddingPx + Utilities.calculateTextHeight(iconTextSizePx); cellYPaddingPx = Math.max(0, cellHeightPx - cellContentHeight) / 2; @@ -698,6 +701,28 @@ public class DeviceProfile { folderIconOffsetYPx = (iconSizePx - folderIconSizePx) / 2; } + /** + * Returns the minimum cell height and width as a pair. + */ + private PointF getMinCellHeightAndWidth() { + PointF result = new PointF(); + + if (isTwoPanels) { + if (isLandscape) { + result.x = inv.twoPanelLandscapeMinCellWidthDps; + result.y = inv.twoPanelLandscapeMinCellHeightDps; + } else { + result.x = inv.twoPanelPortraitMinCellWidthDps; + result.y = inv.twoPanelPortraitMinCellHeightDps; + } + } else { + result.x = inv.minCellWidth; + result.y = inv.minCellHeight; + } + + return result; + } + private void updateAvailableFolderCellDimensions(Resources res) { updateFolderCellSize(1f, res); @@ -781,17 +806,14 @@ public class DeviceProfile { if (result == null) { result = new Point(); } + // Since we are only concerned with the overall padding, layout direction does // not matter. Point padding = getTotalWorkspacePadding(); - // availableWidthPx is the screen width of the device. In 2 panels mode, each panel should - // only have half of the screen width. In addition, there is only cellLayoutPadding in the - // left side of the left most panel and the right most side of the right panel. There is no - // cellLayoutPadding in the middle. - int screenWidthPx = isTwoPanels - ? availableWidthPx / 2 - padding.x - cellLayoutPaddingLeftRightPx - : availableWidthPx - padding.x - cellLayoutPaddingLeftRightPx * 2; - result.x = calculateCellWidth(screenWidthPx, cellLayoutBorderSpacingPx, inv.numColumns); + + int numColumns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns; + int screenWidthPx = availableWidthPx - padding.x; + result.x = calculateCellWidth(screenWidthPx, cellLayoutBorderSpacingPx, numColumns); result.y = calculateCellHeight(availableHeightPx - padding.y - cellLayoutBottomPaddingPx, cellLayoutBorderSpacingPx, inv.numRows); return result; @@ -1038,6 +1060,14 @@ public class DeviceProfile { writer.println(prefix + "\tinv.minCellWidth:" + inv.minCellWidth + "dp"); writer.println(prefix + "\tinv.minCellHeight:" + inv.minCellHeight + "dp"); + writer.println(prefix + "\tinv.twoPanelPortraitMinCellHeightDps:" + + inv.twoPanelPortraitMinCellHeightDps + "dp"); + writer.println(prefix + "\tinv.twoPanelPortraitMinCellWidthDps:" + + inv.twoPanelPortraitMinCellWidthDps + "dp"); + writer.println(prefix + "\tinv.twoPanelLandscapeMinCellHeightDps:" + + inv.twoPanelLandscapeMinCellHeightDps + "dp"); + writer.println(prefix + "\tinv.twoPanelLandscapeMinCellWidthDps:" + + inv.twoPanelLandscapeMinCellWidthDps + "dp"); writer.println(prefix + "\tinv.numColumns:" + inv.numColumns); writer.println(prefix + "\tinv.numRows:" + inv.numRows); diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 244cb59d80..1799f26e06 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -112,6 +112,10 @@ public class InvariantDeviceProfile { public float minCellHeight; public float minCellWidth; + public float twoPanelPortraitMinCellHeightDps; + public float twoPanelPortraitMinCellWidthDps; + public float twoPanelLandscapeMinCellHeightDps; + public float twoPanelLandscapeMinCellWidthDps; public float borderSpacing; private SparseArray mExtraAttrs; @@ -274,6 +278,10 @@ public class InvariantDeviceProfile { minCellHeight = displayOption.minCellHeight; minCellWidth = displayOption.minCellWidth; + twoPanelPortraitMinCellHeightDps = displayOption.twoPanelPortraitMinCellHeightDps; + twoPanelPortraitMinCellWidthDps = displayOption.twoPanelPortraitMinCellWidthDps; + twoPanelLandscapeMinCellHeightDps = displayOption.twoPanelLandscapeMinCellHeightDps; + twoPanelLandscapeMinCellWidthDps = displayOption.twoPanelLandscapeMinCellWidthDps; borderSpacing = displayOption.borderSpacing; numShownHotseatIcons = closestProfile.numHotseatIcons; @@ -707,6 +715,10 @@ public class InvariantDeviceProfile { private float minCellHeight; private float minCellWidth; + private float twoPanelPortraitMinCellHeightDps; + private float twoPanelPortraitMinCellWidthDps; + private float twoPanelLandscapeMinCellHeightDps; + private float twoPanelLandscapeMinCellWidthDps; private float borderSpacing; private final float[] iconSizes = new float[COUNT_TOTAL]; @@ -726,6 +738,17 @@ public class InvariantDeviceProfile { minCellHeight = a.getFloat(R.styleable.ProfileDisplayOption_minCellHeightDps, 0); minCellWidth = a.getFloat(R.styleable.ProfileDisplayOption_minCellWidthDps, 0); + twoPanelPortraitMinCellHeightDps = a.getFloat( + R.styleable.ProfileDisplayOption_twoPanelPortraitMinCellHeightDps, + minCellHeight); + twoPanelPortraitMinCellWidthDps = a.getFloat( + R.styleable.ProfileDisplayOption_twoPanelPortraitMinCellWidthDps, minCellWidth); + twoPanelLandscapeMinCellHeightDps = a.getFloat( + R.styleable.ProfileDisplayOption_twoPanelLandscapeMinCellHeightDps, + twoPanelPortraitMinCellHeightDps); + twoPanelLandscapeMinCellWidthDps = a.getFloat( + R.styleable.ProfileDisplayOption_twoPanelLandscapeMinCellWidthDps, + twoPanelPortraitMinCellWidthDps); borderSpacing = a.getFloat(R.styleable.ProfileDisplayOption_borderSpacingDps, 0); iconSizes[INDEX_DEFAULT] = @@ -782,6 +805,10 @@ public class InvariantDeviceProfile { } minCellHeight *= w; minCellWidth *= w; + twoPanelPortraitMinCellHeightDps *= w; + twoPanelPortraitMinCellWidthDps *= w; + twoPanelLandscapeMinCellHeightDps *= w; + twoPanelLandscapeMinCellWidthDps *= w; borderSpacing *= w; return this; } @@ -793,6 +820,10 @@ public class InvariantDeviceProfile { } minCellHeight += p.minCellHeight; minCellWidth += p.minCellWidth; + twoPanelPortraitMinCellHeightDps += p.twoPanelPortraitMinCellHeightDps; + twoPanelPortraitMinCellWidthDps += p.twoPanelPortraitMinCellWidthDps; + twoPanelLandscapeMinCellHeightDps += p.twoPanelLandscapeMinCellHeightDps; + twoPanelLandscapeMinCellWidthDps += p.twoPanelLandscapeMinCellWidthDps; borderSpacing += p.borderSpacing; return this; } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 54b2c968c0..bd2a14fd2d 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -347,13 +347,13 @@ public class Workspace extends PagedView if (panelCount > 1) { if (i % panelCount == leftPanelModulus) { paddingLeft = paddingLeftRight; - paddingRight = 0; - } else if (i % panelCount == rightPanelModulus) { - paddingLeft = 0; + paddingRight = grid.cellLayoutBorderSpacingPx / 2; + } else if (i % panelCount == rightPanelModulus) { // right side panel + paddingLeft = grid.cellLayoutBorderSpacingPx / 2; paddingRight = paddingLeftRight; } else { // middle panel - paddingLeft = 0; - paddingRight = 0; + paddingLeft = grid.cellLayoutBorderSpacingPx / 2; + paddingRight = grid.cellLayoutBorderSpacingPx / 2; } } // SparseArrayMap doesn't keep the order diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index 94fc70894d..b4907e8772 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -230,13 +230,13 @@ public class LauncherPreviewRenderer extends ContextWrapper CellLayout firstScreen = mRootView.findViewById(R.id.workspace); firstScreen.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingLeftRightPx, mDp.workspacePadding.top, - mDp.workspacePadding.right, + mDp.workspacePadding.right + mDp.cellLayoutBorderSpacingPx / 2, mDp.workspacePadding.bottom); mWorkspaceScreens.put(FIRST_SCREEN_ID, firstScreen); if (mDp.isTwoPanels) { CellLayout rightPanel = mRootView.findViewById(R.id.workspace_right); - rightPanel.setPadding(mDp.workspacePadding.left, + rightPanel.setPadding(mDp.workspacePadding.left + mDp.cellLayoutBorderSpacingPx / 2, mDp.workspacePadding.top, mDp.workspacePadding.right + mDp.cellLayoutPaddingLeftRightPx, mDp.workspacePadding.bottom);