/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.ide.ui.menubutton; import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.MouseOverEvent; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.PopupPanel; import org.eclipse.che.commons.annotation.Nullable; import org.eclipse.che.ide.FontAwesome; import org.eclipse.che.ide.util.Pair; import java.util.List; import java.util.Optional; /** Menu with {@link MenuItem}s list for {@link MenuButton}. */ class ItemsList extends PopupPanel { private final ItemsProvider dataProvider; private final MenuButton.Resources resources; private ActionHandler actionHandler; private ItemsList childList; private ItemWidget overItem; ItemsList(List<MenuItem> children, ItemsProvider dataProvider, MenuButton.Resources resources, @Nullable String title) { super(true, false); this.dataProvider = dataProvider; this.resources = resources; setAnimationEnabled(true); setAnimationType(AnimationType.ROLL_DOWN); addStyleName(resources.css().popupPanel()); final FlowPanel content = new FlowPanel(); add(content); if (title != null) { Label label = new Label(title); label.setStyleName(resources.css().label()); content.add(label); } children.forEach(child -> content.add(new ItemWidget(child))); addCloseHandler(event -> { if (childList != null && childList.isShowing()) { childList.hide(false); } }); } Optional<ActionHandler> getActionHandler() { return Optional.ofNullable(actionHandler); } void setActionHandler(ActionHandler actionHandler) { this.actionHandler = actionHandler; } private class ItemWidget extends FlowPanel { private final MenuItem item; ItemWidget(MenuItem item) { this.item = item; addStyleName(resources.css().popupItem()); final Element itemLabel = Document.get().createDivElement(); itemLabel.setInnerText(item.getName()); itemLabel.getStyle().setFloat(Style.Float.LEFT); getElement().appendChild(itemLabel); if (dataProvider.isGroup(item)) { DivElement arrow = Document.get().createDivElement(); arrow.setInnerHTML(FontAwesome.PLAY); arrow.addClassName(resources.css().arrow()); getElement().appendChild(arrow); } attachEventHandlers(); } private void attachEventHandlers() { addDomHandler(event -> { if (overItem != null) { overItem.removeStyleName(resources.css().popupItemOver()); } overItem = ItemWidget.this; addStyleName(resources.css().popupItemOver()); if (childList != null) { childList.hide(); } if (dataProvider.isGroup(item)) { Pair<List<MenuItem>, String> children = dataProvider.getChildren(item); createChildPopup(children); } }, MouseOverEvent.getType()); addDomHandler(event -> { if (dataProvider.isGroup(item)) { return; } hide(true); getActionHandler().ifPresent(actionHandler -> actionHandler.onAction(item)); }, ClickEvent.getType()); } private void createChildPopup(Pair<List<MenuItem>, String> children) { childList = new ItemsList(children.first, dataProvider, resources, "Execute on:"); getActionHandler().ifPresent(actionHandler -> childList.setActionHandler(actionHandler)); childList.setPopupPosition(getAbsoluteLeft() + getOffsetWidth(), getAbsoluteTop()); childList.show(); childList.setAutoHideEnabled(false); childList.setAnimationEnabled(false); childList.addCloseHandler(event -> { if (event.isAutoClosed()) { hide(); } }); } } }