"nvmnd" (event FnMut)

This commit is contained in:
2025-12-10 13:56:38 -05:00
parent 76f75192d5
commit 2537284372
4 changed files with 17 additions and 18 deletions

View File

@@ -1,4 +1,4 @@
use std::{cell::RefCell, hash::Hash, rc::Rc}; use std::{hash::Hash, rc::Rc};
use crate::{ use crate::{
layout::{Ui, UiModule, WidgetId, WidgetRef}, layout::{Ui, UiModule, WidgetId, WidgetRef},
@@ -24,11 +24,11 @@ pub struct EventIdCtx<'a, Ctx, Data, W: ?Sized> {
pub data: Data, pub data: Data,
} }
pub trait EventFn<Ctx, Data>: FnMut(EventCtx<Ctx, Data>) + 'static {} pub trait EventFn<Ctx, Data>: Fn(EventCtx<Ctx, Data>) + 'static {}
impl<F: FnMut(EventCtx<Ctx, Data>) + 'static, Ctx, Data> EventFn<Ctx, Data> for F {} impl<F: Fn(EventCtx<Ctx, Data>) + 'static, Ctx, Data> EventFn<Ctx, Data> for F {}
pub trait WidgetEventFn<Ctx, Data, W: ?Sized>: FnMut(EventIdCtx<Ctx, Data, W>) + 'static {} pub trait WidgetEventFn<Ctx, Data, W: ?Sized>: Fn(EventIdCtx<Ctx, Data, W>) + 'static {}
impl<F: FnMut(EventIdCtx<Ctx, Data, W>) + 'static, Ctx, Data, W: ?Sized> WidgetEventFn<Ctx, Data, W> impl<F: Fn(EventIdCtx<Ctx, Data, W>) + 'static, Ctx, Data, W: ?Sized> WidgetEventFn<Ctx, Data, W>
for F for F
{ {
} }
@@ -50,13 +50,13 @@ impl Ui {
&mut self, &mut self,
id: WidgetRef<W>, id: WidgetRef<W>,
event: E, event: E,
mut f: impl WidgetEventFn<Ctx, E::Data, W>, f: impl WidgetEventFn<Ctx, E::Data, W>,
) { ) {
self.data self.data
.modules .modules
.get_mut::<E::Module<Ctx>>() .get_mut::<E::Module<Ctx>>()
.register(id.id(), event, move |ctx| { .register(id.id(), event, move |ctx| {
(&mut f)(EventIdCtx { f(EventIdCtx {
widget: id, widget: id,
ui: ctx.ui, ui: ctx.ui,
state: ctx.state, state: ctx.state,
@@ -84,7 +84,7 @@ pub trait EventModule<E: Event, Ctx>: UiModule + Default {
) -> Option<impl FnOnce(EventCtx<Ctx, E::Data>) + use<'a, Self, Ctx, E>>; ) -> Option<impl FnOnce(EventCtx<Ctx, E::Data>) + use<'a, Self, Ctx, E>>;
} }
type EventFnMap<Ctx, Data> = HashMap<WidgetId, Vec<Rc<RefCell<dyn EventFn<Ctx, Data>>>>>; type EventFnMap<Ctx, Data> = HashMap<WidgetId, Vec<Rc<dyn EventFn<Ctx, Data>>>>;
pub struct DefaultEventModule<E: Event, Ctx> { pub struct DefaultEventModule<E: Event, Ctx> {
map: HashMap<E, EventFnMap<Ctx, <E as Event>::Data>>, map: HashMap<E, EventFnMap<Ctx, <E as Event>::Data>>,
} }
@@ -107,7 +107,7 @@ impl<E: HashableEvent, Ctx: 'static> EventModule<E, Ctx> for DefaultEventModule<
.or_default() .or_default()
.entry(id) .entry(id)
.or_default() .or_default()
.push(Rc::new(RefCell::new(f))); .push(Rc::new(f));
} }
fn run<'a>( fn run<'a>(
@@ -121,7 +121,7 @@ impl<E: HashableEvent, Ctx: 'static> EventModule<E, Ctx> for DefaultEventModule<
let fs = fs.clone(); let fs = fs.clone();
Some(move |ctx: EventCtx<Ctx, <E as Event>::Data>| { Some(move |ctx: EventCtx<Ctx, <E as Event>::Data>| {
for f in fs { for f in fs {
f.borrow_mut()(EventCtx { f(EventCtx {
ui: ctx.ui, ui: ctx.ui,
state: ctx.state, state: ctx.state,
data: ctx.data.clone(), data: ctx.data.clone(),
@@ -143,7 +143,7 @@ impl<E: HashableEvent, Ctx: 'static> DefaultEventModule<E, Ctx> {
for fs in map.values() { for fs in map.values() {
let fs = fs.clone(); let fs = fs.clone();
for f in fs { for f in fs {
f.borrow_mut()(EventCtx { f(EventCtx {
ui: ctx.ui, ui: ctx.ui,
state: ctx.state, state: ctx.state,
data: ctx.data.clone(), data: ctx.data.clone(),

View File

@@ -2,7 +2,7 @@ use image::DynamicImage;
use crate::{ use crate::{
layout::{ layout::{
IdLike, PainterData, PixelRegion, TextureHandle, Vec2, Widget, WidgetHandle, WidgetId, IdLike, PainterData, PixelRegion, TextureHandle, Vec2, WidgetHandle, WidgetId,
WidgetInstance, WidgetLike, WidgetUpdate, WidgetInstance, WidgetLike, WidgetUpdate,
}, },
util::HashSet, util::HashSet,

View File

@@ -91,7 +91,7 @@ impl<State: DefaultAppState> AppState for DefaultState<State> {
let input_changed = ui_state.input.event(&event); let input_changed = ui_state.input.event(&event);
let cursor_state = ui_state.cursor_state().clone(); let cursor_state = ui_state.cursor_state().clone();
let old = ui_state.focus.clone(); let old = ui_state.focus;
if cursor_state.buttons.left.is_start() { if cursor_state.buttons.left.is_start() {
ui_state.focus = None; ui_state.focus = None;
} }

View File

@@ -3,7 +3,6 @@ use crate::{
layout::{UiModule, UiRegion, Vec2}, layout::{UiModule, UiRegion, Vec2},
util::HashMap, util::HashMap,
}; };
use std::cell::RefCell;
use std::{ use std::{
ops::{BitOr, Deref, DerefMut}, ops::{BitOr, Deref, DerefMut},
rc::Rc, rc::Rc,
@@ -98,7 +97,7 @@ pub enum ActivationState {
/// but I'm not sure how or if worth it /// but I'm not sure how or if worth it
pub struct Sensor<Ctx, Data> { pub struct Sensor<Ctx, Data> {
pub senses: CursorSenses, pub senses: CursorSenses,
pub f: Rc<RefCell<dyn EventFn<Ctx, Data>>>, pub f: Rc<dyn EventFn<Ctx, Data>>,
} }
pub type SensorMap<Ctx, Data> = HashMap<WidgetId, SensorGroup<Ctx, Data>>; pub type SensorMap<Ctx, Data> = HashMap<WidgetId, SensorGroup<Ctx, Data>>;
@@ -208,7 +207,7 @@ impl<Ctx: 'static> CursorModule<Ctx> {
scroll_delta: cursor.scroll_delta, scroll_delta: cursor.scroll_delta,
sense, sense,
}; };
(sensor.f.borrow_mut())(EventCtx { (sensor.f)(EventCtx {
ui, ui,
state: ctx, state: ctx,
data, data,
@@ -309,7 +308,7 @@ impl<E: Event<Data = <CursorSenses as Event>::Data> + Into<CursorSenses>, Ctx: '
// TODO: does not add to active if currently active // TODO: does not add to active if currently active
self.map.entry(id).or_default().sensors.push(Sensor { self.map.entry(id).or_default().sensors.push(Sensor {
senses: senses.into(), senses: senses.into(),
f: Rc::new(RefCell::new(f)), f: Rc::new(f),
}); });
} }
@@ -333,7 +332,7 @@ impl<E: Event<Data = <CursorSenses as Event>::Data> + Into<CursorSenses>, Ctx: '
.collect(); .collect();
Some(move |ctx: EventCtx<Ctx, CursorData>| { Some(move |ctx: EventCtx<Ctx, CursorData>| {
for f in fs { for f in fs {
f.borrow_mut()(EventCtx { f(EventCtx {
state: ctx.state, state: ctx.state,
ui: ctx.ui, ui: ctx.ui,
data: ctx.data.clone(), data: ctx.data.clone(),