use std::time::Duration;
use gtk::prelude::*;
use relm4::{
component::{AsyncComponent, AsyncComponentParts, AsyncComponentSender},
loading_widgets::LoadingWidgets,
view, RelmApp, RelmWidgetExt,
};
struct App {
counter: u8,
}
#[derive(Debug)]
enum Msg {
Increment,
Decrement,
}
#[relm4::component(async)]
impl AsyncComponent for App {
type Init = u8;
type Input = Msg;
type Output = ();
type CommandOutput = ();
view! {
gtk::Window {
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 {
#[watch]
set_label: &format!("Counter: {}", model.counter),
set_margin_all: 5,
}
}
}
}
fn init_loading_widgets(root: Self::Root) -> Option<LoadingWidgets> {
view! {
#[local]
root {
set_title: Some("Simple app"),
set_default_size: (300, 100),
#[name(spinner)]
gtk::Spinner {
start: (),
set_halign: gtk::Align::Center,
}
}
}
Some(LoadingWidgets::new(root, spinner))
}
async fn init(
counter: Self::Init,
root: Self::Root,
sender: AsyncComponentSender<Self>,
) -> AsyncComponentParts<Self> {
tokio::time::sleep(Duration::from_secs(1)).await;
let model = App { counter };
let widgets = view_output!();
AsyncComponentParts { model, widgets }
}
async fn update(
&mut self,
msg: Self::Input,
_sender: AsyncComponentSender<Self>,
_root: &Self::Root,
) {
tokio::time::sleep(Duration::from_secs(1)).await;
match msg {
Msg::Increment => {
self.counter = self.counter.wrapping_add(1);
}
Msg::Decrement => {
self.counter = self.counter.wrapping_sub(1);
}
}
}
}
fn main() {
let app = RelmApp::new("relm4.example.simple_async");
app.run_async::<App>(0);
}