mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
wip: big flat pt.4: extract layout crate
This commit is contained in:
parent
cb680ab096
commit
34e731f111
21 changed files with 2125 additions and 83 deletions
169
layout/src/collection/split.rs
Normal file
169
layout/src/collection/split.rs
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
use crate::*;
|
||||
|
||||
/// A binary split with fixed proportion
|
||||
pub struct Split<E, A, B>(pub bool, pub Direction, pub E::Unit, A, B, PhantomData<E>)
|
||||
where E: Engine, A: Render<E>, B: Render<E>;
|
||||
|
||||
impl<E: Engine, A: Render<E>, B: Render<E>> Split<E, A, B> {
|
||||
#[inline] pub fn new (flip: bool, direction: Direction, proportion: E::Unit, a: A, b: B) -> Self {
|
||||
Self(flip, direction, proportion, a, b, Default::default())
|
||||
}
|
||||
#[inline] pub fn n (flip: bool, proportion: E::Unit, a: A, b: B) -> Self {
|
||||
Self::new(flip, North, proportion, a, b)
|
||||
}
|
||||
#[inline] pub fn s (flip: bool, proportion: E::Unit, a: A, b: B) -> Self {
|
||||
Self::new(flip, South, proportion, a, b)
|
||||
}
|
||||
#[inline] pub fn e (flip: bool, proportion: E::Unit, a: A, b: B) -> Self {
|
||||
Self::new(flip, West, proportion, a, b)
|
||||
}
|
||||
#[inline] pub fn w (flip: bool, proportion: E::Unit, a: A, b: B) -> Self {
|
||||
Self::new(flip, East, proportion, a, b)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine, A: Render<E>, B: Render<E>> Render<E> for Split<E, A, B> {
|
||||
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
Ok(Some(to))
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
let (a, b) = self.1.split_fixed(self.2, self.3);
|
||||
Ok(if self.0 {
|
||||
to.render_in(a.into(), &self.4)?;
|
||||
to.render_in(b.into(), &self.3)?;
|
||||
} else {
|
||||
to.render_in(a.into(), &self.3)?;
|
||||
to.render_in(b.into(), &self.4)?;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
South => {
|
||||
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 = Max::y(max, Push::y(h, component));
|
||||
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()))
|
||||
},
|
||||
|
||||
East => {
|
||||
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 = Max::x(max, Push::x(h, component));
|
||||
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()))
|
||||
},
|
||||
|
||||
North => {
|
||||
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 = Max::y(to.h() - h, component);
|
||||
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()))
|
||||
},
|
||||
|
||||
West => {
|
||||
let w: E::Unit = 0.into();
|
||||
let 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 {
|
||||
South => {
|
||||
(self.0)(&mut |item| {
|
||||
if h < area.h() {
|
||||
let item = Max::y(area.h() - h, Push::y(h, item));
|
||||
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(())
|
||||
})?;
|
||||
},
|
||||
East => {
|
||||
(self.0)(&mut |item| {
|
||||
if w < area.w() {
|
||||
let item = Max::x(area.w() - w, Push::x(w, item));
|
||||
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(())
|
||||
})?;
|
||||
},
|
||||
North => {
|
||||
(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 {
|
||||
Shrink::y(height, Push::y(area.h() - height, item))
|
||||
.render(to)?;
|
||||
h = h + height;
|
||||
if width > w { w = width }
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
},
|
||||
_ => todo!()
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue