1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.wm.shell.bubbles.bar;
17 
18 import android.annotation.ColorInt;
19 import android.content.Context;
20 import android.graphics.Color;
21 import android.graphics.drawable.Icon;
22 import android.util.AttributeSet;
23 import android.view.LayoutInflater;
24 import android.view.ViewGroup;
25 import android.widget.ImageView;
26 import android.widget.LinearLayout;
27 import android.widget.TextView;
28 
29 import com.android.wm.shell.R;
30 import com.android.wm.shell.bubbles.Bubble;
31 
32 import java.util.ArrayList;
33 
34 /**
35  * Bubble bar expanded view menu
36  */
37 public class BubbleBarMenuView extends LinearLayout {
38     private ViewGroup mBubbleSectionView;
39     private ViewGroup mActionsSectionView;
40     private ImageView mBubbleIconView;
41     private TextView mBubbleTitleView;
42 
BubbleBarMenuView(Context context)43     public BubbleBarMenuView(Context context) {
44         this(context, null /* attrs */);
45     }
46 
BubbleBarMenuView(Context context, AttributeSet attrs)47     public BubbleBarMenuView(Context context, AttributeSet attrs) {
48         this(context, attrs, 0 /* defStyleAttr */);
49     }
50 
BubbleBarMenuView(Context context, AttributeSet attrs, int defStyleAttr)51     public BubbleBarMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
52         this(context, attrs, defStyleAttr, 0 /* defStyleRes */);
53     }
54 
BubbleBarMenuView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)55     public BubbleBarMenuView(Context context, AttributeSet attrs, int defStyleAttr,
56             int defStyleRes) {
57         super(context, attrs, defStyleAttr, defStyleRes);
58     }
59 
60     @Override
onFinishInflate()61     protected void onFinishInflate() {
62         super.onFinishInflate();
63         mBubbleSectionView = findViewById(R.id.bubble_bar_manage_menu_bubble_section);
64         mActionsSectionView = findViewById(R.id.bubble_bar_manage_menu_actions_section);
65         mBubbleIconView = findViewById(R.id.bubble_bar_manage_menu_bubble_icon);
66         mBubbleTitleView = findViewById(R.id.bubble_bar_manage_menu_bubble_title);
67     }
68 
69     /** Update menu details with bubble info */
updateInfo(Bubble bubble)70     void updateInfo(Bubble bubble) {
71         if (bubble.getIcon() != null) {
72             mBubbleIconView.setImageIcon(bubble.getIcon());
73         } else {
74             mBubbleIconView.setImageBitmap(bubble.getBubbleIcon());
75         }
76         mBubbleTitleView.setText(bubble.getTitle());
77     }
78 
79     /**
80      * Update menu action items views
81      * @param actions used to populate menu item views
82      */
updateActions(ArrayList<MenuAction> actions)83     void updateActions(ArrayList<MenuAction> actions) {
84         mActionsSectionView.removeAllViews();
85         LayoutInflater inflater = LayoutInflater.from(mContext);
86 
87         for (MenuAction action : actions) {
88             BubbleBarMenuItemView itemView = (BubbleBarMenuItemView) inflater.inflate(
89                     R.layout.bubble_bar_menu_item, mActionsSectionView, false);
90             itemView.update(action.mIcon, action.mTitle, action.mTint);
91             itemView.setOnClickListener(action.mOnClick);
92             mActionsSectionView.addView(itemView);
93         }
94     }
95 
96     /** Sets on close menu listener */
setOnCloseListener(Runnable onClose)97     void setOnCloseListener(Runnable onClose) {
98         mBubbleSectionView.setOnClickListener(view -> {
99             onClose.run();
100         });
101     }
102 
103     /**
104      * Overridden to proxy to section views alpha.
105      * @implNote
106      * If animate alpha on the parent (menu container) view, section view shadows get distorted.
107      * To prevent distortion and artifacts alpha changes applied directly on the section views.
108      */
109     @Override
setAlpha(float alpha)110     public void setAlpha(float alpha) {
111         mBubbleSectionView.setAlpha(alpha);
112         mActionsSectionView.setAlpha(alpha);
113     }
114 
115     /**
116      * Overridden to proxy section view alpha value.
117      * @implNote
118      * The assumption is that both section views have the same alpha value
119      */
120     @Override
getAlpha()121     public float getAlpha() {
122         return mBubbleSectionView.getAlpha();
123     }
124 
125     /**
126      * Menu action details used to create menu items
127      */
128     static class MenuAction {
129         private Icon mIcon;
130         private @ColorInt int mTint;
131         private String mTitle;
132         private OnClickListener mOnClick;
133 
MenuAction(Icon icon, String title, OnClickListener onClick)134         MenuAction(Icon icon, String title, OnClickListener onClick) {
135             this(icon, title, Color.TRANSPARENT, onClick);
136         }
137 
MenuAction(Icon icon, String title, @ColorInt int tint, OnClickListener onClick)138         MenuAction(Icon icon, String title, @ColorInt int tint, OnClickListener onClick) {
139             this.mIcon = icon;
140             this.mTitle = title;
141             this.mTint = tint;
142             this.mOnClick = onClick;
143         }
144     }
145 }
146