data_binding/
data_binding.rs

1use gtk::prelude::*;
2use relm4::{
3    RelmObjectExt,
4    binding::{Binding, BoolBinding, ConnectBindingExt, F64Binding, StringBinding},
5    prelude::*,
6};
7
8struct App {
9    counter: u8,
10    value: BoolBinding,
11    left_margin: F64Binding,
12    text: StringBinding,
13}
14
15#[derive(Debug)]
16enum Msg {
17    Increment,
18    Decrement,
19}
20
21#[relm4::component]
22impl SimpleComponent for App {
23    type Init = u8;
24    type Input = Msg;
25    type Output = ();
26
27    view! {
28        gtk::Window {
29            set_title: Some("Simple app"),
30            set_default_size: (300, 100),
31            add_binding: (&model.left_margin, "margin-start"),
32
33            gtk::Box {
34                set_orientation: gtk::Orientation::Vertical,
35                set_spacing: 5,
36                set_margin_all: 5,
37
38                gtk::Button {
39                    set_label: "Increment",
40                    connect_clicked => Msg::Increment,
41                },
42
43                gtk::Button {
44                    set_label: "Decrement",
45                    connect_clicked => Msg::Decrement,
46                },
47
48                gtk::Label::with_binding(&model.text) {
49                    set_margin_all: 5,
50                },
51
52                gtk::ToggleButton::with_binding(&model.value) { }
53            }
54        }
55    }
56
57    // Initialize the component.
58    fn init(
59        counter: Self::Init,
60        root: Self::Root,
61        sender: ComponentSender<Self>,
62    ) -> ComponentParts<Self> {
63        let value = BoolBinding::default();
64        let left_margin = F64Binding::default();
65        let text = StringBinding::new("Counter: 0");
66        let model = App {
67            counter,
68            value,
69            left_margin,
70            text,
71        };
72
73        // Insert the code generation of the view! macro here
74        let widgets = view_output!();
75
76        ComponentParts { model, widgets }
77    }
78
79    fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
80        let mut value = self.value.guard();
81        println!("Value: {}", *value);
82
83        let mut margin_left = self.left_margin.guard();
84
85        match msg {
86            Msg::Increment => {
87                *value = false;
88                *margin_left += 1.7;
89                self.counter = self.counter.wrapping_add(1);
90            }
91            Msg::Decrement => {
92                *value = true;
93                self.counter = self.counter.wrapping_sub(1);
94            }
95        }
96
97        *self.text.guard() = format!("Counter: {}", self.counter);
98    }
99}
100
101fn main() {
102    let app = RelmApp::new("relm4.example.simple");
103    app.run::<App>(0);
104}