eventsrustfltk

What is the Rust way of spreading events throughout the application


I'm using ftlk UI library to show window and bind some actins on it. But this question isn't ftlk specific.

What would be the right way of triggering actions on other structs from the UI Window?

Example code below

let mut window: DoubleWindow = Window::default().with_label("").with_size(100, 100).center_screen();
window.handle(move |_, event| {
    match event {
        Event::Released => {
            let left = event_button() == 1;
            if left {
                let (x, y) = event_coords();
                struct_with_action.do_actions(x as usize, y as usize);
            }
            true
        }
        _ => false,
    }
});

A bad solution could be to pass mutable static lifetime reference to struct_with_action and trigger action directly on struct_with_action, but that already brings up too much complications.

What would be the right way to fire event from window handler -> to trigger action somewhere else?

Is there any recommended library or simple implementation to add an event to event queue and register event listener?


Solution

  • It's probably best to send events through fltk's event handler.

    Look through that page to see if something matches your needs. Example from that page of creating a custom event:

    use fltk::{app, button::*, enums::*, frame::*, group::*, prelude::*, window::*};
    use std::cell::RefCell;
    use std::rc::Rc;
    
    pub struct MyEvent;
    
    impl MyEvent {
        const CHANGED: i32 = 40;
    }
    
    #[derive(Clone)]
    pub struct Counter {
        count: Rc<RefCell<i32>>,
    }
    
    impl Counter {
        pub fn new(val: i32) -> Self {
            Counter {
                count: Rc::from(RefCell::from(val)),
            }
        }
    
        pub fn increment(&mut self) {
            *self.count.borrow_mut() += 1;
            app::handle_main(MyEvent::CHANGED).unwrap();
        }
    
        pub fn decrement(&mut self) {
            *self.count.borrow_mut() -= 1;
            app::handle_main(MyEvent::CHANGED).unwrap();
        }
    
        pub fn value(&self) -> i32 {
            *self.count.borrow()
        }
    }
    
    fn main() -> Result<(), Box<dyn std::error::Error>> {
        let app = app::App::default();
        let counter = Counter::new(0);
        let mut wind = Window::default().with_size(160, 200).with_label("Counter");
        let mut pack = Pack::default().with_size(120, 140).center_of(&wind);
        pack.set_spacing(10);
        let mut but_inc = Button::default().with_size(0, 40).with_label("+");
        let mut frame = Frame::default()
            .with_size(0, 40)
            .with_label(&counter.clone().value().to_string());
        let mut but_dec = Button::default().with_size(0, 40).with_label("-");
        pack.end();
        wind.end();
        wind.show();
    
        but_inc.set_callback({
            let mut c = counter.clone();
            move |_| c.increment()
        });
    
        but_dec.set_callback({
            let mut c = counter.clone();
            move |_| c.decrement()
        });
        
        frame.handle(move |f, ev| {
            if ev == MyEvent::CHANGED.into() {
                f.set_label(&counter.clone().value().to_string());
                true
            } else {
                false
            }
        });
    
        Ok(app.run()?)
    }