001
002package org.opencms.ui.client.contextmenu;
003
004import org.opencms.ui.shared.rpc.I_CmsContextMenuServerRpc;
005
006import com.google.gwt.event.dom.client.ClickEvent;
007import com.google.gwt.event.dom.client.ClickHandler;
008import com.google.gwt.event.dom.client.KeyCodes;
009import com.google.gwt.event.dom.client.KeyUpEvent;
010import com.google.gwt.event.dom.client.KeyUpHandler;
011import com.google.gwt.event.dom.client.MouseOutEvent;
012import com.google.gwt.event.dom.client.MouseOutHandler;
013import com.google.gwt.event.dom.client.MouseOverEvent;
014import com.google.gwt.event.dom.client.MouseOverHandler;
015import com.google.gwt.user.client.Timer;
016import com.vaadin.client.ServerConnector;
017import com.vaadin.client.communication.RpcProxy;
018
019/**
020 * ContextMenuItemWidgetHandler is context menu item specific object that
021 * handles the server communication when item is interacted with.<p>
022 *
023 * Adapted from ContextMenu by Peter Lehto / Vaadin Ltd.<p>
024 */
025public class CmsContextMenuItemWidgetHandler implements ClickHandler, MouseOverHandler, MouseOutHandler, KeyUpHandler {
026
027    /** The menu RPC. */
028    private I_CmsContextMenuServerRpc m_contextMenuRpc;
029
030    /** The menu timer. */
031    private final Timer m_openTimer = new Timer() {
032
033        @Override
034        public void run() {
035
036            onItemClicked();
037        }
038    };
039
040    /** The menu item widget. */
041    private CmsContextMenuItemWidget m_widget;
042
043    /**
044     * Constructor.<p>
045     *
046     * @param widget the menu item widget
047     * @param connector the server connector
048     */
049    public CmsContextMenuItemWidgetHandler(CmsContextMenuItemWidget widget, ServerConnector connector) {
050
051        this.m_widget = widget;
052
053        m_contextMenuRpc = RpcProxy.create(I_CmsContextMenuServerRpc.class, connector);
054    }
055
056    /**
057     * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
058     */
059    @Override
060    public void onClick(ClickEvent event) {
061
062        if (isEnabled()) {
063            m_openTimer.cancel();
064
065            if (m_widget.hasSubMenu()) {
066                if (!m_widget.isSubmenuOpen()) {
067                    m_widget.onItemClicked();
068                    m_contextMenuRpc.itemClicked(m_widget.getId(), false);
069                }
070            } else {
071                boolean menuClosed = m_widget.onItemClicked();
072                m_contextMenuRpc.itemClicked(m_widget.getId(), menuClosed);
073            }
074        }
075    }
076
077    /**
078     * @see com.google.gwt.event.dom.client.KeyUpHandler#onKeyUp(com.google.gwt.event.dom.client.KeyUpEvent)
079     */
080    @Override
081    public void onKeyUp(KeyUpEvent event) {
082
083        int keycode = event.getNativeEvent().getKeyCode();
084
085        if (keycode == KeyCodes.KEY_LEFT) {
086            onLeftPressed();
087        } else if (keycode == KeyCodes.KEY_RIGHT) {
088            onRightPressed();
089        } else if (keycode == KeyCodes.KEY_UP) {
090            onUpPressed();
091        } else if (keycode == KeyCodes.KEY_DOWN) {
092            onDownPressed();
093        } else if (keycode == KeyCodes.KEY_ENTER) {
094            onEnterPressed();
095        }
096    }
097
098    /**
099     * @see com.google.gwt.event.dom.client.MouseOutHandler#onMouseOut(com.google.gwt.event.dom.client.MouseOutEvent)
100     */
101    @Override
102    public void onMouseOut(MouseOutEvent event) {
103
104        m_openTimer.cancel();
105        m_widget.setFocus(false);
106    }
107
108    /**
109     * @see com.google.gwt.event.dom.client.MouseOverHandler#onMouseOver(com.google.gwt.event.dom.client.MouseOverEvent)
110     */
111    @Override
112    public void onMouseOver(MouseOverEvent event) {
113
114        m_openTimer.cancel();
115
116        if (isEnabled()) {
117            if (!m_widget.isSubmenuOpen()) {
118                m_widget.closeSiblingMenus();
119            }
120            m_widget.setFocus(true);
121
122            if (m_widget.hasSubMenu() && !m_widget.isSubmenuOpen()) {
123                m_openTimer.schedule(100);
124            }
125        }
126    }
127
128    /**
129     * On item click.<p>
130     */
131    void onItemClicked() {
132
133        boolean menuClosed = m_widget.onItemClicked();
134        m_contextMenuRpc.itemClicked(m_widget.getId(), menuClosed);
135    }
136
137    /**
138     * Returns whether the item is enabled.<p>
139     *
140     * @return <code>true</code> if the item is enabled
141     */
142    private boolean isEnabled() {
143
144        return m_widget.isEnabled();
145    }
146
147    /**
148     * On down press.<p>
149     */
150    private void onDownPressed() {
151
152        if (isEnabled()) {
153            m_widget.selectLowerSibling();
154        }
155    }
156
157    /**
158     * On enter press.<p>
159     */
160    private void onEnterPressed() {
161
162        if (isEnabled()) {
163            if (m_widget.hasSubMenu()) {
164                if (!m_widget.isSubmenuOpen()) {
165                    boolean menuClosed = m_widget.onItemClicked();
166                    m_contextMenuRpc.itemClicked(m_widget.getId(), menuClosed);
167                }
168            } else {
169                boolean menuClosed = m_widget.onItemClicked();
170                m_contextMenuRpc.itemClicked(m_widget.getId(), menuClosed);
171            }
172        }
173    }
174
175    /**
176     * On left press.<p>
177     */
178    private void onLeftPressed() {
179
180        if (isEnabled()) {
181            m_widget.closeThisAndSelectParent();
182        }
183    }
184
185    /**
186     * On right press.<p>
187     */
188    private void onRightPressed() {
189
190        if (isEnabled()) {
191            if (m_widget.hasSubMenu()) {
192                onItemClicked();
193            }
194        }
195    }
196
197    /**
198     * On up press.<p>
199     */
200    private void onUpPressed() {
201
202        if (isEnabled()) {
203            m_widget.selectUpperSibling();
204        }
205    }
206}