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)*) } }
}
pub struct Stack<E, F> {
__: PhantomData<E>,
pub struct Stack<'t, E, F1> {
__: PhantomData<&'t (E, F1)>,
direction: Direction,
callback: F
callback: F1
}
impl<E: Output, F: Fn(&mut dyn FnMut(&dyn Render<E>)->())->()> Stack<E, F> {
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<E> + '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<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 {
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<E>|{
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<E: Output, F: Fn(&mut dyn FnMut(&dyn Render<E>)->())->()> Content<E> 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<E>|{
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<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>
where
E: Output,
B: Render<E>,
I: Iterator<Item = A> + 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<E::Unit, Align<Fixed<E::Unit, B>>>,
I, F,
impl Fn(A, usize)->Push<E::Unit, Align<Fixed<E::Unit, B>>> + 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<E::Unit, Align<Fixed<E::Unit, B>>>,
I, F,
impl Fn(A, usize)->Push<E::Unit, Align<Fixed<E::Unit, B>>> + Send + Sync
macro_rules! impl_map_direction (($name:ident, $axis:ident, $align:ident)=>{
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,
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;
pub const fn $name (
size: E::Unit,
get_iter: F,
get_item: impl Fn(A, usize)->B + Send + Sync
) -> 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
> {
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<E> for Map<E, A, B, I, F, G> where
E: Output,