001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.ade.containerpage.client.ui;
029
030import org.opencms.gwt.client.CmsCoreProvider;
031import org.opencms.gwt.client.CmsPageEditorTouchHandler;
032import org.opencms.gwt.client.I_CmsElementToolbarContext;
033import org.opencms.gwt.client.dnd.CmsDNDHandler;
034import org.opencms.gwt.client.ui.A_CmsHoverHandler;
035import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle;
036import org.opencms.gwt.client.util.I_CmsUniqueActiveItem;
037import org.opencms.gwt.shared.CmsGwtConstants;
038
039import java.util.Iterator;
040
041import com.google.gwt.event.dom.client.HasMouseOutHandlers;
042import com.google.gwt.event.dom.client.HasMouseOverHandlers;
043import com.google.gwt.event.dom.client.MouseOutEvent;
044import com.google.gwt.event.dom.client.MouseOutHandler;
045import com.google.gwt.event.dom.client.MouseOverEvent;
046import com.google.gwt.event.dom.client.MouseOverHandler;
047import com.google.gwt.event.shared.HandlerRegistration;
048import com.google.gwt.user.client.Timer;
049import com.google.gwt.user.client.ui.Composite;
050import com.google.gwt.user.client.ui.FlowPanel;
051import com.google.gwt.user.client.ui.Widget;
052
053/**
054 * A panel to be displayed inside a container element to provide optional functions like edit, move, remove... <p>
055 *
056 * @since 8.0.0
057 */
058public class CmsElementOptionBar extends Composite
059implements HasMouseOverHandlers, HasMouseOutHandlers, I_CmsUniqueActiveItem, I_CmsElementToolbarContext {
060
061    /**
062     * Hover handler for option bar.<p>
063     */
064    protected class HoverHandler extends A_CmsHoverHandler {
065
066        /**
067         * @see org.opencms.gwt.client.ui.A_CmsHoverHandler#onHoverIn(com.google.gwt.event.dom.client.MouseOverEvent)
068         */
069        @Override
070        protected void onHoverIn(MouseOverEvent event) {
071
072            if (!CmsPageEditorTouchHandler.get().ignoreHover()) {
073                timer = null;
074                CmsCoreProvider.get().getFlyoutMenuContainer().setActiveItem(CmsElementOptionBar.this);
075                addHighlighting();
076            }
077        }
078
079        /**
080         * @see org.opencms.gwt.client.ui.A_CmsHoverHandler#onHoverOut(com.google.gwt.event.dom.client.MouseOutEvent)
081         */
082        @Override
083        protected void onHoverOut(MouseOutEvent event) {
084
085            if (!CmsPageEditorTouchHandler.get().ignoreHover()) {
086
087                timer = new Timer() {
088
089                    @Override
090                    public void run() {
091
092                        if (timer == this) {
093                            removeHighlighting();
094                        }
095                    }
096                };
097                timer.schedule(750);
098            }
099        }
100    }
101
102    /** The timer used for hiding the option bar. */
103    /*default */static Timer timer;
104
105    /** The calculated panel width. */
106    private int m_calculatedWidth;
107
108    /** The parent container element. */
109    private CmsContainerPageElementPanel m_containerElement;
110
111    /** The panel. */
112    private FlowPanel m_panel;
113
114    /**
115     * Constructor.<p>
116     *
117     * @param containerElement the parent container element
118     */
119    public CmsElementOptionBar(CmsContainerPageElementPanel containerElement) {
120
121        m_panel = new FlowPanel(CmsGwtConstants.TAG_OC_EDITPOINT);
122        m_containerElement = containerElement;
123        initWidget(m_panel);
124        HoverHandler handler = new HoverHandler();
125        addMouseOverHandler(handler);
126        addMouseOutHandler(handler);
127        setStyleName(I_CmsElementToolbarContext.ELEMENT_OPTION_BAR_CSS_CLASS);
128        addStyleName(I_CmsLayoutBundle.INSTANCE.generalCss().opencms());
129        if (containerElement.isReused()) {
130            addStyleName(
131                org.opencms.ade.containerpage.client.ui.css.I_CmsLayoutBundle.INSTANCE.containerpageCss().reusedElement());
132        } else {
133            removeStyleName(
134                org.opencms.ade.containerpage.client.ui.css.I_CmsLayoutBundle.INSTANCE.containerpageCss().reusedElement());
135        }
136    }
137
138    /**
139     * Creates an option-bar for the given drag element.<p>
140     *
141     * @param element the element to create the option-bar for
142     * @param dndHandler the drag and drop handler
143     * @param buttons the list of buttons to display
144     *
145     * @return the created option-bar
146     */
147    public static CmsElementOptionBar createOptionBarForElement(
148        CmsContainerPageElementPanel element,
149        CmsDNDHandler dndHandler,
150        A_CmsToolbarOptionButton... buttons) {
151
152        CmsElementOptionBar optionBar = new CmsElementOptionBar(element);
153        if (buttons != null) {
154            // add buttons, last as first
155            for (int i = buttons.length - 1; i >= 0; i--) {
156                CmsElementOptionButton option = buttons[i].createOptionForElement(element);
157                if (option == null) {
158                    continue;
159                }
160                optionBar.add(option);
161                if (buttons[i] instanceof CmsToolbarMoveButton) {
162                    option.addMouseDownHandler(dndHandler);
163                }
164            }
165        }
166        return optionBar;
167    }
168
169    /**
170     * @see org.opencms.gwt.client.I_CmsElementToolbarContext#activateToolbarContext()
171     */
172    public void activateToolbarContext() {
173
174        addHighlighting();
175    }
176
177    /**
178     * Adds another option button.<p>
179     *
180     * @param w the button to add
181     */
182    public void add(Widget w) {
183
184        m_panel.add(w);
185    }
186
187    /**
188     * @see com.google.gwt.event.dom.client.HasMouseOutHandlers#addMouseOutHandler(com.google.gwt.event.dom.client.MouseOutHandler)
189     */
190    public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) {
191
192        return addDomHandler(handler, MouseOutEvent.getType());
193
194    }
195
196    /**
197     * @see com.google.gwt.event.dom.client.HasMouseOverHandlers#addMouseOverHandler(com.google.gwt.event.dom.client.MouseOverHandler)
198     */
199    public HandlerRegistration addMouseOverHandler(MouseOverHandler handler) {
200
201        return addDomHandler(handler, MouseOverEvent.getType());
202    }
203
204    /**
205    * Clears the bar.<p>
206    */
207    public void clear() {
208
209        m_panel.clear();
210        m_calculatedWidth = 0;
211    }
212
213    /**
214     * @see org.opencms.gwt.client.I_CmsElementToolbarContext#deactivateToolbarContext()
215     */
216    public void deactivateToolbarContext() {
217
218        try {
219            internalRemoveHighlighting();
220        } catch (Exception e) {
221            // ignore
222        }
223    }
224
225    /**
226     * Returns the calculated width of the widget.<p>
227     *
228     * @return the calculated width
229     */
230    public int getCalculatedWidth() {
231
232        return m_calculatedWidth;
233    }
234
235    /**
236     * Returns an iterator for the child widgets.<p>
237     *
238     * @return the iterator
239     */
240    public Iterator<Widget> iterator() {
241
242        return m_panel.iterator();
243    }
244
245    /**
246     * @see org.opencms.gwt.client.util.I_CmsUniqueActiveItem#onDeactivate()
247     */
248    public void onDeactivate() {
249
250        try {
251            internalRemoveHighlighting();
252        } catch (Exception e) {
253            // ignore
254
255        }
256    }
257
258    /**
259     * Removes the highlighting and option bar.<p>
260     */
261    public void removeHighlighting() {
262
263        timer = null;
264        CmsCoreProvider.get().getFlyoutMenuContainer().clearIfMatches(this);
265        internalRemoveHighlighting();
266    }
267
268    /**
269     * Adds the highlighting and option bar.<p>
270     */
271    protected void addHighlighting() {
272
273        getElement().addClassName(I_CmsLayoutBundle.INSTANCE.stateCss().cmsHovering());
274        getContainerElement().highlightElement();
275
276    }
277
278    /**
279     * Returns the parent container element.<p>
280     *
281     * @return the parent container element
282     */
283    protected CmsContainerPageElementPanel getContainerElement() {
284
285        return m_containerElement;
286    }
287
288    /**
289     * Removes the highlighting.<p>
290     */
291    protected void internalRemoveHighlighting() {
292
293        getElement().removeClassName(I_CmsLayoutBundle.INSTANCE.stateCss().cmsHovering());
294        getContainerElement().removeHighlighting();
295
296    }
297}