output: more big refactors

This commit is contained in:
🪞👃🪞 2025-09-07 12:34:30 +03:00
parent 194f2f9874
commit 5e6338fad8
68 changed files with 1604 additions and 1016 deletions

View file

@ -0,0 +1,139 @@
use crate::*;
/// Draws items from an iterator.
pub struct Map<O, A, B, I, F, G>
where
I: Iterator<Item = A> + Send + Sync,
F: Fn() -> I + Send + Sync,
{
__: PhantomData<(O, B)>,
/// Function that returns iterator over stacked components
get_iter: F,
/// Function that returns each stacked component
get_item: G,
}
impl<'a, O, A, B, I, F, G> Map<O, A, B, I, F, G> where
I: Iterator<Item = A> + Send + Sync + 'a,
F: Fn() -> I + Send + Sync + 'a,
{
pub const fn new (get_iter: F, get_item: G) -> Self {
Self {
__: PhantomData,
get_iter,
get_item
}
}
}
macro_rules! impl_map_direction (($name:ident, $axis:ident, $align:ident)=>{
impl<'a, O, A, B, I, F> Map<
O, A, Push<O::Unit, Align<Fixed<O::Unit, Fill<B>>>>, I, F, fn(A, usize)->B
> where
O: Out,
B: Draw<O> + Layout<O>,
I: Iterator<Item = A> + Send + Sync + 'a,
F: Fn() -> I + Send + Sync + 'a
{
pub const fn $name (
size: O::Unit,
get_iter: F,
get_item: impl Fn(A, usize)->B + Send + Sync
) -> Map<
O, A,
Push<O::Unit, Align<Fixed<O::Unit, B>>>,
I, F,
impl Fn(A, usize)->Push<O::Unit, Align<Fixed<O::Unit, B>>> + Send + Sync
> {
Map {
__: PhantomData,
get_iter,
get_item: move |item: A, index: usize|{
// FIXME: multiply
let mut push: O::Unit = O::Unit::from(0u16);
for _ in 0..index {
push = push + size;
}
Push::$axis(push, Align::$align(Fixed::$axis(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, O, A, B, I, F, G> Layout<O> for Map<O, A, B, I, F, G> where
O: Out,
B: Draw<O> + Layout<O>,
I: Iterator<Item = A> + Send + Sync + 'a,
F: Fn() -> I + Send + Sync + 'a,
G: Fn(A, usize)->B + Send + Sync
{
fn layout (&self, area: O::Area) -> O::Area {
let Self { get_iter, get_item, .. } = self;
let mut index = 0;
let [mut min_x, mut min_y] = area.center();
let [mut max_x, mut max_y] = area.center();
for item in get_iter() {
let [x,y,w,h] = get_item(item, index).layout(area).xywh();
min_x = min_x.min(x.into());
min_y = min_y.min(y.into());
max_x = max_x.max((x + w).into());
max_y = max_y.max((y + h).into());
index += 1;
}
let w = max_x - min_x;
let h = max_y - min_y;
//[min_x.into(), min_y.into(), w.into(), h.into()].into()
area.center_xy([w.into(), h.into()].into()).into()
}
}
impl<'a, O, A, B, I, F, G> Draw<O> for Map<O, A, B, I, F, G> where
O: Out,
B: Draw<O> + Layout<O>,
I: Iterator<Item = A> + Send + Sync + 'a,
F: Fn() -> I + Send + Sync + 'a,
G: Fn(A, usize)->B + Send + Sync
{
fn draw (&self, to: &mut O) {
let Self { get_iter, get_item, .. } = self;
let mut index = 0;
let area = self.layout(to.area());
for item in get_iter() {
let item = get_item(item, index);
//to.place_at(area.into(), &item);
to.place_at(item.layout(area), &item);
index += 1;
}
}
}
#[inline] pub fn map_south<O: Out>(
item_offset: O::Unit,
item_height: O::Unit,
item: impl Draw<O> + Layout<O>
) -> impl Draw<O> + Layout<O> {
Push::y(item_offset, Fixed::y(item_height, Fill::x(item)))
}
#[inline] pub fn map_south_west<O: Out>(
item_offset: O::Unit,
item_height: O::Unit,
item: impl Draw<O> + Layout<O>
) -> impl Draw<O> + Layout<O> {
Push::y(item_offset, Align::nw(Fixed::y(item_height, Fill::x(item))))
}
#[inline] pub fn map_east<O: Out>(
item_offset: O::Unit,
item_width: O::Unit,
item: impl Draw<O> + Layout<O>
) -> impl Draw<O> + Layout<O> {
Push::x(item_offset, Align::w(Fixed::x(item_width, Fill::y(item))))
}