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.gwt.client.ui;
029
030import org.opencms.gwt.client.ui.I_CmsButton.ButtonColor;
031import org.opencms.gwt.client.ui.I_CmsButton.ButtonStyle;
032import org.opencms.gwt.client.ui.I_CmsButton.Size;
033import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle;
034import org.opencms.gwt.client.ui.input.CmsLabel;
035import org.opencms.gwt.client.util.CmsDomUtil;
036import org.opencms.gwt.client.util.CmsSlideAnimation;
037import org.opencms.gwt.client.util.CmsStyleVariable;
038
039import java.util.Iterator;
040
041import com.google.gwt.animation.client.Animation;
042import com.google.gwt.core.client.GWT;
043import com.google.gwt.dom.client.Style.Display;
044import com.google.gwt.event.dom.client.ClickEvent;
045import com.google.gwt.event.logical.shared.CloseEvent;
046import com.google.gwt.event.logical.shared.CloseHandler;
047import com.google.gwt.event.logical.shared.HasCloseHandlers;
048import com.google.gwt.event.logical.shared.HasOpenHandlers;
049import com.google.gwt.event.logical.shared.OpenEvent;
050import com.google.gwt.event.logical.shared.OpenHandler;
051import com.google.gwt.event.shared.HandlerRegistration;
052import com.google.gwt.uibinder.client.UiBinder;
053import com.google.gwt.uibinder.client.UiField;
054import com.google.gwt.uibinder.client.UiHandler;
055import com.google.gwt.user.client.Command;
056import com.google.gwt.user.client.ui.Composite;
057import com.google.gwt.user.client.ui.FlowPanel;
058import com.google.gwt.user.client.ui.HasWidgets;
059import com.google.gwt.user.client.ui.Widget;
060
061/**
062 * A panel that behaves like a HTML fieldset.<p>
063 *
064 * @since 8.0.0
065 */
066public class CmsFieldSet extends Composite
067implements HasOpenHandlers<CmsFieldSet>, HasCloseHandlers<CmsFieldSet>, HasWidgets {
068
069    /** The ui-binder interface for this composite. */
070    protected interface I_CmsFieldSetUiBinder extends UiBinder<Widget, CmsFieldSet> {
071        // GWT interface, nothing to do here
072    }
073
074    /** Default animation duration.*/
075    public static final int DEFAULT_ANIMATION_DURATION = 300;
076
077    /** The ui-binder instance. */
078    private static I_CmsFieldSetUiBinder uiBinder = GWT.create(I_CmsFieldSetUiBinder.class);
079
080    /** The content of the fieldset. */
081    @UiField
082    protected FlowPanel m_content;
083
084    /** The wrapping panel for this fieldset. */
085    @UiField
086    protected FlowPanel m_fieldset;
087
088    /** The image for the top and bottom arrow. */
089    @UiField
090    protected CmsPushButton m_opener;
091
092    /** The legend of the fieldset. */
093    @UiField
094    protected CmsLabel m_legend;
095
096    /** Signals whether the fieldset is opened. */
097    protected boolean m_opened;
098
099    /** The legend of the fieldset. */
100    @UiField
101    protected FlowPanel m_wrapper;
102
103    /** The running slide in/out animation. */
104    private Animation m_animation;
105
106    /** The animation duration. */
107    private int m_animationDuration = DEFAULT_ANIMATION_DURATION;
108
109    /** The fieldset visibility style. */
110    private CmsStyleVariable m_visibilityStyle;
111
112    /**
113     * Default constructor.<p>
114     *
115     * Because this class has a default constructor, it can
116     * be used as a binder template. In other words, it can be used in other
117     * *.ui.xml files:
118     */
119    public CmsFieldSet() {
120
121        initWidget(uiBinder.createAndBindUi(this));
122        m_opener.setImageClass(I_CmsButton.ICON_FONT + " " + I_CmsButton.TRIANGLE_RIGHT);
123        m_opener.setDownImageClass(I_CmsButton.ICON_FONT + " " + I_CmsButton.TRIANGLE_DOWN);
124        m_opener.setButtonStyle(ButtonStyle.TEXT, ButtonColor.GRAY);
125        m_opener.setSize(Size.small);
126        m_visibilityStyle = new CmsStyleVariable(m_fieldset);
127        setOpen(true);
128
129    }
130
131    /**
132     * @see com.google.gwt.user.client.ui.HasWidgets#add(com.google.gwt.user.client.ui.Widget)
133     */
134    public void add(Widget widget) {
135
136        m_content.add(widget);
137    }
138
139    /**
140     * @see com.google.gwt.event.logical.shared.HasCloseHandlers#addCloseHandler(com.google.gwt.event.logical.shared.CloseHandler)
141     */
142    public HandlerRegistration addCloseHandler(CloseHandler<CmsFieldSet> handler) {
143
144        return addHandler(handler, CloseEvent.getType());
145    }
146
147    /**
148     * Adds a widget to this field set.<p>
149     *
150     * @param w the widget to add
151     */
152    public void addContent(Widget w) {
153
154        m_content.add(w);
155    }
156
157    /**
158     * @see com.google.gwt.event.logical.shared.HasOpenHandlers#addOpenHandler(com.google.gwt.event.logical.shared.OpenHandler)
159     */
160    public HandlerRegistration addOpenHandler(OpenHandler<CmsFieldSet> handler) {
161
162        return addHandler(handler, OpenEvent.getType());
163    }
164
165    /**
166     * @see com.google.gwt.user.client.ui.HasWidgets#clear()
167     */
168    public void clear() {
169
170        m_content.clear();
171    }
172
173    /**
174     * Returns the content panel.<p>
175     *
176     * @return the content panel
177     */
178    public FlowPanel getContentPanel() {
179
180        return m_content;
181    }
182
183    /**
184     * Returns the count of widgets inside this fieldset.<p>
185     *
186     * @return the count of widgets inside this fieldset
187     */
188    public int getWidgetCount() {
189
190        return m_content.getWidgetCount();
191    }
192
193    /**
194     * Returns the wrapper.<p>
195     *
196     * @return the wrapper
197     */
198    public FlowPanel getWrapper() {
199
200        return m_wrapper;
201    }
202
203    /**
204     * Returns if the fieldset is opened.<p>
205     *
206     * @return <code>true</code> if the fieldset is opened
207     */
208    public boolean isOpen() {
209
210        return m_opened;
211    }
212
213    /**
214     * @see com.google.gwt.user.client.ui.HasWidgets#iterator()
215     */
216    public Iterator<Widget> iterator() {
217
218        return m_content.iterator();
219    }
220
221    /**
222     * @see com.google.gwt.user.client.ui.HasWidgets#remove(com.google.gwt.user.client.ui.Widget)
223     */
224    public boolean remove(Widget widget) {
225
226        return m_content.remove(widget);
227    }
228
229    /**
230     * Sets the animation duration.
231     * @param animDuration the animation duration
232     */
233    public void setAnimationDuration(int animDuration) {
234
235        m_animationDuration = animDuration;
236    }
237
238    /**
239     * Sets the text for the legend of this field set.<p>
240     *
241     * @param legendText the legend text
242     */
243    public void setLegend(String legendText) {
244
245        m_legend.setText(legendText);
246    }
247
248    /**
249     * Sets the fieldset open, showing the content.<p>
250     *
251     * @param open <code>true</code> to open the fieldset
252     */
253    public void setOpen(boolean open) {
254
255        m_opened = open;
256        if (m_opened) {
257            // show content
258            m_visibilityStyle.setValue(
259                I_CmsLayoutBundle.INSTANCE.generalCss().cornerAll()
260                    + " "
261                    + I_CmsLayoutBundle.INSTANCE.fieldsetCss().fieldsetVisible());
262            m_opener.setDown(true);
263        } else {
264            // hide content
265            m_visibilityStyle.setValue(I_CmsLayoutBundle.INSTANCE.fieldsetCss().fieldsetInvisible());
266            m_opener.setDown(false);
267        }
268        CmsDomUtil.resizeAncestor(getParent());
269    }
270
271    /**
272     * Sets the opener visible.<p>
273     *
274     * @param visible <code>true</code> to set the opener visible
275     */
276    public void setOpenerVisible(boolean visible) {
277
278        if (visible) {
279            m_opener.getElement().getStyle().clearDisplay();
280        } else {
281            m_opener.getElement().getStyle().setDisplay(Display.NONE);
282        }
283    }
284
285    /**
286     * Adds a click handler to the image icon of this fieldset.<p>
287     *
288     * On click the
289     *
290     * @param e the event
291     */
292    @UiHandler("m_opener")
293    protected void handleClick(ClickEvent e) {
294
295        if (m_animation != null) {
296            m_animation.cancel();
297        }
298        if (!m_opened) {
299
300            // show content
301            setOpen(true);
302
303            m_animation = CmsSlideAnimation.slideIn(m_content.getElement(), new Command() {
304
305                /**
306                 * @see com.google.gwt.user.client.Command#execute()
307                 */
308                public void execute() {
309
310                    OpenEvent.fire(CmsFieldSet.this, CmsFieldSet.this);
311                    CmsDomUtil.resizeAncestor(getParent());
312                }
313            }, m_animationDuration);
314        } else {
315
316            // hide content
317            m_animation = CmsSlideAnimation.slideOut(m_content.getElement(), new Command() {
318
319                /**
320                 * @see com.google.gwt.user.client.Command#execute()
321                 */
322                public void execute() {
323
324                    setOpen(false);
325                    CloseEvent.fire(CmsFieldSet.this, CmsFieldSet.this);
326                    CmsDomUtil.resizeAncestor(getParent());
327                }
328            }, m_animationDuration);
329        }
330    }
331}