The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
dialog.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2016 by Mark de Wever <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #ifndef GUI_DIALOGS_DIALOG_HPP_INCLUDED
16 #define GUI_DIALOGS_DIALOG_HPP_INCLUDED
17 
19 
20 #include "utils/functional.hpp"
21 
22 #include <string>
23 #include <vector>
24 
25 class CVideo;
26 
27 namespace gui2
28 {
29 
30 /**
31  * Registers a window.
32  *
33  * This function registers a window. The registration is used to validate
34  * whether the config for the window exists when starting Wesnoth.
35  *
36  * @note Most of the time you want to call @ref REGISTER_DIALOG instead of this
37  * function. It also directly adds the code for the dialog's id function.
38  *
39  * @param id Id of the window, multiple dialogs can use
40  * the same window so the id doesn't need to be
41  * unique.
42  */
43 #define REGISTER_WINDOW(id) \
44  namespace \
45  { \
46  \
47  namespace ns_##id \
48  { \
49  \
50  struct tregister_helper \
51  { \
52  tregister_helper() \
53  { \
54  register_window(#id); \
55  } \
56  }; \
57  \
58  tregister_helper register_helper; \
59  } \
60  }
61 
62 /**
63  * Registers a window for a dialog.
64  *
65  * Call this function to register a window. In the header of the class it adds
66  * the following code:
67  *@code
68  * // Inherited from tdialog, implemented by REGISTER_DIALOG.
69  * virtual const std::string& id() const;
70  *@endcode
71  * Then use this macro in the implementation, inside the gui2 namespace.
72  *
73  * @note When the @p id is "foo" and the type tfoo it's easier to use
74  * REGISTER_DIALOG(foo).
75  *
76  * @param type Class type of the window to register.
77  * @param id Id of the window, multiple dialogs can use
78  * the same window so the id doesn't need to be
79  * unique.
80  */
81 #define REGISTER_DIALOG2(type, id) \
82  REGISTER_WINDOW(id) const std::string& type::window_id() const \
83  { \
84  static const std::string result(#id); \
85  return result; \
86  }
87 
88 /**
89  * Wrapper for REGISTER_DIALOG2.
90  *
91  * "Calls" REGISTER_DIALOG2(twindow_id, window_id)
92  */
93 #define REGISTER_DIALOG(window_id) REGISTER_DIALOG2(t##window_id, window_id)
94 
95 /**
96  * Abstract base class for all dialogs.
97  *
98  * A dialog shows a certain window instance to the user. The subclasses of this
99  * class will hold the parameters used for a certain window, eg a server
100  * connection dialog will hold the name of the selected server as parameter that
101  * way the caller doesn't need to know about the 'contents' of the window.
102  *
103  * @par Usage
104  *
105  * Simple dialogs that are shown to query user information it is recommended to
106  * add a static member called @p execute. The parameters to the function are:
107  * - references to in + out parameters by reference
108  * - references to the in parameters
109  * - the parameters for @ref tdialog::show.
110  *
111  * The 'in + out parameters' are used as initial value and final value when the
112  * OK button is pressed. The 'in parameters' are just extra parameters for
113  * showing.
114  *
115  * When a function only has 'in parameters' it should return a void value and
116  * the function should be called @p display, if it has 'in + out parameters' it
117  * must return a bool value. This value indicates whether or not the OK button
118  * was pressed to close the dialog. See @ref teditor_new_map::execute for an
119  * example.
120  */
121 class tdialog
122 {
123  /**
124  * Special helper function to get the id of the window.
125  *
126  * This is used in the unit tests, but these implementation details
127  * shouldn't be used in the normal code.
128  */
129  friend std::string unit_test_mark_as_tested(const tdialog& dialog);
130 
131 public:
133  : retval_(0)
134  , always_save_fields_(false)
135  , fields_()
136  , focus_()
137  , restore_(false)
138  {
139  }
140 
141  virtual ~tdialog();
142 
143  /**
144  * Shows the window.
145  *
146  * @param video The video which contains the surface to draw
147  * upon.
148  * @param auto_close_time The time in ms after which the dialog will
149  * automatically close, if 0 it doesn't close.
150  * @note the timeout is a minimum time and
151  * there's no guarantee about how fast it closes
152  * after the minimum.
153  *
154  * @returns Whether the final retval_ == twindow::OK
155  */
156  bool show(CVideo& video, const unsigned auto_close_time = 0);
157 
158 
159  /***** ***** ***** setters / getters for members ***** ****** *****/
160 
161  int get_retval() const
162  {
163  return retval_;
164  }
165 
166  void set_always_save_fields(const bool always_save_fields)
167  {
168  always_save_fields_ = always_save_fields;
169  }
170 
171  void set_restore(const bool restore)
172  {
173  restore_ = restore;
174  }
175 
176 protected:
177  /**
178  * Creates a new boolean field.
179  *
180  * The field created is owned by tdialog, the returned pointer can be used
181  * in the child classes as access to a field.
182  *
183  * @param id Id of the widget, same value as in WML.
184  * @param mandatory Is the widget mandatory or mandatory.
185  * @param callback_load_value The callback function to set the initial value
186  * of the widget.
187  * @param callback_save_value The callback function to write the resulting
188  * value of the widget. Saving will only happen
189  * if the widget is enabled and the window closed
190  * with ok.
191  * @param callback_change When the value of the widget changes this
192  * callback is called.
193  *
194  * @returns Pointer to the created widget.
195  */
196  tfield_bool*
197  register_bool(const std::string& id,
198  const bool mandatory,
199  const std::function<bool()>& callback_load_value
200  = std::function<bool()>(),
201  const std::function<void(const bool)>& callback_save_value
202  = std::function<void(const bool)>(),
203  const std::function<void(twidget&)>& callback_change
204  = std::function<void(twidget&)>());
205 
206  /**
207  * Creates a new boolean field.
208  *
209  * The field created is owned by tdialog, the returned pointer can be used
210  * in the child classes as access to a field.
211  *
212  * @param id Id of the widget, same value as in WML.
213  * @param mandatory Is the widget mandatory or mandatory.
214  * @param linked_variable The variable the widget is linked to. See
215  * @ref tfield::tfield for more information.
216  * @param callback_change When the value of the widget changes this
217  * callback is called.
218  *
219  * @returns Pointer to the created widget.
220  */
221  tfield_bool*
222  register_bool(const std::string& id,
223  const bool mandatory,
224  bool& linked_variable,
225  const std::function<void(twidget&)>& callback_change
226  = std::function<void(twidget&)>());
227 
228  /**
229  * Creates a new integer field.
230  *
231  * See @ref register_bool for more info.
232  */
234  register_integer(const std::string& id,
235  const bool mandatory,
236  const std::function<int()>& callback_load_value
237  = std::function<int()>(),
238  const std::function<void(const int)>& callback_save_value
239  = std::function<void(const int)>());
240 
241  /**
242  * Creates a new integer field.
243  *
244  * See @ref register_bool for more info.
245  */
247  const bool mandatory,
248  int& linked_variable);
249  /**
250  * Creates a new text field.
251  *
252  * See @ref register_bool for more info.
253  */
255  const std::string& id,
256  const bool mandatory,
257  const std::function<std::string()>& callback_load_value
258  = std::function<std::string()>(),
259  const std::function<void(const std::string&)>& callback_save_value
260  = std::function<void(const std::string&)>(),
261  const bool capture_focus = false);
262 
263  /**
264  * Creates a new text field.
265  *
266  * See @ref register_bool for more info.
267  */
269  const bool mandatory,
270  std::string& linked_variable,
271  const bool capture_focus = false);
272 
273  /**
274  * Registers a new control as a label.
275  *
276  * The label is used for a control to set the 'label' since it calls the
277  * @ref tcontrol::set_label it can also be used for the @ref timage since
278  * there this sets the filename. (The @p use_markup makes no sense in an
279  * image but that's a detail.)
280  *
281  * @note In general it's preferred a widget sets its markup flag in WML, but
282  * some generic windows (like messages) may need different versions
283  * depending on where used.
284  *
285  * @param id Id of the widget, same value as in WML.
286  * @param mandatory Is the widget mandatory or optional.
287  * @param text The text for the label.
288  * @param use_markup Whether or not use markup for the label.
289  */
291  const bool mandatory,
292  const std::string& text,
293  const bool use_markup = false);
294 
295  /** Registers a new control as image. */
297  const bool mandatory,
298  const std::string& filename)
299  {
300  return register_label(id, mandatory, filename);
301  }
302 
303 private:
304  /** Returns the window exit status, 0 means not shown. */
305  int retval_;
306 
307  /**
308  * Always save the fields upon closing.
309  *
310  * Normally fields are only saved when the twindow::OK button is pressed.
311  * With this flag set is always saves. Be careful with the flag since it
312  * also updates upon canceling, which can be a problem when the field sets
313  * a preference.
314  */
316 
317  /**
318  * Contains the automatically managed fields.
319  *
320  * Since the fields are automatically managed and there are no search
321  * functions defined we don't offer access to the vector. If access is
322  * needed the creator should store a copy of the pointer.
323  */
324  std::vector<tfield_*> fields_;
325 
326  /**
327  * Contains the widget that should get the focus when the window is shown.
328  */
330 
331  /**
332  * Restore the screen after showing?
333  *
334  * Most windows should restore the display after showing so this value
335  * defaults to true. Toplevel windows (like the titlescreen don't want this
336  * behavior so they can change it in pre_show().
337  */
338  bool restore_;
339 
340  /** The id of the window to build. */
341  virtual const std::string& window_id() const = 0;
342 
343  /**
344  * Builds the window.
345  *
346  * Every dialog shows it's own kind of window, this function should return
347  * the window to show.
348  *
349  * @param video The video which contains the surface to draw
350  * upon.
351  * @returns The window to show.
352  */
353  twindow* build_window(CVideo& video) const;
354 
355  /**
356  * Actions to be taken directly after the window is build.
357  *
358  * At this point the registered fields are not yet registered.
359  *
360  * @param video The video which contains the surface to draw
361  * upon.
362  * @param window The window just created.
363  */
364  virtual void post_build(twindow& window);
365 
366  /**
367  * Actions to be taken before showing the window.
368  *
369  * At this point the registered fields are registered and initialized with
370  * their initial values.
371  *
372  * @param window The window to be shown.
373  */
374  virtual void pre_show(twindow& window);
375 
376  /**
377  * Actions to be taken after the window has been shown.
378  *
379  * At this point the registered fields already stored their values (if the
380  * OK has been pressed).
381  *
382  * @param window The window which has been shown.
383  */
384  virtual void post_show(twindow& window);
385 
386  /**
387  * Initializes all fields in the dialog and set the keyboard focus.
388  *
389  * @param window The window which has been shown.
390  */
391  virtual void init_fields(twindow& window);
392 
393  /**
394  * When the dialog is closed with the OK status saves all fields.
395  *
396  * Saving only happens if a callback handler is installed.
397  *
398  * @param window The window which has been shown.
399  * @param save_fields Does the value in the fields need to be saved?
400  */
401  virtual void finalize_fields(twindow& window, const bool save_fields);
402 };
403 
404 } // namespace gui2
405 
406 #endif
tfield_label * register_image(const std::string &id, const bool mandatory, const std::string &filename)
Registers a new control as image.
Definition: dialog.hpp:296
int get_retval() const
Definition: dialog.hpp:161
virtual void pre_show(twindow &window)
Actions to be taken before showing the window.
Definition: dialog.cpp:181
bool always_save_fields_
Always save the fields upon closing.
Definition: dialog.hpp:315
virtual void post_build(twindow &window)
Actions to be taken directly after the window is build.
Definition: dialog.cpp:176
int retval_
Returns the window exit status, 0 means not shown.
Definition: dialog.hpp:305
bool show(CVideo &video, const unsigned auto_close_time=0)
Shows the window.
Definition: dialog.cpp:34
Template class to implement the generic field implementation.
Definition: field-fwd.hpp:36
Definition: video.hpp:58
void set_always_save_fields(const bool always_save_fields)
Definition: dialog.hpp:166
base class of top level items, the only item which needs to store the final canvases to draw on ...
Definition: window.hpp:62
A class inherited from ttext_box that displays its input as stars.
Definition: field-fwd.hpp:23
friend std::string unit_test_mark_as_tested(const tdialog &dialog)
Special helper function to get the id of the window.
Definition: test_gui2.cpp:107
virtual void post_show(twindow &window)
Actions to be taken after the window has been shown.
Definition: dialog.cpp:186
Abstract base class for all dialogs.
Definition: dialog.hpp:121
tfield_integer * register_integer(const std::string &id, const bool mandatory, const std::function< int()> &callback_load_value=std::function< int()>(), const std::function< void(const int)> &callback_save_value=std::function< void(const int)>())
Creates a new integer field.
Definition: dialog.cpp:104
void set_restore(const bool restore)
Definition: dialog.hpp:171
Contains all forward declarations for field.hpp.
bool restore_
Restore the screen after showing?
Definition: dialog.hpp:338
virtual ~tdialog()
Definition: dialog.cpp:26
virtual void init_fields(twindow &window)
Initializes all fields in the dialog and set the keyboard focus.
Definition: dialog.cpp:191
tfield_label * register_label(const std::string &id, const bool mandatory, const std::string &text, const bool use_markup=false)
Registers a new control as a label.
Definition: dialog.cpp:160
twindow * build_window(CVideo &video) const
Builds the window.
Definition: dialog.cpp:171
Base class for all widgets.
Definition: widget.hpp:49
std::vector< tfield_ * > fields_
Contains the automatically managed fields.
Definition: dialog.hpp:324
tfield_bool * register_bool(const std::string &id, const bool mandatory, const std::function< bool()> &callback_load_value=std::function< bool()>(), const std::function< void(const bool)> &callback_save_value=std::function< void(const bool)>(), const std::function< void(twidget &)> &callback_change=std::function< void(twidget &)>())
Creates a new boolean field.
Definition: dialog.cpp:74
virtual void finalize_fields(twindow &window, const bool save_fields)
When the dialog is closed with the OK status saves all fields.
Definition: dialog.cpp:206
std::string focus_
Contains the widget that should get the focus when the window is shown.
Definition: dialog.hpp:329
virtual const std::string & window_id() const =0
The id of the window to build.
Specialized field class for boolean.
Definition: field.hpp:547
tfield_text * register_text(const std::string &id, const bool mandatory, const std::function< std::string()> &callback_load_value=std::function< std::string()>(), const std::function< void(const std::string &)> &callback_save_value=std::function< void(const std::string &)>(), const bool capture_focus=false)
Creates a new text field.
Definition: dialog.cpp:127
GLsizei const GLcharARB ** string
Definition: glew.h:4503
Specialized field class for a control, used for labels and images.
Definition: field.hpp:622
Specialized field class for text.
Definition: field.hpp:588