/* * SPDX-FileCopyrightText: 2025 Felix Morgner * SPDX-License-Identifier: LGPL-2.1-only */ #ifndef TURNS_UI_TEMPLATE_WIDGET_HPP #define TURNS_UI_TEMPLATE_WIDGET_HPP #include #include #include #include #include #include #include #include #include namespace Turns::gui { template struct template_widget : Glib::ExtraClassInit, BaseWidgetType { template template_widget(Glib::ustring && resource_path, BaseWidgetCtorArgTypes &&... base_widget_ctor_args) : Glib::ExtraClassInit{class_init, &resource_path, instance_init} , BaseWidgetType{std::forward(base_widget_ctor_args)...} { } protected: template auto get_widget(char const * name) -> WidgetType * { auto self = static_cast(this); auto widget = GTK_WIDGET(Glib::unwrap(self)); auto type = G_OBJECT_TYPE(Glib::unwrap(self)); auto child = GTK_WIDGET(gtk_widget_get_template_child(widget, type, name)); g_assert_nonnull(child); return dynamic_cast(Glib::wrap(child)); } private: auto static class_init(void * g_class, void * g_class_data) -> void { g_return_if_fail(GTK_IS_WIDGET_CLASS(g_class)); auto resource_path = static_cast(g_class_data); gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(g_class), resource_path->c_str()); std::ranges::for_each(CustomWidgetType::children, [g_class](auto const & child) { gtk_widget_class_bind_template_child_full(GTK_WIDGET_CLASS(g_class), child, false, 0); }); } auto static instance_init(GTypeInstance * instance, void * /* type_class */) -> void { g_return_if_fail(GTK_IS_WIDGET(instance)); gtk_widget_init_template(GTK_WIDGET(instance)); } }; } // namespace Turns::gui #endif