00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef GUI_DIALOGS_FIELD_HPP_INCLUDED
00025 #define GUI_DIALOGS_FIELD_HPP_INCLUDED
00026
00027 #include "gui/dialogs/field-fwd.hpp"
00028 #include "gui/widgets/control.hpp"
00029 #include "gui/widgets/selectable.hpp"
00030 #include "gui/widgets/text_box.hpp"
00031 #include "gui/widgets/window.hpp"
00032 #include "wml_exception.hpp"
00033
00034 #include <boost/static_assert.hpp>
00035
00036 namespace gui2 {
00037
00038
00039
00040
00041
00042
00043
00044
00045 class tfield_
00046 {
00047 public:
00048
00049
00050
00051
00052
00053
00054
00055
00056 tfield_(const std::string& id, const bool mandatory)
00057 : id_(id)
00058 , mandatory_(mandatory)
00059 , widget_(NULL)
00060 {
00061 }
00062
00063 virtual ~tfield_() {}
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 void attach_to_window(twindow& window)
00082 {
00083 assert(!widget_);
00084 widget_ = find_widget<tcontrol>(&window, id(), false, mandatory_);
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 void widget_init(twindow& window)
00106 {
00107 init_generic(window);
00108 init_specialized(window);
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 void widget_finalize(twindow& window)
00125 {
00126 finalize_generic(window);
00127 finalize_specialized(window);
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137 void detach_from_window()
00138 {
00139 assert(!mandatory_ || widget_);
00140 widget_ = NULL;
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 virtual void widget_save(twindow& window) = 0;
00154
00155
00156
00157
00158
00159
00160
00161
00162 virtual void widget_restore(twindow& window) = 0;
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 void widget_set_enabled(twindow& window, const bool enable, const bool sync)
00176 {
00177 tcontrol* widget =
00178 dynamic_cast<tcontrol*>(window.find(id(), false));
00179
00180 if(!widget) {
00181 return;
00182 }
00183
00184 const bool widget_state = widget->get_active();
00185 if(widget_state == enable) {
00186 return;
00187 }
00188
00189 if(sync) {
00190 if(enable) {
00191 widget_restore(window);
00192 } else {
00193 widget_save(window);
00194 }
00195 }
00196
00197 widget->set_active(enable);
00198 }
00199
00200
00201
00202 const std::string& id() const { return id_; }
00203
00204 bool is_mandatory() const { return mandatory_; }
00205
00206 tcontrol* widget()
00207 {
00208 return widget_;
00209 }
00210
00211 const tcontrol* widget() const
00212 {
00213 return widget_;
00214 }
00215
00216 private:
00217
00218 const std::string id_;
00219
00220
00221 const bool mandatory_;
00222
00223
00224 tcontrol* widget_;
00225
00226
00227 virtual void init_generic(twindow& window) = 0;
00228
00229
00230 virtual void init_specialized(twindow& ) {}
00231
00232
00233
00234 virtual void finalize_generic(twindow& window) = 0;
00235
00236
00237 virtual void finalize_specialized(twindow& ) {}
00238 };
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 template<class T, class W, class CT> class tfield : public tfield_
00255 {
00256 public:
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 tfield(const std::string& id,
00275 const bool mandatory,
00276 T (*callback_load_value) (),
00277 void (*callback_save_value) (CT value)) :
00278 tfield_(id, mandatory),
00279 value_(T()),
00280 link_(value_),
00281 callback_load_value_(callback_load_value),
00282 callback_save_value_(callback_save_value)
00283 {
00284 BOOST_STATIC_ASSERT((!boost::is_same<tcontrol, W>::value));
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 tfield(const std::string& id
00302 , const bool mandatory
00303 , T& linked_variable)
00304 : tfield_(id, mandatory)
00305 , value_(T())
00306 , link_(linked_variable)
00307 , callback_load_value_(NULL)
00308 , callback_save_value_(NULL)
00309 {
00310 BOOST_STATIC_ASSERT((!boost::is_same<tcontrol, W>::value));
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 tfield(const std::string& id
00331 , const bool mandatory
00332 , const T& value)
00333 : tfield_(id, mandatory)
00334 , value_(value)
00335 , link_(value_)
00336 , callback_load_value_(NULL)
00337 , callback_save_value_(NULL)
00338 {
00339 BOOST_STATIC_ASSERT((boost::is_same<tcontrol, W>::value));
00340 }
00341
00342
00343 void widget_restore(twindow& window)
00344 {
00345 validate_widget(window);
00346
00347 restore(window);
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 void set_widget_value(twindow& window, CT value)
00360 {
00361 value_ = value;
00362 restore(window);
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 void set_cache_value(CT value)
00374 {
00375 value_ = value;
00376 }
00377
00378
00379 void widget_save(twindow& window)
00380 {
00381 save(window, false);
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 T get_widget_value(twindow& window)
00397 {
00398 save(window, false);
00399 return value_;
00400 }
00401
00402 private:
00403
00404
00405
00406
00407
00408 T value_;
00409
00410
00411
00412
00413
00414
00415
00416 T& link_;
00417
00418
00419
00420
00421
00422
00423 T (*callback_load_value_) ();
00424
00425
00426 void init_generic(twindow& window)
00427 {
00428 validate_widget(window);
00429
00430 if(callback_load_value_) {
00431 value_ = callback_load_value_();
00432 } else {
00433 value_ = link_;
00434 }
00435
00436 restore(window);
00437 }
00438
00439
00440 void finalize_generic(twindow& window)
00441 {
00442 save(window, true);
00443
00444 if(callback_save_value_) {
00445 callback_save_value_(value_);
00446 } else {
00447 link_ = value_;
00448 }
00449 }
00450
00451
00452
00453
00454
00455
00456
00457 void (*callback_save_value_) ( CT value);
00458
00459
00460
00461
00462
00463
00464 void validate_widget(twindow& window)
00465 {
00466 if(!is_mandatory()) {
00467 return;
00468 }
00469 find_widget<const W>(&window, id(), false);
00470 }
00471
00472
00473
00474
00475
00476
00477
00478 void save(twindow& window, const bool must_be_active);
00479
00480
00481
00482
00483
00484
00485 void restore(twindow& window);
00486
00487 };
00488
00489 template<class T, class W, class CT>
00490 void tfield<T, W, CT>::save(twindow& window, const bool must_be_active)
00491 {
00492 const W* widget =
00493 find_widget<const W>(&window, id(), must_be_active, false);
00494
00495 if(widget) {
00496 value_ = widget->get_value();
00497 }
00498 }
00499
00500 template<>
00501 inline void tfield<std::string, tcontrol, const std::string&>::save(
00502 twindow& window
00503 , const bool must_be_active)
00504 {
00505 const tcontrol* control =
00506 find_widget<const tcontrol>(&window, id(), must_be_active, false);
00507
00508 if(control) {
00509 value_ = control->label();
00510 }
00511 }
00512
00513 template<class T, class W, class CT>
00514 void tfield<T, W, CT>::restore(twindow& window)
00515 {
00516 W* widget = find_widget<W>(&window, id(), false, false);
00517
00518 if(widget) {
00519 widget->set_value(value_);
00520 }
00521 }
00522
00523 template<>
00524 inline void tfield<std::string, tcontrol, const std::string&>::restore(
00525 twindow& window)
00526 {
00527 tcontrol* control = find_widget<tcontrol>(&window, id(), false, false);
00528
00529 if(control) {
00530 control->set_label(value_);
00531 }
00532 }
00533
00534
00535 class tfield_bool : public tfield<bool, tselectable_>
00536 {
00537 public:
00538 tfield_bool(const std::string& id,
00539 const bool mandatory,
00540 bool (*callback_load_value) (),
00541 void (*callback_save_value) (const bool value),
00542 void (*callback_change) (twidget* widget)) :
00543 tfield<bool, gui2::tselectable_>
00544 (id, mandatory, callback_load_value, callback_save_value),
00545 callback_change_(callback_change)
00546 {
00547 }
00548
00549 tfield_bool(const std::string& id
00550 , const bool mandatory
00551 , bool& linked_variable
00552 , void (*callback_change) (twidget* widget))
00553 : tfield<bool, gui2::tselectable_>(id, mandatory, linked_variable)
00554 , callback_change_(callback_change)
00555 {
00556 }
00557
00558 private:
00559
00560
00561 void init_specialized(twindow& window)
00562 {
00563 if(callback_change_) {
00564 tselectable_* widget =
00565 dynamic_cast<tselectable_*>(window.find(id(), false));
00566
00567 if(widget) {
00568 widget->set_callback_state_change(callback_change_);
00569 }
00570 }
00571 }
00572
00573 void (*callback_change_) (twidget* widget);
00574 };
00575
00576
00577 class tfield_text : public tfield<std::string, ttext_, const std::string& >
00578 {
00579 public:
00580 tfield_text(const std::string& id,
00581 const bool mandatory,
00582 std::string (*callback_load_value) (),
00583 void (*callback_save_value) (const std::string& value)) :
00584 tfield<std::string, ttext_, const std::string& >
00585 (id, mandatory, callback_load_value, callback_save_value)
00586 {
00587 }
00588
00589 tfield_text(const std::string& id
00590 , const bool mandatory
00591 , std::string& linked_variable)
00592 : tfield<std::string, ttext_, const std::string&>(
00593 id
00594 , mandatory
00595 , linked_variable)
00596 {
00597 }
00598
00599 private:
00600
00601 void finalize_specialized(twindow& window)
00602 {
00603 ttext_box* widget = dynamic_cast<ttext_box*>(window.find(id(), false));
00604
00605 if(widget) {
00606 widget->save_to_history();
00607 }
00608 }
00609 };
00610
00611
00612 class tfield_label : public tfield<std::string, tcontrol, const std::string&>
00613 {
00614 public:
00615 tfield_label(const std::string& id
00616 , const bool mandatory
00617 , const std::string& text
00618 , const bool use_markup)
00619 : tfield<std::string, tcontrol, const std::string&>(
00620 id
00621 , mandatory
00622 , text)
00623 , use_markup_(use_markup)
00624
00625 {
00626 }
00627
00628 private:
00629
00630
00631 bool use_markup_;
00632
00633
00634 void init_specialized(twindow& window)
00635 {
00636 find_widget<tcontrol>(&window, id(), false).set_use_markup(use_markup_);
00637 }
00638 };
00639
00640 }
00641
00642 #endif
00643