1 /* 2 * Copyright (C) 2022 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 package com.android.wallpaper.widget; 17 18 import android.content.Context; 19 import android.content.res.TypedArray; 20 import android.util.AttributeSet; 21 import android.view.LayoutInflater; 22 import android.widget.CompoundButton; 23 import android.widget.FrameLayout; 24 import android.widget.LinearLayout; 25 import android.widget.ToggleButton; 26 27 import androidx.annotation.IntDef; 28 import androidx.annotation.NonNull; 29 import androidx.annotation.Nullable; 30 import androidx.appcompat.content.res.AppCompatResources; 31 32 import com.android.wallpaper.R; 33 34 /** 35 * Custom layout for a group of wallpaper control buttons. 36 */ 37 public final class WallpaperControlButtonGroup extends FrameLayout { 38 39 public static final int DELETE = 0; 40 public static final int EDIT = 1; 41 public static final int CUSTOMIZE = 2; 42 public static final int EFFECTS = 3; 43 public static final int INFORMATION = 4; 44 public static final int SHARE = 5; 45 final int[] mFloatingSheetControlButtonTypes = {CUSTOMIZE, EFFECTS, SHARE, INFORMATION}; 46 ToggleButton mDeleteButton; 47 ToggleButton mEditButton; 48 ToggleButton mCustomizeButton; 49 ToggleButton mEffectsButton; 50 ToggleButton mShareButton; 51 ToggleButton mInformationButton; 52 53 /** 54 * The default orientation is vertical 55 */ 56 private int mOrientation = LinearLayout.VERTICAL; 57 58 /** 59 * Constructor 60 */ WallpaperControlButtonGroup(@onNull Context context, @Nullable AttributeSet attrs)61 public WallpaperControlButtonGroup(@NonNull Context context, @Nullable AttributeSet attrs) { 62 super(context, attrs); 63 initAttributes(attrs); 64 LayoutInflater.from(context).inflate(R.layout.wallpaper_control_button_group, this, 65 true); 66 LinearLayout buttonGroupContainer = findViewById(R.id.wallpaper_control_container); 67 if (mOrientation == LinearLayout.HORIZONTAL) { 68 buttonGroupContainer.setOrientation(LinearLayout.HORIZONTAL); 69 buttonGroupContainer.setDividerDrawable(context.getDrawable( 70 R.drawable.wallpaper_control_button_group_divider_horizontal)); 71 } else { 72 buttonGroupContainer.setOrientation(LinearLayout.VERTICAL); 73 buttonGroupContainer.setDividerDrawable( 74 context.getDrawable( 75 R.drawable.wallpaper_control_button_group_divider_vertical)); 76 } 77 78 mDeleteButton = findViewById(R.id.delete_button); 79 mEditButton = findViewById(R.id.edit_button); 80 mCustomizeButton = findViewById(R.id.customize_button); 81 mEffectsButton = findViewById(R.id.effects_button); 82 mShareButton = findViewById(R.id.share_button); 83 mInformationButton = findViewById(R.id.information_button); 84 } 85 86 /** 87 * @param attrs sets the local attribute properties for [WallpaperControlButtonGroup] 88 */ initAttributes(AttributeSet attrs)89 private void initAttributes(AttributeSet attrs) { 90 if (attrs != null) { 91 TypedArray typeArray = getContext().obtainStyledAttributes(attrs, 92 R.styleable.WallpaperControlButtonGroup); 93 94 // default to vertical 95 mOrientation = typeArray.getInt(R.styleable.WallpaperControlButtonGroup_orientation, 96 LinearLayout.VERTICAL); 97 98 typeArray.recycle(); 99 } 100 } 101 102 /** 103 * Show a button by giving a correspondent listener 104 */ showButton(@allpaperControlType int type, CompoundButton.OnCheckedChangeListener listener)105 public void showButton(@WallpaperControlType int type, 106 CompoundButton.OnCheckedChangeListener listener) { 107 ToggleButton button = getActionButton(type); 108 if (button != null) { 109 button.setVisibility(VISIBLE); 110 button.setOnCheckedChangeListener(listener); 111 } 112 } 113 getActionButton(@allpaperControlType int type)114 private ToggleButton getActionButton(@WallpaperControlType int type) { 115 switch (type) { 116 case DELETE: 117 return mDeleteButton; 118 case EDIT: 119 return mEditButton; 120 case CUSTOMIZE: 121 return mCustomizeButton; 122 case EFFECTS: 123 return mEffectsButton; 124 case SHARE: 125 return mShareButton; 126 case INFORMATION: 127 return mInformationButton; 128 default: 129 return null; 130 } 131 } 132 133 /** 134 * Hide a button 135 */ hideButton(@allpaperControlType int type)136 public void hideButton(@WallpaperControlType int type) { 137 getActionButton(type).setVisibility(GONE); 138 } 139 140 /** 141 * Set checked for a button 142 */ setChecked(@allpaperControlType int type, boolean checked)143 public void setChecked(@WallpaperControlType int type, boolean checked) { 144 getActionButton(type).setChecked(checked); 145 } 146 147 /** 148 * Update the background color in case the context theme has changed. 149 */ updateBackgroundColor()150 public void updateBackgroundColor() { 151 Context context = getContext(); 152 if (context == null) { 153 return; 154 } 155 mDeleteButton.setForeground(null); 156 mEditButton.setForeground(null); 157 mCustomizeButton.setForeground(null); 158 mEffectsButton.setForeground(null); 159 mShareButton.setForeground(null); 160 mInformationButton.setForeground(null); 161 mDeleteButton.setForeground(AppCompatResources.getDrawable(context, 162 R.drawable.wallpaper_control_button_delete)); 163 mEditButton.setForeground( 164 AppCompatResources.getDrawable(context, R.drawable.wallpaper_control_button_edit)); 165 mCustomizeButton.setForeground(AppCompatResources.getDrawable(context, 166 R.drawable.wallpaper_control_button_customize)); 167 mEffectsButton.setForeground(AppCompatResources.getDrawable(context, 168 R.drawable.wallpaper_control_button_effect)); 169 mShareButton.setForeground(AppCompatResources.getDrawable(context, 170 R.drawable.wallpaper_control_button_share)); 171 mInformationButton.setForeground( 172 AppCompatResources.getDrawable(context, R.drawable.wallpaper_control_button_info)); 173 } 174 175 /** 176 * Ensures only one toggle button with a floating sheet is selected at a time 177 */ deselectOtherFloatingSheetControlButtons(@allpaperControlType int selectedType)178 public void deselectOtherFloatingSheetControlButtons(@WallpaperControlType int selectedType) { 179 for (int type : mFloatingSheetControlButtonTypes) { 180 if (type != selectedType) { 181 getActionButton(type).setChecked(false); 182 } 183 } 184 } 185 186 /** 187 * Returns true if there is a floating sheet button selected, and false if not 188 */ isFloatingSheetControlButtonSelected()189 public boolean isFloatingSheetControlButtonSelected() { 190 for (int type : mFloatingSheetControlButtonTypes) { 191 if (getActionButton(type).isChecked()) { 192 return true; 193 } 194 } 195 return false; 196 } 197 198 /** 199 * Deselects all floating sheet toggle buttons in the Wallpaper Control Button Group 200 */ deselectAllFloatingSheetControlButtons()201 public void deselectAllFloatingSheetControlButtons() { 202 for (int type : mFloatingSheetControlButtonTypes) { 203 getActionButton(type).setChecked(false); 204 } 205 } 206 207 /** 208 * Overlay tab 209 */ 210 @IntDef({DELETE, EDIT, CUSTOMIZE, EFFECTS, SHARE, INFORMATION}) 211 public @interface WallpaperControlType { 212 } 213 } 214