From 90c579d7346e9163e18e05ad57e13a77a5b2b549 Mon Sep 17 00:00:00 2001 From: shadow cat Date: Sat, 22 Nov 2025 20:22:26 -0500 Subject: [PATCH] oopsie (orderlerss -> ordered rendering) --- src/bin/test/main.rs | 2 +- src/core/position/layer.rs | 23 ++++++++ src/core/position/mod.rs | 2 + src/core/position/stack.rs | 12 ----- src/core/text/mod.rs | 3 +- src/core/trait_fns.rs | 10 ++-- src/layout/layer.rs | 105 ++++++++++++++++++++----------------- src/layout/painter.rs | 8 +-- src/layout/ui.rs | 12 +++++ src/render/mod.rs | 3 +- 10 files changed, 105 insertions(+), 75 deletions(-) create mode 100644 src/core/position/layer.rs diff --git a/src/bin/test/main.rs b/src/bin/test/main.rs index 36888b0..460ef20 100644 --- a/src/bin/test/main.rs +++ b/src/bin/test/main.rs @@ -203,7 +203,7 @@ impl Client { ) .stack() .size(StackSize::Child(1)) - .offset_layer(1) + .layer_offset(1) .align(Align::BOT), ) .span(Dir::DOWN) diff --git a/src/core/position/layer.rs b/src/core/position/layer.rs new file mode 100644 index 0000000..58bb7bd --- /dev/null +++ b/src/core/position/layer.rs @@ -0,0 +1,23 @@ +use crate::prelude::*; + +pub struct LayerOffset { + pub inner: WidgetId, + pub offset: usize, +} + +impl Widget for LayerOffset { + fn draw(&mut self, painter: &mut Painter) { + for _ in 0..self.offset { + painter.next_layer(); + } + painter.widget(&self.inner); + } + + fn desired_width(&mut self, ctx: &mut SizeCtx) -> Len { + ctx.width(&self.inner) + } + + fn desired_height(&mut self, ctx: &mut SizeCtx) -> Len { + ctx.height(&self.inner) + } +} diff --git a/src/core/position/mod.rs b/src/core/position/mod.rs index 159c1f0..c389b6c 100644 --- a/src/core/position/mod.rs +++ b/src/core/position/mod.rs @@ -1,4 +1,5 @@ mod align; +mod layer; mod max_size; mod offset; mod pad; @@ -8,6 +9,7 @@ mod span; mod stack; pub use align::*; +pub use layer::*; pub use max_size::*; pub use offset::*; pub use pad::*; diff --git a/src/core/position/stack.rs b/src/core/position/stack.rs index 60bfb74..178ecc2 100644 --- a/src/core/position/stack.rs +++ b/src/core/position/stack.rs @@ -5,14 +5,10 @@ use crate::prelude::*; pub struct Stack { pub children: Vec, pub size: StackSize, - pub offset: usize, } impl Widget for Stack { fn draw(&mut self, painter: &mut Painter) { - for _ in 0..self.offset { - painter.next_layer(); - } let mut iter = self.children.iter(); if let Some(child) = iter.next() { painter.child_layer(); @@ -49,7 +45,6 @@ pub enum StackSize { pub struct StackBuilder, Tag> { pub children: Wa, pub size: StackSize, - pub offset: usize, _pd: PhantomData, } @@ -61,7 +56,6 @@ impl, Tag> FnOnce<(&mut Ui,)> extern "rust-call" fn call_once(self, args: (&mut Ui,)) -> Self::Output { Stack { children: self.children.ui(args.0).arr.to_vec(), - offset: self.offset, size: self.size, } } @@ -72,7 +66,6 @@ impl, Tag> StackBuilder, Tag> StackBuilder Self { - self.offset = offset; - self - } } diff --git a/src/core/text/mod.rs b/src/core/text/mod.rs index 30839a2..1ef3354 100644 --- a/src/core/text/mod.rs +++ b/src/core/text/mod.rs @@ -91,8 +91,9 @@ impl TextView { && line.text().is_empty() { painter.widget(hint); + } else { + painter.texture_within(&tex.handle, region); } - painter.texture_within(&tex.handle, region); region } diff --git a/src/core/trait_fns.rs b/src/core/trait_fns.rs index 24dca87..186f2d2 100644 --- a/src/core/trait_fns.rs +++ b/src/core/trait_fns.rs @@ -15,7 +15,7 @@ pub trait CoreWidget { fn scroll(self) -> impl WidgetIdFn; fn masked(self) -> impl WidgetFn; fn background(self, w: impl WidgetLike) -> impl WidgetFn; - fn layer_offset(self, offset: usize) -> impl WidgetFn; + fn layer_offset(self, offset: usize) -> impl WidgetFn; } impl, Tag> CoreWidget for W { @@ -117,14 +117,12 @@ impl, Tag> CoreWidget for W { move |ui| Stack { children: vec![w.add(ui).any(), self.add(ui).any()], size: StackSize::Child(1), - offset: 0, } } - fn layer_offset(self, offset: usize) -> impl WidgetFn { - move |ui| Stack { - children: vec![self.add(ui).any()], - size: StackSize::Child(0), + fn layer_offset(self, offset: usize) -> impl WidgetFn { + move |ui| LayerOffset { + inner: self.add(ui).any(), offset, } } diff --git a/src/layout/layer.rs b/src/layout/layer.rs index 9fbcfd8..c0a0603 100644 --- a/src/layout/layer.rs +++ b/src/layout/layer.rs @@ -2,11 +2,12 @@ use std::ops::{Index, IndexMut}; use crate::render::{MaskIdx, Primitive, PrimitiveHandle, PrimitiveInst, Primitives}; -struct LayerNode { +struct LayerNode { next: Ptr, prev: Ptr, child: Option, - data: Layer, + depth: usize, + data: T, } #[derive(Clone, Copy, Debug)] @@ -21,26 +22,22 @@ enum Ptr { /// TODO: currently this does not ever free layers /// is that realistically desired? -pub struct Layers { - vec: Vec, +pub struct Layers { + vec: Vec>, /// index of last layer at top level (start at first = 0) last: usize, } -/// TODO: this can be replaced with Primitives itself atm -#[derive(Default)] -pub struct Layer { - pub primitives: Primitives, -} - #[derive(Clone, Copy)] struct Child { head: usize, tail: usize, } -impl Layers { - pub fn new() -> Layers { +pub type PrimitiveLayers = Layers; + +impl Layers { + pub fn new() -> Layers { Self { vec: vec![LayerNode::head()], last: 0, @@ -52,7 +49,7 @@ impl Layers { self.vec.push(LayerNode::head()); } - fn push(&mut self, node: LayerNode) -> usize { + fn push(&mut self, node: LayerNode) -> usize { let i = self.vec.len(); self.vec.push(node); i @@ -63,9 +60,10 @@ impl Layers { return i; } let i_new = self.push(LayerNode::new( - Layer::default(), + T::default(), self.vec[i].next, Ptr::Next(i), + self.vec[i].depth, )); self.vec[i].next = Ptr::Next(i_new); self.vec[i_new].prev = Ptr::Next(i); @@ -82,9 +80,10 @@ impl Layers { return c.head; } let i_child = self.push(LayerNode::new( - Layer::default(), + T::default(), Ptr::Parent(i), Ptr::Parent(i), + self.vec[i].depth + 1, )); self.vec[i].child = Some(Child { head: i_child, @@ -93,107 +92,115 @@ impl Layers { i_child } - pub fn iter_mut(&mut self) -> LayerIteratorMut<'_> { + pub fn iter_mut(&mut self) -> LayerIteratorMut<'_, T> { LayerIteratorMut::new(&mut self.vec, self.last) } - pub fn iter_orderless_mut(&mut self) -> impl Iterator { + pub fn iter_orderless_mut(&mut self) -> impl Iterator { self.vec.iter_mut().map(|n| &mut n.data).enumerate() } - pub fn iter(&self) -> impl Iterator { + pub fn iter(&self) -> impl Iterator { self.indices().map(|i| (i, &self.vec[i].data)) } - pub fn indices(&self) -> LayerIndexIterator<'_> { + pub fn iter_depth(&self) -> impl Iterator { + self.indices() + .map(|i| ((i, self.vec[i].depth), &self.vec[i].data)) + } + + pub fn indices(&self) -> LayerIndexIterator<'_, T> { LayerIndexIterator::new(&self.vec, self.last) } - - pub fn write(&mut self, layer: usize, info: PrimitiveInst

) -> PrimitiveHandle { - self[layer].primitives.write(layer, info) - } - - pub fn free(&mut self, h: &PrimitiveHandle) -> MaskIdx { - self[h.layer].primitives.free(h) - } } -impl Default for Layers { +impl PrimitiveLayers { + pub fn write(&mut self, layer: usize, info: PrimitiveInst

) -> PrimitiveHandle { + self[layer].write(layer, info) + } + + pub fn free(&mut self, h: &PrimitiveHandle) -> MaskIdx { + self[h.layer].free(h) + } +} + +impl Default for Layers { fn default() -> Self { Self::new() } } -impl Index for Layers { - type Output = Layer; +impl Index for Layers { + type Output = T; fn index(&self, index: usize) -> &Self::Output { &self.vec[index].data } } -impl IndexMut for Layers { +impl IndexMut for Layers { fn index_mut(&mut self, index: usize) -> &mut Self::Output { &mut self.vec[index].data } } -impl LayerNode { - pub fn new(data: Layer, next: Ptr, prev: Ptr) -> Self { +impl LayerNode { + pub fn new(data: T, next: Ptr, prev: Ptr, depth: usize) -> Self { Self { next, prev, child: None, data, + depth, } } pub fn head() -> Self { - Self::new(Layer::default(), Ptr::None, Ptr::None) + Self::new(T::default(), Ptr::None, Ptr::None, 0) } } -pub struct LayerIteratorMut<'a> { - inner: LayerIndexIterator<'a>, +pub struct LayerIteratorMut<'a, T> { + inner: LayerIndexIterator<'a, T>, } -impl<'a> Iterator for LayerIteratorMut<'a> { - type Item = (usize, &'a mut Layer); +impl<'a, T> Iterator for LayerIteratorMut<'a, T> { + type Item = (usize, &'a mut T); fn next(&mut self) -> Option { let i = self.inner.next()?; // SAFETY: requires index iterator to work properly #[allow(mutable_transmutes)] - let layer = unsafe { std::mem::transmute::<&Layer, &mut Layer>(&self.inner.vec[i].data) }; + let layer = unsafe { std::mem::transmute::<&T, &mut T>(&self.inner.vec[i].data) }; Some((i, layer)) } } -impl<'a> DoubleEndedIterator for LayerIteratorMut<'a> { +impl<'a, T> DoubleEndedIterator for LayerIteratorMut<'a, T> { fn next_back(&mut self) -> Option { let i = self.inner.next_back()?; // SAFETY: requires index iterator to work properly #[allow(mutable_transmutes)] - let layer = unsafe { std::mem::transmute::<&Layer, &mut Layer>(&self.inner.vec[i].data) }; + let layer = unsafe { std::mem::transmute::<&T, &mut T>(&self.inner.vec[i].data) }; Some((i, layer)) } } -impl<'a> LayerIteratorMut<'a> { - fn new(vec: &'a mut Vec, last: usize) -> Self { +impl<'a, T> LayerIteratorMut<'a, T> { + fn new(vec: &'a mut Vec>, last: usize) -> Self { Self { inner: LayerIndexIterator::new(vec, last), } } } -pub struct LayerIndexIterator<'a> { +pub struct LayerIndexIterator<'a, T> { next: Option, next_back: Option, - vec: &'a Vec, + vec: &'a Vec>, } -impl<'a> Iterator for LayerIndexIterator<'a> { +impl<'a, T> Iterator for LayerIndexIterator<'a, T> { type Item = usize; fn next(&mut self) -> Option { @@ -224,7 +231,7 @@ impl<'a> Iterator for LayerIndexIterator<'a> { } } -impl<'a> DoubleEndedIterator for LayerIndexIterator<'a> { +impl<'a, T> DoubleEndedIterator for LayerIndexIterator<'a, T> { fn next_back(&mut self) -> Option { let ret_i = self.next_back?; let node = &self.vec[ret_i]; @@ -246,8 +253,8 @@ impl<'a> DoubleEndedIterator for LayerIndexIterator<'a> { } } -impl<'a> LayerIndexIterator<'a> { - fn new(vec: &'a Vec, last: usize) -> Self { +impl<'a, T> LayerIndexIterator<'a, T> { + fn new(vec: &'a Vec>, last: usize) -> Self { let mut last = last; while let Some(c) = vec[last].child { last = c.tail; diff --git a/src/layout/painter.rs b/src/layout/painter.rs index 100a0f4..7fd9220 100644 --- a/src/layout/painter.rs +++ b/src/layout/painter.rs @@ -1,6 +1,6 @@ use crate::{ layout::{ - Axis, Layers, Len, Modules, Size, TextAttrs, TextBuffer, TextData, RenderedText, + Axis, PrimitiveLayers, Len, Modules, Size, TextAttrs, TextBuffer, TextData, RenderedText, TextureHandle, Textures, UiRegion, UiVec2, Vec2, WidgetId, Widgets, }, render::{Mask, MaskIdx, Primitive, PrimitiveHandle, PrimitiveInst}, @@ -25,7 +25,7 @@ pub struct Painter<'a, 'c> { struct PainterCtx<'a> { pub widgets: &'a Widgets, pub active: &'a mut HashMap, - pub layers: &'a mut Layers, + pub layers: &'a mut PrimitiveLayers, pub textures: &'a mut Textures, pub masks: &'a mut TrackedArena, pub text: &'a mut TextData, @@ -64,7 +64,7 @@ pub struct WidgetInstance { pub struct PainterData { pub widgets: Widgets, pub active: HashMap, - pub layers: Layers, + pub layers: PrimitiveLayers, pub textures: Textures, pub text: TextData, pub output_size: Vec2, @@ -277,7 +277,7 @@ impl<'a> PainterCtx<'a> { fn mov(&mut self, id: Id, from: UiRegion, to: UiRegion) { let active = self.active.get_mut(&id).unwrap(); for h in &active.primitives { - let region = self.layers[h.layer].primitives.region_mut(h); + let region = self.layers[h.layer].region_mut(h); *region = region.outside(&from).within(&to); } active.region = active.region.outside(&from).within(&to); diff --git a/src/layout/ui.rs b/src/layout/ui.rs index 127abd6..08b26e5 100644 --- a/src/layout/ui.rs +++ b/src/layout/ui.rs @@ -184,6 +184,18 @@ impl Ui { } } + pub fn debug_layers(&self) { + for ((idx, depth), primitives) in self.data.layers.iter_depth() { + let indent = " ".repeat(depth * 2); + let len = primitives.instances().len(); + print!("{indent}{idx}: {len} primitives"); + if len >= 1 { + print!(" ({})", primitives.instances()[0].binding); + } + println!(); + } + } + pub fn window_region(&self, id: &impl IdLike) -> Option { let region = self.data.active.get(&id.id())?.region; Some(region.to_px(self.data.output_size)) diff --git a/src/render/mod.rs b/src/render/mod.rs index 5f1e184..8b3ba03 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -61,9 +61,8 @@ impl UiRenderer { pub fn update(&mut self, device: &Device, queue: &Queue, ui: &mut Ui) { self.active.clear(); - for (i, ulayer) in ui.data.layers.iter_orderless_mut() { + for (i, primitives) in ui.data.layers.iter_mut() { self.active.push(i); - let primitives = &mut ulayer.primitives; for change in primitives.apply_free() { if let Some(inst) = ui.data.active.get_mut(&change.id) { for h in &mut inst.primitives {