Loading quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt +19 −9 Original line number Original line Diff line number Diff line Loading @@ -50,6 +50,22 @@ class BubbleBarBackground(context: TaskbarActivityContext, private val backgroun var width: Float = 0f var width: Float = 0f /** * Set whether the drawable is anchored to the left or right edge of the container. * * When `anchorLeft` is set to `true`, drawable left edge aligns up with the container left * edge. Drawable can be drawn outside container bounds on the right edge. When it is set to * `false` (the default), drawable right edge aligns up with the container right edge. Drawable * can be drawn outside container bounds on the left edge. */ var anchorLeft: Boolean = false set(value) { if (field != value) { field = value invalidateSelf() } } init { init { paint.color = context.getColor(R.color.taskbar_background) paint.color = context.getColor(R.color.taskbar_background) paint.flags = Paint.ANTI_ALIAS_FLAG paint.flags = Paint.ANTI_ALIAS_FLAG Loading Loading @@ -106,15 +122,9 @@ class BubbleBarBackground(context: TaskbarActivityContext, private val backgroun // Draw background. // Draw background. val radius = backgroundHeight / 2f val radius = backgroundHeight / 2f canvas.drawRoundRect( val left = if (anchorLeft) 0f else canvas.width.toFloat() - width canvas.width.toFloat() - width, val right = if (anchorLeft) width else canvas.width.toFloat() 0f, canvas.drawRoundRect(left, 0f, right, canvas.height.toFloat(), radius, radius, paint) canvas.width.toFloat(), canvas.height.toFloat(), radius, radius, paint ) if (showingArrow) { if (showingArrow) { // Draw arrow. // Draw arrow. Loading quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java +61 −18 Original line number Original line Diff line number Diff line Loading @@ -197,6 +197,16 @@ public class BubbleBarView extends FrameLayout { updateChildrenRenderNodeProperties(); updateChildrenRenderNodeProperties(); } } @Override public void onRtlPropertiesChanged(int layoutDirection) { // TODO(b/273310265): set this based on bubble bar position and not LTR or RTL mBubbleBarBackground.setAnchorLeft(layoutDirection == LAYOUT_DIRECTION_RTL); } private boolean isOnLeft() { return getLayoutDirection() == LAYOUT_DIRECTION_RTL; } /** /** * Updates the bounds with translation that may have been applied and returns the result. * Updates the bounds with translation that may have been applied and returns the result. */ */ Loading Loading @@ -275,18 +285,31 @@ public class BubbleBarView extends FrameLayout { int bubbleCount = getChildCount(); int bubbleCount = getChildCount(); final float ty = (mBubbleBarBounds.height() - mIconSize) / 2f; final float ty = (mBubbleBarBounds.height() - mIconSize) / 2f; final boolean animate = getVisibility() == VISIBLE; final boolean animate = getVisibility() == VISIBLE; final boolean onLeft = isOnLeft(); for (int i = 0; i < bubbleCount; i++) { for (int i = 0; i < bubbleCount; i++) { BubbleView bv = (BubbleView) getChildAt(i); BubbleView bv = (BubbleView) getChildAt(i); bv.setTranslationY(ty); bv.setTranslationY(ty); // the position of the bubble when the bar is fully expanded // the position of the bubble when the bar is fully expanded final float expandedX = i * (mIconSize + mIconSpacing); final float expandedX; // the position of the bubble when the bar is fully collapsed // the position of the bubble when the bar is fully collapsed final float collapsedX = i == 0 ? 0 : mIconOverlapAmount; final float collapsedX; if (onLeft) { // If bar is on the left, bubbles are ordered right to left expandedX = (bubbleCount - i - 1) * (mIconSize + mIconSpacing); // 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); collapsedX = i == 0 ? 0 : mIconOverlapAmount; } if (mIsBarExpanded) { if (mIsBarExpanded) { // If bar is on the right, account for bubble bar expanding and shifting left final float expandedBarShift = onLeft ? 0 : currentWidth - expandedWidth; // where the bubble will end up when the animation ends // where the bubble will end up when the animation ends final float targetX = currentWidth - expandedWidth + expandedX; final float targetX = expandedX + expandedBarShift; bv.setTranslationX(widthState * (targetX - collapsedX) + collapsedX); bv.setTranslationX(widthState * (targetX - collapsedX) + collapsedX); // if we're fully expanded, set the z level to 0 or to bubble elevation if dragged // if we're fully expanded, set the z level to 0 or to bubble elevation if dragged if (widthState == 1f) { if (widthState == 1f) { Loading @@ -296,7 +319,9 @@ public class BubbleBarView extends FrameLayout { bv.setBehindStack(false, animate); bv.setBehindStack(false, animate); bv.setAlpha(1); bv.setAlpha(1); } else { } else { final float targetX = currentWidth - collapsedWidth + collapsedX; // If bar is on the right, account for bubble bar expanding and shifting left final float collapsedBarShift = onLeft ? 0 : currentWidth - collapsedWidth; final float targetX = collapsedX + collapsedBarShift; bv.setTranslationX(widthState * (expandedX - targetX) + targetX); bv.setTranslationX(widthState * (expandedX - targetX) + targetX); bv.setZ((MAX_BUBBLES * mBubbleElevation) - i); bv.setZ((MAX_BUBBLES * mBubbleElevation) - i); // If we're not the first bubble we're behind the stack // If we're not the first bubble we're behind the stack Loading @@ -318,18 +343,22 @@ public class BubbleBarView extends FrameLayout { final float expandedArrowPosition = arrowPositionForSelectedWhenExpanded(); final float expandedArrowPosition = arrowPositionForSelectedWhenExpanded(); final float interpolatedWidth = final float interpolatedWidth = widthState * (expandedWidth - collapsedWidth) + collapsedWidth; widthState * (expandedWidth - collapsedWidth) + collapsedWidth; final float arrowPosition; if (onLeft) { float interpolatedShift = (expandedArrowPosition - collapsedArrowPosition) * widthState; arrowPosition = collapsedArrowPosition + interpolatedShift; } else { if (mIsBarExpanded) { if (mIsBarExpanded) { // when the bar is expanding, the selected bubble is always the first, so the arrow // when the bar is expanding, the selected bubble is always the first, so the arrow // always shifts with the interpolated width. // always shifts with the interpolated width. final float arrowPosition = currentWidth - interpolatedWidth + collapsedArrowPosition; arrowPosition = currentWidth - interpolatedWidth + collapsedArrowPosition; mBubbleBarBackground.setArrowPosition(arrowPosition); } else { } else { final float targetPosition = currentWidth - collapsedWidth + collapsedArrowPosition; final float targetPosition = currentWidth - collapsedWidth + collapsedArrowPosition; final float arrowPosition = arrowPosition = targetPosition + widthState * (expandedArrowPosition - targetPosition); targetPosition + widthState * (expandedArrowPosition - targetPosition); mBubbleBarBackground.setArrowPosition(arrowPosition); } } } mBubbleBarBackground.setArrowPosition(arrowPosition); mBubbleBarBackground.setArrowAlpha((int) (255 * widthState)); mBubbleBarBackground.setArrowAlpha((int) (255 * widthState)); mBubbleBarBackground.setWidth(interpolatedWidth); mBubbleBarBackground.setWidth(interpolatedWidth); } } Loading Loading @@ -394,9 +423,8 @@ public class BubbleBarView extends FrameLayout { Log.w(TAG, "trying to update selection arrow without a selected view!"); Log.w(TAG, "trying to update selection arrow without a selected view!"); return; return; } } final int index = indexOfChild(mSelectedBubbleView); // Find the center of the bubble when it's expanded, set the arrow position to it. // Find the center of the bubble when it's expanded, set the arrow position to it. final float tx = getPaddingStart() + index * (mIconSize + mIconSpacing) + mIconSize / 2f; final float tx = arrowPositionForSelectedWhenExpanded(); if (shouldAnimate) { if (shouldAnimate) { final float currentArrowPosition = mBubbleBarBackground.getArrowPositionX(); final float currentArrowPosition = mBubbleBarBackground.getArrowPositionX(); Loading @@ -416,12 +444,27 @@ public class BubbleBarView extends FrameLayout { private float arrowPositionForSelectedWhenExpanded() { private float arrowPositionForSelectedWhenExpanded() { final int index = indexOfChild(mSelectedBubbleView); final int index = indexOfChild(mSelectedBubbleView); return getPaddingStart() + index * (mIconSize + mIconSpacing) + mIconSize / 2f; final int bubblePosition; if (isOnLeft()) { // Bubble positions are reversed. First bubble is on the right. bubblePosition = getChildCount() - index - 1; } else { bubblePosition = index; } return getPaddingStart() + bubblePosition * (mIconSize + mIconSpacing) + mIconSize / 2f; } } private float arrowPositionForSelectedWhenCollapsed() { private float arrowPositionForSelectedWhenCollapsed() { final int index = indexOfChild(mSelectedBubbleView); final int index = indexOfChild(mSelectedBubbleView); return getPaddingStart() + index * (mIconOverlapAmount) + mIconSize / 2f; final int bubblePosition; if (isOnLeft()) { // Bubble positions are reversed. First bubble may be shifted, if there are more // bubbles than the current bubble and overflow. bubblePosition = index == 0 && getChildCount() > 2 ? 1 : 0; } else { bubblePosition = index; } return getPaddingStart() + bubblePosition * (mIconOverlapAmount) + mIconSize / 2f; } } @Override @Override Loading quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.view.View.VISIBLE; import android.graphics.Point; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Rect; import android.util.Log; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.MotionEvent; import android.view.View; import android.view.View; import android.widget.FrameLayout; import android.widget.FrameLayout; Loading Loading @@ -289,7 +290,8 @@ public class BubbleBarViewController { */ */ public void addBubble(BubbleBarItem b) { public void addBubble(BubbleBarItem b) { if (b != null) { if (b != null) { mBarView.addView(b.getView(), 0, new FrameLayout.LayoutParams(mIconSize, mIconSize)); mBarView.addView(b.getView(), 0, new FrameLayout.LayoutParams(mIconSize, mIconSize, Gravity.LEFT)); b.getView().setOnClickListener(mBubbleClickListener); b.getView().setOnClickListener(mBubbleClickListener); mBubbleDragController.setupBubbleView(b.getView()); mBubbleDragController.setupBubbleView(b.getView()); } else { } else { Loading Loading
quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt +19 −9 Original line number Original line Diff line number Diff line Loading @@ -50,6 +50,22 @@ class BubbleBarBackground(context: TaskbarActivityContext, private val backgroun var width: Float = 0f var width: Float = 0f /** * Set whether the drawable is anchored to the left or right edge of the container. * * When `anchorLeft` is set to `true`, drawable left edge aligns up with the container left * edge. Drawable can be drawn outside container bounds on the right edge. When it is set to * `false` (the default), drawable right edge aligns up with the container right edge. Drawable * can be drawn outside container bounds on the left edge. */ var anchorLeft: Boolean = false set(value) { if (field != value) { field = value invalidateSelf() } } init { init { paint.color = context.getColor(R.color.taskbar_background) paint.color = context.getColor(R.color.taskbar_background) paint.flags = Paint.ANTI_ALIAS_FLAG paint.flags = Paint.ANTI_ALIAS_FLAG Loading Loading @@ -106,15 +122,9 @@ class BubbleBarBackground(context: TaskbarActivityContext, private val backgroun // Draw background. // Draw background. val radius = backgroundHeight / 2f val radius = backgroundHeight / 2f canvas.drawRoundRect( val left = if (anchorLeft) 0f else canvas.width.toFloat() - width canvas.width.toFloat() - width, val right = if (anchorLeft) width else canvas.width.toFloat() 0f, canvas.drawRoundRect(left, 0f, right, canvas.height.toFloat(), radius, radius, paint) canvas.width.toFloat(), canvas.height.toFloat(), radius, radius, paint ) if (showingArrow) { if (showingArrow) { // Draw arrow. // Draw arrow. Loading
quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java +61 −18 Original line number Original line Diff line number Diff line Loading @@ -197,6 +197,16 @@ public class BubbleBarView extends FrameLayout { updateChildrenRenderNodeProperties(); updateChildrenRenderNodeProperties(); } } @Override public void onRtlPropertiesChanged(int layoutDirection) { // TODO(b/273310265): set this based on bubble bar position and not LTR or RTL mBubbleBarBackground.setAnchorLeft(layoutDirection == LAYOUT_DIRECTION_RTL); } private boolean isOnLeft() { return getLayoutDirection() == LAYOUT_DIRECTION_RTL; } /** /** * Updates the bounds with translation that may have been applied and returns the result. * Updates the bounds with translation that may have been applied and returns the result. */ */ Loading Loading @@ -275,18 +285,31 @@ public class BubbleBarView extends FrameLayout { int bubbleCount = getChildCount(); int bubbleCount = getChildCount(); final float ty = (mBubbleBarBounds.height() - mIconSize) / 2f; final float ty = (mBubbleBarBounds.height() - mIconSize) / 2f; final boolean animate = getVisibility() == VISIBLE; final boolean animate = getVisibility() == VISIBLE; final boolean onLeft = isOnLeft(); for (int i = 0; i < bubbleCount; i++) { for (int i = 0; i < bubbleCount; i++) { BubbleView bv = (BubbleView) getChildAt(i); BubbleView bv = (BubbleView) getChildAt(i); bv.setTranslationY(ty); bv.setTranslationY(ty); // the position of the bubble when the bar is fully expanded // the position of the bubble when the bar is fully expanded final float expandedX = i * (mIconSize + mIconSpacing); final float expandedX; // the position of the bubble when the bar is fully collapsed // the position of the bubble when the bar is fully collapsed final float collapsedX = i == 0 ? 0 : mIconOverlapAmount; final float collapsedX; if (onLeft) { // If bar is on the left, bubbles are ordered right to left expandedX = (bubbleCount - i - 1) * (mIconSize + mIconSpacing); // 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); collapsedX = i == 0 ? 0 : mIconOverlapAmount; } if (mIsBarExpanded) { if (mIsBarExpanded) { // If bar is on the right, account for bubble bar expanding and shifting left final float expandedBarShift = onLeft ? 0 : currentWidth - expandedWidth; // where the bubble will end up when the animation ends // where the bubble will end up when the animation ends final float targetX = currentWidth - expandedWidth + expandedX; final float targetX = expandedX + expandedBarShift; bv.setTranslationX(widthState * (targetX - collapsedX) + collapsedX); bv.setTranslationX(widthState * (targetX - collapsedX) + collapsedX); // if we're fully expanded, set the z level to 0 or to bubble elevation if dragged // if we're fully expanded, set the z level to 0 or to bubble elevation if dragged if (widthState == 1f) { if (widthState == 1f) { Loading @@ -296,7 +319,9 @@ public class BubbleBarView extends FrameLayout { bv.setBehindStack(false, animate); bv.setBehindStack(false, animate); bv.setAlpha(1); bv.setAlpha(1); } else { } else { final float targetX = currentWidth - collapsedWidth + collapsedX; // If bar is on the right, account for bubble bar expanding and shifting left final float collapsedBarShift = onLeft ? 0 : currentWidth - collapsedWidth; final float targetX = collapsedX + collapsedBarShift; bv.setTranslationX(widthState * (expandedX - targetX) + targetX); bv.setTranslationX(widthState * (expandedX - targetX) + targetX); bv.setZ((MAX_BUBBLES * mBubbleElevation) - i); bv.setZ((MAX_BUBBLES * mBubbleElevation) - i); // If we're not the first bubble we're behind the stack // If we're not the first bubble we're behind the stack Loading @@ -318,18 +343,22 @@ public class BubbleBarView extends FrameLayout { final float expandedArrowPosition = arrowPositionForSelectedWhenExpanded(); final float expandedArrowPosition = arrowPositionForSelectedWhenExpanded(); final float interpolatedWidth = final float interpolatedWidth = widthState * (expandedWidth - collapsedWidth) + collapsedWidth; widthState * (expandedWidth - collapsedWidth) + collapsedWidth; final float arrowPosition; if (onLeft) { float interpolatedShift = (expandedArrowPosition - collapsedArrowPosition) * widthState; arrowPosition = collapsedArrowPosition + interpolatedShift; } else { if (mIsBarExpanded) { if (mIsBarExpanded) { // when the bar is expanding, the selected bubble is always the first, so the arrow // when the bar is expanding, the selected bubble is always the first, so the arrow // always shifts with the interpolated width. // always shifts with the interpolated width. final float arrowPosition = currentWidth - interpolatedWidth + collapsedArrowPosition; arrowPosition = currentWidth - interpolatedWidth + collapsedArrowPosition; mBubbleBarBackground.setArrowPosition(arrowPosition); } else { } else { final float targetPosition = currentWidth - collapsedWidth + collapsedArrowPosition; final float targetPosition = currentWidth - collapsedWidth + collapsedArrowPosition; final float arrowPosition = arrowPosition = targetPosition + widthState * (expandedArrowPosition - targetPosition); targetPosition + widthState * (expandedArrowPosition - targetPosition); mBubbleBarBackground.setArrowPosition(arrowPosition); } } } mBubbleBarBackground.setArrowPosition(arrowPosition); mBubbleBarBackground.setArrowAlpha((int) (255 * widthState)); mBubbleBarBackground.setArrowAlpha((int) (255 * widthState)); mBubbleBarBackground.setWidth(interpolatedWidth); mBubbleBarBackground.setWidth(interpolatedWidth); } } Loading Loading @@ -394,9 +423,8 @@ public class BubbleBarView extends FrameLayout { Log.w(TAG, "trying to update selection arrow without a selected view!"); Log.w(TAG, "trying to update selection arrow without a selected view!"); return; return; } } final int index = indexOfChild(mSelectedBubbleView); // Find the center of the bubble when it's expanded, set the arrow position to it. // Find the center of the bubble when it's expanded, set the arrow position to it. final float tx = getPaddingStart() + index * (mIconSize + mIconSpacing) + mIconSize / 2f; final float tx = arrowPositionForSelectedWhenExpanded(); if (shouldAnimate) { if (shouldAnimate) { final float currentArrowPosition = mBubbleBarBackground.getArrowPositionX(); final float currentArrowPosition = mBubbleBarBackground.getArrowPositionX(); Loading @@ -416,12 +444,27 @@ public class BubbleBarView extends FrameLayout { private float arrowPositionForSelectedWhenExpanded() { private float arrowPositionForSelectedWhenExpanded() { final int index = indexOfChild(mSelectedBubbleView); final int index = indexOfChild(mSelectedBubbleView); return getPaddingStart() + index * (mIconSize + mIconSpacing) + mIconSize / 2f; final int bubblePosition; if (isOnLeft()) { // Bubble positions are reversed. First bubble is on the right. bubblePosition = getChildCount() - index - 1; } else { bubblePosition = index; } return getPaddingStart() + bubblePosition * (mIconSize + mIconSpacing) + mIconSize / 2f; } } private float arrowPositionForSelectedWhenCollapsed() { private float arrowPositionForSelectedWhenCollapsed() { final int index = indexOfChild(mSelectedBubbleView); final int index = indexOfChild(mSelectedBubbleView); return getPaddingStart() + index * (mIconOverlapAmount) + mIconSize / 2f; final int bubblePosition; if (isOnLeft()) { // Bubble positions are reversed. First bubble may be shifted, if there are more // bubbles than the current bubble and overflow. bubblePosition = index == 0 && getChildCount() > 2 ? 1 : 0; } else { bubblePosition = index; } return getPaddingStart() + bubblePosition * (mIconOverlapAmount) + mIconSize / 2f; } } @Override @Override Loading
quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.view.View.VISIBLE; import android.graphics.Point; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Rect; import android.util.Log; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.MotionEvent; import android.view.View; import android.view.View; import android.widget.FrameLayout; import android.widget.FrameLayout; Loading Loading @@ -289,7 +290,8 @@ public class BubbleBarViewController { */ */ public void addBubble(BubbleBarItem b) { public void addBubble(BubbleBarItem b) { if (b != null) { if (b != null) { mBarView.addView(b.getView(), 0, new FrameLayout.LayoutParams(mIconSize, mIconSize)); mBarView.addView(b.getView(), 0, new FrameLayout.LayoutParams(mIconSize, mIconSize, Gravity.LEFT)); b.getView().setOnClickListener(mBubbleClickListener); b.getView().setOnClickListener(mBubbleClickListener); mBubbleDragController.setupBubbleView(b.getView()); mBubbleDragController.setupBubbleView(b.getView()); } else { } else { Loading