00001 /* $Id: dialog.hpp 52533 2012-01-07 02:35:17Z shadowmaster $ */ 00002 /* 00003 Copyright (C) 2008 - 2012 by Mark de Wever <koraq@xs4all.nl> 00004 Part of the Battle for Wesnoth Project http://www.wesnoth.org/ 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY. 00012 00013 See the COPYING file for more details. 00014 */ 00015 00016 #ifndef GUI_DIALOGS_DIALOG_HPP_INCLUDED 00017 #define GUI_DIALOGS_DIALOG_HPP_INCLUDED 00018 00019 #include "gui/dialogs/field-fwd.hpp" 00020 00021 #include <string> 00022 #include <vector> 00023 00024 class CVideo; 00025 00026 namespace gui2 { 00027 00028 /** 00029 * Registers a window. 00030 * 00031 * This function registers a window. The registration is used to validate 00032 * whether the config for the window exists when starting Wesnoth. 00033 * 00034 * @note Most of the time you want to call @ref REGISTER_DIALOG instead of this 00035 * function. It also directly adds the code for the dialog's id function. 00036 * 00037 * @param id Id of the window, multiple dialogs can use 00038 * the same window so the id doesn't need to be 00039 * unique. 00040 */ 00041 #define REGISTER_WINDOW( \ 00042 id) \ 00043 namespace { \ 00044 \ 00045 namespace ns_##id { \ 00046 \ 00047 struct tregister_helper { \ 00048 tregister_helper() \ 00049 { \ 00050 register_window(#id); \ 00051 } \ 00052 }; \ 00053 \ 00054 tregister_helper register_helper; \ 00055 } \ 00056 } 00057 00058 /** 00059 * Registers a window for a dialog. 00060 * 00061 * Call this function to register a window. In the header of the class it adds 00062 * the following code: 00063 *@code 00064 * // Inherited from tdialog, implemented by REGISTER_DIALOG. 00065 * virtual const std::string& id() const; 00066 *@endcode 00067 * Then use this macro in the implementation, inside the gui2 namespace. 00068 * 00069 * @note When the @p id is "foo" and the type tfoo it's easier to use 00070 * REGISTER_DIALOG(foo). 00071 * 00072 * @param type Class type of the window to register. 00073 * @param id Id of the window, multiple dialogs can use 00074 * the same window so the id doesn't need to be 00075 * unique. 00076 */ 00077 #define REGISTER_DIALOG2( \ 00078 type \ 00079 , id) \ 00080 \ 00081 REGISTER_WINDOW(id) \ 00082 \ 00083 const std::string& \ 00084 type::window_id() const \ 00085 { \ 00086 static const std::string result(#id); \ 00087 return result; \ 00088 } 00089 00090 /** 00091 * Wrapper for REGISTER_DIALOG2. 00092 * 00093 * "Calls" REGISTER_DIALOG2(twindow_id, window_id) 00094 */ 00095 #define REGISTER_DIALOG(window_id) REGISTER_DIALOG2(t##window_id, window_id) 00096 00097 /** 00098 * Abstract base class for all dialogs. 00099 * 00100 * A dialog shows a certain window instance to the user. The subclasses of this 00101 * class will hold the parameters used for a certain window, eg a server 00102 * connection dialog will hold the name of the selected server as parameter that 00103 * way the caller doesn't need to know about the 'contents' of the window. 00104 * 00105 * @par Usage 00106 * 00107 * Simple dialogs that are shown to query user information it is recommended to 00108 * add a static member called @p execute. The parameters to the function are: 00109 * - references to in + out parameters by reference 00110 * - references to the in parameters 00111 * - the parameters for @ref tdialog::show. 00112 * 00113 * The 'in + out parameters' are used as initial value and final value when the 00114 * OK button is pressed. The 'in parameters' are just extra parameters for 00115 * showing. 00116 * 00117 * When a function only has 'in parameters' it should return a void value and 00118 * the function should be called @p display, if it has 'in + out parameters' it 00119 * must return a bool value. This value indicates whether or not the OK button 00120 * was pressed to close the dialog. See @ref teditor_new_map::execute for an 00121 * example. 00122 */ 00123 class tdialog 00124 { 00125 /** 00126 * Special helper function to get the id of the window. 00127 * 00128 * This is used in the unit tests, but these implementation details 00129 * shouldn't be used in the normal code. 00130 */ 00131 friend std::string unit_test_mark_as_tested(const tdialog& dialog); 00132 00133 public: 00134 tdialog() : 00135 retval_(0), 00136 always_save_fields_(false), 00137 fields_(), 00138 focus_(), 00139 restore_(true) 00140 {} 00141 00142 virtual ~tdialog(); 00143 00144 /** 00145 * Shows the window. 00146 * 00147 * @param video The video which contains the surface to draw 00148 * upon. 00149 * @param auto_close_time The time in ms after which the dialog will 00150 * automatically close, if 0 it doesn't close. 00151 * @note the timeout is a minimum time and 00152 * there's no quarantee about how fast it closes 00153 * after the minimum. 00154 * 00155 * @returns Whether the final retval_ == twindow::OK 00156 */ 00157 bool show(CVideo& video, const unsigned auto_close_time = 0); 00158 00159 00160 /***** ***** ***** setters / getters for members ***** ****** *****/ 00161 00162 int get_retval() const { return retval_; } 00163 00164 void set_always_save_fields(const bool always_save_fields) 00165 { 00166 always_save_fields_ = always_save_fields; 00167 } 00168 00169 void set_restore(const bool restore) { restore_ = restore; } 00170 00171 protected: 00172 00173 /** 00174 * Creates a new boolean field. 00175 * 00176 * The field created is owned by tdialog, the returned pointer can be used 00177 * in the child classes as access to a field. 00178 * 00179 * @param id Id of the widget, same value as in WML. 00180 * @param mandatory Is the widget mandatory or mandatory. 00181 * @param callback_load_value The callback function to set the initial value 00182 * of the widget. 00183 * @param callback_save_value The callback function to write the resulting 00184 * value of the widget. Saving will only happen 00185 * if the widget is enabled and the window closed 00186 * with ok. 00187 * @param callback_change When the value of the widget changes this 00188 * callback is called. 00189 * 00190 * @returns Pointer to the created widget. 00191 */ 00192 tfield_bool* register_bool(const std::string& id 00193 , const bool mandatory 00194 , bool (*callback_load_value) () = NULL 00195 , void (*callback_save_value) (const bool value) = NULL 00196 , void (*callback_change) (twidget* widget) = NULL); 00197 00198 /** 00199 * Creates a new boolean field. 00200 * 00201 * The field created is owned by tdialog, the returned pointer can be used 00202 * in the child classes as access to a field. 00203 * 00204 * @param id Id of the widget, same value as in WML. 00205 * @param mandatory Is the widget mandatory or mandatory. 00206 * @param linked_variable The variable the widget is linked to. See 00207 * @ref tfield::tfield for more information. 00208 * @param callback_change When the value of the widget changes this 00209 * callback is called. 00210 * 00211 * @returns Pointer to the created widget. 00212 */ 00213 tfield_bool* register_bool(const std::string& id 00214 , const bool mandatory 00215 , bool& linked_variable 00216 , void (*callback_change) (twidget* widget) = NULL); 00217 00218 /** 00219 * Creates a new integer field. 00220 * 00221 * See @ref register_bool for more info. 00222 */ 00223 tfield_integer* register_integer(const std::string& id 00224 , const bool mandatory 00225 , int (*callback_load_value) () = NULL 00226 , void (*callback_save_value) (const int value) = NULL); 00227 00228 /** 00229 * Creates a new integer field. 00230 * 00231 * See @ref register_bool for more info. 00232 */ 00233 tfield_integer* register_integer(const std::string& id 00234 , const bool mandatory 00235 , int& linked_variable); 00236 /** 00237 * Creates a new text field. 00238 * 00239 * See @ref register_bool for more info. 00240 */ 00241 tfield_text* register_text(const std::string& id 00242 , const bool mandatory 00243 , std::string (*callback_load_value) () = NULL 00244 , void (*callback_save_value) (const std::string& value) = NULL 00245 , const bool capture_focus = false); 00246 00247 /** 00248 * Creates a new text field. 00249 * 00250 * See @ref register_bool for more info. 00251 */ 00252 tfield_text* register_text(const std::string& id 00253 , const bool mandatory 00254 , std::string& linked_variable 00255 , const bool capture_focus = false); 00256 00257 /** 00258 * Registers a new control as a label. 00259 * 00260 * The label is used for a control to set the 'label' since it calls the 00261 * @ref tcontrol::set_label it can also be used for the @ref timage since 00262 * there this sets the filename. (The @p use_markup makes no sense in an 00263 * image but that's a detail.) 00264 * 00265 * @note In general it's prefered a widget sets its markup flag in WML, but 00266 * some generice windows (like messages) may need different versions 00267 * depending on where used. 00268 * 00269 * @param id Id of the widget, same value as in WML. 00270 * @param mandatory Is the widget mandatory or optional. 00271 * @param text The text for the label. 00272 * @param use_markup Whether or not use markup for the label. 00273 */ 00274 tfield_label* register_label(const std::string& id 00275 , const bool mandatory 00276 , const std::string& text 00277 , const bool use_markup = false); 00278 00279 /** Registers a new control as image. */ 00280 tfield_label* register_image(const std::string& id 00281 , const bool mandatory 00282 , const std::string& filename) 00283 { 00284 return register_label(id, mandatory, filename); 00285 } 00286 00287 private: 00288 /** Returns the window exit status, 0 means not shown. */ 00289 int retval_; 00290 00291 /** 00292 * Always save the fields upon closing. 00293 * 00294 * Normally fields are only saved when the twindow::OK button is pressed. 00295 * With this flag set is always saves. Be careful with the flag since it 00296 * also updates upon canceling, which can be a problem when the field sets 00297 * a preference. 00298 */ 00299 bool always_save_fields_; 00300 00301 /** 00302 * Contains the automatically managed fields. 00303 * 00304 * Since the fields are automatically managed and there are no search 00305 * functions defined we don't offer access to the vector. If access is 00306 * needed the creator should store a copy of the pointer. 00307 */ 00308 std::vector<tfield_*> fields_; 00309 00310 /** 00311 * Contains the widget that should get the focus when the window is shown. 00312 */ 00313 std::string focus_; 00314 00315 /** 00316 * Restore the screen after showing? 00317 * 00318 * Most windows should restore the display after showing so this value 00319 * defaults to true. Toplevel windows (like the titlescreen don't want this 00320 * behaviour so they can change it in pre_show(). 00321 */ 00322 bool restore_; 00323 00324 /** The id of the window to build. */ 00325 virtual const std::string& window_id() const = 0; 00326 00327 /** 00328 * Builds the window. 00329 * 00330 * Every dialog shows it's own kind of window, this function should return 00331 * the window to show. 00332 * 00333 * @param video The video which contains the surface to draw 00334 * upon. 00335 * @returns The window to show. 00336 */ 00337 twindow* build_window(CVideo& video) const; 00338 00339 /** 00340 * Actions to be taken directly after the window is build. 00341 * 00342 * At this point the registered fields are not yet registered. 00343 * 00344 * @param video The video which contains the surface to draw 00345 * upon. 00346 * @param window The window just created. 00347 */ 00348 virtual void post_build(CVideo& /*video*/, twindow& /*window*/) {} 00349 00350 /** 00351 * Actions to be taken before showing the window. 00352 * 00353 * At this point the registered fields are registered and initialized with 00354 * their initial values. 00355 * 00356 * @param video The video which contains the surface to draw 00357 * upon. 00358 * @param window The window to be shown. 00359 */ 00360 virtual void pre_show(CVideo& /*video*/, twindow& /*window*/) {} 00361 00362 /** 00363 * Actions to be taken after the window has been shown. 00364 * 00365 * At this point the registered fields already stored their values (if the 00366 * OK has been pressed). 00367 * 00368 * @param window The window which has been shown. 00369 */ 00370 virtual void post_show(twindow& /*window*/) {} 00371 00372 /** 00373 * Initializes all fields in the dialog and set the keyboard focus. 00374 * 00375 * @param window The window which has been shown. 00376 */ 00377 virtual void init_fields(twindow& window); 00378 00379 /** 00380 * When the dialog is closed with the OK status saves all fields. 00381 * 00382 * Saving only happens if a callback handler is installed. 00383 * 00384 * @param window The window which has been shown. 00385 * @param save_fields Does the value in the fields need to be saved? 00386 */ 00387 virtual void finalize_fields(twindow& window, const bool save_fields); 00388 }; 00389 00390 } // namespace gui2 00391 00392 #endif 00393
| Generated by doxygen 1.7.1 on Thu May 24 2012 01:02:42 for The Battle for Wesnoth | Gna! | Forum | Wiki | CIA | devdocs |