1 // This may look like C code, but it's really -*- C++ -*-
2 /*
3  * Copyright (C) 2008 Emweb bv, Herent, Belgium.
4  *
5  * See the LICENSE file for terms of use.
6  */
7 #ifndef WPANEL_H_
8 #define WPANEL_H_
9 
10 #include <Wt/WCompositeWidget.h>
11 
12 namespace Wt {
13 
14   class WContainerWidget;
15   class WIconPair;
16   class WTemplate;
17   class WText;
18 
19 /*! \class WPanel Wt/WPanel.h Wt/WPanel.h
20  *  \brief A %WPanel provides a container with a title bar.
21  *
22  * The panel provides a container with an optional title bar, and an
23  * optional collapse icon.
24  *
25  * \if cpp
26  * Usage example:
27  * \code
28  * auto panel = std::make_unique<Wt::WPanel>();
29  * panel->setTitle("A panel");
30  * panel->setCentralWidget(std::make_unique<Wt::WText>("This is the panel contents"));
31  * panel->setCollapsible(true);
32  * \endcode
33  * \endif
34  *
35  * \image html WPanel-default-1.png "Two panels: one collapsed and one expanded (default theme)"
36  * \image html WPanel-polished-1.png "Two panels: one collapsed and one expanded (polished theme)"
37  */
38 class WT_API WPanel : public WCompositeWidget
39 {
40 public:
41   /*! \brief Creates a panel.
42    */
43   WPanel();
44 
45   /*! \brief Sets a title.
46    *
47    * The panel title is set in the title bar. This method also makes
48    * the title bar visible by calling setTitleBar(true).
49    *
50    * The default value is "" (no title).
51    *
52    * \sa title(), setTitleBar(bool)
53    */
54   void setTitle(const WString& title);
55 
56   /*! \brief Returns the title.
57    *
58    * \sa setTitle(const WString&)
59    */
60   WString title() const;
61 
62   /*! \brief Shows or hides the title bar for the panel.
63    *
64    * The title bar appears at the top of the panel.
65    *
66    * The default value is \c false: the title bar is not shown unless a
67    * title is set or the panel is made collapsible.
68    *
69    * \sa setTitle(const WString&), setCollapsible(bool)
70    */
71   void setTitleBar(bool enable);
72 
73   /*! \brief Returns if a title bar is set.
74    *
75    * \sa setTitleBar(bool)
76    */
77   bool titleBar() const;
78 
79   /*! \brief Returns the title bar widget.
80    *
81    * The title bar widget contains the collapse/expand icon (if the
82    * panel isCollapsible()), and the title text (if a title was set
83    * using setTitle()). You can access the title bar widget to customize
84    * the contents of the title.
85    *
86    * The method returns \c 0 if titleBar() is \p false. You need to call
87    * setTitleBar() first.
88    *
89    * \sa setTitleBar()
90    */
91   WContainerWidget *titleBarWidget() const;
92 
93   /*! \brief Makes the panel collapsible.
94    *
95    * When \p on is \c true, a collapse/expand icon is added to the
96    * title bar. This also calls setTitleBar(true) to enable the
97    * title bar.
98    *
99    * The default value is \c false.
100    *
101    * \sa setTitleBar(bool), setCollapsed(bool), isCollapsed()
102    *
103    * \note It is possible to make a WPanel collapsible with WBootstrap5Theme,
104    * but collapsing and expanding from C++, and the accompanying signals
105    * is not supported.
106    */
107   void setCollapsible(bool on);
108 
109   /*! \brief Returns if the panel can be collapsed by the user.
110    *
111    * \sa setCollapsible(bool)
112    */
isCollapsible()113   bool isCollapsible() const { return isCollapsible_; }
114 
115   /*! \brief Sets the panel expanded or collapsed.
116    *
117    * When \p on is \c true, equivalent to collapse(), otherwise to
118    * expand().
119    *
120    * The default value is \c false.
121    *
122    * \sa setCollapsible(bool)
123    *
124    * \note It is possible to make a WPanel collapsible with WBootstrap5Theme,
125    * but collapsing and expanding from C++, and the accompanying signals
126    * is not supported.
127    */
128   void setCollapsed(bool on);
129 
130   /*! \brief Returns if the panel is collapsed.
131    *
132    * \sa setCollapsed(bool)
133    * \sa collapsed(), expanded()
134    *
135    * \note It is possible to make a WPanel collapsible with WBootstrap5Theme,
136    * but collapsing and expanding from C++, and the accompanying signals
137    * is not supported.
138    */
139   bool isCollapsed() const;
140 
141   /*! \brief Collapses the panel.
142    *
143    * When isCollapsible() is true, the panel is collapsed to minimize
144    * screen real-estate.
145    *
146    * \sa setCollapsible(bool), expand()
147    *
148    * \note It is possible to make a WPanel collapsible with WBootstrap5Theme,
149    * but collapsing and expanding from C++, and the accompanying signals
150    * is not supported.
151    */
152   void collapse();
153 
154   /*! \brief Collapses the panel.
155    *
156    * When isCollapsible() is true, the panel is expanded to its original
157    * state.
158    *
159    * \sa setCollapsible(bool), expand()
160    *
161    * \note It is possible to make a WPanel collapsible with WBootstrap5Theme,
162    * but collapsing and expanding from C++, and the accompanying signals
163    * is not supported.
164    */
165   void expand();
166 
167   /*! \brief Sets an animation.
168    *
169    * The animation is used when collapsing or expanding the panel.
170    *
171    * \note It is possible to make a WPanel collapsible with WBootstrap5Theme,
172    * but it's not possible to set the animation.
173    */
174   void setAnimation(const WAnimation& transition);
175 
176   /*! \brief Sets the central widget.
177    *
178    * Sets the widget that is the contents of the panel.
179    *
180    * The default value is \c 0 (no widget set).
181    */
182   void setCentralWidget(std::unique_ptr<WWidget> widget);
183 
184   template <typename Widget>
setCentralWidget(std::unique_ptr<Widget> widget)185     Widget *setCentralWidget(std::unique_ptr<Widget> widget)
186 #ifndef WT_TARGET_JAVA
187   {
188     Widget *result = widget.get();
189     setCentralWidget(std::unique_ptr<WWidget>(std::move(widget)));
190     return result;
191   }
192 #else // WT_TARGET_JAVA
193   ;
194 #endif // WT_TARGET_JAVA
195 
196   /*! \brief Returns the central widget.
197    *
198    * \sa setCentralWidget()
199    */
centralWidget()200   WWidget *centralWidget() const { return centralWidget_; }
201 
202   /*! \brief %Signal emitted when the panel is collapsed.
203    *
204    * %Signal emitted when the panel is collapsed. The signal is only
205    * emitted when the panel is collapsed by the user using the
206    * collapse icon in the tible bar, not when calling
207    * setCollapsed(bool).
208    *
209    * \sa expanded()
210    *
211    * \note It is possible to make a WPanel collapsible with WBootstrap5Theme,
212    * but it's not possible to set the animation.
213    */
collapsed()214   Signal<>& collapsed() { return collapsed_; }
215 
216   /*! \brief %Signal emitted when the panel is expanded.
217    *
218    * %Signal emitted when the panel is expanded. The signal is only
219    * emitted when the panel is expanded by the user using the expand
220    * icon in the title bar, not when calling setCollapsed(bool).
221    *
222    * \sa collapsed()
223    *
224    * \note It is possible to make a WPanel collapsible with WBootstrap5Theme,
225    * but it's not possible to set the animation.
226    */
expanded()227   Signal<>& expanded() { return expanded_; }
228 
collapsedSS()229   Signal<bool>& collapsedSS() { return collapsedSS_; }
expandedSS()230   Signal<bool>& expandedSS() { return expandedSS_; }
231 
collapseIcon()232   WIconPair *collapseIcon() const { return collapseIcon_; }
233 
234 private:
235   WIconPair *collapseIcon_;
236   WWidget *title_;
237 
238   WTemplate *impl_;
239   WWidget *centralWidget_;
240   WAnimation animation_;
241 
242   Signal<> collapsed_, expanded_;
243   Signal<bool> collapsedSS_, expandedSS_;
244 
245   bool wasCollapsed_;
246   bool isCollapsible_;
247 
248   void setJsSize();
249   void toggleCollapse();
250   void doExpand();
251   void doCollapse();
252   void undoExpand();
253   void undoCollapse();
254 
255   virtual void onExpand();
256   virtual void onCollapse();
257 
258   WContainerWidget *centralArea() const;
259 };
260 
261 }
262 
263 #endif // WPANEL_H_
264