• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.car.settings.common;
18 
19 import android.content.Context;
20 import android.content.res.Resources;
21 import android.graphics.drawable.Drawable;
22 import android.text.TextUtils;
23 import android.view.View;
24 import android.widget.ImageView;
25 import android.widget.TextView;
26 import android.widget.Toast;
27 
28 import androidx.annotation.DrawableRes;
29 import androidx.annotation.StringRes;
30 import androidx.annotation.VisibleForTesting;
31 
32 import com.android.car.settings.R;
33 
34 import java.lang.ref.WeakReference;
35 
36 /**
37  * Class representing a button item for an {@link ActionButtonsPreference}
38  */
39 public class ActionButtonInfo {
40     private static final Logger LOG = new Logger(ActionButtonInfo.class);
41     private final Context mContext;
42     private View mButtonView;
43     private ImageView mButtonIconView;
44     private TextView mButtonTextView;
45     private CharSequence mText;
46     private Drawable mIcon;
47     private View.OnClickListener mListener;
48     private boolean mIsPreferenceRestricted = false;
49     private boolean mIsEnabled = true;
50     private boolean mIsVisible = true;
51     private WeakReference<ButtonInfoChangeListener> mButtonInfoChangeListener;
52     private String mMessageToShowWhenUxRestrictedPreferenceClicked;
53 
ActionButtonInfo(Context context, ButtonInfoChangeListener changeListener)54     ActionButtonInfo(Context context, ButtonInfoChangeListener changeListener) {
55         mContext = context;
56         mButtonInfoChangeListener = new WeakReference<>(changeListener);
57         mMessageToShowWhenUxRestrictedPreferenceClicked = context.getString(
58                 R.string.car_ui_restricted_while_driving);
59     }
60 
61     /**
62      * Set the visibility state.
63      */
setVisible(boolean isVisible)64     public ActionButtonInfo setVisible(boolean isVisible) {
65         if (isVisible != mIsVisible) {
66             mIsVisible = isVisible;
67             update();
68         }
69         return this;
70     }
71 
72     /**
73      * Sets the text to be displayed.
74      */
setText(@tringRes int textResId)75     public ActionButtonInfo setText(@StringRes int textResId) {
76         final String newText = mContext.getString(textResId);
77         if (!TextUtils.equals(newText, mText)) {
78             mText = newText;
79             update();
80         }
81         return this;
82     }
83 
84     /**
85      * Sets the drawable to be displayed above of text.
86      */
setIcon(@rawableRes int iconResId)87     public ActionButtonInfo setIcon(@DrawableRes int iconResId) {
88         if (iconResId == 0) {
89             return this;
90         }
91 
92         final Drawable icon;
93         try {
94             icon = mContext.getDrawable(iconResId);
95             mIcon = icon;
96             update();
97         } catch (Resources.NotFoundException exception) {
98             LOG.e("Resource does not exist: " + iconResId);
99         }
100         return this;
101     }
102 
103     /**
104      * Set the enabled state.
105      */
setEnabled(boolean isEnabled)106     public ActionButtonInfo setEnabled(boolean isEnabled) {
107         if (isEnabled != mIsEnabled) {
108             mIsEnabled = isEnabled;
109             update();
110         }
111         return this;
112     }
113 
114     /**
115      * Register a callback to be invoked when clicked.
116      */
setOnClickListener( View.OnClickListener listener)117     public ActionButtonInfo setOnClickListener(
118             View.OnClickListener listener) {
119         if (listener != mListener) {
120             mListener = listener;
121             update();
122         }
123         return this;
124     }
125 
setButtonView(View view)126     ActionButtonInfo setButtonView(View view) {
127         mButtonView = view;
128         return this;
129     }
130 
setButtonTextView(TextView textView)131     ActionButtonInfo setButtonTextView(TextView textView) {
132         mButtonTextView = textView;
133         return this;
134     }
135 
setButtonIconView(ImageView iconView)136     ActionButtonInfo setButtonIconView(ImageView iconView) {
137         mButtonIconView = iconView;
138         return this;
139     }
140 
setPreferenceRestricted(boolean isRestricted)141     ActionButtonInfo setPreferenceRestricted(boolean isRestricted) {
142         mIsPreferenceRestricted = isRestricted;
143         return this;
144     }
145 
146     /**
147      * Get the current button text.
148      */
149     @VisibleForTesting
getText()150     public CharSequence getText() {
151         return mText;
152     }
153 
154     /**
155      * Get the current button icon.
156      */
157     @VisibleForTesting
getIcon()158     public Drawable getIcon() {
159         return mIcon;
160     }
161 
162     /**
163      * Get the current button click listener.
164      */
165     @VisibleForTesting
getOnClickListener()166     public View.OnClickListener getOnClickListener() {
167         return mListener;
168     }
169 
170     /**
171      * Get the current button enabled state.
172      */
173     @VisibleForTesting
isEnabled()174     public boolean isEnabled() {
175         return mIsEnabled;
176     }
177 
178     /**
179      * Get the current button visibility.
180      */
181     @VisibleForTesting
isVisible()182     public boolean isVisible() {
183         return shouldBeVisible();
184     }
185 
setUpButton()186     void setUpButton() {
187         mButtonTextView.setText(mText);
188         mButtonIconView.setImageDrawable(mIcon);
189         mButtonView.setOnClickListener(this::performClick);
190 
191         boolean enabled = isEnabled() || mIsPreferenceRestricted;
192         mButtonView.setEnabled(enabled);
193         mButtonTextView.setEnabled(enabled);
194         mButtonIconView.setEnabled(enabled);
195 
196         mButtonIconView.setVisibility(mIcon != null ? View.VISIBLE : View.GONE);
197 
198         if (shouldBeVisible()) {
199             mButtonView.setVisibility(View.VISIBLE);
200         } else {
201             mButtonView.setVisibility(View.GONE);
202         }
203     }
204 
205     @VisibleForTesting
performClick(View v)206     void performClick(View v) {
207         if (!isEnabled()) {
208             return;
209         }
210         if (mListener == null) {
211             return;
212         }
213         if (mIsPreferenceRestricted) {
214             if (!TextUtils.isEmpty(mMessageToShowWhenUxRestrictedPreferenceClicked)) {
215                 Toast.makeText(mContext, mMessageToShowWhenUxRestrictedPreferenceClicked,
216                         Toast.LENGTH_LONG).show();
217             }
218             return;
219         }
220         mListener.onClick(v);
221     }
222 
223     /**
224      * By default, four buttons are visible.
225      * However, there are two cases which button should be invisible.
226      *
227      * 1. User set invisible for this button. ex: mIsVisible = false.
228      * 2. User didn't set any title or icon.
229      */
shouldBeVisible()230     private boolean shouldBeVisible() {
231         return mIsVisible && (!TextUtils.isEmpty(mText) || mIcon != null);
232     }
233 
update()234     private void update() {
235         ButtonInfoChangeListener listener = mButtonInfoChangeListener.get();
236         if (listener != null) {
237             listener.onButtonInfoChange(this);
238         }
239     }
240 
241     /**
242      * Listener that is notified when a button has been updated.
243      */
244     interface ButtonInfoChangeListener {
onButtonInfoChange(ActionButtonInfo buttonInfo)245         void onButtonInfoChange(ActionButtonInfo buttonInfo);
246     }
247 }
248