Compare commits

1 Commits

Author SHA1 Message Date
90c579d734 oopsie (orderlerss -> ordered rendering) 2025-11-22 20:22:26 -05:00
10 changed files with 105 additions and 75 deletions

View File

@@ -203,7 +203,7 @@ impl Client {
) )
.stack() .stack()
.size(StackSize::Child(1)) .size(StackSize::Child(1))
.offset_layer(1) .layer_offset(1)
.align(Align::BOT), .align(Align::BOT),
) )
.span(Dir::DOWN) .span(Dir::DOWN)

View File

@@ -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)
}
}

View File

@@ -1,4 +1,5 @@
mod align; mod align;
mod layer;
mod max_size; mod max_size;
mod offset; mod offset;
mod pad; mod pad;
@@ -8,6 +9,7 @@ mod span;
mod stack; mod stack;
pub use align::*; pub use align::*;
pub use layer::*;
pub use max_size::*; pub use max_size::*;
pub use offset::*; pub use offset::*;
pub use pad::*; pub use pad::*;

View File

@@ -5,14 +5,10 @@ use crate::prelude::*;
pub struct Stack { pub struct Stack {
pub children: Vec<WidgetId>, pub children: Vec<WidgetId>,
pub size: StackSize, pub size: StackSize,
pub offset: usize,
} }
impl Widget for Stack { impl Widget for Stack {
fn draw(&mut self, painter: &mut Painter) { fn draw(&mut self, painter: &mut Painter) {
for _ in 0..self.offset {
painter.next_layer();
}
let mut iter = self.children.iter(); let mut iter = self.children.iter();
if let Some(child) = iter.next() { if let Some(child) = iter.next() {
painter.child_layer(); painter.child_layer();
@@ -49,7 +45,6 @@ pub enum StackSize {
pub struct StackBuilder<const LEN: usize, Wa: WidgetArrLike<LEN, Tag>, Tag> { pub struct StackBuilder<const LEN: usize, Wa: WidgetArrLike<LEN, Tag>, Tag> {
pub children: Wa, pub children: Wa,
pub size: StackSize, pub size: StackSize,
pub offset: usize,
_pd: PhantomData<Tag>, _pd: PhantomData<Tag>,
} }
@@ -61,7 +56,6 @@ impl<const LEN: usize, Wa: WidgetArrLike<LEN, Tag>, Tag> FnOnce<(&mut Ui,)>
extern "rust-call" fn call_once(self, args: (&mut Ui,)) -> Self::Output { extern "rust-call" fn call_once(self, args: (&mut Ui,)) -> Self::Output {
Stack { Stack {
children: self.children.ui(args.0).arr.to_vec(), children: self.children.ui(args.0).arr.to_vec(),
offset: self.offset,
size: self.size, size: self.size,
} }
} }
@@ -72,7 +66,6 @@ impl<const LEN: usize, Wa: WidgetArrLike<LEN, Tag>, Tag> StackBuilder<LEN, Wa, T
Self { Self {
children, children,
size: StackSize::default(), size: StackSize::default(),
offset: 0,
_pd: PhantomData, _pd: PhantomData,
} }
} }
@@ -81,9 +74,4 @@ impl<const LEN: usize, Wa: WidgetArrLike<LEN, Tag>, Tag> StackBuilder<LEN, Wa, T
self.size = size; self.size = size;
self self
} }
pub fn offset_layer(mut self, offset: usize) -> Self {
self.offset = offset;
self
}
} }

View File

@@ -91,8 +91,9 @@ impl TextView {
&& line.text().is_empty() && line.text().is_empty()
{ {
painter.widget(hint); painter.widget(hint);
} } else {
painter.texture_within(&tex.handle, region); painter.texture_within(&tex.handle, region);
}
region region
} }

View File

