blob: 0046e3d651c0589038fd3c7e8c3b0a8cd28d033f [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.car.settings.common;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.DrawableRes;
import androidx.annotation.StringRes;
import androidx.annotation.VisibleForTesting;
import com.android.car.settings.R;
import com.android.car.ui.utils.CarUiUtils;
import java.lang.ref.WeakReference;
/**
* Class representing a button item for an {@link ActionButtonsPreference}
*/
public class ActionButtonInfo {
private static final Logger LOG = new Logger(ActionButtonInfo.class);
private final Context mContext;
private View mButtonView;
private ImageView mButtonIconView;
private TextView mButtonTextView;
private CharSequence mText;
private Drawable mIcon;
private View.OnClickListener mListener;
private boolean mIsPreferenceRestricted = false;
private boolean mIsEnabled = true;
private boolean mIsVisible = true;
private WeakReference<ButtonInfoChangeListener> mButtonInfoChangeListener;
private String mMessageToShowWhenUxRestrictedPreferenceClicked;
ActionButtonInfo(Context context, ButtonInfoChangeListener changeListener) {
mContext = context;
mButtonInfoChangeListener = new WeakReference<>(changeListener);
mMessageToShowWhenUxRestrictedPreferenceClicked = context.getString(
R.string.car_ui_restricted_while_driving);
}
/**
* Set the visibility state.
*/
public ActionButtonInfo setVisible(boolean isVisible) {
if (isVisible != mIsVisible) {
mIsVisible = isVisible;
update();
}
return this;
}
/**
* Sets the text to be displayed.
*/
public ActionButtonInfo setText(@StringRes int textResId) {
final String newText = mContext.getString(textResId);
if (!TextUtils.equals(newText, mText)) {
mText = newText;
update();
}
return this;
}
/**
* Sets the drawable to be displayed above of text.
*/
public ActionButtonInfo setIcon(@DrawableRes int iconResId) {
if (iconResId == 0) {
return this;
}
final Drawable icon;
try {
icon = mContext.getDrawable(iconResId);
mIcon = icon;
update();
} catch (Resources.NotFoundException exception) {
LOG.e("Resource does not exist: " + iconResId);
}
return this;
}
/**
* Set the enabled state.
*/
public ActionButtonInfo setEnabled(boolean isEnabled) {
if (isEnabled != mIsEnabled) {
mIsEnabled = isEnabled;
update();
}
return this;
}
/**
* Register a callback to be invoked when clicked.
*/
public ActionButtonInfo setOnClickListener(
View.OnClickListener listener) {
if (listener != mListener) {
mListener = listener;
update();
}
return this;
}
ActionButtonInfo setButtonView(View view) {
mButtonView = view;
return this;
}
ActionButtonInfo setButtonTextView(TextView textView) {
mButtonTextView = textView;
return this;
}
ActionButtonInfo setButtonIconView(ImageView iconView) {
mButtonIconView = iconView;
return this;
}
ActionButtonInfo setPreferenceRestricted(boolean isRestricted) {
mIsPreferenceRestricted = isRestricted;
return this;
}
/**
* Get the current button text.
*/
@VisibleForTesting
public CharSequence getText() {
return mText;
}
/**
* Get the current button icon.
*/
@VisibleForTesting
public Drawable getIcon() {
return mIcon;
}
/**
* Get the current button click listener.
*/
@VisibleForTesting
public View.OnClickListener getOnClickListener() {
return mListener;
}
/**
* Get the current button enabled state.
*/
@VisibleForTesting
public boolean isEnabled() {
return mIsEnabled;
}
/**
* Get the current button visibility.
*/
@VisibleForTesting
public boolean isVisible() {
return shouldBeVisible();
}
void setUpButton() {
mButtonTextView.setText(mText);
mButtonIconView.setImageDrawable(mIcon);
mButtonView.setOnClickListener(this::performClick);
boolean enabled = isEnabled() || mIsPreferenceRestricted;
mButtonView.setEnabled(enabled);
CarUiUtils.makeAllViewsEnabledAndUxRestricted(mButtonView, isEnabled(),
mIsPreferenceRestricted);
mButtonIconView.setVisibility(mIcon != null ? View.VISIBLE : View.GONE);
if (shouldBeVisible()) {
mButtonView.setVisibility(View.VISIBLE);
} else {
mButtonView.setVisibility(View.GONE);
}
}
@VisibleForTesting
void performClick(View v) {
if (!isEnabled()) {
return;
}
if (mListener == null) {
return;
}
if (mIsPreferenceRestricted) {
if (!TextUtils.isEmpty(mMessageToShowWhenUxRestrictedPreferenceClicked)) {
Toast.makeText(mContext, mMessageToShowWhenUxRestrictedPreferenceClicked,
Toast.LENGTH_LONG).show();
}
return;
}
mListener.onClick(v);
}
/**
* By default, four buttons are visible.
* However, there are two cases which button should be invisible.
*
* 1. User set invisible for this button. ex: mIsVisible = false.
* 2. User didn't set any title or icon.
*/
private boolean shouldBeVisible() {
return mIsVisible && (!TextUtils.isEmpty(mText) || mIcon != null);
}
private void update() {
ButtonInfoChangeListener listener = mButtonInfoChangeListener.get();
if (listener != null) {
listener.onButtonInfoChange(this);
}
}
/**
* Listener that is notified when a button has been updated.
*/
interface ButtonInfoChangeListener {
void onButtonInfoChange(ActionButtonInfo buttonInfo);
}
}