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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use gtk::prelude::*;
use relm4::{
    binding::{Binding, BoolBinding, ConnectBindingExt, F64Binding, StringBinding},
    prelude::*,
    RelmObjectExt,
};

struct App {
    counter: u8,
    value: BoolBinding,
    left_margin: F64Binding,
    text: StringBinding,
}

#[derive(Debug)]
enum Msg {
    Increment,
    Decrement,
}

#[relm4::component]
impl SimpleComponent for App {
    type Init = u8;
    type Input = Msg;
    type Output = ();

    view! {
        gtk::Window {
            set_title: Some("Simple app"),
            set_default_size: (300, 100),
            add_binding: (&model.left_margin, "margin-start"),

            gtk::Box {
                set_orientation: gtk::Orientation::Vertical,
                set_spacing: 5,
                set_margin_all: 5,

                gtk::Button {
                    set_label: "Increment",
                    connect_clicked => Msg::Increment,
                },

                gtk::Button {
                    set_label: "Decrement",
                    connect_clicked => Msg::Decrement,
                },

                gtk::Label::with_binding(&model.text) {
                    set_margin_all: 5,
                },

                gtk::ToggleButton::with_binding(&model.value) { }
            }
        }
    }

    // Initialize the component.
    fn init(
        counter: Self::Init,
        root: Self::Root,
        sender: ComponentSender<Self>,
    ) -> ComponentParts<Self> {
        let value = BoolBinding::default();
        let left_margin = F64Binding::default();
        let text = StringBinding::new("Counter: 0");
        let model = App {
            counter,
            value,
            left_margin,
            text,
        };

        // Insert the code generation of the view! macro here
        let widgets = view_output!();

        ComponentParts { model, widgets }
    }

    fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
        let mut value = self.value.guard();
        println!("Value: {}", *value);

        let mut margin_left = self.left_margin.guard();

        match msg {
            Msg::Increment => {
                *value = false;
                *margin_left += 1.7;
                self.counter = self.counter.wrapping_add(1);
            }
            Msg::Decrement => {
                *value = true;
                self.counter = self.counter.wrapping_sub(1);
            }
        }

        *self.text.guard() = format!("Counter: {}", self.counter);
    }
}

fn main() {
    let app = RelmApp::new("relm4.example.simple");
    app.run::<App>(0);
}