From 4e81236ca05c9d7341d7e85e02a3e9586ba226e6 Mon Sep 17 00:00:00 2001 From: Charles Dang Date: Sun, 20 Aug 2017 14:42:47 +1100 Subject: [PATCH] GUI2/Window Builder: added function to generate a single widget instance with its builder This will be used in some upcoming changes. The main benefit of this over directly initializing a new widget object is any extra builder steps can also be executed. I'm not entirely happy with the design, though, especially with having to specify both the type and type ID... --- src/gui/core/window_builder.cpp | 9 +++++++++ src/gui/core/window_builder.hpp | 26 +++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/gui/core/window_builder.cpp b/src/gui/core/window_builder.cpp index 67d516e247a5..74429ae061a5 100644 --- a/src/gui/core/window_builder.cpp +++ b/src/gui/core/window_builder.cpp @@ -219,6 +219,15 @@ builder_widget_ptr create_builder_widget(const config& cfg) FAIL("Unknown widget type " + cfg.ordered_begin()->key); } +widget* build_single_widget_instance_helper(const std::string& type, const config& cfg) +{ + const auto& iter = builder_widget_lookup().find(type); + VALIDATE(iter != builder_widget_lookup().end(), "Invalid widget type '" + type + "'"); + + widget_builder_func_t& builder = iter->second; + return builder(cfg)->build(); +} + /*WIKI * @page = GUIToolkitWML * @order = 1_window diff --git a/src/gui/core/window_builder.hpp b/src/gui/core/window_builder.hpp index 604b7c517e75..2909ab0cfc1e 100644 --- a/src/gui/core/window_builder.hpp +++ b/src/gui/core/window_builder.hpp @@ -87,7 +87,6 @@ using widget_builder_func_t = std::function; void register_builder_widget(const std::string& id, widget_builder_func_t functor); - /** * Create a widget builder. * @@ -116,6 +115,31 @@ builder_widget_ptr build_widget(const config& cfg) return std::make_shared(cfg); } +/** + * Helper function to implement @ref build_single_widget_instance. This keeps the main + * logic in the implementation despite said function being a template and therefor + * needing to be fully implemented in the declaration. + */ +widget* build_single_widget_instance_helper(const std::string& type, const config& cfg); + +/** + * Builds a single widget instance of the given type with the specified attributes. + * + * This should be used in place of creating a widget object directly, as it + * allows the widget-specific builder code to be executed. + * + * @tparam The final widget type. The widget pointer will be + * cast to this. + * + * @param type String ID of the widget type. + * @param cfg Data config to pass to the widget's builder. + */ +template +T* build_single_widget_instance(const std::string& type, const config& cfg = config()) +{ + return dynamic_cast(build_single_widget_instance_helper(type, cfg)); +} + struct builder_grid : public builder_widget { public: