diff --git a/src/gui/dialogs/drop_down_menu.cpp b/src/gui/dialogs/drop_down_menu.cpp index 7dd1451c4196..937d220324c8 100644 --- a/src/gui/dialogs/drop_down_menu.cpp +++ b/src/gui/dialogs/drop_down_menu.cpp @@ -139,8 +139,7 @@ void drop_down_menu::pre_show(window& window) find_widget(&new_row, "panel", false).set_tooltip(entry["tooltip"]); if(entry.has_attribute("image")) { - image* img = new image(); - img->set_definition("default"); + image* img = build_single_widget_instance("image"); img->set_label(entry["image"]); grid* mi_grid = dynamic_cast(new_row.find("menu_item", false)); @@ -150,8 +149,7 @@ void drop_down_menu::pre_show(window& window) } if(entry.has_attribute("checkbox")) { - toggle_button* checkbox = new toggle_button(); - checkbox->set_definition("default"); + toggle_button* checkbox = build_single_widget_instance("toggle_button"); checkbox->set_id("checkbox"); checkbox->set_value_bool(entry["checkbox"].to_bool(false)); diff --git a/src/gui/dialogs/preferences_dialog.cpp b/src/gui/dialogs/preferences_dialog.cpp index 60be889a88cf..087b1f6f1ff6 100644 --- a/src/gui/dialogs/preferences_dialog.cpp +++ b/src/gui/dialogs/preferences_dialog.cpp @@ -604,8 +604,7 @@ void preferences_dialog::post_build(window& window) } case ADVANCED_PREF_TYPE::SLIDER: { - slider* setter_widget = new slider(); - setter_widget->set_definition("minimal"); + slider* setter_widget = build_single_widget_instance("slider", config {"definition", "minimal"}); setter_widget->set_id("setter"); // Maximum must be set first or this will assert setter_widget->set_maximum_value(option["max"].to_int()); @@ -647,8 +646,7 @@ void preferences_dialog::post_build(window& window) const unsigned selected = std::find(option_ids.begin(), option_ids.end(), get(pref_name, option["default"].str())) - option_ids.begin(); - menu_button* setter_widget = new menu_button(); - setter_widget->set_definition("default"); + menu_button* setter_widget = build_single_widget_instance("menu_button"); setter_widget->set_id("setter"); details_grid.swap_child("setter", setter_widget, true); @@ -671,8 +669,7 @@ void preferences_dialog::post_build(window& window) case ADVANCED_PREF_TYPE::SPECIAL: { //main_grid->remove_child("setter"); - image* value_widget = new image(); - value_widget->set_definition("default"); + image* value_widget = build_single_widget_instance("image"); value_widget->set_label("icons/arrows/arrows_blank_right_25.png~CROP(3,3,18,18)"); main_grid->swap_child("value", value_widget, true); diff --git a/src/gui/widgets/addon_list.cpp b/src/gui/widgets/addon_list.cpp index fa5dad887fcd..cd8c5bc4a68d 100644 --- a/src/gui/widgets/addon_list.cpp +++ b/src/gui/widgets/addon_list.cpp @@ -39,6 +39,18 @@ namespace gui2 REGISTER_WIDGET(addon_list) +addon_list::addon_list(const implementation::builder_addon_list& builder) + : container_base(builder, get_control_type()) + , addon_vector_() + , install_status_visibility_(visibility::visible) + , install_buttons_visibility_(visibility::invisible) + , install_function_() + , uninstall_function_() + , publish_function_() + , delete_function_() +{ +} + static color_t color_outdated {255, 127, 0}; std::string addon_list::colorify_addon_state_string(const std::string& str, ADDON_STATUS state, bool verbose) @@ -439,9 +451,7 @@ builder_addon_list::builder_addon_list(const config& cfg) : widget* builder_addon_list::build() const { - addon_list* widget = new addon_list(); - - init_control(widget); + addon_list* widget = new addon_list(*this); DBG_GUI_G << "Window builder: placed add-on list '" << id << "' with definition '" << definition << "'.\n"; diff --git a/src/gui/widgets/addon_list.hpp b/src/gui/widgets/addon_list.hpp index cc8b41e591bb..edda93d2972f 100644 --- a/src/gui/widgets/addon_list.hpp +++ b/src/gui/widgets/addon_list.hpp @@ -38,16 +38,7 @@ class addon_list : public container_base friend struct implementation::builder_addon_list; public: - addon_list() - : container_base() - , addon_vector_() - , install_status_visibility_(visibility::visible) - , install_buttons_visibility_(visibility::invisible) - , install_function_() - , uninstall_function_() - , publish_function_() - , delete_function_() - {} + explicit addon_list(const implementation::builder_addon_list& builder); /** Special retval for the toggle panels in the addons list */ static const int DEFAULT_ACTION_RETVAL = 200; diff --git a/src/gui/widgets/button.cpp b/src/gui/widgets/button.cpp index 59d305b06698..75d6a065ef41 100644 --- a/src/gui/widgets/button.cpp +++ b/src/gui/widgets/button.cpp @@ -40,7 +40,11 @@ namespace gui2 REGISTER_WIDGET(button) -button::button() : styled_widget(), clickable_item(), state_(ENABLED), retval_(0) +button::button(const implementation::builder_button& builder) + : styled_widget(builder, get_control_type()) + , clickable_item() + , state_(ENABLED) + , retval_(0) { connect_signal( std::bind(&button::signal_handler_mouse_enter, this, _2, _3)); @@ -246,9 +250,7 @@ builder_button::builder_button(const config& cfg) widget* builder_button::build() const { - button* widget = new button(); - - init_control(widget); + button* widget = new button(*this); widget->set_retval(get_retval(retval_id_, retval_, id)); diff --git a/src/gui/widgets/button.hpp b/src/gui/widgets/button.hpp index d361d564cfee..73cf093b0e35 100644 --- a/src/gui/widgets/button.hpp +++ b/src/gui/widgets/button.hpp @@ -22,6 +22,10 @@ namespace gui2 { +namespace implementation +{ + struct builder_button; +} // ------------ WIDGET -----------{ @@ -31,7 +35,7 @@ namespace gui2 class button : public styled_widget, public clickable_item { public: - button(); + explicit button(const implementation::builder_button& builder); /***** ***** ***** ***** Inherited ***** ***** ***** *****/ diff --git a/src/gui/widgets/chatbox.cpp b/src/gui/widgets/chatbox.cpp index 85dd2ad80548..45b8d2b8be2d 100644 --- a/src/gui/widgets/chatbox.cpp +++ b/src/gui/widgets/chatbox.cpp @@ -52,8 +52,8 @@ namespace gui2 REGISTER_WIDGET(chatbox) -chatbox::chatbox() - : container_base() +chatbox::chatbox(const implementation::builder_chatbox& builder) + : container_base(builder, get_control_type()) , roomlistbox_(nullptr) , chat_log_container_(nullptr) , chat_input_(nullptr) @@ -758,9 +758,7 @@ builder_chatbox::builder_chatbox(const config& cfg) widget* builder_chatbox::build() const { - chatbox* widget = new chatbox(); - - init_control(widget); + chatbox* widget = new chatbox(*this); DBG_GUI_G << "Window builder: placed unit preview pane '" << id << "' with definition '" << definition << "'.\n"; diff --git a/src/gui/widgets/chatbox.hpp b/src/gui/widgets/chatbox.hpp index c27d145f83ae..d278b89aefa5 100644 --- a/src/gui/widgets/chatbox.hpp +++ b/src/gui/widgets/chatbox.hpp @@ -57,7 +57,7 @@ class chatbox : public container_base, public events::chat_handler friend struct implementation::builder_chatbox; public: - chatbox(); + explicit chatbox(const implementation::builder_chatbox& builder); /** See @ref styled_widget::set_active. */ virtual void set_active(const bool active) override; diff --git a/src/gui/widgets/container_base.cpp b/src/gui/widgets/container_base.cpp index 07c9243a2a8c..0121cbeb898e 100644 --- a/src/gui/widgets/container_base.cpp +++ b/src/gui/widgets/container_base.cpp @@ -28,8 +28,9 @@ namespace gui2 { -container_base::container_base() - : styled_widget(), grid_() +container_base::container_base(const implementation::builder_styled_widget& builder, const std::string& control_type) + : styled_widget(builder, control_type) + , grid_() { grid_.set_parent(this); connect_signal( diff --git a/src/gui/widgets/container_base.hpp b/src/gui/widgets/container_base.hpp index f75c8b81bb8d..1a5520e9cbcc 100644 --- a/src/gui/widgets/container_base.hpp +++ b/src/gui/widgets/container_base.hpp @@ -20,6 +20,10 @@ namespace gui2 { +namespace implementation +{ +struct builder_styled_widget; +} /** * A generic container base class. @@ -33,7 +37,7 @@ class container_base : public styled_widget friend class debug_layout_graph; public: - container_base(); + explicit container_base(const implementation::builder_styled_widget& builder, const std::string& control_type); /** * Returns the client rect. diff --git a/src/gui/widgets/drawing.cpp b/src/gui/widgets/drawing.cpp index 0b4c60c17b21..80dba9cfa905 100644 --- a/src/gui/widgets/drawing.cpp +++ b/src/gui/widgets/drawing.cpp @@ -31,6 +31,12 @@ namespace gui2 REGISTER_WIDGET(drawing) +drawing::drawing(const implementation::builder_drawing& builder) + : styled_widget(builder, get_control_type()) + , best_size_(0, 0) +{ +} + point drawing::calculate_best_size() const { return best_size_ != point() ? best_size_ @@ -177,9 +183,7 @@ builder_drawing::builder_drawing(const config& cfg) widget* builder_drawing::build() const { - drawing* widget = new drawing(); - - init_control(widget); + drawing* widget = new drawing(*this); const wfl::map_formula_callable& size = get_screen_size_variables(); diff --git a/src/gui/widgets/drawing.hpp b/src/gui/widgets/drawing.hpp index dbb08f4bfc1e..1af9d6409685 100644 --- a/src/gui/widgets/drawing.hpp +++ b/src/gui/widgets/drawing.hpp @@ -23,7 +23,10 @@ class config; namespace gui2 { - +namespace implementation +{ + struct builder_drawing; +} // ------------ WIDGET -----------{ /** @@ -35,9 +38,7 @@ namespace gui2 class drawing : public styled_widget { public: - drawing() : styled_widget(), best_size_(0, 0) - { - } + explicit drawing(const implementation::builder_drawing& builder); canvas& get_drawing_canvas() { diff --git a/src/gui/widgets/horizontal_scrollbar.cpp b/src/gui/widgets/horizontal_scrollbar.cpp index 9448e6a0c4dc..73c3bfc66914 100644 --- a/src/gui/widgets/horizontal_scrollbar.cpp +++ b/src/gui/widgets/horizontal_scrollbar.cpp @@ -33,6 +33,11 @@ namespace gui2 REGISTER_WIDGET(horizontal_scrollbar) +horizontal_scrollbar::horizontal_scrollbar(const implementation::builder_horizontal_scrollbar& builder) + : scrollbar_base(builder, get_control_type()) +{ +} + unsigned horizontal_scrollbar::minimum_positioner_length() const { const auto conf = cast_config_to(); @@ -217,9 +222,9 @@ builder_horizontal_scrollbar::builder_horizontal_scrollbar(const config& cfg) widget* builder_horizontal_scrollbar::build() const { - horizontal_scrollbar* widget = new horizontal_scrollbar(); + horizontal_scrollbar* widget = new horizontal_scrollbar(*this); - init_control(widget); + widget->finalize_setup(); DBG_GUI_G << "Window builder:" << " placed horizontal scrollbar '" << id << "' with definition '" diff --git a/src/gui/widgets/horizontal_scrollbar.hpp b/src/gui/widgets/horizontal_scrollbar.hpp index c8688704da42..93eba3ad8e0d 100644 --- a/src/gui/widgets/horizontal_scrollbar.hpp +++ b/src/gui/widgets/horizontal_scrollbar.hpp @@ -21,16 +21,20 @@ namespace gui2 { +namespace implementation +{ +struct builder_horizontal_scrollbar; +} // ------------ WIDGET -----------{ /** A horizontal scrollbar. */ class horizontal_scrollbar : public scrollbar_base { + friend struct implementation::builder_horizontal_scrollbar; + public: - horizontal_scrollbar() : scrollbar_base() - { - } + explicit horizontal_scrollbar(const implementation::builder_horizontal_scrollbar& builder); private: /** Inherited from tscrollbar. */ diff --git a/src/gui/widgets/image.cpp b/src/gui/widgets/image.cpp index f2a9983a678a..f2ddbec91b16 100644 --- a/src/gui/widgets/image.cpp +++ b/src/gui/widgets/image.cpp @@ -36,6 +36,11 @@ namespace gui2 REGISTER_WIDGET(image) +image::image(const implementation::builder_image& builder) + : styled_widget(builder, get_control_type()) +{ +} + point image::calculate_best_size() const { surface image(::image::get_image(::image::locator(get_label()))); @@ -168,9 +173,7 @@ builder_image::builder_image(const config& cfg) : builder_styled_widget(cfg) widget* builder_image::build() const { - image* widget = new image(); - - init_control(widget); + image* widget = new image(*this); DBG_GUI_G << "Window builder: placed image '" << id << "' with definition '" << definition << "'.\n"; diff --git a/src/gui/widgets/image.hpp b/src/gui/widgets/image.hpp index 74684a508376..ac46804a9647 100644 --- a/src/gui/widgets/image.hpp +++ b/src/gui/widgets/image.hpp @@ -21,6 +21,10 @@ namespace gui2 { +namespace implementation +{ + struct builder_image; +} // ------------ WIDGET -----------{ @@ -28,9 +32,7 @@ namespace gui2 class image : public styled_widget { public: - image() : styled_widget() - { - } + explicit image(const implementation::builder_image& builder); /** * Wrapper for set_label. diff --git a/src/gui/widgets/label.cpp b/src/gui/widgets/label.cpp index a51f05f0b69c..b8faf25bfd5a 100644 --- a/src/gui/widgets/label.cpp +++ b/src/gui/widgets/label.cpp @@ -40,15 +40,15 @@ namespace gui2 REGISTER_WIDGET(label) -label::label() - : styled_widget() - , state_(ENABLED) - , can_wrap_(false) - , characters_per_line_(0) - , link_aware_(false) - , link_color_(color_t::from_hex_string("ffff00")) - , can_shrink_(false) - , text_alpha_(255) +label::label(const implementation::builder_label& builder) + : styled_widget(builder, get_control_type()) + , state_(ENABLED) + , can_wrap_(false) + , characters_per_line_(0) + , link_aware_(false) + , link_color_(color_t::from_hex_string("ffff00")) + , can_shrink_(false) + , text_alpha_(255) { connect_signal(std::bind(&label::signal_handler_left_button_click, this, _2, _3)); connect_signal(std::bind(&label::signal_handler_right_button_click, this, _2, _3)); @@ -147,18 +147,6 @@ const std::string& label::get_control_type() const return type; } -void label::load_config_extra() -{ - assert(config()); - - const auto conf = cast_config_to(); - assert(conf); - - set_link_aware(conf->link_aware); - set_link_color(conf->link_color); -} - - void label::signal_handler_left_button_click(const event::ui_event /* event */, bool & handled) { DBG_GUI_E << "label click" << std::endl; @@ -334,15 +322,18 @@ builder_label::builder_label(const config& cfg) widget* builder_label::build() const { - label* lbl = new label(); + label* lbl = new label(*this); - init_control(lbl); + const auto conf = lbl->cast_config_to(); + assert(conf); lbl->set_can_wrap(wrap); lbl->set_characters_per_line(characters_per_line); lbl->set_text_alignment(text_alignment); lbl->set_text_alpha(ALPHA_OPAQUE); lbl->set_can_shrink(can_shrink); + lbl->set_link_aware(conf->link_aware); + lbl->set_link_color(conf->link_color); DBG_GUI_G << "Window builder: placed label '" << id << "' with definition '" << definition << "'.\n"; diff --git a/src/gui/widgets/label.hpp b/src/gui/widgets/label.hpp index b04d03080d96..25923b4529fa 100644 --- a/src/gui/widgets/label.hpp +++ b/src/gui/widgets/label.hpp @@ -21,14 +21,20 @@ namespace gui2 { +namespace implementation +{ + struct builder_label; +} // ------------ WIDGET -----------{ /** Label showing a text. */ class label : public styled_widget { + friend struct implementation::builder_label; + public: - label(); + explicit label(const implementation::builder_label& builder); /** See @ref widget::can_wrap. */ virtual bool can_wrap() const override; @@ -131,9 +137,6 @@ class label : public styled_widget /** See @ref styled_widget::get_control_type. */ virtual const std::string& get_control_type() const override; - /** Inherited from styled_widget. */ - void load_config_extra() override; - /***** ***** ***** signal handlers ***** ****** *****/ /** diff --git a/src/gui/widgets/listbox.cpp b/src/gui/widgets/listbox.cpp index a86225dd7bc8..a983fc922100 100644 --- a/src/gui/widgets/listbox.cpp +++ b/src/gui/widgets/listbox.cpp @@ -60,11 +60,12 @@ void callback_list_item_clicked(widget& caller) } // namespace -listbox::listbox(const bool has_minimum, - const bool has_maximum, - const generator_base::placement placement, - const bool select) - : scrollbar_container() +listbox::listbox(const implementation::builder_styled_widget& builder, + const bool has_minimum, + const bool has_maximum, + const generator_base::placement placement, + const bool select) + : scrollbar_container(builder, get_control_type()) , generator_(generator_base::build(has_minimum, has_maximum, placement, select)) , is_horizontal_(placement == generator_base::horizontal_list) , list_builder_(nullptr) @@ -972,16 +973,14 @@ widget* builder_listbox::build() const list_view* widget = new list_view( true, true, generator_base::vertical_list, true, list_builder); - init_control(widget); + //init_control(widget); if(!list_data.empty()) { widget->append_rows(list_data); } return widget; #else listbox* widget - = new listbox(has_minimum_, has_maximum_, generator_base::vertical_list, true); - - init_control(widget); + = new listbox(*this, has_minimum_, has_maximum_, generator_base::vertical_list, true); widget->set_list_builder(list_builder); // FIXME in finalize??? @@ -1095,16 +1094,14 @@ widget* builder_horizontal_listbox::build() const list_view* widget = new list_view( true, true, generator_base::horizontal_list, true, list_builder); - init_control(widget); + //init_control(widget); if(!list_data.empty()) { widget->append_rows(list_data); } return widget; #else listbox* widget - = new listbox(has_minimum_, has_maximum_, generator_base::horizontal_list, true); - - init_control(widget); + = new listbox(*this, has_minimum_, has_maximum_, generator_base::horizontal_list, true); widget->set_list_builder(list_builder); // FIXME in finalize??? @@ -1218,16 +1215,14 @@ widget* builder_grid_listbox::build() const list_view* widget = new list_view( true, true, generator_base::grid, true, list_builder); - init_control(widget); + //init_control(widget); if(!list_data.empty()) { widget->append_rows(list_data); } return widget; #else listbox* widget - = new listbox(has_minimum_, has_maximum_, generator_base::table, true); - - init_control(widget); + = new listbox(*this, has_minimum_, has_maximum_, generator_base::table, true); widget->set_list_builder(list_builder); // FIXME in finalize??? diff --git a/src/gui/widgets/listbox.hpp b/src/gui/widgets/listbox.hpp index 4cee882801c5..22734d4cabab 100644 --- a/src/gui/widgets/listbox.hpp +++ b/src/gui/widgets/listbox.hpp @@ -35,6 +35,7 @@ namespace implementation struct builder_listbox; struct builder_horizontal_listbox; struct builder_grid_listbox; +struct builder_styled_widget; } /** The listbox class. */ @@ -49,6 +50,8 @@ class listbox : public scrollbar_container /** * Constructor. * + * @param builder The builder for the appropriate listbox + * variant. * @param has_minimum Does the listbox need to have one item * selected. * @param has_maximum Can the listbox only have one item @@ -57,10 +60,11 @@ class listbox : public scrollbar_container * @param select Select an item when selected, if false it * changes the visible state instead. */ - listbox(const bool has_minimum, - const bool has_maximum, - const generator_base::placement placement, - const bool select); + listbox(const implementation::builder_styled_widget& builder, + const bool has_minimum, + const bool has_maximum, + const generator_base::placement placement, + const bool select); /***** ***** ***** ***** Row handling. ***** ***** ****** *****/ /** diff --git a/src/gui/widgets/menu_button.cpp b/src/gui/widgets/menu_button.cpp index 586b2cee9ee1..55c14fe6ab69 100644 --- a/src/gui/widgets/menu_button.cpp +++ b/src/gui/widgets/menu_button.cpp @@ -37,8 +37,8 @@ namespace gui2 REGISTER_WIDGET(menu_button) -menu_button::menu_button() - : styled_widget() +menu_button::menu_button(const implementation::builder_menu_button& builder) + : styled_widget(builder, get_control_type()) , selectable_item() , state_(ENABLED) , retval_(0) @@ -309,9 +309,7 @@ builder_menu_button::builder_menu_button(const config& cfg) widget* builder_menu_button::build() const { - menu_button* widget = new menu_button(); - - init_control(widget); + menu_button* widget = new menu_button(*this); widget->set_retval(get_retval(retval_id_, retval_, id)); if(!options_.empty()) { diff --git a/src/gui/widgets/menu_button.hpp b/src/gui/widgets/menu_button.hpp index 1b9aff48ead7..0eb5fcc31e19 100644 --- a/src/gui/widgets/menu_button.hpp +++ b/src/gui/widgets/menu_button.hpp @@ -28,6 +28,10 @@ class config; namespace gui2 { +namespace implementation +{ + struct builder_menu_button; +} // ------------ WIDGET -----------{ @@ -37,7 +41,7 @@ namespace gui2 class menu_button : public styled_widget, public selectable_item { public: - menu_button(); + explicit menu_button(const implementation::builder_menu_button& builder); /***** ***** ***** ***** Inherited ***** ***** ***** *****/ diff --git a/src/gui/widgets/minimap.cpp b/src/gui/widgets/minimap.cpp index 92d2497e616c..3337d6f16129 100644 --- a/src/gui/widgets/minimap.cpp +++ b/src/gui/widgets/minimap.cpp @@ -47,6 +47,13 @@ namespace gui2 REGISTER_WIDGET(minimap) +minimap::minimap(const implementation::builder_minimap& builder) + : styled_widget(builder, get_control_type()) + , map_data_() + , terrain_(nullptr) +{ +} + void minimap::set_active(const bool /*active*/) { /* DO NOTHING */ @@ -325,9 +332,7 @@ builder_minimap::builder_minimap(const config& cfg) : builder_styled_widget(cfg) widget* builder_minimap::build() const { - minimap* widget = new minimap(); - - init_control(widget); + minimap* widget = new minimap(*this); DBG_GUI_G << "Window builder: placed minimap '" << id << "' with definition '" << definition << "'.\n"; diff --git a/src/gui/widgets/minimap.hpp b/src/gui/widgets/minimap.hpp index 63e0a6260aaf..de4c31df043a 100644 --- a/src/gui/widgets/minimap.hpp +++ b/src/gui/widgets/minimap.hpp @@ -23,6 +23,10 @@ class config; namespace gui2 { +namespace implementation +{ +struct builder_minimap; +} // ------------ WIDGET -----------{ @@ -35,9 +39,7 @@ namespace gui2 class minimap : public styled_widget { public: - minimap() : styled_widget(), map_data_(), terrain_(nullptr) - { - } + explicit minimap(const implementation::builder_minimap& builder); /***** ***** ***** ***** Inherited ***** ***** ***** *****/ diff --git a/src/gui/widgets/multi_page.cpp b/src/gui/widgets/multi_page.cpp index 6fc79de78914..c4df0a97af7e 100644 --- a/src/gui/widgets/multi_page.cpp +++ b/src/gui/widgets/multi_page.cpp @@ -32,10 +32,10 @@ namespace gui2 // ------------ WIDGET -----------{ REGISTER_WIDGET(multi_page) -multi_page::multi_page() - : container_base() - , generator_( - generator_base::build(true, true, generator_base::independent, false)) + +multi_page::multi_page(const implementation::builder_multi_page& builder) + : container_base(builder, get_control_type()) + , generator_(generator_base::build(true, true, generator_base::independent, false)) , page_builders_() { } @@ -292,9 +292,7 @@ builder_multi_page::builder_multi_page(const config& cfg) widget* builder_multi_page::build() const { - multi_page* widget = new multi_page(); - - init_control(widget); + multi_page* widget = new multi_page(*this); widget->set_page_builders(builders); diff --git a/src/gui/widgets/multi_page.hpp b/src/gui/widgets/multi_page.hpp index 2e39b11fd0c7..e3a5900bb948 100644 --- a/src/gui/widgets/multi_page.hpp +++ b/src/gui/widgets/multi_page.hpp @@ -38,7 +38,7 @@ class multi_page : public container_base friend class debug_layout_graph; public: - multi_page(); + explicit multi_page(const implementation::builder_multi_page& builder); /***** ***** ***** ***** Page handling. ***** ***** ****** *****/ diff --git a/src/gui/widgets/multimenu_button.cpp b/src/gui/widgets/multimenu_button.cpp index 60695faead0d..c7cc77e39372 100644 --- a/src/gui/widgets/multimenu_button.cpp +++ b/src/gui/widgets/multimenu_button.cpp @@ -39,8 +39,8 @@ namespace gui2 REGISTER_WIDGET(multimenu_button) -multimenu_button::multimenu_button() - : styled_widget() +multimenu_button::multimenu_button(const implementation::builder_multimenu_button& builder) + : styled_widget(builder, get_control_type()) , state_(ENABLED) , retval_(0) , values_() @@ -353,9 +353,7 @@ builder_multimenu_button::builder_multimenu_button(const config& cfg) widget* builder_multimenu_button::build() const { - multimenu_button* widget = new multimenu_button(); - - init_control(widget); + multimenu_button* widget = new multimenu_button(*this); widget->set_retval(get_retval(retval_id_, retval_, id)); widget->set_max_shown(max_shown_); diff --git a/src/gui/widgets/multimenu_button.hpp b/src/gui/widgets/multimenu_button.hpp index f4be46a0dc47..82f649a73a9f 100644 --- a/src/gui/widgets/multimenu_button.hpp +++ b/src/gui/widgets/multimenu_button.hpp @@ -28,6 +28,10 @@ class config; namespace gui2 { +namespace implementation +{ +struct builder_multimenu_button; +} // ------------ WIDGET -----------{ @@ -37,7 +41,7 @@ namespace gui2 class multimenu_button : public styled_widget { public: - multimenu_button(); + explicit multimenu_button(const implementation::builder_multimenu_button& builder); /***** ***** ***** ***** Inherited ***** ***** ***** *****/ diff --git a/src/gui/widgets/panel.cpp b/src/gui/widgets/panel.cpp index c655738f9660..e5cc1fd0e39a 100644 --- a/src/gui/widgets/panel.cpp +++ b/src/gui/widgets/panel.cpp @@ -35,6 +35,11 @@ namespace gui2 REGISTER_WIDGET(panel) +panel::panel(const implementation::builder_styled_widget& builder, const std::string& control_type) + : container_base(builder, control_type.empty() ? get_control_type() : control_type) +{ +} + SDL_Rect panel::get_client_rect() const { const auto conf = cast_config_to(); @@ -199,9 +204,7 @@ builder_panel::builder_panel(const config& cfg) widget* builder_panel::build() const { - panel* widget = new panel(); - - init_control(widget); + panel* widget = new panel(*this); DBG_GUI_G << "Window builder: placed panel '" << id << "' with definition '" << definition << "'.\n"; diff --git a/src/gui/widgets/panel.hpp b/src/gui/widgets/panel.hpp index bf94aed116b2..cbeaa7ba7f8d 100644 --- a/src/gui/widgets/panel.hpp +++ b/src/gui/widgets/panel.hpp @@ -21,6 +21,10 @@ namespace gui2 { +namespace implementation +{ +struct builder_panel; +} // ------------ WIDGET -----------{ @@ -32,14 +36,11 @@ namespace gui2 */ class panel : public container_base { - public: /** * Constructor. */ - panel() : container_base() - { - } + panel(const implementation::builder_styled_widget& builder, const std::string& control_type = ""); /** See @ref container_base::get_client_rect. */ virtual SDL_Rect get_client_rect() const override; diff --git a/src/gui/widgets/password_box.cpp b/src/gui/widgets/password_box.cpp index c6c21634b15e..b7298efe7228 100644 --- a/src/gui/widgets/password_box.cpp +++ b/src/gui/widgets/password_box.cpp @@ -37,6 +37,12 @@ namespace gui2 REGISTER_WIDGET3(text_box_definition, password_box, "text_box_definition") +password_box::password_box(const implementation::builder_password_box& builder) + : text_box(builder) + , real_value_() +{ +} + void password_box::set_value(const std::string& text) { real_value_ = text; @@ -129,9 +135,7 @@ builder_password_box::builder_password_box(const config& cfg) widget* builder_password_box::build() const { - password_box* widget = new password_box(); - - init_control(widget); + password_box* widget = new password_box(*this); // A password box doesn't have a label but a text. // It also has no history. diff --git a/src/gui/widgets/password_box.hpp b/src/gui/widgets/password_box.hpp index fe4a111b1fce..fc3355e10002 100644 --- a/src/gui/widgets/password_box.hpp +++ b/src/gui/widgets/password_box.hpp @@ -28,15 +28,17 @@ */ namespace gui2 { +namespace implementation +{ + struct builder_password_box; +} // ------------ WIDGET -----------{ class password_box : public text_box { public: - password_box() : text_box(), real_value_() - { - } + explicit password_box(const implementation::builder_password_box& builder); /** Inherited from text_box_base. */ virtual void set_value(const std::string& text) override; diff --git a/src/gui/widgets/progress_bar.cpp b/src/gui/widgets/progress_bar.cpp index e0e505de1340..ff4da58b44dc 100644 --- a/src/gui/widgets/progress_bar.cpp +++ b/src/gui/widgets/progress_bar.cpp @@ -32,6 +32,14 @@ namespace gui2 REGISTER_WIDGET(progress_bar) +progress_bar::progress_bar(const implementation::builder_progress_bar& builder) + : styled_widget(builder, get_control_type()) + , percentage_(static_cast(-1)) +{ + // Force canvas update + set_percentage(0); +} + void progress_bar::set_active(const bool /*active*/) { /* DO NOTHING */ @@ -146,9 +154,7 @@ builder_progress_bar::builder_progress_bar(const config& cfg) widget* builder_progress_bar::build() const { - progress_bar* widget = new progress_bar(); - - init_control(widget); + progress_bar* widget = new progress_bar(*this); DBG_GUI_G << "Window builder: placed progress bar '" << id << "' with definition '" << definition << "'.\n"; diff --git a/src/gui/widgets/progress_bar.hpp b/src/gui/widgets/progress_bar.hpp index 66c9639a99a9..c7d5453d7c0d 100644 --- a/src/gui/widgets/progress_bar.hpp +++ b/src/gui/widgets/progress_bar.hpp @@ -21,17 +21,17 @@ namespace gui2 { +namespace implementation +{ +struct builder_progress_bar; +} // ------------ WIDGET -----------{ class progress_bar : public styled_widget { public: - progress_bar() : styled_widget(), percentage_(static_cast(-1)) - { - // Force canvas update - set_percentage(0); - } + explicit progress_bar(const implementation::builder_progress_bar& builder); /***** ***** ***** ***** Inherited ***** ***** ***** *****/ diff --git a/src/gui/widgets/repeating_button.cpp b/src/gui/widgets/repeating_button.cpp index 4a473c0e8aa4..b68069cddc2f 100644 --- a/src/gui/widgets/repeating_button.cpp +++ b/src/gui/widgets/repeating_button.cpp @@ -35,8 +35,11 @@ namespace gui2 REGISTER_WIDGET(repeating_button) -repeating_button::repeating_button() - : styled_widget(), clickable_item(), state_(ENABLED), repeat_timer_(0) +repeating_button::repeating_button(const implementation::builder_repeating_button& builder) + : styled_widget(builder, get_control_type()) + , clickable_item() + , state_(ENABLED) + , repeat_timer_(0) { connect_signal(std::bind( &repeating_button::signal_handler_mouse_enter, this, _2, _3)); @@ -249,9 +252,7 @@ builder_repeating_button::builder_repeating_button(const config& cfg) widget* builder_repeating_button::build() const { - repeating_button* widget = new repeating_button(); - - init_control(widget); + repeating_button* widget = new repeating_button(*this); DBG_GUI_G << "Window builder: placed repeating button '" << id << "' with definition '" << definition << "'.\n"; diff --git a/src/gui/widgets/repeating_button.hpp b/src/gui/widgets/repeating_button.hpp index 49bcab73200d..304bcdbcffce 100644 --- a/src/gui/widgets/repeating_button.hpp +++ b/src/gui/widgets/repeating_button.hpp @@ -22,13 +22,17 @@ namespace gui2 { +namespace implementation +{ +struct builder_repeating_button; +} // ------------ WIDGET -----------{ class repeating_button : public styled_widget, public clickable_item { public: - repeating_button(); + explicit repeating_button(const implementation::builder_repeating_button& builder); ~repeating_button(); /** diff --git a/src/gui/widgets/scroll_label.cpp b/src/gui/widgets/scroll_label.cpp index 51c5bf4d15ef..1eed2b8d7754 100644 --- a/src/gui/widgets/scroll_label.cpp +++ b/src/gui/widgets/scroll_label.cpp @@ -39,11 +39,11 @@ namespace gui2 REGISTER_WIDGET(scroll_label) -scroll_label::scroll_label(bool wrap, const PangoAlignment text_alignment) - : scrollbar_container() +scroll_label::scroll_label(const implementation::builder_scroll_label& builder) + : scrollbar_container(builder, get_control_type()) , state_(ENABLED) - , wrap_on_(wrap) - , text_alignment_(text_alignment) + , wrap_on_(builder.wrap_on) + , text_alignment_(builder.text_alignment) { connect_signal( std::bind(&scroll_label::signal_handler_left_button_down, this, _2), @@ -277,9 +277,7 @@ builder_scroll_label::builder_scroll_label(const config& cfg) widget* builder_scroll_label::build() const { - scroll_label* widget = new scroll_label(wrap_on, text_alignment); - - init_control(widget); + scroll_label* widget = new scroll_label(*this); widget->set_vertical_scrollbar_mode(vertical_scrollbar_mode); widget->set_horizontal_scrollbar_mode(horizontal_scrollbar_mode); diff --git a/src/gui/widgets/scroll_label.hpp b/src/gui/widgets/scroll_label.hpp index e5253b5d18ca..a1d2bd1a0a89 100644 --- a/src/gui/widgets/scroll_label.hpp +++ b/src/gui/widgets/scroll_label.hpp @@ -44,7 +44,7 @@ class scroll_label : public scrollbar_container friend struct implementation::builder_scroll_label; public: - scroll_label(bool wrap, const PangoAlignment text_alignment); + explicit scroll_label(const implementation::builder_scroll_label& builder); /** See @ref styled_widget::set_label. */ virtual void set_label(const t_string& label) override; diff --git a/src/gui/widgets/scrollbar.cpp b/src/gui/widgets/scrollbar.cpp index 2e7ff0363640..5371dd583b4f 100644 --- a/src/gui/widgets/scrollbar.cpp +++ b/src/gui/widgets/scrollbar.cpp @@ -27,8 +27,8 @@ namespace gui2 { -scrollbar_base::scrollbar_base() - : styled_widget() +scrollbar_base::scrollbar_base(const implementation::builder_styled_widget& builder, const std::string& control_type) + : styled_widget(builder, control_type) , state_(ENABLED) , item_count_(0) , item_position_(0) @@ -51,6 +51,15 @@ scrollbar_base::scrollbar_base() &scrollbar_base::signal_handler_left_button_up, this, _2, _3)); } +void scrollbar_base::finalize_setup() +{ + // These values won't change so set them once. + for(auto& tmp : get_canvases()) { + tmp.set_variable("offset_before", wfl::variant(offset_before())); + tmp.set_variable("offset_after", wfl::variant(offset_after())); + } +} + void scrollbar_base::scroll(const scroll_mode scroll) { switch(scroll) { @@ -148,7 +157,6 @@ void scrollbar_base::set_item_position(const unsigned item_position) void scrollbar_base::update_canvas() { - for(auto & tmp : get_canvases()) { tmp.set_variable("positioner_offset", wfl::variant(positioner_offset_)); @@ -168,7 +176,7 @@ void scrollbar_base::set_state(const state_t state) void scrollbar_base::recalculate() { // We can be called before the size has been set up in that case we can't do - // the proper recalcultion so stop before we die with an assert. + // the proper recalculation so stop before we die with an assert. if(!get_length()) { return; } @@ -303,16 +311,6 @@ void scrollbar_base::move_positioner(const int distance) update_canvas(); } -void scrollbar_base::load_config_extra() -{ - // These values won't change so set them here. - for(auto & tmp : get_canvases()) - { - tmp.set_variable("offset_before", wfl::variant(offset_before())); - tmp.set_variable("offset_after", wfl::variant(offset_after())); - } -} - void scrollbar_base::signal_handler_mouse_enter(const event::ui_event event, bool& handled, bool& halt) diff --git a/src/gui/widgets/scrollbar.hpp b/src/gui/widgets/scrollbar.hpp index c834de86f4a8..aa0c62bc3252 100644 --- a/src/gui/widgets/scrollbar.hpp +++ b/src/gui/widgets/scrollbar.hpp @@ -43,7 +43,7 @@ class scrollbar_base : public styled_widget friend class slider; public: - scrollbar_base(); + scrollbar_base(const implementation::builder_styled_widget& builder, const std::string& control_type); /** * scroll 'step size'. @@ -56,7 +56,7 @@ class scrollbar_base : public styled_widget ITEM_BACKWARDS, /**< Go one item towards the begin. */ HALF_JUMP_BACKWARDS, /**< Go half the visible items towards the begin. */ - JUMP_BACKWARDS, /**< Go the visibile items towards the begin. */ + JUMP_BACKWARDS, /**< Go the visible items towards the begin. */ END, /**< Go to the end position. */ ITEM_FORWARD, /**< Go one item towards the end. */ HALF_JUMP_FORWARD, /**< Go half the visible items towards the end. */ @@ -148,6 +148,7 @@ class scrollbar_base : public styled_widget { return visible_items_; } + void set_visible_items(const unsigned visible_items) { visible_items_ = visible_items; @@ -158,6 +159,7 @@ class scrollbar_base : public styled_widget { return step_size_; } + void set_step_size(const unsigned step_size) { step_size_ = step_size; @@ -170,6 +172,8 @@ class scrollbar_base : public styled_widget } protected: + void finalize_setup(); + unsigned get_positioner_offset() const { return positioner_offset_; @@ -356,9 +360,6 @@ class scrollbar_base : public styled_widget */ virtual void move_positioner(const int distance); - /** Inherited from styled_widget. */ - void load_config_extra() override; - /***** ***** ***** signal handlers ***** ****** *****/ void signal_handler_mouse_enter(const event::ui_event event, diff --git a/src/gui/widgets/scrollbar_container.cpp b/src/gui/widgets/scrollbar_container.cpp index 4dfa78318706..36d864404846 100644 --- a/src/gui/widgets/scrollbar_container.cpp +++ b/src/gui/widgets/scrollbar_container.cpp @@ -66,8 +66,9 @@ const std::map& scroll_lookup() } // namespace -scrollbar_container::scrollbar_container() - : container_base() +scrollbar_container::scrollbar_container(const implementation::builder_styled_widget& builder, + const std::string& control_type) + : container_base(builder, control_type) , state_(ENABLED) , vertical_scrollbar_mode_(AUTO_VISIBLE_FIRST_RUN) , horizontal_scrollbar_mode_(AUTO_VISIBLE_FIRST_RUN) @@ -825,8 +826,7 @@ void scrollbar_container::finalize_setup() } /***** Setup the content *****/ - content_ = new spacer(); - content_->set_definition("default"); + content_ = build_single_widget_instance("spacer"); content_grid_ = dynamic_cast( get_grid().swap_child("_content_grid", content_, true).release()); diff --git a/src/gui/widgets/scrollbar_container.hpp b/src/gui/widgets/scrollbar_container.hpp index f72b2c4edd82..98c162dadc33 100644 --- a/src/gui/widgets/scrollbar_container.hpp +++ b/src/gui/widgets/scrollbar_container.hpp @@ -27,6 +27,7 @@ namespace implementation { struct builder_scroll_label; struct builder_scrollbar_panel; +struct builder_styled_widget; } /** @@ -50,7 +51,8 @@ class scrollbar_container : public container_base friend struct scrollbar_container_implementation; public: - scrollbar_container(); + explicit scrollbar_container(const implementation::builder_styled_widget& builder, + const std::string& control_type); ~scrollbar_container() { diff --git a/src/gui/widgets/scrollbar_panel.cpp b/src/gui/widgets/scrollbar_panel.cpp index 9050eff0e3fd..582778947b3e 100644 --- a/src/gui/widgets/scrollbar_panel.cpp +++ b/src/gui/widgets/scrollbar_panel.cpp @@ -32,6 +32,11 @@ namespace gui2 REGISTER_WIDGET(scrollbar_panel) +scrollbar_panel::scrollbar_panel(const implementation::builder_scrollbar_panel& builder) + : scrollbar_container(builder, get_control_type()) +{ +} + bool scrollbar_panel::get_active() const { return true; @@ -152,9 +157,7 @@ builder_scrollbar_panel::builder_scrollbar_panel(const config& cfg) widget* builder_scrollbar_panel::build() const { - scrollbar_panel* panel = new scrollbar_panel(); - - init_control(panel); + scrollbar_panel* panel = new scrollbar_panel(*this); panel->set_vertical_scrollbar_mode(vertical_scrollbar_mode); panel->set_horizontal_scrollbar_mode(horizontal_scrollbar_mode); diff --git a/src/gui/widgets/scrollbar_panel.hpp b/src/gui/widgets/scrollbar_panel.hpp index 361c0cea3789..600c93b78e42 100644 --- a/src/gui/widgets/scrollbar_panel.hpp +++ b/src/gui/widgets/scrollbar_panel.hpp @@ -43,10 +43,7 @@ class scrollbar_panel : public scrollbar_container /** * Constructor. */ - scrollbar_panel() - : scrollbar_container() - { - } + explicit scrollbar_panel(const implementation::builder_scrollbar_panel& builder); /** See @ref styled_widget::get_active. */ virtual bool get_active() const override; diff --git a/src/gui/widgets/size_lock.cpp b/src/gui/widgets/size_lock.cpp index 858ea571da63..45f1c04883a3 100644 --- a/src/gui/widgets/size_lock.cpp +++ b/src/gui/widgets/size_lock.cpp @@ -27,6 +27,12 @@ namespace gui2 REGISTER_WIDGET(size_lock) +size_lock::size_lock(const implementation::builder_size_lock& builder) + : container_base(builder, get_control_type()) + , widget_(nullptr) +{ +} + void size_lock::place(const point& origin, const point& size) { point content_size = widget_->get_best_size(); @@ -137,9 +143,7 @@ builder_size_lock::builder_size_lock(const config& cfg) : widget* builder_size_lock::build() const { - size_lock* widget = new size_lock(); - - init_control(widget); + size_lock* widget = new size_lock(*this); DBG_GUI_G << "Window builder: placed fixed size widget '" << id << "' with definition '" << definition << "'.\n"; diff --git a/src/gui/widgets/size_lock.hpp b/src/gui/widgets/size_lock.hpp index 67cb0dda1cb5..e5e663879f8f 100644 --- a/src/gui/widgets/size_lock.hpp +++ b/src/gui/widgets/size_lock.hpp @@ -36,10 +36,7 @@ class size_lock : public container_base friend struct implementation::builder_size_lock; public: - size_lock() : - container_base(), - widget_(nullptr) - {} + explicit size_lock(const implementation::builder_size_lock& builder); /** See @ref control::get_active. */ bool get_active() const override diff --git a/src/gui/widgets/slider.cpp b/src/gui/widgets/slider.cpp index 49375bd9d6a2..fece4862aaa0 100644 --- a/src/gui/widgets/slider.cpp +++ b/src/gui/widgets/slider.cpp @@ -37,8 +37,8 @@ namespace gui2 REGISTER_WIDGET(slider) -slider::slider() - : scrollbar_base() +slider::slider(const implementation::builder_slider& builder) + : scrollbar_base(builder, get_control_type()) , best_slider_length_(0) , minimum_value_(0) , minimum_value_label_() @@ -487,15 +487,15 @@ builder_slider::builder_slider(const config& cfg) widget* builder_slider::build() const { - slider* widget = new slider(); - - init_control(widget); + slider* widget = new slider(*this); widget->set_best_slider_length(best_slider_length_); widget->set_maximum_value(maximum_value_); widget->set_minimum_value(minimum_value_); widget->set_step_size(step_size_); widget->set_value(value_); + + widget->finalize_setup(); if(!value_labels_.empty()) { VALIDATE(value_labels_.size() == widget->get_item_count(), diff --git a/src/gui/widgets/slider.hpp b/src/gui/widgets/slider.hpp index ce76e72db097..553f4d5ca4b0 100644 --- a/src/gui/widgets/slider.hpp +++ b/src/gui/widgets/slider.hpp @@ -22,14 +22,20 @@ namespace gui2 { +namespace implementation +{ +struct builder_slider; +} // ------------ WIDGET -----------{ /** A slider. */ class slider : public scrollbar_base, public integer_selector { + friend struct implementation::builder_slider; + public: - slider(); + explicit slider(const implementation::builder_slider& builder); /***** ***** ***** ***** layout functions ***** ***** ***** *****/ @@ -178,8 +184,8 @@ class slider : public scrollbar_base, public integer_selector tlabel_creator value_labels_; /** - * When initially pessing the positioner and every time a new value is chosen through dragging, - * this value is upda with the mouse position at the time. This allows the widget to track + * When initially pressing the positioner and every time a new value is chosen through dragging, + * this value is updated with the mouse position at the time. This allows the widget to track * how far the mouse has moved since setting the last value. */ point current_item_mouse_position_; diff --git a/src/gui/widgets/spacer.cpp b/src/gui/widgets/spacer.cpp index 788b9ba3abda..5cb8dbd649ac 100644 --- a/src/gui/widgets/spacer.cpp +++ b/src/gui/widgets/spacer.cpp @@ -28,6 +28,13 @@ namespace gui2 REGISTER_WIDGET(spacer) +spacer::spacer(const implementation::builder_spacer& builder, const std::string& w, const std::string& h) + : styled_widget(builder, get_control_type()) + , width_(w) + , height_(h) +{ +} + bool spacer::fills_available_space() { return (!width_.has_formula() && width_() == 0) && (!height_.has_formula() && height_() == 0); @@ -178,9 +185,7 @@ builder_spacer::builder_spacer(const config& cfg) widget* builder_spacer::build() const { - spacer* widget = new spacer(width_, height_); - - init_control(widget); + spacer* widget = new spacer(*this, width_, height_); DBG_GUI_G << "Window builder: placed spacer '" << id << "' with definition '" << definition << "'.\n"; diff --git a/src/gui/widgets/spacer.hpp b/src/gui/widgets/spacer.hpp index 4039a4de0659..792a8659b44f 100644 --- a/src/gui/widgets/spacer.hpp +++ b/src/gui/widgets/spacer.hpp @@ -22,6 +22,10 @@ namespace gui2 { +namespace implementation +{ +struct builder_spacer; +} // ------------ WIDGET -----------{ @@ -37,12 +41,7 @@ namespace gui2 class spacer : public styled_widget { public: - spacer(const std::string& w = "0", const std::string& h = "0") - : styled_widget() - , width_(w) - , height_(h) - { - } + spacer(const implementation::builder_spacer& builder, const std::string& w = "0", const std::string& h = "0"); /***** ***** ***** ***** layout functions ***** ***** ***** *****/ diff --git a/src/gui/widgets/stacked_widget.cpp b/src/gui/widgets/stacked_widget.cpp index 32f9d9dc6e84..1df890fc1f3b 100644 --- a/src/gui/widgets/stacked_widget.cpp +++ b/src/gui/widgets/stacked_widget.cpp @@ -33,8 +33,8 @@ namespace gui2 REGISTER_WIDGET(stacked_widget) -stacked_widget::stacked_widget() - : container_base() +stacked_widget::stacked_widget(const implementation::builder_stacked_widget& builder) + : container_base(builder, get_control_type()) , generator_(generator_base::build(false, false, generator_base::independent, false)) , selected_layer_(-1) { @@ -250,9 +250,7 @@ builder_stacked_widget::builder_stacked_widget(const config& real_cfg) widget* builder_stacked_widget::build() const { - stacked_widget* widget = new stacked_widget(); - - init_control(widget); + stacked_widget* widget = new stacked_widget(*this); DBG_GUI_G << "Window builder: placed stacked widget '" << id << "' with definition '" << definition << "'.\n"; diff --git a/src/gui/widgets/stacked_widget.hpp b/src/gui/widgets/stacked_widget.hpp index c56f21da7070..ca12fccac096 100644 --- a/src/gui/widgets/stacked_widget.hpp +++ b/src/gui/widgets/stacked_widget.hpp @@ -39,7 +39,7 @@ class stacked_widget : public container_base friend class debug_layout_graph; public: - stacked_widget(); + explicit stacked_widget(const implementation::builder_stacked_widget& builder); /***** ***** ***** inherited ***** ****** *****/ diff --git a/src/gui/widgets/styled_widget.cpp b/src/gui/widgets/styled_widget.cpp index e667cce2de9c..68b884084357 100644 --- a/src/gui/widgets/styled_widget.cpp +++ b/src/gui/widgets/styled_widget.cpp @@ -43,31 +43,6 @@ namespace gui2 // ------------ WIDGET -----------{ -styled_widget::styled_widget() - : definition_("default") - , label_() - , use_markup_(false) - , use_tooltip_on_label_overflow_(true) - , tooltip_() - , help_message_() - , canvas_() - , config_(nullptr) - , renderer_() - , text_maximum_width_(0) - , text_alignment_(PANGO_ALIGN_LEFT) - , text_ellipse_mode_(PANGO_ELLIPSIZE_END) - , shrunken_(false) -{ - connect_signal(std::bind( - &styled_widget::signal_handler_show_tooltip, this, _2, _3, _5)); - - connect_signal(std::bind( - &styled_widget::signal_handler_show_helptip, this, _2, _3, _5)); - - connect_signal(std::bind( - &styled_widget::signal_handler_notify_remove_tooltip, this, _2, _3)); -} - styled_widget::styled_widget(const implementation::builder_styled_widget& builder, const std::string& control_type) : widget(builder) @@ -296,16 +271,6 @@ void styled_widget::place(const point& origin, const point& size) update_canvas(); } -void styled_widget::load_config() -{ - if(!config()) { - - definition_load_configuration(get_control_type()); - - load_config_extra(); - } -} - widget* styled_widget::find_at(const point& coordinate, const bool must_be_active) { return (widget::find_at(coordinate, must_be_active) @@ -340,16 +305,6 @@ const widget* styled_widget::find(const std::string& id, const bool must_be_acti : nullptr; } -void styled_widget::set_definition(const std::string& definition) -{ - assert(!config()); - definition_ = definition; - load_config(); - assert(config()); - - init(); -} - void styled_widget::set_label(const t_string& label) { if(label == label_) { @@ -406,9 +361,16 @@ void styled_widget::update_canvas() canvas.set_variable("text", wfl::variant(label_)); canvas.set_variable("text_markup", wfl::variant(use_markup_)); canvas.set_variable("text_link_aware", wfl::variant(get_link_aware())); - // Possible TODO: Consider making a formula_callable for colours + + // Possible TODO: consider making a formula_callable for colors. color_t link_color = get_link_color(); - std::vector link_color_as_list{wfl::variant(link_color.r), wfl::variant(link_color.g), wfl::variant(link_color.b), wfl::variant(link_color.a)}; + std::vector link_color_as_list { + wfl::variant(link_color.r), + wfl::variant(link_color.g), + wfl::variant(link_color.b), + wfl::variant(link_color.a) + }; + canvas.set_variable("text_link_color", wfl::variant(link_color_as_list)); canvas.set_variable("text_alignment", wfl::variant(encode_text_alignment(text_alignment_))); @@ -706,22 +668,6 @@ builder_styled_widget::builder_styled_widget(const config& cfg) << "' and definition '" << definition << "'.\n"; } -void builder_styled_widget::init_control(styled_widget* control) const -{ - assert(control); - - control->set_id(id); - control->set_definition(definition); - control->set_linked_group(linked_group); - control->set_label(label_string); - control->set_tooltip(tooltip); - control->set_help_message(help); - control->set_use_tooltip_on_label_overflow(use_tooltip_on_label_overflow); - control->set_use_markup(use_markup); - control->set_debug_border_mode(debug_border_mode); - control->set_debug_border_color(debug_border_color); -} - widget* builder_styled_widget::build(const replacements_map& /*replacements*/) const { return build(); diff --git a/src/gui/widgets/styled_widget.hpp b/src/gui/widgets/styled_widget.hpp index 9b16728bb45f..4b6aacf5ff59 100644 --- a/src/gui/widgets/styled_widget.hpp +++ b/src/gui/widgets/styled_widget.hpp @@ -35,9 +35,6 @@ class styled_widget : public widget friend class debug_layout_graph; public: - /** @deprecated Used the second overload. */ - styled_widget(); - /** * Constructor. * @@ -186,18 +183,6 @@ class styled_widget : public widget /***** ***** ***** ***** Inherited ***** ***** ***** *****/ private: - /** - * Loads the configuration of the widget. - * - * Controls have their definition stored in a definition object. In order to - * determine sizes and drawing the widget this definition needs to be - * loaded. The member definition_ contains the name of the definition and - * function load the proper configuration. - * - * @deprecated @ref definition_load_configuration() is the replacement. - */ - void load_config(); - /** * Uses the load function. * @@ -223,17 +208,6 @@ class styled_widget : public widget const widget* find(const std::string& id, const bool must_be_active) const override; - /** - * Sets the definition. - * - * This function sets the definition of a styled_widget and should be called soon - * after creating the object since a lot of internal functions depend on the - * definition. - * - * This function should be called one time only!!! - */ - void set_definition(const std::string& definition); - /***** ***** ***** setters / getters for members ***** ****** *****/ bool get_use_tooltip_on_label_overflow() const { @@ -249,9 +223,11 @@ class styled_widget : public widget { return label_; } + virtual void set_label(const t_string& label); virtual void set_use_markup(bool use_markup); + bool get_use_markup() const { return use_markup_; @@ -293,6 +269,7 @@ class styled_widget : public widget } virtual void set_text_alignment(const PangoAlignment text_alignment); + PangoAlignment get_text_alignment() const { return text_alignment_; @@ -334,7 +311,8 @@ class styled_widget : public widget std::shared_ptr cast_config_to() const { static_assert(std::is_base_of::value, - "Given type's resolution object does not derive from resolution_definition."); + "Given type's resolution object does not derive from resolution_definition." + ); return std::static_pointer_cast(config()); } @@ -430,16 +408,6 @@ class styled_widget : public widget */ resolution_definition_ptr config_; - /** - * Load class dependent config settings. - * - * load_config will call this method after loading the config, by default it - * does nothing but classes can override it to implement custom behavior. - */ - virtual void load_config_extra() - { - } - /** * Loads the configuration of the widget. * @@ -479,19 +447,6 @@ class styled_widget : public widget std::string get_label_link(const gui2::point & position) const; private: - /** - * Allows derived classes to implement initialization steps after the config and - * canvases have been loaded. - * - * Another area this is useful is for initialization making use of virtual functions, - * which can't be used in a constructor. - * - * This function should only be called once. - */ - virtual void init() - { - } - /** * Gets the best size for a text. * @@ -568,9 +523,6 @@ struct builder_styled_widget : public builder_widget virtual widget* build(const replacements_map& replacements) const override; - /** @deprecated The styled_widget can initialize itself. */ - void init_control(styled_widget* styled_widget) const; - /** Parameters for the styled_widget. */ std::string definition; t_string label_string; diff --git a/src/gui/widgets/text_box.cpp b/src/gui/widgets/text_box.cpp index 310b563328cc..42369d59e773 100644 --- a/src/gui/widgets/text_box.cpp +++ b/src/gui/widgets/text_box.cpp @@ -95,8 +95,8 @@ std::string text_history::get_value() const } } -text_box::text_box() - : text_box_base() +text_box::text_box(const implementation::builder_styled_widget& builder) + : text_box_base(builder, get_control_type()) , history_() , max_input_length_(0) , text_x_offset_(0) @@ -114,6 +114,8 @@ text_box::text_box() &text_box::signal_handler_left_button_up, this, _2, _3)); connect_signal(std::bind( &text_box::signal_handler_left_button_double_click, this, _2, _3)); + + update_offsets(); } void text_box::place(const point& origin, const point& size) @@ -333,19 +335,6 @@ void text_box::handle_key_clear_line(SDL_Keymod /*modifier*/, bool& handled) set_value(""); } -void text_box::load_config_extra() -{ - assert(config()); - - const auto conf = cast_config_to(); - assert(conf); - - set_font_size(conf->text_font_size); - set_font_style(conf->text_font_style); - - update_offsets(); -} - const std::string& text_box::get_control_type() const { static const std::string type = "text_box"; @@ -494,9 +483,7 @@ builder_text_box::builder_text_box(const config& cfg) widget* builder_text_box::build() const { - text_box* widget = new text_box(); - - init_control(widget); + text_box* widget = new text_box(*this); // A textbox doesn't have a label but a text widget->set_value(label_string); @@ -507,6 +494,12 @@ widget* builder_text_box::build() const widget->set_max_input_length(max_input_length); + const auto conf = widget->cast_config_to(); + assert(conf); + + widget->set_font_size(conf->text_font_size); + widget->set_font_style(conf->text_font_style); + DBG_GUI_G << "Window builder: placed text box '" << id << "' with definition '" << definition << "'.\n"; diff --git a/src/gui/widgets/text_box.hpp b/src/gui/widgets/text_box.hpp index 390c3967a202..1b1789ed8b00 100644 --- a/src/gui/widgets/text_box.hpp +++ b/src/gui/widgets/text_box.hpp @@ -18,6 +18,10 @@ namespace gui2 { +namespace implementation +{ +struct builder_text_box; +} // ------------ WIDGET -----------{ @@ -116,8 +120,10 @@ class text_history /** Class for a single line text area. */ class text_box : public text_box_base { + friend struct implementation::builder_text_box; + public: - text_box(); + explicit text_box(const implementation::builder_styled_widget& builder); /** Saves the text in the widget to the history. */ void save_to_history() @@ -255,9 +261,6 @@ class text_box : public text_box_base /** See @ref styled_widget::get_control_type. */ virtual const std::string& get_control_type() const override; - /** Inherited from styled_widget. */ - void load_config_extra() override; - /***** ***** ***** signal handlers ***** ****** *****/ void signal_handler_mouse_motion(const event::ui_event event, diff --git a/src/gui/widgets/text_box_base.cpp b/src/gui/widgets/text_box_base.cpp index 487caf7e64e1..bd96a0729477 100644 --- a/src/gui/widgets/text_box_base.cpp +++ b/src/gui/widgets/text_box_base.cpp @@ -32,8 +32,8 @@ namespace gui2 { -text_box_base::text_box_base() - : styled_widget() +text_box_base::text_box_base(const implementation::builder_styled_widget& builder, const std::string& control_type) + : styled_widget(builder, control_type) , state_(ENABLED) , text_() , selection_start_(0) diff --git a/src/gui/widgets/text_box_base.hpp b/src/gui/widgets/text_box_base.hpp index d0247c39bd8e..7cbe9b08c95c 100644 --- a/src/gui/widgets/text_box_base.hpp +++ b/src/gui/widgets/text_box_base.hpp @@ -24,6 +24,10 @@ namespace gui2 { +namespace implementation +{ + struct builder_styled_widget; +} /** * Abstract base class for text items. @@ -43,7 +47,7 @@ class text_box_base : public styled_widget { public: - text_box_base(); + text_box_base(const implementation::builder_styled_widget& builder, const std::string& control_type); ~text_box_base(); diff --git a/src/gui/widgets/toggle_button.cpp b/src/gui/widgets/toggle_button.cpp index b5e57c556c5e..40b7039dba5e 100644 --- a/src/gui/widgets/toggle_button.cpp +++ b/src/gui/widgets/toggle_button.cpp @@ -36,8 +36,8 @@ namespace gui2 REGISTER_WIDGET(toggle_button) -toggle_button::toggle_button() - : styled_widget() +toggle_button::toggle_button(const implementation::builder_toggle_button& builder) + : styled_widget(builder, get_control_type()) , state_(ENABLED) , state_num_(0) , retval_(0) @@ -290,9 +290,7 @@ builder_toggle_button::builder_toggle_button(const config& cfg) widget* builder_toggle_button::build() const { - toggle_button* widget = new toggle_button(); - - init_control(widget); + toggle_button* widget = new toggle_button(*this); widget->set_icon_name(icon_name_); widget->set_retval(get_retval(retval_id_, retval_, id)); diff --git a/src/gui/widgets/toggle_button.hpp b/src/gui/widgets/toggle_button.hpp index 2200d4f65a57..bae322579845 100644 --- a/src/gui/widgets/toggle_button.hpp +++ b/src/gui/widgets/toggle_button.hpp @@ -19,6 +19,10 @@ namespace gui2 { +namespace implementation +{ + struct builder_toggle_button; +} // ------------ WIDGET -----------{ @@ -31,7 +35,7 @@ namespace gui2 class toggle_button : public styled_widget, public selectable_item { public: - toggle_button(); + explicit toggle_button(const implementation::builder_toggle_button& builder); /***** ***** ***** ***** Inherited ***** ***** ***** *****/ diff --git a/src/gui/widgets/toggle_panel.cpp b/src/gui/widgets/toggle_panel.cpp index 62fe488bd571..1606b5dbba5e 100644 --- a/src/gui/widgets/toggle_panel.cpp +++ b/src/gui/widgets/toggle_panel.cpp @@ -37,8 +37,8 @@ namespace gui2 REGISTER_WIDGET(toggle_panel) -toggle_panel::toggle_panel() - : panel() +toggle_panel::toggle_panel(const implementation::builder_toggle_panel& builder) + : panel(builder, get_control_type()) , state_(ENABLED) , state_num_(0) , retval_(0) @@ -419,9 +419,7 @@ builder_toggle_panel::builder_toggle_panel(const config& cfg) widget* builder_toggle_panel::build() const { - toggle_panel* widget = new toggle_panel(); - - init_control(widget); + toggle_panel* widget = new toggle_panel(*this); widget->set_retval(get_retval(retval_id_, retval_, id)); diff --git a/src/gui/widgets/toggle_panel.hpp b/src/gui/widgets/toggle_panel.hpp index 6c1ea60078ba..468a9fde1679 100644 --- a/src/gui/widgets/toggle_panel.hpp +++ b/src/gui/widgets/toggle_panel.hpp @@ -20,6 +20,11 @@ namespace gui2 { +namespace implementation +{ +struct builder_toggle_panel; +} + // ------------ WIDGET -----------{ /** @@ -33,7 +38,7 @@ namespace gui2 class toggle_panel : public panel, public selectable_item { public: - toggle_panel(); + explicit toggle_panel(const implementation::builder_toggle_panel& builder); /** * Sets the members of the child controls. diff --git a/src/gui/widgets/tree_view.cpp b/src/gui/widgets/tree_view.cpp index eb6a4db78c28..3b1abd417c74 100644 --- a/src/gui/widgets/tree_view.cpp +++ b/src/gui/widgets/tree_view.cpp @@ -37,9 +37,9 @@ namespace gui2 REGISTER_WIDGET(tree_view) -tree_view::tree_view(const std::vector& node_definitions) - : scrollbar_container() - , node_definitions_(node_definitions) +tree_view::tree_view(const implementation::builder_tree_view& builder) + : scrollbar_container(builder, get_control_type()) + , node_definitions_(builder.nodes) , indentation_step_size_(0) , need_layout_(false) , root_node_(new tree_view_node("root", @@ -398,9 +398,7 @@ widget* builder_tree_view::build() const * TODO see how much we can move in the constructor instead of * building in several steps. */ - tree_view* widget = new tree_view(nodes); - - init_control(widget); + tree_view* widget = new tree_view(*this); widget->set_vertical_scrollbar_mode(vertical_scrollbar_mode); widget->set_horizontal_scrollbar_mode(horizontal_scrollbar_mode); diff --git a/src/gui/widgets/tree_view.hpp b/src/gui/widgets/tree_view.hpp index abd0035d47ca..9b7170b38c32 100644 --- a/src/gui/widgets/tree_view.hpp +++ b/src/gui/widgets/tree_view.hpp @@ -43,7 +43,7 @@ class tree_view : public scrollbar_container public: typedef implementation::tree_node node_definition; - explicit tree_view(const std::vector& node_definitions); + explicit tree_view(const implementation::builder_tree_view& builder); ~tree_view(); diff --git a/src/gui/widgets/unit_preview_pane.cpp b/src/gui/widgets/unit_preview_pane.cpp index 8da25ad09768..cc5d7eaef5f7 100644 --- a/src/gui/widgets/unit_preview_pane.cpp +++ b/src/gui/widgets/unit_preview_pane.cpp @@ -62,6 +62,22 @@ namespace gui2 REGISTER_WIDGET(unit_preview_pane) +unit_preview_pane::unit_preview_pane(const implementation::builder_unit_preview_pane& builder) + : container_base(builder, get_control_type()) + , current_type_() + , icon_type_(nullptr) + , icon_race_(nullptr) + , icon_alignment_(nullptr) + , label_name_(nullptr) + , label_level_(nullptr) + , label_race_(nullptr) + , label_details_(nullptr) + , tree_details_(nullptr) + , button_profile_(nullptr) + , image_mods_() +{ +} + void unit_preview_pane::finalize_setup() { // Icons @@ -588,9 +604,7 @@ builder_unit_preview_pane::builder_unit_preview_pane(const config& cfg) widget* builder_unit_preview_pane::build() const { - unit_preview_pane* widget = new unit_preview_pane(); - - init_control(widget); + unit_preview_pane* widget = new unit_preview_pane(*this); DBG_GUI_G << "Window builder: placed unit preview pane '" << id << "' with definition '" << definition << "'.\n"; diff --git a/src/gui/widgets/unit_preview_pane.hpp b/src/gui/widgets/unit_preview_pane.hpp index 86f59793c8db..4ae972f95670 100644 --- a/src/gui/widgets/unit_preview_pane.hpp +++ b/src/gui/widgets/unit_preview_pane.hpp @@ -41,21 +41,7 @@ class unit_preview_pane : public container_base friend struct implementation::builder_unit_preview_pane; public: - unit_preview_pane() - : container_base() - , current_type_() - , icon_type_(nullptr) - , icon_race_(nullptr) - , icon_alignment_(nullptr) - , label_name_(nullptr) - , label_level_(nullptr) - , label_race_(nullptr) - , label_details_(nullptr) - , tree_details_(nullptr) - , button_profile_(nullptr) - , image_mods_() - { - } + explicit unit_preview_pane(const implementation::builder_unit_preview_pane& builder); /** Displays the stats of a specified unit type */ void set_displayed_type(const unit_type& type); diff --git a/src/gui/widgets/vertical_scrollbar.cpp b/src/gui/widgets/vertical_scrollbar.cpp index 671ce6b0b54d..f18fa1c959ad 100644 --- a/src/gui/widgets/vertical_scrollbar.cpp +++ b/src/gui/widgets/vertical_scrollbar.cpp @@ -28,6 +28,11 @@ namespace gui2 REGISTER_WIDGET(vertical_scrollbar) +vertical_scrollbar::vertical_scrollbar(const implementation::builder_vertical_scrollbar& builder) + : scrollbar_base(builder, get_control_type()) +{ +} + unsigned vertical_scrollbar::minimum_positioner_length() const { const auto conf = cast_config_to(); @@ -197,9 +202,9 @@ builder_vertical_scrollbar::builder_vertical_scrollbar(const config& cfg) widget* builder_vertical_scrollbar::build() const { - vertical_scrollbar* widget = new vertical_scrollbar(); + vertical_scrollbar* widget = new vertical_scrollbar(*this); - init_control(widget); + widget->finalize_setup(); DBG_GUI_G << "Window builder:" << " placed vertical scrollbar '" << id << "' with definition '" diff --git a/src/gui/widgets/vertical_scrollbar.hpp b/src/gui/widgets/vertical_scrollbar.hpp index efd1ca2eeafc..521d36dfc8fe 100644 --- a/src/gui/widgets/vertical_scrollbar.hpp +++ b/src/gui/widgets/vertical_scrollbar.hpp @@ -18,16 +18,20 @@ namespace gui2 { +namespace implementation +{ +struct builder_vertical_scrollbar; +} // ------------ WIDGET -----------{ /** A vertical scrollbar. */ class vertical_scrollbar : public scrollbar_base { + friend struct implementation::builder_vertical_scrollbar; + public: - vertical_scrollbar() : scrollbar_base() - { - } + explicit vertical_scrollbar(const implementation::builder_vertical_scrollbar& builder); private: /** Inherited from tscrollbar. */ diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp index 76c92da93ca7..ba222467b5df 100644 --- a/src/gui/widgets/window.cpp +++ b/src/gui/widgets/window.cpp @@ -304,7 +304,7 @@ window::window(CVideo& video, const std::string& definition, const builder_window::window_resolution::tooltip_info& tooltip, const builder_window::window_resolution::tooltip_info& helptip) - : panel() + : panel(implementation::builder_window(::config {"definition", definition->definition}), get_control_type()) , cursor::setter(cursor::NORMAL) , video_(video) , status_(NEW) @@ -344,11 +344,6 @@ window::window(CVideo& video, , exit_hook_([](window&)->bool { return true; }) , callback_next_draw_(nullptr) { - // We load the config in here as exception. - // Our caller did update the screen size so no need for us to do that again. - set_definition(definition); - load_config(); - manager::instance().add(*this); connect();