rename Widget::layout to Widget::min_size

This commit is contained in:
🪞👃🪞 2024-12-04 21:21:18 +01:00
parent d652feb705
commit f018988567
10 changed files with 100 additions and 98 deletions

View file

@ -51,7 +51,7 @@ pub trait Widget: Send + Sync {
/// Engine for which this component is implemented
type Engine: Engine;
/// Minimum size to use
fn layout (&self, to: <Self::Engine as Engine>::Size)
fn min_size (&self, to: <Self::Engine as Engine>::Size)
-> Perhaps<<Self::Engine as Engine>::Size>
{
Ok(Some(to))
@ -61,8 +61,8 @@ pub trait Widget: Send + Sync {
}
impl<E: Engine> Widget for &dyn Widget<Engine = E> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
(*self).layout(to)
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
(*self).min_size(to)
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
(*self).render(to)
@ -70,8 +70,8 @@ impl<E: Engine> Widget for &dyn Widget<Engine = E> {
}
impl<E: Engine> Widget for &mut dyn Widget<Engine = E> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
(**self).layout(to)
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
(**self).min_size(to)
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
(**self).render(to)
@ -79,8 +79,8 @@ impl<E: Engine> Widget for &mut dyn Widget<Engine = E> {
}
impl<'a, E: Engine> Widget for Box<dyn Widget<Engine = E> + 'a> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
(**self).layout(to)
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
(**self).min_size(to)
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
(**self).render(to)
@ -88,8 +88,8 @@ impl<'a, E: Engine> Widget for Box<dyn Widget<Engine = E> + 'a> {
}
impl<E: Engine, W: Widget<Engine = E>> Widget for Arc<W> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
self.as_ref().layout(to)
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
self.as_ref().min_size(to)
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
self.as_ref().render(to)
@ -97,8 +97,8 @@ impl<E: Engine, W: Widget<Engine = E>> Widget for Arc<W> {
}
impl<E: Engine, W: Widget<Engine = E>> Widget for Mutex<W> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
self.lock().unwrap().layout(to)
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
self.lock().unwrap().min_size(to)
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
self.lock().unwrap().render(to)
@ -106,8 +106,8 @@ impl<E: Engine, W: Widget<Engine = E>> Widget for Mutex<W> {
}
impl<E: Engine, W: Widget<Engine = E>> Widget for RwLock<W> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
self.read().unwrap().layout(to)
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
self.read().unwrap().min_size(to)
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
self.read().unwrap().render(to)
@ -115,8 +115,8 @@ impl<E: Engine, W: Widget<Engine = E>> Widget for RwLock<W> {
}
impl<E: Engine, W: Widget<Engine = E>> Widget for Option<W> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.as_ref().map(|widget|widget.layout(to)).transpose()?.flatten())
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.as_ref().map(|widget|widget.min_size(to)).transpose()?.flatten())
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
self.as_ref().map(|widget|widget.render(to)).unwrap_or(Ok(()))
@ -130,8 +130,8 @@ pub struct Either<E: Engine, A: Widget<Engine = E>, B: Widget<Engine = E>>(
);
impl<E: Engine, A: Widget<Engine = E>, B: Widget<Engine = E>> Widget for Either<E, A, B> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
if self.0 { self.1.layout(to) } else { self.2.layout(to) }
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
if self.0 { self.1.min_size(to) } else { self.2.min_size(to) }
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
if self.0 { self.1.render(to) } else { self.2.render(to) }
@ -158,7 +158,7 @@ impl<
R: Send + Sync + Fn(&mut E::Output)->Usually<()>
> Widget for CustomWidget<E, L, R> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
self.0(to)
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
@ -173,11 +173,11 @@ pub trait Content: Send + Sync {
/// Every struct that has [Content] is a renderable [Widget].
impl<E: Engine, W: Content<Engine = E>> Widget for W {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
self.content().layout(to)
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
self.content().min_size(to)
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
match self.layout(to.area().wh().into())? {
match self.min_size(to.area().wh().into())? {
Some(wh) => to.render_in(to.area().clip(wh).into(), &self.content()),
None => Ok(())
}

View file

@ -195,8 +195,8 @@ impl<E: Engine, W: Widget<Engine = E>> Fill<E, W> {
impl<E: Engine, W: Widget<Engine = E>> Widget for Fill<E, W> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
let area = self.inner().layout(to.into())?;
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
let area = self.inner().min_size(to.into())?;
if let Some(area) = area {
Ok(Some(match self {
Self::X(_) => [to.w().into(), area.h()],
@ -232,11 +232,11 @@ where
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = E>)->Usually<()>)->Usually<()>
{
type Engine = E;
fn layout (&self, area: E::Size) -> Perhaps<E::Size> {
fn min_size (&self, area: E::Size) -> Perhaps<E::Size> {
let mut w: E::Unit = 0.into();
let mut h: E::Unit = 0.into();
(self.0)(&mut |layer| {
if let Some(layer_area) = layer.layout(area)? {
if let Some(layer_area) = layer.min_size(area)? {
w = w.max(layer_area.w());
h = h.max(layer_area.h());
}
@ -245,7 +245,7 @@ where
Ok(Some([w, h].into()))
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
if let Some(size) = self.layout(to.area().wh().into())? {
if let Some(size) = self.min_size(to.area().wh().into())? {
(self.0)(&mut |layer|to.render_in(to.area().clip(size).into(), &layer))
} else {
Ok(())
@ -348,12 +348,12 @@ fn align<T, N: Coordinate, R: Area<N> + From<[N;4]>> (align: &Align<T>, outer: R
impl<E: Engine, T: Widget<Engine = E>> Widget for Align<T> {
type Engine = E;
fn layout (&self, outer_area: E::Size) -> Perhaps<E::Size> {
self.inner().layout(outer_area)
fn min_size (&self, outer_area: E::Size) -> Perhaps<E::Size> {
self.inner().min_size(outer_area)
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
let outer_area = to.area();
Ok(if let Some(inner_size) = self.layout(outer_area.wh().into())? {
Ok(if let Some(inner_size) = self.min_size(outer_area.wh().into())? {
let inner_area = outer_area.clip(inner_size);
if let Some(aligned) = align(&self, outer_area.into(), inner_area.into()) {
to.render_in(aligned, self.inner())?
@ -382,7 +382,7 @@ impl<N: Coordinate, T> Fixed<N, T> {
}
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> {
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(match self {
Self::X(w, _) =>
if to.w() >= *w { Some([*w, to.h()].into()) } else { None },
@ -394,7 +394,7 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Fixed<E::Unit, T> {
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
// 🡘 🡙 ←🡙→
if let Some(size) = self.layout(to.area().wh().into())? {
if let Some(size) = self.min_size(to.area().wh().into())? {
to.render_in(to.area().clip(size).into(), self.inner())
} else {
Ok(())
@ -418,8 +418,8 @@ impl<N: Coordinate, T> Min<N, T> {
}
impl<E: Engine, T: Widget<Engine = E>> Widget for Min<E::Unit, T> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.inner().layout(to)?.map(|to|match *self {
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.inner().min_size(to)?.map(|to|match *self {
Self::X(w, _) => [to.w().max(w), to.h()],
Self::Y(h, _) => [to.w(), to.h().max(h)],
Self::XY(w, h, _) => [to.w().max(w), to.h().max(h)],
@ -427,7 +427,7 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Min<E::Unit, T> {
}
// TODO: 🡘 🡙 ←🡙→
fn render (&self, to: &mut E::Output) -> Usually<()> {
Ok(self.layout(to.area().wh().into())?
Ok(self.min_size(to.area().wh().into())?
.map(|size|to.render_in(to.area().clip(size).into(), self.inner()))
.transpose()?.unwrap_or(()))
}
@ -451,15 +451,15 @@ impl<N: Coordinate, T> Max<N, T> {
impl<E: Engine, T: Widget<Engine = E>> Widget for Max<E:: Unit, T> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.inner().layout(to)?.map(|to|match *self {
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.inner().min_size(to)?.map(|to|match *self {
Self::X(w, _) => [to.w().min(w), to.h()],
Self::Y(h, _) => [to.w(), to.h().min(h)],
Self::XY(w, h, _) => [to.w().min(w), to.h().min(h)],
}.into()))
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
Ok(self.layout(to.area().wh().into())?
Ok(self.min_size(to.area().wh().into())?
.map(|size|to.render_in(to.area().clip(size).into(), self.inner()))
.transpose()?.unwrap_or(()))
}
@ -483,15 +483,15 @@ impl<N: Coordinate, T> Grow<N, T> {
impl<E: Engine, T: Widget<Engine = E>> Widget for Grow<E::Unit, T> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.inner().layout(to)?.map(|to|match *self {
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.inner().min_size(to)?.map(|to|match *self {
Self::X(w, _) => [to.w() + w, to.h()],
Self::Y(h, _) => [to.w(), to.h() + h],
Self::XY(w, h, _) => [to.w() + w, to.h() + h],
}.into()))
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
Ok(self.layout(to.area().wh().into())?
Ok(self.min_size(to.area().wh().into())?
.map(|size|to.render_in(to.area().clip(size).into(), self.inner()))
.transpose()?.unwrap_or(()))
}
@ -515,8 +515,8 @@ impl<N: Coordinate, T: Widget> Shrink<N, T> {
impl<E: Engine, T: Widget<Engine = E>> Widget for Shrink<E::Unit, T> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.inner().layout(to)?.map(|to|match *self {
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.inner().min_size(to)?.map(|to|match *self {
Self::X(w, _) => [
if to.w() > w { to.w() - w } else { 0.into() },
to.h()
@ -532,7 +532,7 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Shrink<E::Unit, T> {
}.into()))
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
Ok(self.layout(to.area().wh().into())?
Ok(self.min_size(to.area().wh().into())?
.map(|size|to.render_in(to.area().clip(size).into(), self.inner()))
.transpose()?.unwrap_or(()))
}
@ -586,7 +586,7 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Inset<E::Unit, T> {
impl<E: Engine, T: Widget<Engine = E>> Widget for Outset<E::Unit, T> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
match *self {
Self::X(x, ref inner) =>
(inner as &dyn Widget<Engine = E>).grow_x(x + x),
@ -594,7 +594,7 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Outset<E::Unit, T> {
(inner as &dyn Widget<Engine = E>).grow_y(y + y),
Self::XY(x, y, ref inner) =>
(inner as &dyn Widget<Engine = E>).grow_xy(x + x, y + y),
}.layout(to)
}.min_size(to)
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
match *self {
@ -632,12 +632,12 @@ impl<N: Coordinate, T: Widget> Push<N, T> {
impl<E: Engine, T: Widget<Engine = E>> Widget for Push<E::Unit, T> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
self.inner().layout(to)
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
self.inner().min_size(to)
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
let area = to.area();
Ok(self.layout(area.wh().into())?
Ok(self.min_size(area.wh().into())?
.map(|size|to.render_in(match *self {
Self::X(x, _) => [area.x() + x, area.y(), size.w(), size.h()],
Self::Y(y, _) => [area.x(), area.y() + y, size.w(), size.h()],
@ -670,12 +670,12 @@ impl<N: Coordinate, T: Widget> Pull<N, T> {
impl<E: Engine, T: Widget<Engine = E>> Widget for Pull<E::Unit, T> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
self.inner().layout(to)
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
self.inner().min_size(to)
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
let area = to.area();
Ok(self.layout(area.wh().into())?
Ok(self.min_size(area.wh().into())?
.map(|size|to.render_in(match *self {
Self::X(x, _) => [area.x().minus(x), area.y(), size.w(), size.h()],
Self::Y(y, _) => [area.x(), area.y().minus(y), size.w(), size.h()],
@ -709,14 +709,14 @@ 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> {
fn min_size (&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 = component.push_y(h).max_y(to.h() - h).layout(to)?;
let size = component.push_y(h).max_y(to.h() - h).min_size(to)?;
if let Some([width, height]) = size.map(|size|size.wh()) {
h = h + height.into();
if width > w { w = width; }
@ -727,7 +727,7 @@ where
Direction::Right => {
(self.0)(&mut |component| {
if w >= to.w() { return Ok(()) }
let size = component.push_x(w).max_x(to.w() - w).layout(to)?;
let size = component.push_x(w).max_x(to.w() - w).min_size(to)?;
if let Some([width, height]) = size.map(|size|size.wh()) {
w = w + width.into();
if height > h { h = height }
@ -748,7 +748,7 @@ where
(self.0)(&mut |component| {
if h >= area.h() { return Ok(()) }
let item = component.push_y(h).max_y(area.h() - h);
let size = item.layout(area.wh().into())?;
let size = item.min_size(area.wh().into())?;
if let Some([width, height]) = size.map(|size|size.wh()) {
item.render(to)?;
h = h + height;
@ -761,7 +761,7 @@ where
(self.0)(&mut |component| {
if w >= area.w() { return Ok(()) }
let item = component.push_x(w).max_x(area.w() - w);
let size = item.layout(area.wh().into())?;
let size = item.min_size(area.wh().into())?;
if let Some([width, height]) = size.map(|size|size.wh()) {
item.render(to)?;
w = width + w;
@ -832,7 +832,7 @@ impl<E: Engine, A: Widget<Engine = E>, B: Widget<Engine = E>> Split<E, A, B> {
impl<E: Engine, A: Widget<Engine = E>, B: Widget<Engine = E>> Widget for Split<E, A, B> {
type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(Some(to))
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
@ -878,7 +878,7 @@ impl<E: Engine> Measure<E> {
impl<E: Engine> Widget for Measure<E> {
type Engine = E;
fn layout (&self, _: E::Size) -> Perhaps<E::Size> {
fn min_size (&self, _: E::Size) -> Perhaps<E::Size> {
Ok(Some([0u16.into(), 0u16.into()].into()))
}
fn render (&self, to: &mut E::Output) -> Usually<()> {

View file

@ -24,7 +24,7 @@ struct TestArea(u16, u16);
impl Widget for TestArea {
type Engine = TestEngine;
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
fn min_size (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
Ok(Some([to[0], to[1], self.0, self.1]))
}
fn render (&self, to: &mut Self::Engine) -> Perhaps<[u16;4]> {

View file

@ -289,32 +289,32 @@ 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, _: [u16;2]) -> Perhaps<[u16;2]> {
fn min_size (&self, _: [u16;2]) -> Perhaps<[u16;2]> {
// TODO: line breaks
Ok(Some([self.chars().count() as u16, 1]))
}
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
let [x, y, ..] = to.area();
//let [w, h] = self.layout(to.area().wh())?.unwrap();
//let [w, h] = self.min_size(to.area().wh())?.unwrap();
Ok(to.blit(&self, x, y, None))
}
}
impl Widget for String {
type Engine = Tui;
fn layout (&self, _: [u16;2]) -> Perhaps<[u16;2]> {
fn min_size (&self, _: [u16;2]) -> Perhaps<[u16;2]> {
// TODO: line breaks
Ok(Some([self.chars().count() as u16, 1]))
}
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
let [x, y, ..] = to.area();
//let [w, h] = self.layout(to.area().wh())?.unwrap();
//let [w, h] = self.min_size(to.area().wh())?.unwrap();
Ok(to.blit(&self, x, y, None))
}
}
impl<T: Widget<Engine = Tui>> Widget for DebugOverlay<Tui, T> {
type Engine = Tui;
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
self.0.layout(to)
fn min_size (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
self.0.min_size(to)
}
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
let [x, y, w, h] = to.area();
@ -325,13 +325,13 @@ impl<T: Widget<Engine = Tui>> Widget for DebugOverlay<Tui, T> {
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]> {
fn min_size (&self, _: [u16;2]) -> Perhaps<[u16;2]> {
Ok(Some([self.1.chars().count() as u16, 1]))
}
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
// FIXME
let [x, y, ..] = to.area();
//let [w, h] = self.layout(to.area().wh())?.unwrap();
//let [w, h] = self.min_size(to.area().wh())?.unwrap();
Ok(to.blit(&self.1, x, y, None))
}
}
@ -353,25 +353,25 @@ impl<W: Widget<Engine = Tui>> TuiStyle for W {}
pub struct Bold(pub bool);
impl Widget for Bold {
type Engine = Tui;
fn layout (&self, _: [u16;2]) -> Perhaps<[u16;2]> { Ok(Some([0,0])) }
fn min_size (&self, _: [u16;2]) -> Perhaps<[u16;2]> { Ok(Some([0,0])) }
fn render (&self, to: &mut TuiOutput) -> Usually<()> { Ok(to.fill_bold(to.area(), self.0)) }
}
pub struct Foreground(pub Color);
impl Widget for Foreground {
type Engine = Tui;
fn layout (&self, _: [u16;2]) -> Perhaps<[u16;2]> { Ok(Some([0,0])) }
fn min_size (&self, _: [u16;2]) -> Perhaps<[u16;2]> { Ok(Some([0,0])) }
fn render (&self, to: &mut TuiOutput) -> Usually<()> { Ok(to.fill_fg(to.area(), self.0)) }
}
pub struct Background(pub Color);
impl Widget for Background {
type Engine = Tui;
fn layout (&self, _: [u16;2]) -> Perhaps<[u16;2]> { Ok(Some([0,0])) }
fn min_size (&self, _: [u16;2]) -> Perhaps<[u16;2]> { Ok(Some([0,0])) }
fn render (&self, to: &mut TuiOutput) -> Usually<()> { Ok(to.fill_bg(to.area(), self.0)) }
}
pub struct Border<S: BorderStyle>(pub S);
impl<S: BorderStyle> Widget for Border<S> {
type Engine = Tui;
fn layout (&self, _: [u16;2]) -> Perhaps<[u16;2]> {
fn min_size (&self, _: [u16;2]) -> Perhaps<[u16;2]> {
Ok(Some([0, 0]))
}
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
@ -499,7 +499,7 @@ macro_rules! border {
pub struct $T(pub Style);
impl Widget for $T {
type Engine = Tui;
fn layout (&self, _: [u16;2]) -> Perhaps<[u16;2]> { Ok(Some([0,0])) }
fn min_size (&self, _: [u16;2]) -> Perhaps<[u16;2]> { Ok(Some([0,0])) }
fn render (&self, to: &mut TuiOutput) -> Usually<()> { self.draw(to) }
}
)+}