multi_window/
multi_window.rs

1use gtk::prelude::*;
2use relm4::prelude::*;
3
4struct App {
5    counter: u8,
6}
7
8#[derive(Debug)]
9enum Msg {
10    Increment,
11    Decrement,
12    NewWindow,
13}
14
15#[relm4::component]
16impl SimpleComponent for App {
17    type Init = u8;
18    type Input = Msg;
19    type Output = ();
20
21    view! {
22        gtk::Window {
23            set_title: Some("Simple app"),
24            set_default_size: (300, 100),
25            // This is necessary to make new windows visible
26            set_visible: true,
27
28            gtk::Box {
29                set_orientation: gtk::Orientation::Vertical,
30                set_spacing: 5,
31                set_margin_all: 5,
32
33                gtk::Button {
34                    set_label: "New window",
35                    connect_clicked => Msg::NewWindow,
36                },
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 {
49                    #[watch]
50                    set_label: &format!("Counter: {}", model.counter),
51                    set_margin_all: 5,
52                }
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 model = App { counter };
64
65        // Insert the code generation of the view! macro here
66        let widgets = view_output!();
67
68        ComponentParts { model, widgets }
69    }
70
71    fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
72        match msg {
73            Msg::Increment => {
74                self.counter = self.counter.wrapping_add(1);
75            }
76            Msg::Decrement => {
77                self.counter = self.counter.wrapping_sub(1);
78            }
79            Msg::NewWindow => {
80                let app = relm4::main_application();
81                let builder = Self::builder();
82
83                // Add window to the GTK application.
84                // This ensures that the app will live as long
85                // as at least one window exists.
86                app.add_window(&builder.root);
87
88                builder.launch(self.counter).detach_runtime();
89            }
90        }
91    }
92}
93
94fn main() {
95    let app = RelmApp::new("relm4.example.multi_window");
96    app.run::<App>(0);
97}