use crate::widget::Controller;
use crate::{Data, Env, Event, EventCtx, LifeCycle, LifeCycleCtx, Widget};
pub struct Click<T> {
action: Box<dyn Fn(&mut EventCtx, &mut T, &Env)>,
}
impl<T: Data> Click<T> {
pub fn new(action: impl Fn(&mut EventCtx, &mut T, &Env) + 'static) -> Self {
Click {
action: Box::new(action),
}
}
}
impl<T: Data, W: Widget<T>> Controller<T, W> for Click<T> {
fn event(&mut self, child: &mut W, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
match event {
Event::MouseDown(_) => {
ctx.set_active(true);
ctx.request_paint();
}
Event::MouseUp(_) => {
if ctx.is_active() {
ctx.set_active(false);
if ctx.is_hot() {
(self.action)(ctx, data, env);
}
ctx.request_paint();
}
}
_ => {}
}
child.event(ctx, event, data, env);
}
fn lifecycle(
&mut self,
child: &mut W,
ctx: &mut LifeCycleCtx,
event: &LifeCycle,
data: &T,
env: &Env,
) {
if let LifeCycle::HotChanged(_) | LifeCycle::FocusChanged(_) = event {
ctx.request_paint();
}
child.lifecycle(ctx, event, data, env);
}
}