| /* |
| * Copyright (C) 2018 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.systemui.statusbar.phone; |
| |
| import android.annotation.IdRes; |
| import android.annotation.NonNull; |
| import android.view.View; |
| |
| import java.io.PrintWriter; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| public class ContextualButtonGroup extends ButtonDispatcher { |
| private static final int INVALID_INDEX = -1; |
| |
| // List of pairs that contains the button and if the button was visible within this group |
| private final List<ButtonData> mButtonData = new ArrayList<>(); |
| |
| public ContextualButtonGroup(@IdRes int containerId) { |
| super(containerId); |
| } |
| |
| /** |
| * Add a contextual button to the group. The order of adding increases in its priority. The |
| * priority is used to determine which button should be visible when setting multiple button's |
| * visibility {@see setButtonVisiblity}. |
| * @param button the button added to the group |
| */ |
| public void addButton(@NonNull ContextualButton button) { |
| button.attachToGroup(this); |
| mButtonData.add(new ButtonData(button)); |
| } |
| |
| public ContextualButton getContextButton(@IdRes int buttonResId) { |
| int index = getContextButtonIndex(buttonResId); |
| if (index != INVALID_INDEX) { |
| return mButtonData.get(index).button; |
| } |
| return null; |
| } |
| |
| public ContextualButton getVisibleContextButton() { |
| for (int i = mButtonData.size() - 1; i >= 0; --i) { |
| if (mButtonData.get(i).markedVisible) { |
| return mButtonData.get(i).button; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Set the visibility of the button by {@param buttonResId} with {@param visible}. Only one |
| * button is shown at a time. The input button will only show up if it has higher priority than |
| * a previous button, otherwise it will be marked as visible and shown later if all higher |
| * priority buttons are invisible. Therefore hiding a button will show the next marked visible |
| * button. This group's view will be visible if at least one button is visible. |
| * @return if the button is visible after operation |
| * @throws RuntimeException if the input id does not match any of the ids in the group |
| */ |
| public int setButtonVisiblity(@IdRes int buttonResId, boolean visible) { |
| final int index = getContextButtonIndex(buttonResId); |
| if (index == INVALID_INDEX) { |
| throw new RuntimeException("Cannot find the button id of " + buttonResId |
| + " in context group"); |
| } |
| setVisibility(View.INVISIBLE); |
| mButtonData.get(index).markedVisible = visible; |
| |
| // Make all buttons invisible except the first markedVisible button |
| boolean alreadyFoundVisibleButton = false; |
| int i = mButtonData.size() - 1; |
| for (; i >= 0; --i) { |
| final ButtonData buttonData = mButtonData.get(i); |
| if (!alreadyFoundVisibleButton && buttonData.markedVisible) { |
| buttonData.setVisibility(View.VISIBLE); |
| setVisibility(View.VISIBLE); |
| alreadyFoundVisibleButton = true; |
| } else { |
| buttonData.setVisibility(View.INVISIBLE); |
| } |
| } |
| return mButtonData.get(index).button.getVisibility(); |
| } |
| |
| /** |
| * See if button is group visible. Group visible determines if a button can be visible when |
| * higher priority buttons go invisible. |
| * @param buttonResId the button to see if it is group visible |
| * @return true if button is group visible |
| */ |
| public boolean isButtonVisibleWithinGroup(@IdRes int buttonResId) { |
| final int index = getContextButtonIndex(buttonResId); |
| return index != INVALID_INDEX && mButtonData.get(index).markedVisible; |
| } |
| |
| /** |
| * Update all the icons that are attached to this group. This will get all the buttons to update |
| * their icons for their buttons. |
| */ |
| public void updateIcons() { |
| for (ButtonData data : mButtonData) { |
| data.button.updateIcon(); |
| } |
| } |
| |
| public void dump(PrintWriter pw) { |
| pw.println("ContextualButtonGroup {"); |
| pw.println(" getVisibleContextButton(): " + getVisibleContextButton()); |
| pw.println(" isVisible(): " + isVisible()); |
| pw.println(" mButtonData [ "); |
| for (int i = mButtonData.size() - 1; i >= 0; --i) { |
| final ButtonData data = mButtonData.get(i); |
| pw.println(" " + i + ": markedVisible=" + data.markedVisible |
| + " visible=" + data.button.getVisibility() |
| + " alpha=" + data.button.getAlpha()); |
| } |
| pw.println(" ]"); |
| pw.println(" }"); |
| } |
| |
| private int getContextButtonIndex(@IdRes int buttonResId) { |
| for (int i = 0; i < mButtonData.size(); ++i) { |
| if (mButtonData.get(i).button.getId() == buttonResId) { |
| return i; |
| } |
| } |
| return INVALID_INDEX; |
| } |
| |
| private final static class ButtonData { |
| ContextualButton button; |
| boolean markedVisible; |
| |
| ButtonData(ContextualButton button) { |
| this.button = button; |
| this.markedVisible = false; |
| } |
| |
| void setVisibility(int visiblity) { |
| button.setVisibility(visiblity); |
| } |
| } |
| } |