generalize Fixed and bring back some more of the arranger

This commit is contained in:
🪞👃🪞 2024-09-17 00:38:22 +03:00
parent d577449b72
commit 2352b72377
4 changed files with 51 additions and 52 deletions

View file

@ -298,12 +298,32 @@ pub enum Fixed<U: Number, T> {
/// Enforce fixed width and height
XY(U, U, T),
}
impl<N: Number, T> Fixed<N, T> {
pub fn inner (&self) -> &T {
match self { Self::X(_, i) => i, Self::Y(_, i) => i, Self::XY(_, _, i) => i, }
}
}
impl<E: Engine, T: Widget<Engine = E>> Widget for Fixed<E::Unit, T> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(match self {
Self::X(w, _) =>
if to.w() >= *w { Some([*w, to.h()].into()) } else { None },
Self::Y(h, _) =>
if to.h() >= *h { Some([to.w(), *h].into()) } else { None },
Self::XY(w, h, _)
=> if to.w() >= *w && to.h() >= *h { Some([*w, *h].into()) } else { None },
})
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
// 🡘 🡙 ←🡙→
if let Some(size) = self.layout(to.area().wh().into())? {
to.render_in(to.area().clip(size).into(), self.inner())
} else {
Ok(())
}
}
}
/// Enforce minimum size of drawing area
pub enum Min<U: Number, T> {

View file

@ -282,7 +282,7 @@ impl Widget for &str {
type Engine = Tui;
fn layout (&self, _: [u16;2]) -> Perhaps<[u16;2]> {
// TODO: line breaks
Ok(Some([self.len() as u16, 1]))
Ok(Some([self.chars().count() as u16, 1]))
}
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
let [x, y, ..] = to.area();
@ -296,7 +296,7 @@ pub struct Styled<T: Widget<Engine = Tui>>(pub Option<Style>, pub T);
impl Widget for Styled<&str> {
type Engine = Tui;
fn layout (&self, _: [u16;2]) -> Perhaps<[u16;2]> {
Ok(Some([self.1.len() as u16, 1]))
Ok(Some([self.1.chars().count() as u16, 1]))
}
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
// FIXME
@ -318,25 +318,6 @@ impl Widget for Background {
}
}
impl<T: Widget<Engine = Tui>> Widget for Fixed<u16, T> {
type Engine = Tui;
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
Ok(match self {
Self::X(w, _) => (to.w() < *w).then(||[to.w() - *w, to.h()]),
Self::Y(h, _) => (to.h() < *h).then(||[to.w(), to.h() - *h]),
Self::XY(w, h, _) => (to.w() < *w && to.h() < *h).then(||[to.w() - *w, to.h() - *h])
}.map(|offset_area|self.inner().layout(offset_area.into())).transpose()?.flatten())
}
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
// 🡘 🡙 ←🡙→
if let Some(size) = self.layout(to.area().wh())? {
to.render_in(to.area().clip(size), self.inner())
} else {
Ok(())
}
}
}
//impl<F> Widget for Layers<Tui, F>
//where
//F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = Tui>)->Usually<()>)->Usually<()>