1 /*
2  * Copyright (C) 2018 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.statusbar.phone;
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 import com.android.systemui.statusbar.policy.KeyButtonDrawable;
26 import com.android.systemui.statusbar.policy.KeyButtonView;
27 
28 /**
29  * Simple contextual button that is added to the {@link ContextualButtonGroup}. Extend if need extra
30  * functionality.
31  */
32 public class ContextualButton extends ButtonDispatcher {
33 
34     private ContextButtonListener mListener;
35     private ContextualButtonGroup mGroup;
36 
37     protected final @DrawableRes int mIconResId;
38 
39     /**
40       * Create a contextual button that will use a {@link KeyButtonView} and
41       * {@link KeyButtonDrawable} get and show the button from xml to its icon drawable.
42       * @param buttonResId the button view from xml layout
43       * @param iconResId icon resource to be used
44       */
ContextualButton(@dRes int buttonResId, @DrawableRes int iconResId)45     public ContextualButton(@IdRes int buttonResId, @DrawableRes int iconResId) {
46         super(buttonResId);
47         mIconResId = iconResId;
48     }
49 
50     /**
51      * Reload the drawable from resource id, should reapply the previous dark intensity.
52      */
updateIcon()53     public void updateIcon() {
54         if (getCurrentView() == null || !getCurrentView().isAttachedToWindow() || mIconResId == 0) {
55             return;
56         }
57         final KeyButtonDrawable currentDrawable = getImageDrawable();
58         KeyButtonDrawable drawable = getNewDrawable();
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()119     protected KeyButtonDrawable getNewDrawable() {
120         return KeyButtonDrawable.create(getContext().getApplicationContext(), mIconResId,
121                 false /* shadow */);
122     }
123 
124     /**
125      * This context is from the view that could be stale after rotation or config change. To get
126      * correct resources use getApplicationContext() as well.
127      * @return current view context
128      */
getContext()129     protected Context getContext() {
130         return getCurrentView().getContext();
131     }
132 
133     public interface ContextButtonListener {
onVisibilityChanged(ContextualButton button, boolean visible)134         void onVisibilityChanged(ContextualButton button, boolean visible);
135     }
136 }
137