blob: 38df17ab52fdaab72799b14adbbe914b925c52aa [file] [log] [blame]
/*
* 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() {
if (getCurrentView() == null || !getCurrentView().isAttachedToWindow()) {
return;
}
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);
}
}
}