package org.ovirt.engine.ui.common.widget.refresh; import java.util.Set; import org.gwtbootstrap3.client.ui.constants.Placement; import org.ovirt.engine.ui.common.CommonApplicationConstants; import org.ovirt.engine.ui.common.gin.AssetProvider; import org.ovirt.engine.ui.common.idhandler.HasElementId; import org.ovirt.engine.ui.common.utils.ElementIdUtils; import org.ovirt.engine.ui.common.widget.renderer.MillisecondRenderer; import org.ovirt.engine.ui.common.widget.tooltip.WidgetTooltip; import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.Style.BorderStyle; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.HasClickHandlers; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.ImageResource; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.DecoratedPopupPanel; import com.google.gwt.user.client.ui.FocusPanel; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.MenuBar; import com.google.gwt.user.client.ui.MenuItem; import com.google.gwt.user.client.ui.MenuItemSeparator; import com.google.gwt.user.client.ui.PushButton; import com.google.gwt.user.client.ui.ToggleButton; /** * A panel that shows a refresh button, with popup menu to select the refresh rate.<BR> * Works with an {@link AbstractRefreshManager}. */ public abstract class BaseRefreshPanel extends FocusPanel implements HasClickHandlers, HasElementId { private static final CommonApplicationConstants constants = AssetProvider.getConstants(); public interface BaseResources extends ClientBundle { ImageResource check_icon(); ImageResource refresh_button(); BaseRefreshPanelCss refreshPanelCss(); ImageResource separator(); ImageResource triangle_down(); } private class RefreshRateOptionCommand implements Command { private RefreshRateOptionMenuItem menuItem; public RefreshRateOptionCommand() { super(); } @Override public void execute() { menuPopup.hide(); refreshMenuButton.setDown(false); refreshManager.setCurrentRefreshRate(menuItem.getRefreshRate()); } public void setMenuItem(RefreshRateOptionMenuItem menuItem) { this.menuItem = menuItem; } } /** * A custom menu bar with check icon */ private class RefreshRateOptionMenuItem extends MenuItem { private final Image checkItem; private final int refreshRate; public RefreshRateOptionMenuItem(int refreshRate, Command cmd) { super("", true, cmd); //$NON-NLS-1$ this.refreshRate = refreshRate; checkItem = new Image(RESOURCES.check_icon()); checkItem.setStylePrimaryName(style.checkitem()); checkItem.setVisible(false); getElement().appendChild(checkItem.getElement()); Anchor textItem = new Anchor(); textItem.setText(MillisecondRenderer.getInstance().render(refreshRate)); textItem.setStylePrimaryName(style.textItem()); getElement().appendChild(textItem.getElement()); } public int getRefreshRate() { return refreshRate; } public void select() { checkItem.setVisible(true); } @Override public void setSelectionStyle(boolean selected) { super.setSelectionStyle(selected); } public void unselect() { checkItem.setVisible(false); } } /** * A custom menu bar for 'RefreshRateOptionMenuItem' items. */ private static class RefreshRateOptionsMenu extends MenuBar { public RefreshRateOptionsMenu(boolean vertical) { super(vertical); } public RefreshRateOptionMenuItem getItemByRefreshRate(int refreshRate) { // Find the menu item that is associated with the specified refresh rate value for (MenuItem item : this.getItems()) { if (item instanceof RefreshRateOptionMenuItem) { RefreshRateOptionMenuItem refreshRateOptionMenuItem = (RefreshRateOptionMenuItem) item; if (refreshRateOptionMenuItem.getRefreshRate() == refreshRate) { return refreshRateOptionMenuItem; } } } return null; } public void selectItem(RefreshRateOptionMenuItem menuItem) { if (menuItem == null) { return; } // Select the specified item after unselecting the others for (MenuItem item : this.getItems()) { if (item instanceof RefreshRateOptionMenuItem) { RefreshRateOptionMenuItem refreshRateOptionMenuItem = (RefreshRateOptionMenuItem) item; refreshRateOptionMenuItem.unselect(); refreshRateOptionMenuItem.setSelectionStyle(false); } } menuItem.select(); } } private static BaseResources RESOURCES; private final DecoratedPopupPanel menuPopup; private PushButton refreshButton; private final AbstractRefreshManager<?> refreshManager; private ToggleButton refreshMenuButton; private final Image separator; private final RefreshRateOptionsMenu refreshOptionsMenu; private final Label statusLabel; private final BaseRefreshPanelCss style; private WidgetTooltip tooltip; /** * Create a Panel managed by the specified {@link RefreshManager}<BR> * used only by the Refresh Manager * */ protected BaseRefreshPanel(AbstractRefreshManager<?> refreshManager) { RESOURCES = createResources(); this.refreshManager = refreshManager; style = RESOURCES.refreshPanelCss(); style.ensureInjected(); // Set panel's attributes // setWidth("32px"); // setHeight("18px"); // Create menu popup menuPopup = new DecoratedPopupPanel(true, false); menuPopup.setStylePrimaryName(style.refreshRateMenuPopup()); // Add mouse hover events addMouseOverHandler(event -> { // border: 1px solid #96B7D6; Style border = getElement().getStyle(); border.setBorderWidth(1, Unit.PX); border.setBorderStyle(BorderStyle.SOLID); border.setBorderColor("#96B7D6"); //$NON-NLS-1$ }); addMouseOutHandler(event -> { // border: 1px solid transparent; Style border = getElement().getStyle(); border.setBorderWidth(1, Unit.PX); border.setBorderStyle(BorderStyle.SOLID); border.setBorderColor("transparent"); //$NON-NLS-1$ }); // Create refresh and refresh menu buttons createRefreshButton(); createRefreshMenuButton(); // Create refresh options menu refreshOptionsMenu = getRefreshOptionsMenu(); // Add menu to the popup menuPopup.add(refreshOptionsMenu); menuPopup.addAutoHidePartner(refreshMenuButton.getElement()); menuPopup.addCloseHandler(event -> refreshMenuButton.setDown(false)); // Hide popup on window resize Window.addResizeHandler(event -> menuPopup.hide()); // Create panel separator ImageResource separatorImg = RESOURCES.separator(); separator = new Image(separatorImg); // Add refresh button, refresh options menu button, and tooltip HorizontalPanel panel = new HorizontalPanel(); statusLabel = new Label(); panel.add(statusLabel); panel.add(refreshButton); panel.add(separator); panel.add(refreshMenuButton); setWidget(panel); tooltip = new WidgetTooltip(this); tooltip.setPlacement(Placement.BOTTOM); setTooltipText(refreshManager.getRefreshStatus()); } public void hideRefreshMenuButton() { HorizontalPanel refreshPanel = (HorizontalPanel) getWidget(); refreshPanel.remove(separator); refreshPanel.remove(refreshMenuButton); getElement().getStyle().setMarginRight(2, Unit.PX); } @Override public void setElementId(String elementId) { // Set refresh button element ID refreshButton.getElement().setId( ElementIdUtils.createElementId(elementId, "refreshButton")); //$NON-NLS-1$ } @Override public HandlerRegistration addClickHandler(ClickHandler handler) { return addHandler(handler, ClickEvent.getType()); } public void setTooltipText(String status) { tooltip.setText(status); } private void createRefreshButton() { Image refreshIcon = new Image(RESOURCES.refresh_button()); refreshIcon.setPixelSize(11, 11); refreshIcon.setStylePrimaryName(style.refreshIcon()); refreshButton = new PushButton(refreshIcon); refreshButton.setStylePrimaryName(style.refreshButton()); refreshButton.addStyleName("brp_refreshButton_pfly_fix"); //$NON-NLS-1$ refreshButton.setPixelSize(17, 17); refreshButton.addClickHandler(event -> fireEvent(event)); } private void createRefreshMenuButton() { Image refreshMenuIcon = new Image(RESOURCES.triangle_down()); refreshMenuButton = new ToggleButton(refreshMenuIcon); refreshMenuButton.setStylePrimaryName(style.refreshMenuButton()); refreshMenuButton.setPixelSize(13, 17); refreshMenuButton.addClickHandler(event -> { // Show/Hide popup if (refreshMenuButton.isDown()) { // Check selected item int globalRefreshRate = refreshManager.getCurrentRefreshRate(); refreshOptionsMenu.selectItem(refreshOptionsMenu.getItemByRefreshRate(globalRefreshRate)); menuPopup.showRelativeTo(refreshButton); } else { menuPopup.hide(); } }); } private RefreshRateOptionsMenu getRefreshOptionsMenu() { // Create refresh rate options menu bar RefreshRateOptionsMenu refreshOptionsMenu = new RefreshRateOptionsMenu(true); refreshOptionsMenu.setStylePrimaryName(style.refreshRateMenu()); // Create menu's title and add it as the first item MenuItem title = new MenuItem(constants.refreshRate(), () -> {}); title.setEnabled(false); title.setStylePrimaryName(style.refreshMenuTitle()); refreshOptionsMenu.addItem(title); Set<Integer> refreshRates = AbstractRefreshManager.getRefreshRates(); int itemIndex = 0; for (Integer refreshRate : refreshRates) { // Create command and menu item RefreshRateOptionCommand command = new RefreshRateOptionCommand(); RefreshRateOptionMenuItem refreshRateOption = new RefreshRateOptionMenuItem(refreshRate, command); refreshRateOption.setStylePrimaryName(style.refreshRateOption()); // Set command with the item it's associated with command.setMenuItem(refreshRateOption); // Add item (and a separator if needed) refreshOptionsMenu.addItem(refreshRateOption); if (itemIndex != refreshRates.size() - 1) { MenuItemSeparator separator = refreshOptionsMenu.addSeparator(); separator.getElement().getStyle().setBackgroundColor("#E0E9F2"); //$NON-NLS-1$ } itemIndex++; } return refreshOptionsMenu; } protected abstract BaseResources createResources(); }