Here's an example using GTK that does something vaguely useful, I have no idea if it's considered idiomatic, but it works as intended: https://github.com/seaneshbaugh/image_viewer/blob/master/src...
The closures themselves are trivial, it's manipulating the stuff outside the closure that's tricky (for a Rust neophyte like me).
The relevant definitions are
let area = Rc::new(RefCell::new(DrawingArea::new()));
and let scale = Rc::new(Cell::new(1.0));
Rather than just define things as usual they need to be wrapped in a Cell (for value types) or RefCell (for reference types) and then wrapped in an Rc so we can keep track of reference counts at run time. {
let scale = scale.clone();
let area = area.clone();
window.connect_key_release_event(move |_, key_event| {
let mut s = scale.get();
let key = key_event.get_keyval() as i32;
if key == gdk_sys::GDK_KEY_plus {
s += 0.1;
} else {
if key == gdk_sys::GDK_KEY_minus {
s -= 0.1;
}
}
scale.set(s);
area.borrow().queue_draw();
Inhibit(false)
});
}
Inside the new scope (which is very important) scale and area are cloned which increments their count, then inside the close scale.get() is used to get a copy of scale (which is possible since it's a float) and then after doing stuff to it based on the key that is pressed it's set using scale.set(). For area it's a bit trickier, it has to first be borrow()'ed before anything can be done with it.