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

@ -152,7 +152,7 @@ fn query_ports(client: &Client, names: Vec<String>) -> BTreeMap<String, Port<Uno
//impl<E: Engine> Widget for JackDevice<E> { //impl<E: Engine> Widget for JackDevice<E> {
//type Engine = E; //type Engine = E;
//fn layout(&self, to: E::Size) -> Perhaps<E::Size> { //fn min_size(&self, to: E::Size) -> Perhaps<E::Size> {
//self.state.read().unwrap().layout(to) //self.state.read().unwrap().layout(to)
//} //}
//fn render(&self, to: &mut E::Output) -> Usually<()> { //fn render(&self, to: &mut E::Output) -> Usually<()> {

View file

@ -51,7 +51,7 @@ pub trait Widget: Send + Sync {
/// Engine for which this component is implemented /// Engine for which this component is implemented
type Engine: Engine; type Engine: Engine;
/// Minimum size to use /// 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> -> Perhaps<<Self::Engine as Engine>::Size>
{ {
Ok(Some(to)) Ok(Some(to))
@ -61,8 +61,8 @@ pub trait Widget: Send + Sync {
} }
impl<E: Engine> Widget for &dyn Widget<Engine = E> { impl<E: Engine> Widget for &dyn Widget<Engine = E> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
(*self).layout(to) (*self).min_size(to)
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { fn render (&self, to: &mut E::Output) -> Usually<()> {
(*self).render(to) (*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> { impl<E: Engine> Widget for &mut dyn Widget<Engine = E> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
(**self).layout(to) (**self).min_size(to)
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { fn render (&self, to: &mut E::Output) -> Usually<()> {
(**self).render(to) (**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> { impl<'a, E: Engine> Widget for Box<dyn Widget<Engine = E> + 'a> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
(**self).layout(to) (**self).min_size(to)
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { fn render (&self, to: &mut E::Output) -> Usually<()> {
(**self).render(to) (**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> { impl<E: Engine, W: Widget<Engine = E>> Widget for Arc<W> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
self.as_ref().layout(to) self.as_ref().min_size(to)
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { fn render (&self, to: &mut E::Output) -> Usually<()> {
self.as_ref().render(to) 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> { impl<E: Engine, W: Widget<Engine = E>> Widget for Mutex<W> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
self.lock().unwrap().layout(to) self.lock().unwrap().min_size(to)
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { fn render (&self, to: &mut E::Output) -> Usually<()> {
self.lock().unwrap().render(to) 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> { impl<E: Engine, W: Widget<Engine = E>> Widget for RwLock<W> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
self.read().unwrap().layout(to) self.read().unwrap().min_size(to)
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { fn render (&self, to: &mut E::Output) -> Usually<()> {
self.read().unwrap().render(to) 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> { impl<E: Engine, W: Widget<Engine = E>> Widget for Option<W> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.as_ref().map(|widget|widget.layout(to)).transpose()?.flatten()) Ok(self.as_ref().map(|widget|widget.min_size(to)).transpose()?.flatten())
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { fn render (&self, to: &mut E::Output) -> Usually<()> {
self.as_ref().map(|widget|widget.render(to)).unwrap_or(Ok(())) 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> { impl<E: Engine, A: Widget<Engine = E>, B: Widget<Engine = E>> Widget for Either<E, A, B> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
if self.0 { self.1.layout(to) } else { self.2.layout(to) } if self.0 { self.1.min_size(to) } else { self.2.min_size(to) }
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { fn render (&self, to: &mut E::Output) -> Usually<()> {
if self.0 { self.1.render(to) } else { self.2.render(to) } 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<()> R: Send + Sync + Fn(&mut E::Output)->Usually<()>
> Widget for CustomWidget<E, L, R> { > Widget for CustomWidget<E, L, R> {
type Engine = E; 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) self.0(to)
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { 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]. /// Every struct that has [Content] is a renderable [Widget].
impl<E: Engine, W: Content<Engine = E>> Widget for W { impl<E: Engine, W: Content<Engine = E>> Widget for W {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
self.content().layout(to) self.content().min_size(to)
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { 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()), Some(wh) => to.render_in(to.area().clip(wh).into(), &self.content()),
None => Ok(()) 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> { impl<E: Engine, W: Widget<Engine = E>> Widget for Fill<E, W> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
let area = self.inner().layout(to.into())?; let area = self.inner().min_size(to.into())?;
if let Some(area) = area { if let Some(area) = area {
Ok(Some(match self { Ok(Some(match self {
Self::X(_) => [to.w().into(), area.h()], 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<()> F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = E>)->Usually<()>)->Usually<()>
{ {
type Engine = E; 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 w: E::Unit = 0.into();
let mut h: E::Unit = 0.into(); let mut h: E::Unit = 0.into();
(self.0)(&mut |layer| { (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()); w = w.max(layer_area.w());
h = h.max(layer_area.h()); h = h.max(layer_area.h());
} }
@ -245,7 +245,7 @@ where
Ok(Some([w, h].into())) Ok(Some([w, h].into()))
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { 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)) (self.0)(&mut |layer|to.render_in(to.area().clip(size).into(), &layer))
} else { } else {
Ok(()) 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> { impl<E: Engine, T: Widget<Engine = E>> Widget for Align<T> {
type Engine = E; type Engine = E;
fn layout (&self, outer_area: E::Size) -> Perhaps<E::Size> { fn min_size (&self, outer_area: E::Size) -> Perhaps<E::Size> {
self.inner().layout(outer_area) self.inner().min_size(outer_area)
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { fn render (&self, to: &mut E::Output) -> Usually<()> {
let outer_area = to.area(); 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); let inner_area = outer_area.clip(inner_size);
if let Some(aligned) = align(&self, outer_area.into(), inner_area.into()) { if let Some(aligned) = align(&self, outer_area.into(), inner_area.into()) {
to.render_in(aligned, self.inner())? 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> { impl<E: Engine, T: Widget<Engine = E>> Widget for Fixed<E::Unit, T> {
type Engine = E; 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 { Ok(match self {
Self::X(w, _) => Self::X(w, _) =>
if to.w() >= *w { Some([*w, to.h()].into()) } else { None }, 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<()> { 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()) to.render_in(to.area().clip(size).into(), self.inner())
} else { } else {
Ok(()) 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> { impl<E: Engine, T: Widget<Engine = E>> Widget for Min<E::Unit, T> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.inner().layout(to)?.map(|to|match *self { Ok(self.inner().min_size(to)?.map(|to|match *self {
Self::X(w, _) => [to.w().max(w), to.h()], Self::X(w, _) => [to.w().max(w), to.h()],
Self::Y(h, _) => [to.w(), to.h().max(h)], Self::Y(h, _) => [to.w(), to.h().max(h)],
Self::XY(w, h, _) => [to.w().max(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: 🡘 🡙 ←🡙→ // TODO: 🡘 🡙 ←🡙→
fn render (&self, to: &mut E::Output) -> Usually<()> { 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())) .map(|size|to.render_in(to.area().clip(size).into(), self.inner()))
.transpose()?.unwrap_or(())) .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> { impl<E: Engine, T: Widget<Engine = E>> Widget for Max<E:: Unit, T> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.inner().layout(to)?.map(|to|match *self { Ok(self.inner().min_size(to)?.map(|to|match *self {
Self::X(w, _) => [to.w().min(w), to.h()], Self::X(w, _) => [to.w().min(w), to.h()],
Self::Y(h, _) => [to.w(), to.h().min(h)], Self::Y(h, _) => [to.w(), to.h().min(h)],
Self::XY(w, h, _) => [to.w().min(w), to.h().min(h)], Self::XY(w, h, _) => [to.w().min(w), to.h().min(h)],
}.into())) }.into()))
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { 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())) .map(|size|to.render_in(to.area().clip(size).into(), self.inner()))
.transpose()?.unwrap_or(())) .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> { impl<E: Engine, T: Widget<Engine = E>> Widget for Grow<E::Unit, T> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.inner().layout(to)?.map(|to|match *self { Ok(self.inner().min_size(to)?.map(|to|match *self {
Self::X(w, _) => [to.w() + w, to.h()], Self::X(w, _) => [to.w() + w, to.h()],
Self::Y(h, _) => [to.w(), to.h() + h], Self::Y(h, _) => [to.w(), to.h() + h],
Self::XY(w, h, _) => [to.w() + w, to.h() + h], Self::XY(w, h, _) => [to.w() + w, to.h() + h],
}.into())) }.into()))
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { 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())) .map(|size|to.render_in(to.area().clip(size).into(), self.inner()))
.transpose()?.unwrap_or(())) .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> { impl<E: Engine, T: Widget<Engine = E>> Widget for Shrink<E::Unit, T> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.inner().layout(to)?.map(|to|match *self { Ok(self.inner().min_size(to)?.map(|to|match *self {
Self::X(w, _) => [ Self::X(w, _) => [
if to.w() > w { to.w() - w } else { 0.into() }, if to.w() > w { to.w() - w } else { 0.into() },
to.h() to.h()
@ -532,7 +532,7 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Shrink<E::Unit, T> {
}.into())) }.into()))
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { 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())) .map(|size|to.render_in(to.area().clip(size).into(), self.inner()))
.transpose()?.unwrap_or(())) .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> { impl<E: Engine, T: Widget<Engine = E>> Widget for Outset<E::Unit, T> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
match *self { match *self {
Self::X(x, ref inner) => Self::X(x, ref inner) =>
(inner as &dyn Widget<Engine = E>).grow_x(x + x), (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), (inner as &dyn Widget<Engine = E>).grow_y(y + y),
Self::XY(x, y, ref inner) => Self::XY(x, y, ref inner) =>
(inner as &dyn Widget<Engine = E>).grow_xy(x + x, y + y), (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<()> { fn render (&self, to: &mut E::Output) -> Usually<()> {
match *self { 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> { impl<E: Engine, T: Widget<Engine = E>> Widget for Push<E::Unit, T> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
self.inner().layout(to) self.inner().min_size(to)
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { fn render (&self, to: &mut E::Output) -> Usually<()> {
let area = to.area(); let area = to.area();
Ok(self.layout(area.wh().into())? Ok(self.min_size(area.wh().into())?
.map(|size|to.render_in(match *self { .map(|size|to.render_in(match *self {
Self::X(x, _) => [area.x() + x, area.y(), size.w(), size.h()], Self::X(x, _) => [area.x() + x, area.y(), size.w(), size.h()],
Self::Y(y, _) => [area.x(), area.y() + 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> { impl<E: Engine, T: Widget<Engine = E>> Widget for Pull<E::Unit, T> {
type Engine = E; type Engine = E;
fn layout (&self, to: E::Size) -> Perhaps<E::Size> { fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
self.inner().layout(to) self.inner().min_size(to)
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { fn render (&self, to: &mut E::Output) -> Usually<()> {
let area = to.area(); let area = to.area();
Ok(self.layout(area.wh().into())? Ok(self.min_size(area.wh().into())?
.map(|size|to.render_in(match *self { .map(|size|to.render_in(match *self {
Self::X(x, _) => [area.x().minus(x), area.y(), size.w(), size.h()], 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()], 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<()> F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = E>)->Usually<()>)->Usually<()>
{ {
type Engine = E; 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 w = 0.into();
let mut h = 0.into(); let mut h = 0.into();
match self.1 { match self.1 {
Direction::Down => { Direction::Down => {
(self.0)(&mut |component| { (self.0)(&mut |component| {
if h >= to.h() { return Ok(()) } 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()) { if let Some([width, height]) = size.map(|size|size.wh()) {
h = h + height.into(); h = h + height.into();
if width > w { w = width; } if width > w { w = width; }
@ -727,7 +727,7 @@ where
Direction::Right => { Direction::Right => {
(self.0)(&mut |component| { (self.0)(&mut |component| {
if w >= to.w() { return Ok(()) } 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()) { if let Some([width, height]) = size.map(|size|size.wh()) {
w = w + width.into(); w = w + width.into();
if height > h { h = height } if height > h { h = height }
@ -748,7 +748,7 @@ where
(self.0)(&mut |component| { (self.0)(&mut |component| {
if h >= area.h() { return Ok(()) } if h >= area.h() { return Ok(()) }
let item = component.push_y(h).max_y(area.h() - h); 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()) { if let Some([width, height]) = size.map(|size|size.wh()) {
item.render(to)?; item.render(to)?;
h = h + height; h = h + height;
@ -761,7 +761,7 @@ where
(self.0)(&mut |component| { (self.0)(&mut |component| {
if w >= area.w() { return Ok(()) } if w >= area.w() { return Ok(()) }
let item = component.push_x(w).max_x(area.w() - w); 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()) { if let Some([width, height]) = size.map(|size|size.wh()) {
item.render(to)?; item.render(to)?;
w = width + w; 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> { impl<E: Engine, A: Widget<Engine = E>, B: Widget<Engine = E>> Widget for Split<E, A, B> {
type Engine = E; 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)) Ok(Some(to))
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { fn render (&self, to: &mut E::Output) -> Usually<()> {
@ -878,7 +878,7 @@ impl<E: Engine> Measure<E> {
impl<E: Engine> Widget for Measure<E> { impl<E: Engine> Widget for Measure<E> {
type Engine = 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())) Ok(Some([0u16.into(), 0u16.into()].into()))
} }
fn render (&self, to: &mut E::Output) -> Usually<()> { fn render (&self, to: &mut E::Output) -> Usually<()> {

View file

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

View file

@ -97,7 +97,7 @@ pub struct TrackView<'a, E: Engine> {
impl<'a> Widget for TrackView<'a, Tui> { impl<'a> Widget for TrackView<'a, Tui> {
type Engine = Tui; type Engine = Tui;
fn layout (&self, area: [u16;2]) -> Perhaps<[u16;2]> { fn min_size (&self, area: [u16;2]) -> Perhaps<[u16;2]> {
todo!() todo!()
} }
fn render (&self, to: &mut TuiOutput) -> Usually<()> { fn render (&self, to: &mut TuiOutput) -> Usually<()> {

View file

@ -33,7 +33,7 @@ impl<E> Plugin<E> {
} }
impl Widget for Plugin<Tui> { impl Widget for Plugin<Tui> {
type Engine = Tui; type Engine = Tui;
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> { fn min_size (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
Ok(Some(to)) Ok(Some(to))
} }
fn render (&self, to: &mut TuiOutput) -> Usually<()> { fn render (&self, to: &mut TuiOutput) -> Usually<()> {

View file

@ -318,7 +318,7 @@ impl Sample {
impl Widget for SamplerView<Tui> { impl Widget for SamplerView<Tui> {
type Engine = Tui; type Engine = Tui;
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> { fn min_size (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
todo!() todo!()
} }
fn render (&self, to: &mut TuiOutput) -> Usually<()> { fn render (&self, to: &mut TuiOutput) -> Usually<()> {
@ -373,7 +373,7 @@ fn draw_sample (
impl Widget for AddSampleModal { impl Widget for AddSampleModal {
type Engine = Tui; type Engine = Tui;
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> { fn min_size (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
todo!() todo!()
//Align::Center(()).layout(to) //Align::Center(()).layout(to)
} }

View file

@ -9,11 +9,9 @@ pub struct PhraseView<'a> {
now: &'a Arc<Pulse>, now: &'a Arc<Pulse>,
size: &'a Measure<Tui>, size: &'a Measure<Tui>,
view_mode: &'a PhraseViewMode, view_mode: &'a PhraseViewMode,
note_point: usize, note_point: usize,
note_range: (usize, usize), note_range: (usize, usize),
note_names: (&'a str, &'a str), note_names: (&'a str, &'a str),
time_start: usize, time_start: usize,
time_point: usize, time_point: usize,
} }
@ -24,7 +22,7 @@ impl<'a, T: HasEditor> From<&'a T> for PhraseView<'a> {
let height = editor.size.h(); let height = editor.size.h();
let note_point = editor.note_point.load(Ordering::Relaxed); let note_point = editor.note_point.load(Ordering::Relaxed);
let mut note_lo = editor.note_lo.load(Ordering::Relaxed); let mut note_lo = editor.note_lo.load(Ordering::Relaxed);
let mut note_hi = 127.min(note_lo + height + 1); let mut note_hi = 127.min(note_lo + height);
if note_point < note_lo { if note_point < note_lo {
note_lo = note_point; note_lo = note_point;
editor.note_lo.store(note_lo, Ordering::Relaxed); editor.note_lo.store(note_lo, Ordering::Relaxed);
@ -84,10 +82,10 @@ impl<'a> Content for PhraseView<'a> {
); );
let mut lower_right = format!( let mut lower_right = format!(
"┤{}├", size.format() " {} ", size.format()
); );
if *focused && *entered { if *focused && *entered {
lower_right = format!("┤Note: {} ({}) {}├─{lower_right}", lower_right = format!(" Note: {} ({}) {} {lower_right}",
note_point, to_note_name(*note_point), pulses_to_name(*note_len) note_point, to_note_name(*note_point), pulses_to_name(*note_len)
); );
} }
@ -97,7 +95,7 @@ impl<'a> Content for PhraseView<'a> {
if *entered {""} else {" "} if *entered {""} else {" "}
); );
if let Some(phrase) = phrase { if let Some(phrase) = phrase {
upper_right = format!("┤Time: {}/{} {}{upper_right}", upper_right = format!(" Time: {}/{} {} {upper_right}",
time_point, phrase.read().unwrap().length, pulses_to_name(view_mode.time_zoom()), time_point, phrase.read().unwrap().length, pulses_to_name(view_mode.time_zoom()),
) )
}; };
@ -108,7 +106,7 @@ impl<'a> Content for PhraseView<'a> {
row!( row!(
CustomWidget::new(|to:[u16;2]|Ok(Some(to.clip_w(2))), move|to: &mut TuiOutput|{ CustomWidget::new(|to:[u16;2]|Ok(Some(to.clip_w(2))), move|to: &mut TuiOutput|{
Ok(if to.area().h() >= 2 { Ok(if to.area().h() >= 2 {
view_mode.blit_keys(to, *note_hi, *note_lo) view_mode.render_keys(to, *note_hi, *note_lo)
}) })
}).fill_y(), }).fill_y(),
lay!( lay!(
@ -116,14 +114,14 @@ impl<'a> Content for PhraseView<'a> {
size.set_wh(to.area.w(), to.area.h() as usize - 1); size.set_wh(to.area.w(), to.area.h() as usize - 1);
let draw = to.area().h() >= 2; let draw = to.area().h() >= 2;
Ok(if draw { Ok(if draw {
view_mode.blit_notes( view_mode.render_notes(
to, buffer, *time_start, *note_hi to, buffer, *time_start, *note_hi
) )
}) })
}).fill_x(), }).fill_x(),
CustomWidget::new(|to|Ok(Some(to)), move|to: &mut TuiOutput|{ CustomWidget::new(|to|Ok(Some(to)), move|to: &mut TuiOutput|{
Ok(if *focused && *entered { Ok(if *focused && *entered {
view_mode.blit_cursor( view_mode.render_cursor(
to, to,
*time_point, *time_start, view_mode.time_zoom(), *time_point, *time_start, view_mode.time_zoom(),
*note_point, *note_len, *note_hi, *note_lo, *note_point, *note_len, *note_hi, *note_lo,
@ -131,13 +129,14 @@ impl<'a> Content for PhraseView<'a> {
}) })
}) })
).fill_x() ).fill_x()
).fill_x() )
.bg(Color::Rgb(40, 50, 30)) .fill_x()
.border(Lozenge(Style::default().bg(Color::Rgb(40, 50, 30)).fg(if *focused{ .bg(Color::Rgb(40, 50, 30)),
Color::Rgb(100, 110, 40) //.border(Lozenge(Style::default().bg(Color::Rgb(40, 50, 30)).fg(if *focused{
} else { //Color::Rgb(100, 110, 40)
Color::Rgb(70, 80, 50) //} else {
}))), //Color::Rgb(70, 80, 50)
//}))),
CustomWidget::new(|to:[u16;2]|Ok(Some(to.clip_h(1))), move|to: &mut TuiOutput|{ CustomWidget::new(|to:[u16;2]|Ok(Some(to.clip_h(1))), move|to: &mut TuiOutput|{
//let playhead_inactive = Style::default().fg(Color::Rgb(255,255,255)).bg(Color::Rgb(40,50,30)); //let playhead_inactive = Style::default().fg(Color::Rgb(255,255,255)).bg(Color::Rgb(40,50,30));
//let playhead_active = playhead_inactive.clone().yellow().bold().not_dim(); //let playhead_active = playhead_inactive.clone().yellow().bold().not_dim();
@ -214,7 +213,7 @@ impl PhraseViewMode {
buffer buffer
} }
/// Draw a subsection of the [BigBuffer] onto a regular ratatui [Buffer]. /// Draw a subsection of the [BigBuffer] onto a regular ratatui [Buffer].
fn blit_notes ( fn render_notes (
&self, &self,
target: &mut TuiOutput, target: &mut TuiOutput,
source: &BigBuffer, source: &BigBuffer,
@ -228,6 +227,9 @@ impl PhraseViewMode {
let [x0, y0, w, h] = area.xywh(); let [x0, y0, w, h] = area.xywh();
for (x, target_x) in (x0..x0+w).enumerate() { for (x, target_x) in (x0..x0+w).enumerate() {
for (y, target_y) in (y0..y0+h).enumerate() { for (y, target_y) in (y0..y0+h).enumerate() {
if y > note_hi {
break
}
let source_x = time_start + x; let source_x = time_start + x;
let source_y = note_hi - y; let source_y = note_hi - y;
// TODO: enable loop rollover: // TODO: enable loop rollover:
@ -245,7 +247,7 @@ impl PhraseViewMode {
_ => unimplemented!() _ => unimplemented!()
} }
} }
fn blit_keys (&self, to: &mut TuiOutput, note_hi: usize, note_lo: usize) { fn render_keys (&self, to: &mut TuiOutput, note_hi: usize, note_lo: usize) {
let style = Some(Style::default().fg(Color::Rgb(192, 192, 192)).bg(Color::Rgb(0, 0, 0))); let style = Some(Style::default().fg(Color::Rgb(192, 192, 192)).bg(Color::Rgb(0, 0, 0)));
match self { match self {
Self::PianoHorizontal { .. } => { Self::PianoHorizontal { .. } => {
@ -271,7 +273,7 @@ impl PhraseViewMode {
_ => unimplemented!() _ => unimplemented!()
} }
} }
fn blit_cursor ( fn render_cursor (
&self, &self,
to: &mut TuiOutput, to: &mut TuiOutput,
time_point: usize, time_point: usize,

View file

@ -2,8 +2,8 @@ use crate::*;
impl Widget for TransportTui { impl Widget for TransportTui {
type Engine = Tui; type Engine = Tui;
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> { fn min_size (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
TransportView::from(self).layout(to) TransportView::from(self).min_size(to)
} }
fn render (&self, to: &mut TuiOutput) -> Usually<()> { fn render (&self, to: &mut TuiOutput) -> Usually<()> {
TransportView::from(self).render(to) TransportView::from(self).render(to)