diff --git a/res/drawable/drop_target_frame.xml b/res/drawable/drop_target_frame.xml index 666a96e940..9f04103510 100644 --- a/res/drawable/drop_target_frame.xml +++ b/res/drawable/drop_target_frame.xml @@ -17,6 +17,6 @@ - + \ No newline at end of file diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml index 662b86ebbe..422240c939 100644 --- a/res/values-land/dimens.xml +++ b/res/values-land/dimens.xml @@ -22,8 +22,22 @@ 24dp + 15.28dp 4dp + 36dp + 20dp 16dp + 45dp + + + 28dp + 16dp + 2dp + 6dp + 6dp + + + 24dp diff --git a/res/values-sw600dp-land/dimens.xml b/res/values-sw600dp-land/dimens.xml new file mode 100644 index 0000000000..6c5be914dd --- /dev/null +++ b/res/values-sw600dp-land/dimens.xml @@ -0,0 +1,29 @@ + + + + + + 44dp + + + 11.33dp + 11.33dp + + + 0dp + 16dp + diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml index 92f806e8b2..501ead685f 100644 --- a/res/values-sw600dp/dimens.xml +++ b/res/values-sw600dp/dimens.xml @@ -32,8 +32,22 @@ 32dp + 9dp 7dp + 9dp + 0dp + 97dp + + + 34dp + 16dp + 16dp + 16dp + 56dp + + + 6dp diff --git a/res/values-sw720dp-land/dimens.xml b/res/values-sw720dp-land/dimens.xml index 9821526d4d..33da4a1bd8 100644 --- a/res/values-sw720dp-land/dimens.xml +++ b/res/values-sw720dp-land/dimens.xml @@ -15,9 +15,16 @@ --> - + + 0dp + 32dp + + 21.93dp + 29.33dp + + 64dp + 49dp - - + 0dp diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml index 7ebc3f886b..b4c8837224 100644 --- a/res/values-sw720dp/dimens.xml +++ b/res/values-sw720dp/dimens.xml @@ -17,6 +17,19 @@ 65dp + + 27.59dp + 36dp + + 20sp + 72dp + 24dp + 20dp + 32dp + 32dp + 32dp + + 164dp 30dp diff --git a/res/values/config.xml b/res/values/config.xml index e2fd0e3bc8..5e90bea98a 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -22,9 +22,6 @@ - - 85 - 50 diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 338e218b9e..a6abee2341 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -19,14 +19,14 @@ 4dp - 8dp + 10.77dp 8dp 7dp 8dp 16dp - 5.5dp + 10.77dp 8dp @@ -34,6 +34,7 @@ 2dp 0dp 0dp + 76dp - 52dp + 56dp 20dp + 36dp + 16dp 13dp @@ -206,6 +209,9 @@ 2dp 4dp 8dp + 16dp + 8dp + 22dp 30dp @@ -358,8 +364,9 @@ - 22dp - 6dp + 28dp + 6dp + 6dp 48dp diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index ad4cae4440..e184a91e3c 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -148,7 +148,8 @@ public class CellLayout extends ViewGroup { private boolean mVisualizeDropLocation = true; private RectF mVisualizeGridRect = new RectF(); private Paint mVisualizeGridPaint = new Paint(); - private int mGridVisualizationPadding; + private int mGridVisualizationPaddingX; + private int mGridVisualizationPaddingY; private int mGridVisualizationRoundingRadius; private float mGridAlpha = 0f; private int mGridColor = 0; @@ -275,8 +276,10 @@ public class CellLayout extends ViewGroup { mBackground.setAlpha(0); mGridColor = Themes.getAttrColor(getContext(), R.attr.workspaceAccentColor); - mGridVisualizationPadding = - res.getDimensionPixelSize(R.dimen.grid_visualization_cell_spacing); + mGridVisualizationPaddingX = res.getDimensionPixelSize( + R.dimen.grid_visualization_horizontal_cell_spacing); + mGridVisualizationPaddingY = res.getDimensionPixelSize( + R.dimen.grid_visualization_vertical_cell_spacing); mGridVisualizationRoundingRadius = res.getDimensionPixelSize(R.dimen.grid_visualization_rounding_radius); mReorderPreviewAnimationMagnitude = (REORDER_PREVIEW_MAGNITUDE * deviceProfile.iconSizePx); @@ -573,8 +576,8 @@ public class CellLayout extends ViewGroup { protected void visualizeGrid(Canvas canvas) { DeviceProfile dp = mActivity.getDeviceProfile(); - int paddingX = (int) Math.min((mCellWidth - dp.iconSizePx) / 2, mGridVisualizationPadding); - int paddingY = (int) Math.min((mCellHeight - dp.iconSizePx) / 2, mGridVisualizationPadding); + int paddingX = Math.min((mCellWidth - dp.iconSizePx) / 2, mGridVisualizationPaddingX); + int paddingY = Math.min((mCellHeight - dp.iconSizePx) / 2, mGridVisualizationPaddingY); mVisualizeGridRect.set(paddingX, paddingY, mCellWidth - paddingX, mCellHeight - paddingY); diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 622d750c83..514490adc0 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -94,18 +94,16 @@ public class DeviceProfile { private static final float TALL_DEVICE_EXTRA_SPACE_THRESHOLD_DP = 252; private static final float TALL_DEVICE_MORE_EXTRA_SPACE_THRESHOLD_DP = 268; - // To evenly space the icons, increase the left/right margins for tablets in portrait mode. - private static final int PORTRAIT_TABLET_LEFT_RIGHT_PADDING_MULTIPLIER = 4; - // Workspace public final int desiredWorkspaceHorizontalMarginOriginalPx; public int desiredWorkspaceHorizontalMarginPx; public Point cellLayoutBorderSpaceOriginalPx; public Point cellLayoutBorderSpacePx; - public final int cellLayoutPaddingLeftRightPx; - public final int cellLayoutBottomPaddingPx; + public Rect cellLayoutPaddingPx = new Rect(); + public final int edgeMarginPx; - public float workspaceSpringLoadShrinkFactor; + public float workspaceSpringLoadShrunkTop; + public float workspaceSpringLoadShrunkBottom; public final int workspaceSpringLoadedBottomSpace; private final int extraSpace; @@ -161,6 +159,7 @@ public class DeviceProfile { public int hotseatBarSizePx; public int hotseatBarTopPaddingPx; public final int hotseatBarBottomPaddingPx; + 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; @@ -206,8 +205,13 @@ public class DeviceProfile { // Drop Target public int dropTargetBarSizePx; + public int dropTargetBarTopMarginPx; + public int dropTargetBarBottomMarginPx; public int dropTargetDragPaddingPx; public int dropTargetTextSizePx; + public int dropTargetHorizontalPaddingPx; + public int dropTargetVerticalPaddingPx; + public int dropTargetGapPx; // Insets private final Rect mInsets = new Rect(); @@ -318,23 +322,6 @@ public class DeviceProfile { folderCellLayoutBorderSpacePx = new Point(folderCellLayoutBorderSpaceOriginalPx, folderCellLayoutBorderSpaceOriginalPx); - int cellLayoutPaddingLeftRightMultiplier = !isVerticalBarLayout() && isTablet - ? PORTRAIT_TABLET_LEFT_RIGHT_PADDING_MULTIPLIER : 1; - int cellLayoutPadding = isScalableGrid - ? 0 - : res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_layout_padding); - - if (isTwoPanels) { - cellLayoutPaddingLeftRightPx = 0; - cellLayoutBottomPaddingPx = 0; - } else if (isLandscape) { - cellLayoutPaddingLeftRightPx = 0; - cellLayoutBottomPaddingPx = cellLayoutPadding; - } else { - cellLayoutPaddingLeftRightPx = cellLayoutPaddingLeftRightMultiplier * cellLayoutPadding; - cellLayoutBottomPaddingPx = 0; - } - workspacePageIndicatorHeight = res.getDimensionPixelSize( R.dimen.workspace_page_indicator_height); mWorkspacePageIndicatorOverlapWorkspace = @@ -344,8 +331,15 @@ public class DeviceProfile { res.getDimensionPixelSize(R.dimen.dynamic_grid_icon_drawable_padding); dropTargetBarSizePx = res.getDimensionPixelSize(R.dimen.dynamic_grid_drop_target_size); + dropTargetBarTopMarginPx = res.getDimensionPixelSize(R.dimen.drop_target_top_margin); + dropTargetBarBottomMarginPx = res.getDimensionPixelSize(R.dimen.drop_target_bottom_margin); dropTargetDragPaddingPx = res.getDimensionPixelSize(R.dimen.drop_target_drag_padding); dropTargetTextSizePx = res.getDimensionPixelSize(R.dimen.drop_target_text_size); + dropTargetHorizontalPaddingPx = res.getDimensionPixelSize( + R.dimen.drop_target_button_drawable_horizontal_padding); + dropTargetVerticalPaddingPx = res.getDimensionPixelSize( + R.dimen.drop_target_button_drawable_vertical_padding); + dropTargetGapPx = res.getDimensionPixelSize(R.dimen.drop_target_button_gap); workspaceSpringLoadedBottomSpace = res.getDimensionPixelSize(R.dimen.dynamic_grid_min_spring_loaded_space); @@ -383,6 +377,8 @@ public class DeviceProfile { + res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_bottom_padding); qsbWidth = 0; } + springLoadedHotseatBarTopMarginPx = res.getDimensionPixelSize( + R.dimen.spring_loaded_hotseat_top_margin); hotseatBarSidePaddingEndPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_side_padding); // Add a bit of space between nav bar and hotseat in vertical bar layout. @@ -476,6 +472,12 @@ public class DeviceProfile { // Recalculate the available dimensions using the new hotseat size. updateAvailableDimensions(res); } + + int cellLayoutPadding = + isTwoPanels ? cellLayoutBorderSpacePx.x / 2 : res.getDimensionPixelSize( + R.dimen.cell_layout_padding); + cellLayoutPaddingPx = new Rect(cellLayoutPadding, cellLayoutPadding, cellLayoutPadding, + cellLayoutPadding); updateWorkspacePadding(); flingToDeleteThresholdVelocity = res.getDimensionPixelSize( @@ -586,7 +588,6 @@ public class DeviceProfile { float appWidgetScaleX = (float) profile.getCellSize().x / getCellSize().x; float appWidgetScaleY = (float) profile.getCellSize().y / getCellSize().y; profile.appWidgetScale.set(appWidgetScaleX, appWidgetScaleY); - profile.updateWorkspacePadding(); return profile; } @@ -621,18 +622,18 @@ public class DeviceProfile { } private void updateAllAppsWidth(Resources res) { - + int cellLayoutHorizontalPadding = + (cellLayoutPaddingPx.left + cellLayoutPaddingPx.right) / 2; if (isTablet) { - allAppsLeftRightPadding = - res.getDimensionPixelSize(R.dimen.all_apps_bottom_sheet_horizontal_padding) - + cellLayoutPaddingLeftRightPx; + allAppsLeftRightPadding = res.getDimensionPixelSize( + R.dimen.all_apps_bottom_sheet_horizontal_padding) + cellLayoutHorizontalPadding; int usedWidth = (allAppsCellWidthPx * numShownAllAppsColumns) + (allAppsBorderSpacePx.x * (numShownAllAppsColumns + 1)) + allAppsLeftRightPadding * 2; allAppsLeftRightMargin = Math.max(1, (availableWidthPx - usedWidth) / 2); } else { allAppsLeftRightPadding = - desiredWorkspaceHorizontalMarginPx + cellLayoutPaddingLeftRightPx; + desiredWorkspaceHorizontalMarginPx + cellLayoutHorizontalPadding; } } @@ -642,11 +643,12 @@ public class DeviceProfile { private int updateAvailableDimensions(Resources res) { updateIconSize(1f, res); + updateWorkspacePadding(); Point workspacePadding = getTotalWorkspacePadding(); // Check to see if the icons fit within the available height. float usedHeight = getCellLayoutHeight(); - final int maxHeight = availableHeightPx - workspacePadding.y; + final int maxHeight = getWorkspaceHeight(workspacePadding); float extraHeight = Math.max(0, maxHeight - usedHeight); float scaleY = maxHeight / usedHeight; boolean shouldScale = scaleY < 1f; @@ -656,10 +658,7 @@ 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. - int numColumns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns; - float usedWidth = (cellWidthPx * numColumns) - + (cellLayoutBorderSpacePx.x * (numColumns - 1)) - + (desiredWorkspaceHorizontalMarginPx * 2); + float usedWidth = getCellLayoutWidth() + (desiredWorkspaceHorizontalMarginPx * 2); // We do not subtract padding here, as we also scale the workspace padding if needed. scaleX = availableWidthPx / usedWidth; shouldScale = true; @@ -676,7 +675,14 @@ public class DeviceProfile { } private int getCellLayoutHeight() { - return (cellHeightPx * inv.numRows) + (cellLayoutBorderSpacePx.y * (inv.numRows - 1)); + return (cellHeightPx * inv.numRows) + (cellLayoutBorderSpacePx.y * (inv.numRows - 1)) + + cellLayoutPaddingPx.top + cellLayoutPaddingPx.bottom; + } + + private int getCellLayoutWidth() { + int numColumns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns; + return (cellWidthPx * numColumns) + (cellLayoutBorderSpacePx.x * (numColumns - 1)) + + cellLayoutPaddingPx.left + cellLayoutPaddingPx.right; } /** @@ -736,18 +742,6 @@ public class DeviceProfile { } updateHotseatIconSize(iconSizePx); - if (!isVerticalLayout) { - int expectedWorkspaceHeight = availableHeightPx - hotseatBarSizePx - - workspacePageIndicatorHeight - edgeMarginPx; - float minRequiredHeight = dropTargetBarSizePx + workspaceSpringLoadedBottomSpace; - workspaceSpringLoadShrinkFactor = Math.min( - res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100.0f, - 1 - (minRequiredHeight / expectedWorkspaceHeight)); - } else { - workspaceSpringLoadShrinkFactor = - res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100.0f; - } - // Folder icon folderIconSizePx = IconNormalizer.getNormalizedCircleSize(iconSizePx); folderIconOffsetYPx = (iconSizePx - folderIconSizePx) / 2; @@ -848,7 +842,6 @@ public class DeviceProfile { public void updateInsets(Rect insets) { mInsets.set(insets); - updateWorkspacePadding(); } /** @@ -875,23 +868,62 @@ public class DeviceProfile { int numColumns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns; int screenWidthPx = getWorkspaceWidth(padding); result.x = calculateCellWidth(screenWidthPx, cellLayoutBorderSpacePx.x, numColumns); - result.y = calculateCellHeight(availableHeightPx - padding.y - - cellLayoutBottomPaddingPx, cellLayoutBorderSpacePx.y, inv.numRows); + int screenHeightPx = getWorkspaceHeight(padding); + result.y = calculateCellHeight(screenHeightPx, cellLayoutBorderSpacePx.y, inv.numRows); return result; } + /** + * Gets the space in px from the bottom of last item in the vertical-bar hotseat to the + * bottom of the screen. + */ + public int getVerticalHotseatLastItemBottomOffset() { + int cellHeight = calculateCellHeight( + heightPx - mHotseatPadding.top - mHotseatPadding.bottom, hotseatBorderSpace, + numShownHotseatIcons); + int hotseatSize = (cellHeight * numShownHotseatIcons) + + (hotseatBorderSpace * (numShownHotseatIcons - 1)); + int extraHotseatEndSpacing = (heightPx - hotseatSize) / 2; + int extraIconEndSpacing = (cellHeight - iconSizePx) / 2; + return extraHotseatEndSpacing + extraIconEndSpacing + mHotseatPadding.bottom; + } + + /** + * Gets the scaled top of the workspace in px for the spring-loaded edit state. + */ + public float getWorkspaceSpringLoadShrunkTop() { + workspaceSpringLoadShrunkTop = mInsets.top + dropTargetBarTopMarginPx + dropTargetBarSizePx + + dropTargetBarBottomMarginPx; + return workspaceSpringLoadShrunkTop; + } + + /** + * Gets the scaled bottom of the workspace in px for the spring-loaded edit state. + */ + public float getWorkspaceSpringLoadShrunkBottom() { + int topOfHotseat = hotseatBarSizePx + springLoadedHotseatBarTopMarginPx; + workspaceSpringLoadShrunkBottom = + heightPx - (isVerticalBarLayout() ? getVerticalHotseatLastItemBottomOffset() + : topOfHotseat); + return workspaceSpringLoadShrunkBottom; + } + public int getWorkspaceWidth() { return getWorkspaceWidth(getTotalWorkspacePadding()); } public int getWorkspaceWidth(Point workspacePadding) { int cellLayoutTotalPadding = - isTwoPanels ? 4 * cellLayoutPaddingLeftRightPx : 2 * cellLayoutPaddingLeftRightPx; + (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); + } + public Point getTotalWorkspacePadding() { - updateWorkspacePadding(); return new Point(workspacePadding.left + workspacePadding.right, workspacePadding.top + workspacePadding.bottom); } @@ -917,12 +949,26 @@ public class DeviceProfile { int hotseatTop = hotseatBarSizePx; int paddingBottom = hotseatTop + workspacePageIndicatorHeight + workspaceBottomPadding - mWorkspacePageIndicatorOverlapWorkspace; + int paddingTop = workspaceTopPadding + (isScalableGrid ? 0 : edgeMarginPx); + int paddingSide = desiredWorkspaceHorizontalMarginPx; - padding.set(desiredWorkspaceHorizontalMarginPx, - workspaceTopPadding + (isScalableGrid ? 0 : edgeMarginPx), - desiredWorkspaceHorizontalMarginPx, - paddingBottom); + padding.set(paddingSide, paddingTop, paddingSide, paddingBottom); } + insetPadding(workspacePadding, cellLayoutPaddingPx); + } + + private void insetPadding(Rect paddings, Rect insets) { + insets.left = Math.min(insets.left, paddings.left); + paddings.left -= insets.left; + + insets.top = Math.min(insets.top, paddings.top); + paddings.top -= insets.top; + + insets.right = Math.min(insets.right, paddings.right); + paddings.right -= insets.right; + + insets.bottom = Math.min(insets.bottom, paddings.bottom); + paddings.bottom -= insets.bottom; } /** @@ -930,12 +976,14 @@ public class DeviceProfile { */ public Rect getHotseatLayoutPadding(Context context) { if (isVerticalBarLayout()) { + int paddingTop = Math.max(mInsets.top - cellLayoutPaddingPx.top, 0); + int paddingBottom = Math.max(mInsets.bottom - cellLayoutPaddingPx.bottom, 0); if (isSeascape()) { - mHotseatPadding.set(mInsets.left + hotseatBarSidePaddingStartPx, - mInsets.top, hotseatBarSidePaddingEndPx, mInsets.bottom); + mHotseatPadding.set(mInsets.left + hotseatBarSidePaddingStartPx, paddingTop, + hotseatBarSidePaddingEndPx, paddingBottom); } else { - mHotseatPadding.set(hotseatBarSidePaddingEndPx, mInsets.top, - mInsets.right + hotseatBarSidePaddingStartPx, mInsets.bottom); + mHotseatPadding.set(hotseatBarSidePaddingEndPx, paddingTop, + mInsets.right + hotseatBarSidePaddingStartPx, paddingBottom); } } else if (isTaskbarPresent) { int hotseatHeight = workspacePadding.bottom; @@ -974,14 +1022,12 @@ 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 + cellLayoutPaddingLeftRightPx - + mInsets.left, - hotseatBarTopPaddingPx, - hotseatAdjustment + workspacePadding.right + cellLayoutPaddingLeftRightPx + mHotseatPadding.set(hotseatAdjustment + workspacePadding.left + cellLayoutPaddingPx.left + + mInsets.left, hotseatBarTopPaddingPx, + hotseatAdjustment + workspacePadding.right + cellLayoutPaddingPx.right + mInsets.right, hotseatBarSizePx - hotseatCellHeightPx - hotseatBarTopPaddingPx - + cellLayoutBottomPaddingPx + mInsets.bottom); + + mInsets.bottom); } return mHotseatPadding; } @@ -1065,6 +1111,8 @@ public class DeviceProfile { .getInfo().rotation == Surface.ROTATION_270; if (mIsSeascape != isSeascape) { mIsSeascape = isSeascape; + // Hotseat changing sides requires updating workspace left/right paddings + updateWorkspacePadding(); return true; } } @@ -1143,6 +1191,11 @@ public class DeviceProfile { cellLayoutBorderSpacePx.x)); writer.println(prefix + pxToDpStr("cellLayoutBorderSpacePx Vertical", cellLayoutBorderSpacePx.y)); + writer.println(prefix + pxToDpStr("cellLayoutPaddingPx.left", cellLayoutPaddingPx.left)); + writer.println(prefix + pxToDpStr("cellLayoutPaddingPx.top", cellLayoutPaddingPx.top)); + writer.println(prefix + pxToDpStr("cellLayoutPaddingPx.right", cellLayoutPaddingPx.right)); + writer.println( + prefix + pxToDpStr("cellLayoutPaddingPx.bottom", cellLayoutPaddingPx.bottom)); writer.println(prefix + pxToDpStr("iconSizePx", iconSizePx)); writer.println(prefix + pxToDpStr("iconTextSizePx", iconTextSizePx)); @@ -1179,6 +1232,12 @@ public class DeviceProfile { hotseatBarSidePaddingStartPx)); writer.println(prefix + pxToDpStr("hotseatBarSidePaddingEndPx", hotseatBarSidePaddingEndPx)); + 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 + "\tnumShownHotseatIcons: " + numShownHotseatIcons); writer.println(prefix + pxToDpStr("hotseatBorderSpace", hotseatBorderSpace)); writer.println(prefix + "\tisQsbInline: " + isQsbInline); @@ -1229,6 +1288,16 @@ public class DeviceProfile { writer.println(prefix + pxToDpStr("overviewPageSpacing", overviewPageSpacing)); writer.println(prefix + pxToDpStr("overviewRowSpacing", overviewRowSpacing)); writer.println(prefix + pxToDpStr("overviewGridSideMargin", overviewGridSideMargin)); + + writer.println(prefix + pxToDpStr("dropTargetBarTopMarginPx", dropTargetBarTopMarginPx)); + writer.println(prefix + pxToDpStr("dropTargetBarSizePx", dropTargetBarSizePx)); + writer.println( + prefix + pxToDpStr("dropTargetBarBottomMarginPx", dropTargetBarBottomMarginPx)); + + writer.println( + prefix + pxToDpStr("workspaceSpringLoadShrunkTop", workspaceSpringLoadShrunkTop)); + writer.println(prefix + pxToDpStr("workspaceSpringLoadShrunkBottom", + workspaceSpringLoadShrunkBottom)); } private static Context getContext(Context c, Info info, int orientation) { diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java index 9fb14f68cb..73289fb878 100644 --- a/src/com/android/launcher3/DropTargetBar.java +++ b/src/com/android/launcher3/DropTargetBar.java @@ -17,8 +17,6 @@ package com.android.launcher3; import static com.android.launcher3.ButtonDropTarget.TOOLTIP_DEFAULT; -import static com.android.launcher3.ButtonDropTarget.TOOLTIP_LEFT; -import static com.android.launcher3.ButtonDropTarget.TOOLTIP_RIGHT; import static com.android.launcher3.anim.AlphaUpdateListener.updateVisibility; import android.animation.TimeInterpolator; @@ -41,6 +39,8 @@ import com.android.launcher3.dragndrop.DragController.DragListener; import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.testing.TestProtocol; +import java.util.Arrays; + /* * The top bar containing various drop targets: Delete/App Info/Uninstall. */ @@ -94,30 +94,28 @@ public class DropTargetBar extends FrameLayout lp.rightMargin = insets.right; int tooltipLocation = TOOLTIP_DEFAULT; - if (grid.isVerticalBarLayout()) { - lp.width = grid.dropTargetBarSizePx; - lp.height = grid.availableHeightPx - 2 * grid.edgeMarginPx; - lp.gravity = grid.isSeascape() ? Gravity.RIGHT : Gravity.LEFT; - tooltipLocation = grid.isSeascape() ? TOOLTIP_LEFT : TOOLTIP_RIGHT; + int horizontalMargin; + if (grid.isTablet) { + // XXX: If the icon size changes across orientations, we will have to take + // that into account here too. + horizontalMargin = ((grid.widthPx - 2 * grid.edgeMarginPx + - (grid.inv.numColumns * grid.cellWidthPx)) + / (2 * (grid.inv.numColumns + 1))) + + grid.edgeMarginPx; } else { - int gap; - if (grid.isTablet) { - // XXX: If the icon size changes across orientations, we will have to take - // that into account here too. - gap = ((grid.widthPx - 2 * grid.edgeMarginPx - - (grid.inv.numColumns * grid.cellWidthPx)) - / (2 * (grid.inv.numColumns + 1))) - + grid.edgeMarginPx; - } else { - gap = getContext().getResources() - .getDimensionPixelSize(R.dimen.drop_target_bar_margin_horizontal); - } - lp.width = grid.availableWidthPx - 2 * gap; - - lp.topMargin += grid.edgeMarginPx; - lp.height = grid.dropTargetBarSizePx; - lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP; + horizontalMargin = getContext().getResources() + .getDimensionPixelSize(R.dimen.drop_target_bar_margin_horizontal); } + lp.topMargin += grid.dropTargetBarTopMarginPx; + lp.bottomMargin += grid.dropTargetBarBottomMarginPx; + lp.width = grid.availableWidthPx - 2 * horizontalMargin; + if (mIsVertical) { + lp.leftMargin = (grid.widthPx - lp.width) / 2; + lp.rightMargin = (grid.widthPx - lp.width) / 2; + } + lp.height = grid.dropTargetBarSizePx; + lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP; + setLayoutParams(lp); for (ButtonDropTarget button : mDropTargets) { button.setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.dropTargetTextSizePx); @@ -139,19 +137,7 @@ public class DropTargetBar extends FrameLayout int height = MeasureSpec.getSize(heightMeasureSpec); int visibleCount = getVisibleButtonsCount(); - if (visibleCount == 0) { - // do nothing - } else if (mIsVertical) { - int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); - int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); - - for (ButtonDropTarget button : mDropTargets) { - if (button.getVisibility() != GONE) { - button.setTextVisible(false); - button.measure(widthSpec, heightSpec); - } - } - } else { + if (visibleCount > 0) { int availableWidth = width / visibleCount; boolean textVisible = true; for (ButtonDropTarget buttons : mDropTargets) { @@ -176,31 +162,91 @@ public class DropTargetBar extends FrameLayout protected void onLayout(boolean changed, int left, int top, int right, int bottom) { int visibleCount = getVisibleButtonsCount(); if (visibleCount == 0) { - // do nothing - } else if (mIsVertical) { - int gap = getResources().getDimensionPixelSize(R.dimen.drop_target_vertical_gap); - int start = gap; - int end; + return; + } - for (ButtonDropTarget button : mDropTargets) { - if (button.getVisibility() != GONE) { - end = start + button.getMeasuredHeight(); - button.layout(0, start, button.getMeasuredWidth(), end); - start = end + gap; - } - } - } else { - int frameSize = (right - left) / visibleCount; + Launcher launcher = Launcher.getLauncher(getContext()); + Workspace workspace = launcher.getWorkspace(); + DeviceProfile dp = launcher.getDeviceProfile(); + int buttonHorizontalPadding = dp.dropTargetHorizontalPaddingPx; + int buttonVerticalPadding = dp.dropTargetVerticalPaddingPx; + int barCenter = (right - left) / 2; - int start = frameSize / 2; - int halfWidth; - for (ButtonDropTarget button : mDropTargets) { - if (button.getVisibility() != GONE) { - halfWidth = button.getMeasuredWidth() / 2; - button.layout(start - halfWidth, 0, - start + halfWidth, button.getMeasuredHeight()); - start = start + frameSize; + ButtonDropTarget[] visibleButtons = Arrays.stream(mDropTargets) + .filter(b -> b.getVisibility() != GONE) + .toArray(ButtonDropTarget[]::new); + Arrays.stream(visibleButtons).forEach( + b -> b.setPadding(buttonHorizontalPadding, buttonVerticalPadding, + buttonHorizontalPadding, buttonVerticalPadding)); + + if (visibleCount == 1) { + ButtonDropTarget button = visibleButtons[0]; + button.layout(barCenter - (button.getMeasuredWidth() / 2), 0, + barCenter + (button.getMeasuredWidth() / 2), button.getMeasuredHeight()); + } else if (visibleCount == 2) { + int buttonGap = dp.dropTargetGapPx; + + if (dp.isTwoPanels) { + ButtonDropTarget leftButton = visibleButtons[0]; + leftButton.layout(barCenter - leftButton.getMeasuredWidth() - (buttonGap / 2), 0, + barCenter - (buttonGap / 2), leftButton.getMeasuredHeight()); + + ButtonDropTarget rightButton = visibleButtons[1]; + rightButton.layout(barCenter + (buttonGap / 2), 0, + barCenter + rightButton.getMeasuredWidth() + (buttonGap / 2), + rightButton.getMeasuredHeight()); + } else if (dp.isTablet) { + int numberOfMargins = visibleCount - 1; + int buttonWidths = Arrays.stream(mDropTargets) + .filter(b -> b.getVisibility() != GONE) + .mapToInt(ButtonDropTarget::getMeasuredWidth) + .sum(); + int totalWidth = buttonWidths + (numberOfMargins * buttonGap); + int buttonsStartMargin = barCenter - (totalWidth / 2); + + int start = buttonsStartMargin; + for (ButtonDropTarget button : visibleButtons) { + int margin = (start != buttonsStartMargin) ? buttonGap : 0; + button.layout(start + margin, 0, start + margin + button.getMeasuredWidth(), + button.getMeasuredHeight()); + start += button.getMeasuredWidth() + margin; } + } else if (mIsVertical) { + // Center buttons over workspace, not screen. + int verticalCenter = (workspace.getRight() - workspace.getLeft()) / 2; + ButtonDropTarget leftButton = visibleButtons[0]; + leftButton.layout(verticalCenter - leftButton.getMeasuredWidth() - (buttonGap / 2), + 0, verticalCenter - (buttonGap / 2), leftButton.getMeasuredHeight()); + + ButtonDropTarget rightButton = visibleButtons[1]; + rightButton.layout(verticalCenter + (buttonGap / 2), 0, + verticalCenter + rightButton.getMeasuredWidth() + (buttonGap / 2), + rightButton.getMeasuredHeight()); + } else if (dp.isPhone) { + // Buttons aligned to outer edges of scaled workspace. + float shrunkTop = dp.getWorkspaceSpringLoadShrunkTop(); + float shrunkBottom = dp.getWorkspaceSpringLoadShrunkBottom(); + float scale = + (shrunkBottom - shrunkTop) / launcher.getWorkspace().getNormalChildHeight(); + int workspaceWidth = (int) (launcher.getWorkspace().getNormalChildWidth() * scale); + int start = barCenter - (workspaceWidth / 2); + int end = barCenter + (workspaceWidth / 2); + + ButtonDropTarget leftButton = visibleButtons[0]; + ButtonDropTarget rightButton = visibleButtons[1]; + + // If the text within the buttons is too long, the buttons can overlap + int overlap = start + leftButton.getMeasuredWidth() + rightButton.getMeasuredWidth() + - end; + if (overlap > 0) { + start -= overlap / 2; + end += overlap / 2; + } + + leftButton.layout(start, 0, start + leftButton.getMeasuredWidth(), + leftButton.getMeasuredHeight()); + rightButton.layout(end - rightButton.getMeasuredWidth(), 0, end, + rightButton.getMeasuredHeight()); } } } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 8b19a19c02..a7fc2f52ba 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -324,37 +324,14 @@ public class Workspace extends PagedView setPageSpacing(Math.max(maxInsets, maxPadding)); } - updateWorkspaceScreensPadding(); + updateCellLayoutPadding(); updateWorkspaceWidgetsSizes(); } - private void updateWorkspaceScreensPadding() { - DeviceProfile grid = mLauncher.getDeviceProfile(); - int paddingLeftRight = grid.cellLayoutPaddingLeftRightPx; - int paddingBottom = grid.cellLayoutBottomPaddingPx; - - int panelCount = getPanelCount(); - int rightPanelModulus = mIsRtl ? 0 : panelCount - 1; - int leftPanelModulus = mIsRtl ? panelCount - 1 : 0; - int numberOfScreens = mScreenOrder.size(); - for (int i = 0; i < numberOfScreens; i++) { - int paddingLeft = paddingLeftRight; - int paddingRight = paddingLeftRight; - // Add missing cellLayout border in-between panels. - if (panelCount > 1) { - if (i % panelCount == leftPanelModulus) { - paddingRight += grid.cellLayoutBorderSpacePx.x / 2; - } else if (i % panelCount == rightPanelModulus) { // right side panel - paddingLeft += grid.cellLayoutBorderSpacePx.x / 2; - } else { // middle panel - paddingLeft += grid.cellLayoutBorderSpacePx.x / 2; - paddingRight += grid.cellLayoutBorderSpacePx.x / 2; - } - } - // SparseArrayMap doesn't keep the order - mWorkspaceScreens.get(mScreenOrder.get(i)) - .setPadding(paddingLeft, 0, paddingRight, paddingBottom); - } + private void updateCellLayoutPadding() { + Rect padding = mLauncher.getDeviceProfile().cellLayoutPaddingPx; + mWorkspaceScreens.forEach( + s -> s.setPadding(padding.left, padding.top, padding.right, padding.bottom)); } private void updateWorkspaceWidgetsSizes() { @@ -652,7 +629,7 @@ public class Workspace extends PagedView mLauncher.getStateManager().getState(), newScreen, insertIndex); updatePageScrollValues(); - updateWorkspaceScreensPadding(); + updateCellLayoutPadding(); return newScreen; } diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index cc170643c9..3dfece7660 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -225,21 +225,21 @@ public class LauncherPreviewRenderer extends ContextWrapper mHotseat.resetLayout(false); CellLayout firstScreen = mRootView.findViewById(R.id.workspace); - firstScreen.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingLeftRightPx, - mDp.workspacePadding.top, + firstScreen.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingPx.left, + mDp.workspacePadding.top + mDp.cellLayoutPaddingPx.top, (mDp.isTwoPanels ? mDp.cellLayoutBorderSpacePx.x / 2 - : mDp.workspacePadding.right) + mDp.cellLayoutPaddingLeftRightPx, - mDp.workspacePadding.bottom + : mDp.workspacePadding.right) + mDp.cellLayoutPaddingPx.right, + mDp.workspacePadding.bottom + mDp.cellLayoutPaddingPx.bottom ); mWorkspaceScreens.put(FIRST_SCREEN_ID, firstScreen); if (mDp.isTwoPanels) { CellLayout rightPanel = mRootView.findViewById(R.id.workspace_right); rightPanel.setPadding( - mDp.cellLayoutBorderSpacePx.x / 2 + mDp.cellLayoutPaddingLeftRightPx, - mDp.workspacePadding.top, - mDp.workspacePadding.right + mDp.cellLayoutPaddingLeftRightPx, - mDp.workspacePadding.bottom + mDp.cellLayoutBorderSpacePx.x / 2 + mDp.cellLayoutPaddingPx.left, + mDp.workspacePadding.top + mDp.cellLayoutPaddingPx.top, + mDp.workspacePadding.right + mDp.cellLayoutPaddingPx.right, + mDp.workspacePadding.bottom + mDp.cellLayoutPaddingPx.bottom ); mWorkspaceScreens.put(Workspace.SECOND_SCREEN_ID, rightPanel); } diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java index 967f2c8400..9201006cd7 100644 --- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java @@ -113,13 +113,17 @@ public class SecondaryDragLayer extends BaseDragLayer for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child == mAppsView) { - int padding = 2 * (grid.desiredWorkspaceHorizontalMarginPx - + grid.cellLayoutPaddingLeftRightPx); + int horizontalPadding = (2 * grid.desiredWorkspaceHorizontalMarginPx) + + grid.cellLayoutPaddingPx.left + grid.cellLayoutPaddingPx.right; + int verticalPadding = + grid.cellLayoutPaddingPx.top + grid.cellLayoutPaddingPx.bottom; - int maxWidth = grid.allAppsCellWidthPx * grid.numShownAllAppsColumns + padding; + int maxWidth = + grid.allAppsCellWidthPx * grid.numShownAllAppsColumns + horizontalPadding; int appsWidth = Math.min(width, maxWidth); - int maxHeight = grid.allAppsCellHeightPx * grid.numShownAllAppsColumns + padding; + int maxHeight = + grid.allAppsCellHeightPx * grid.numShownAllAppsColumns + verticalPadding; int appsHeight = Math.min(height, maxHeight); mAppsView.measure( diff --git a/src/com/android/launcher3/states/SpringLoadedState.java b/src/com/android/launcher3/states/SpringLoadedState.java index d52594e409..9be3cc5539 100644 --- a/src/com/android/launcher3/states/SpringLoadedState.java +++ b/src/com/android/launcher3/states/SpringLoadedState.java @@ -18,7 +18,6 @@ package com.android.launcher3.states; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME; import android.content.Context; -import android.graphics.Rect; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; @@ -52,28 +51,15 @@ public class SpringLoadedState extends LauncherState { return super.getWorkspaceScaleAndTranslation(launcher); } - if (grid.isVerticalBarLayout()) { - float scale = grid.workspaceSpringLoadShrinkFactor; - return new ScaleAndTranslation(scale, 0, 0); - } - - float scale = grid.workspaceSpringLoadShrinkFactor; - Rect insets = launcher.getDragLayer().getInsets(); - - float scaledHeight = scale * ws.getNormalChildHeight(); - float shrunkTop = insets.top + grid.dropTargetBarSizePx; - float shrunkBottom = ws.getMeasuredHeight() - insets.bottom - - grid.workspacePadding.bottom - - grid.workspaceSpringLoadedBottomSpace; - float totalShrunkSpace = shrunkBottom - shrunkTop; - - float desiredCellTop = shrunkTop + (totalShrunkSpace - scaledHeight) / 2; + float shrunkTop = grid.getWorkspaceSpringLoadShrunkTop(); + float shrunkBottom = grid.getWorkspaceSpringLoadShrunkBottom(); + float scale = (shrunkBottom - shrunkTop) / ws.getNormalChildHeight(); float halfHeight = ws.getHeight() / 2; float myCenter = ws.getTop() + halfHeight; float cellTopFromCenter = halfHeight - ws.getChildAt(0).getTop(); float actualCellTop = myCenter - cellTopFromCenter * scale; - return new ScaleAndTranslation(scale, 0, (desiredCellTop - actualCellTop) / scale); + return new ScaleAndTranslation(scale, 0, (shrunkTop - actualCellTop) / scale); } @Override