Coverage Report

Created: 2026-01-10 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wt/src/Wt/WTabWidget.h
Line
Count
Source
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 WTABWIDGET_H_
8
#define WTABWIDGET_H_
9
10
#include <Wt/WCompositeWidget.h>
11
#include <Wt/WContainerWidget.h>
12
13
namespace Wt {
14
15
  class WMenu;
16
  class WMenuItem;
17
  class WStackedWidget;
18
19
/*! \class WTabWidget Wt/WTabWidget.h Wt/WTabWidget.h
20
 *  \brief A widget that organizes contents in tab panes.
21
 *
22
 * This widget combines a horizontal WMenu with a WStackedWidget, and a
23
 * tab-like look.
24
 *
25
 * A tab widget will place the tab bar on top of the contents, and fit the
26
 * contents below it.
27
 *
28
 * Usage example:
29
 * \if cpp
30
 * \code
31
 * Wt::WTabWidget *examples = addWidget(std::make_unique<Wt::WTabWidget>());
32
 *
33
 * examples->addTab(helloWorldExample(), "Hello World");
34
 * examples->addTab(chartExample(), "Charts");
35
 * examples->addTab(std::make_unique<Wt::WText>("A WText"), "WText");
36
 *
37
 * examples->currentChanged().connect(this, &MyClass::logInternalPath);
38
 * examples->setInternalPathEnabled();
39
 * examples->setInternalBasePath("/examples");
40
 * \endcode
41
 * \elseif java
42
 * \code
43
 * WTabWidget examples = new WTabWidget(this);
44
 *
45
 * examples.addTab(helloWorldExample(), "Hello World");
46
 * examples.addTab(chartExample(), "Charts");
47
 * examples.addTab(new WText("A WText"), "WText");
48
 *
49
 * examples.currentChanged().addListener(this, new Signal.Listener(){
50
 *   public void trigger() {
51
 *     //custom code
52
 *   }
53
 * });
54
 * examples.setInternalPathEnabled();
55
 * examples.setInternalBasePath("/examples");
56
 * \endcode
57
 * \endif
58
 *
59
 * <h3>CSS</h3>
60
 *
61
 * The tab widget is styled by the current CSS theme.
62
 *
63
 * <TABLE border="0" align="center"> <TR> <TD>
64
 * \image html WTabWidget-default-1.png "An example WTabWidget (default)"
65
 * </TD> <TD>
66
 * \image html WTabWidget-polished-1.png "An example WTabWidget (polished)"
67
 * </TD> </TR> </TABLE>
68
 */
69
class WT_API WTabWidget : public WCompositeWidget
70
{
71
public:
72
  /*! \brief Creates a new tab widget
73
   */
74
  WTabWidget();
75
76
  /*! \brief Adds a new tab, with <i>child</i> as content, and the given label.
77
   *
78
   * Returns the menu item that implements the tab item.
79
   */
80
  WMenuItem *addTab(std::unique_ptr<WWidget> child,
81
                    const WString& label,
82
                    ContentLoading loadPolicy = ContentLoading::Lazy);
83
84
  /*! \brief Inserts a new tab, with <i>child</i> as content, and the given label.
85
   *
86
   * Returns the menu item that implements the tab item.
87
   */
88
  WMenuItem *insertTab(int index, std::unique_ptr<WWidget> child, const WString& label,
89
                       ContentLoading loadPolicy = ContentLoading::Lazy);
90
91
  /*! \brief Removes a tab item.
92
   *
93
   * \sa WMenu::removeItem()
94
   */
95
  std::unique_ptr<WWidget> removeTab(WWidget *widget);
96
97
  /*! \brief Returns the number of tabs.
98
   */
99
  int count() const;
100
101
  /*! \brief Returns the content widget at the given tab <i>index</i>.
102
   */
103
  WWidget *widget(int index) const;
104
105
  /*! \brief Returns the item at the given tab <i>index</i>.
106
   */
107
  WMenuItem *itemAt(int index) const;
108
109
  /*! \brief Returns the index of the tab of the given content widget.
110
   *
111
   * If the widget is not in this tab widget, then -1 is returned.
112
   */
113
  int indexOf(WWidget *widget) const;
114
115
  /*! \brief Activates the tab at <i>index</i>.
116
   */
117
  void setCurrentIndex(int index);
118
119
  /*! \brief Returns the index of the activated tab.
120
   */
121
  int currentIndex() const;
122
123
  /*! \brief Activates the tab showing the given <i>widget</i>
124
   */
125
  void setCurrentWidget(WWidget *widget);
126
127
  /*! \brief Returns the widget of the activated tab.
128
   */
129
  WWidget *currentWidget() const;
130
131
  /*! \brief Returns the item of the activated tab.
132
   */
133
  WMenuItem *currentItem() const;
134
135
  /*! \brief Enables or disables a tab.
136
   *
137
   * Enables or disables the tab at \p index. A disabled tab cannot be
138
   * activated.
139
   */
140
  void setTabEnabled(int index, bool enable);
141
142
  /*! \brief Returns whether a tab is enabled.
143
   *
144
   * \sa WMenu::enableItem(), WMenu::disableItem()
145
   */
146
  bool isTabEnabled(int index) const;
147
148
  /*! \brief Hides or shows a tab.
149
   *
150
   * Hides or shows the tab at \p index.
151
   */
152
  void setTabHidden(int index, bool hidden);
153
154
  /*! \brief Returns whether a tab is hidden.
155
   */
156
  bool isTabHidden(int index) const;
157
158
  /*! \brief Make it possible to close a tab interactively or by
159
   * \link WTabWidget::closeTab() closeTab\endlink.
160
   *
161
   * A tab that has been closed is marked as hidden, but not removed
162
   * from the menu.
163
   *
164
   * \sa removeTab()
165
   */
166
  void setTabCloseable(int index, bool closeable);
167
168
  /*! \brief Returns whether a tab is closeable.
169
   *
170
   * \sa setTabCloseable()
171
   */
172
  bool isTabCloseable(int index);
173
174
  /*! \brief Changes the label for a tab.
175
   */
176
  void setTabText(int index, const WString& label);
177
178
  /*! \brief Returns the label for a tab.
179
   *
180
   * \sa setTabText()
181
   */
182
  WString tabText(int index) const;
183
184
  /*! \brief Sets the tooltip for a tab.
185
   *
186
   * The tooltip is shown when the user hovers over the label.
187
   */
188
  void setTabToolTip(int index, const WString& tip);
189
190
  /*! \brief Returns the tooltip for a tab.
191
   *
192
   * \sa setTabToolTip()
193
   */
194
  WString tabToolTip(int index) const;
195
196
  /*! \brief Enables internal paths for items.
197
   *
198
   * \copydetails WMenu::setInternalPathEnabled
199
   */
200
  void setInternalPathEnabled(const std::string& basePath = "");
201
202
  /*! \brief Returns whether internal paths are enabled.
203
   *
204
   * \copydetails WMenu::internalPathEnabled
205
   */
206
  bool internalPathEnabled() const;
207
208
  /*! \brief Sets the internal base path.
209
   *
210
   * \copydetails WMenu::setInternalBasePath
211
   */
212
  void setInternalBasePath(const std::string& path);
213
214
  /*! \brief Returns the internal base path.
215
   *
216
   * \copydetails WMenu::internalBasePath
217
   */
218
  const std::string& internalBasePath() const;
219
220
  /*! \brief %Signal emitted when the user activates a tab.
221
   *
222
   * The index of the newly activated tab is passed as an argument.
223
   */
224
0
  Signal<int>& currentChanged() { return currentChanged_; }
225
226
  /*! \brief Closes a tab at \p index.
227
   *
228
   * A tab that has been closed is marked as hidden, but not removed
229
   * from the menu.
230
   *
231
   * \sa removeTab(), setTabHidden()
232
   */
233
  void closeTab(int index);
234
235
  /*! \brief %Signal emitted when the user closes a tab.
236
   *
237
   * The index of the closed tab is passed as an argument.
238
   *
239
   * \sa closeTab(), setTabCloseable()
240
   */
241
0
  Signal<int>& tabClosed() { return tabClosed_; }
242
243
  /*! \brief Returns the contents stack.
244
   *
245
   * The tab widget is implemented as a WMenu + WStackedWidget which
246
   * displays the contents. This method returns a reference to this
247
   * contents stack.
248
   */
249
  WStackedWidget *contentsStack() const;
250
251
  /*! \brief Sets how overflow of contained children must be handled.
252
   */
253
  void setOverflow(Overflow overflow,
254
                   WFlags<Orientation> orientation
255
                   = (Orientation::Horizontal | Orientation::Vertical));
256
257
258
private:
259
  Signal<int> currentChanged_;
260
  Signal<int> tabClosed_;
261
  WContainerWidget *layout_;
262
  WMenu            *menu_;
263
264
  std::vector<WWidget *> contentsWidgets_;
265
266
  void create();
267
  void onItemSelected(WMenuItem *item);
268
  void onItemClosed(WMenuItem *item);
269
270
  void setJsSize();
271
};
272
273
}
274
275
#endif // WTABWIDGET_H_