diff --git a/fm:w b/fm:w deleted file mode 100644 index 8292549..0000000 --- a/fm:w +++ /dev/null @@ -1,400 +0,0 @@ -use crate::prelude::*; -use iris_core::util::{HashMap}; -use std::{ - ops::{BitOr, Deref, DerefMut}, - rc::Rc, -}; - - - -#[derive(Clone, Copy, PartialEq)] -pub enum Button { - Left, - Right, - Middle, -} - -#[derive(Clone, Copy, PartialEq)] -pub enum CursorSense { - PressStart(Button), - Pressing(Button), - PressEnd(Button), - HoverStart, - Hovering, - HoverEnd, - Scroll, -} - -pub struct CursorSenses(Vec); - -impl CursorSense { - pub fn click() -> Self { - Self::PressStart(Button::Left) - } - pub fn click_or_drag() -> CursorSenses { - Self::click() | Self::Pressing(Button::Left) - } - pub fn unclick() -> Self { - Self::PressEnd(Button::Left) - } - pub fn is_dragging(&self) -> bool { - matches!(self, CursorSense::Pressing(Button::Left)) - } -} - -#[derive(Default, Clone)] -pub struct CursorState { - pub pos: Vec2, - pub exists: bool, - pub buttons: CursorButtons, - pub scroll_delta: Vec2, -} - -#[derive(Default, Clone)] -pub struct CursorButtons { - pub left: ActivationState, - pub middle: ActivationState, - pub right: ActivationState, -} - -impl CursorButtons { - pub fn select(&self, button: &Button) -> &ActivationState { - match button { - Button::Left => &self.left, - Button::Right => &self.right, - Button::Middle => &self.middle, - } - } - - pub fn end_frame(&mut self) { - self.left.end_frame(); - self.middle.end_frame(); - self.right.end_frame(); - } -} - -impl CursorState { - pub fn end_frame(&mut self) { - self.buttons.end_frame(); - self.scroll_delta = Vec2::ZERO; - } -} - -#[derive(Debug, Clone, Copy, Default, PartialEq)] -pub enum ActivationState { - Start, - On, - End, - #[default] - Off, -} - -/// this and other similar stuff has a generic -/// because I kind of want to make CursorModule generic -/// or basically have some way to have custom senses -/// that depend on active widget positions -/// but I'm not sure how or if worth it -pub struct Sensor { - pub senses: CursorSenses, - pub f: Rc>, -} - -pub type SensorMap = HashMap>; -pub type SenseShape = UiRegion; -pub struct SensorGroup { - pub hover: ActivationState, - pub sensors: Vec>, -} - -#[derive(Clone)] -pub struct CursorData { - pub cursor: Vec2, - pub size: Vec2, - pub scroll_delta: Vec2, - /// the (first) sense that triggered this event - /// the senses are checked in order - pub sense: CursorSense, -} - -pub struct CursorModule { - map: SensorMap, - active: HashMap>, -} - -impl UiModule for CursorModule { - fn on_draw(&mut self, inst: &ActiveData) { - if self.map.contains_key(&inst.id) { - self.active - .entry(inst.layer) - .or_default() - .insert(inst.id, inst.region); - } - } - - fn on_undraw(&mut self, inst: &ActiveData) { - if let Some(layer) = self.active.get_mut(&inst.layer) { - layer.remove(&inst.id); - } - } - - fn on_remove(&mut self, id: &Id) { - self.map.remove(id); - for layer in self.active.values_mut() { - layer.remove(id); - } - } - - fn on_move(&mut self, inst: &ActiveData) { - if let Some(map) = self.active.get_mut(&inst.layer) - && let Some(region) = map.get_mut(&inst.id) - { - *region = inst.region; - } - } -} - -impl CursorModule { - pub fn merge(&mut self, other: Self) { - for (id, group) in other.map { - for sensor in group.sensors { - self.map.entry(id).or_default().sensors.push(sensor); - } - } - } -} - -pub trait SensorUi { - fn run_sensors(&mut self, ctx: &mut Ctx, cursor: &CursorState, window_size: Vec2); -} - -impl SensorUi for Ui { - fn run_sensors( - &mut self, - ctx: &mut Ctx, - cursor: &CursorState, - window_size: Vec2, - ) { - CursorModule::::run(self, ctx, cursor, window_size); - } -} - -impl CursorModule { - pub fn run(ui: &mut Ui, ctx: &mut Ctx, cursor: &CursorState, window_size: Vec2) { - let layers = std::mem::take(&mut ui.data.layers); - let mut module = std::mem::take(ui.data.modules.get_mut::()); - - for i in layers.indices().rev() { - let Some(list) = module.active.get_mut(&i) else { - continue; - }; - let mut sensed = false; - for (id, shape) in list.iter() { - let group = module.map.get_mut(id).unwrap(); - let region = shape.to_px(window_size); - let in_shape = cursor.exists && region.contains(cursor.pos); - group.hover.update(in_shape); - if group.hover == ActivationState::Off { - continue; - } - sensed = true; - - for sensor in &mut group.sensors { - if let Some(sense) = should_run(&sensor.senses, cursor, group.hover) { - let data = CursorData { - cursor: cursor.pos - region.top_left, - size: region.bot_right - region.top_left, - scroll_delta: cursor.scroll_delta, - sense, - }; - (sensor.f)(EventCtx { - ui, - state: ctx, - data, - }); - } - } - } - if sensed { - break; - } - } - - let ui_mod = ui.data.modules.get_mut::(); - std::mem::swap(ui_mod, &mut module); - ui_mod.merge(module); - ui.data.layers = layers; - } -} - -pub fn should_run( - senses: &CursorSenses, - cursor: &CursorState, - hover: ActivationState, -) -> Option { - for sense in senses.iter() { - if match sense { - CursorSense::PressStart(button) => cursor.buttons.select(button).is_start(), - CursorSense::Pressing(button) => cursor.buttons.select(button).is_on(), - CursorSense::PressEnd(button) => cursor.buttons.select(button).is_end(), - CursorSense::HoverStart => hover.is_start(), - CursorSense::Hovering => hover.is_on(), - CursorSense::HoverEnd => hover.is_end(), - CursorSense::Scroll => cursor.scroll_delta != Vec2::ZERO, - } { - return Some(*sense); - } - } - None -} - -impl ActivationState { - pub fn is_start(&self) -> bool { - *self == Self::Start - } - pub fn is_on(&self) -> bool { - *self == Self::Start || *self == Self::On - } - pub fn is_end(&self) -> bool { - *self == Self::End - } - pub fn is_off(&self) -> bool { - *self == Self::End || *self == Self::Off - } - pub fn update(&mut self, on: bool) { - *self = match *self { - Self::Start => match on { - true => Self::On, - false => Self::End, - }, - Self::On => match on { - true => Self::On, - false => Self::End, - }, - Self::End => match on { - true => Self::Start, - false => Self::Off, - }, - Self::Off => match on { - true => Self::Start, - false => Self::Off, - }, - } - } - - pub fn end_frame(&mut self) { - match self { - Self::Start => *self = Self::On, - Self::End => *self = Self::Off, - _ => (), - } - } -} - -impl Event for CursorSenses { - type Module = CursorModule; - type Data = CursorData; -} - -impl Event for CursorSense { - type Module = CursorModule; - type Data = CursorData; -} - -impl::Data> + Into, Ctx: 'static> - EventModule for CursorModule -{ - fn register(&mut self, id: Id, senses: E, f: impl EventFn::Data>) { - // TODO: does not add to active if currently active - self.map.entry(id).or_default().sensors.push(Sensor { - senses: senses.into(), - f: Rc::new(f), - }); - } - - fn run<'a>( - &self, - id: &Id, - event: E, - ) -> Option::Data>) + use<'a, E, Ctx>> { - let senses = event.into(); - if let Some(group) = self.map.get(id) { - let fs: Vec<_> = group - .sensors - .iter() - .filter_map(|sensor| { - if sensor.senses.iter().any(|s| senses.contains(s)) { - Some(sensor.f.clone()) - } else { - None - } - }) - .collect(); - Some(move |ctx: EventCtx| { - for f in &fs { - f(EventCtx { - state: ctx.state, - ui: ctx.ui, - data: ctx.data.clone(), - }); - } - }) - } else { - None - } - } -} - -impl Default for SensorGroup { - fn default() -> Self { - Self { - hover: Default::default(), - sensors: Default::default(), - } - } -} - -impl Deref for CursorSenses { - type Target = Vec; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for CursorSenses { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl From for CursorSenses { - fn from(val: CursorSense) -> Self { - CursorSenses(vec![val]) - } -} - -impl BitOr for CursorSense { - type Output = CursorSenses; - - fn bitor(self, rhs: Self) -> Self::Output { - CursorSenses(vec![self, rhs]) - } -} - -impl BitOr for CursorSenses { - type Output = Self; - - fn bitor(mut self, rhs: CursorSense) -> Self::Output { - self.0.push(rhs); - self - } -} - -impl Default for CursorModule { - fn default() -> Self { - Self { - map: Default::default(), - active: Default::default(), - } - } -}