rustfltk

RUST + FLTK: accessing another widget from widget on_push() function


I used FLTK to create a window and two buttons inside, the btn_A has a callback and should change the btn_B label, but I dont see any non-monstrous approach do to this, ples halp? =''[

fn main() {

showMainWindow();

}

pub fn showMainWindow() {

    //WINDOW
    let application=app::App::default();
    let mut win = window::Window::default().with_size(500,300);

    //BTN_A
    let mut btn_A:Listener<_> = button::Button::new(100,100,100,50,"btn_A").into();

    //BTN_B
    let mut btn_B:Listener<_> = button::Button::new(300,100,100,50,"btn_B").into();

    //BTN_A_CALLBACK
    btn_A.handle(|elem,evt| match evt {
     enums::Event::Push => { btn_A(elem); true }
     _ => { false }
     });

    win.end();
    win.show();

    application.run().unwrap();
}


pub fn btn_A(elem:&mut button::Button) {

    elem.deactivate(); //deactivate itself

    //but how do I access btn_B here?
}

Solution

  • In principle all that is needed is to pass a mutable reference to btn_B to your handler function:

    pub fn btn_A(elem:&mut button::Button, btn_B: &mut button::Button) {
        ...
    }
    

    However there is one slight problem with your code: You named the function the same as the variable that holds your button.

    Apart from that in the most recent version of the fltk crate (v.1.2.23, that I used because you did not specify which version you used in your question) there does not seem to be a Listener<_> type.

    Here is an example based on the snippet you posted for changing the label of btn_B:

    use fltk::{prelude::{WidgetExt, GroupExt, WidgetBase}, window, app, button, enums};
    
    fn main() {
        showMainWindow();
    }
    
    pub fn showMainWindow() {
        //WINDOW
        let application = app::App::default();
        let mut win = window::Window::default().with_size(500, 300);
    
        //BTN_A
        let mut btn_A = button::Button::new(100, 100, 100, 50, "btn_A");
    
        //BTN_B
        let mut btn_B = button::Button::new(300, 100, 100, 50, "btn_B");
    
        //BTN_A_CALLBACK
        btn_A.handle(move |elem, evt| match evt {
            enums::Event::Push => {
                btn_A_click(elem, &mut btn_B);
                true
            }
            _ => false,
        });
    
        win.end();
        win.show();
    
        application.run().unwrap();
    }
    
    pub fn btn_A_click(elem: &mut button::Button, btn_B: &mut button::Button) {
        elem.deactivate(); //deactivate itself
    
        //but how do I access btn_B here?
        btn_B.set_label("New title.")
    }
    

    Also note, that the handle closure now takes ownership of btn_B because of the move keyword.