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> {
//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)
//}
//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
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) }
}
)+}

View file

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

View file

@ -33,7 +33,7 @@ impl<E> Plugin<E> {
}
impl Widget for Plugin<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))
}
fn render (&self, to: &mut TuiOutput) -> Usually<()> {

View file

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

View file

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

View file

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