From bd9a180fbc068350e67ee30efa47eb21b2054881 Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Thu, 8 Jun 2023 16:33:15 -0700 Subject: [PATCH] Allow LauncherState to define floating search side margins. This lets home screen align to workspace icons while All Apps aligns with those icons. In addition, on tablets where the QSB is inlined with the hotseat, floating search bar can also move horizontally accordingly. Bug: 275635606 Bug: 259619990 Test: Manual on tablet as well as foldable. Flag: ENABLE_FLOATING_SEARCH_BAR Change-Id: I67745c66390736cdf39d969ef7767096ae13c671 --- .../uioverrides/states/AllAppsState.java | 12 +++++++ src/com/android/launcher3/DeviceProfile.java | 19 +++++++++++ src/com/android/launcher3/LauncherState.java | 29 +++++++++++++++++ .../allapps/ActivityAllAppsContainerView.java | 26 +++++++++++++++ .../allapps/LauncherAllAppsContainerView.java | 32 +++++++++++++++++++ 5 files changed, 118 insertions(+) diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java index 6ebcf8c115..ed0a0d5172 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java @@ -118,6 +118,18 @@ public class AllAppsState extends LauncherState { return 0; } + @Override + public int getFloatingSearchBarRestingMarginStart(Launcher launcher) { + DeviceProfile dp = launcher.getDeviceProfile(); + return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin(); + } + + @Override + public int getFloatingSearchBarRestingMarginEnd(Launcher launcher) { + DeviceProfile dp = launcher.getDeviceProfile(); + return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin(); + } + @Override public boolean shouldFloatingSearchBarUsePillWhenUnfocused(Launcher launcher) { DeviceProfile dp = launcher.getDeviceProfile(); diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index bafcb9fefa..d6669ea4f0 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -1436,6 +1436,25 @@ public class DeviceProfile { return hotseatBarPadding; } + /** The margin between the edge of all apps and the edge of the first icon. */ + public int getAllAppsIconStartMargin() { + int allAppsSpacing; + if (isVerticalBarLayout()) { + // On phones, the landscape layout uses a different setup. + allAppsSpacing = workspacePadding.left + workspacePadding.right; + } else { + allAppsSpacing = allAppsLeftRightPadding * 2 + allAppsLeftRightMargin * 2; + } + + int cellWidth = DeviceProfile.calculateCellWidth( + availableWidthPx - allAppsSpacing, + 0 /* borderSpace */, + numShownAllAppsColumns); + int iconVisibleSize = Math.round(ICON_VISIBLE_AREA_FACTOR * allAppsIconSizePx); + int iconAlignmentMargin = (cellWidth - iconVisibleSize) / 2; + return allAppsLeftRightPadding + iconAlignmentMargin; + } + private int getAdditionalQsbSpace() { return isQsbInline ? hotseatQsbWidth + hotseatBorderSpace : 0; } diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java index 035b9c8d33..bfbca657ed 100644 --- a/src/com/android/launcher3/LauncherState.java +++ b/src/com/android/launcher3/LauncherState.java @@ -33,6 +33,7 @@ import static com.android.launcher3.testing.shared.TestProtocol.SPRING_LOADED_ST import android.content.Context; import android.graphics.Color; +import android.view.View; import android.view.animation.Interpolator; import androidx.annotation.FloatRange; @@ -218,6 +219,34 @@ public abstract class LauncherState implements BaseState { : -dp.hotseatQsbHeight; } + /** + * How far from the start of the screen the floating search bar should rest. + *

+ * To use original margin, return a negative value. + */ + public int getFloatingSearchBarRestingMarginStart(Launcher launcher) { + boolean isRtl = Utilities.isRtl(launcher.getResources()); + View qsb = launcher.getHotseat().getQsb(); + return isRtl ? launcher.getHotseat().getRight() - qsb.getRight() : qsb.getLeft(); + } + + /** + * How far from the end of the screen the floating search bar should rest. + *

+ * To use original margin, return a negative value. + */ + public int getFloatingSearchBarRestingMarginEnd(Launcher launcher) { + DeviceProfile dp = launcher.getDeviceProfile(); + if (dp.isQsbInline) { + int marginStart = getFloatingSearchBarRestingMarginStart(launcher); + return dp.widthPx - marginStart - dp.hotseatQsbWidth; + } + + boolean isRtl = Utilities.isRtl(launcher.getResources()); + View qsb = launcher.getHotseat().getQsb(); + return isRtl ? qsb.getLeft() : launcher.getHotseat().getRight() - qsb.getRight(); + } + /** Whether the floating search bar should use the pill UI when not focused. */ public boolean shouldFloatingSearchBarUsePillWhenUnfocused(Launcher launcher) { return false; diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java index a4dbe78800..c7ae2e7e83 100644 --- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java @@ -748,6 +748,32 @@ public class ActivityAllAppsContainerView return 0; } + /** + * How far from the start of the screen the floating search bar should rest. + *

+ * To use original margin, return a negative value. + *

+ * Note: This method mirrors one in LauncherState. For subclasses that use Launcher, it likely + * makes sense to use that method to derive an appropriate value for the current/target state. + */ + public int getFloatingSearchBarRestingMarginStart() { + DeviceProfile dp = mActivityContext.getDeviceProfile(); + return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin(); + } + + /** + * How far from the end of the screen the floating search bar should rest. + *

+ * To use original margin, return a negative value. + *

+ * Note: This method mirrors one in LauncherState. For subclasses that use Launcher, it likely + * makes sense to use that method to derive an appropriate value for the current/target state. + */ + public int getFloatingSearchBarRestingMarginEnd() { + DeviceProfile dp = mActivityContext.getDeviceProfile(); + return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin(); + } + private void layoutBelowSearchContainer(View v, boolean includeTabsMargin) { if (!(v.getLayoutParams() instanceof RelativeLayout.LayoutParams)) { return; diff --git a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java index bdba1538c6..d78e453218 100644 --- a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java @@ -93,4 +93,36 @@ public class LauncherAllAppsContainerView extends ActivityAllAppsContainerView stateManager = mActivityContext.getStateManager(); + + if (stateManager.isInTransition() && stateManager.getTargetState() != null) { + return stateManager.getTargetState() + .getFloatingSearchBarRestingMarginStart(mActivityContext); + } + return stateManager.getCurrentStableState() + .getFloatingSearchBarRestingMarginStart(mActivityContext); + } + + @Override + public int getFloatingSearchBarRestingMarginEnd() { + if (!isSearchBarFloating()) { + return super.getFloatingSearchBarRestingMarginEnd(); + } + + StateManager stateManager = mActivityContext.getStateManager(); + + if (stateManager.isInTransition() && stateManager.getTargetState() != null) { + return stateManager.getTargetState() + .getFloatingSearchBarRestingMarginEnd(mActivityContext); + } + return stateManager.getCurrentStableState() + .getFloatingSearchBarRestingMarginEnd(mActivityContext); + } }