use gtk::glib::clone; use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt}; use relm4::{ComponentParts, ComponentSender, RelmApp, RelmWidgetExt, SimpleComponent}; struct App { counter: u8, } #[derive(Debug)] enum Msg { Increment, Decrement, } struct AppWidgets { // window: gtk::Window, // vbox: gtk::Box, // inc_button: gtk::Button, // dec_button: gtk::Button, label: gtk::Label, } impl SimpleComponent for App { type Init = u8; type Input = Msg; type Output = (); type Widgets = AppWidgets; type Root = gtk::Window; fn init_root() -> Self::Root { gtk::Window::builder() .title("Simple app") .default_width(300) .default_height(100) .build() } // Initialize the component. fn init( counter: Self::Init, window: Self::Root, sender: ComponentSender, ) -> ComponentParts { let model = App { counter }; let vbox = gtk::Box::builder() .orientation(gtk::Orientation::Vertical) .spacing(5) .build(); let inc_button = gtk::Button::with_label("Increment"); let dec_button = gtk::Button::with_label("Decrement"); let label = gtk::Label::new(Some(&format!("Counter: {}", model.counter))); label.set_margin_all(5); window.set_child(Some(&vbox)); vbox.set_margin_all(5); vbox.append(&inc_button); vbox.append(&dec_button); vbox.append(&label); inc_button.connect_clicked(clone!( #[strong] sender, move |_| { sender.input(Msg::Increment); } )); dec_button.connect_clicked(clone!( #[strong] sender, move |_| { sender.input(Msg::Decrement); } )); let widgets = AppWidgets { label }; ComponentParts { model, widgets } } fn update(&mut self, msg: Self::Input, _sender: ComponentSender) { match msg { Msg::Increment => { self.counter = self.counter.wrapping_add(1); } Msg::Decrement => { self.counter = self.counter.wrapping_sub(1); } } } // Update the view to represent the updated model. fn update_view(&self, widgets: &mut Self::Widgets, _sender: ComponentSender) { widgets .label .set_label(&format!("Counter: {}", self.counter)); } } fn main() { let app = RelmApp::new("relm4.example.simple_manual"); app.run::(0); }