/******************************************************************************* * Copyright (c) 2013 RelationWare, Benno Luthiger * 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: * RelationWare, Benno Luthiger ******************************************************************************/ package org.ripla.rap.internal.menu; import java.util.List; import org.eclipse.rap.rwt.RWT; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import org.osgi.service.useradmin.Authorization; import org.ripla.interfaces.IMenuCommand; import org.ripla.interfaces.IMenuItem; import org.ripla.rap.Constants; import org.ripla.rap.util.GridLayoutHelper; /** * A drop down menu composite. * * @author Luthiger */ @SuppressWarnings("serial") public class DropDownMenu extends Composite { private ToolItem mainMenuItem; private final IMenuCommand defaultCmd; private final Composite menuBox; /** * DropDownMenu constructor. * * @param inParent * {@link Composite} * @param inItemCreator * {@link IMenuItemsCreator} the object responsible to create * this menu's items */ public DropDownMenu(final Composite inParent, final IMenuItemsCreator inItemCreator) { super(inParent, SWT.NONE); setData(RWT.CUSTOM_VARIANT, "ripla-menu-dropdown"); setLayout(GridLayoutHelper.createGridLayout()); menuBox = GridLayoutHelper.createComposite(this); menuBox.setData(RWT.CUSTOM_VARIANT, "ripla-menu-box"); final Menu lMenu = createMenu(this); defaultCmd = inItemCreator.create(lMenu); createDropDownToolItem(menuBox, lMenu, inItemCreator.getMenuConfig()); } /** * @return {@link IMenuCommand} this menu's default command, i.e. the first * one that is visible */ public IMenuCommand getDefaultCmd() { return defaultCmd; } private Menu createMenu(final Composite inParent) { final Menu outMenu = new Menu(inParent.getShell(), SWT.POP_UP); outMenu.setData(RWT.CUSTOM_VARIANT, Constants.CSS_MENU); setLayout(GridLayoutHelper.createGridLayout()); return outMenu; } private void createDropDownToolItem(final Composite inParent, final Menu inPullDown, final IMenuItem inMenu) { final ToolBar lToolBar = new ToolBar(inParent, SWT.HORIZONTAL); lToolBar.setData(RWT.CUSTOM_VARIANT, Constants.CSS_MENU); mainMenuItem = new ToolItem(lToolBar, SWT.DROP_DOWN); mainMenuItem.setData(RWT.CUSTOM_VARIANT, Constants.CSS_MENU); mainMenuItem.setText(inMenu.getLabel()); mainMenuItem.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(final SelectionEvent inEvent) { final int lOffsetY = (inEvent.detail == SWT.ARROW) ? 0 : lToolBar.getSize().y - 1; inPullDown.setLocation(lToolBar.toDisplay(inEvent.x, inEvent.y + lOffsetY)); inPullDown.setVisible(true); } }); } /** * Factory method for <code>IMenuItemsCreator</code> instance. * * @param inMenuConfig * @param inListener * @param inAuthorization * @return {@link IMenuItemsCreator} */ public static IMenuItemsCreator getItemsCreator( final IMenuItem inMenuConfig, final SelectionListener inListener, final Authorization inAuthorization) { return new MenuItemsCreator(inMenuConfig, inListener, inAuthorization); } /** * Sets this menu's marker as selected. * * @param inSelected * boolean <code>true</code> if menu should be marked selected, * <code>false</code> for deactivated */ public void setSelected(final boolean inSelected) { menuBox.setData(RWT.CUSTOM_VARIANT, inSelected ? "ripla-menu-box-active" : "ripla-menu-box"); mainMenuItem.setData(RWT.CUSTOM_VARIANT, inSelected ? Constants.CSS_MENU_ACTIVE : Constants.CSS_MENU); } // --- /** * Interface for classes responsible to create the menu's items. * * @author Luthiger */ public interface IMenuItemsCreator { /** * Create the menu item's for the specified menu. * * @param inMenu * {@link Menu} * @return {@link IMenuCommand} this menu's default command (i.e. the * first one) */ IMenuCommand create(Menu inMenu); /** * @return {@link IMenuItem} the menu configuration for the menu * creation */ IMenuItem getMenuConfig(); } protected static class MenuItemsCreator implements IMenuItemsCreator { private final IMenuItem menuConfig; private final Authorization authorization; private final SelectionListener listener; private IMenuCommand defaultCmd; protected MenuItemsCreator(final IMenuItem inMenuConfig, final SelectionListener inListener, final Authorization inAuthorization) { menuConfig = inMenuConfig; listener = inListener; authorization = inAuthorization; } @Override public IMenuCommand create(final Menu inMenu) { for (final IMenuItem lItemConfig : menuConfig.getSubMenu()) { createMenuItem(inMenu, lItemConfig, authorization); } return defaultCmd; } @Override public IMenuItem getMenuConfig() { return menuConfig; } protected SelectionListener getListener() { return listener; } protected void createMenuItem(final Menu inMenu, final IMenuItem inMenuConfig, final Authorization inAuthorization) { // item is created only if permissions are ok if (MenuFactory.checkPermissions(inMenuConfig.getPermission(), inAuthorization)) { final List<IMenuItem> lSubMenuItems = inMenuConfig.getSubMenu(); final int lStyle = lSubMenuItems.isEmpty() ? SWT.PUSH : SWT.CASCADE; final MenuItem lItem = new MenuItem(inMenu, lStyle | SWT.LEFT); lItem.setText(inMenuConfig.getLabel()); lItem.setData(RWT.CUSTOM_VARIANT, Constants.CSS_MENU_ITEM); lItem.addSelectionListener(listener); lItem.setData(MenuFactory.KEY_MENU_ACTION, createMenuCommand(inMenuConfig.getControllerName())); if (defaultCmd == null) { defaultCmd = createMenuCommand(inMenuConfig .getControllerName()); } // create nested sub menu if (!lSubMenuItems.isEmpty()) { final Menu lSubMenu = new Menu(inMenu); lItem.setMenu(lSubMenu); for (final IMenuItem lItemConfig : lSubMenuItems) { createMenuItem(lSubMenu, lItemConfig, inAuthorization); } } } } protected IMenuCommand createMenuCommand(final String inControllerName) { return new IMenuCommand() { @Override public String getControllerName() { return inControllerName; } }; } } }