/*
|
* 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 setButtonVisibility}.
|
* @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 setButtonVisibility(@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) {
|
View view = getCurrentView();
|
pw.println("ContextualButtonGroup {");
|
pw.println(" getVisibleContextButton(): " + getVisibleContextButton());
|
pw.println(" isVisible(): " + isVisible());
|
pw.println(" attached(): " + (view != null && view.isAttachedToWindow()));
|
pw.println(" mButtonData [ ");
|
for (int i = mButtonData.size() - 1; i >= 0; --i) {
|
final ButtonData data = mButtonData.get(i);
|
view = data.button.getCurrentView();
|
pw.println(" " + i + ": markedVisible=" + data.markedVisible
|
+ " visible=" + data.button.getVisibility()
|
+ " attached=" + (view != null && view.isAttachedToWindow())
|
+ " 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);
|
}
|
}
|
}
|