From 7a97b07c0a6e6bcae221bf60b5acb38f8893aaf6 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 25 Jan 2025 19:48:05 +0100 Subject: [PATCH] demacroify per_track_top --- tek/src/view.rs | 149 +++++++++++++++++++++++------------------------- 1 file changed, 70 insertions(+), 79 deletions(-) diff --git a/tek/src/view.rs b/tek/src/view.rs index b4643592..b7e79ebe 100644 --- a/tek/src/view.rs +++ b/tek/src/view.rs @@ -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 + 'a, b: impl Content + 'a ) -> impl Content + '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 + 'a> ( + &'a self, f: impl Fn(usize, &'a Track)->T + Send + Sync + 'a + ) -> impl Content + '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) -> impl Content { 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 + Send + Sync + 'a - ) -> impl Content + '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 + '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 + 'a, label: impl Content + 'a + fn view_header <'a> ( + &'a self, key: &'a str, label: &str, count: usize, content: impl Content + Send + Sync + 'a ) -> impl Content + 'a { + Fill::xy(Align::nw(Bsp::s( + self.button(key, format!("{:10} ({})", label, count)), + content, + ))) + } + fn button <'a, K: Content + 'a, L: Content + 'a> (&'a self, key: K, label: L) + -> impl Content + '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 + 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 + 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>>::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 + 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 + 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 + 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 + 'a, - label: impl Content + 'a -) -> impl Content + '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,