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
diff --git a/src/com/android/launcher3/DevicePaddings.java b/src/com/android/launcher3/DevicePaddings.java
index 7c387b1..08fb47b 100644
--- a/src/com/android/launcher3/DevicePaddings.java
+++ b/src/com/android/launcher3/DevicePaddings.java
@@ -36,12 +36,12 @@
* 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 @@
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 b7d0481..3121bfc 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -33,6 +33,7 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 244cb59..1799f26 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -112,6 +112,10 @@
public float minCellHeight;
public float minCellWidth;
+ public float twoPanelPortraitMinCellHeightDps;
+ public float twoPanelPortraitMinCellWidthDps;
+ public float twoPanelLandscapeMinCellHeightDps;
+ public float twoPanelLandscapeMinCellWidthDps;
public float borderSpacing;
private SparseArray<TypedValue> mExtraAttrs;
@@ -274,6 +278,10 @@
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 @@
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 @@
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 @@
}
minCellHeight *= w;
minCellWidth *= w;
+ twoPanelPortraitMinCellHeightDps *= w;
+ twoPanelPortraitMinCellWidthDps *= w;
+ twoPanelLandscapeMinCellHeightDps *= w;
+ twoPanelLandscapeMinCellWidthDps *= w;
borderSpacing *= w;
return this;
}
@@ -793,6 +820,10 @@
}
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 54b2c96..bd2a14f 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -347,13 +347,13 @@
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 94fc708..b4907e8 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -230,13 +230,13 @@
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);