diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 69e07f24cb..dc28614cdc 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -427,11 +427,14 @@ 2dp 90dp - 50dp + 32dp + 36dp 24dp 12dp - 24dp - 3dp + 16dp + 6dp + 8dp + 12dp 1dp diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt index 8eeb0550ae..979934904d 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt @@ -31,7 +31,7 @@ import com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound import com.android.wm.shell.common.TriangleShape /** Drawable for the background of the bubble bar. */ -class BubbleBarBackground(context: Context, private val backgroundHeight: Float) : Drawable() { +class BubbleBarBackground(context: Context, private var backgroundHeight: Float) : Drawable() { private val DARK_THEME_SHADOW_ALPHA = 51f private val LIGHT_THEME_SHADOW_ALPHA = 25f @@ -171,4 +171,8 @@ class BubbleBarBackground(context: Context, private val backgroundHeight: Float) fun setArrowAlpha(alpha: Int) { arrowDrawable.paint.alpha = alpha } + + fun setHeight(newHeight: Float) { + backgroundHeight = newHeight + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java index 711ba6258f..1003c3f8e0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java @@ -106,10 +106,12 @@ public class BubbleBarView extends FrameLayout { private final Rect mBubbleBarBounds = new Rect(); // The amount the bubbles overlap when they are stacked in the bubble bar private final float mIconOverlapAmount; - // The spacing between the bubbles when they are expanded in the bubble bar - private final float mIconSpacing; + // The spacing between the bubbles when bubble bar is expanded + private final float mExpandedBarIconsSpacing; + // The spacing between the bubbles and the borders of the bubble bar + private float mBubbleBarPadding; // The size of a bubble in the bar - private final float mIconSize; + private float mIconSize; // The elevation of the bubbles within the bar private final float mBubbleElevation; private final float mDragElevation; @@ -169,16 +171,17 @@ public class BubbleBarView extends FrameLayout { setAlpha(0); setVisibility(INVISIBLE); mIconOverlapAmount = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_overlap); - mIconSpacing = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_spacing); + mBubbleBarPadding = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_spacing); mIconSize = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_size); + mExpandedBarIconsSpacing = getResources().getDimensionPixelSize( + R.dimen.bubblebar_expanded_icon_spacing); mBubbleElevation = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_elevation); mDragElevation = getResources().getDimensionPixelSize(R.dimen.bubblebar_drag_elevation); mPointerSize = getResources().getDimensionPixelSize(R.dimen.bubblebar_pointer_size); setClipToPadding(false); - mBubbleBarBackground = new BubbleBarBackground(context, - getResources().getDimensionPixelSize(R.dimen.bubblebar_size)); + mBubbleBarBackground = new BubbleBarBackground(context, getBubbleBarHeight()); setBackgroundDrawable(mBubbleBarBackground); mWidthAnimator.setDuration(WIDTH_ANIMATION_DURATION_MS); @@ -219,6 +222,29 @@ public class BubbleBarView extends FrameLayout { }); } + /** + * Sets new icon size and spacing between icons and bubble bar borders. + * + * @param newIconSize new icon size + * @param spacing spacing between icons and bubble bar borders. + */ + // TODO(b/335575529): animate bubble bar icons size change + public void setIconSizeAndPadding(float newIconSize, float spacing) { + // TODO(b/335457839): handle new bubble animation during the size change + mBubbleBarPadding = spacing; + mIconSize = newIconSize; + int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + View childView = getChildAt(i); + FrameLayout.LayoutParams params = (LayoutParams) childView.getLayoutParams(); + params.height = (int) mIconSize; + params.width = (int) mIconSize; + childView.setLayoutParams(params); + } + mBubbleBarBackground.setHeight(getBubbleBarHeight()); + updateLayoutParams(); + } + @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); @@ -516,6 +542,13 @@ public class BubbleBarView extends FrameLayout { setLayoutParams(lp); } + private void updateLayoutParams() { + LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); + lp.height = getBubbleBarHeight(); + lp.width = (int) (mIsBarExpanded ? expandedWidth() : collapsedWidth()); + setLayoutParams(lp); + } + /** @return the horizontal margin between the bubble bar and the edge of the screen. */ int getHorizontalMargin() { LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); @@ -551,12 +584,12 @@ public class BubbleBarView extends FrameLayout { final float collapsedX; if (onLeft) { // If bar is on the left, bubbles are ordered right to left - expandedX = (bubbleCount - i - 1) * (mIconSize + mIconSpacing); + expandedX = (bubbleCount - i - 1) * (mIconSize + mExpandedBarIconsSpacing); // Shift the first bubble only if there are more bubbles in addition to overflow collapsedX = i == 0 && bubbleCount > 2 ? mIconOverlapAmount : 0; } else { // Bubbles ordered left to right, don't move the first bubble - expandedX = i * (mIconSize + mIconSpacing); + expandedX = i * (mIconSize + mExpandedBarIconsSpacing); collapsedX = i == 0 ? 0 : mIconOverlapAmount; } @@ -599,14 +632,14 @@ public class BubbleBarView extends FrameLayout { final float interpolatedWidth = widthState * (expandedWidth - collapsedWidth) + collapsedWidth; final float arrowPosition; + + float interpolatedShift = (expandedArrowPosition - collapsedArrowPosition) * widthState; if (onLeft) { - float interpolatedShift = (expandedArrowPosition - collapsedArrowPosition) * widthState; arrowPosition = collapsedArrowPosition + interpolatedShift; } else { if (mIsBarExpanded) { - // when the bar is expanding, the selected bubble is always the first, so the arrow - // always shifts with the interpolated width. - arrowPosition = currentWidth - interpolatedWidth + collapsedArrowPosition; + arrowPosition = currentWidth - interpolatedWidth + collapsedArrowPosition + + interpolatedShift; } else { final float targetPosition = currentWidth - collapsedWidth + collapsedArrowPosition; arrowPosition = @@ -709,7 +742,8 @@ public class BubbleBarView extends FrameLayout { } else { bubblePosition = index; } - return getPaddingStart() + bubblePosition * (mIconSize + mIconSpacing) + mIconSize / 2f; + return getPaddingStart() + bubblePosition * (mIconSize + mExpandedBarIconsSpacing) + + mIconSize / 2f; } private float arrowPositionForSelectedWhenCollapsed() { @@ -770,7 +804,9 @@ public class BubbleBarView extends FrameLayout { public float expandedWidth() { final int childCount = getChildCount(); final int horizontalPadding = getPaddingStart() + getPaddingEnd(); - return childCount * (mIconSize + mIconSpacing) + horizontalPadding; + // spaces amount is less than child count by 1, or 0 if no child views + int spacesCount = Math.max(childCount - 1, 0); + return childCount * mIconSize + spacesCount * mExpandedBarIconsSpacing + horizontalPadding; } private float collapsedWidth() { @@ -783,6 +819,10 @@ public class BubbleBarView extends FrameLayout { : mIconSize + horizontalPadding; } + private int getBubbleBarHeight() { + return (int) (mIconSize + mBubbleBarPadding * 2 + mPointerSize); + } + /** * Returns whether the given MotionEvent, *in screen coordinates*, is within bubble bar * touch bounds. diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java index 86d8a9bfc2..a1a2898b9b 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java @@ -18,9 +18,12 @@ package com.android.launcher3.taskbar.bubbles; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; +import android.content.res.Resources; import android.graphics.Point; import android.graphics.Rect; +import android.util.DisplayMetrics; import android.util.Log; +import android.util.TypedValue; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; @@ -52,12 +55,13 @@ import java.util.function.Consumer; public class BubbleBarViewController { private static final String TAG = BubbleBarViewController.class.getSimpleName(); - + private static final float APP_ICON_SMALL_DP = 44f; + private static final float APP_ICON_MEDIUM_DP = 48f; + private static final float APP_ICON_LARGE_DP = 52f; private final SystemUiProxy mSystemUiProxy; private final TaskbarActivityContext mActivity; private final BubbleBarView mBarView; - private final int mIconSize; - private final int mPointerSize; + private int mIconSize; // Initialized in init. private BubbleStashController mBubbleStashController; @@ -96,9 +100,8 @@ public class BubbleBarViewController { mSystemUiProxy = SystemUiProxy.INSTANCE.get(mActivity); mBubbleBarAlpha = new MultiValueAlpha(mBarView, 1 /* num alpha channels */); mBubbleBarAlpha.setUpdateVisibility(true); - mIconSize = activity.getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_size); - mPointerSize = activity.getResources().getDimensionPixelSize( - R.dimen.bubblebar_pointer_size); + mIconSize = activity.getResources().getDimensionPixelSize( + R.dimen.bubblebar_icon_size); } public void init(TaskbarControllers controllers, BubbleControllers bubbleControllers) { @@ -108,12 +111,8 @@ public class BubbleBarViewController { mTaskbarStashController = controllers.taskbarStashController; mTaskbarInsetsController = controllers.taskbarInsetsController; - mActivity.addOnDeviceProfileChangeListener(dp -> - mBarView.getLayoutParams().height = - mActivity.getDeviceProfile().taskbarHeight + mPointerSize - ); - mBarView.getLayoutParams().height = - mActivity.getDeviceProfile().taskbarHeight + mPointerSize; + mActivity.addOnDeviceProfileChangeListener(dp -> setBubbleBarIconSize(dp.taskbarIconSize)); + setBubbleBarIconSize(mActivity.getDeviceProfile().taskbarIconSize); mBubbleBarScale.updateValue(1f); mBubbleClickListener = v -> onBubbleClicked(v); mBubbleBarClickListener = v -> onBubbleBarClicked(); @@ -260,6 +259,33 @@ public class BubbleBarViewController { } } + private void setBubbleBarIconSize(int newIconSize) { + if (newIconSize == mIconSize) { + return; + } + Resources res = mActivity.getResources(); + DisplayMetrics dm = res.getDisplayMetrics(); + float smallIconSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, + APP_ICON_SMALL_DP, dm); + float mediumIconSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, + APP_ICON_MEDIUM_DP, dm); + float largeIconSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, + APP_ICON_LARGE_DP, dm); + float smallMediumThreshold = (smallIconSize + mediumIconSize) / 2f; + float mediumLargeThreshold = (mediumIconSize + largeIconSize) / 2f; + mIconSize = newIconSize <= smallMediumThreshold + ? res.getDimensionPixelSize(R.dimen.bubblebar_icon_size_small) : + res.getDimensionPixelSize(R.dimen.bubblebar_icon_size); + float bubbleBarPadding = newIconSize >= mediumLargeThreshold + ? res.getDimensionPixelSize(R.dimen.bubblebar_icon_spacing_large) : + res.getDimensionPixelSize(R.dimen.bubblebar_icon_spacing); + + mBarView.setIconSizeAndPadding(mIconSize, bubbleBarPadding); + mBarView.setPadding((int) bubbleBarPadding, mBarView.getPaddingTop(), + (int) bubbleBarPadding, + mBarView.getPaddingBottom()); + } + /** Sets a callback that updates the selected bubble after the bubble bar collapses. */ public void setUpdateSelectedBubbleAfterCollapse( Consumer updateSelectedBubbleAfterCollapse) {