/* * This is part of Geomajas, a GIS framework, http://www.geomajas.org/. * * Copyright 2008-2015 Geosparc nv, http://www.geosparc.com/, Belgium. * * The program is available in open source according to the GNU Affero * General Public License. All contributions in this program are covered * by the Geomajas Contributors License Agreement. For full licensing * details, see LICENSE.txt in the project root. */ package org.geomajas.gwt.client.widget; import com.smartgwt.client.util.SC; import com.smartgwt.client.widgets.Canvas; import org.geomajas.annotation.Api; import org.geomajas.configuration.Parameter; import org.geomajas.configuration.client.ClientMapInfo; import org.geomajas.configuration.client.ClientToolInfo; import org.geomajas.configuration.client.ClientToolbarInfo; import org.geomajas.gwt.client.action.ConfigurableAction; import org.geomajas.gwt.client.action.ToolbarAction; import org.geomajas.gwt.client.action.ToolbarBaseAction; import org.geomajas.gwt.client.action.ToolbarCanvas; import org.geomajas.gwt.client.action.ToolbarModalAction; import org.geomajas.gwt.client.action.ToolbarWidget; import org.geomajas.gwt.client.action.event.ToolbarActionDisabledEvent; import org.geomajas.gwt.client.action.event.ToolbarActionEnabledEvent; import org.geomajas.gwt.client.action.event.ToolbarActionHandler; import org.geomajas.gwt.client.action.toolbar.ToolId; import org.geomajas.gwt.client.action.toolbar.ToolbarRegistry; import com.smartgwt.client.types.SelectionType; import com.smartgwt.client.widgets.IButton; import com.smartgwt.client.widgets.events.ClickEvent; import com.smartgwt.client.widgets.events.ClickHandler; import com.smartgwt.client.widgets.layout.LayoutSpacer; import com.smartgwt.client.widgets.toolbar.ToolStrip; import com.smartgwt.client.widgets.toolbar.ToolStripSeparator; import org.geomajas.gwt.client.util.Log; import org.geomajas.gwt.client.util.WidgetLayout; import java.util.ArrayList; import java.util.List; /** * A toolbar that supports two types of buttons: * <ul> * <li>modal (radiobutton-like) buttons.</li> * <li>non-modal or action buttons.</li> * </ul> * * @author Pieter De Graef * @author Joachim Van der Auwera * @since 1.6.0 */ @Api public class Toolbar extends ToolStrip { private List<Canvas> extraCanvasMembers = new ArrayList<Canvas>(); /** * Button size for small buttons. * @deprecated use {@link WidgetLayout#toolbarSmallButtonSize} */ @Deprecated public static final int BUTTON_SIZE_SMALL = 24; /** * Button size for large buttons. * @deprecated use {@link WidgetLayout#toolbarLargeButtonSize} */ @Deprecated public static final int BUTTON_SIZE_BIG = 32; private static final String CONTROLLER_RADIO_GROUP = "graphicsController"; private MapWidget mapWidget; private int buttonSize; /** * keep track of the currently selected ModalAction. */ private ToolbarModalAction currentModalAction; // ------------------------------------------------------------------------- // Constructor: // ------------------------------------------------------------------------- /** * Create a toolbar for the given {@link MapWidget}. * * @param mapWidget map widget for toolbar * @since 1.10.0 */ @Api public Toolbar(MapWidget mapWidget) { this(mapWidget, WidgetLayout.toolbarSmallButtonSize); } /** * Create a toolbar for given {@link MapWidget} and given button size. * * @param mapWidget map widget for toolbar * @param buttonSize size of toolbar button * @since 1.15.0 */ @Api public Toolbar(MapWidget mapWidget, int buttonSize) { this.mapWidget = mapWidget; setPadding(WidgetLayout.toolbarPadding); setWidth100(); this.buttonSize = buttonSize; setHeight(buttonSize); mapWidget.getMapModel().runWhenInitialized(new Runnable() { @Override public void run() { initialize(Toolbar.this.mapWidget.getMapModel().getMapInfo()); } }); } @Override public void addMember(Canvas component) { extraCanvasMembers.add(component); super.addMember(component); } @Override public void removeMember(Canvas canvas) { extraCanvasMembers.remove(canvas); super.removeMember(canvas); } /** * Initialize this widget. * * @param mapInfo map info */ public void initialize(ClientMapInfo mapInfo) { // remove previous members super.removeMembers(getMembers()); // add new members ClientToolbarInfo toolbarInfo = mapInfo.getToolbar(); if (toolbarInfo != null) { for (ClientToolInfo tool : toolbarInfo.getTools()) { String id = tool.getToolId(); if (ToolId.TOOL_SEPARATOR.equals(id)) { addToolbarSeparator(); } else { ToolbarBaseAction action = ToolbarRegistry.getToolbarAction(id, mapWidget); if (action instanceof ConfigurableAction) { for (Parameter parameter : tool.getParameters()) { ((ConfigurableAction) action).configure(parameter.getName(), parameter.getValue()); } } String description = tool.getDescription(); // Overrides tooltip parameter if description is set in ClientToolInfo. if (null != description && !"".equals(description)) { action.setTooltip(description); } if (action instanceof ToolbarWidget) { super.addMember(((ToolbarWidget) action).getWidget()); } else if (action instanceof ToolbarCanvas) { super.addMember(((ToolbarCanvas) action).getCanvas()); } else if (action instanceof ToolbarModalAction) { addModalButton((ToolbarModalAction) action); } else if (action instanceof ToolbarAction) { addActionButton((ToolbarAction) action); } else { String msg = "Tool with id " + id + " unknown."; Log.logError(msg); // console log SC.warn(msg); // in your face } } } } // add extra members for (Canvas extra : extraCanvasMembers) { super.addMember(extra); } } /** * Add a new action button to the toolbar. An action button is the kind of button that executes immediately when * clicked upon. It can not be selected or deselected, it just executes every click. * * @param action * The actual action to execute on click. */ public void addActionButton(final ToolbarAction action) { final IButton button = new IButton(); button.setWidth(buttonSize); button.setHeight(buttonSize); button.setIconSize(buttonSize - WidgetLayout.toolbarStripHeight); button.setIcon(action.getIcon()); button.setActionType(SelectionType.BUTTON); button.addClickHandler(action); button.setShowRollOver(false); button.setShowFocused(false); button.setTooltip(action.getTooltip()); button.setDisabled(action.isDisabled()); if (getMembers() != null && getMembers().length > 0) { LayoutSpacer spacer = new LayoutSpacer(); spacer.setWidth(2); super.addMember(spacer); } action.addToolbarActionHandler(new ToolbarActionHandler() { public void onToolbarActionDisabled(ToolbarActionDisabledEvent event) { button.setDisabled(true); } public void onToolbarActionEnabled(ToolbarActionEnabledEvent event) { button.setDisabled(false); } }); super.addMember(button); } /** * Add a new modal button (checkbox) to the toolbar. This kind of button is selected and deselected as the user * clicks upon it. By selecting and deselecting, a certain state will be activate or deactivated, determined by the * given <code>ModalAction</code>. * * @param modalAction * The actual action that determines what should happen when the button is selected or deselected. */ public void addModalButton(final ToolbarModalAction modalAction) { final IButton button = new IButton(); button.setWidth(buttonSize); button.setHeight(buttonSize); button.setIconSize(buttonSize - WidgetLayout.toolbarStripHeight); button.setIcon(modalAction.getIcon()); button.setActionType(SelectionType.CHECKBOX); button.setRadioGroup(CONTROLLER_RADIO_GROUP); button.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { if (button.isSelected()) { if (currentModalAction != null) { currentModalAction.onDeselect(event); } modalAction.onSelect(event); currentModalAction = modalAction; } else { modalAction.onDeselect(event); currentModalAction = null; } } }); button.setShowRollOver(false); button.setShowFocused(true); button.setTooltip(modalAction.getTooltip()); button.setDisabled(modalAction.isDisabled()); if (getMembers() != null && getMembers().length > 0) { LayoutSpacer spacer = new LayoutSpacer(); spacer.setWidth(WidgetLayout.toolbarPadding); super.addMember(spacer); } modalAction.addToolbarActionHandler(new ToolbarActionHandler() { public void onToolbarActionDisabled(ToolbarActionDisabledEvent event) { button.setDisabled(true); } public void onToolbarActionEnabled(ToolbarActionEnabledEvent event) { button.setDisabled(false); } }); super.addMember(button); } /** Add a vertical line to the toolbar. */ public void addToolbarSeparator() { ToolStripSeparator stripSeparator = new ToolStripSeparator(); stripSeparator.setHeight(WidgetLayout.toolbarStripHeight); super.addMember(stripSeparator); } // ------------------------------------------------------------------------- // Getters and setters: // ------------------------------------------------------------------------- /** * Get the size of the buttons. Set this before the toolbar is drawn, because afterwards, it can't be changed * anymore. * * @return button size */ public int getButtonSize() { return buttonSize; } /** * Set the size of the buttons. Use this before the toolbar is drawn, because afterwards, it can't be changed * anymore. * * @param buttonSize * The new button size. * * @deprecated use {@link #Toolbar(MapWidget, int)} instead . * */ @Deprecated public void setButtonSize(int buttonSize) { this.buttonSize = buttonSize; // TODO: resize all buttons setHeight(buttonSize); } }