mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
142 lines
4.4 KiB
Rust
142 lines
4.4 KiB
Rust
use crate::*;
|
|
|
|
use std::sync::RwLock;
|
|
|
|
impl<E: Engine> Layout<E> for E {}
|
|
|
|
pub trait Layout<E: Engine> {
|
|
/// Content `item` when `cond` is true.
|
|
fn when <A: Content<E>> (cond: bool, item: A) -> When<E, A> {
|
|
When(cond, item, Default::default())
|
|
}
|
|
/// Content `item` if `cond` is true, otherwise render `other`.
|
|
fn either <A: Content<E>, B: Content<E>> (cond: bool, a: A, b: B)
|
|
-> Either<E, A, B>
|
|
{
|
|
Either(cond, a, b, Default::default())
|
|
}
|
|
/// Maps an [Option<T>] through a callback `F`
|
|
fn opt <A, F: Fn(A)->R, R: Content<E>> (option: Option<A>, cb: F)
|
|
-> Opt<E, A, F, R>
|
|
{
|
|
Opt(option, cb, Default::default())
|
|
}
|
|
fn map <T, I, J, R, F>(iterator: J, callback: F) -> Map<E, T, I, J, R, F> where
|
|
E: Engine,
|
|
I: Iterator<Item = T> + Send + Sync,
|
|
J: Fn() -> I + Send + Sync,
|
|
R: Content<E>,
|
|
F: Fn(T, usize)->R + Send + Sync
|
|
{
|
|
Map(Default::default(), iterator, callback)
|
|
}
|
|
//pub fn reduce <E, T, I, R, F>(iterator: I, callback: F) -> Reduce<E, T, I, R, F> where
|
|
//E: Engine,
|
|
//I: Iterator<Item = T> + Send + Sync,
|
|
//R: Content<E>,
|
|
//F: Fn(R, T, usize) -> R + Send + Sync
|
|
//{
|
|
//Reduce(Default::default(), iterator, callback)
|
|
//}
|
|
}
|
|
|
|
pub struct Opt<E: Engine, A, F: Fn(A)->R, R: Content<E>>(Option<A>, F, PhantomData<E>);
|
|
|
|
/// Contents `self.1` when `self.0` is true.
|
|
pub struct When<E: Engine, A>(bool, A, PhantomData<E>);
|
|
|
|
impl<E: Engine, A: Content<E>> Content<E> for When<E, A> {
|
|
fn layout (&self, to: E::Area) -> E::Area {
|
|
let Self(cond, item, ..) = self;
|
|
let mut area = E::Area::zero();
|
|
if *cond {
|
|
let item_area = item.layout(to);
|
|
area[0] = item_area.x();
|
|
area[1] = item_area.y();
|
|
area[2] = item_area.w();
|
|
area[3] = item_area.h();
|
|
}
|
|
area.into()
|
|
}
|
|
fn render (&self, to: &mut E::Output) {
|
|
let Self(cond, item, ..) = self;
|
|
if *cond { item.render(to) }
|
|
}
|
|
}
|
|
|
|
/// Contents `self.1` when `self.0` is true, otherwise renders `self.2`
|
|
pub struct Either<E: Engine, A, B>(bool, A, B, PhantomData<E>);
|
|
|
|
impl<E: Engine, A: Content<E>, B: Content<E>> Content<E> for Either<E, A, B> {
|
|
fn layout (&self, to: E::Area) -> E::Area {
|
|
let Self(cond, a, b, ..) = self;
|
|
if *cond { a.layout(to) } else { b.layout(to) }
|
|
}
|
|
fn render (&self, to: &mut E::Output) {
|
|
let Self(cond, a, b, ..) = self;
|
|
if *cond { a.render(to) } else { b.render(to) }
|
|
}
|
|
}
|
|
|
|
pub struct Map<E, T, I, J, R, F>(PhantomData<E>, J, F) where
|
|
E: Engine,
|
|
I: Iterator<Item = T> + Send + Sync,
|
|
J: Fn()->I + Send + Sync,
|
|
R: Content<E>,
|
|
F: Fn(T, usize)->R + Send + Sync;
|
|
|
|
impl<E, T, I, J, R, F> Content<E> for Map<E, T, I, J, R, F> where
|
|
E: Engine,
|
|
I: Iterator<Item = T> + Send + Sync,
|
|
J: Fn()->I + Send + Sync,
|
|
R: Content<E>,
|
|
F: Fn(T, usize)->R + Send + Sync
|
|
{
|
|
fn layout (&self, area: E::Area) -> E::Area {
|
|
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 (self.1)() {
|
|
let area = (self.2)(item, index).layout(area).xywh();
|
|
let [x,y,w,h] = 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()
|
|
}
|
|
fn render (&self, to: &mut E::Output) {
|
|
let mut index = 0;
|
|
let area = self.layout(to.area());
|
|
//panic!("{area:?}");
|
|
//to.blit(&format!("{area:?}"), 0, 0, None);
|
|
for item in (self.1)() {
|
|
let item = (self.2)(item, index);
|
|
to.place(area.into(), &item);
|
|
index += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
pub struct Reduce<E, T, I, R, F>(PhantomData<(E, R)>, I, F) where
|
|
E: Engine,
|
|
I: Iterator<Item = T> + Send + Sync,
|
|
R: Content<E>,
|
|
F: Fn(R, T, usize) -> R + Send + Sync;
|
|
impl<E, T, I, R, F> Content<E> for Reduce<E, T, I, R, F> where
|
|
E: Engine,
|
|
I: Iterator<Item = T> + Send + Sync,
|
|
R: Content<E>,
|
|
F: Fn(R, T, usize) -> R + Send + Sync
|
|
{
|
|
fn render (&self, to: &mut E::Output) {
|
|
todo!()
|
|
}
|
|
}
|
|
*/
|