Merge "Align bubble bar stash anim with taskbar (1/n)" into main

This commit is contained in:
Ats Jenk
2024-09-10 00:45:36 +00:00
committed by Android (Google) Code Review
6 changed files with 97 additions and 25 deletions
@@ -71,6 +71,27 @@ class BubbleBarBackground(context: Context, private var backgroundHeight: Float)
}
}
/**
* Scale of the background in the x direction. Pivot is at the left edge if [anchorLeft] is
* `true` and at the right edge if it is `false`
*/
var scaleX: Float = 1f
set(value) {
if (field != value) {
field = value
invalidateSelf()
}
}
/** Scale of the background in the y direction. Pivot is at the bottom edge. */
var scaleY: Float = 1f
set(value) {
if (field != value) {
field = value
invalidateSelf()
}
}
init {
val res = context.resources
// configure fill paint
@@ -123,13 +144,17 @@ class BubbleBarBackground(context: Context, private var backgroundHeight: Float)
)
// Create background path
val backgroundPath = Path()
val topOffset = backgroundHeight - bounds.height().toFloat()
val scaledBackgroundHeight = backgroundHeight * scaleY
val scaledWidth = width * scaleX
val topOffset = scaledBackgroundHeight - bounds.height().toFloat()
val radius = backgroundHeight / 2f
val left = bounds.left + (if (anchorLeft) 0f else bounds.width().toFloat() - width)
val right = bounds.left + (if (anchorLeft) width else bounds.width().toFloat())
val top = bounds.top - topOffset + arrowVisibleHeight
val bottom = bounds.top + bounds.height().toFloat()
val left = bounds.left + (if (anchorLeft) 0f else bounds.width().toFloat() - scaledWidth)
val right = bounds.left + (if (anchorLeft) scaledWidth else bounds.width().toFloat())
// Calculate top with scaled heights for background and arrow to align with stash handle
val top = bounds.bottom - scaledBackgroundHeight + getScaledArrowVisibleHeight()
val bottom = bounds.bottom.toFloat()
backgroundPath.addRoundRect(left, top, right, bottom, radius, radius, Path.Direction.CW)
addArrowPathIfNeeded(backgroundPath, topOffset)
@@ -142,19 +167,20 @@ class BubbleBarBackground(context: Context, private var backgroundHeight: Float)
private fun addArrowPathIfNeeded(sourcePath: Path, topOffset: Float) {
if (!showingArrow || arrowHeightFraction <= 0) return
val arrowPath = Path()
val scaledHeight = getScaledArrowHeight()
RoundedArrowDrawable.addDownPointingRoundedTriangleToPath(
arrowWidth,
arrowHeight,
scaledHeight,
arrowTipRadius,
arrowPath
)
// flip it horizontally
val pathTransform = Matrix()
pathTransform.setRotate(180f, arrowWidth * 0.5f, arrowHeight * 0.5f)
pathTransform.setRotate(180f, arrowWidth * 0.5f, scaledHeight * 0.5f)
arrowPath.transform(pathTransform)
// shift to arrow position
val arrowStart = bounds.left + arrowPositionX - (arrowWidth / 2f)
val arrowTop = (1 - arrowHeightFraction) * arrowVisibleHeight - topOffset
val arrowTop = (1 - arrowHeightFraction) * getScaledArrowVisibleHeight() - topOffset
arrowPath.offset(arrowStart, arrowTop)
// union with rectangle
sourcePath.op(arrowPath, Path.Op.UNION)
@@ -183,6 +209,7 @@ class BubbleBarBackground(context: Context, private var backgroundHeight: Float)
fun setBackgroundHeight(newHeight: Float) {
backgroundHeight = newHeight
invalidateSelf()
}
/**
@@ -199,6 +226,14 @@ class BubbleBarBackground(context: Context, private var backgroundHeight: Float)
invalidateSelf()
}
private fun getScaledArrowHeight(): Float {
return arrowHeight * scaleY
}
private fun getScaledArrowVisibleHeight(): Float {
return max(0f, getScaledArrowHeight() - (arrowHeight - arrowVisibleHeight))
}
companion object {
private const val DARK_THEME_STROKE_ALPHA = 51
private const val LIGHT_THEME_STROKE_ALPHA = 41
@@ -305,6 +305,20 @@ public class BubbleBarView extends FrameLayout {
}
}
/**
* Set scale for bubble bar background in x direction
*/
public void setBackgroundScaleX(float scaleX) {
mBubbleBarBackground.setScaleX(scaleX);
}
/**
* Set scale for bubble bar background in y direction
*/
public void setBackgroundScaleY(float scaleY) {
mBubbleBarBackground.setScaleY(scaleY);
}
/**
* Sets new icon sizes and newBubbleBarPadding between icons and bubble bar borders.
*
@@ -322,7 +336,7 @@ public class BubbleBarView extends FrameLayout {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
childView.setScaleY(mIconScale);
childView.setScaleX(mIconScale);
childView.setScaleY(mIconScale);
FrameLayout.LayoutParams params = (LayoutParams) childView.getLayoutParams();
params.height = (int) mIconSize;
@@ -82,6 +82,10 @@ public class BubbleBarViewController {
private final MultiValueAlpha mBubbleBarAlpha;
private final AnimatedFloat mBubbleBarScaleX = new AnimatedFloat(this::updateScaleX);
private final AnimatedFloat mBubbleBarScaleY = new AnimatedFloat(this::updateScaleY);
private final AnimatedFloat mBubbleBarBackgroundScaleX = new AnimatedFloat(
this::updateBackgroundScaleX);
private final AnimatedFloat mBubbleBarBackgroundScaleY = new AnimatedFloat(
this::updateBackgroundScaleY);
private final AnimatedFloat mBubbleBarTranslationY = new AnimatedFloat(
this::updateTranslationY);
@@ -266,6 +270,14 @@ public class BubbleBarViewController {
return mBubbleBarScaleY;
}
public AnimatedFloat getBubbleBarBackgroundScaleX() {
return mBubbleBarBackgroundScaleX;
}
public AnimatedFloat getBubbleBarBackgroundScaleY() {
return mBubbleBarBackgroundScaleY;
}
public AnimatedFloat getBubbleBarTranslationY() {
return mBubbleBarTranslationY;
}
@@ -535,6 +547,14 @@ public class BubbleBarViewController {
mBarView.setScaleY(scale);
}
private void updateBackgroundScaleX(float scale) {
mBarView.setBackgroundScaleX(scale);
}
private void updateBackgroundScaleY(float scale) {
mBarView.setBackgroundScaleY(scale);
}
//
// Manipulating the specific bubble views in the bar
//
@@ -169,6 +169,8 @@ constructor(
bubbleBarView.translationY = 0f
bubbleBarView.scaleX = 1f
bubbleBarView.scaleY = BUBBLE_ANIMATION_INITIAL_SCALE_Y
bubbleBarView.setBackgroundScaleX(1f)
bubbleBarView.setBackgroundScaleY(1f)
bubbleBarView.relativePivotY = 0.5f
// this is the offset between the center of the bubble bar and the center of the stash
@@ -311,6 +313,7 @@ constructor(
animatingBubble = null
if (!canceled) bubbleStashController.stashBubbleBarImmediate()
bubbleBarView.relativePivotY = 1f
bubbleBarView.scaleY = 1f
bubbleStashController.updateTaskbarTouchRegion()
}
animator.start()
@@ -67,8 +67,8 @@ class TransientBubbleStashController(
// bubble bar properties
private lateinit var bubbleBarAlpha: MultiPropertyFactory<View>.MultiProperty
private lateinit var bubbleBarTranslationYAnimator: AnimatedFloat
private lateinit var bubbleBarScaleX: AnimatedFloat
private lateinit var bubbleBarScaleY: AnimatedFloat
private lateinit var bubbleBarBackgroundScaleX: AnimatedFloat
private lateinit var bubbleBarBackgroundScaleY: AnimatedFloat
private val handleCenterFromScreenBottom =
context.resources.getDimensionPixelSize(R.dimen.bubblebar_stashed_size) / 2f
@@ -149,8 +149,8 @@ class TransientBubbleStashController(
bubbleBarTranslationYAnimator = bubbleBarViewController.bubbleBarTranslationY
// bubble bar has only alpha property, getting it at index 0
bubbleBarAlpha = bubbleBarViewController.bubbleBarAlpha.get(/* index= */ 0)
bubbleBarScaleX = bubbleBarViewController.bubbleBarScaleX
bubbleBarScaleY = bubbleBarViewController.bubbleBarScaleY
bubbleBarBackgroundScaleX = bubbleBarViewController.bubbleBarBackgroundScaleX
bubbleBarBackgroundScaleY = bubbleBarViewController.bubbleBarBackgroundScaleY
stashedHeight = bubbleStashedHandleViewController?.stashedHeight ?: 0
stashHandleViewAlpha = bubbleStashedHandleViewController?.stashedHandleAlpha?.get(0)
}
@@ -160,8 +160,8 @@ class TransientBubbleStashController(
if (isBubblesShowingOnHome || isBubblesShowingOnOverview) {
isStashed = false
animatorSet.playTogether(
bubbleBarScaleX.animateToValue(1f),
bubbleBarScaleY.animateToValue(1f),
bubbleBarBackgroundScaleX.animateToValue(1f),
bubbleBarBackgroundScaleY.animateToValue(1f),
bubbleBarTranslationYAnimator.animateToValue(bubbleBarTranslationY),
bubbleBarAlpha.animateToValue(1f)
)
@@ -181,8 +181,8 @@ class TransientBubbleStashController(
stashHandleViewAlpha?.value = 0f
this.bubbleBarTranslationYAnimator.updateValue(bubbleBarTranslationY)
bubbleBarAlpha.setValue(1f)
bubbleBarScaleX.updateValue(1f)
bubbleBarScaleY.updateValue(1f)
bubbleBarBackgroundScaleX.updateValue(1f)
bubbleBarBackgroundScaleY.updateValue(1f)
isStashed = false
onIsStashedChanged()
}
@@ -192,8 +192,8 @@ class TransientBubbleStashController(
stashHandleViewAlpha?.value = 1f
this.bubbleBarTranslationYAnimator.updateValue(getStashTranslation())
bubbleBarAlpha.setValue(0f)
bubbleBarScaleX.updateValue(getStashScaleX())
bubbleBarScaleY.updateValue(getStashScaleY())
bubbleBarBackgroundScaleX.updateValue(getStashScaleX())
bubbleBarBackgroundScaleY.updateValue(getStashScaleY())
isStashed = true
onIsStashedChanged()
}
@@ -259,7 +259,7 @@ class TransientBubbleStashController(
override fun getHandleTranslationY(): Float? = bubbleStashedHandleViewController?.translationY
private fun getStashTranslation(): Float {
return bubbleBarTranslationY / 2f
return (bubbleBarTranslationY - stashedHeight) / 2f
}
@VisibleForTesting
@@ -366,8 +366,8 @@ class TransientBubbleStashController(
val scaleXTarget = if (isStashed) getStashScaleX() else 1f
val scaleYTarget = if (isStashed) getStashScaleY() else 1f
return AnimatorSet().apply {
play(bubbleBarScaleX.animateToValue(scaleXTarget))
play(bubbleBarScaleY.animateToValue(scaleYTarget))
play(bubbleBarBackgroundScaleX.animateToValue(scaleXTarget))
play(bubbleBarBackgroundScaleY.animateToValue(scaleYTarget))
}
}
@@ -60,7 +60,7 @@ class TransientBubbleStashControllerTest {
const val TASK_BAR_TRANSLATION_Y = -TASKBAR_BOTTOM_SPACE
const val HANDLE_VIEW_WIDTH = 150
const val HANDLE_VIEW_HEIGHT = 4
const val BUBBLE_BAR_STASHED_TRANSLATION_Y = -2.5f
const val BUBBLE_BAR_STASHED_TRANSLATION_Y = -4.5f
}
@get:Rule val animatorTestRule: AnimatorTestRule = AnimatorTestRule(this)
@@ -302,8 +302,8 @@ class TransientBubbleStashControllerTest {
whenever(bubbleBarViewController.hasBubbles()).thenReturn(true)
whenever(bubbleBarViewController.bubbleBarTranslationY).thenReturn(barTranslationY)
whenever(bubbleBarViewController.bubbleBarScaleX).thenReturn(barScaleX)
whenever(bubbleBarViewController.bubbleBarScaleY).thenReturn(barScaleY)
whenever(bubbleBarViewController.bubbleBarBackgroundScaleX).thenReturn(barScaleX)
whenever(bubbleBarViewController.bubbleBarBackgroundScaleY).thenReturn(barScaleY)
whenever(bubbleBarViewController.bubbleBarAlpha).thenReturn(barAlpha)
whenever(bubbleBarViewController.bubbleBarCollapsedWidth).thenReturn(BUBBLE_BAR_WIDTH)
whenever(bubbleBarViewController.bubbleBarCollapsedHeight).thenReturn(BUBBLE_BAR_HEIGHT)