wip: provide more components to app

This commit is contained in:
🪞👃🪞 2025-01-11 21:09:21 +01:00
parent ed462cd0f6
commit 2cd56e7391
3 changed files with 126 additions and 21 deletions

View file

@ -98,15 +98,15 @@ impl EdnViewData<TuiOut> for &App {
Nil => Box::new(()),
Exp(items) => Box::new(EdnView::from_items(*self, items.as_slice())),
Sym(":editor") => (&self.editor).boxed(),
Sym(":inputs") => self.input_row(w).boxed(),
Sym(":outputs") => self.output_row(w).boxed(),
Sym(":inputs") => self.input_row(w, 3).boxed(),
Sym(":outputs") => self.output_row(w, 3).boxed(),
Sym(":pool") => self.pool().boxed(),
Sym(":sample") => self.sample().boxed(),
Sym(":sampler") => self.sampler().boxed(),
Sym(":scenes") => self.scene_row(w).boxed(),
Sym(":status") => self.status(0).boxed(),
Sym(":toolbar") => self.toolbar().boxed(),
Sym(":tracks") => self.track_row(w).boxed(),
Sym(":tracks") => self.track_row(w, 3).boxed(),
_ => panic!("no content for {item:?}")
}
}
@ -162,10 +162,25 @@ impl App {
}
None
}
fn track_row (&self, w: u16) -> impl Content<TuiOut> + '_ { "" }
fn input_row (&self, w: u16) -> impl Content<TuiOut> + '_ { "" }
fn row <'a> (
&'a self, w: u16, h: u16, a: impl Content<TuiOut> + 'a, b: impl Content<TuiOut> + 'a
) -> impl Content<TuiOut> + 'a {
Fixed::y(h, Bsp::e(
Fixed::xy(self.sidebar_w() as u16, h, a),
Fill::x(Align::c(Fixed::xy(w, h, b)))
))
}
fn track_row (&self, w: u16, h: u16) -> impl Content<TuiOut> + '_ {
self.row(w, h, track_header(&self), track_cells(&self))
}
fn input_row (&self, w: u16, h: u16) -> impl Content<TuiOut> + '_ {
self.row(w, h, input_header(&self), input_cells(&self))
}
fn output_row (&self, w: u16, h: u16) -> impl Content<TuiOut> + '_ {
self.row(w, h, output_header(&self), output_cells(&self))
}
fn scene_row (&self, w: u16) -> impl Content<TuiOut> + '_ { "" }
fn output_row (&self, w: u16) -> impl Content<TuiOut> + '_ { "" }
pub fn tracks_with_sizes (&self)
-> impl Iterator<Item = (usize, &ArrangerTrack, usize, usize)>
@ -205,3 +220,93 @@ pub fn tracks_with_sizes <'a> (
data
})
}
pub fn track_header <'a> (state: &'a App) -> BoxThunk<'a, TuiOut> {
(||Tui::bg(TuiTheme::g(32), Tui::bold(true, Bsp::s(
row!(
Tui::fg(TuiTheme::g(128), "add "),
Tui::fg(TuiTheme::orange(), "t"),
Tui::fg(TuiTheme::g(128), "rack"),
),
row!(
Tui::fg(TuiTheme::orange(), "a"),
Tui::fg(TuiTheme::g(128), "dd scene"),
),
))).boxed()).into()
}
pub fn track_cells <'a> (state: &'a App) -> BoxThunk<'a, TuiOut> {
let iter = ||state.tracks_with_sizes();
(move||Align::x(Map::new(iter, move|(_, track, x1, x2), i| {
let name = Push::x(1, &track.name);
let color = track.color();
let fg = color.lightest.rgb;
let bg = color.base.rgb;
let active = state.selected.track() == Some(i);
let bfg = if active { Color::Rgb(255,255,255) } else { Color::Rgb(0,0,0) };
let border = Style::default().fg(bfg).bg(bg);
Tui::bg(bg, map_east(x1 as u16, (x2 - x1) as u16,
Outer(border).enclose(Tui::fg_bg(fg, bg, Tui::bold(true, Fill::x(Align::x(name)))))
))
})).boxed()).into()
}
fn help_tag <'a>(before: &'a str, key: &'a str, after: &'a str) -> impl Content<TuiOut> + 'a {
let lo = TuiTheme::g(128);
let hi = TuiTheme::orange();
Tui::bold(true, row!(Tui::fg(lo, before), Tui::fg(hi, key), Tui::fg(lo, after)))
}
fn input_header <'a> (state: &'a App) -> BoxThunk<'a, TuiOut> {
let fg = TuiTheme::g(224);
let bg = TuiTheme::g(64);
(move||Bsp::s(help_tag("midi ", "I", "ns"), state.midi_ins.get(0).map(|inp|Bsp::s(
Fill::x(Tui::bold(true, Tui::fg_bg(fg, bg, Align::w(inp.name.clone())))),
inp.connect.get(0).map(|connect|Fill::x(Align::w(Tui::bold(false,
Tui::fg_bg(fg, bg, connect.info()))))),
))).boxed()).into()
}
fn input_cells <'a> (state: &'a App) -> BoxThunk<'a, TuiOut> {
(move||Align::x(Map::new(||state.tracks_with_sizes(), move|(_, track, x1, x2), i| {
let w = (x2 - x1) as u16;
let color: ItemPalette = track.color().dark.into();
map_east(x1 as u16, w, Fixed::x(w, cell(color, Bsp::n(
rec_mon(color.base.rgb, false, false),
phat_hi(color.base.rgb, color.dark.rgb)
))))
})).boxed()).into()
}
fn output_header <'a> (state: &'a App) -> BoxThunk<'a, TuiOut> {
let fg = TuiTheme::g(224);
let bg = TuiTheme::g(64);
(move||Bsp::s(help_tag("midi ", "O", "uts"), state.midi_outs.get(0).map(|out|Bsp::s(
Fill::x(Tui::bold(true, Tui::fg_bg(fg, bg, Align::w(out.name.clone())))),
out.connect.get(0).map(|connect|Fill::x(Align::w(Tui::bold(false,
Tui::fg_bg(fg, bg, connect.info()))))),
))).boxed()).into()
}
fn output_cells <'a> (state: &'a App) -> BoxThunk<'a, TuiOut> {
(move||Align::x(Map::new(||state.tracks_with_sizes(), move|(_, track, x1, x2), i| {
let w = (x2 - x1) as u16;
let color: ItemPalette = track.color().dark.into();
map_east(x1 as u16, w, Fixed::x(w, cell(color, Bsp::n(
mute_solo(color.base.rgb, false, false),
phat_hi(color.dark.rgb, color.darker.rgb)
))))
})).boxed()).into()
}
fn rec_mon (bg: Color, rec: bool, mon: bool) -> impl Content<TuiOut> {
row!(
Tui::fg_bg(if rec { Color::Red } else { bg }, bg, ""),
Tui::fg_bg(if rec { Color::White } else { Color::Rgb(0,0,0) }, bg, "REC"),
Tui::fg_bg(if rec { Color::White } else { bg }, bg, ""),
Tui::fg_bg(if mon { Color::White } else { Color::Rgb(0,0,0) }, bg, "MON"),
Tui::fg_bg(if mon { Color::White } else { bg }, bg, ""),
)
}
fn mute_solo (bg: Color, mute: bool, solo: bool) -> impl Content<TuiOut> {
row!(
Tui::fg_bg(if mute { Color::White } else { Color::Rgb(0,0,0) }, bg, "MUTE"),
Tui::fg_bg(if mute { Color::White } else { bg }, bg, ""),
Tui::fg_bg(if solo { Color::White } else { Color::Rgb(0,0,0) }, bg, "SOLO"),
)
}
fn cell <T: Content<TuiOut>> (color: ItemPalette, field: T) -> impl Content<TuiOut> {
Tui::fg_bg(color.lightest.rgb, color.base.rgb, Fixed::y(1, field))
}

View file

@ -520,15 +520,15 @@ impl Arranger {
}
}
/// A phat line
fn phat_lo (fg: Color, bg: Color) -> impl Content<TuiOut> {
pub fn phat_lo (fg: Color, bg: Color) -> impl Content<TuiOut> {
Fixed::y(1, Tui::fg_bg(fg, bg, RepeatH(&"")))
}
/// A phat line
fn phat_hi (fg: Color, bg: Color) -> impl Content<TuiOut> {
pub fn phat_hi (fg: Color, bg: Color) -> impl Content<TuiOut> {
Fixed::y(1, Tui::fg_bg(fg, bg, RepeatH(&"")))
}
/// A cell that is 3-row on its own, but stacks, giving (N+1)*2 rows per N cells.
fn phat_cell <T: Content<TuiOut>> (
pub fn phat_cell <T: Content<TuiOut>> (
color: ItemPalette, last: ItemPalette, field: T
) -> impl Content<TuiOut> {
Bsp::s(phat_lo(color.base.rgb, last.base.rgb),
@ -537,7 +537,7 @@ fn phat_cell <T: Content<TuiOut>> (
)
)
}
fn phat_cell_3 <T: Content<TuiOut>> (
pub fn phat_cell_3 <T: Content<TuiOut>> (
field: T, top: Color, middle: Color, bottom: Color
) -> impl Content<TuiOut> {
Bsp::s(phat_lo(middle, top),
@ -546,7 +546,7 @@ fn phat_cell_3 <T: Content<TuiOut>> (
)
)
}
fn phat_sel_3 <T: Content<TuiOut>> (
pub fn phat_sel_3 <T: Content<TuiOut>> (
selected: bool, field_1: T, field_2: T, top: Option<Color>, middle: Color, bottom: Color
) -> impl Content<TuiOut> {
let border = Style::default().fg(Color::Rgb(255,255,255)).bg(middle);