simple_async/
simple_async.rs1use std::time::Duration;
2
3use gtk::prelude::*;
4use relm4::{
5 RelmApp, RelmWidgetExt,
6 component::{AsyncComponent, AsyncComponentParts, AsyncComponentSender},
7 loading_widgets::LoadingWidgets,
8 view,
9};
10
11struct AppModel {
12 counter: u8,
13}
14
15#[derive(Debug)]
16enum AppMsg {
17 Increment,
18 Decrement,
19}
20
21#[relm4::component(async)]
22impl AsyncComponent for AppModel {
23 type Init = u8;
24 type Input = AppMsg;
25 type Output = ();
26 type CommandOutput = ();
27
28 view! {
29 gtk::Window {
30 gtk::Box {
31 set_orientation: gtk::Orientation::Vertical,
32 set_spacing: 5,
33 set_margin_all: 5,
34
35 gtk::Button {
36 set_label: "Increment",
37 connect_clicked => AppMsg::Increment,
38 },
39
40 gtk::Button {
41 set_label: "Decrement",
42 connect_clicked => AppMsg::Decrement,
43 },
44
45 gtk::Label {
46 #[watch]
47 set_label: &format!("Counter: {}", model.counter),
48 set_margin_all: 5,
49 }
50 }
51 }
52 }
53
54 fn init_loading_widgets(root: Self::Root) -> Option<LoadingWidgets> {
55 view! {
56 #[local]
57 root {
58 set_title: Some("Simple app"),
59 set_default_size: (300, 100),
60
61 #[name(spinner)]
64 gtk::Spinner {
65 start: (),
66 set_halign: gtk::Align::Center,
67 }
68 }
69 }
70 Some(LoadingWidgets::new(root, spinner))
71 }
72
73 async fn init(
75 counter: Self::Init,
76 root: Self::Root,
77 sender: AsyncComponentSender<Self>,
78 ) -> AsyncComponentParts<Self> {
79 tokio::time::sleep(Duration::from_secs(1)).await;
80
81 let model = AppModel { counter };
82
83 let widgets = view_output!();
85
86 AsyncComponentParts { model, widgets }
87 }
88
89 async fn update(
90 &mut self,
91 msg: Self::Input,
92 _sender: AsyncComponentSender<Self>,
93 _root: &Self::Root,
94 ) {
95 tokio::time::sleep(Duration::from_secs(1)).await;
96 match msg {
97 AppMsg::Increment => {
98 self.counter = self.counter.wrapping_add(1);
99 }
100 AppMsg::Decrement => {
101 self.counter = self.counter.wrapping_sub(1);
102 }
103 }
104 }
105}
106
107fn main() {
108 let app = RelmApp::new("relm4.example.simple_async");
109 app.run_async::<AppModel>(0);
110}