widget_id/
widget_id.rs

1use fltk::{prelude::*, *};
2
3// So we can do `widget.on_trigger()` and get self back. Useful for chaining methods.
4trait OnTrigger<W>
5where
6    W: WidgetExt,
7{
8    fn on_trigger<F: 'static + FnMut(&mut Self)>(self, cb: F) -> Self
9    where
10        Self: Sized;
11}
12
13impl<W> OnTrigger<W> for W
14where
15    W: WidgetExt,
16{
17    fn on_trigger<F: 'static + FnMut(&mut Self)>(mut self, mut cb: F) -> Self {
18        self.set_callback(move |s| cb(s));
19        self
20    }
21}
22
23struct Counter {
24    count: i32,
25}
26
27// For calls inside a closure
28fn increment_by(step: i32) {
29    let mut frame: frame::Frame = app::widget_from_id("my_frame").unwrap();
30    let state = app::GlobalState::<Counter>::get();
31    let count = state.with(move |c| {
32        c.count += step;
33        c.count
34    });
35    frame.set_label(&count.to_string());
36}
37
38// To pass a function object directly!
39fn increment(_w: &mut impl WidgetExt) {
40    let mut frame: frame::Frame = app::widget_from_id("my_frame").unwrap();
41    let state = app::GlobalState::<Counter>::get();
42    let count = state.with(|c| {
43        c.count += 1;
44        c.count
45    });
46    frame.set_label(&count.to_string());
47}
48
49fn main() {
50    let counter = Counter { count: 0 };
51    let _state = app::GlobalState::new(counter);
52    let app = app::App::default().with_scheme(app::Scheme::Gtk);
53    let mut wind = window::Window::default()
54        .with_size(160, 200)
55        .with_label("Counter");
56    let col = group::Flex::default_fill().column();
57    button::Button::default()
58        .with_label("+")
59        .on_trigger(increment); // passed by function object
60    frame::Frame::default().with_label("0").with_id("my_frame"); // pass id here
61    button::Button::default()
62        .with_label("-")
63        .on_trigger(|_| increment_by(-1)); // called in closure
64    col.end();
65    wind.make_resizable(true);
66    wind.end();
67    wind.show();
68
69    app.run().unwrap();
70}