change Layout to output minimum size (breaks Align::Center?)

This commit is contained in:
🪞👃🪞 2024-09-15 01:31:26 +03:00
parent 0737769232
commit 1a0e06dc66
13 changed files with 232 additions and 162 deletions

View file

@ -246,15 +246,15 @@ pub fn buffer_update (buf: &mut Buffer, area: [u16;4], callback: &impl Fn(&mut C
impl Widget for &str {
type Engine = Tui;
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
let [x, y, ..] = area;
fn layout (&self, area: [u16;2]) -> Perhaps<[u16;2]> {
// TODO: line breaks
Ok(Some([x, y, self.len() as u16, 1]))
Ok(Some([self.len() as u16, 1]))
}
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = self.layout(to.area())?.unwrap();
to.blit(&self, area.x(), area.y(), None)?;
Ok(Some(area))
let [x, y, ..] = to.area();
let [w, h] = self.layout(to.area().wh())?.unwrap();
to.blit(&self, x, y, None)?;
Ok(Some([x, y, w, h]))
}
}
@ -262,12 +262,12 @@ pub struct Styled<T: Widget<Engine = Tui>>(pub Option<Style>, pub T);
impl Widget for Styled<&str> {
type Engine = Tui;
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
Ok(Some([area.x(), area.y(), self.1.len() as u16, 1]))
fn layout (&self, area: [u16;2]) -> Perhaps<[u16;2]> {
Ok(Some([self.1.len() as u16, 1]))
}
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = self.layout(to.area())?.unwrap();
Ok(Some([area.x(), area.y(), self.1.len() as u16, 1]))
let _ = self.layout(to.area().wh())?.unwrap();
Ok(Some([to.area.x(), to.area.y(), self.1.len() as u16, 1]))
}
}
@ -275,8 +275,8 @@ pub struct Background(pub Color);
impl Widget for Background {
type Engine = Tui;
fn layout (&self, [x,y,_,_]: [u16;4]) -> Perhaps<[u16;4]> {
Ok(Some([x,y,0,0]))
fn layout (&self, _: [u16;2]) -> Perhaps<[u16;2]> {
Ok(Some([0,0]))
}
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
to.fill_bg(to.area(), self.0);
@ -286,19 +286,17 @@ impl Widget for Background {
impl<T: Widget<Engine = Tui>> Widget for Fixed<u16, T> {
type Engine = Tui;
fn layout (&self, to: [u16;4]) -> Perhaps<[u16;4]> {
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
Ok(match self {
Self::X(w, _) => (to.w() < *w).then(||[to.x() + *w, to.y(), to.w() - *w, to.h()]),
Self::Y(h, _) => (to.h() < *h).then(||[to.x(), to.y() + *h, to.w(), to.h() - *h]),
Self::XY(w, h, _) => (to.w() < *w || to.h() < *h).then(||[
to.x() + *w, to.y() + *h, to.w() - *w, to.h() - *h
])
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 Tui) -> Perhaps<[u16;4]> {
// 🡘 🡙 ←🡙→
if let Some(area) = self.layout(to.area())? {
to.render_in(area, self.inner())
if let Some(size) = self.layout(to.area().wh())? {
to.render_in(to.area().clip(size), self.inner())
} else {
Ok(None)
}
@ -310,7 +308,7 @@ where
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = Tui>)->Usually<()>)->Usually<()>
{
type Engine = Tui;
fn layout (&self, to: [u16;4]) -> Perhaps<[u16;4]> {
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
let mut w = 0;
let mut h = 0;
match self.1 {
@ -320,7 +318,7 @@ where
return Ok(())
}
let area = Plus::Y(h, component as &dyn Widget<Engine = Tui>).layout(to)?;
if let Some([_, _, width, height]) = area {
if let Some([width, height]) = area {
h += height;
w = w.max(width)
}
@ -333,7 +331,7 @@ where
return Ok(())
}
let area = Plus::X(w, component as &dyn Widget<Engine = Tui>).layout(to)?;
if let Some([_, _, width, height]) = area {
if let Some([width, height]) = area {
w += width;
h = h.max(height)
}
@ -342,7 +340,7 @@ where
},
_ => todo!()
};
Ok(Some([to.x(), to.y(), w, h]))
Ok(Some([w, h]))
}
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area();
@ -386,8 +384,7 @@ where
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = Tui>)->Usually<()>)->Usually<()>
{
type Engine = Tui;
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
let [x, y, ..] = area;
fn layout (&self, area: [u16;2]) -> Perhaps<[u16;2]> {
let mut w = 0;
let mut h = 0;
(self.0)(&mut |layer| {
@ -397,11 +394,14 @@ where
}
Ok(())
})?;
Ok(Some([x, y, w, h]))
Ok(Some([w, h]))
}
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
self.layout(to.area())?
.map(|area|(self.0)(&mut |layer|to.render_in(area, &layer).map(|_|())).map(|_|area))
self.layout(to.area().wh())?
.map(|size|(self.0)(&mut |layer|{
to.render_in(to.area().clip(size), &layer).map(|_|())
})
.map(|_|to.area()))
.transpose()
}
}
@ -410,7 +410,7 @@ pub struct Border<S: BorderStyle>(pub S);
impl<S: BorderStyle> Widget for Border<S> {
type Engine = Tui;
fn layout (&self, to: [u16;4]) -> Perhaps<[u16;4]> {
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
Outset::XY(1, 1, "").layout(to)
}
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
@ -558,7 +558,7 @@ macro_rules! border {
}
impl Widget for $T {
type Engine = Tui;
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
fn layout (&self, area: [u16;2]) -> Perhaps<[u16;2]> {
Ok(Some(area))
}
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {