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 
17 package com.android.settings.accessibility;
18 
19 import android.content.Context;
20 import android.util.AttributeSet;
21 import android.view.View;
22 import android.widget.CompoundButton;
23 import android.widget.LinearLayout;
24 import android.widget.RadioButton;
25 
26 import androidx.annotation.ColorInt;
27 import androidx.annotation.Nullable;
28 
29 import com.android.settings.R;
30 
31 import java.util.Arrays;
32 import java.util.List;
33 import java.util.stream.Collectors;
34 
35 /**
36  * Layout for Screen flash notification color picker.
37  */
38 public class ColorSelectorLayout extends LinearLayout {
39     // Holds the checked id. The selection is empty by default
40     private int mCheckedId = -1;
41     // Tracks children radio buttons checked state
42     private CompoundButton.OnCheckedChangeListener mChildOnCheckedChangeListener;
43 
44     private ColorSelectorLayout.OnCheckedChangeListener mOnCheckedChangeListener;
45 
46     private final List<Integer> mRadioButtonResourceIds = Arrays.asList(
47             R.id.color_radio_button_00,
48             R.id.color_radio_button_01,
49             R.id.color_radio_button_02,
50             R.id.color_radio_button_03,
51             R.id.color_radio_button_04,
52             R.id.color_radio_button_05,
53             R.id.color_radio_button_06,
54             R.id.color_radio_button_07,
55             R.id.color_radio_button_08,
56             R.id.color_radio_button_09,
57             R.id.color_radio_button_10,
58             R.id.color_radio_button_11
59     );
60 
61     private List<Integer> mColorList;
62 
ColorSelectorLayout(Context context)63     public ColorSelectorLayout(Context context) {
64         super(context);
65         mChildOnCheckedChangeListener = new CheckedStateTracker();
66         inflate(mContext, R.layout.layout_color_selector, this);
67         init();
68         mColorList = Arrays.stream(mContext.getResources()
69                         .getIntArray(R.array.screen_flash_notification_preset_opacity_colors))
70                 .boxed()
71                 .collect(Collectors.toList());
72     }
73 
ColorSelectorLayout(Context context, @Nullable AttributeSet attrs)74     public ColorSelectorLayout(Context context, @Nullable AttributeSet attrs) {
75         super(context, attrs);
76         mChildOnCheckedChangeListener = new CheckedStateTracker();
77         inflate(mContext, R.layout.layout_color_selector, this);
78         init();
79         mColorList = Arrays.stream(mContext.getResources()
80                         .getIntArray(R.array.screen_flash_notification_preset_opacity_colors))
81                 .boxed()
82                 .collect(Collectors.toList());
83     }
84 
init()85     private void init() {
86         for (int resId : mRadioButtonResourceIds) {
87             RadioButton radioButton = findViewById(resId);
88             if (radioButton != null) {
89                 radioButton.setOnCheckedChangeListener(mChildOnCheckedChangeListener);
90             }
91         }
92     }
93 
setOnCheckedChangeListener(ColorSelectorLayout.OnCheckedChangeListener listener)94     void setOnCheckedChangeListener(ColorSelectorLayout.OnCheckedChangeListener listener) {
95         mOnCheckedChangeListener = listener;
96     }
97 
setCheckedColor(@olorInt int color)98     void setCheckedColor(@ColorInt int color) {
99         int resId = getResId(mColorList.indexOf(color));
100         if (resId != NO_ID && resId == mCheckedId) return;
101 
102         if (mCheckedId != NO_ID) {
103             setCheckedStateForView(mCheckedId, false);
104         }
105 
106         if (resId != NO_ID) {
107             setCheckedStateForView(resId, true);
108         }
109 
110         setCheckedId(resId);
111     }
112 
getCheckedColor(int defaultColor)113     int getCheckedColor(int defaultColor) {
114         int checkedItemIndex = mRadioButtonResourceIds.indexOf(mCheckedId);
115         if (checkedItemIndex < 0 || checkedItemIndex >= mColorList.size()) {
116             return defaultColor;
117         } else {
118             return mColorList.get(checkedItemIndex);
119         }
120     }
121 
getResId(int index)122     private int getResId(int index) {
123         if (index < 0 || index >= mRadioButtonResourceIds.size()) {
124             return NO_ID;
125         } else {
126             return mRadioButtonResourceIds.get(index);
127         }
128     }
129 
setCheckedId(int resId)130     private void setCheckedId(int resId) {
131         mCheckedId = resId;
132         if (mOnCheckedChangeListener != null) {
133             mOnCheckedChangeListener.onCheckedChanged(this);
134         }
135     }
136 
setCheckedStateForView(int viewId, boolean checked)137     private void setCheckedStateForView(int viewId, boolean checked) {
138         final View checkedView = findViewById(viewId);
139         if (checkedView instanceof RadioButton) {
140             ((RadioButton) checkedView).setChecked(checked);
141         }
142     }
143 
144     interface OnCheckedChangeListener {
onCheckedChanged(ColorSelectorLayout group)145         void onCheckedChanged(ColorSelectorLayout group);
146     }
147 
148     private class CheckedStateTracker implements CompoundButton.OnCheckedChangeListener {
149         @Override
onCheckedChanged(CompoundButton buttonView, boolean isChecked)150         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
151             if (!isChecked) {
152                 return;
153             }
154 
155             if (mCheckedId != NO_ID) {
156                 setCheckedStateForView(mCheckedId, false);
157             }
158 
159             int id = buttonView.getId();
160             setCheckedId(id);
161         }
162     }
163 }
164