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        this.m_widget = widget;
051
052        m_contextMenuRpc = RpcProxy.create(I_CmsContextMenuServerRpc.class, connector);
053    }
054
055    /**
056     * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
057     */
058    @Override
059    public void onClick(ClickEvent event) {
060
061        if (isEnabled()) {
062            m_openTimer.cancel();
063
064            if (m_widget.hasSubMenu()) {
065                if (!m_widget.isSubmenuOpen()) {
066                    m_widget.onItemClicked();
067                    m_contextMenuRpc.itemClicked(m_widget.getId(), false);
068                }
069            } else {
070                boolean menuClosed = m_widget.onItemClicked();
071                m_contextMenuRpc.itemClicked(m_widget.getId(), menuClosed);
072            }
073        }
074    }
075
076    /**
077     * @see com.google.gwt.event.dom.client.KeyUpHandler#onKeyUp(com.google.gwt.event.dom.client.KeyUpEvent)
078     */
079    @Override
080    public void onKeyUp(KeyUpEvent event) {
081
082        int keycode = event.getNativeEvent().getKeyCode();
083
084        if (keycode == KeyCodes.KEY_LEFT) {
085            onLeftPressed();
086        } else if (keycode == KeyCodes.KEY_RIGHT) {
087            onRightPressed();
088        } else if (keycode == KeyCodes.KEY_UP) {
089            onUpPressed();
090        } else if (keycode == KeyCodes.KEY_DOWN) {
091            onDownPressed();
092        } else if (keycode == KeyCodes.KEY_ENTER) {
093            onEnterPressed();
094        }
095    }
096
097    /**
098     * @see com.google.gwt.event.dom.client.MouseOutHandler#onMouseOut(com.google.gwt.event.dom.client.MouseOutEvent)
099     */
100    @Override
101    public void onMouseOut(MouseOutEvent event) {
102
103        m_openTimer.cancel();
104        m_widget.setFocus(false);
105    }
106
107    /**
108     * @see com.google.gwt.event.dom.client.MouseOverHandler#onMouseOver(com.google.gwt.event.dom.client.MouseOverEvent)
109     */
110    @Override
111    public void onMouseOver(MouseOverEvent event) {
112
113        m_openTimer.cancel();
114
115        if (isEnabled()) {
116            if (!m_widget.isSubmenuOpen()) {
117                m_widget.closeSiblingMenus();
118            }
119            m_widget.setFocus(true);
120
121            if (m_widget.hasSubMenu() && !m_widget.isSubmenuOpen()) {
122                m_openTimer.schedule(100);
123            }
124        }
125    }
126
127    /**
128     * On item click.<p>
129     */
130    void onItemClicked() {
131
132        boolean menuClosed = m_widget.onItemClicked();
133        m_contextMenuRpc.itemClicked(m_widget.getId(), menuClosed);
134    }
135
136    /**
137     * Returns whether the item is enabled.<p>
138     *
139     * @return <code>true</code> if the item is enabled
140     */
141    private boolean isEnabled() {
142
143        return m_widget.isEnabled();
144    }
145
146    /**
147     * On down press.<p>
148     */
149    private void onDownPressed() {
150
151        if (isEnabled()) {
152            m_widget.selectLowerSibling();
153        }
154    }
155
156    /**
157     * On enter press.<p>
158     */
159    private void onEnterPressed() {
160
161        if (isEnabled()) {
162            if (m_widget.hasSubMenu()) {
163                if (!m_widget.isSubmenuOpen()) {
164                    boolean menuClosed = m_widget.onItemClicked();
165                    m_contextMenuRpc.itemClicked(m_widget.getId(), menuClosed);
166                }
167            } else {
168                boolean menuClosed = m_widget.onItemClicked();
169                m_contextMenuRpc.itemClicked(m_widget.getId(), menuClosed);
170            }
171        }
172    }
173
174    /**
175     * On left press.<p>
176     */
177    private void onLeftPressed() {
178
179        if (isEnabled()) {
180            m_widget.closeThisAndSelectParent();
181        }
182    }
183
184    /**
185     * On right press.<p>
186     */
187    private void onRightPressed() {
188
189        if (isEnabled()) {
190            if (m_widget.hasSubMenu()) {
191                onItemClicked();
192            }
193        }
194    }
195
196    /**
197     * On up press.<p>
198     */
199    private void onUpPressed() {
200
201        if (isEnabled()) {
202            m_widget.selectUpperSibling();
203        }
204    }
205}