use gtk::{ prelude::*, Inhibit, Label, ApplicationWindow, Button, }; use relm4::{send, AppUpdate, Model, RelmApp, Sender, WidgetPlus, Widgets}; use gladis4::Gladis; struct AppModel { counter: i32, } enum AppMsg { Decrement, Increment, Quit, } // Create the structure that holds the widgets used in the view. #[derive(Clone, Gladis)] struct GladisWidgets { counter_label: Label, minus_button: Button, plus_button: Button, window: ApplicationWindow, } struct Win { widgets: GladisWidgets, } impl Model for AppModel { type Msg = AppMsg; type Components = (); type Widgets = GladisWidgets; } impl AppUpdate for AppModel { fn update(&mut self, event: AppMsg, _components: &(), _sender: Sender) -> bool { match event { AppMsg::Decrement => { self.counter -= 1; } AppMsg::Increment => { self.counter += 1; } AppMsg::Quit => return false, } true } } impl Widgets for GladisWidgets { // Specify the type of the root widget. type Root = ApplicationWindow; // Return the root widget. fn root_widget(&self) -> Self::Root { self.window.clone() } fn init_view(model: &AppModel, _parent_widgets: &(), sender: Sender) -> Self { let glade_src = include_str!("window.glade"); let widgets = GladisWidgets::from_string(glade_src).unwrap(); widgets.window.present(); let minus_sender = sender.clone(); widgets.minus_button.connect_clicked(move |_| { send!(minus_sender, AppMsg::Decrement) }); let sender = sender.clone(); widgets.plus_button.connect_clicked(move |_| { send!(sender, AppMsg::Increment) }); widgets } fn view(&mut self, model: &AppModel, _sender: Sender) { self.counter_label.set_text(&model.counter.to_string()); } } fn main() { let model = AppModel { counter: 0 }; let app = RelmApp::new(model); app.run(); } #[cfg(test)] mod tests { use gtk::prelude::LabelExt; use gtk_test::assert_text; use relm_test::click; use crate::Win; #[test] #[ignore] fn label_change() { let (_component, _, widgets) = relm::init_test::(()).expect("init_test failed"); let plus_button = &widgets.plus_button; let minus_button = &widgets.minus_button; let label = &widgets.counter_label; assert_text!(label, 0); click(plus_button); assert_text!(label, 1); click(plus_button); assert_text!(label, 2); click(plus_button); assert_text!(label, 3); click(plus_button); assert_text!(label, 4); click(minus_button); assert_text!(label, 3); click(minus_button); assert_text!(label, 2); click(minus_button); assert_text!(label, 1); click(minus_button); assert_text!(label, 0); click(minus_button); assert_text!(label, -1); } }