1 /*
2  * Copyright (C) 2020 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 
17 package com.android.systemui.navigationbar.buttons;
18 
19 import android.annotation.DrawableRes;
20 import android.annotation.IdRes;
21 import android.annotation.NonNull;
22 import android.content.Context;
23 import android.view.View;
24 
25 /**
26  * Simple contextual button that is added to the {@link ContextualButtonGroup}. Extend if need extra
27  * functionality.
28  */
29 public class ContextualButton extends ButtonDispatcher {
30 
31     private ContextButtonListener mListener;
32     private ContextualButtonGroup mGroup;
33 
34     protected final Context mLightContext;
35     protected final @DrawableRes int mIconResId;
36 
37     /**
38       * Create a contextual button that will use a {@link KeyButtonView} and
39       * {@link KeyButtonDrawable} get and show the button from xml to its icon drawable.
40       * @param buttonResId the button view from xml layout
41       * @param iconResId icon resource to be used
42       */
ContextualButton(@dRes int buttonResId, Context lightContext, @DrawableRes int iconResId)43     public ContextualButton(@IdRes int buttonResId, Context lightContext,
44             @DrawableRes int iconResId) {
45         super(buttonResId);
46         mLightContext = lightContext;
47         mIconResId = iconResId;
48     }
49 
50     /**
51      * Reload the drawable from resource id, should reapply the previous dark intensity.
52      */
updateIcon(int lightIconColor, int darkIconColor)53     public void updateIcon(int lightIconColor, int darkIconColor) {
54         if (mIconResId == 0) {
55             return;
56         }
57         final KeyButtonDrawable currentDrawable = getImageDrawable();
58         KeyButtonDrawable drawable = getNewDrawable(lightIconColor, darkIconColor);
59         if (currentDrawable != null) {
60             drawable.setDarkIntensity(currentDrawable.getDarkIntensity());
61         }
62         setImageDrawable(drawable);
63     }
64 
65     @Override
setVisibility(int visibility)66     public void setVisibility(int visibility) {
67         super.setVisibility(visibility);
68 
69         // Stop any active animations if hidden
70         final KeyButtonDrawable currentDrawable = getImageDrawable();
71         if (visibility != View.VISIBLE && currentDrawable != null && currentDrawable.canAnimate()) {
72             currentDrawable.clearAnimationCallbacks();
73             currentDrawable.resetAnimation();
74         }
75 
76         if (mListener != null) {
77             mListener.onVisibilityChanged(this, visibility == View.VISIBLE);
78         }
79     }
80 
setListener(ContextButtonListener listener)81     public void setListener(ContextButtonListener listener) {
82         mListener = listener;
83     }
84 
85     /**
86      * Show this button based on its priority compared to other buttons in the group. If not
87      * attached to a group it will set its own visibility to be visible.
88      * @return if visible
89      */
show()90     public boolean show() {
91         if (mGroup == null) {
92             setVisibility(View.VISIBLE);
93             return true;
94         }
95         return mGroup.setButtonVisibility(getId(), true /* visible */) == View.VISIBLE;
96     }
97 
98     /**
99      * Hide this button.
100      * @return if visible
101      */
hide()102     public boolean hide() {
103         if (mGroup == null) {
104             setVisibility(View.INVISIBLE);
105             return false;
106         }
107         return mGroup.setButtonVisibility(getId(), false /* visible */) != View.VISIBLE;
108     }
109 
110     /**
111      * Called when this button was added to the group. Keep a reference to the group to show based
112      * on priority compared to other buttons.
113      * @param group the holder of all the buttons
114      */
attachToGroup(@onNull ContextualButtonGroup group)115     void attachToGroup(@NonNull ContextualButtonGroup group) {
116         mGroup = group;
117     }
118 
getNewDrawable(int lightIconColor, int darkIconColor)119     protected KeyButtonDrawable getNewDrawable(int lightIconColor, int darkIconColor) {
120         return KeyButtonDrawable.create(mLightContext, lightIconColor, darkIconColor, mIconResId,
121                 false /* shadow */, null /* ovalBackground */);
122     }
123 
124     public interface ContextButtonListener {
onVisibilityChanged(ContextualButton button, boolean visible)125         void onVisibilityChanged(ContextualButton button, boolean visible);
126     }
127 }
128