mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-11 22:26:44 +01:00
wip: extract tek_layout
This commit is contained in:
parent
ddb3c28c01
commit
2265d951d1
36 changed files with 2010 additions and 1780 deletions
179
crates/tek_layout/src/stack.rs
Normal file
179
crates/tek_layout/src/stack.rs
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
use crate::*;
|
||||
|
||||
#[macro_export] macro_rules! col {
|
||||
($($expr:expr),* $(,)?) => { Stack::down(move|add|{ $(add(&$expr)?;)* Ok(()) }) };
|
||||
($pat:pat in $collection:expr => $item:expr) => {
|
||||
Stack::down(move |add|{
|
||||
for $pat in $collection { add(&$item)?; }
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
#[macro_export] macro_rules! col_up {
|
||||
($($expr:expr),* $(,)?) => { Stack::down(move|add|{ $(add(&$expr)?;)* Ok(()) }) };
|
||||
($pat:pat in $collection:expr => $item:expr) => {
|
||||
Stack::up(move |add|{
|
||||
for $pat in $collection { add(&$item)?; }
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
#[macro_export] macro_rules! row {
|
||||
($($expr:expr),* $(,)?) => { Stack::right(move|add|{ $(add(&$expr)?;)* Ok(()) }) };
|
||||
($pat:pat in $collection:expr => $item:expr) => {
|
||||
Stack::right(move |add|{
|
||||
for $pat in $collection { add(&$item)?; }
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Stack<
|
||||
E: Engine,
|
||||
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Render<E>)->Usually<()>)->Usually<()>
|
||||
>(pub F, pub Direction, PhantomData<E>);
|
||||
|
||||
impl<
|
||||
E: Engine,
|
||||
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Render<E>)->Usually<()>)->Usually<()>
|
||||
> Stack<E, F> {
|
||||
#[inline] pub fn new (direction: Direction, build: F) -> Self {
|
||||
Self(build, direction, Default::default())
|
||||
}
|
||||
#[inline] pub fn right (build: F) -> Self {
|
||||
Self::new(Direction::Right, build)
|
||||
}
|
||||
#[inline] pub fn down (build: F) -> Self {
|
||||
Self::new(Direction::Down, build)
|
||||
}
|
||||
#[inline] pub fn up (build: F) -> Self {
|
||||
Self::new(Direction::Up, build)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine, F> Render<E> for Stack<E, F>
|
||||
where
|
||||
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Render<E>)->Usually<()>)->Usually<()>
|
||||
{
|
||||
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
match self.1 {
|
||||
|
||||
Direction::Down => {
|
||||
let mut w: E::Unit = 0.into();
|
||||
let mut h: E::Unit = 0.into();
|
||||
(self.0)(&mut |component: &dyn Render<E>| {
|
||||
let max = to.h().minus(h);
|
||||
if max > E::Unit::ZERO() {
|
||||
let item = component.push_y(h).max_y(max);
|
||||
let size = item.min_size(to)?.map(|size|size.wh());
|
||||
if let Some([width, height]) = size {
|
||||
h = h + height.into();
|
||||
w = w.max(width);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
Ok(Some([w, h].into()))
|
||||
},
|
||||
|
||||
Direction::Right => {
|
||||
let mut w: E::Unit = 0.into();
|
||||
let mut h: E::Unit = 0.into();
|
||||
(self.0)(&mut |component: &dyn Render<E>| {
|
||||
let max = to.w().minus(w);
|
||||
if max > E::Unit::ZERO() {
|
||||
let item = component.push_x(w).max_x(max);
|
||||
let size = item.min_size(to)?.map(|size|size.wh());
|
||||
if let Some([width, height]) = size {
|
||||
w = w + width.into();
|
||||
h = h.max(height);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
Ok(Some([w, h].into()))
|
||||
},
|
||||
|
||||
Direction::Up => {
|
||||
let mut w: E::Unit = 0.into();
|
||||
let mut h: E::Unit = 0.into();
|
||||
(self.0)(&mut |component: &dyn Render<E>| {
|
||||
let max = to.h().minus(h);
|
||||
if max > E::Unit::ZERO() {
|
||||
let item = component.max_y(to.h() - h);
|
||||
let size = item.min_size(to)?.map(|size|size.wh());
|
||||
if let Some([width, height]) = size {
|
||||
h = h + height.into();
|
||||
w = w.max(width);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
Ok(Some([w, h].into()))
|
||||
},
|
||||
|
||||
Direction::Left => {
|
||||
let mut w: E::Unit = 0.into();
|
||||
let mut h: E::Unit = 0.into();
|
||||
(self.0)(&mut |component: &dyn Render<E>| {
|
||||
if w < to.w() {
|
||||
todo!();
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
Ok(Some([w, h].into()))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
let area = to.area();
|
||||
let mut w = 0.into();
|
||||
let mut h = 0.into();
|
||||
match self.1 {
|
||||
Direction::Down => {
|
||||
(self.0)(&mut |item| {
|
||||
if h < area.h() {
|
||||
let item = item.push_y(h).max_y(area.h() - h);
|
||||
let show = item.min_size(area.wh().into())?.map(|s|s.wh());
|
||||
if let Some([width, height]) = show {
|
||||
item.render(to)?;
|
||||
h = h + height;
|
||||
if width > w { w = width }
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
},
|
||||
Direction::Right => {
|
||||
(self.0)(&mut |item| {
|
||||
if w < area.w() {
|
||||
let item = item.push_x(w).max_x(area.w() - w);
|
||||
let show = item.min_size(area.wh().into())?.map(|s|s.wh());
|
||||
if let Some([width, height]) = show {
|
||||
item.render(to)?;
|
||||
w = width + w;
|
||||
if height > h { h = height }
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
},
|
||||
Direction::Up => {
|
||||
(self.0)(&mut |item| {
|
||||
if h < area.h() {
|
||||
let show = item.min_size([area.w(), area.h().minus(h)].into())?.map(|s|s.wh());
|
||||
if let Some([width, height]) = show {
|
||||
item.push_y(area.h() - height).shrink_y(height).render(to)?;
|
||||
h = h + height;
|
||||
if width > w { w = width }
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
},
|
||||
_ => todo!()
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue