5 compile errors left

This commit is contained in:
🪞👃🪞 2024-09-07 16:44:49 +03:00
parent 7bcd40b425
commit b3f0f60400
13 changed files with 462 additions and 180 deletions

View file

@ -1,6 +1,4 @@
use crate::*; use crate::*;
use std::ops::{Add, Sub};
use std::cmp::{Ord, Eq, PartialEq};
/// Entry point for main loop /// Entry point for main loop
pub trait App<T: Engine> { pub trait App<T: Engine> {
@ -29,18 +27,6 @@ pub trait Engine: Sized {
-> &mut Self; -> &mut Self;
} }
pub trait Number: Send + Sync + Copy
+ Add<Self, Output=Self>
+ Sub<Self, Output=Self>
+ Ord + PartialEq + Eq {}
impl<T> Number for T where
T: Send + Sync + Copy
+ Add<Self, Output=Self>
+ Sub<Self, Output=Self>
+ Ord + PartialEq + Eq
{}
submod! { submod! {
collect collect
component component

View file

@ -54,6 +54,13 @@ impl<'a, E: Engine> Collect<'a, E> for Collection<'a, E> {
} }
} }
pub struct Layers<'a, E: Engine>(pub &'a [&'a dyn Render<E>]);
// this actually works, except for the type inference
//pub struct Layers<'a, E: Engine + 'a, I: std::iter::IntoIterator<Item = &'a dyn Render<E>>>(
//pub &'a I
//);
pub struct Layered<'a, E: Engine>(pub Collection<'a, E>); pub struct Layered<'a, E: Engine>(pub Collection<'a, E>);
impl<'a, E: Engine> Layered<'a, E> { impl<'a, E: Engine> Layered<'a, E> {

View file

@ -57,13 +57,15 @@ impl<R, E: Engine> Render<E> for RwLock<R> where R: Render<E> {
} }
} }
/// Boxed closures can be rendered. // FIXME: components are now 2 thunks (layout and render).
/// // maybe this resolves the conflict describe below?
/// Rendering unboxed closures should also be possible; ///// Boxed closures can be rendered.
/// but in practice implementing the trait for an unboxed /////
/// `Fn` closure causes an impl conflict. ///// Rendering unboxed closures should also be possible;
impl<'a, E: Engine> Render<E> for Box<dyn Fn(&mut E) -> Perhaps<E::Rendered> + Send + Sync + 'a> { ///// but in practice implementing the trait for an unboxed
fn render (&self, to: &mut E) -> Perhaps<E::Rendered> { ///// `Fn` closure causes an impl conflict.
(*self)(to) //impl<'a, E: Engine> Render<E> for Box<dyn Fn(&mut E) -> Perhaps<E::Rendered> + Send + Sync + 'a> {
} //fn render (&self, to: &mut E) -> Perhaps<E::Rendered> {
} //(*self)(to)
//}
//}

View file

@ -15,6 +15,9 @@ pub(crate) use std::thread::{spawn, JoinHandle};
pub(crate) use std::time::Duration; pub(crate) use std::time::Duration;
pub(crate) use atomic_float::*; pub(crate) use atomic_float::*;
use better_panic::{Settings, Verbosity}; use better_panic::{Settings, Verbosity};
use std::ops::{Add, Sub};
use std::cmp::{Ord, Eq, PartialEq};
use std::fmt::{Debug, Display};
/// Define and reexport submodules. /// Define and reexport submodules.
#[macro_export] macro_rules! submod { #[macro_export] macro_rules! submod {
@ -40,3 +43,18 @@ pub type Usually<T> = Result<T, Box<dyn Error>>;
/// Standard optional result type. /// Standard optional result type.
pub type Perhaps<T> = Result<Option<T>, Box<dyn Error>>; pub type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
/// Standard numeric type.
pub trait Number: Send + Sync + Copy
+ Add<Self, Output=Self>
+ Sub<Self, Output=Self>
+ Ord + PartialEq + Eq
+ Debug + Display {}
impl<T> Number for T where
T: Send + Sync + Copy
+ Add<Self, Output=Self>
+ Sub<Self, Output=Self>
+ Ord + PartialEq + Eq
+ Debug + Display
{}

View file

@ -30,6 +30,13 @@ pub trait Area<N: Number>: Copy {
fn lrtb (&self) -> [N;4] { fn lrtb (&self) -> [N;4] {
[self.x(), self.x2(), self.y(), self.y2()] [self.x(), self.x2(), self.y(), self.y2()]
} }
fn expect_min (&self, w: N, h: N) -> Usually<&Self> {
if self.w() < w || self.h() < h {
Err(format!("min {w}x{h}").into())
} else {
Ok(self)
}
}
} }
impl<N: Number> Area<N> for (N, N, N, N) { impl<N: Number> Area<N> for (N, N, N, N) {

View file

@ -201,7 +201,14 @@ pub enum TuiEvent {
/// Rendering unit struct to Ratatui returns zero-sized [Area] at render coordinates. /// Rendering unit struct to Ratatui returns zero-sized [Area] at render coordinates.
impl Render<Tui> for () { impl Render<Tui> for () {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
Ok(Some([to.area.x(), to.area.y(), 0, 0])) self.layout(to.area())
}
}
/// Layout of unit struct in Ratatui is zero-sized [Area] at render coordinates.
impl Layout<Tui> for () {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
Ok(Some([area.x(), area.y(), 0, 0]))
} }
} }

View file

@ -86,8 +86,8 @@ macro_rules! border {
($($T:ty { ($($T:ty {
$nw:literal $n:literal $ne:literal $w:literal $e:literal $sw:literal $s:literal $se:literal $nw:literal $n:literal $ne:literal $w:literal $e:literal $sw:literal $s:literal $se:literal
$($x:tt)* $($x:tt)*
}),+) => { }),+) => {$(
$(impl BorderStyle for $T { impl BorderStyle for $T {
const NW: &'static str = $nw; const NW: &'static str = $nw;
const N: &'static str = $n; const N: &'static str = $n;
const NE: &'static str = $ne; const NE: &'static str = $ne;
@ -97,8 +97,13 @@ macro_rules! border {
const S: &'static str = $s; const S: &'static str = $s;
const SE: &'static str = $se; const SE: &'static str = $se;
$($x)* $($x)*
})+
} }
impl Render<Tui> for $T {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
self.draw(to)
}
}
)+}
} }
pub struct Lozenge(pub Style); pub struct Lozenge(pub Style);

View file

