From e41970287d3e7b745551f9dab82454b5aa41aa9e Mon Sep 17 00:00:00 2001 From: Shadow Cat Date: Thu, 14 Aug 2025 12:21:26 -0400 Subject: [PATCH] TAG TECHNOLOGY --- src/base/trait_fns.rs | 37 ------------- src/{base => core}/frame.rs | 12 ++-- src/{base => core}/mod.rs | 2 + src/{base => core}/num.rs | 0 src/{base => core}/rect.rs | 4 +- src/core/sense.rs | 35 ++++++++++++ src/{base => core}/span.rs | 8 +-- src/core/trait_fns.rs | 39 +++++++++++++ src/layout/mod.rs | 2 +- src/layout/painter.rs | 28 ++++++---- src/layout/region.rs | 6 +- src/layout/ui.rs | 99 +++++++++++++++++++++++---------- src/layout/widget.rs | 106 ++++++++++++++++++------------------ src/lib.rs | 6 +- src/render/data.rs | 4 +- src/render/mod.rs | 14 ++++- src/testing/mod.rs | 12 +++- src/testing/render/mod.rs | 6 +- src/util/id.rs | 12 ++-- 19 files changed, 267 insertions(+), 165 deletions(-) delete mode 100644 src/base/trait_fns.rs rename src/{base => core}/frame.rs (73%) rename src/{base => core}/mod.rs (83%) rename src/{base => core}/num.rs (100%) rename src/{base => core}/rect.rs (89%) create mode 100644 src/core/sense.rs rename src/{base => core}/span.rs (92%) create mode 100644 src/core/trait_fns.rs diff --git a/src/base/trait_fns.rs b/src/base/trait_fns.rs deleted file mode 100644 index 90627c3..0000000 --- a/src/base/trait_fns.rs +++ /dev/null @@ -1,37 +0,0 @@ -use super::*; -use crate::{UIRegion, Ui, Vec2, WidgetArrLike, WidgetFn, WidgetFnRet, WidgetLike}; - -pub trait BaseWidget { - fn pad(self, padding: impl Into) -> WidgetFnRet!(Regioned); - fn center(self, size: impl Into) -> WidgetFnRet!(Regioned); -} - -impl BaseWidget for W { - fn pad(self, padding: impl Into) -> WidgetFnRet!(Regioned) { - WidgetFn(|ui| Regioned { - region: padding.into().region(), - inner: self.add(ui).erase_type(), - }) - } - - fn center(self, size: impl Into) -> WidgetFnRet!(Regioned) { - WidgetFn(|ui| Regioned { - region: UIRegion::center(size.into()), - inner: self.add(ui).erase_type(), - }) - } -} - -pub trait BaseWidgetArr { - fn span(self, dir: Dir, lengths: [impl Into; LEN]) -> WidgetFnRet!(Span); -} - -impl> BaseWidgetArr for Wa { - fn span(self, dir: Dir, lengths: [impl Into; LEN]) -> WidgetFnRet!(Span) { - let lengths = lengths.map(Into::into); - WidgetFn(move |ui| Span { - dir, - children: self.ui(ui).arr.into_iter().zip(lengths).collect(), - }) - } -} diff --git a/src/base/frame.rs b/src/core/frame.rs similarity index 73% rename from src/base/frame.rs rename to src/core/frame.rs index eaf4dce..7b9bd15 100644 --- a/src/base/frame.rs +++ b/src/core/frame.rs @@ -1,12 +1,12 @@ -use crate::{Painter, UINum, UIRegion, Widget, WidgetId}; +use crate::{Painter, UINum, UiRegion, Widget, WidgetId}; pub struct Regioned { - pub region: UIRegion, + pub region: UiRegion, pub inner: WidgetId, } -impl Widget for Regioned { - fn draw(&self, painter: &mut Painter) { +impl Widget for Regioned { + fn draw(&self, painter: &mut Painter) { painter.region.select(&self.region); painter.draw(&self.inner); } @@ -28,8 +28,8 @@ impl Padding { bottom: amt, } } - pub fn region(&self) -> UIRegion { - let mut region = UIRegion::full(); + pub fn region(&self) -> UiRegion { + let mut region = UiRegion::full(); region.top_left.offset.x += self.left; region.top_left.offset.y += self.top; region.bot_right.offset.x -= self.right; diff --git a/src/base/mod.rs b/src/core/mod.rs similarity index 83% rename from src/base/mod.rs rename to src/core/mod.rs index 647220b..2136c32 100644 --- a/src/base/mod.rs +++ b/src/core/mod.rs @@ -1,11 +1,13 @@ mod frame; mod num; mod rect; +mod sense; mod span; mod trait_fns; pub use frame::*; pub use num::*; pub use rect::*; +pub use sense::*; pub use span::*; pub use trait_fns::*; diff --git a/src/base/num.rs b/src/core/num.rs similarity index 100% rename from src/base/num.rs rename to src/core/num.rs diff --git a/src/base/rect.rs b/src/core/rect.rs similarity index 89% rename from src/base/rect.rs rename to src/core/rect.rs index a719af4..e27510e 100644 --- a/src/base/rect.rs +++ b/src/core/rect.rs @@ -23,8 +23,8 @@ impl Rect { } } -impl Widget for Rect { - fn draw(&self, painter: &mut Painter) { +impl Widget for Rect { + fn draw(&self, painter: &mut Painter) { painter.write(RoundedRectData { color: self.color, radius: self.radius, diff --git a/src/core/sense.rs b/src/core/sense.rs new file mode 100644 index 0000000..c598b04 --- /dev/null +++ b/src/core/sense.rs @@ -0,0 +1,35 @@ +use std::marker::PhantomData; + +use crate::{Painter, Widget, WidgetFn, WidgetId, WidgetLike}; + +pub struct Sensor, Ctx> { + inner: WidgetId, + f: F, + _pd: PhantomData, +} + +impl, Ctx: 'static> Widget for Sensor { + fn draw(&self, painter: &mut Painter) { + (self.f)(painter.ctx_mut()); + painter.draw(&self.inner); + } +} + +pub trait SenseFn = Fn(&mut Ctx) + 'static; + +pub trait Sensable { + fn sense>(self, f: F) -> impl WidgetFn, Ctx>; +} + +impl, Ctx: 'static, Tag> Sensable for W { + fn sense>(self, f: F) -> impl WidgetFn, Ctx> { + |ui| { + let inner = self.add(ui).erase_type(); + Sensor { + inner, + f, + _pd: PhantomData, + } + } + } +} diff --git a/src/base/span.rs b/src/core/span.rs similarity index 92% rename from src/base/span.rs rename to src/core/span.rs index f596eb0..67d7fd5 100644 --- a/src/base/span.rs +++ b/src/core/span.rs @@ -1,16 +1,16 @@ -use crate::{Dir, Painter, Sign, UINum, UIRegion, UIScalar, Widget, WidgetId}; +use crate::{Dir, Painter, Sign, UINum, UiRegion, UIScalar, Widget, WidgetId}; pub struct Span { pub children: Vec<(WidgetId, SpanLen)>, pub dir: Dir, } -impl Widget for Span { - fn draw(&self, painter: &mut Painter) { +impl Widget for Span { + fn draw(&self, painter: &mut Painter) { let total = self.sums(); let mut start = UIScalar::min(); for (child, length) in &self.children { - let mut child_region = UIRegion::full(); + let mut child_region = UiRegion::full(); let mut axis = child_region.axis_mut(self.dir.axis); axis.top_left.set(start); match *length { diff --git a/src/core/trait_fns.rs b/src/core/trait_fns.rs new file mode 100644 index 0000000..e81e26a --- /dev/null +++ b/src/core/trait_fns.rs @@ -0,0 +1,39 @@ +use super::*; +use crate::{UiRegion, Vec2, WidgetArrLike, WidgetFn, WidgetLike}; + +pub trait CoreWidget { + fn pad(self, padding: impl Into) -> impl WidgetFn; + fn center(self, size: impl Into) -> impl WidgetFn; +} + +impl, Ctx: 'static, Tag> CoreWidget for W { + fn pad(self, padding: impl Into) -> impl WidgetFn { + |ui| Regioned { + region: padding.into().region(), + inner: self.add(ui).erase_type(), + } + } + + fn center(self, size: impl Into) -> impl WidgetFn { + |ui| Regioned { + region: UiRegion::center(size.into()), + inner: self.add(ui).erase_type(), + } + } +} + +pub trait CoreWidgetArr { + fn span(self, dir: Dir, lengths: [impl Into; LEN]) -> impl WidgetFn; +} + +impl, Ctx: 'static, Tag> CoreWidgetArr + for Wa +{ + fn span(self, dir: Dir, lengths: [impl Into; LEN]) -> impl WidgetFn { + let lengths = lengths.map(Into::into); + move |ui| Span { + dir, + children: self.ui(ui).arr.into_iter().zip(lengths).collect(), + } + } +} diff --git a/src/layout/mod.rs b/src/layout/mod.rs index fab6dcc..6891c09 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -6,10 +6,10 @@ mod vec2; mod widget; pub use color::*; +pub use painter::*; pub use region::*; pub use ui::*; pub use vec2::*; pub use widget::*; -pub use painter::*; pub type UiColor = Color; diff --git a/src/layout/painter.rs b/src/layout/painter.rs index 24d9c2c..4003291 100644 --- a/src/layout/painter.rs +++ b/src/layout/painter.rs @@ -1,20 +1,22 @@ use crate::{ - UIRegion, WidgetId, Widgets, + UiRegion, WidgetId, Widgets, primitive::{PrimitiveData, PrimitiveInstance, Primitives}, }; -pub struct Painter<'a> { - nodes: &'a Widgets, +pub struct Painter<'a, Ctx> { + nodes: &'a Widgets, + ctx: &'a mut Ctx, primitives: Primitives, - pub region: UIRegion, + pub region: UiRegion, } -impl<'a> Painter<'a> { - pub fn new(nodes: &'a Widgets) -> Self { +impl<'a, Ctx> Painter<'a, Ctx> { + pub fn new(nodes: &'a Widgets, ctx: &'a mut Ctx) -> Self { Self { nodes, + ctx, primitives: Primitives::default(), - region: UIRegion::full(), + region: UiRegion::full(), } } pub fn write(&mut self, data: Data) { @@ -28,10 +30,12 @@ impl<'a> Painter<'a> { .data .extend_from_slice(bytemuck::cast_slice::<_, u32>(&[data])); } - pub fn draw(&mut self, node: &WidgetId) { - self.nodes.get_dyn(node).draw(self); + + pub fn draw(&mut self, id: &WidgetId) where Ctx: 'static { + self.nodes.get_dyn(id).draw(self); } - pub fn draw_within(&mut self, node: &WidgetId, region: UIRegion) { + + pub fn draw_within(&mut self, node: &WidgetId, region: UiRegion) where Ctx: 'static { let old = self.region; self.region.select(®ion); self.draw(node); @@ -41,4 +45,8 @@ impl<'a> Painter<'a> { pub fn finish(self) -> Primitives { self.primitives } + + pub fn ctx_mut(&mut self) -> &mut Ctx { + &mut self.ctx + } } diff --git a/src/layout/region.rs b/src/layout/region.rs index 76427fe..bc61169 100644 --- a/src/layout/region.rs +++ b/src/layout/region.rs @@ -36,7 +36,7 @@ impl UIPos { self } - pub const fn within(&self, region: &UIRegion) -> UIPos { + pub const fn within(&self, region: &UiRegion) -> UIPos { let anchor = self .anchor .lerp(region.top_left.anchor, region.bot_right.anchor); @@ -110,12 +110,12 @@ impl UIScalar { #[repr(C)] #[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] -pub struct UIRegion { +pub struct UiRegion { pub top_left: UIPos, pub bot_right: UIPos, } -impl UIRegion { +impl UiRegion { pub const fn full() -> Self { Self { top_left: UIPos::top_left(), diff --git a/src/layout/ui.rs b/src/layout/ui.rs index 1987298..766db67 100644 --- a/src/layout/ui.rs +++ b/src/layout/ui.rs @@ -1,46 +1,60 @@ use crate::{ - HashMap, Painter, Widget, WidgetId, WidgetLike, + HashMap, Painter, Vec2, Widget, WidgetId, WidgetLike, primitive::Primitives, - util::{ID, IDTracker}, + util::{IDTracker, Id}, }; use std::{ any::{Any, TypeId}, ops::{Index, IndexMut}, }; -#[derive(Default)] -pub struct Ui { +pub struct Ui { ids: IDTracker, base: Option, - widgets: Widgets, + widgets: Widgets, updates: Vec, primitives: Primitives, full_redraw: bool, } -#[derive(Default)] -pub struct Widgets(HashMap>); +pub struct MouseState { + pos: Vec2, + primary: ButtonState, + secondary: ButtonState, +} -impl Ui { - pub fn add(&mut self, w: impl WidgetLike) -> WidgetId { +pub enum ButtonState { + JustPressed, + Pressed, + Released, +} + +#[derive(Default)] +pub struct Widgets(HashMap>>); + +impl Ui { + pub fn add, Tag>( + &mut self, + w: impl WidgetLike, + ) -> WidgetId { w.add(self) } - pub fn add_widget(&mut self, w: W) -> WidgetId { + pub fn add_widget>(&mut self, w: W) -> WidgetId { self.push(w) } - pub fn push(&mut self, w: W) -> WidgetId { + pub fn push>(&mut self, w: W) -> WidgetId { let id = self.ids.next(); self.widgets.insert(id.duplicate(), w); WidgetId::new(id, TypeId::of::()) } - pub fn set(&mut self, i: &WidgetId, w: W) { + pub fn set>(&mut self, i: &WidgetId, w: W) { self.widgets.insert(i.id.duplicate(), w); } - pub fn set_base(&mut self, w: impl WidgetLike) { + pub fn set_base(&mut self, w: impl WidgetLike) { self.base = Some(w.add(self).erase_type()); self.full_redraw = true; } @@ -49,36 +63,42 @@ impl Ui { Self::default() } - pub fn get(&self, id: &WidgetId) -> Option<&W> { + pub fn get>(&self, id: &WidgetId) -> Option<&W> { self.widgets.get(id) } - pub fn get_mut(&mut self, id: &WidgetId) -> Option<&mut W> { + pub fn get_mut>(&mut self, id: &WidgetId) -> Option<&mut W> { self.widgets.get_mut(id) } - pub fn id(&mut self) -> WidgetId { + pub fn id>(&mut self) -> WidgetId { WidgetId::new(self.ids.next(), TypeId::of::()) } - pub fn redraw_all(&mut self) { - let mut painter = Painter::new(&self.widgets); + pub fn redraw_all(&mut self, ctx: &mut Ctx) + where + Ctx: 'static, + { + let mut painter = Painter::new(&self.widgets, ctx); if let Some(base) = &self.base { painter.draw(base); } self.primitives = painter.finish(); } - pub fn update(&mut self) -> Option<&Primitives> { + pub fn update(&mut self, ctx: &mut Ctx) -> Option<&Primitives> + where + Ctx: 'static, + { if self.full_redraw { - self.redraw_all(); + self.redraw_all(ctx); self.full_redraw = false; return Some(&self.primitives); } if self.updates.is_empty() { return None; } - self.redraw_all(); + self.redraw_all(ctx); self.updates.drain(..); Some(&self.primitives) } @@ -86,9 +106,11 @@ impl Ui { pub fn needs_redraw(&self) -> bool { self.full_redraw || !self.updates.is_empty() } + + pub fn set_mouse_pos(&mut self) {} } -impl Index<&WidgetId> for Ui { +impl, Ctx> Index<&WidgetId> for Ui { type Output = W; fn index(&self, id: &WidgetId) -> &Self::Output { @@ -96,36 +118,40 @@ impl Index<&WidgetId> for Ui { } } -impl IndexMut<&WidgetId> for Ui { +impl, Ctx> IndexMut<&WidgetId> for Ui { fn index_mut(&mut self, id: &WidgetId) -> &mut Self::Output { self.updates.push(id.clone().erase_type()); self.get_mut(id).unwrap() } } -impl Widgets { - pub fn get_dyn(&self, id: &WidgetId) -> &dyn Widget { +impl Widgets { + pub fn new() -> Self { + Self(HashMap::new()) + } + + pub fn get_dyn(&self, id: &WidgetId) -> &dyn Widget { self.0.get(&id.id).unwrap().as_ref() } - pub fn get(&self, id: &WidgetId) -> Option<&W> { + pub fn get>(&self, id: &WidgetId) -> Option<&W> { self.0.get(&id.id).unwrap().as_any().downcast_ref() } - pub fn get_mut(&mut self, id: &WidgetId) -> Option<&mut W> { + pub fn get_mut>(&mut self, id: &WidgetId) -> Option<&mut W> { self.0.get_mut(&id.id).unwrap().as_any_mut().downcast_mut() } - pub fn insert(&mut self, id: ID, widget: impl Widget) { + pub fn insert(&mut self, id: Id, widget: impl Widget) { self.0.insert(id, Box::new(widget)); } - pub fn insert_any(&mut self, id: ID, widget: Box) { + pub fn insert_any(&mut self, id: Id, widget: Box>) { self.0.insert(id, widget); } } -impl dyn Widget { +impl dyn Widget { pub fn as_any(&self) -> &dyn Any { self } @@ -134,3 +160,16 @@ impl dyn Widget { self } } + +impl Default for Ui { + fn default() -> Self { + Self { + ids: Default::default(), + base: Default::default(), + widgets: Widgets::new(), + updates: Default::default(), + primitives: Default::default(), + full_redraw: Default::default(), + } + } +} diff --git a/src/layout/widget.rs b/src/layout/widget.rs index 7f1eebb..f8d3df4 100644 --- a/src/layout/widget.rs +++ b/src/layout/widget.rs @@ -3,10 +3,10 @@ use std::{ marker::PhantomData, }; -use crate::{Painter, Ui, util::ID}; +use crate::{Painter, Ui, util::Id}; -pub trait Widget: 'static + Any { - fn draw(&self, painter: &mut Painter); +pub trait Widget: Any { + fn draw(&self, painter: &mut Painter); } pub struct AnyWidget; @@ -19,7 +19,7 @@ pub struct AnyWidget; #[derive(Eq, Hash, PartialEq, Debug)] pub struct WidgetId { pub(super) ty: TypeId, - pub(super) id: ID, + pub(super) id: Id, _pd: PhantomData, } @@ -31,7 +31,7 @@ impl Clone for WidgetId { } impl WidgetId { - pub(super) fn new(id: ID, ty: TypeId) -> Self { + pub(super) fn new(id: Id, ty: TypeId) -> Self { Self { ty, id, @@ -51,85 +51,81 @@ impl WidgetId { } } -pub trait WidgetLike { +pub struct WidgetTag; +pub struct FnTag; +pub struct IdTag; + +pub trait WidgetLike { type Widget; - fn add(self, ui: &mut Ui) -> WidgetId; + fn add(self, ui: &mut Ui) -> WidgetId; } /// A function that returns a widget given a UI. /// Useful for defining trait functions on widgets that create a parent widget so that the children /// don't need to be IDs yet -pub trait WFn = FnOnce(&mut Ui) -> W; -pub struct WidgetFn W, W>(pub F); -pub struct WidgetIdFn WidgetId, W>(pub F); +pub trait WidgetFn, Ctx> = FnOnce(&mut Ui) -> W; +pub trait WidgetIdFn, Ctx> = FnOnce(&mut Ui) -> WidgetId; -macro_rules! WidgetFnRet { - ($W:ident) => { - WidgetFn $W, $W> - }; -} -pub(crate) use WidgetFnRet; - -pub trait Idable { - type Widget: Widget; - fn set(self, ui: &mut Ui, id: &WidgetId); +pub trait Idable { + type Widget: Widget; + fn set(self, ui: &mut Ui, id: &WidgetId); } -pub trait WidgetFns { - fn id(self, id: &WidgetId) -> impl WidgetLike; +pub trait WidgetFns, Ctx, Tag> { + fn id(self, id: &WidgetId) -> impl WidgetIdFn; } -impl WidgetFns for I { - fn id(self, id: &WidgetId) -> impl WidgetLike { - WidgetIdFn(|ui| { +impl, Ctx, Tag> WidgetFns for I { + fn id(self, id: &WidgetId) -> impl WidgetIdFn { + |ui| { self.set(ui, id); id.clone() - }) + } } } -impl Idable for W { +impl, Ctx> Idable for W { type Widget = W; - fn set(self, ui: &mut Ui, id: &WidgetId) { + fn set(self, ui: &mut Ui, id: &WidgetId) { ui.set(id, self); } } -impl FnOnce(&'a mut Ui) -> W, W: Widget> Idable for WidgetFn { +impl) -> W, W: Widget, Ctx> Idable for F { type Widget = W; - fn set(self, ui: &mut Ui, id: &WidgetId) { - let w = self.0(ui); + fn set(self, ui: &mut Ui, id: &WidgetId) { + let w = self(ui); ui.set(id, w); } } -impl W> WidgetLike for WidgetFn { +impl, Ctx, F: FnOnce(&mut Ui) -> W> WidgetLike for F { type Widget = W; - fn add(self, ui: &mut Ui) -> WidgetId { - let w = (self.0)(ui); + fn add(self, ui: &mut Ui) -> WidgetId { + let w = self(ui); ui.add(w) } } -impl WidgetId> WidgetLike for WidgetIdFn { +impl, F: FnOnce(&mut Ui) -> WidgetId, Ctx> WidgetLike for F { type Widget = W; - fn add(self, ui: &mut Ui) -> WidgetId { - (self.0)(ui) + fn add(self, ui: &mut Ui) -> WidgetId { + self(ui) } } -impl WidgetLike for W { +impl, Ctx> WidgetLike for W { type Widget = W; - fn add(self, ui: &mut Ui) -> WidgetId { + fn add(self, ui: &mut Ui) -> WidgetId { ui.add_widget(self) } } -impl WidgetLike for WidgetId { +impl, Ctx> WidgetLike for WidgetId { type Widget = W; - fn add(self, _: &mut Ui) -> WidgetId { + fn add(self, _: &mut Ui) -> WidgetId { self } } @@ -148,35 +144,39 @@ impl WidgetArr { } } -pub trait WidgetArrLike { +pub struct ArrTag; +pub trait WidgetArrLike { type Ws; - fn ui(self, ui: &mut Ui) -> WidgetArr; + fn ui(self, ui: &mut Ui) -> WidgetArr; } -impl WidgetArrLike for WidgetArr { +impl WidgetArrLike for WidgetArr { type Ws = Ws; - fn ui(self, _: &mut Ui) -> WidgetArr { + fn ui(self, _: &mut Ui) -> WidgetArr { self } } -impl WidgetArrLike<1> for W { +impl, Ctx> WidgetArrLike<1, Ctx, WidgetTag> for W { type Ws = (W::Widget,); - fn ui(self, ui: &mut Ui) -> WidgetArr<1, (W::Widget,)> { + fn ui(self, ui: &mut Ui) -> WidgetArr<1, (W::Widget,)> { WidgetArr::new([self.add(ui).erase_type()]) } } // I hate this language it's so bad why do I even use it macro_rules! impl_widget_arr { - ($n:expr;$($T:tt)*) => { - impl<$($T: WidgetLike,)*> WidgetArrLike<$n> for ($($T,)*) { - type Ws = ($($T::Widget,)*); - fn ui(self, ui: &mut Ui) -> WidgetArr<$n, ($($T::Widget,)*)> { + ($n:expr;$($W:ident)*) => { + impl_widget_arr!($n;$($W)*;$(${concat($W,Tag)})*); + }; + ($n:expr;$($W:ident)*;$($Tag:ident)*) => { + impl<$($W: WidgetLike,$Tag,)* Ctx> WidgetArrLike<$n, Ctx, ($($Tag,)*)> for ($($W,)*) { + type Ws = ($($W::Widget,)*); + fn ui(self, ui: &mut Ui) -> WidgetArr<$n, ($($W::Widget,)*)> { #[allow(non_snake_case)] - let ($($T,)*) = self; + let ($($W,)*) = self; WidgetArr::new( - [$($T.add(ui).cast_type(),)*], + [$($W.add(ui).cast_type(),)*], ) } } diff --git a/src/lib.rs b/src/lib.rs index 89d2b0e..5ba7372 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,14 +3,16 @@ #![feature(const_trait_impl)] #![feature(const_from)] #![feature(trait_alias)] +#![feature(negative_impls)] mod layout; mod render; mod util; -mod base; +mod core; pub use layout::*; pub use render::*; -pub use base::*; +pub use core::*; pub type HashMap = std::collections::HashMap; +pub type HashSet = std::collections::HashSet; diff --git a/src/render/data.rs b/src/render/data.rs index c0e02b9..299299b 100644 --- a/src/render/data.rs +++ b/src/render/data.rs @@ -1,6 +1,6 @@ use wgpu::VertexAttribute; -use crate::UIRegion; +use crate::UiRegion; #[repr(C)] #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable, Default)] @@ -12,7 +12,7 @@ pub struct WindowUniform { #[repr(C)] #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] pub struct PrimitiveInstance { - pub region: UIRegion, + pub region: UiRegion, pub ptr: u32, } diff --git a/src/render/mod.rs b/src/render/mod.rs index 0dc36fc..cc963e4 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -1,4 +1,7 @@ -use crate::{Ui, primitive::PrimitiveInstance, render::util::ArrBuf}; +use crate::{ + primitive::{PrimitiveInstance, Primitives}, + render::util::ArrBuf, +}; use data::WindowUniform; use wgpu::{ util::{BufferInitDescriptor, DeviceExt}, @@ -32,8 +35,13 @@ impl UIRenderNode { } } - pub fn update(&mut self, device: &Device, queue: &Queue, ui: &mut Ui) { - if let Some(primitives) = ui.update() { + pub fn update( + &mut self, + device: &Device, + queue: &Queue, + primitives: Option<&Primitives>, + ) { + if let Some(primitives) = primitives { self.instance.update(device, queue, &primitives.instances); self.data.update(device, queue, &primitives.data); self.bind_group = Self::bind_group( diff --git a/src/testing/mod.rs b/src/testing/mod.rs index d1cdd8c..a530518 100644 --- a/src/testing/mod.rs +++ b/src/testing/mod.rs @@ -12,9 +12,13 @@ pub fn main() { App::run(); } +struct Data { + x: u32, +} + pub struct Client { renderer: Renderer, - ui: Ui, + ui: Ui, test: WidgetId, } @@ -32,7 +36,8 @@ impl Client { ui.set_base( ( ( - rect.color(UiColor::BLUE), + rect.color(UiColor::BLUE) + .sense(|d: &mut Data| println!("{}", d.x)), ( rect.color(UiColor::RED).center((100.0, 100.0)), ( @@ -77,7 +82,8 @@ impl Client { match event { WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::RedrawRequested => { - self.renderer.update(&mut self.ui); + let primitives = self.ui.update(&mut Data { x: 39 }); + self.renderer.update(primitives); self.renderer.draw() } WindowEvent::Resized(size) => self.renderer.resize(&size), diff --git a/src/testing/render/mod.rs b/src/testing/render/mod.rs index a353d28..3069b0a 100644 --- a/src/testing/render/mod.rs +++ b/src/testing/render/mod.rs @@ -1,4 +1,4 @@ -use gui::{UIRenderNode, Ui}; +use gui::{primitive::Primitives, UIRenderNode, Ui}; use pollster::FutureExt; use std::sync::Arc; use wgpu::util::StagingBelt; @@ -18,8 +18,8 @@ pub struct Renderer { } impl Renderer { - pub fn update(&mut self, ui: &mut Ui) { - self.ui_node.update(&self.device, &self.queue, ui); + pub fn update(&mut self, primitives: Option<&Primitives>) { + self.ui_node.update(&self.device, &self.queue, primitives); } pub fn draw(&mut self) { diff --git a/src/util/id.rs b/src/util/id.rs index d5fd9ae..cdb8b9f 100644 --- a/src/util/id.rs +++ b/src/util/id.rs @@ -4,11 +4,11 @@ /// point to something valid, although duplicate /// gets around this if needed #[derive(Eq, Hash, PartialEq, Debug)] -pub struct ID(u64); +pub struct Id(u64); #[derive(Default)] pub struct IDTracker { - free: Vec, + free: Vec, cur: u64, } @@ -18,22 +18,22 @@ impl IDTracker { } #[allow(clippy::should_implement_trait)] - pub fn next(&mut self) -> ID { + pub fn next(&mut self) -> Id { if let Some(id) = self.free.pop() { return id; } - let id = ID(self.cur); + let id = Id(self.cur); self.cur += 1; id } #[allow(dead_code)] - pub fn free(&mut self, id: ID) { + pub fn free(&mut self, id: Id) { self.free.push(id); } } -impl ID { +impl Id { /// this must be used carefully to make sure /// all IDs are still valid references; /// named weirdly to indicate this.