mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
generalize Split
This commit is contained in:
parent
f7b2134310
commit
73aed04c64
2 changed files with 90 additions and 79 deletions
|
|
@ -46,6 +46,7 @@ pub trait Size<N: Number> {
|
|||
fn y (&self) -> N;
|
||||
#[inline] fn w (&self) -> N { self.x() }
|
||||
#[inline] fn h (&self) -> N { self.y() }
|
||||
#[inline] fn wh (&self) -> [N;2] { [self.x(), self.y()] }
|
||||
#[inline] fn expect_min (&self, w: N, h: N) -> Usually<&Self> {
|
||||
if self.w() < w || self.h() < h {
|
||||
Err(format!("min {w}x{h}").into())
|
||||
|
|
@ -574,3 +575,92 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Minus<E::Unit, T> {
|
|||
}.into(), self.inner())).transpose()?.unwrap_or(()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine, F> Widget for Split<E, F>
|
||||
where
|
||||
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = E>)->Usually<()>)->Usually<()>
|
||||
{
|
||||
type Engine = E;
|
||||
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
let mut w = 0.into();
|
||||
let mut h = 0.into();
|
||||
match self.1 {
|
||||
Direction::Down => {
|
||||
(self.0)(&mut |component| {
|
||||
if h >= to.h() {
|
||||
return Ok(())
|
||||
}
|
||||
let size = Plus::Y(h, component as &dyn Widget<Engine = E>)
|
||||
.layout(to)?;
|
||||
if let Some([width, height]) = size.map(|size|size.wh()) {
|
||||
h = h + height.into();
|
||||
if width > w {
|
||||
w = width;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
},
|
||||
Direction::Right => {
|
||||
(self.0)(&mut |component| {
|
||||
if w >= to.w() {
|
||||
return Ok(())
|
||||
}
|
||||
let size = Plus::X(w, component as &dyn Widget<Engine = E>)
|
||||
.layout(to)?;
|
||||
if let Some([width, height]) = size.map(|size|size.wh()) {
|
||||
w = w + width.into();
|
||||
if height > h {
|
||||
h = height
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
},
|
||||
_ => todo!()
|
||||
};
|
||||
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 |component| {
|
||||
if h >= area.h() {
|
||||
return Ok(())
|
||||
}
|
||||
// FIXME -> ???
|
||||
let size = Plus::Y(h, component as &dyn Widget<Engine = E>)
|
||||
.layout(area.wh().into())?;
|
||||
if let Some([width, height]) = size.map(|size|size.wh()) {
|
||||
Plus::Y(h, component as &dyn Widget<Engine = E>).render(to)?;
|
||||
h = h + height;
|
||||
if width > w {
|
||||
w = width
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
})?;
|
||||
},
|
||||
Direction::Right => {
|
||||
(self.0)(&mut |component| {
|
||||
if w >= area.w() {
|
||||
return Ok(())
|
||||
}
|
||||
let size = Plus::X(w, component as &dyn Widget<Engine = E>)
|
||||
.layout(area.wh().into())?;
|
||||
if let Some([width, height]) = size.map(|size|size.wh()) {
|
||||
Plus::X(w, component as &dyn Widget<Engine = E>).render(to)?;
|
||||
w = width + w;
|
||||
h = h.max(height)
|
||||
};
|
||||
Ok(())
|
||||
})?;
|
||||
},
|
||||
_ => todo!()
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -337,85 +337,6 @@ impl<T: Widget<Engine = Tui>> Widget for Fixed<u16, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<F> Widget for Split<Tui, F>
|
||||
where
|
||||
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = Tui>)->Usually<()>)->Usually<()>
|
||||
{
|
||||
type Engine = Tui;
|
||||
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
|
||||
let mut w = 0;
|
||||
let mut h = 0;
|
||||
match self.1 {
|
||||
Direction::Down => {
|
||||
(self.0)(&mut |component| {
|
||||
if h >= to.h() {
|
||||
return Ok(())
|
||||
}
|
||||
let area = Plus::Y(h, component as &dyn Widget<Engine = Tui>).layout(to)?;
|
||||
if let Some([width, height]) = area {
|
||||
h += height;
|
||||
w = w.max(width)
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
},
|
||||
Direction::Right => {
|
||||
(self.0)(&mut |component| {
|
||||
if w >= to.w() {
|
||||
return Ok(())
|
||||
}
|
||||
let area = Plus::X(w, component as &dyn Widget<Engine = Tui>).layout(to)?;
|
||||
if let Some([width, height]) = area {
|
||||
w += width;
|
||||
h = h.max(height)
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
},
|
||||
_ => todo!()
|
||||
};
|
||||
Ok(Some([w, h]))
|
||||
}
|
||||
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
|
||||
let area = to.area();
|
||||
let mut w = 0;
|
||||
let mut h = 0;
|
||||
match self.1 {
|
||||
Direction::Down => {
|
||||
(self.0)(&mut |component| {
|
||||
if h >= area.h() {
|
||||
return Ok(())
|
||||
}
|
||||
// FIXME
|
||||
let area = Plus::Y(h, component as &dyn Widget<Engine = Tui>).layout(area.wh())?;
|
||||
if let Some([width, height]) = area {
|
||||
Plus::Y(h, component as &dyn Widget<Engine = Tui>).render(to)?;
|
||||
h += height;
|
||||
w = w.max(width)
|
||||
};
|
||||
Ok(())
|
||||
})?;
|
||||
},
|
||||
Direction::Right => {
|
||||
(self.0)(&mut |component| {
|
||||
if w >= area.w() {
|
||||
return Ok(())
|
||||
}
|
||||
let area = Plus::X(w, component as &dyn Widget<Engine = Tui>).layout(area.wh())?;
|
||||
if let Some([width, height]) = area {
|
||||
Plus::X(w, component as &dyn Widget<Engine = Tui>).render(to)?;
|
||||
w += width;
|
||||
h = h.max(height)
|
||||
};
|
||||
Ok(())
|
||||
})?;
|
||||
},
|
||||
_ => todo!()
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//impl<F> Widget for Layers<Tui, F>
|
||||
//where
|
||||
//F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = Tui>)->Usually<()>)->Usually<()>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue