output: fix(?) the stacks

This commit is contained in:
🪞👃🪞 2025-08-30 03:57:54 +03:00
parent 1b98e468b6
commit f35ac97737

View file

@ -771,33 +771,38 @@ impl<T: PartialEq, U> Memo<T, U> {
($buf:ident, $($rest:tt)*) => { |$buf,_,_|{ $buf.clear(); write!($buf, $($rest)*) } } ($buf:ident, $($rest:tt)*) => { |$buf,_,_|{ $buf.clear(); write!($buf, $($rest)*) } }
} }
pub struct Stack<E, F> { pub struct Stack<'t, E, F1> {
__: PhantomData<E>, __: PhantomData<&'t (E, F1)>,
direction: Direction, direction: Direction,
callback: F callback: F1
} }
impl<E: Output, F: Fn(&mut dyn FnMut(&dyn Render<E>)->())->()> Stack<E, F> { impl<'t, E, F1> Stack<'t, E, F1> where
pub fn north (callback: F) -> Self { Self::new(North, callback) } E: Output,
pub fn south (callback: F) -> Self { Self::new(South, callback) } F1: Fn(&mut dyn FnMut(&(dyn Render<E> + 't))) + Send + Sync,
pub fn east (callback: F) -> Self { Self::new(East, callback) } {
pub fn west (callback: F) -> Self { Self::new(West, callback) } pub fn north (callback: F1) -> Self { Self::new(North, callback) }
pub fn above (callback: F) -> Self { Self::new(Above, callback) } pub fn south (callback: F1) -> Self { Self::new(South, callback) }
pub fn below (callback: F) -> Self { Self::new(Below, callback) } pub fn east (callback: F1) -> Self { Self::new(East, callback) }
pub fn new (direction: Direction, callback: F) -> Self { 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(), } Self { direction, callback, __: Default::default(), }
} }
} }
impl<E: Output, F: Fn(&mut dyn FnMut(&dyn Render<E>)->())->()> Content<E> for Stack<E, F> { impl<'t, E, F1> Content<E> for Stack<'t, E, F1> where
Self: 't,
E: Output,
F1: Fn(&mut dyn FnMut(&(dyn Render<E> + 't))) + Send + Sync,
{
fn layout (&self, to: E::Area) -> E::Area { fn layout (&self, to: E::Area) -> E::Area {
let mut x = to.x(); let Self { direction, callback, .. } = self;
let mut y = to.y(); let (mut x, mut y) = (to.x(), to.y());
let (mut w_used, mut w_remaining) = (E::Unit::zero(), to.w()); let (mut w_used, mut w_remaining) = (E::Unit::zero(), to.w());
let (mut h_used, mut h_remaining) = (E::Unit::zero(), to.h()); let (mut h_used, mut h_remaining) = (E::Unit::zero(), to.h());
(self.callback)(&mut move |component: &dyn Render<E>|{ callback(&mut move|component|{
let [_, _, w, h] = component.layout([x, y, w_remaining, h_remaining].into()).xywh(); let [_, _, w, h] = component.layout([x, y, w_remaining, h_remaining].into()).xywh();
match self.direction { match direction {
North | West => { todo!() },
Above | Below => {},
South => { y = y.plus(h); South => { y = y.plus(h);
h_used = h_used.plus(h); h_used = h_used.plus(h);
h_remaining = h_remaining.minus(h); h_remaining = h_remaining.minus(h);
@ -806,33 +811,36 @@ impl<E: Output, F: Fn(&mut dyn FnMut(&dyn Render<E>)->())->()> Content<E> for St
w_used = w_used.plus(w); w_used = w_used.plus(w);
w_remaining = w_remaining.minus(w); w_remaining = w_remaining.minus(w);
h_used = h_used.max(h); }, h_used = h_used.max(h); },
North | West => { todo!() },
Above | Below => {},
} }
}); });
match self.direction { match direction {
North | West => { todo!() }, North | West => { todo!() },
South | East => { [to.x(), to.y(), w_used.into(), h_used.into()].into() }, South | East => { [to.x(), to.y(), w_used.into(), h_used.into()].into() },
Above | Below => { [to.x(), to.y(), to.w(), to.h()].into() }, Above | Below => { [to.x(), to.y(), to.w(), to.h()].into() },
} }
} }
fn render (&self, to: &mut E) { fn render (&self, to: &mut E) {
let mut x = to.x(); let Self { direction, callback, .. } = self;
let mut y = to.y(); let (mut x, mut y) = (to.x(), to.y());
let (mut w_used, mut w_remaining) = (E::Unit::zero(), to.w()); let (mut w_used, mut w_remaining) = (E::Unit::zero(), to.w());
let (mut h_used, mut h_remaining) = (E::Unit::zero(), to.h()); let (mut h_used, mut h_remaining) = (E::Unit::zero(), to.h());
(self.callback)(&mut move |component: &dyn Render<E>|{ callback(&mut move|component|{
let layout = component.layout([x, y, w_remaining, h_remaining].into()); let layout = component.layout([x, y, w_remaining, h_remaining].into());
match self.direction { match direction {
Above | Below => { to.place(layout, component); } South => {
North | West => { todo!() }, y = y.plus(layout.h());
South => { y = y.plus(layout.h());
h_remaining = h_remaining.minus(layout.h()); h_remaining = h_remaining.minus(layout.h());
h_used = h_used.plus(layout.h()); h_used = h_used.plus(layout.h()) },
to.place(layout, component); }, East => {
East => { x = x.plus(layout.w()); x = x.plus(layout.w());
w_remaining = w_remaining.minus(layout.w()); w_remaining = w_remaining.minus(layout.w());
w_used = w_used.plus(layout.h()); w_used = w_used.plus(layout.h()) },
to.place(layout, component); }, North | West => { todo!() },
} Above | Below => {}
};
to.place(layout, component);
}); });
} }
} }
@ -881,14 +889,16 @@ impl<'a, E, A, B, I, F, G> Map<E, A, B, I, F, G> where
} }
} }
impl<'a, E, A, B, I, F> Map<E, A, Push<E::Unit, Align<Fixed<E::Unit, Fill<B>>>>, I, F, fn(A, usize)->B> macro_rules! impl_map_direction (($name:ident, $axis:ident, $align:ident)=>{
where impl<'a, E, A, B, I, F> Map<
E, A, Push<E::Unit, Align<Fixed<E::Unit, Fill<B>>>>, I, F, fn(A, usize)->B
> where
E: Output, E: Output,
B: Render<E>, B: Render<E>,
I: Iterator<Item = A> + Send + Sync + 'a, I: Iterator<Item = A> + Send + Sync + 'a,
F: Fn() -> I + Send + Sync + 'a F: Fn() -> I + Send + Sync + 'a
{ {
pub const fn east ( pub const fn $name (
size: E::Unit, size: E::Unit,
get_iter: F, get_iter: F,
get_item: impl Fn(A, usize)->B + Send + Sync get_item: impl Fn(A, usize)->B + Send + Sync
@ -907,40 +917,17 @@ where
for _ in 0..index { for _ in 0..index {
push = push + size; push = push + size;
} }
Push::x(push, Align::w(Fixed::x(size, get_item(item, index)))) Push::$axis(push, Align::$align(Fixed::$axis(size, get_item(item, index))))
} }
} }
} }
}
});
pub const fn south ( impl_map_direction!(east, x, w);
size: E::Unit, impl_map_direction!(south, y, n);
get_iter: F, impl_map_direction!(west, x, e);
get_item: impl Fn(A, usize)->B + Send + Sync impl_map_direction!(north, y, s);
) -> Map<
E, A,
Push<E::Unit, Align<Fixed<E::Unit, B>>>,
I, F,
impl Fn(A, usize)->Push<E::Unit, Align<Fixed<E::Unit, B>>> + Send + Sync
> where
E: Output,
B: Render<E>,
I: Iterator<Item = A> + 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;
}
Push::y(push, Align::n(Fixed::y(size, get_item(item, index))))
}
}
}
}
impl<'a, E, A, B, I, F, G> Content<E> for Map<E, A, B, I, F, G> where impl<'a, E, A, B, I, F, G> Content<E> for Map<E, A, B, I, F, G> where
E: Output, E: Output,