widget_template/
widget_template.rs1use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt};
2use relm4::{
3 ComponentParts, ComponentSender, RelmApp, RelmWidgetExt, SimpleComponent, WidgetTemplate,
4};
5
6#[relm4::widget_template]
7impl WidgetTemplate for MyBox {
8 view! {
9 gtk::Box {
10 set_margin_all: 10,
11 inline_css: "border: 2px solid blue",
13 }
14 }
15}
16
17#[relm4::widget_template]
18impl WidgetTemplate for MySpinner {
19 view! {
20 gtk::Spinner {
21 set_spinning: true,
22 }
23 }
24}
25
26#[relm4::widget_template]
27impl WidgetTemplate for MyWindow {
28 view! {
29 gtk::Window {
30 set_title: Some("Widget template"),
31 set_default_width: 300,
32 set_default_height: 100,
33 }
34 }
35}
36
37#[relm4::widget_template]
38impl WidgetTemplate for CustomBox {
39 view! {
40 gtk::Box {
41 set_orientation: gtk::Orientation::Vertical,
42 set_margin_all: 5,
43 set_spacing: 5,
44
45 #[template]
46 MyBox {
47 #[template]
48 MySpinner,
49
50 #[template]
51 MyBox {
52 #[template]
53 MySpinner,
54
55 #[template]
56 MyBox {
57 #[template]
58 MySpinner,
59
60 #[name = "child_label"]
62 gtk::Label {
63 set_label: "This is a test",
64 }
65 }
66 }
67 }
68 }
69 }
70}
71
72#[derive(Default)]
73struct AppModel {
74 counter: u8,
75}
76
77#[derive(Debug)]
78enum AppMsg {
79 Increment,
80 Decrement,
81}
82
83#[relm4::component]
84impl SimpleComponent for AppModel {
85 type Init = u8;
86 type Input = AppMsg;
87 type Output = ();
88
89 view! {
90 #[template]
91 MyWindow {
92 #[template]
93 CustomBox {
94 #[template_child]
95 child_label {
96 #[watch]
97 set_label: &format!("Counter: {}", model.counter),
98 },
99 gtk::Button {
100 set_label: "Increment",
101 connect_clicked[sender] => move |_| {
102 sender.input(AppMsg::Increment);
103 },
104 },
105 gtk::Button {
106 set_label: "Decrement",
107 connect_clicked[sender] => move |_| {
108 sender.input(AppMsg::Decrement);
109 },
110 },
111 },
112 }
113 }
114
115 fn init(
116 counter: Self::Init,
117 root: Self::Root,
118 sender: ComponentSender<Self>,
119 ) -> ComponentParts<Self> {
120 let model = Self { counter };
121
122 let widgets = view_output!();
123
124 ComponentParts { model, widgets }
125 }
126
127 fn update(&mut self, msg: AppMsg, _sender: ComponentSender<Self>) {
128 match msg {
129 AppMsg::Increment => {
130 self.counter = self.counter.wrapping_add(1);
131 }
132 AppMsg::Decrement => {
133 self.counter = self.counter.wrapping_sub(1);
134 }
135 }
136 }
137}
138
139fn main() {
140 let app = RelmApp::new("relm4.example.widget_template");
141 app.run::<AppModel>(0);
142}