@ -1,5 +1,36 @@
use crate::*; use crate::*;
impl Layout<Tui> for &str {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
let [x, y, ..] = area;
// TODO: line breaks
Ok(Some([x, y, self.len() as u16, 1]))
}
}
impl Render<Tui> for &str {
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))
}
}
pub struct Styled<T: Layout<Tui>>(pub Option<Style>, pub T);
impl Layout<Tui> for Styled<&str> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
Ok(Some([area.x(), area.y(), self.1.len() as u16, 1]))
}
}
impl Render<Tui> for Styled<&str> {
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]))
}
}
pub struct FillBg(pub Color); pub struct FillBg(pub Color);
impl Render<Tui> for FillBg { impl Render<Tui> for FillBg {

View file

@ -1,5 +1,24 @@
use crate::*; use crate::*;
impl<T: Layout<Tui>> Layout<Tui> for Option<T> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
match self {
Some(layout) => layout.layout(area),
None => ().layout(area)
}
}
}
impl<'a> Render<Tui> for Layers<'a, Tui> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area();
for layer in self.0.iter() {
layer.render(to)?;
}
Ok(Some(area))
}
}
impl<'a> Render<Tui> for Layered<'a, Tui> { impl<'a> Render<Tui> for Layered<'a, Tui> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area(); let area = to.area();
@ -16,6 +35,12 @@ impl<'a> Render<Tui> for Split<'a, Tui> {
} }
} }
impl<'a> Layout<Tui> for Split<'a, Tui> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
// TODO // TODO
impl<'a> Split<'a, Tui> { impl<'a> Split<'a, Tui> {
pub fn render_areas (&self, to: &mut Tui) -> Usually<([u16;4], Vec<Option<[u16;4]>>)> { pub fn render_areas (&self, to: &mut Tui) -> Usually<([u16;4], Vec<Option<[u16;4]>>)> {

View file

@ -4,187 +4,235 @@ pub fn draw (state: &Arranger<Tui>, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area(); let area = to.area();
let area = [area.x(), area.y(), area.w(), area.h().min((2 + state.tracks.len() * 2) as u16)]; let area = [area.x(), area.y(), area.w(), area.h().min((2 + state.tracks.len() * 2) as u16)];
let tracks = state.tracks.as_slice(); let tracks = state.tracks.as_slice();
Layered::new() Layers(&[
//.add(FillBg(Nord::bg_lo(state.focused, state.entered))) &state.focused.then_some(FillBg(COLOR_BG0)),
.add(Split::right() &Split::right()
.add(TrackNameColumn(tracks, state.selected)) .add(TrackNameColumn(tracks, state.selected))
.add(TrackMonitorColumn(tracks)) .add(TrackMonitorColumn(tracks))
.add(TrackRecordColumn(tracks)) .add(TrackRecordColumn(tracks))
.add(TrackOverdubColumn(tracks)) .add(TrackOverdubColumn(tracks))
.add(TrackEraseColumn(tracks)) .add(TrackEraseColumn(tracks))
.add(TrackGainColumn(tracks)) .add(TrackGainColumn(tracks))
.add(TrackScenesColumn(tracks, state.scenes.as_slice(), state.selected))) .add(TrackScenesColumn(tracks, state.scenes.as_slice(), state.selected))
.render(to) ]).render(to.with_rect(area))
} }
struct TrackNameColumn<'a>(&'a [Sequencer], ArrangerFocus); struct TrackNameColumn<'a>(&'a [Sequencer], ArrangerFocus);
impl<'a> Layout<Tui> for TrackNameColumn<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for TrackNameColumn<'a> { impl<'a> Render<Tui> for TrackNameColumn<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let Self(tracks, selected) = self; todo!();
let yellow = Some(Style::default().yellow().bold().not_dim()); //let Self(tracks, selected) = self;
let white = Some(Style::default().white().bold().not_dim()); //let yellow = Some(Style::default().yellow().bold().not_dim());
let area = to.area(); //let white = Some(Style::default().white().bold().not_dim());
let area = [area.x(), area.y(), 3 + 5.max(track_name_max_len(tracks)) as u16, area.h()]; //let area = to.area();
let offset = 0; // track scroll offset //let area = [area.x(), area.y(), 3 + 5.max(track_name_max_len(tracks)) as u16, area.h()];
for y in 0..area.h() { //let offset = 0; // track scroll offset
if y == 0 { //for y in 0..area.h() {
to.blit(&"Mixer", area.x() + 1, area.y() + y, Some(DIM))?; //if y == 0 {
} else if y % 2 == 0 { //to.blit(&"Mixer", area.x() + 1, area.y() + y, Some(DIM))?;
let index = (y as usize - 2) / 2 + offset; //} else if y % 2 == 0 {
if let Some(track) = tracks.get(index) { //let index = (y as usize - 2) / 2 + offset;
let selected = selected.track() == Some(index); //if let Some(track) = tracks.get(index) {
let style = if selected { yellow } else { white }; //let selected = selected.track() == Some(index);
to.blit(&format!(" {index:>02} "), area.x(), area.y() + y, style)?; //let style = if selected { yellow } else { white };
to.blit(&*track.name.read().unwrap(), area.x() + 4, area.y() + y, style)?; //to.blit(&format!(" {index:>02} "), area.x(), area.y() + y, style)?;
} //to.blit(&*track.name.read().unwrap(), area.x() + 4, area.y() + y, style)?;
} //}
} //}
Ok(Some(area)) //}
//Ok(Some(area))
} }
} }
struct TrackMonitorColumn<'a>(&'a [Sequencer]); struct TrackMonitorColumn<'a>(&'a [Sequencer]);
impl<'a> Layout<Tui> for TrackMonitorColumn<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for TrackMonitorColumn<'a> { impl<'a> Render<Tui> for TrackMonitorColumn<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let Self(tracks) = self; todo!();
let mut area = to.area(); //let Self(tracks) = self;
let on = Some(Style::default().not_dim().green().bold()); //let mut area = to.area();
let off = Some(DIM); //let on = Some(Style::default().not_dim().green().bold());
area.x += 1; //let off = Some(DIM);
for y in 0..area.h() { //area.x += 1;
if y == 0 { //for y in 0..area.h() {
//" MON ".blit(to.buffer, area.x, area.y + y, style2)?; //if y == 0 {
} else if y % 2 == 0 { ////" MON ".blit(to.buffer, area.x, area.y + y, style2)?;
let index = (y as usize - 2) / 2; //} else if y % 2 == 0 {
if let Some(track) = tracks.get(index) { //let index = (y as usize - 2) / 2;
let style = if track.monitoring { on } else { off }; //if let Some(track) = tracks.get(index) {
to.blit(&" MON ", area.x(), area.y() + y, style)?; //let style = if track.monitoring { on } else { off };
} else { //to.blit(&" MON ", area.x(), area.y() + y, style)?;
area.height = y; //} else {
break //area.height = y;
} //break
} //}
} //}
area.width = 4; //}
Ok(Some(area)) //area.width = 4;
//Ok(Some(area))
} }
} }
struct TrackRecordColumn<'a>(&'a [Sequencer]); struct TrackRecordColumn<'a>(&'a [Sequencer]);
impl<'a> Layout<Tui> for TrackRecordColumn<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for TrackRecordColumn<'a> { impl<'a> Render<Tui> for TrackRecordColumn<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let Self(tracks) = self; todo!();
let mut area = to.area(); //let Self(tracks) = self;
let on = Some(Style::default().not_dim().red().bold()); //let mut area = to.area();
let off = Some(Style::default().dim()); //let on = Some(Style::default().not_dim().red().bold());
area.x += 1; //let off = Some(Style::default().dim());
for y in 0..area.h() { //area.x += 1;
if y == 0 { //for y in 0..area.h() {
//" REC ".blit(to.buffer, area.x, area.y + y, style2)?; //if y == 0 {
} else if y % 2 == 0 { ////" REC ".blit(to.buffer, area.x, area.y + y, style2)?;
let index = (y as usize - 2) / 2; //} else if y % 2 == 0 {
if let Some(track) = tracks.get(index) { //let index = (y as usize - 2) / 2;
let style = if track.recording { on } else { off }; //if let Some(track) = tracks.get(index) {
to.blit(&" REC ", area.x(), area.y() + y, style)?; //let style = if track.recording { on } else { off };
} else { //to.blit(&" REC ", area.x(), area.y() + y, style)?;
area.height = y; //} else {
break //area.height = y;
} //break
} //}
} //}
area.width = 4; //}
Ok(Some(area)) //area.width = 4;
//Ok(Some(area))
} }
} }
struct TrackOverdubColumn<'a>(&'a [Sequencer]); struct TrackOverdubColumn<'a>(&'a [Sequencer]);
impl<'a> Layout<Tui> for TrackOverdubColumn<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for TrackOverdubColumn<'a> { impl<'a> Render<Tui> for TrackOverdubColumn<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let Self(tracks) = self; todo!();
let mut area = to.area(); //let Self(tracks) = self;
let on = Some(Style::default().not_dim().yellow().bold()); //let mut area = to.area();
let off = Some(Style::default().dim()); //let on = Some(Style::default().not_dim().yellow().bold());
area.x = area.x + 1; //let off = Some(Style::default().dim());
for y in 0..area.h() { //area.x = area.x + 1;
if y == 0 { //for y in 0..area.h() {
//" OVR ".blit(to.buffer, area.x, area.y + y, style2)?; //if y == 0 {
} else if y % 2 == 0 { ////" OVR ".blit(to.buffer, area.x, area.y + y, style2)?;
let index = (y as usize - 2) / 2; //} else if y % 2 == 0 {
if let Some(track) = tracks.get(index) { //let index = (y as usize - 2) / 2;
to.blit(&" OVR ", area.x(), area.y() + y, if track.overdub { //if let Some(track) = tracks.get(index) {
on //to.blit(&" OVR ", area.x(), area.y() + y, if track.overdub {
} else { //on
off //} else {
})?; //off
} else { //})?;
area.height = y; //} else {
break //area.height = y;
} //break
} //}
} //}
area.width = 4; //}
Ok(Some(area)) //area.width = 4;
//Ok(Some(area))
} }
} }
struct TrackEraseColumn<'a>(&'a [Sequencer]); struct TrackEraseColumn<'a>(&'a [Sequencer]);
impl<'a> Layout<Tui> for TrackEraseColumn<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for TrackEraseColumn<'a> { impl<'a> Render<Tui> for TrackEraseColumn<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let Self(tracks) = self; todo!();
let mut area = to.area(); //let Self(tracks) = self;
let off = Some(Style::default().dim()); //let mut area = to.area();
area.x = area.x + 1; //let off = Some(Style::default().dim());
for y in 0..area.h() { //area.x = area.x + 1;
if y == 0 { //for y in 0..area.h() {
//" DEL ".blit(to.buffer, area.x, area.y + y, style2)?; //if y == 0 {
} else if y % 2 == 0 { ////" DEL ".blit(to.buffer, area.x, area.y + y, style2)?;
let index = (y as usize - 2) / 2; //} else if y % 2 == 0 {
if let Some(_) = tracks.get(index) { //let index = (y as usize - 2) / 2;
to.blit(&" DEL ", area.x(), area.y() + y, off)?; //if let Some(_) = tracks.get(index) {
} else { //to.blit(&" DEL ", area.x(), area.y() + y, off)?;
area.height = y; //} else {
break //area.height = y;
} //break
} //}
} //}
area.width = 4; //}
Ok(Some(area)) //area.width = 4;
//Ok(Some(area))
} }
} }
struct TrackGainColumn<'a>(&'a [Sequencer]); struct TrackGainColumn<'a>(&'a [Sequencer]);
impl<'a> Layout<Tui> for TrackGainColumn<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for TrackGainColumn<'a> { impl<'a> Render<Tui> for TrackGainColumn<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let Self(tracks) = self; todo!();
let mut area = to.area(); //let Self(tracks) = self;
let off = Some(Style::default().dim()); //let mut area = to.area();
area.x = area.x() + 1; //let off = Some(Style::default().dim());
for y in 0..area.h() { //area.x = area.x() + 1;
if y == 0 { //for y in 0..area.h() {
//" GAIN ".blit(to.buffer, area.x, area.y + y, style2)?; //if y == 0 {
} else if y % 2 == 0 { ////" GAIN ".blit(to.buffer, area.x, area.y + y, style2)?;
let index = (y as usize - 2) / 2; //} else if y % 2 == 0 {
if let Some(_) = tracks.get(index) { //let index = (y as usize - 2) / 2;
to.blit(&" +0.0 ", area.x(), area.y() + y, off)?; //if let Some(_) = tracks.get(index) {
} else { //to.blit(&" +0.0 ", area.x(), area.y() + y, off)?;
area.height = y; //} else {
break //area.height = y;
} //break
} //}
} //}
area.width = 7; //}
Ok(Some(area)) //area.width = 7;
//Ok(Some(area))
} }
} }
struct TrackScenesColumn<'a>(&'a [Sequencer], &'a [Scene], ArrangerFocus); struct TrackScenesColumn<'a>(&'a [Sequencer], &'a [Scene], ArrangerFocus);
impl<'a> Layout<Tui> for TrackScenesColumn<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for TrackScenesColumn<'a> { impl<'a> Render<Tui> for TrackScenesColumn<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let Self(tracks, scenes, selected) = self; let Self(tracks, scenes, selected) = self;

View file

@ -51,6 +51,12 @@ pub fn draw <'a, 'b> (
struct ColumnSeparators<'a>(u16, &'a [(usize, usize)]); struct ColumnSeparators<'a>(u16, &'a [(usize, usize)]);
impl<'a> Layout<Tui> for ColumnSeparators<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for ColumnSeparators<'a> { impl<'a> Render<Tui> for ColumnSeparators<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area(); let area = to.area();
@ -68,6 +74,12 @@ impl<'a> Render<Tui> for ColumnSeparators<'a> {
struct RowSeparators<'a>(&'a [(usize, usize)]); struct RowSeparators<'a>(&'a [(usize, usize)]);
impl<'a> Layout<Tui> for RowSeparators<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for RowSeparators<'a> { impl<'a> Render<Tui> for RowSeparators<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area(); let area = to.area();
@ -91,6 +103,12 @@ struct CursorFocus<'a>(
ArrangerFocus, u16, &'a [(usize, usize)], &'a [(usize, usize)] ArrangerFocus, u16, &'a [(usize, usize)], &'a [(usize, usize)]
); );
impl<'a> Layout<Tui> for CursorFocus<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for CursorFocus<'a> { impl<'a> Render<Tui> for CursorFocus<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area(); let area = to.area();
@ -157,6 +175,12 @@ impl<'a> Render<Tui> for CursorFocus<'a> {
struct TracksHeader<'a>(u16, &'a[(usize, usize)], &'a [Sequencer]); struct TracksHeader<'a>(u16, &'a[(usize, usize)], &'a [Sequencer]);
impl<'a> Layout<Tui> for TracksHeader<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for TracksHeader<'a> { impl<'a> Render<Tui> for TracksHeader<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area(); let area = to.area();
@ -177,6 +201,12 @@ impl<'a> Render<Tui> for TracksHeader<'a> {
struct SceneRows<'a>(u16, &'a[(usize, usize)], &'a[(usize, usize)], &'a[Sequencer], &'a[Scene]); struct SceneRows<'a>(u16, &'a[(usize, usize)], &'a[(usize, usize)], &'a[Sequencer], &'a[Scene]);
impl<'a> Layout<Tui> for SceneRows<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for SceneRows<'a> { impl<'a> Render<Tui> for SceneRows<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area(); let area = to.area();
@ -206,6 +236,12 @@ impl<'a> Render<Tui> for SceneRows<'a> {
struct SceneRow<'a>(&'a[Sequencer], &'a Scene, &'a[(usize, usize)], u16); struct SceneRow<'a>(&'a[Sequencer], &'a Scene, &'a[(usize, usize)], u16);
impl<'a> Layout<Tui> for SceneRow<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for SceneRow<'a> { impl<'a> Render<Tui> for SceneRow<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area(); let area = to.area();
@ -232,6 +268,12 @@ impl<'a> Render<Tui> for SceneRow<'a> {
struct SceneClip<'a>(&'a Sequencer, usize); struct SceneClip<'a>(&'a Sequencer, usize);
impl<'a> Layout<Tui> for SceneClip<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for SceneClip<'a> { impl<'a> Render<Tui> for SceneClip<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area(); let area = to.area();

View file

@ -48,6 +48,12 @@ const STYLE_VALUE: Option<Style> = Some(Style {
struct SequenceName<'a>(&'a Sequencer); struct SequenceName<'a>(&'a Sequencer);
impl<'a> Layout<Tui> for SequenceName<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for SequenceName<'a> { impl<'a> Render<Tui> for SequenceName<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let [x, y, ..] = to.area(); let [x, y, ..] = to.area();
@ -61,6 +67,12 @@ impl<'a> Render<Tui> for SequenceName<'a> {
struct SequenceRange; struct SequenceRange;
impl Layout<Tui> for SequenceRange {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for SequenceRange { impl<'a> Render<Tui> for SequenceRange {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let [x, y, ..] = to.area(); let [x, y, ..] = to.area();
@ -76,6 +88,12 @@ impl<'a> Render<Tui> for SequenceRange {
struct SequenceLoopRange; struct SequenceLoopRange;
impl Layout<Tui> for SequenceLoopRange {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for SequenceLoopRange { impl<'a> Render<Tui> for SequenceLoopRange {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let [x, y, ..] = to.area(); let [x, y, ..] = to.area();
@ -92,6 +110,12 @@ impl<'a> Render<Tui> for SequenceLoopRange {
struct SequenceNoteRange; struct SequenceNoteRange;
impl Layout<Tui> for SequenceNoteRange {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for SequenceNoteRange { impl<'a> Render<Tui> for SequenceNoteRange {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let [x, y, ..] = to.area(); let [x, y, ..] = to.area();
@ -110,6 +134,12 @@ impl<'a> Render<Tui> for SequenceNoteRange {
struct SequenceKeys<'a>(&'a Sequencer); struct SequenceKeys<'a>(&'a Sequencer);
impl<'a> Layout<Tui> for SequenceKeys<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for SequenceKeys<'a> { impl<'a> Render<Tui> for SequenceKeys<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area(); let area = to.area();
@ -129,6 +159,12 @@ impl<'a> Render<Tui> for SequenceKeys<'a> {
struct SequenceNotes<'a>(&'a Sequencer); struct SequenceNotes<'a>(&'a Sequencer);
impl<'a> Layout<Tui> for SequenceNotes<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for SequenceNotes<'a> { impl<'a> Render<Tui> for SequenceNotes<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area(); let area = to.area();
@ -158,6 +194,12 @@ impl<'a> Render<Tui> for SequenceNotes<'a> {
struct SequenceCursor<'a>(&'a Sequencer); struct SequenceCursor<'a>(&'a Sequencer);
impl<'a> Layout<Tui> for SequenceCursor<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for SequenceCursor<'a> { impl<'a> Render<Tui> for SequenceCursor<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area(); let area = to.area();
@ -174,6 +216,12 @@ impl<'a> Render<Tui> for SequenceCursor<'a> {
struct SequenceZoom<'a>(&'a Sequencer); struct SequenceZoom<'a>(&'a Sequencer);
impl<'a> Layout<Tui> for SequenceZoom<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for SequenceZoom<'a> { impl<'a> Render<Tui> for SequenceZoom<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area(); let area = to.area();
@ -186,6 +234,12 @@ impl<'a> Render<Tui> for SequenceZoom<'a> {
struct SequenceTimer<'a>(&'a Sequencer, Arc<RwLock<Phrase>>); struct SequenceTimer<'a>(&'a Sequencer, Arc<RwLock<Phrase>>);
impl<'a> Layout<Tui> for SequenceTimer<'a> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
impl<'a> Render<Tui> for SequenceTimer<'a> { impl<'a> Render<Tui> for SequenceTimer<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area(); let area = to.area();

View file

@ -21,31 +21,60 @@ impl Render<Tui> for TransportToolbar {
} }
} }
impl Layout<Tui> for TransportPlayPauseButton {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
area.expect_min(10, 1)?;
Ok(Some([area.x(), area.y(), 10, 1]))
}
}
impl Render<Tui> for TransportPlayPauseButton { impl Render<Tui> for TransportPlayPauseButton {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area();
let [x, y, ..] = area;
let Self { value, focused } = &self; let Self { value, focused } = &self;
let style = Some(match value { Layers(&[
Some(TransportState::Stopped) => GRAY_DIM.bold(), &focused.then_some(CORNERS),
Some(TransportState::Starting) => GRAY_NOT_DIM_BOLD, &Inset::W(1, Styled(match value {
Some(TransportState::Rolling) => WHITE_NOT_DIM_BOLD, Some(TransportState::Stopped) => Some(GRAY_DIM.bold()),
Some(TransportState::Starting) => Some(GRAY_NOT_DIM_BOLD),
Some(TransportState::Rolling) => Some(WHITE_NOT_DIM_BOLD),
_ => unreachable!(), _ => unreachable!(),
}); }, match value {
let label = match value {
Some(TransportState::Rolling) => "▶ PLAYING", Some(TransportState::Rolling) => "▶ PLAYING",
Some(TransportState::Starting) => "READY ...", Some(TransportState::Starting) => "READY ...",
Some(TransportState::Stopped) => "⏹ STOPPED", Some(TransportState::Stopped) => "⏹ STOPPED",
_ => unreachable!(), _ => unreachable!(),
}; }))
let area = to.blit(&label, x + 1, y, style)?.unwrap(); ]).render(to)
let area = [area.x(), area.y(), area.w() + 1, area.h() + 1]; //let area = to.area();
if *focused { //let [x, y, ..] = area;
let area = [area.x() - 1, area.y(), area.w() - 1, area.h() ]; //let Self { value, focused } = &self;
CORNERS.draw(to)?; //let style = Some(match value {
to.fill_bg(area, COLOR_BG1); //Some(TransportState::Stopped) => GRAY_DIM.bold(),
//Some(TransportState::Starting) => GRAY_NOT_DIM_BOLD,
//Some(TransportState::Rolling) => WHITE_NOT_DIM_BOLD,
//_ => unreachable!(),
//});
//let label = match value {
//Some(TransportState::Rolling) => "▶ PLAYING",
//Some(TransportState::Starting) => "READY ...",
//Some(TransportState::Stopped) => "⏹ STOPPED",
//_ => unreachable!(),
//};
//let area = to.blit(&label, x + 1, y, style)?.unwrap();
//let area = [area.x(), area.y(), area.w() + 1, area.h() + 1];
//if *focused {
//let area = [area.x() - 1, area.y(), area.w() - 1, area.h() ];
//CORNERS.draw(to)?;
//to.fill_bg(area, COLOR_BG1);
//}
//Ok(Some(area))
} }
Ok(Some(area)) }
impl Layout<Tui> for TransportBPM {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
area.expect_min(10, 1)?;
Ok(Some([area.x(), area.y(), 10, 1]))
} }
} }
@ -68,6 +97,13 @@ impl Render<Tui> for TransportBPM {
} }
} }
impl Layout<Tui> for TransportQuantize {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
area.expect_min(10, 1)?;
Ok(Some([area.x(), area.y(), 10, 1]))
}
}
impl Render<Tui> for TransportQuantize { impl Render<Tui> for TransportQuantize {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let [x, y, ..] = to.area(); let [x, y, ..] = to.area();
@ -86,6 +122,13 @@ impl Render<Tui> for TransportQuantize {
} }
} }
impl Layout<Tui> for TransportSync {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
area.expect_min(10, 1)?;
Ok(Some([area.x(), area.y(), 10, 1]))
}
}
impl Render<Tui> for TransportSync { impl Render<Tui> for TransportSync {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let [x, y, ..] = to.area(); let [x, y, ..] = to.area();
@ -104,6 +147,13 @@ impl Render<Tui> for TransportSync {
} }
} }
impl Layout<Tui> for TransportClock {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
area.expect_min(10, 1)?;
Ok(Some([area.x(), area.y(), 20, 1]))
}
}
impl Render<Tui> for TransportClock { impl Render<Tui> for TransportClock {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let [x, y, width, _] = to.area(); let [x, y, width, _] = to.area();