/src/wt/src/Wt/WPushButton.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 WPUSHBUTTON_H_ |
8 | | #define WPUSHBUTTON_H_ |
9 | | |
10 | | #include <Wt/WAnchor.h> |
11 | | #include <Wt/WFormWidget.h> |
12 | | #include <Wt/WJavaScript.h> |
13 | | #include <Wt/WLink.h> |
14 | | #include <Wt/WText.h> |
15 | | |
16 | | namespace Wt { |
17 | | |
18 | | /*! \class WPushButton Wt/WPushButton.h Wt/WPushButton.h |
19 | | * \brief A widget that represents a push button. |
20 | | * |
21 | | * To act on a button click, connect a slot to the clicked() signal. |
22 | | * |
23 | | * \if cpp |
24 | | * Usage example: |
25 | | * \code |
26 | | * // container is a WContainerWidget* |
27 | | * Wt::WPushButton *ok = |
28 | | * container->addWidget(std::make_unique<Wt::WPushButton>("Okay")); |
29 | | * ok->clicked().connect(ok, &Wt::WPushButton::disable); |
30 | | * ok->clicked().connect(this, &MyClass::processData); |
31 | | * \endcode |
32 | | * \endif |
33 | | * |
34 | | * %WPushButton is an \link WWidget::setInline(bool) inline \endlink widget. |
35 | | * |
36 | | * <h3>CSS</h3> |
37 | | * |
38 | | * The widget corresponds to the HTML <tt><button></tt> tag (with some |
39 | | * exceptions in the bootstrap theme). |
40 | | */ |
41 | | class WT_API WPushButton : public WFormWidget |
42 | | { |
43 | | public: |
44 | | /*! \brief Creates a push button. |
45 | | */ |
46 | | WPushButton(); |
47 | | |
48 | | /*! \brief Creates a push button with given label text. |
49 | | * |
50 | | * The default text format is TextFormat::Plain. |
51 | | */ |
52 | | WPushButton(const WString& text); |
53 | | |
54 | | /*! \brief Creates a push button with given label text. |
55 | | */ |
56 | | WPushButton(const WString& text, TextFormat textFormat); |
57 | | |
58 | | virtual ~WPushButton(); |
59 | | |
60 | | /*! \brief Sets the default property. |
61 | | * |
62 | | * This has only a functional meaning for a button in a dialog |
63 | | * footer, as it becomes associated with pressing 'enter' in the |
64 | | * dialog. |
65 | | * |
66 | | * A default button may be rendered in a different style, depending |
67 | | * on the theme. |
68 | | */ |
69 | | void setDefault(bool enabled); |
70 | | |
71 | | /*! \brief Returns whether the button is a default button. |
72 | | * |
73 | | * \sa setDefault() |
74 | | */ |
75 | | bool isDefault() const; |
76 | | |
77 | | /*! \brief Sets whether the button is checkable. |
78 | | * |
79 | | * A checkable button can be checked and unchecked, and clicking |
80 | | * will toggle between these two states. |
81 | | * |
82 | | * \sa setChecked(bool) |
83 | | */ |
84 | | void setCheckable(bool checkable); |
85 | | |
86 | | /*! \brief Returns whether a button is checkable. |
87 | | * |
88 | | * \sa setCheckable() |
89 | | */ |
90 | | bool isCheckable() const; |
91 | | |
92 | | /*! \brief Sets the button state. |
93 | | * |
94 | | * This is ignored for a button which is not checkable. |
95 | | * |
96 | | * This method does not emit one of the checked() or unChecked() |
97 | | * signals. |
98 | | * |
99 | | * \sa setCheckable(), setChecked(), setUnChecked() |
100 | | */ |
101 | | void setChecked(bool checked); |
102 | | |
103 | | /*! \brief Checks the button. |
104 | | * |
105 | | * Does not emit the checked() signal. |
106 | | * |
107 | | * \sa setChecked(bool) |
108 | | */ |
109 | | void setChecked(); |
110 | | |
111 | | /*! \brief Unchecks the button. |
112 | | * |
113 | | * Does not emit the unChecked() signal. |
114 | | * |
115 | | * \sa setChecked(bool) |
116 | | */ |
117 | | void setUnChecked(); |
118 | | |
119 | | /*! \brief Returns the button state. |
120 | | * |
121 | | * \sa setChecked() |
122 | | */ |
123 | | bool isChecked() const; |
124 | | |
125 | | /*! \brief Sets the button text. |
126 | | * |
127 | | * The default text format is Wt::TextFormat::Plain. |
128 | | * |
129 | | * When the current text format is Wt::TextFormat::XHTML, and \p text is |
130 | | * literal (not created using WString::tr()), it is parsed using an |
131 | | * XML parser which discards malicious tags and attributes |
132 | | * silently. When the parser encounters an XML parse error, the |
133 | | * textFormat is changed to Wt::TextFormat::Plain. |
134 | | * If \p text is not a literal, the same parser is applied only |
135 | | * when the text is resolved. |
136 | | * |
137 | | * Returns whether the text could be set using the current |
138 | | * textFormat. A return value of \c false indicates that the text |
139 | | * format was changed in order to be able to accept the new text. |
140 | | * |
141 | | * \sa setTextFormat() |
142 | | */ |
143 | | bool setText(const WString& text); |
144 | | |
145 | | /*! \brief Returns the button text. |
146 | | * |
147 | | * \sa setText() |
148 | | */ |
149 | 0 | const WString& text() const { return text_.text; } |
150 | | |
151 | | /*! \brief Sets the text format. |
152 | | * |
153 | | * The textFormat controls how the string should be interpreted: |
154 | | * either as plain text, which is displayed literally, or as |
155 | | * XHTML-markup. |
156 | | * |
157 | | * When changing the textFormat to Wt::TextFormat::XHTML, and the |
158 | | * current text is literal (not created using WString::tr()), the |
159 | | * current text is parsed using an XML parser which discards |
160 | | * malicious tags and attributes silently. When the parser |
161 | | * encounters an XML parse error, the textFormat is left unchanged, |
162 | | * and this method returns false. |
163 | | * |
164 | | * Returns whether the textFormat could be set for the current text. |
165 | | * |
166 | | * The default format is Wt::TextFormat::Plain. |
167 | | */ |
168 | | bool setTextFormat(TextFormat format); |
169 | | |
170 | | /*! \brief Returns the text format. |
171 | | * |
172 | | * \sa setTextFormat() |
173 | | */ |
174 | 0 | TextFormat textFormat() const { return text_.format; } |
175 | | |
176 | | /*! \brief Sets an icon. |
177 | | * |
178 | | * The icon is placed to the left of the text. |
179 | | */ |
180 | | void setIcon(const WLink& link); |
181 | | |
182 | | /*! \brief Returns the icon. |
183 | | * |
184 | | * \sa setIcon() |
185 | | */ |
186 | 0 | WLink icon() const { return icon_; } |
187 | | |
188 | | /*! \brief Sets a destination link. |
189 | | * |
190 | | * This method can be used to make the button behave like a WAnchor |
191 | | * (or conversely, an anchor look like a button) and redirect to |
192 | | * another URL when clicked. |
193 | | * |
194 | | * The \p link may be to a URL, a resource, or an internal path. |
195 | | * |
196 | | * By default, a button does not link to an URL and you should |
197 | | * listen to the clicked() signal to react to a click event. |
198 | | * |
199 | | * \warning In Bootstrap theme, you should set a link before it's rendered |
200 | | * since it commit's the button to be rendered as an anchor. |
201 | | * (see also http://redmine.emweb.be/issues/1802). |
202 | | */ |
203 | | void setLink(const WLink& link); |
204 | | |
205 | | /*! \brief Returns the destination link. |
206 | | * |
207 | | * \sa setLink() |
208 | | */ |
209 | 0 | const WLink& link() const { return linkState_.link; } |
210 | | |
211 | | /*! \brief Returns the current value. |
212 | | * |
213 | | * Returns an empty string, since a button has no value. |
214 | | */ |
215 | | virtual WT_USTRING valueText() const override; |
216 | | |
217 | | /*! \brief Sets the current value. |
218 | | * |
219 | | * Has no effect, since a button has not value. |
220 | | */ |
221 | | virtual void setValueText(const WT_USTRING& value) override; |
222 | | |
223 | | /*! \brief Links a popup menu to the button. |
224 | | * |
225 | | * When the button is clicked, the linked popup menu is shown. |
226 | | */ |
227 | | void setMenu(std::unique_ptr<WPopupMenu> menu); |
228 | | |
229 | | /*! \brief Returns an associated popup menu. |
230 | | * |
231 | | * \sa setMenu() |
232 | | */ |
233 | 0 | WPopupMenu *menu() const { return popupMenu_.get(); } |
234 | | |
235 | | virtual void refresh() override; |
236 | | |
237 | | /*! \brief %Signal emitted when the button gets checked. |
238 | | * |
239 | | * This signal is emitted when the user checks the button. |
240 | | * |
241 | | * You can use the clicked() signal to react to any change of the |
242 | | * button state. |
243 | | * |
244 | | * \sa setCheckable() |
245 | | */ |
246 | | EventSignal<>& checked(); |
247 | | |
248 | | /*! \brief %Signal emitted when the button gets unchecked. |
249 | | * |
250 | | * This signal is emitted when the user unchecks the button. |
251 | | * |
252 | | * You can use the clicked() signal to react to any change of the |
253 | | * button state. |
254 | | * |
255 | | * \sa setCheckable() |
256 | | */ |
257 | | EventSignal<>& unChecked(); |
258 | | |
259 | | virtual bool setFirstFocus() override; |
260 | | |
261 | | private: |
262 | | static const char *CHECKED_SIGNAL; |
263 | | static const char *UNCHECKED_SIGNAL; |
264 | | |
265 | | static const int BIT_TEXT_CHANGED = 0; |
266 | | static const int BIT_ICON_CHANGED = 1; |
267 | | static const int BIT_ICON_RENDERED = 2; |
268 | | static const int BIT_LINK_CHANGED = 3; |
269 | | static const int BIT_DEFAULT = 4; |
270 | | static const int BIT_IS_CHECKABLE = 5; |
271 | | static const int BIT_IS_CHECKED = 6; |
272 | | static const int BIT_CHECKED_CHANGED = 7; |
273 | | |
274 | | WAnchor::LinkState linkState_; |
275 | | WText::RichText text_; |
276 | | |
277 | | WLink icon_; |
278 | | std::bitset<8> flags_; |
279 | | std::unique_ptr<WPopupMenu> popupMenu_; |
280 | | |
281 | | protected: |
282 | | virtual void updateDom(DomElement& element, bool all) override; |
283 | | virtual DomElementType domElementType() const override; |
284 | | virtual void propagateRenderOk(bool deep) override; |
285 | | virtual void getDomChanges(std::vector<DomElement *>& result, |
286 | | WApplication *app) override; |
287 | | virtual void propagateSetEnabled(bool enabled) override; |
288 | | |
289 | | virtual void enableAjax() override; |
290 | | |
291 | | private: |
292 | | void doRedirect(); |
293 | | void resourceChanged(); |
294 | | void renderHRef(DomElement& href); |
295 | | void toggled(); |
296 | | }; |
297 | | |
298 | | } |
299 | | |
300 | | #endif // WPUSHBUTTON_H_ |