IDC FINALLY OH MY GOD (I think like ctx + resize propagation + some other stuff)

This commit is contained in:
2025-09-11 00:59:26 -04:00
parent 709a2d0e17
commit 242c3b992e
15 changed files with 476 additions and 281 deletions

View File

@@ -1,7 +1,5 @@
use std::any::Any;
use crate::{
layout::{Ui, UiRegion, Vec2, WidgetId},
layout::{Ui, UiRegion, Vec2},
util::{HashMap, Id, bitflags},
};
@@ -30,19 +28,18 @@ pub enum ActivationState {
Off,
}
pub struct Sensor {
pub struct Sensor<Ctx> {
pub senses: Senses,
pub f: Box<dyn SenseFn>,
pub f: Box<dyn SenseFn<Ctx>>,
}
pub type SensorMap = HashMap<Id, SensorGroup>;
pub type SensorMap<Ctx> = HashMap<Id, SensorGroup<Ctx>>;
pub type ActiveSensors = HashMap<Id, SenseShape>;
pub type SenseShape = UiRegion;
#[derive(Default)]
pub struct SensorGroup {
pub struct SensorGroup<Ctx> {
pub hover: ActivationState,
pub cursor: ActivationState,
pub sensors: Vec<Sensor>,
pub sensors: Vec<Sensor<Ctx>>,
}
pub struct SenseCtx {
@@ -50,41 +47,37 @@ pub struct SenseCtx {
pub size: Vec2,
}
pub trait SenseFn: FnMut(&mut Ui, SenseCtx) + 'static {}
impl<F: FnMut(&mut Ui, SenseCtx) + 'static> SenseFn for F {}
pub trait SenseFn<Ctx>: FnMut(&mut Ctx, SenseCtx) + 'static {}
impl<F: FnMut(&mut Ctx, SenseCtx) + 'static, Ctx> SenseFn<Ctx> for F {}
impl Ui {
pub fn add_sensor<W>(&mut self, id: &WidgetId<W>, f: Sensor) {
self.sensor_map
.entry(id.id.duplicate())
.or_default()
.sensors
.push(f);
}
pub trait UiCtx {
fn ui(&mut self) -> &mut Ui<Self>
where
Self: Sized;
}
pub fn run_sensors(&mut self, cursor: &CursorState, window_size: Vec2) {
let active = std::mem::take(&mut self.active.sensors);
let mut map = std::mem::take(&mut self.sensor_map);
for (id, shape) in active.iter() {
let group = &mut map.get_mut(id).unwrap();
let region = shape.to_screen(window_size);
let in_shape = cursor.exists && region.contains(cursor.pos);
group.hover.update(in_shape);
group.cursor.update(cursor.pressed && in_shape);
pub fn run_sensors<Ctx: UiCtx>(ctx: &mut Ctx, cursor: &CursorState, window_size: Vec2) {
let active = std::mem::take(&mut ctx.ui().active.sensors);
let mut map = std::mem::take(&mut ctx.ui().sensor_map);
for (id, shape) in active.iter() {
let group = &mut map.get_mut(id).unwrap();
let region = shape.to_screen(window_size);
let in_shape = cursor.exists && region.contains(cursor.pos);
group.hover.update(in_shape);
group.cursor.update(cursor.pressed && in_shape);
for sensor in &mut group.sensors {
if should_run(sensor.senses, group.cursor, group.hover) {
let ctx = SenseCtx {
cursor: cursor.pos - region.top_left,
size: region.bot_right - region.top_left,
};
(sensor.f)(self, ctx);
}
for sensor in &mut group.sensors {
if should_run(sensor.senses, group.cursor, group.hover) {
let sctx = SenseCtx {
cursor: cursor.pos - region.top_left,
size: region.bot_right - region.top_left,
};
(sensor.f)(ctx, sctx);
}
}
self.sensor_map = map;
self.active.sensors = active;
}
ctx.ui().sensor_map = map;
ctx.ui().active.sensors = active;
}
pub fn should_run(senses: Senses, cursor: ActivationState, hover: ActivationState) -> bool {
@@ -138,3 +131,13 @@ impl ActivationState {
}
}
}
impl<Ctx> Default for SensorGroup<Ctx> {
fn default() -> Self {
Self {
hover: Default::default(),
cursor: Default::default(),
sensors: Default::default(),
}
}
}