package org.ovirt.engine.ui.common.widget.action;
import java.util.ArrayList;
import java.util.List;
import org.ovirt.engine.core.common.utils.Pair;
import org.ovirt.engine.ui.common.CommonApplicationResources;
import org.ovirt.engine.ui.common.gin.AssetProvider;
import org.ovirt.engine.ui.common.utils.ElementTooltipUtils;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.ToggleButton;
public class DropdownActionButton<T> extends AbstractActionButton {
interface WidgetUiBinder extends UiBinder<FocusPanel, DropdownActionButton> {
WidgetUiBinder uiBinder = GWT.create(WidgetUiBinder.class);
}
@UiField
Style style;
@UiField
FocusPanel container;
@UiField(provided = true)
ToggleButton dropdownButton;
MenuPanelPopup menuPopup;
private List<Pair<MenuItem, ActionButtonDefinition<T>>> items = new ArrayList<>();
private final SelectedItemsProvider<T> selectedItemsProvider;
private static final CommonApplicationResources resources = AssetProvider.getResources();
public DropdownActionButton(List<ActionButtonDefinition<T>> actions, SelectedItemsProvider<T> selectedItemsProvider) {
this.selectedItemsProvider = selectedItemsProvider;
initDropdownButton();
initWidget(WidgetUiBinder.uiBinder.createAndBindUi(this));
initMenuPopup(actions);
addMouseHandlers();
}
private void initDropdownButton() {
dropdownButton = new ToggleButton(new Image(resources.triangle_down()));
dropdownButton.addClickHandler(event -> {
if (dropdownButton.isDown()) {
menuPopup.asPopupPanel().showRelativeToAndFitToScreen(container);
} else {
menuPopup.asPopupPanel().hide();
}
});
}
private void initMenuPopup(List<ActionButtonDefinition<T>> actions) {
menuPopup = new MenuPanelPopup(true);
for (final ActionButtonDefinition<T> buttonDef : actions) {
MenuItem menuItem = new MenuItem(buttonDef.getText(), () -> {
menuPopup.asPopupPanel().hide();
buttonDef.onClick(selectedItemsProvider.getSelectedItems());
});
menuItem.addStyleName(style.menuItem());
updateMenuItem(menuItem, buttonDef, selectedItemsProvider.getSelectedItems());
menuPopup.getMenuBar().addItem(menuItem);
items.add(new Pair<>(menuItem, buttonDef));
}
menuPopup.asPopupPanel().setAutoHideEnabled(true);
menuPopup.asPopupPanel().addAutoHidePartner(dropdownButton.getElement());
menuPopup.asPopupPanel().addCloseHandler(event -> dropdownButton.setDown(false));
}
/**
* Ensures that the specified action button is visible or hidden and enabled or disabled as it should.
*/
void updateMenuItem(MenuItem item, ActionButtonDefinition<T> buttonDef, List selectedItems) {
item.setVisible(buttonDef.isAccessible(selectedItems) && buttonDef.isVisible(selectedItems));
item.setEnabled(buttonDef.isEnabled(selectedItems));
if (buttonDef.getTooltip() != null) {
ElementTooltipUtils.setTooltipOnElement(item.getElement(), buttonDef.getTooltip());
}
}
private void addMouseHandlers() {
button.addClickHandler(event -> {
container.removeStyleName(style.buttonMouseOver());
container.addStyleName(style.buttonMouseOut());
});
container.addMouseOverHandler(event -> {
if (isEnabled()) {
container.removeStyleName(style.buttonMouseOut());
container.addStyleName(style.buttonMouseOver());
}
});
container.addMouseOutHandler(event -> {
container.removeStyleName(style.buttonMouseOver());
container.addStyleName(style.buttonMouseOut());
});
}
@Override
public void setEnabled(boolean enabled) {
button.setEnabled(enabled);
for (Pair<MenuItem, ActionButtonDefinition<T>> item : items) {
updateMenuItem(item.getFirst(), item.getSecond(), selectedItemsProvider.getSelectedItems());
}
dropdownButton.setEnabled(enabled);
}
interface Style extends CssResource {
String buttonMouseOver();
String buttonMouseOut();
String menuItem();
}
public interface SelectedItemsProvider<T> {
List<T> getSelectedItems();
}
}