1use gtk::prelude::*;
2use relm4::actions::*;
3use relm4::prelude::*;
4
5#[derive(Default)]
6struct App {
7 counter: u8,
8}
9
10#[derive(Debug)]
11enum Msg {
12 Increment,
13 Decrement,
14}
15
16#[relm4::component]
17impl SimpleComponent for App {
18 type Init = ();
19 type Input = Msg;
20 type Output = ();
21
22 view! {
23 main_window = gtk::ApplicationWindow {
24 set_title: Some("Action example"),
25 set_default_size: (300, 100),
26
27 gtk::Box {
28 set_orientation: gtk::Orientation::Vertical,
29 set_margin_all: 5,
30 set_spacing: 5,
31
32 gtk::Button {
33 set_label: "Increment",
34 connect_clicked => Msg::Increment,
35 ActionablePlus::set_action::<ExampleU8Action>: 1,
36 },
37
38 gtk::Button::with_label("Decrement") {
39 connect_clicked => Msg::Decrement,
40 },
41
42 gtk::Label {
43 set_margin_all: 5,
44 #[watch]
45 set_label: &format!("Counter: {}", model.counter),
46 },
47
48 gtk::MenuButton {
49 set_menu_model: Some(&menu_model),
50 }
51 },
52 }
53 }
54
55 fn init(
56 _init: Self::Init,
57 root: Self::Root,
58 sender: ComponentSender<Self>,
59 ) -> ComponentParts<Self> {
60 let menu_model = gtk::gio::Menu::new();
61 menu_model.append(Some("Stateless"), Some(&ExampleAction::action_name()));
62
63 let model = Self { counter: 0 };
64
65 let widgets = view_output!();
66
67 let app = relm4::main_application();
68 app.set_accelerators_for_action::<ExampleAction>(&["<primary>W"]);
69
70 let action: RelmAction<ExampleAction> = RelmAction::new_stateless(move |_| {
71 println!("Statelesss action!");
72 sender.input(Msg::Increment);
73 });
74
75 let action2: RelmAction<ExampleU8Action> =
76 RelmAction::new_stateful_with_target_value(&0, |_, state, value| {
77 println!("Stateful action -> state: {state}, value: {value}");
78 *state += value;
79 });
80
81 let mut group = RelmActionGroup::<WindowActionGroup>::new();
82 group.add_action(action);
83 group.add_action(action2);
84 group.register_for_widget(&widgets.main_window);
85
86 ComponentParts { model, widgets }
87 }
88
89 fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self>) {
90 match message {
91 Msg::Increment => {
92 self.counter = self.counter.wrapping_add(1);
93 }
94 Msg::Decrement => {
95 self.counter = self.counter.wrapping_sub(1);
96 }
97 }
98 }
99}
100
101relm4::new_action_group!(WindowActionGroup, "win");
102relm4::new_stateless_action!(ExampleAction, WindowActionGroup, "example");
103relm4::new_stateful_action!(ExampleU8Action, WindowActionGroup, "example2", u8, u8);
104
105fn main() {
106 let app = RelmApp::new("relm4.example.actions");
107 app.run::<App>(());
108}