00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "gui/widgets/window_builder.hpp"
00016
00017 #include "config.hpp"
00018 #include "gettext.hpp"
00019 #include "gui/widgets/button.hpp"
00020 #include "gui/widgets/label.hpp"
00021 #include "gui/widgets/listbox.hpp"
00022 #include "gui/widgets/spacer.hpp"
00023 #include "gui/widgets/text_box.hpp"
00024 #include "gui/widgets/toggle_button.hpp"
00025 #include "gui/widgets/vertical_scrollbar.hpp"
00026 #include "gui/widgets/widget.hpp"
00027 #include "gui/widgets/window.hpp"
00028 #include "log.hpp"
00029 #include "util.hpp"
00030 #include "wml_exception.hpp"
00031
00032 #include <cassert>
00033
00034 #define DBG_G LOG_STREAM_INDENT(debug, gui)
00035 #define LOG_G LOG_STREAM_INDENT(info, gui)
00036 #define WRN_G LOG_STREAM_INDENT(warn, gui)
00037 #define ERR_G LOG_STREAM_INDENT(err, gui)
00038
00039 #define DBG_G_D LOG_STREAM_INDENT(debug, gui_draw)
00040 #define LOG_G_D LOG_STREAM_INDENT(info, gui_draw)
00041 #define WRN_G_D LOG_STREAM_INDENT(warn, gui_draw)
00042 #define ERR_G_D LOG_STREAM_INDENT(err, gui_draw)
00043
00044 #define DBG_G_E LOG_STREAM_INDENT(debug, gui_event)
00045 #define LOG_G_E LOG_STREAM_INDENT(info, gui_event)
00046 #define WRN_G_E LOG_STREAM_INDENT(warn, gui_event)
00047 #define ERR_G_E LOG_STREAM_INDENT(err, gui_event)
00048
00049 #define DBG_G_P LOG_STREAM_INDENT(debug, gui_parse)
00050 #define LOG_G_P LOG_STREAM_INDENT(info, gui_parse)
00051 #define WRN_G_P LOG_STREAM_INDENT(warn, gui_parse)
00052 #define ERR_G_P LOG_STREAM_INDENT(err, gui_parse)
00053
00054 namespace gui2 {
00055
00056 static unsigned get_v_align(const std::string& v_align);
00057 static unsigned get_h_align(const std::string& h_align);
00058 static unsigned get_border(const std::vector<std::string>& border);
00059 static unsigned read_flags(const config& cfg);
00060
00061 struct tbuilder_control : public tbuilder_widget
00062 {
00063 private:
00064 tbuilder_control();
00065 public:
00066
00067 tbuilder_control(const config& cfg);
00068
00069 void init_control(tcontrol* control) const;
00070
00071
00072 std::string id;
00073 std::string definition;
00074 t_string label;
00075 t_string tooltip;
00076 t_string help;
00077 };
00078
00079 struct tbuilder_button : public tbuilder_control
00080 {
00081
00082 private:
00083 tbuilder_button();
00084 public:
00085 tbuilder_button(const config& cfg);
00086
00087 twidget* build () const;
00088
00089 private:
00090 int retval_;
00091 };
00092
00093 struct tbuilder_label : public tbuilder_control
00094 {
00095
00096 private:
00097 tbuilder_label();
00098 public:
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 tbuilder_label(const config& cfg) :
00109 tbuilder_control(cfg)
00110 {}
00111
00112 twidget* build () const;
00113
00114 };
00115
00116 struct tbuilder_listbox : public tbuilder_control
00117 {
00118
00119 private:
00120 tbuilder_listbox();
00121 public:
00122 tbuilder_listbox(const config& cfg);
00123
00124 twidget* build () const;
00125
00126 tbuilder_grid* header;
00127 tbuilder_grid* list;
00128 tbuilder_grid* footer;
00129
00130 tbuilder_grid* list_builder;
00131
00132 const bool assume_fixed_row_size;
00133 };
00134
00135 struct tbuilder_panel : public tbuilder_control
00136 {
00137
00138 private:
00139 tbuilder_panel();
00140 public:
00141 tbuilder_panel(const config& cfg);
00142
00143 twidget* build () const;
00144
00145 tbuilder_grid* grid;
00146 };
00147
00148 struct tbuilder_spacer : public tbuilder_control
00149 {
00150
00151 private:
00152 tbuilder_spacer();
00153 public:
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 tbuilder_spacer(const config& cfg) :
00164 tbuilder_control(cfg)
00165 {}
00166
00167 twidget* build () const;
00168
00169 };
00170
00171 struct tbuilder_text_box : public tbuilder_control
00172 {
00173 private:
00174 tbuilder_text_box();
00175 std::string history_;
00176
00177 public:
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 tbuilder_text_box(const config& cfg) :
00197 tbuilder_control(cfg),
00198 history_(cfg["history"])
00199 {}
00200
00201 twidget* build () const;
00202 };
00203
00204 struct tbuilder_toggle_button : public tbuilder_control
00205 {
00206 private:
00207 tbuilder_toggle_button();
00208
00209 public:
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 tbuilder_toggle_button(const config& cfg) :
00220 tbuilder_control(cfg)
00221 {}
00222
00223 twidget* build () const;
00224 };
00225
00226 struct tbuilder_vertical_scrollbar : public tbuilder_control
00227 {
00228 private:
00229 tbuilder_vertical_scrollbar();
00230
00231 public:
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 tbuilder_vertical_scrollbar(const config& cfg) :
00242 tbuilder_control(cfg)
00243 {}
00244
00245 twidget* build () const;
00246 };
00247
00248 twindow build(CVideo& video, const std::string& type)
00249 {
00250 std::vector<twindow_builder::tresolution>::const_iterator
00251 definition = get_window_builder(type);
00252
00253
00254
00255 twindow window(video,
00256 definition->x, definition->y, definition->width, definition->height,
00257 definition->automatic_placement,
00258 definition->horizontal_placement, definition->vertical_placement);
00259
00260 log_scope2(gui, "Window builder: building grid for window");
00261
00262 const unsigned rows = definition->grid->rows;
00263 const unsigned cols = definition->grid->cols;
00264
00265 window.set_rows_cols(rows, cols);
00266
00267 for(unsigned x = 0; x < rows; ++x) {
00268 window.set_row_grow_factor(x, definition->grid->row_grow_factor[x]);
00269 for(unsigned y = 0; y < cols; ++y) {
00270
00271 if(x == 0) {
00272 window.set_col_grow_factor(y, definition->grid->col_grow_factor[y]);
00273 }
00274
00275 twidget* widget = definition->grid->widgets[x * cols + y]->build();
00276 window.add_child(widget, x, y, definition->grid->flags[x * cols + y], definition->grid->border_size[x * cols + y]);
00277 }
00278 }
00279
00280 window.recalculate_size();
00281
00282 return window;
00283 }
00284
00285 const std::string& twindow_builder::read(const config& cfg)
00286 {
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 id_ = cfg["id"];
00306 description_ = cfg["description"];
00307
00308 VALIDATE(!id_.empty(), missing_mandatory_wml_key("window", "id"));
00309 VALIDATE(!description_.empty(), missing_mandatory_wml_key("window", "description"));
00310
00311 DBG_G_P << "Window builder: reading data for window " << id_ << ".\n";
00312
00313 const config::child_list& cfgs = cfg.get_children("resolution");
00314 VALIDATE(!cfgs.empty(), _("No resolution defined."));
00315 for(std::vector<config*>::const_iterator itor = cfgs.begin();
00316 itor != cfgs.end(); ++itor) {
00317
00318 resolutions.push_back(tresolution(**itor));
00319 }
00320
00321 return id_;
00322 }
00323
00324 twindow_builder::tresolution::tresolution(const config& cfg) :
00325 window_width(lexical_cast_default<unsigned>(cfg["window_width"])),
00326 window_height(lexical_cast_default<unsigned>(cfg["window_height"])),
00327 automatic_placement(utils::string_bool(cfg["automatic_placement"], true)),
00328 x(lexical_cast_default<unsigned>(cfg["x"])),
00329 y(lexical_cast_default<unsigned>(cfg["y"])),
00330 width(lexical_cast_default<unsigned>(cfg["width"])),
00331 height(lexical_cast_default<unsigned>(cfg["height"])),
00332 vertical_placement(get_v_align(cfg["vertical_placement"])),
00333 horizontal_placement(get_h_align(cfg["horizontal_placement"])),
00334 definition(cfg["definition"]),
00335 grid(0)
00336 {
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 VALIDATE(cfg.child("grid"), _("No grid defined."));
00377
00378 grid = new tbuilder_grid(*(cfg.child("grid")));
00379
00380 if(!automatic_placement) {
00381 VALIDATE(width, missing_mandatory_wml_key("resulution", "width"));
00382 VALIDATE(height, missing_mandatory_wml_key("resulution", "height"));
00383 }
00384
00385 DBG_G_P << "Window builder: parsing resolution "
00386 << window_width << ',' << window_height << '\n';
00387
00388 if(definition.empty()) {
00389 definition = "default";
00390 }
00391
00392 }
00393
00394 static unsigned get_v_align(const std::string& v_align)
00395 {
00396
00397 if(v_align == "top") {
00398 return tgrid::VERTICAL_ALIGN_TOP;
00399 } else if(v_align == "bottom") {
00400 return tgrid::VERTICAL_ALIGN_BOTTOM;
00401 } else {
00402 if(!v_align.empty() && v_align != "center") {
00403 ERR_G_E << "Invalid vertical alignment '"
00404 << v_align << "' falling back to 'center'.\n";
00405 }
00406 return tgrid::VERTICAL_ALIGN_CENTER;
00407 }
00408 }
00409
00410 static unsigned get_h_align(const std::string& h_align)
00411 {
00412 if(h_align == "left") {
00413 return tgrid::HORIZONTAL_ALIGN_LEFT;
00414 } else if(h_align == "right") {
00415 return tgrid::HORIZONTAL_ALIGN_RIGHT;
00416 } else {
00417 if(!h_align.empty() && h_align != "center") {
00418 ERR_G_E << "Invalid horizontal alignment '"
00419 << h_align << "' falling back to 'center'.\n";
00420 }
00421 return tgrid::HORIZONTAL_ALIGN_CENTER;
00422 }
00423 }
00424
00425 static unsigned get_border(const std::vector<std::string>& border)
00426 {
00427 if(std::find(border.begin(), border.end(), "all") != border.end()) {
00428 return tgrid::BORDER_TOP
00429 | tgrid::BORDER_BOTTOM | tgrid::BORDER_LEFT | tgrid::BORDER_RIGHT;
00430 } else {
00431 if(std::find(border.begin(), border.end(), "top") != border.end()) {
00432 return tgrid::BORDER_TOP;
00433 }
00434 if(std::find(border.begin(), border.end(), "bottom") != border.end()) {
00435 return tgrid::BORDER_BOTTOM;
00436 }
00437 if(std::find(border.begin(), border.end(), "left") != border.end()) {
00438 return tgrid::BORDER_LEFT;
00439 }
00440 if(std::find(border.begin(), border.end(), "right") != border.end()) {
00441 return tgrid::BORDER_RIGHT;
00442 }
00443 }
00444
00445 return 0;
00446 }
00447
00448 static unsigned read_flags(const config& cfg)
00449 {
00450 unsigned flags = 0;
00451
00452
00453 flags |= get_v_align(cfg["vertical_alignment"]);
00454 flags |= get_h_align(cfg["horizontal_alignment"]);
00455 flags |= get_border( utils::split(cfg["border"]));
00456
00457 if(utils::string_bool(cfg["vertical_grow"])) {
00458 flags |= tgrid::VERTICAL_GROW_SEND_TO_CLIENT;
00459 }
00460
00461 if(utils::string_bool(cfg["horizontal_grow"])) {
00462 flags |= tgrid::HORIZONTAL_GROW_SEND_TO_CLIENT;
00463 }
00464
00465 return flags;
00466 }
00467
00468 tbuilder_grid::tbuilder_grid(const config& cfg) :
00469 tbuilder_widget(cfg),
00470 rows(0),
00471 cols(0),
00472 row_grow_factor(),
00473 col_grow_factor(),
00474 flags(),
00475 border_size(),
00476 widgets()
00477 {
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 log_scope2(gui_parse, "Window builder: parsing a grid");
00542
00543 const config::child_list& row_cfgs = cfg.get_children("row");
00544 for(std::vector<config*>::const_iterator row_itor = row_cfgs.begin();
00545 row_itor != row_cfgs.end(); ++row_itor) {
00546
00547 unsigned col = 0;
00548
00549 row_grow_factor.push_back(lexical_cast_default<unsigned>((**row_itor)["grow_factor"]));
00550
00551 const config::child_list& col_cfgs = (**row_itor).get_children("column");
00552 for(std::vector<config*>::const_iterator col_itor = col_cfgs.begin();
00553 col_itor != col_cfgs.end(); ++col_itor) {
00554
00555 flags.push_back(read_flags(**col_itor));
00556 border_size.push_back(lexical_cast_default<unsigned>((**col_itor)["border_size"]));
00557 if(rows == 0) {
00558 col_grow_factor.push_back(lexical_cast_default<unsigned>((**col_itor)["grow_factor"]));
00559 }
00560
00561 if((**col_itor).child("button")) {
00562 widgets.push_back(new tbuilder_button(*((**col_itor).child("button"))));
00563 } else if((**col_itor).child("label")) {
00564 widgets.push_back(new tbuilder_label(*((**col_itor).child("label"))));
00565 } else if((**col_itor).child("listbox")) {
00566 widgets.push_back(new tbuilder_listbox(*((**col_itor).child("listbox"))));
00567 } else if((**col_itor).child("panel")) {
00568 widgets.push_back(new tbuilder_panel(*((**col_itor).child("panel"))));
00569 } else if((**col_itor).child("spacer")) {
00570 widgets.push_back(new tbuilder_spacer(*((**col_itor).child("spacer"))));
00571 } else if((**col_itor).child("text_box")) {
00572 widgets.push_back(new tbuilder_text_box(*((**col_itor).child("text_box"))));
00573 } else if((**col_itor).child("toggle_button")) {
00574 widgets.push_back(new tbuilder_toggle_button(*((**col_itor).child("toggle_button"))));
00575 } else if((**col_itor).child("vertical_scrollbar")) {
00576 widgets.push_back(
00577 new tbuilder_vertical_scrollbar(*((**col_itor).child("vertical_scrollbar"))));
00578 } else if((**col_itor).child("grid")) {
00579 widgets.push_back(new tbuilder_grid(*((**col_itor).child("grid"))));
00580 } else {
00581 assert(false);
00582 }
00583
00584 ++col;
00585 }
00586
00587 ++rows;
00588 if(row_itor == row_cfgs.begin()) {
00589 cols = col;
00590 } else {
00591 VALIDATE(col, _("A row must have a column."));
00592 VALIDATE(col == cols, _("Number of columns differ."));
00593 }
00594
00595 }
00596
00597 DBG_G_P << "Window builder: grid has "
00598 << rows << " rows and " << cols << " columns.\n";
00599 }
00600
00601 tbuilder_control::tbuilder_control(const config& cfg) :
00602 tbuilder_widget(cfg),
00603 id(cfg["id"]),
00604 definition(cfg["definition"]),
00605 label(cfg["label"]),
00606 tooltip(cfg["tooltip"]),
00607 help(cfg["help"])
00608 {
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 if(definition.empty()) {
00656 definition = "default";
00657 }
00658
00659
00660 DBG_G_P << "Window builder: found control with id '"
00661 << id << "' and definition '" << definition << "'.\n";
00662 }
00663
00664 void tbuilder_control::init_control(tcontrol* control) const
00665 {
00666 assert(control);
00667
00668 control->set_id(id);
00669 control->set_definition(definition);
00670 control->set_label(label);
00671 control->set_tooltip(tooltip);
00672 control->set_help_message(help);
00673 }
00674
00675 tbuilder_button::tbuilder_button(const config& cfg) :
00676 tbuilder_control(cfg),
00677 retval_(lexical_cast_default<int>(cfg["return_value"]))
00678 {
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 }
00700
00701 twidget* tbuilder_button::build() const
00702 {
00703 tbutton* button = new tbutton();
00704
00705 init_control(button);
00706
00707 if(retval_) {
00708 button->set_retval(retval_);
00709 } else {
00710 button->set_retval(tbutton::get_retval_by_id(id));
00711 }
00712
00713 DBG_G << "Window builder: placed button '" << id << "' with defintion '"
00714 << definition << "'.\n";
00715
00716 return button;
00717 }
00718
00719 twidget* tbuilder_label::build() const
00720 {
00721 tlabel* tmp_label = new tlabel();
00722
00723 init_control(tmp_label);
00724
00725 DBG_G << "Window builder: placed label '" << id << "' with defintion '"
00726 << definition << "'.\n";
00727
00728 return tmp_label;
00729 }
00730
00731 tbuilder_listbox::tbuilder_listbox(const config& cfg) :
00732 tbuilder_control(cfg),
00733 header(cfg.child("header") ? new tbuilder_grid(*(cfg.child("header"))) : 0),
00734 list(0),
00735 footer(cfg.child("footer") ? new tbuilder_grid(*(cfg.child("footer"))) : 0),
00736 list_builder(0),
00737 assume_fixed_row_size(utils::string_bool(cfg["assume_fixed_row_size"]))
00738 {
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792 if(cfg.child("list_definition")) {
00793 list_builder = new tbuilder_grid(*(cfg.child("list_definition")));
00794 } else if(cfg.child("list")) {
00795 list = new tbuilder_grid(*(cfg.child("list")));
00796 } else {
00797 VALIDATE(false, _("No 'list_builder' nor a 'list' section defined."));
00798 }
00799 }
00800
00801 twidget* tbuilder_listbox::build() const
00802 {
00803 tlistbox *listbox = new tlistbox();
00804
00805 init_control(listbox);
00806
00807 listbox->set_list_builder(list_builder);
00808
00809 listbox->set_assume_fixed_row_size(assume_fixed_row_size);
00810
00811 DBG_G << "Window builder: placed listbox '" << id << "' with defintion '"
00812 << definition << "'.\n";
00813
00814 tlistbox_definition::tresolution* conf = static_cast<tlistbox_definition::tresolution*>(listbox->config());
00815 assert(conf);
00816
00817 tgrid* scrollbar = dynamic_cast<tgrid*>(conf->scrollbar->build());
00818 assert(scrollbar);
00819
00820 scrollbar->set_id("_scroll");
00821
00822 twidget* list_area = 0;
00823 if(list_builder) {
00824 list_area = new tspacer();
00825 assert(list_area);
00826 list_area->set_definition("default");
00827 } else {
00828 assert(list);
00829 list_area = dynamic_cast<tgrid*>(list->build());
00830 assert(list_area);
00831 }
00832
00833 list_area->set_id("_list");
00834
00835 listbox->grid().set_rows_cols(1, 2);
00836 listbox->grid().add_child(list_area, 0, 0,
00837 tgrid::VERTICAL_GROW_SEND_TO_CLIENT
00838 | tgrid::HORIZONTAL_GROW_SEND_TO_CLIENT
00839 | tgrid::VERTICAL_ALIGN_CENTER
00840 | tgrid::HORIZONTAL_ALIGN_CENTER
00841 , 0);
00842 listbox->grid().set_col_grow_factor(0, 1);
00843 listbox->grid().add_child(scrollbar, 0, 1,
00844 tgrid::VERTICAL_GROW_SEND_TO_CLIENT
00845 | tgrid::VERTICAL_ALIGN_CENTER
00846 | tgrid::HORIZONTAL_ALIGN_CENTER
00847 , 0);
00848
00849 listbox->finalize_setup();
00850
00851 return listbox;
00852 }
00853
00854 tbuilder_panel::tbuilder_panel(const config& cfg) :
00855 tbuilder_control(cfg),
00856 grid(0)
00857 {
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874 VALIDATE(cfg.child("grid"), _("No grid defined."));
00875
00876 grid = new tbuilder_grid(*(cfg.child("grid")));
00877 }
00878
00879 twidget* tbuilder_panel::build() const
00880 {
00881 tpanel* panel = new tpanel();
00882
00883 init_control(panel);
00884
00885 DBG_G << "Window builder: placed panel '" << id << "' with defintion '"
00886 << definition << "'.\n";
00887
00888
00889 log_scope2(gui, "Window builder: building grid for panel.");
00890
00891 const unsigned rows = grid->rows;
00892 const unsigned cols = grid->cols;
00893
00894 panel->set_rows_cols(rows, cols);
00895
00896 for(unsigned x = 0; x < rows; ++x) {
00897 panel->set_row_grow_factor(x, grid->row_grow_factor[x]);
00898 for(unsigned y = 0; y < cols; ++y) {
00899
00900 if(x == 0) {
00901 panel->set_col_grow_factor(y, grid->col_grow_factor[y]);
00902 }
00903
00904 twidget* widget = grid->widgets[x * cols + y]->build();
00905 panel->add_child(widget, x, y, grid->flags[x * cols + y], grid->border_size[x * cols + y]);
00906 }
00907 }
00908
00909 return panel;
00910 }
00911
00912 twidget* tbuilder_spacer::build() const
00913 {
00914 tspacer* spacer = new tspacer();
00915
00916 init_control(spacer);
00917
00918 DBG_G << "Window builder: placed spacer '" << id << "' with defintion '"
00919 << definition << "'.\n";
00920
00921 return spacer;
00922 }
00923
00924 twidget* tbuilder_toggle_button::build() const
00925 {
00926 ttoggle_button *toggle_button = new ttoggle_button();
00927
00928 init_control(toggle_button);
00929
00930 DBG_G << "Window builder: placed toggle button '" << id << "' with defintion '"
00931 << definition << "'.\n";
00932
00933 return toggle_button;
00934 }
00935
00936 twidget* tbuilder_text_box::build() const
00937 {
00938 ttext_box* text_box = new ttext_box();
00939
00940 init_control(text_box);
00941
00942
00943 text_box->set_text(label);
00944
00945 if (!history_.empty()) {
00946 text_box->set_history(history_);
00947 }
00948
00949 DBG_G << "Window builder: placed text box '" << id << "' with defintion '"
00950 << definition << "'.\n";
00951
00952 return text_box;
00953 }
00954
00955 twidget* tbuilder_vertical_scrollbar::build() const
00956 {
00957 tvertical_scrollbar *vertical_scrollbar = new tvertical_scrollbar();
00958
00959 init_control(vertical_scrollbar);
00960
00961 DBG_G << "Window builder: placed text box '" << id << "' with defintion '"
00962 << definition << "'.\n";
00963
00964 return vertical_scrollbar;
00965 }
00966
00967 twidget* tbuilder_grid::build() const
00968 {
00969 tgrid* grid = new tgrid();
00970
00971 grid->set_rows_cols(rows, cols);
00972
00973 log_scope2(gui, "Window builder: building grid");
00974
00975 DBG_G << "Window builder: grid has " << rows << " rows and "
00976 << cols << " columns.\n";
00977
00978 for(unsigned x = 0; x < rows; ++x) {
00979 grid->set_row_grow_factor(x, row_grow_factor[x]);
00980 for(unsigned y = 0; y < cols; ++y) {
00981
00982 if(x == 0) {
00983 grid->set_col_grow_factor(y, col_grow_factor[y]);
00984 }
00985
00986 DBG_G << "Window builder: adding child at " << x << ',' << y << ".\n";
00987
00988 twidget* widget = widgets[x * cols + y]->build();
00989 grid->add_child(widget, x, y, flags[x * cols + y], border_size[x * cols + y]);
00990 }
00991 }
00992
00993 return grid;
00994 }
00995
00996 }
00997
00998
00999
01000
01001
01002
01003
01004
01005