org.opencms.ui.client.contextmenu.CmsContextMenuWidget Maven / Gradle / Ivy
Show all versions of opencms-gwt Show documentation
package org.opencms.ui.client.contextmenu;
import org.opencms.ui.shared.CmsContextMenuState.ContextMenuItemState;
import java.util.Set;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.google.gwt.user.client.Event.NativePreviewHandler;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.Widget;
/**
* Client side implementation for ContextMenu component.
*
* Adapted from ContextMenu by Peter Lehto / Vaadin Ltd.
*/
public class CmsContextMenuWidget extends Widget {
/** The menu overlay. */
private final CmsContextMenuOverlay m_menuOverlay;
/** The event preview handler. */
private final NativePreviewHandler m_nativeEventHandler = new NativePreviewHandler() {
@Override
public void onPreviewNativeEvent(NativePreviewEvent event) {
if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ESCAPE) {
// Always close the context menu on esc, no matter the focus
hide();
}
Event nativeEvent = Event.as(event.getNativeEvent());
boolean targetsContextMenu = eventTargetContextMenu(nativeEvent);
if (!targetsContextMenu && (nativeEvent.getTypeInt() == Event.ONMOUSEDOWN) && isHideAutomatically()) {
hide();
}
}
};
/** The preview handler registration. */
private final HandlerRegistration m_nativeEventHandlerRegistration;
/** The hide automatically flag. */
private boolean m_hideAutomatically;
/** The extension target widget. */
private Widget m_extensionTarget;
/**
* Constructor.
*/
public CmsContextMenuWidget() {
Element element = DOM.createDiv();
setElement(element);
m_nativeEventHandlerRegistration = Event.addNativePreviewHandler(m_nativeEventHandler);
m_menuOverlay = new CmsContextMenuOverlay();
}
/**
* Adds a menu popup close handler.
*
* @param popupCloseHandler the close handler
*
* @return the handler registration
*/
public HandlerRegistration addCloseHandler(CloseHandler popupCloseHandler) {
return m_menuOverlay.addCloseHandler(popupCloseHandler);
}
/**
* Adds new item as context menu root item.
*
* @param rootItem the root item
* @param connector the connector
*/
public void addRootMenuItem(ContextMenuItemState rootItem, CmsContextMenuConnector connector) {
CmsContextMenuItemWidget itemWidget = createEmptyItemWidget(
rootItem.getId(),
rootItem.getCaption(),
rootItem.getDescription(),
connector);
itemWidget.setEnabled(rootItem.isEnabled());
itemWidget.setSeparatorVisible(rootItem.isSeparator());
setStyleNames(itemWidget, rootItem.getStyles());
m_menuOverlay.addMenuItem(itemWidget);
for (ContextMenuItemState childState : rootItem.getChildren()) {
createSubMenu(itemWidget, childState, connector);
}
}
/**
* Clears the menu items.
*/
public void clearItems() {
m_menuOverlay.clearItems();
}
/**
* Returns the extension target widget.
*
* @return the extension target widget
*/
public Widget getExtensionTarget() {
return m_extensionTarget;
}
/**
* Hides the menu popup.
*/
public void hide() {
m_menuOverlay.hide();
}
/**
* Returns whether the menu is set to hide automatically.
*
* @return true
if the menu is set to hide automatically
*/
public boolean isHideAutomatically() {
return m_hideAutomatically;
}
/**
* Sets the extension target.
*
* @param extensionTarget the etension target
*/
public void setExtensionTarget(Widget extensionTarget) {
this.m_extensionTarget = extensionTarget;
m_menuOverlay.setOwner(extensionTarget);
}
/**
* Sets the hide automatically flag.
*
* @param hideAutomatically the hide automatically flag
*/
public void setHideAutomatically(boolean hideAutomatically) {
this.m_hideAutomatically = hideAutomatically;
}
/**
* Shows the context menu at the given position.
*
* @param rootMenuX the client x position
* @param rootMenuY the client y position
*/
public void showContextMenu(int rootMenuX, int rootMenuY) {
m_menuOverlay.showAt(rootMenuX, rootMenuY);
}
/**
* Shows the context menu relative to the given widget.
*
* @param widget the widget
*/
public void showContextMenu(Widget widget) {
m_menuOverlay.showRelativeTo(widget);
}
/**
* Unregisters the menu.
*/
public void unregister() {
m_nativeEventHandlerRegistration.removeHandler();
m_menuOverlay.unregister();
}
/**
* Returns whether the given event targets the context menu.
*
* @param nativeEvent the event to check
*
* @return true
if the event targets the menu
*/
protected boolean eventTargetContextMenu(Event nativeEvent) {
for (CmsContextMenuItemWidget item : m_menuOverlay.getMenuItems()) {
if (item.eventTargetsPopup(nativeEvent)) {
return true;
}
}
return false;
}
/**
* Returns whether the menu is showing.
*
* @return true
if the menu is showing
*/
protected boolean isShowing() {
return m_menuOverlay.isShowing();
}
/**
* Creates new empty menu item.
*
* @param id the id
* @param caption the caption
* @param description the item description used as tool-tip
* @param contextMenuConnector the connector
*
* @return the menu item
*/
private CmsContextMenuItemWidget createEmptyItemWidget(
String id,
String caption,
String description,
CmsContextMenuConnector contextMenuConnector) {
CmsContextMenuItemWidget widget = GWT.create(CmsContextMenuItemWidget.class);
widget.setId(id);
widget.setCaption(caption);
widget.setTitle(description);
widget.setIcon(contextMenuConnector.getConnection().getIcon(contextMenuConnector.getResourceUrl(id)));
CmsContextMenuItemWidgetHandler handler = new CmsContextMenuItemWidgetHandler(widget, contextMenuConnector);
widget.addClickHandler(handler);
widget.addMouseOutHandler(handler);
widget.addMouseOverHandler(handler);
widget.addKeyUpHandler(handler);
widget.setRootComponent(this);
return widget;
}
/**
* Creates a new sub menu.
*
* @param parentWidget the parent widget
* @param childState the child state
* @param connector the connector
*/
private void createSubMenu(
CmsContextMenuItemWidget parentWidget,
ContextMenuItemState childState,
CmsContextMenuConnector connector) {
CmsContextMenuItemWidget childWidget = createEmptyItemWidget(
childState.getId(),
childState.getCaption(),
childState.getDescription(),
connector);
childWidget.setEnabled(childState.isEnabled());
childWidget.setSeparatorVisible(childState.isSeparator());
setStyleNames(childWidget, childState.getStyles());
parentWidget.addSubMenuItem(childWidget);
for (ContextMenuItemState child : childState.getChildren()) {
createSubMenu(childWidget, child, connector);
}
}
/**
* Adds the given style names to the item widget.
*
* @param item the item
* @param styles the style names
*/
private void setStyleNames(CmsContextMenuItemWidget item, Set styles) {
for (String style : styles) {
item.addStyleName(style);
}
}
}