diff --git a/src/core/sense.rs b/src/core/sense.rs index 7a7ed95..6676afb 100644 --- a/src/core/sense.rs +++ b/src/core/sense.rs @@ -142,6 +142,17 @@ impl SensorModule { } } +pub trait SensorCtx: UiCtx { + fn run_sensors(&mut self, cursor: &CursorState, window_size: Vec2); +} + +impl SensorCtx for Ctx { + fn run_sensors(&mut self, cursor: &CursorState, window_size: Vec2) { + SensorModule::::run(self, cursor, window_size); + SensorModule::::run(self.ui(), cursor, window_size); + } +} + impl SensorModule { pub fn run(ctx: &mut Ctx, cursor: &CursorState, window_size: Vec2) { let layers = std::mem::take(&mut ctx.ui().layers); @@ -243,20 +254,20 @@ impl ActivationState { } } -impl Event for Senses { - type Module = SensorModule; +impl Event for Senses { + type Module = SensorModule; type Data = SenseData; } -impl Event for Sense { - type Module = SensorModule; +impl Event for Sense { + type Module = SensorModule; type Data = SenseData; } -impl>::Data> + Into, Ctx: 'static> - EventModule for SensorModule +impl::Data> + Into, Ctx: 'static> EventModule + for SensorModule { - fn register(&mut self, id: Id, senses: E, f: impl EventFn>::Data>) { + fn register(&mut self, id: Id, senses: E, f: impl EventFn::Data>) { // TODO: does not add to active if currently active self.map.entry(id).or_default().sensors.push(Sensor { senses: senses.into(), diff --git a/src/layout/event.rs b/src/layout/event.rs index 64a88af..375d1c3 100644 --- a/src/layout/event.rs +++ b/src/layout/event.rs @@ -15,8 +15,8 @@ impl UiCtx for Ui { } } -pub trait Event: Sized { - type Module: EventModule; +pub trait Event: Sized { + type Module: EventModule; type Data: Clone; } @@ -24,13 +24,13 @@ pub trait EventFn: Fn(&mut Ctx, Data) + 'static {} impl EventFn for F {} pub trait Eventable { - fn on, Ctx>( + fn on( self, event: E, f: impl EventFn, ) -> impl WidgetIdFn + Eventable; - fn id_on, Ctx>( + fn id_on( self, event: E, f: impl Fn(&WidgetId, &mut Ctx, E::Data) + 'static, @@ -38,7 +38,7 @@ pub trait Eventable { where W: Widget; - fn edit_on>( + fn edit_on( self, event: E, f: impl Fn(&mut W, E::Data) + 'static, @@ -48,7 +48,7 @@ pub trait Eventable { } impl, Tag> Eventable for W { - fn on, Ctx>( + fn on( self, event: E, f: impl EventFn, @@ -56,13 +56,13 @@ impl, Tag> Eventable for W { move |ui| { let id = self.add(ui); ui.modules - .get_mut::() + .get_mut::>() .register(id.id.duplicate(), event, f); id } } - fn id_on, Ctx>( + fn id_on( self, event: E, f: impl Fn(&WidgetId, &mut Ctx, E::Data) + 'static, @@ -76,7 +76,7 @@ impl, Tag> Eventable for W { }) } - fn edit_on>( + fn edit_on( self, event: E, f: impl Fn(&mut W::Widget, E::Data) + 'static, @@ -84,7 +84,7 @@ impl, Tag> Eventable for W { where W::Widget: Widget, { - self.id_on(event, move |id, ui, pos| f(&mut ui[id], pos)) + self.id_on(event, move |id, ui: &mut Ui, pos| f(&mut ui[id], pos)) } } @@ -92,12 +92,12 @@ pub trait DefaultEvent: Hash + Eq + 'static { type Data: Clone; } -impl Event for E { - type Module = DefaultEventModule; +impl Event for E { + type Module = DefaultEventModule; type Data = E::Data; } -pub trait EventModule, Ctx>: UiModule + Default { +pub trait EventModule: UiModule + Default { fn register(&mut self, id: Id, event: E, f: impl EventFn); fn run<'a>( &self, @@ -107,11 +107,11 @@ pub trait EventModule, Ctx>: UiModule + Default { } type EventFnMap = HashMap>>>; -pub struct DefaultEventModule, Ctx> { - map: HashMap>::Data>>, +pub struct DefaultEventModule { + map: HashMap::Data>>, } -impl + 'static, Ctx: 'static> UiModule for DefaultEventModule { +impl UiModule for DefaultEventModule { fn on_remove(&mut self, id: &Id) { for map in self.map.values_mut() { map.remove(id); @@ -119,11 +119,11 @@ impl + 'static, Ctx: 'static> UiModule for DefaultEventModule: Event + Hash + Eq + 'static {} -impl + Hash + Eq + 'static, Ctx> HashableEvent for E {} +pub trait HashableEvent: Event + Hash + Eq + 'static {} +impl HashableEvent for E {} -impl, Ctx: 'static> EventModule for DefaultEventModule { - fn register(&mut self, id: Id, event: E, f: impl EventFn>::Data>) { +impl EventModule for DefaultEventModule { + fn register(&mut self, id: Id, event: E, f: impl EventFn::Data>) { self.map .entry(event) .or_default() @@ -148,7 +148,7 @@ impl, Ctx: 'static> EventModule for DefaultEventMo } } -impl, Ctx: 'static> DefaultEventModule { +impl DefaultEventModule { pub fn run_all(&self, ctx: &mut Ctx, event: E, data: E::Data) where E::Data: Clone, @@ -163,7 +163,7 @@ impl, Ctx: 'static> DefaultEventModule { } } -impl + 'static, Ctx: 'static> Default for DefaultEventModule { +impl Default for DefaultEventModule { fn default() -> Self { Self { map: Default::default(), @@ -172,14 +172,40 @@ impl + 'static, Ctx: 'static> Default for DefaultEventModule, Ctx: UiCtx, W>( + pub fn run_event( ctx: &mut Ctx, id: &WidgetId, event: E, data: E::Data, ) { - if let Some(f) = ctx.ui().modules.get_mut::().run(&id.id, event) { + Self::run_event_inner(ctx, id, event.clone(), data.clone()); + Self::run_event_inner(ctx.ui(), id, event, data); + } + + fn run_event_inner( + ctx: &mut Ctx, + id: &WidgetId, + event: E, + data: E::Data, + ) { + if let Some(f) = ctx + .ui() + .modules + .get_mut::>() + .run(&id.id, event) + { f(ctx, data); } } } + +pub trait EventCtx: UiCtx { + fn run_event(&mut self, id: &WidgetId, event: E, data: E::Data); +} + +impl EventCtx for Ctx { + fn run_event(&mut self, id: &WidgetId, event: E, data: E::Data) { + Ui::run_event_inner(self, id, event.clone(), data.clone()); + Ui::run_event_inner(self.ui(), id, event, data); + } +} diff --git a/src/testing/mod.rs b/src/testing/mod.rs index 70fc243..6c6c53d 100644 --- a/src/testing/mod.rs +++ b/src/testing/mod.rs @@ -24,7 +24,7 @@ pub struct Client { focus: Option>, } -#[derive(Eq, PartialEq, Hash)] +#[derive(Eq, PartialEq, Hash, Clone)] struct Submit; impl DefaultEvent for Submit { @@ -153,7 +153,7 @@ impl Client { add_text.clone(), Rect::new(Color::GREEN) .on(Sense::click(), move |client: &mut Client, _| { - Ui::run_event(client, &add_text, Submit, ()); + client.run_event(&add_text, Submit, ()); }) .size(40), ) @@ -221,8 +221,7 @@ impl Client { } if input_changed { let window_size = self.window_size(); - SensorModule::run(&mut self.ui, &cursor_state, window_size); - SensorModule::run(self, &cursor_state, window_size); + self.run_sensors(&cursor_state, window_size); } match event { WindowEvent::CloseRequested => event_loop.exit(), @@ -244,7 +243,7 @@ impl Client { self.focus = None; } TextInputResult::Submit => { - Ui::run_event(self, &sel.clone(), Submit, ()); + self.run_event(&sel.clone(), Submit, ()); } _ => (), }