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