demacroify per_track_top

This commit is contained in:
🪞👃🪞 2025-01-25 19:48:05 +01:00
parent 1fb5dfbe11
commit 7a97b07c0a

View file

@ -194,19 +194,35 @@ macro_rules! per_track {
let content = Fixed::y(1, $content);
let styled = Tui::fg_bg($track.color.lightest.rgb, $track.color.base.rgb, content);
map_east(x1 as u16, width, Align::y(Fixed::x(width, styled))) }))).into() }} }
macro_rules! per_track_top {
($area:expr;|$self:ident,$track:ident,$index:ident|$content:expr) => {{
let tracks = ||$self.tracks_sizes($self.is_editing(), $self.editor_w())
.map_while(|(t, track, x1, x2)|if x2 >= $area {
None } else { Some((t, track, x1, x2)) });
(move||Fill::xy(Align::nw(Map::new(tracks, move|(_, $track, x1, x2), $index| {
let width = (x2 - x1) as u16;
let content = Fixed::y(1, $content);
let styled = Tui::fg_bg($track.color.lightest.rgb, $track.color.base.rgb, content);
map_east(x1 as u16, width, Fixed::x(width, Align::n(styled))) }))).boxed()).into() }} }
impl Tek {
fn view_row_top <'a> (
// SIZES //////////////////////////////////////////////////////////////////////////////////////
fn w (&self) -> u16 {
self.tracks_sizes(self.is_editing(), self.editor_w())
.last().map(|x|x.3 as u16) .unwrap_or(0)
}
fn w_sidebar (&self) -> u16 {
let w = (self.size.w() / 10);
let w = w.min(if w > 80 { 20 } else if w > 70 { 18 } else if w > 60 { 16 }
else if w > 50 { 14 } else if w > 40 { 12 } else { 10 });
//let w = if self.is_editing() { w / 2 } else { w };
w as u16
}
fn w_tracks (&self, editing: bool, bigger: usize) -> u16 {
self.tracks_sizes(editing, bigger).last().map(|(_, _, _, x)|x as u16).unwrap_or(0)
}
fn h_inputs (&self) -> u16 {
1 + self.inputs_sizes().last().map(|(_, _, _, _, y)|y as u16).unwrap_or(0)
}
fn h_outputs (&self) -> u16 {
1 + self.outputs_sizes().last().map(|(_, _, _, _, y)|y as u16).unwrap_or(0)
}
fn h_scenes (&self, editing: bool, height: usize, larger: usize) -> u16 {
self.scenes_sizes(editing, height, larger).last().map(|(_, _, _, y)|y as u16).unwrap_or(0)
}
/// COMPONENTS ////////////////////////////////////////////////////////////////////////////////
fn row_top <'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::a(
@ -214,17 +230,21 @@ impl Tek {
Fill::xy(Align::n(Fixed::xy(w, h, b)))
))
}
fn per_track_top <'a, T: Content<TuiOut> + 'a> (
&'a self, f: impl Fn(usize, &'a Track)->T + Send + Sync + 'a
) -> impl Content<TuiOut> + 'a {
let width = self.size.w();
let filter = move|(t, track, x1, x2)|if x2 >= width {None} else {Some((t, track, x1, x2))};
let tracks = move||self.tracks_sizes(self.is_editing(), self.editor_w()).map_while(filter);
Fill::xy(Align::nw(Map::new(tracks, move|(index, track, x1, x2), _|{
let width = (x2 - x1) as u16;
let content = Fixed::y(1, f(index, track));
let styled = Tui::fg_bg(track.color.lightest.rgb, track.color.base.rgb, content);
map_east(x1 as u16, width, Fixed::x(width, Align::n(styled))) })))
}
fn wrap (bg: Color, fg: Color, content: impl Content<TuiOut>) -> impl Content<TuiOut> {
Bsp::e(Tui::fg_bg(bg, Reset, ""), Bsp::w(Tui::fg_bg(bg, Reset, ""), Tui::fg_bg(fg, bg, content)))
}
fn view_header <'a> (
&'a self, key: &'a str, label: &str, count: usize, content: impl Content<TuiOut> + Send + Sync + 'a
) -> impl Content<TuiOut> + 'a {
Fill::xy(Align::nw(Bsp::s(
self.button(key, format!("{:10} ({})", label, count)),
content,
)))
}
fn view_io_header <'a, T: PortsSizes<'a>> (
&'a self,
key: &'a str,
@ -236,24 +256,30 @@ impl Tek {
) -> impl Content<TuiOut> + 'a {
self.view_header(key, label, count, Map::new(iter,
move|(index, name, connections, y, y2), _|map_south(y as u16, (y2-y) as u16, Bsp::s(
Fill::x(Tui::bold(true, Tui::fg_bg(fg, bg, Align::w(name)))),
Fill::x(Tui::bold(true, Tui::fg_bg(fg, bg, Align::w(Bsp::e(" 󰣲 ", name))))),
Map::new(||connections.iter(), move|connect, index|map_south(index as u16, 1,
Fill::x(Align::w(Tui::bold(false, Tui::fg_bg(fg, bg, connect.info()))))))))))
}
fn button <'a> (
&'a self, key: impl Content<TuiOut> + 'a, label: impl Content<TuiOut> + 'a
fn view_header <'a> (
&'a self, key: &'a str, label: &str, count: usize, content: impl Content<TuiOut> + Send + Sync + 'a
) -> impl Content<TuiOut> + 'a {
Fill::xy(Align::nw(Bsp::s(
self.button(key, format!("{:10} ({})", label, count)),
content,
)))
}
fn button <'a, K: Content<TuiOut> + 'a, L: Content<TuiOut> + 'a> (&'a self, key: K, label: L)
-> impl Content<TuiOut> + 'a
{
let compact = !self.is_editing();
Tui::bold(true, Bsp::e(
Margin::x(1, Tui::fg_bg(Tui::g(0), Tui::orange(), key)),
Tui::fg_bg(Tui::g(0), Tui::orange(), Bsp::e(key, Tui::fg(Tui::g(96), ""))),
When::new(compact, Margin::x(1, Tui::fg_bg(Tui::g(255), Tui::g(96), label))),
))
}
// TRACKS /////////////////////////////////////////////////////////////////////////////////////
fn w_tracks (&self, editing: bool, bigger: usize) -> u16 {
self.tracks_sizes(editing, bigger).last().map(|(_, _, _, x)|x as u16).unwrap_or(0)
}
const TRACK_SPACING: usize = 0;
fn tracks_sizes <'a> (&'a self, editing: bool, bigger: usize) -> impl TracksSizes<'a> {
let mut x = 0;
let active = match self.selected() {
@ -264,7 +290,7 @@ impl Tek {
self.tracks().iter().enumerate().map(move |(index, track)|{
let width = if Some(index) == active { bigger } else { track.width.max(8) };
let data = (index, track, x, x + width);
x += width + Self::WIDTH_OFFSET;
x += width + Self::TRACK_SPACING;
data
})
}
@ -284,6 +310,12 @@ impl Tek {
});
self.view_row(self.w(), height, header, content)
}
fn view_track_add (&self) -> impl Content<TuiOut> + use<'_> {
let data = (self.selected.track().unwrap_or(0), self.tracks().len());
self.fmtd.write().unwrap().trks.update(Some(data),
rewrite!(buf, "({}/{})", data.0, data.1));
self.button(" T", Bsp::e("track ", self.fmtd.read().unwrap().trks.view.clone()))
}
// INPUTS /////////////////////////////////////////////////////////////////////////////////////
fn inputs_sizes (&self) -> impl PortsSizes<'_> {
@ -295,14 +327,11 @@ impl Tek {
data
})
}
fn h_inputs (&self) -> u16 {
1 + self.inputs_sizes().last().map(|(_, _, _, _, y)|y as u16).unwrap_or(0)
}
fn view_inputs (&self) -> impl Content<TuiOut> + use<'_> {
let fg = Tui::g(224);
let bg = Tui::g(64);
let header = self.view_io_header(" I ", " midi ins", self.midi_ins.len(), fg, bg, ||self.inputs_sizes());
let cells: ThunkBox<_> = per_track_top!(self.size.w();|self, track, t|{
let header = self.view_io_header(" I", "midi ins", self.midi_ins.len(), fg, bg, ||self.inputs_sizes());
let cells = self.per_track_top(move|t, track|{
let rec = track.player.recording;
let mon = track.player.monitoring;
let bg = if self.selected().track() == Some(t+1) { track.color.light.rgb } else { track.color.base.rgb };
@ -317,17 +346,13 @@ impl Tek {
Self::wrap(bg, fg, Bsp::e(
Tui::fg_bg(if rec { White } else { track.color.darkest.rgb }, bg, "R▞▞▞▞"),
Tui::fg_bg(if mon { White } else { track.color.darkest.rgb }, bg, "M▞▞▞▞"))))))))});
Bsp::<_, Push<u16, ThunkBox<_>>>::s(
Tui::bg(Black, self.view_row_top(self.w(), self.h_inputs(), header, Tui::bg(Red, cells))),
Push::xy(self.w_sidebar(), 1, per_track_top!(self.size.w();|self, track, t|"kyp"))
Bsp::s(
Tui::bg(Black, self.row_top(self.w(), self.h_inputs(), header, Tui::bg(Red, cells))),
Tui::bg(Black, self.row_top(self.w(), self.h_inputs(), "Into:", self.per_track_top(|_, _|" --- ")))
)
}
// OUTPUTS ////////////////////////////////////////////////////////////////////////////////////
fn h_outputs (&self) -> u16 {
1 + self.outputs_sizes().last().map(|(_, _, _, _, y)|y as u16).unwrap_or(0)
}
fn outputs_sizes (&self) -> impl PortsSizes<'_> {
let mut y = 0;
self.midi_outs.iter().enumerate().map(move|(i, output)|{
@ -340,10 +365,10 @@ impl Tek {
fn view_outputs (&self) -> impl Content<TuiOut> + use<'_> {
let fg = Tui::g(224);
let bg = Tui::g(64);
let header = self.view_io_header(" O ", " midi outs", self.midi_outs.len(), fg, bg, ||self.outputs_sizes());
let mute = false;
let solo = false;
let cells: ThunkBox<_> = per_track_top!(self.size.w();|self, track, t|{
let header = self.view_io_header(" O", "midi outs", self.midi_outs.len(), fg, bg, ||self.outputs_sizes());
let cells = self.per_track_top(move |t, track|{
let mute = false;
let solo = false;
let bg = if self.selected().track() == Some(t+1) { track.color.light.rgb } else { track.color.base.rgb };
let bg2 = if t > 0 { self.tracks()[t - 1].color.base.rgb } else { Reset };
Bsp::s(
@ -357,15 +382,10 @@ impl Tek {
Tui::fg_bg(if mute { White } else { track.color.darkest.rgb }, bg, "P▞▞▞▞"),
Tui::fg_bg(if solo { White } else { track.color.darkest.rgb }, bg, "S▞▞▞▞")))))))});
Tui::bg(Black, self.view_row_top(self.w(), self.h_outputs(),
Tui::bg(Yellow, header),
Tui::bg(Blue, cells)))
Tui::bg(Black, self.row_top(self.w(), self.h_outputs(), header, cells))
}
// SCENES /////////////////////////////////////////////////////////////////////////////////////
fn h_scenes (&self, editing: bool, height: usize, larger: usize) -> u16 {
self.scenes_sizes(editing, height, larger).last().map(|(_, _, _, y)|y as u16).unwrap_or(0)
}
fn scenes_sizes (&self, editing: bool, height: usize, larger: usize) -> impl ScenesSizes<'_> {
let mut y = 0;
let (selected_track, selected_scene) = match self.selected() {
@ -466,43 +486,14 @@ impl Tek {
let colors = colors(color, prev, selected, neighbor, is_last);
Phat { width: 0, height: 0, selected, content, colors, }
}
fn w (&self) -> u16 {
self.tracks_sizes(self.is_editing(), self.editor_w())
.last()
.map(|x|x.3 as u16)
.unwrap_or(0)
}
fn w_sidebar (&self) -> u16 {
let w = (self.size.w() / 10);
let w = w.min(if w > 80 { 20 } else if w > 70 { 18 } else if w > 60 { 16 }
else if w > 50 { 14 } else if w > 40 { 12 } else { 10 });
//let w = if self.is_editing() { w / 2 } else { w };
w as u16
}
fn view_track_add (&self) -> impl Content<TuiOut> + use<'_> {
let data = (self.selected.track().unwrap_or(0), self.tracks().len());
self.fmtd.write().unwrap().trks.update(Some(data),
rewrite!(buf, "({}/{})", data.0, data.1));
button(" T ", Bsp::e(" track ",
self.fmtd.read().unwrap().trks.view.clone()))
}
fn view_scene_add (&self) -> impl Content<TuiOut> + use<'_> {
let data = (self.selected().scene().unwrap_or(0), self.scenes().len());
self.fmtd.write().unwrap().scns.update(Some(data),
rewrite!(buf, "({}/{})", data.0, data.1));
button(" C-a ", Bsp::e(" add scene ",
self.button(" C-a ", Bsp::e(" add scene ",
self.fmtd.read().unwrap().scns.view.clone()))
}
}
fn button <'a> (
key: impl Content<TuiOut> + 'a,
label: impl Content<TuiOut> + 'a
) -> impl Content<TuiOut> + 'a {
Tui::bold(true, Bsp::e(
Tui::fg_bg(Tui::g(0), Tui::orange(), key),
Tui::fg_bg(Tui::g(255), Tui::g(96), label),
))
}
fn colors (
this: &ItemPalette,
prev: Option<ItemPalette>,