use druid::{widget::Controller, *};
type PressKeyAction<T> = Box<dyn Fn(&mut EventCtx, &mut T, &Env)>;
pub struct PressKey<T> {
is_key_down: bool,
key_code: Code,
action: PressKeyAction<T>,
}
impl<T> PressKey<T> {
pub fn new(key_code: Code, action: impl Fn(&mut EventCtx, &mut T, &Env) + 'static) -> Self {
PressKey {
action: Box::new(action),
key_code,
is_key_down: false,
}
}
}
impl<T, W: Widget<T>> Controller<T, W> for PressKey<T> {
fn event(&mut self, child: &mut W, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
if ctx.is_focused() && !ctx.is_disabled() {
if let Event::KeyDown(key) = event {
if key.code == self.key_code {
self.is_key_down = true;
}
} else if let Event::KeyUp(key) = event {
if key.code == self.key_code && self.is_key_down {
(self.action)(ctx, data, env);
self.is_key_down = false;
}
}
} else {
self.is_key_down = false;
}
child.event(ctx, event, data, env)
}
}