001
002package org.opencms.ui.client.contextmenu;
003
004import org.opencms.ui.contextmenu.CmsContextMenu;
005import org.opencms.ui.shared.CmsContextMenuState;
006import org.opencms.ui.shared.CmsContextMenuState.ContextMenuItemState;
007import org.opencms.ui.shared.rpc.I_CmsContextMenuClientRpc;
008import org.opencms.ui.shared.rpc.I_CmsContextMenuServerRpc;
009
010import com.google.gwt.core.client.GWT;
011import com.google.gwt.dom.client.Element;
012import com.google.gwt.dom.client.EventTarget;
013import com.google.gwt.event.dom.client.ContextMenuEvent;
014import com.google.gwt.event.dom.client.ContextMenuHandler;
015import com.google.gwt.event.logical.shared.CloseEvent;
016import com.google.gwt.event.logical.shared.CloseHandler;
017import com.google.gwt.event.shared.HandlerRegistration;
018import com.google.gwt.user.client.ui.PopupPanel;
019import com.google.gwt.user.client.ui.Widget;
020import com.vaadin.client.ComponentConnector;
021import com.vaadin.client.ConnectorMap;
022import com.vaadin.client.ServerConnector;
023import com.vaadin.client.Util;
024import com.vaadin.client.communication.RpcProxy;
025import com.vaadin.client.communication.StateChangeEvent;
026import com.vaadin.client.extensions.AbstractExtensionConnector;
027import com.vaadin.client.ui.AbstractComponentConnector;
028import com.vaadin.shared.ui.Connect;
029
030/**
031 * ContextMenuConnector is client side object that receives updates from server
032 * and passes them to context menu client side widget. Connector is also
033 * responsible for handling user interaction and communicating it back to
034 * server.<p>
035 *
036 * Adapted from ContextMenu by Peter Lehto / Vaadin Ltd.<p>
037 *
038 */
039@Connect(CmsContextMenu.class)
040public class CmsContextMenuConnector extends AbstractExtensionConnector {
041
042    /** The serial version id. */
043    private static final long serialVersionUID = 3830712282306785118L;
044
045    /** The client to server RPC. */
046    I_CmsContextMenuServerRpc m_clientToServerRPC = RpcProxy.create(I_CmsContextMenuServerRpc.class, this);
047
048    /** The exntion target widget. */
049    Widget m_extensionTarget;
050
051    /** The context menu widget. */
052    CmsContextMenuWidget m_widget;
053
054    /** The close handler. */
055    private CloseHandler<PopupPanel> m_contextMenuCloseHandler = new CloseHandler<PopupPanel>() {
056
057        @Override
058        public void onClose(CloseEvent<PopupPanel> popupPanelCloseEvent) {
059
060            m_clientToServerRPC.contextMenuClosed();
061        }
062    };
063
064    /** The close handler registration. */
065    private HandlerRegistration m_contextMenuCloseHandlerRegistration;
066
067    /** The menu handler. */
068    private final ContextMenuHandler m_contextMenuHandler = new ContextMenuHandler() {
069
070        @Override
071        public void onContextMenu(ContextMenuEvent event) {
072
073            event.preventDefault();
074            event.stopPropagation();
075
076            EventTarget eventTarget = event.getNativeEvent().getEventTarget();
077
078            ComponentConnector connector = Util.getConnectorForElement(
079                getConnection(),
080                getConnection().getUIConnector().getWidget(),
081                (Element)eventTarget.cast());
082
083            Widget clickTargetWidget = connector.getWidget();
084
085            if (m_extensionTarget.equals(clickTargetWidget)) {
086                if (getState().isOpenAutomatically()) {
087                    m_widget.showContextMenu(event.getNativeEvent().getClientX(), event.getNativeEvent().getClientY());
088                } else {
089                    m_clientToServerRPC.onContextMenuOpenRequested(
090                        event.getNativeEvent().getClientX(),
091                        event.getNativeEvent().getClientY(),
092                        connector.getConnectorId());
093                }
094            }
095        }
096    };
097
098    /** The menu handler registration. */
099    private HandlerRegistration m_contextMenuHandlerRegistration;
100
101    /** The server tot client RPC. */
102    private I_CmsContextMenuClientRpc m_serverToClientRPC = new I_CmsContextMenuClientRpc() {
103
104        private static final long serialVersionUID = 1L;
105
106        @Override
107        public void hide() {
108
109            m_widget.hide();
110        }
111
112        @Override
113        public void showContextMenu(int x, int y) {
114
115            m_widget.showContextMenu(x, y);
116        }
117
118        @Override
119        public void showContextMenuRelativeTo(String connectorId) {
120
121            ServerConnector connector = ConnectorMap.get(getConnection()).getConnector(connectorId);
122
123            if (connector instanceof AbstractComponentConnector) {
124                AbstractComponentConnector componentConnector = (AbstractComponentConnector)connector;
125                componentConnector.getWidget();
126
127                m_widget.showContextMenu(componentConnector.getWidget());
128            }
129        }
130
131    };
132
133    /**
134     * @see com.vaadin.client.ui.AbstractConnector#getState()
135     */
136    @Override
137    public CmsContextMenuState getState() {
138
139        return (CmsContextMenuState)super.getState();
140    }
141
142    /**
143     * @see com.vaadin.client.ui.AbstractConnector#onStateChanged(com.vaadin.client.communication.StateChangeEvent)
144     */
145    @Override
146    public void onStateChanged(StateChangeEvent stateChangeEvent) {
147
148        super.onStateChanged(stateChangeEvent);
149
150        m_widget.clearItems();
151        m_widget.setHideAutomatically(getState().isHideAutomatically());
152
153        for (ContextMenuItemState rootItem : getState().getRootItems()) {
154            m_widget.addRootMenuItem(rootItem, this);
155        }
156    }
157
158    /**
159     * @see com.vaadin.client.ui.AbstractConnector#onUnregister()
160     */
161    @Override
162    public void onUnregister() {
163
164        m_contextMenuCloseHandlerRegistration.removeHandler();
165        m_contextMenuHandlerRegistration.removeHandler();
166
167        m_widget.unregister();
168
169        super.onUnregister();
170    }
171
172    /**
173     * @see com.vaadin.client.extensions.AbstractExtensionConnector#extend(com.vaadin.client.ServerConnector)
174     */
175    @Override
176    protected void extend(ServerConnector extensionTarget) {
177
178        this.m_extensionTarget = ((ComponentConnector)extensionTarget).getWidget();
179
180        m_widget.setExtensionTarget(this.m_extensionTarget);
181
182        m_contextMenuHandlerRegistration = this.m_extensionTarget.addDomHandler(
183            m_contextMenuHandler,
184            ContextMenuEvent.getType());
185    }
186
187    /**
188     * @see com.vaadin.client.ui.AbstractConnector#init()
189     */
190    @Override
191    protected void init() {
192
193        m_widget = GWT.create(CmsContextMenuWidget.class);
194        m_contextMenuCloseHandlerRegistration = m_widget.addCloseHandler(m_contextMenuCloseHandler);
195        registerRpc(I_CmsContextMenuClientRpc.class, m_serverToClientRPC);
196    }
197}