move ctx in event to be on module so run event and stuff can be used easily

This commit is contained in:
2025-09-25 13:59:39 -04:00
parent fe42092556
commit 552d66d90f
3 changed files with 72 additions and 36 deletions

View File

@@ -15,8 +15,8 @@ impl UiCtx for Ui {
}
}
pub trait Event<Ctx>: Sized {
type Module: EventModule<Self, Ctx>;
pub trait Event: Sized {
type Module<Ctx: 'static>: EventModule<Self, Ctx>;
type Data: Clone;
}
@@ -24,13 +24,13 @@ pub trait EventFn<Ctx, Data>: Fn(&mut Ctx, Data) + 'static {}
impl<F: Fn(&mut Ctx, Data) + 'static, Ctx, Data> EventFn<Ctx, Data> for F {}
pub trait Eventable<W, Tag> {
fn on<E: Event<Ctx>, Ctx>(
fn on<E: Event, Ctx: 'static>(
self,
event: E,
f: impl EventFn<Ctx, E::Data>,
) -> impl WidgetIdFn<W> + Eventable<W, IdFnTag>;
fn id_on<E: Event<Ctx>, Ctx>(
fn id_on<E: Event, Ctx: 'static>(
self,
event: E,
f: impl Fn(&WidgetId<W>, &mut Ctx, E::Data) + 'static,
@@ -38,7 +38,7 @@ pub trait Eventable<W, Tag> {
where
W: Widget;
fn edit_on<E: Event<Ui>>(
fn edit_on<E: Event>(
self,
event: E,
f: impl Fn(&mut W, E::Data) + 'static,
@@ -48,7 +48,7 @@ pub trait Eventable<W, Tag> {
}
impl<W: WidgetLike<Tag>, Tag> Eventable<W::Widget, Tag> for W {
fn on<E: Event<Ctx>, Ctx>(
fn on<E: Event, Ctx: 'static>(
self,
event: E,
f: impl EventFn<Ctx, E::Data>,
@@ -56,13 +56,13 @@ impl<W: WidgetLike<Tag>, Tag> Eventable<W::Widget, Tag> for W {
move |ui| {
let id = self.add(ui);
ui.modules
.get_mut::<E::Module>()
.get_mut::<E::Module<Ctx>>()
.register(id.id.duplicate(), event, f);
id
}
}
fn id_on<E: Event<Ctx>, Ctx>(
fn id_on<E: Event, Ctx: 'static>(
self,
event: E,
f: impl Fn(&WidgetId<W::Widget>, &mut Ctx, E::Data) + 'static,
@@ -76,7 +76,7 @@ impl<W: WidgetLike<Tag>, Tag> Eventable<W::Widget, Tag> for W {
})
}
fn edit_on<E: Event<Ui>>(
fn edit_on<E: Event>(
self,
event: E,
f: impl Fn(&mut W::Widget, E::Data) + 'static,
@@ -84,7 +84,7 @@ impl<W: WidgetLike<Tag>, Tag> Eventable<W::Widget, Tag> 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<E: DefaultEvent, Ctx: 'static> Event<Ctx> for E {
type Module = DefaultEventModule<E, Ctx>;
impl<E: DefaultEvent> Event for E {
type Module<Ctx: 'static> = DefaultEventModule<E, Ctx>;
type Data = E::Data;
}
pub trait EventModule<E: Event<Ctx>, Ctx>: UiModule + Default {
pub trait EventModule<E: Event, Ctx>: UiModule + Default {
fn register(&mut self, id: Id, event: E, f: impl EventFn<Ctx, E::Data>);
fn run<'a>(
&self,
@@ -107,11 +107,11 @@ pub trait EventModule<E: Event<Ctx>, Ctx>: UiModule + Default {
}
type EventFnMap<Ctx, Data> = HashMap<Id, Vec<Rc<dyn EventFn<Ctx, Data>>>>;
pub struct DefaultEventModule<E: Event<Ctx>, Ctx> {
map: HashMap<E, EventFnMap<Ctx, <E as Event<Ctx>>::Data>>,
pub struct DefaultEventModule<E: Event, Ctx> {
map: HashMap<E, EventFnMap<Ctx, <E as Event>::Data>>,
}
impl<E: Event<Ctx> + 'static, Ctx: 'static> UiModule for DefaultEventModule<E, Ctx> {
impl<E: Event + 'static, Ctx: 'static> UiModule for DefaultEventModule<E, Ctx> {
fn on_remove(&mut self, id: &Id) {
for map in self.map.values_mut() {
map.remove(id);
@@ -119,11 +119,11 @@ impl<E: Event<Ctx> + 'static, Ctx: 'static> UiModule for DefaultEventModule<E, C
}
}
pub trait HashableEvent<Ctx>: Event<Ctx> + Hash + Eq + 'static {}
impl<E: Event<Ctx> + Hash + Eq + 'static, Ctx> HashableEvent<Ctx> for E {}
pub trait HashableEvent: Event + Hash + Eq + 'static {}
impl<E: Event + Hash + Eq + 'static> HashableEvent for E {}
impl<E: HashableEvent<Ctx>, Ctx: 'static> EventModule<E, Ctx> for DefaultEventModule<E, Ctx> {
fn register(&mut self, id: Id, event: E, f: impl EventFn<Ctx, <E as Event<Ctx>>::Data>) {
impl<E: HashableEvent, Ctx: 'static> EventModule<E, Ctx> for DefaultEventModule<E, Ctx> {
fn register(&mut self, id: Id, event: E, f: impl EventFn<Ctx, <E as Event>::Data>) {
self.map
.entry(event)
.or_default()
@@ -148,7 +148,7 @@ impl<E: HashableEvent<Ctx>, Ctx: 'static> EventModule<E, Ctx> for DefaultEventMo
}
}
impl<E: HashableEvent<Ctx>, Ctx: 'static> DefaultEventModule<E, Ctx> {
impl<E: HashableEvent, Ctx: 'static> DefaultEventModule<E, Ctx> {
pub fn run_all(&self, ctx: &mut Ctx, event: E, data: E::Data)
where
E::Data: Clone,
@@ -163,7 +163,7 @@ impl<E: HashableEvent<Ctx>, Ctx: 'static> DefaultEventModule<E, Ctx> {
}
}
impl<E: Event<Ctx> + 'static, Ctx: 'static> Default for DefaultEventModule<E, Ctx> {
impl<E: Event + 'static, Ctx: 'static> Default for DefaultEventModule<E, Ctx> {
fn default() -> Self {
Self {
map: Default::default(),
@@ -172,14 +172,40 @@ impl<E: Event<Ctx> + 'static, Ctx: 'static> Default for DefaultEventModule<E, Ct
}
impl Ui {
pub fn run_event<E: Event<Ctx>, Ctx: UiCtx, W>(
pub fn run_event<E: Event + Clone, Ctx: UiCtx + 'static, W>(
ctx: &mut Ctx,
id: &WidgetId<W>,
event: E,
data: E::Data,
) {
if let Some(f) = ctx.ui().modules.get_mut::<E::Module>().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<E: Event, Ctx: UiCtx + 'static, W>(
ctx: &mut Ctx,
id: &WidgetId<W>,
event: E,
data: E::Data,
) {
if let Some(f) = ctx
.ui()
.modules
.get_mut::<E::Module<Ctx>>()
.run(&id.id, event)
{
f(ctx, data);
}
}
}
pub trait EventCtx: UiCtx {
fn run_event<E: Event + Clone, W>(&mut self, id: &WidgetId<W>, event: E, data: E::Data);
}
impl<Ctx: UiCtx + 'static> EventCtx for Ctx {
fn run_event<E: Event + Clone, W>(&mut self, id: &WidgetId<W>, event: E, data: E::Data) {
Ui::run_event_inner(self, id, event.clone(), data.clone());
Ui::run_event_inner(self.ui(), id, event, data);
}
}