1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
/*
* SPDX-FileCopyrightText: 2025 Felix Morgner <felix.morgner@gmail.com>
* SPDX-License-Identifier: LGPL-2.1-only
*/
#ifndef TURNS_UI_TEMPLATE_WIDGET_HPP
#define TURNS_UI_TEMPLATE_WIDGET_HPP
#include <glib-object.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <glibmm/extraclassinit.h>
#include <glibmm/ustring.h>
#include <glibmm/wrap.h>
#include <gtkmm/widget.h>
#include <algorithm>
#include <utility>
namespace Turns::gui
{
template<typename CustomWidgetType, typename BaseWidgetType>
struct template_widget : Glib::ExtraClassInit,
BaseWidgetType
{
template<typename... BaseWidgetCtorArgTypes>
template_widget(Glib::ustring && resource_path, BaseWidgetCtorArgTypes &&... base_widget_ctor_args)
: Glib::ExtraClassInit{class_init, &resource_path, instance_init}
, BaseWidgetType{std::forward<BaseWidgetCtorArgTypes>(base_widget_ctor_args)...}
{
}
template<typename WidgetType = Gtk::Widget>
auto get_widget(char const * name) -> WidgetType *
{
auto self = static_cast<CustomWidgetType *>(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<WidgetType *>(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<Glib::ustring const *>(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
|