From f35ac97737b0381ce73c8e85e92befb460289e07 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 30 Aug 2025 03:57:54 +0300 Subject: [PATCH] output: fix(?) the stacks --- output/src/layout.rs | 153 ++++++++++++++++++++----------------------- 1 file changed, 70 insertions(+), 83 deletions(-) diff --git a/output/src/layout.rs b/output/src/layout.rs index cfa7f37..14f1cef 100644 --- a/output/src/layout.rs +++ b/output/src/layout.rs @@ -771,33 +771,38 @@ impl Memo { ($buf:ident, $($rest:tt)*) => { |$buf,_,_|{ $buf.clear(); write!($buf, $($rest)*) } } } -pub struct Stack { - __: PhantomData, +pub struct Stack<'t, E, F1> { + __: PhantomData<&'t (E, F1)>, direction: Direction, - callback: F + callback: F1 } -impl)->())->()> Stack { - pub fn north (callback: F) -> Self { Self::new(North, callback) } - pub fn south (callback: F) -> Self { Self::new(South, callback) } - pub fn east (callback: F) -> Self { Self::new(East, callback) } - pub fn west (callback: F) -> Self { Self::new(West, callback) } - pub fn above (callback: F) -> Self { Self::new(Above, callback) } - pub fn below (callback: F) -> Self { Self::new(Below, callback) } - pub fn new (direction: Direction, callback: F) -> Self { +impl<'t, E, F1> Stack<'t, E, F1> where + E: Output, + F1: Fn(&mut dyn FnMut(&(dyn Render + 't))) + Send + Sync, +{ + pub fn north (callback: F1) -> Self { Self::new(North, callback) } + pub fn south (callback: F1) -> Self { Self::new(South, callback) } + pub fn east (callback: F1) -> Self { Self::new(East, callback) } + pub fn west (callback: F1) -> Self { Self::new(West, callback) } + pub fn above (callback: F1) -> Self { Self::new(Above, callback) } + pub fn below (callback: F1) -> Self { Self::new(Below, callback) } + pub fn new (direction: Direction, callback: F1) -> Self { Self { direction, callback, __: Default::default(), } } } -impl)->())->()> Content for Stack { +impl<'t, E, F1> Content for Stack<'t, E, F1> where + Self: 't, + E: Output, + F1: Fn(&mut dyn FnMut(&(dyn Render + 't))) + Send + Sync, +{ fn layout (&self, to: E::Area) -> E::Area { - let mut x = to.x(); - let mut y = to.y(); + let Self { direction, callback, .. } = self; + let (mut x, mut y) = (to.x(), to.y()); let (mut w_used, mut w_remaining) = (E::Unit::zero(), to.w()); let (mut h_used, mut h_remaining) = (E::Unit::zero(), to.h()); - (self.callback)(&mut move |component: &dyn Render|{ + callback(&mut move|component|{ let [_, _, w, h] = component.layout([x, y, w_remaining, h_remaining].into()).xywh(); - match self.direction { - North | West => { todo!() }, - Above | Below => {}, + match direction { South => { y = y.plus(h); h_used = h_used.plus(h); h_remaining = h_remaining.minus(h); @@ -806,33 +811,36 @@ impl)->())->()> Content for St w_used = w_used.plus(w); w_remaining = w_remaining.minus(w); h_used = h_used.max(h); }, + North | West => { todo!() }, + Above | Below => {}, } }); - match self.direction { + match direction { North | West => { todo!() }, South | East => { [to.x(), to.y(), w_used.into(), h_used.into()].into() }, Above | Below => { [to.x(), to.y(), to.w(), to.h()].into() }, } } fn render (&self, to: &mut E) { - let mut x = to.x(); - let mut y = to.y(); + let Self { direction, callback, .. } = self; + let (mut x, mut y) = (to.x(), to.y()); let (mut w_used, mut w_remaining) = (E::Unit::zero(), to.w()); let (mut h_used, mut h_remaining) = (E::Unit::zero(), to.h()); - (self.callback)(&mut move |component: &dyn Render|{ + callback(&mut move|component|{ let layout = component.layout([x, y, w_remaining, h_remaining].into()); - match self.direction { - Above | Below => { to.place(layout, component); } + match direction { + South => { + y = y.plus(layout.h()); + h_remaining = h_remaining.minus(layout.h()); + h_used = h_used.plus(layout.h()) }, + East => { + x = x.plus(layout.w()); + w_remaining = w_remaining.minus(layout.w()); + w_used = w_used.plus(layout.h()) }, North | West => { todo!() }, - South => { y = y.plus(layout.h()); - h_remaining = h_remaining.minus(layout.h()); - h_used = h_used.plus(layout.h()); - to.place(layout, component); }, - East => { x = x.plus(layout.w()); - w_remaining = w_remaining.minus(layout.w()); - w_used = w_used.plus(layout.h()); - to.place(layout, component); }, - } + Above | Below => {} + }; + to.place(layout, component); }); } } @@ -881,66 +889,45 @@ impl<'a, E, A, B, I, F, G> Map where } } -impl<'a, E, A, B, I, F> Map>>>, I, F, fn(A, usize)->B> -where - E: Output, - B: Render, - I: Iterator + Send + Sync + 'a, - F: Fn() -> I + Send + Sync + 'a -{ - pub const fn east ( - size: E::Unit, - get_iter: F, - get_item: impl Fn(A, usize)->B + Send + Sync - ) -> Map< - E, A, - Push>>, - I, F, - impl Fn(A, usize)->Push>> + Send + Sync - > { - Map { - __: PhantomData, - get_iter, - get_item: move |item: A, index: usize|{ - // FIXME: multiply - let mut push: E::Unit = E::Unit::from(0u16); - for _ in 0..index { - push = push + size; - } - Push::x(push, Align::w(Fixed::x(size, get_item(item, index)))) - } - } - } - - pub const fn south ( - size: E::Unit, - get_iter: F, - get_item: impl Fn(A, usize)->B + Send + Sync - ) -> Map< - E, A, - Push>>, - I, F, - impl Fn(A, usize)->Push>> + Send + Sync +macro_rules! impl_map_direction (($name:ident, $axis:ident, $align:ident)=>{ + impl<'a, E, A, B, I, F> Map< + E, A, Push>>>, I, F, fn(A, usize)->B > where E: Output, B: Render, I: Iterator + Send + Sync + 'a, F: Fn() -> I + Send + Sync + 'a { - Map { - __: PhantomData, - get_iter, - get_item: move |item: A, index: usize|{ - // FIXME: multiply - let mut push: E::Unit = E::Unit::from(0u16); - for _ in 0..index { - push = push + size; + pub const fn $name ( + size: E::Unit, + get_iter: F, + get_item: impl Fn(A, usize)->B + Send + Sync + ) -> Map< + E, A, + Push>>, + I, F, + impl Fn(A, usize)->Push>> + Send + Sync + > { + Map { + __: PhantomData, + get_iter, + get_item: move |item: A, index: usize|{ + // FIXME: multiply + let mut push: E::Unit = E::Unit::from(0u16); + for _ in 0..index { + push = push + size; + } + Push::$axis(push, Align::$align(Fixed::$axis(size, get_item(item, index)))) } - Push::y(push, Align::n(Fixed::y(size, get_item(item, index)))) } } } -} +}); + +impl_map_direction!(east, x, w); +impl_map_direction!(south, y, n); +impl_map_direction!(west, x, e); +impl_map_direction!(north, y, s); impl<'a, E, A, B, I, F, G> Content for Map where E: Output,