IDC FINALLY OH MY GOD (I think like ctx + resize propagation + some other stuff)
This commit is contained in:
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user