Loading libs/WindowManager/Shell/res/layout/bubble_bar_expanded_view.xml +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="vertical" android:clipChildren="false" android:id="@+id/bubble_expanded_view"> <com.android.wm.shell.bubbles.bar.BubbleBarHandleView Loading libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml +6 −8 Original line number Diff line number Diff line Loading @@ -14,20 +14,18 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> <com.android.wm.shell.bubbles.bar.BubbleBarMenuView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" <com.android.wm.shell.bubbles.bar.BubbleBarMenuView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:clipToPadding="false" android:minWidth="@dimen/bubble_bar_manage_menu_min_width" android:orientation="vertical" android:elevation="@dimen/bubble_manage_menu_elevation" android:paddingTop="@dimen/bubble_bar_manage_menu_padding_top" android:paddingHorizontal="@dimen/bubble_bar_manage_menu_padding" android:paddingBottom="@dimen/bubble_bar_manage_menu_padding" android:clipToPadding="false"> android:visibility="invisible" tools:visibility="visible"> <LinearLayout android:id="@+id/bubble_bar_manage_menu_bubble_section" Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java +1 −1 Original line number Diff line number Diff line Loading @@ -222,7 +222,7 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView mHandleView.setAccessibilityDelegate(new HandleViewAccessibilityDelegate()); } mMenuViewController = new BubbleBarMenuViewController(mContext, this); mMenuViewController = new BubbleBarMenuViewController(mContext, mHandleView, this); mMenuViewController.setListener(new BubbleBarMenuViewController.Listener() { @Override public void onMenuVisibilityChanged(boolean visible) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java +101 −27 Original line number Diff line number Diff line Loading @@ -17,17 +17,18 @@ package com.android.wm.shell.bubbles.bar; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ArgbEvaluator; import android.animation.ObjectAnimator; import android.annotation.Nullable; import android.content.Context; import android.graphics.Outline; import android.graphics.Path; import android.graphics.RectF; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; import android.view.ViewOutlineProvider; import androidx.annotation.ColorInt; import androidx.annotation.VisibleForTesting; import androidx.core.animation.IntProperty; import androidx.core.content.ContextCompat; import com.android.wm.shell.R; Loading @@ -37,14 +38,33 @@ import com.android.wm.shell.R; */ public class BubbleBarHandleView extends View { private static final long COLOR_CHANGE_DURATION = 120; // Path used to draw the dots private final Path mPath = new Path(); /** Custom property to set handle color. */ private static final IntProperty<BubbleBarHandleView> HANDLE_COLOR = new IntProperty<>( "handleColor") { @Override public void setValue(BubbleBarHandleView bubbleBarHandleView, int color) { bubbleBarHandleView.setHandleColor(color); } @Override public Integer get(BubbleBarHandleView bubbleBarHandleView) { return bubbleBarHandleView.getHandleColor(); } }; @VisibleForTesting final Paint mHandlePaint = new Paint(); private final @ColorInt int mHandleLightColor; private final @ColorInt int mHandleDarkColor; private @ColorInt int mCurrentColor; private final ArgbEvaluator mArgbEvaluator = ArgbEvaluator.getInstance(); private final float mHandleHeight; private final float mHandleWidth; private float mCurrentHandleHeight; private float mCurrentHandleWidth; @Nullable private ObjectAnimator mColorChangeAnim; private @ColorInt int mRegionSamplerColor; public BubbleBarHandleView(Context context) { this(context, null /* attrs */); Loading @@ -61,28 +81,50 @@ public class BubbleBarHandleView extends View { public BubbleBarHandleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); final int handleHeight = getResources().getDimensionPixelSize( mHandlePaint.setFlags(Paint.ANTI_ALIAS_FLAG); mHandlePaint.setStyle(Paint.Style.FILL); mHandlePaint.setColor(0); mHandleHeight = getResources().getDimensionPixelSize( R.dimen.bubble_bar_expanded_view_handle_height); mHandleWidth = getResources().getDimensionPixelSize( R.dimen.bubble_bar_expanded_view_caption_width); mHandleLightColor = ContextCompat.getColor(getContext(), R.color.bubble_bar_expanded_view_handle_light); mHandleDarkColor = ContextCompat.getColor(getContext(), R.color.bubble_bar_expanded_view_handle_dark); mCurrentHandleHeight = mHandleHeight; mCurrentHandleWidth = mHandleWidth; setContentDescription(getResources().getString(R.string.handle_text)); } private void setHandleColor(int color) { mHandlePaint.setColor(color); invalidate(); } private int getHandleColor() { return mHandlePaint.getColor(); } setClipToOutline(true); setOutlineProvider(new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { final int handleCenterY = view.getHeight() / 2; final int handleTop = handleCenterY - handleHeight / 2; final int handleBottom = handleTop + handleHeight; final int radius = handleHeight / 2; RectF handle = new RectF(/* left = */ 0, handleTop, view.getWidth(), handleBottom); mPath.reset(); mPath.addRoundRect(handle, radius, radius, Path.Direction.CW); outline.setPath(mPath); protected void onDraw(Canvas canvas) { super.onDraw(canvas); float handleLeft = (getWidth() - mCurrentHandleWidth) / 2; float handleRight = handleLeft + mCurrentHandleWidth; float handleCenterY = (float) getHeight() / 2; float handleTop = (int) (handleCenterY - mCurrentHandleHeight / 2); float handleBottom = handleTop + mCurrentHandleHeight; float cornerRadius = mCurrentHandleHeight / 2; canvas.drawRoundRect(handleLeft, handleTop, handleRight, handleBottom, cornerRadius, cornerRadius, mHandlePaint); } }); setContentDescription(getResources().getString(R.string.handle_text)); /** Sets handle width, height and color. Does not change the layout properties */ private void setHandleProperties(float width, float height, int color) { mCurrentHandleHeight = height; mCurrentHandleWidth = width; mHandlePaint.setColor(color); invalidate(); } /** Loading @@ -94,15 +136,15 @@ public class BubbleBarHandleView extends View { */ public void updateHandleColor(boolean isRegionDark, boolean animated) { int newColor = isRegionDark ? mHandleLightColor : mHandleDarkColor; if (newColor == mCurrentColor) { if (newColor == mRegionSamplerColor) { return; } mRegionSamplerColor = newColor; if (mColorChangeAnim != null) { mColorChangeAnim.cancel(); } mCurrentColor = newColor; if (animated) { mColorChangeAnim = ObjectAnimator.ofArgb(this, "backgroundColor", newColor); mColorChangeAnim = ObjectAnimator.ofArgb(this, HANDLE_COLOR, newColor); mColorChangeAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { Loading @@ -112,7 +154,39 @@ public class BubbleBarHandleView extends View { mColorChangeAnim.setDuration(COLOR_CHANGE_DURATION); mColorChangeAnim.start(); } else { setBackgroundColor(newColor); setHandleColor(newColor); } } /** Returns handle padding top. */ public int getHandlePaddingTop() { return (getHeight() - getResources().getDimensionPixelSize( R.dimen.bubble_bar_expanded_view_handle_height)) / 2; } /** Animates handle for the bubble menu. */ public void animateHandleForMenu(float progress, float widthDelta, float heightDelta, int menuColor) { float currentWidth = mHandleWidth + widthDelta * progress; float currentHeight = mHandleHeight + heightDelta * progress; int color = (int) mArgbEvaluator.evaluate(progress, mRegionSamplerColor, menuColor); setHandleProperties(currentWidth, currentHeight, color); setTranslationY(heightDelta * progress / 2); } /** Restores all the properties that were animated to the default values. */ public void restoreAnimationDefaults() { setHandleProperties(mHandleWidth, mHandleHeight, mRegionSamplerColor); setTranslationY(0); } /** Returns the handle height. */ public int getHandleHeight() { return (int) mHandleHeight; } /** Returns the handle width. */ public int getHandleWidth() { return (int) mHandleWidth; } } libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java +38 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,10 @@ public class BubbleBarMenuView extends LinearLayout { private ImageView mBubbleIconView; private ImageView mBubbleDismissIconView; private TextView mBubbleTitleView; // The animation has three stages. Each stage transition lasts until the animation ends. In // stage 1, the title item content fades in. In stage 2, the background of the option items // fades in. In stage 3, the option item content fades in. private static final int SHOW_MENU_STAGES_COUNT = 3; public BubbleBarMenuView(Context context) { this(context, null /* attrs */); Loading Loading @@ -97,6 +101,35 @@ public class BubbleBarMenuView extends LinearLayout { } } /** Animates the menu from the specified start scale. */ public void animateFromStartScale(float currentScale, float progress) { int menuItemElevation = getResources().getDimensionPixelSize( R.dimen.bubble_manage_menu_elevation); setScaleX(currentScale); setScaleY(currentScale); setAlphaForTitleViews(progress); mBubbleSectionView.setElevation(menuItemElevation * progress); float actionsBackgroundAlpha = Math.max(0, (progress - (float) 1 / SHOW_MENU_STAGES_COUNT) * (SHOW_MENU_STAGES_COUNT - 1)); float actionItemsAlpha = Math.max(0, (progress - (float) 2 / SHOW_MENU_STAGES_COUNT) * SHOW_MENU_STAGES_COUNT); mActionsSectionView.setAlpha(actionsBackgroundAlpha); mActionsSectionView.setElevation(menuItemElevation * actionsBackgroundAlpha); setMenuItemViewsAlpha(actionItemsAlpha); } private void setAlphaForTitleViews(float alpha) { mBubbleIconView.setAlpha(alpha); mBubbleTitleView.setAlpha(alpha); mBubbleDismissIconView.setAlpha(alpha); } private void setMenuItemViewsAlpha(float alpha) { for (int i = mActionsSectionView.getChildCount() - 1; i >= 0; i--) { mActionsSectionView.getChildAt(i).setAlpha(alpha); } } /** Update menu details with bubble info */ void updateInfo(Bubble bubble) { if (bubble.getIcon() != null) { Loading Loading @@ -153,6 +186,11 @@ public class BubbleBarMenuView extends LinearLayout { return mBubbleSectionView.getAlpha(); } /** Return title menu item height. */ public float getTitleItemHeight() { return mBubbleSectionView.getHeight(); } /** * Menu action details used to create menu items */ Loading Loading
libs/WindowManager/Shell/res/layout/bubble_bar_expanded_view.xml +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="vertical" android:clipChildren="false" android:id="@+id/bubble_expanded_view"> <com.android.wm.shell.bubbles.bar.BubbleBarHandleView Loading
libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml +6 −8 Original line number Diff line number Diff line Loading @@ -14,20 +14,18 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> <com.android.wm.shell.bubbles.bar.BubbleBarMenuView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" <com.android.wm.shell.bubbles.bar.BubbleBarMenuView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:clipToPadding="false" android:minWidth="@dimen/bubble_bar_manage_menu_min_width" android:orientation="vertical" android:elevation="@dimen/bubble_manage_menu_elevation" android:paddingTop="@dimen/bubble_bar_manage_menu_padding_top" android:paddingHorizontal="@dimen/bubble_bar_manage_menu_padding" android:paddingBottom="@dimen/bubble_bar_manage_menu_padding" android:clipToPadding="false"> android:visibility="invisible" tools:visibility="visible"> <LinearLayout android:id="@+id/bubble_bar_manage_menu_bubble_section" Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java +1 −1 Original line number Diff line number Diff line Loading @@ -222,7 +222,7 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView mHandleView.setAccessibilityDelegate(new HandleViewAccessibilityDelegate()); } mMenuViewController = new BubbleBarMenuViewController(mContext, this); mMenuViewController = new BubbleBarMenuViewController(mContext, mHandleView, this); mMenuViewController.setListener(new BubbleBarMenuViewController.Listener() { @Override public void onMenuVisibilityChanged(boolean visible) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java +101 −27 Original line number Diff line number Diff line Loading @@ -17,17 +17,18 @@ package com.android.wm.shell.bubbles.bar; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ArgbEvaluator; import android.animation.ObjectAnimator; import android.annotation.Nullable; import android.content.Context; import android.graphics.Outline; import android.graphics.Path; import android.graphics.RectF; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; import android.view.ViewOutlineProvider; import androidx.annotation.ColorInt; import androidx.annotation.VisibleForTesting; import androidx.core.animation.IntProperty; import androidx.core.content.ContextCompat; import com.android.wm.shell.R; Loading @@ -37,14 +38,33 @@ import com.android.wm.shell.R; */ public class BubbleBarHandleView extends View { private static final long COLOR_CHANGE_DURATION = 120; // Path used to draw the dots private final Path mPath = new Path(); /** Custom property to set handle color. */ private static final IntProperty<BubbleBarHandleView> HANDLE_COLOR = new IntProperty<>( "handleColor") { @Override public void setValue(BubbleBarHandleView bubbleBarHandleView, int color) { bubbleBarHandleView.setHandleColor(color); } @Override public Integer get(BubbleBarHandleView bubbleBarHandleView) { return bubbleBarHandleView.getHandleColor(); } }; @VisibleForTesting final Paint mHandlePaint = new Paint(); private final @ColorInt int mHandleLightColor; private final @ColorInt int mHandleDarkColor; private @ColorInt int mCurrentColor; private final ArgbEvaluator mArgbEvaluator = ArgbEvaluator.getInstance(); private final float mHandleHeight; private final float mHandleWidth; private float mCurrentHandleHeight; private float mCurrentHandleWidth; @Nullable private ObjectAnimator mColorChangeAnim; private @ColorInt int mRegionSamplerColor; public BubbleBarHandleView(Context context) { this(context, null /* attrs */); Loading @@ -61,28 +81,50 @@ public class BubbleBarHandleView extends View { public BubbleBarHandleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); final int handleHeight = getResources().getDimensionPixelSize( mHandlePaint.setFlags(Paint.ANTI_ALIAS_FLAG); mHandlePaint.setStyle(Paint.Style.FILL); mHandlePaint.setColor(0); mHandleHeight = getResources().getDimensionPixelSize( R.dimen.bubble_bar_expanded_view_handle_height); mHandleWidth = getResources().getDimensionPixelSize( R.dimen.bubble_bar_expanded_view_caption_width); mHandleLightColor = ContextCompat.getColor(getContext(), R.color.bubble_bar_expanded_view_handle_light); mHandleDarkColor = ContextCompat.getColor(getContext(), R.color.bubble_bar_expanded_view_handle_dark); mCurrentHandleHeight = mHandleHeight; mCurrentHandleWidth = mHandleWidth; setContentDescription(getResources().getString(R.string.handle_text)); } private void setHandleColor(int color) { mHandlePaint.setColor(color); invalidate(); } private int getHandleColor() { return mHandlePaint.getColor(); } setClipToOutline(true); setOutlineProvider(new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { final int handleCenterY = view.getHeight() / 2; final int handleTop = handleCenterY - handleHeight / 2; final int handleBottom = handleTop + handleHeight; final int radius = handleHeight / 2; RectF handle = new RectF(/* left = */ 0, handleTop, view.getWidth(), handleBottom); mPath.reset(); mPath.addRoundRect(handle, radius, radius, Path.Direction.CW); outline.setPath(mPath); protected void onDraw(Canvas canvas) { super.onDraw(canvas); float handleLeft = (getWidth() - mCurrentHandleWidth) / 2; float handleRight = handleLeft + mCurrentHandleWidth; float handleCenterY = (float) getHeight() / 2; float handleTop = (int) (handleCenterY - mCurrentHandleHeight / 2); float handleBottom = handleTop + mCurrentHandleHeight; float cornerRadius = mCurrentHandleHeight / 2; canvas.drawRoundRect(handleLeft, handleTop, handleRight, handleBottom, cornerRadius, cornerRadius, mHandlePaint); } }); setContentDescription(getResources().getString(R.string.handle_text)); /** Sets handle width, height and color. Does not change the layout properties */ private void setHandleProperties(float width, float height, int color) { mCurrentHandleHeight = height; mCurrentHandleWidth = width; mHandlePaint.setColor(color); invalidate(); } /** Loading @@ -94,15 +136,15 @@ public class BubbleBarHandleView extends View { */ public void updateHandleColor(boolean isRegionDark, boolean animated) { int newColor = isRegionDark ? mHandleLightColor : mHandleDarkColor; if (newColor == mCurrentColor) { if (newColor == mRegionSamplerColor) { return; } mRegionSamplerColor = newColor; if (mColorChangeAnim != null) { mColorChangeAnim.cancel(); } mCurrentColor = newColor; if (animated) { mColorChangeAnim = ObjectAnimator.ofArgb(this, "backgroundColor", newColor); mColorChangeAnim = ObjectAnimator.ofArgb(this, HANDLE_COLOR, newColor); mColorChangeAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { Loading @@ -112,7 +154,39 @@ public class BubbleBarHandleView extends View { mColorChangeAnim.setDuration(COLOR_CHANGE_DURATION); mColorChangeAnim.start(); } else { setBackgroundColor(newColor); setHandleColor(newColor); } } /** Returns handle padding top. */ public int getHandlePaddingTop() { return (getHeight() - getResources().getDimensionPixelSize( R.dimen.bubble_bar_expanded_view_handle_height)) / 2; } /** Animates handle for the bubble menu. */ public void animateHandleForMenu(float progress, float widthDelta, float heightDelta, int menuColor) { float currentWidth = mHandleWidth + widthDelta * progress; float currentHeight = mHandleHeight + heightDelta * progress; int color = (int) mArgbEvaluator.evaluate(progress, mRegionSamplerColor, menuColor); setHandleProperties(currentWidth, currentHeight, color); setTranslationY(heightDelta * progress / 2); } /** Restores all the properties that were animated to the default values. */ public void restoreAnimationDefaults() { setHandleProperties(mHandleWidth, mHandleHeight, mRegionSamplerColor); setTranslationY(0); } /** Returns the handle height. */ public int getHandleHeight() { return (int) mHandleHeight; } /** Returns the handle width. */ public int getHandleWidth() { return (int) mHandleWidth; } }
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java +38 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,10 @@ public class BubbleBarMenuView extends LinearLayout { private ImageView mBubbleIconView; private ImageView mBubbleDismissIconView; private TextView mBubbleTitleView; // The animation has three stages. Each stage transition lasts until the animation ends. In // stage 1, the title item content fades in. In stage 2, the background of the option items // fades in. In stage 3, the option item content fades in. private static final int SHOW_MENU_STAGES_COUNT = 3; public BubbleBarMenuView(Context context) { this(context, null /* attrs */); Loading Loading @@ -97,6 +101,35 @@ public class BubbleBarMenuView extends LinearLayout { } } /** Animates the menu from the specified start scale. */ public void animateFromStartScale(float currentScale, float progress) { int menuItemElevation = getResources().getDimensionPixelSize( R.dimen.bubble_manage_menu_elevation); setScaleX(currentScale); setScaleY(currentScale); setAlphaForTitleViews(progress); mBubbleSectionView.setElevation(menuItemElevation * progress); float actionsBackgroundAlpha = Math.max(0, (progress - (float) 1 / SHOW_MENU_STAGES_COUNT) * (SHOW_MENU_STAGES_COUNT - 1)); float actionItemsAlpha = Math.max(0, (progress - (float) 2 / SHOW_MENU_STAGES_COUNT) * SHOW_MENU_STAGES_COUNT); mActionsSectionView.setAlpha(actionsBackgroundAlpha); mActionsSectionView.setElevation(menuItemElevation * actionsBackgroundAlpha); setMenuItemViewsAlpha(actionItemsAlpha); } private void setAlphaForTitleViews(float alpha) { mBubbleIconView.setAlpha(alpha); mBubbleTitleView.setAlpha(alpha); mBubbleDismissIconView.setAlpha(alpha); } private void setMenuItemViewsAlpha(float alpha) { for (int i = mActionsSectionView.getChildCount() - 1; i >= 0; i--) { mActionsSectionView.getChildAt(i).setAlpha(alpha); } } /** Update menu details with bubble info */ void updateInfo(Bubble bubble) { if (bubble.getIcon() != null) { Loading Loading @@ -153,6 +186,11 @@ public class BubbleBarMenuView extends LinearLayout { return mBubbleSectionView.getAlpha(); } /** Return title menu item height. */ public float getTitleItemHeight() { return mBubbleSectionView.getHeight(); } /** * Menu action details used to create menu items */ Loading