sensor ctx

This commit is contained in:
2025-08-20 13:09:03 -04:00
parent 1482e5d67c
commit b7f83b58a9
4 changed files with 22 additions and 19 deletions

1
TODO
View File

@@ -1,5 +1,4 @@
images images
text text
ui ctx = ui + app ctx for sensors
abstract sensors to work with any event, maybe associate data as well? abstract sensors to work with any event, maybe associate data as well?
make current senses orable so you can select multiple make current senses orable so you can select multiple

View File

@@ -1,11 +1,11 @@
use crate::{Sense, SenseFn, Sensor, Ui, Widget, WidgetId, WidgetIdFnRet, WidgetLike}; use crate::{Sense, SenseCtx, SenseFn, Sensor, Widget, WidgetId, WidgetIdFnRet, WidgetLike};
pub trait Sensable<W, Ctx, Tag> { pub trait Sensable<W, Ctx, Tag> {
fn on(self, sense: Sense, f: impl SenseFn<Ctx>) -> WidgetIdFnRet!(W, Ctx); fn on(self, sense: Sense, f: impl SenseFn<Ctx>) -> WidgetIdFnRet!(W, Ctx);
fn id_on( fn id_on(
self, self,
sense: Sense, sense: Sense,
f: impl FnMut(&WidgetId<W>, &mut Ui<Ctx>, &mut Ctx) + 'static + Clone, f: impl FnMut(&WidgetId<W>, SenseCtx<Ctx>) + 'static + Clone,
) -> WidgetIdFnRet!(W, Ctx) ) -> WidgetIdFnRet!(W, Ctx)
where where
W: Widget<Ctx>; W: Widget<Ctx>;
@@ -35,26 +35,24 @@ impl<W: WidgetLike<Ctx, Tag>, Ctx, Tag> Sensable<W::Widget, Ctx, Tag> for W {
fn id_on( fn id_on(
self, self,
sense: Sense, sense: Sense,
// trait copied here bc rust analyzer skill issue mut f: impl FnMut(&WidgetId<W::Widget>, SenseCtx<Ctx>) + 'static + Clone,
mut f: impl FnMut(&WidgetId<W::Widget>, &mut Ui<Ctx>, &mut Ctx) + 'static + Clone,
) -> WidgetIdFnRet!(W::Widget, Ctx) ) -> WidgetIdFnRet!(W::Widget, Ctx)
where where
W::Widget: Widget<Ctx>, W::Widget: Widget<Ctx>,
{ {
self.with_id(move |ui, id| { self.with_id(move |ui, id| {
let id2 = id.clone(); let id2 = id.clone();
ui.add(id.on(sense, move |ui, ctx| f(&id2, ui, ctx))) ui.add(id.on(sense, move |ctx| f(&id2, ctx)))
}) })
} }
fn edit_on( fn edit_on(
self, self,
sense: Sense, sense: Sense,
// trait copied here bc rust analyzer skill issue
mut f: impl FnMut(&mut W::Widget, &mut Ctx) + 'static + Clone, mut f: impl FnMut(&mut W::Widget, &mut Ctx) + 'static + Clone,
) -> WidgetIdFnRet!(W::Widget, Ctx) ) -> WidgetIdFnRet!(W::Widget, Ctx)
where where
W::Widget: Widget<Ctx>, W::Widget: Widget<Ctx>,
{ {
self.id_on(sense, move |id, ui, ctx| f(&mut ui[id], ctx)) self.id_on(sense, move |id, ctx| f(&mut ctx.ui[id], ctx.app))
} }
} }

View File

@@ -44,10 +44,14 @@ pub struct SensorGroup<Ctx> {
pub cursor: ActivationState, pub cursor: ActivationState,
pub sensors: Vec<Sensor<Ctx>>, pub sensors: Vec<Sensor<Ctx>>,
} }
pub trait SenseFn<Ctx>: FnMut(&mut Ui<Ctx>, &mut Ctx) + 'static { pub struct SenseCtx<'a, Ctx> {
pub ui: &'a mut Ui<Ctx>,
pub app: &'a mut Ctx,
}
pub trait SenseFn<Ctx>: FnMut(SenseCtx<Ctx>) + 'static {
fn box_clone(&self) -> Box<dyn SenseFn<Ctx>>; fn box_clone(&self) -> Box<dyn SenseFn<Ctx>>;
} }
impl<F: FnMut(&mut Ui<Ctx>, &mut Ctx) + 'static + Clone, Ctx> SenseFn<Ctx> for F { impl<F: FnMut(SenseCtx<Ctx>) + 'static + Clone, Ctx> SenseFn<Ctx> for F {
fn box_clone(&self) -> Box<dyn SenseFn<Ctx>> { fn box_clone(&self) -> Box<dyn SenseFn<Ctx>> {
Box::new(self.clone()) Box::new(self.clone())
} }
@@ -77,7 +81,10 @@ impl<Ctx> Ui<Ctx> {
for sensor in &mut group.sensors { for sensor in &mut group.sensors {
if should_run(sensor.sense, group.cursor, group.hover) { if should_run(sensor.sense, group.cursor, group.hover) {
(sensor.f.box_clone())(self, ctx); (sensor.f.box_clone())(SenseCtx {
ui: self,
app: ctx,
});
} }
} }
} }

View File

@@ -84,10 +84,9 @@ impl Client {
let main = main.clone(); let main = main.clone();
let to = to.clone().erase_type(); let to = to.clone().erase_type();
Rect::new(color) Rect::new(color)
.on(Sense::PressEnd, |_, _| {}) .id_on(Sense::PressStart, move |id, ctx| {
.id_on(Sense::PressStart, move |id, ui, _| { ctx.ui[&main].inner = to.clone();
ui[&main].inner = to.clone(); ctx.ui[id].color = color.add_rgb(-0.2);
ui[id].color = color.add_rgb(-0.2);
}) })
.edit_on(Sense::HoverStart, move |r, _| { .edit_on(Sense::HoverStart, move |r, _| {
r.color = color.add_rgb(0.1); r.color = color.add_rgb(0.1);
@@ -110,8 +109,8 @@ impl Client {
); );
let test_button = Rect::new(Color::PURPLE) let test_button = Rect::new(Color::PURPLE)
.radius(30) .radius(30)
.on(Sense::PressStart, move |ui, _| { .on(Sense::PressStart, move |ctx| {
println!("{}", ui.num_widgets()); println!("{}", ctx.ui.num_widgets());
}) })
.region( .region(
UiRegion::corner(Corner::BotRight) UiRegion::corner(Corner::BotRight)
@@ -122,8 +121,8 @@ impl Client {
let s = span_add.clone(); let s = span_add.clone();
let del_button = Rect::new(Color::RED) let del_button = Rect::new(Color::RED)
.radius(30) .radius(30)
.on(Sense::PressStart, move |ui, _| { .on(Sense::PressStart, move |ctx| {
ui[&s].children.pop(); ctx.ui[&s].children.pop();
}) })
.region( .region(
UiRegion::corner(Corner::BotLeft) UiRegion::corner(Corner::BotLeft)