toast/
toast.rs

1use gtk::prelude::*;
2use relm4::{abstractions::Toaster, prelude::*};
3
4struct App {
5    activated: &'static str,
6    toaster: Toaster,
7}
8
9#[derive(Debug)]
10enum Msg {
11    Activate,
12    Cancel,
13}
14
15#[relm4::component]
16impl SimpleComponent for App {
17    type Init = ();
18    type Input = Msg;
19    type Output = ();
20
21    view! {
22        adw::Window {
23            set_title: Some("Simple app"),
24            set_default_size: (300, 200),
25
26            gtk::Box {
27                set_orientation: gtk::Orientation::Vertical,
28
29                adw::HeaderBar {
30                    #[wrap(Some)]
31                    set_title_widget = &adw::WindowTitle {
32                        set_title: "Toast",
33                    }
34                },
35
36                #[local_ref]
37                toast_overlay -> adw::ToastOverlay {
38                    set_vexpand: true,
39                    gtk::Box {
40                        set_orientation: gtk::Orientation::Vertical,
41                        set_spacing: 5,
42                        set_margin_all: 5,
43                        set_valign: gtk::Align::Center,
44
45                        gtk::Button {
46                            set_hexpand: false,
47                            set_vexpand: false,
48                            set_label: "Activate",
49                            connect_clicked => Msg::Activate,
50                        },
51                        gtk::Button {
52                            set_hexpand: false,
53                            set_vexpand: false,
54                            set_label: "Cancel",
55                            connect_clicked => Msg::Cancel,
56                        },
57                        gtk::Text {
58                            #[watch]
59                            set_text: model.activated,
60                        },
61                    },
62                }
63            }
64
65        }
66    }
67
68    // Initialize the component.
69    fn init(
70        _: Self::Init,
71        root: Self::Root,
72        sender: ComponentSender<Self>,
73    ) -> ComponentParts<Self> {
74        let model = App {
75            activated: "Idle",
76            toaster: Toaster::default(),
77        };
78
79        let toast_overlay = model.toaster.overlay_widget();
80
81        // Insert the code generation of the view! macro here
82        let widgets = view_output!();
83
84        ComponentParts { model, widgets }
85    }
86
87    fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
88        match msg {
89            Msg::Activate => {
90                self.activated = "Active";
91                let toast = adw::Toast::builder()
92                    .title("Activated")
93                    .button_label("Cancel")
94                    .timeout(0)
95                    .build();
96                toast.connect_button_clicked(move |this| {
97                    this.dismiss();
98                    sender.input(Msg::Cancel);
99                });
100                self.toaster.add_toast(toast);
101            }
102            Msg::Cancel => self.activated = "Idle",
103        }
104    }
105}
106
107fn main() {
108    let app = RelmApp::new("relm4.example.toast");
109    app.run::<App>(());
110}