@@ -15,7 +15,7 @@ pub trait CoreWidget<W, Tag> {
fn scroll(self) -> impl WidgetIdFn<Scroll>; fn scroll(self) -> impl WidgetIdFn<Scroll>;
fn masked(self) -> impl WidgetFn<Masked>; fn masked(self) -> impl WidgetFn<Masked>;
fn background<T>(self, w: impl WidgetLike<T>) -> impl WidgetFn<Stack>; fn background<T>(self, w: impl WidgetLike<T>) -> impl WidgetFn<Stack>;
fn layer_offset(self, offset: usize) -> impl WidgetFn<Stack>; fn layer_offset(self, offset: usize) -> impl WidgetFn<LayerOffset>;
} }
impl<W: WidgetLike<Tag>, Tag> CoreWidget<W::Widget, Tag> for W { impl<W: WidgetLike<Tag>, Tag> CoreWidget<W::Widget, Tag> for W {
@@ -117,14 +117,12 @@ impl<W: WidgetLike<Tag>, Tag> CoreWidget<W::Widget, Tag> for W {
move |ui| Stack { move |ui| Stack {
children: vec![w.add(ui).any(), self.add(ui).any()], children: vec![w.add(ui).any(), self.add(ui).any()],
size: StackSize::Child(1), size: StackSize::Child(1),
offset: 0,
} }
} }
fn layer_offset(self, offset: usize) -> impl WidgetFn<Stack> { fn layer_offset(self, offset: usize) -> impl WidgetFn<LayerOffset> {
move |ui| Stack { move |ui| LayerOffset {
children: vec![self.add(ui).any()], inner: self.add(ui).any(),
size: StackSize::Child(0),
offset, offset,
} }
} }

View File

@@ -2,11 +2,12 @@ use std::ops::{Index, IndexMut};
use crate::render::{MaskIdx, Primitive, PrimitiveHandle, PrimitiveInst, Primitives}; use crate::render::{MaskIdx, Primitive, PrimitiveHandle, PrimitiveInst, Primitives};
struct LayerNode { struct LayerNode<T> {
next: Ptr, next: Ptr,
prev: Ptr, prev: Ptr,
child: Option<Child>, child: Option<Child>,
data: Layer, depth: usize,
data: T,
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
@@ -21,26 +22,22 @@ enum Ptr {
/// TODO: currently this does not ever free layers /// TODO: currently this does not ever free layers
/// is that realistically desired? /// is that realistically desired?
pub struct Layers { pub struct Layers<T> {
vec: Vec<LayerNode>, vec: Vec<LayerNode<T>>,
/// index of last layer at top level (start at first = 0) /// index of last layer at top level (start at first = 0)
last: usize, last: usize,
} }
/// TODO: this can be replaced with Primitives itself atm
#[derive(Default)]
pub struct Layer {
pub primitives: Primitives,
}
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
struct Child { struct Child {
head: usize, head: usize,
tail: usize, tail: usize,
} }
impl Layers { pub type PrimitiveLayers = Layers<Primitives>;
pub fn new() -> Layers {
impl<T: Default> Layers<T> {
pub fn new() -> Layers<T> {
Self { Self {
vec: vec![LayerNode::head()], vec: vec![LayerNode::head()],
last: 0, last: 0,
@@ -52,7 +49,7 @@ impl Layers {
self.vec.push(LayerNode::head()); self.vec.push(LayerNode::head());
} }
fn push(&mut self, node: LayerNode) -> usize { fn push(&mut self, node: LayerNode<T>) -> usize {
let i = self.vec.len(); let i = self.vec.len();
self.vec.push(node); self.vec.push(node);
i i
@@ -63,9 +60,10 @@ impl Layers {
return i; return i;
} }
let i_new = self.push(LayerNode::new( let i_new = self.push(LayerNode::new(
Layer::default(), T::default(),
self.vec[i].next, self.vec[i].next,
Ptr::Next(i), Ptr::Next(i),
self.vec[i].depth,
)); ));
self.vec[i].next = Ptr::Next(i_new); self.vec[i].next = Ptr::Next(i_new);
self.vec[i_new].prev = Ptr::Next(i); self.vec[i_new].prev = Ptr::Next(i);
@@ -82,9 +80,10 @@ impl Layers {
return c.head; return c.head;
} }
let i_child = self.push(LayerNode::new( let i_child = self.push(LayerNode::new(
Layer::default(), T::default(),
Ptr::Parent(i), Ptr::Parent(i),
Ptr::Parent(i), Ptr::Parent(i),
self.vec[i].depth + 1,
)); ));
self.vec[i].child = Some(Child { self.vec[i].child = Some(Child {
head: i_child, head: i_child,
@@ -93,107 +92,115 @@ impl Layers {
i_child i_child
} }
pub fn iter_mut(&mut self) -> LayerIteratorMut<'_> { pub fn iter_mut(&mut self) -> LayerIteratorMut<'_, T> {
LayerIteratorMut::new(&mut self.vec, self.last) LayerIteratorMut::new(&mut self.vec, self.last)
} }
pub fn iter_orderless_mut(&mut self) -> impl Iterator<Item = (usize, &mut Layer)> { pub fn iter_orderless_mut(&mut self) -> impl Iterator<Item = (usize, &mut T)> {
self.vec.iter_mut().map(|n| &mut n.data).enumerate() self.vec.iter_mut().map(|n| &mut n.data).enumerate()
} }
pub fn iter(&self) -> impl Iterator<Item = (usize, &Layer)> { pub fn iter(&self) -> impl Iterator<Item = (usize, &T)> {
self.indices().map(|i| (i, &self.vec[i].data)) self.indices().map(|i| (i, &self.vec[i].data))
} }
pub fn indices(&self) -> LayerIndexIterator<'_> { pub fn iter_depth(&self) -> impl Iterator<Item = ((usize, usize), &T)> {
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) LayerIndexIterator::new(&self.vec, self.last)
} }
pub fn write<P: Primitive>(&mut self, layer: usize, info: PrimitiveInst<P>) -> 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<P: Primitive>(&mut self, layer: usize, info: PrimitiveInst<P>) -> PrimitiveHandle {
self[layer].write(layer, info)
}
pub fn free(&mut self, h: &PrimitiveHandle) -> MaskIdx {
self[h.layer].free(h)
}
}
impl<T: Default> Default for Layers<T> {
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()
} }
} }
impl Index<usize> for Layers { impl<T> Index<usize> for Layers<T> {
type Output = Layer; type Output = T;
fn index(&self, index: usize) -> &Self::Output { fn index(&self, index: usize) -> &Self::Output {
&self.vec[index].data &self.vec[index].data
} }
} }
impl IndexMut<usize> for Layers { impl<T> IndexMut<usize> for Layers<T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output { fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.vec[index].data &mut self.vec[index].data
} }
} }
impl LayerNode { impl<T: Default> LayerNode<T> {
pub fn new(data: Layer, next: Ptr, prev: Ptr) -> Self { pub fn new(data: T, next: Ptr, prev: Ptr, depth: usize) -> Self {
Self { Self {
next, next,
prev, prev,
child: None, child: None,
data, data,
depth,
} }
} }
pub fn head() -> Self { 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> { pub struct LayerIteratorMut<'a, T> {
inner: LayerIndexIterator<'a>, inner: LayerIndexIterator<'a, T>,
} }
impl<'a> Iterator for LayerIteratorMut<'a> { impl<'a, T> Iterator for LayerIteratorMut<'a, T> {
type Item = (usize, &'a mut Layer); type Item = (usize, &'a mut T);
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
let i = self.inner.next()?; let i = self.inner.next()?;
// SAFETY: requires index iterator to work properly // SAFETY: requires index iterator to work properly
#[allow(mutable_transmutes)] #[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)) Some((i, layer))
} }
} }
impl<'a> DoubleEndedIterator for LayerIteratorMut<'a> { impl<'a, T> DoubleEndedIterator for LayerIteratorMut<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> { fn next_back(&mut self) -> Option<Self::Item> {
let i = self.inner.next_back()?; let i = self.inner.next_back()?;
// SAFETY: requires index iterator to work properly // SAFETY: requires index iterator to work properly
#[allow(mutable_transmutes)] #[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)) Some((i, layer))
} }
} }
impl<'a> LayerIteratorMut<'a> { impl<'a, T> LayerIteratorMut<'a, T> {
fn new(vec: &'a mut Vec<LayerNode>, last: usize) -> Self { fn new(vec: &'a mut Vec<LayerNode<T>>, last: usize) -> Self {
Self { Self {
inner: LayerIndexIterator::new(vec, last), inner: LayerIndexIterator::new(vec, last),
} }
} }
} }
pub struct LayerIndexIterator<'a> { pub struct LayerIndexIterator<'a, T> {
next: Option<usize>, next: Option<usize>,
next_back: Option<usize>, next_back: Option<usize>,
vec: &'a Vec<LayerNode>, vec: &'a Vec<LayerNode<T>>,
} }
impl<'a> Iterator for LayerIndexIterator<'a> { impl<'a, T> Iterator for LayerIndexIterator<'a, T> {
type Item = usize; type Item = usize;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
@@ -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<Self::Item> { fn next_back(&mut self) -> Option<Self::Item> {
let ret_i = self.next_back?; let ret_i = self.next_back?;
let node = &self.vec[ret_i]; let node = &self.vec[ret_i];
@@ -246,8 +253,8 @@ impl<'a> DoubleEndedIterator for LayerIndexIterator<'a> {
} }
} }
impl<'a> LayerIndexIterator<'a> { impl<'a, T> LayerIndexIterator<'a, T> {
fn new(vec: &'a Vec<LayerNode>, last: usize) -> Self { fn new(vec: &'a Vec<LayerNode<T>>, last: usize) -> Self {
let mut last = last; let mut last = last;
while let Some(c) = vec[last].child { while let Some(c) = vec[last].child {
last = c.tail; last = c.tail;

View File

@@ -1,6 +1,6 @@
use crate::{ use crate::{
layout::{ 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, TextureHandle, Textures, UiRegion, UiVec2, Vec2, WidgetId, Widgets,
}, },
render::{Mask, MaskIdx, Primitive, PrimitiveHandle, PrimitiveInst}, render::{Mask, MaskIdx, Primitive, PrimitiveHandle, PrimitiveInst},
@@ -25,7 +25,7 @@ pub struct Painter<'a, 'c> {
struct PainterCtx<'a> { struct PainterCtx<'a> {
pub widgets: &'a Widgets, pub widgets: &'a Widgets,
pub active: &'a mut HashMap<Id, WidgetInstance>, pub active: &'a mut HashMap<Id, WidgetInstance>,
pub layers: &'a mut Layers, pub layers: &'a mut PrimitiveLayers,
pub textures: &'a mut Textures, pub textures: &'a mut Textures,
pub masks: &'a mut TrackedArena<Mask, u32>, pub masks: &'a mut TrackedArena<Mask, u32>,
pub text: &'a mut TextData, pub text: &'a mut TextData,
@@ -64,7 +64,7 @@ pub struct WidgetInstance {
pub struct PainterData { pub struct PainterData {
pub widgets: Widgets, pub widgets: Widgets,
pub active: HashMap<Id, WidgetInstance>, pub active: HashMap<Id, WidgetInstance>,
pub layers: Layers, pub layers: PrimitiveLayers,
pub textures: Textures, pub textures: Textures,
pub text: TextData, pub text: TextData,
pub output_size: Vec2, pub output_size: Vec2,
@@ -277,7 +277,7 @@ impl<'a> PainterCtx<'a> {
fn mov(&mut self, id: Id, from: UiRegion, to: UiRegion) { fn mov(&mut self, id: Id, from: UiRegion, to: UiRegion) {
let active = self.active.get_mut(&id).unwrap(); let active = self.active.get_mut(&id).unwrap();
for h in &active.primitives { 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); *region = region.outside(&from).within(&to);
} }
active.region = active.region.outside(&from).within(&to); active.region = active.region.outside(&from).within(&to);

View File

@@ -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<W>(&self, id: &impl IdLike<W>) -> Option<PixelRegion> { pub fn window_region<W>(&self, id: &impl IdLike<W>) -> Option<PixelRegion> {
let region = self.data.active.get(&id.id())?.region; let region = self.data.active.get(&id.id())?.region;
Some(region.to_px(self.data.output_size)) Some(region.to_px(self.data.output_size))

View File

@@ -61,9 +61,8 @@ impl UiRenderer {
pub fn update(&mut self, device: &Device, queue: &Queue, ui: &mut Ui) { pub fn update(&mut self, device: &Device, queue: &Queue, ui: &mut Ui) {
self.active.clear(); 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); self.active.push(i);
let primitives = &mut ulayer.primitives;
for change in primitives.apply_free() { for change in primitives.apply_free() {
if let Some(inst) = ui.data.active.get_mut(&change.id) { if let Some(inst) = ui.data.active.get_mut(&change.id) {
for h in &mut inst.primitives { for h in &mut inst.primitives {