diff --git a/app/src/lib.rs b/app/src/lib.rs index e9dfd04c..4370703c 100644 --- a/app/src/lib.rs +++ b/app/src/lib.rs @@ -6,12 +6,13 @@ #![feature(impl_trait_in_assoc_type)] #![feature(type_alias_impl_trait)] #![feature(trait_alias)] -mod cli; pub use self::cli::*; -mod audio; pub use self::audio::*; -mod device; pub use self::device::*; -mod keys; pub use self::keys::*; -mod model; pub use self::model::*; -mod view; pub use self::view::*; +#![feature(type_changing_struct_update)] +mod cli; pub use self::cli::*; +mod audio; pub use self::audio::*; +mod device; pub use self::device::*; +mod keys; pub use self::keys::*; +mod model; pub use self::model::*; +mod view; pub use self::view::*; /// Standard result type. pub type Usually = std::result::Result>; /// Standard optional result type. diff --git a/app/src/view.rs b/app/src/view.rs index f9ac3209..70e6ee73 100644 --- a/app/src/view.rs +++ b/app/src/view.rs @@ -36,38 +36,6 @@ provide_num!(u16: |self: Tek| { ":y-outs" => (self.size.h() as u16).saturating_sub(self.h_outputs() + 1), ":y-samples" => if self.is_editing() { 1 } else { 0 }, }); -pub(crate) fn row <'a> ( - w: u16, - h: u16, - s: u16, - a: impl Content + 'a, - b: impl Content + 'a, - c: impl Content + 'a, -) -> impl Content + 'a { - Fixed::y(h, Bsp::a( - Fill::xy(Align::c(Fixed::x(w, Align::x(b)))), - Bsp::a( - Fill::xy(Align::w(Fixed::x(s, a))), - Fill::xy(Align::e(Fixed::x(s, c))), - ), - )) -} -pub(crate) fn row_top <'a> ( - w: u16, - h: u16, - s: u16, - a: impl Content + 'a, - b: impl Content + 'a, - c: impl Content + 'a, -) -> impl Content + 'a { - Fixed::y(h, Bsp::a( - Fill::x(Align::n(Fixed::x(w, Align::x(Tui::bg(Reset, b))))), - Bsp::a( - Fill::x(Align::nw(Fixed::x(s, Tui::bg(Reset, a)))), - Fill::x(Align::ne(Fixed::x(s, Tui::bg(Reset, c)))), - ), - )) -} pub(crate) fn wrap ( bg: Color, fg: Color, diff --git a/app/src/view/view_arranger.rs b/app/src/view/view_arranger.rs index ee6ea5eb..2364547c 100644 --- a/app/src/view/view_arranger.rs +++ b/app/src/view/view_arranger.rs @@ -1,65 +1,67 @@ use crate::*; + +/// A three-column row. +struct Tryptich { + pub top: bool, + pub h: u16, + pub left: (u16, A), + pub middle: (u16, B), + pub right: (u16, C), +} +impl Tryptich<(), (), ()> { + fn center (h: u16) -> Self { + Self { h, top: false, left: (0, ()), middle: (0, ()), right: (0, ()) } + } + fn top (h: u16) -> Self { + Self { h, top: true, left: (0, ()), middle: (0, ()), right: (0, ()) } + } +} +impl Tryptich { + fn left (self, w: u16, content: D) -> Tryptich { + Tryptich { left: (w, content), ..self } + } + fn middle (self, w: u16, content: D) -> Tryptich { + Tryptich { middle: (w, content), ..self } + } + fn right (self, w: u16, content: D) -> Tryptich { + Tryptich { right: (w, content), ..self } + } +} + +impl Content for Tryptich +where A: Content, B: Content, C: Content { + fn content (&self) -> impl Render { + let Self { top, h, left: (w_a, ref a), middle: (w_b, ref b), right: (w_c, ref c) } = *self; + if top { + Fixed::y(h, Bsp::a( + Fill::x(Align::n(Fixed::x(w_b, Align::x(Tui::bg(Reset, b))))), + Bsp::a( + Fill::x(Align::nw(Fixed::x(w_a, Tui::bg(Reset, a)))), + Fill::x(Align::ne(Fixed::x(w_c, Tui::bg(Reset, c)))), + ), + )) + } else { + Fixed::y(h, Bsp::a( + Fill::xy(Align::c(Fixed::x(w_b, Align::x(Tui::bg(Reset, b))))), + Bsp::a( + Fill::xy(Align::w(Fixed::x(w_a, Tui::bg(Reset, a)))), + Fill::xy(Align::e(Fixed::x(w_c, Tui::bg(Reset, c)))), + ), + )) + } + } +} + impl Tek { - - // FIXME: The memoized arranger is too complex. - // Just render a slice of the arranger for now, - // starting from tracks[scroll_offset] and ending - // at the last track that fits fully. - - /// Blit the currently visible section of the arranger view buffer to the output. - /// - /// If the arranger is larger than the available display area, - /// the scrollbars determine the portion that will be shown. - /// - /// This function is called on every frame, but is relatively cheap - /// as the rendering logic of [redraw_arranger] is only invoked on - /// changes to the content. - pub fn view_arranger_todo (&self) -> impl Content + use<'_> { - Fill::xy(ThunkRender::new(move|to: &mut TuiOut|{ - let [x0, y0, w, h] = to.area().xywh(); - let source = self.arranger.read().unwrap(); - for (source_x, target_x) in (x0..x0+w).enumerate() { - for (source_y, target_y) in (y0..y0+h).enumerate() { - let target_pos = Position::from((target_x, target_y)); - if let Some(target) = to.buffer.cell_mut(target_pos) { - //target.set_bg(Color::Rgb(128,0,0)); - let source_pos = Position::from((source_x as u16, source_y as u16)); - if let Some(source) = source.cell(source_pos) { - *target = source.clone(); - //target.set_bg(Color::Rgb(0,128,0)); - } - } - } - } - })) - } - - /// Draw the full arranger to the arranger view buffer. - /// - /// This should happen on changes to the arrangement contents, - /// i.e. not on scroll. Scrolling just determines which part - /// of the arranger buffer to blit in [view_arranger]. - pub fn redraw_arranger (&self) { - return; - //let width = self.w_tracks(); - //let height = self.h_scenes() + self.h_inputs() + self.h_outputs(); - //let buffer = Buffer::empty(ratatui::prelude::Rect { x: 0, y: 0, width, height }); - //let mut output = TuiOut { buffer, area: [0, 0, width, height] }; - //let layout = Bsp::s(self.view_inputs(), - //Bsp::s(self.view_tracks(), - //Bsp::n(self.view_outputs(), - //self.view_scenes()))); - //Content::render(&layout, &mut output); - //*self.arranger.write().unwrap() = output.buffer; - } + pub fn redraw_arranger (&self) { /*FIXME: remove*/ } pub fn view_arranger (&self) -> impl Content + use<'_> { - let ins = self.view_inputs(); - let trs = self.view_tracks(); - let out = self.view_outputs(); - let scn = self.view_scenes(); - Bsp::s(ins, Bsp::s(trs, Bsp::n(out, scn))) + let inputs = self.view_inputs(); + let tracks = self.view_tracks(); + let scenes = self.view_scenes(); + let outputs = self.view_outputs(); + Bsp::s(inputs, Bsp::s(tracks, Bsp::n(outputs, scenes))) } pub fn view_tracks (&self) -> impl Content + use<'_> { @@ -68,9 +70,13 @@ impl Tek { let data = (self.selected.track().unwrap_or(0), self.tracks().len()); let editing = self.is_editing(); self.fmtd.write().unwrap().trks.update(Some(data), rewrite!(buf, "{}/{}", data.0, data.1)); - row(w, 1, s, button_3("t", "track", self.fmtd.read().unwrap().trks.view.clone(), editing), - self.per_track(|t, track|track_header(t, track, self.selected().track() == Some(t))), - button_2("T", "add track", editing)) + Tryptich::center(1) + .left(s, + button_3("t", "track", self.fmtd.read().unwrap().trks.view.clone(), editing)) + .middle(w, + self.per_track(|t, track|track_header(t, track, self.selected().track() == Some(t)))) + .right(s, + button_2("T", "add track", editing)) } pub fn view_scenes (&self) -> impl Content + use<'_> { @@ -82,20 +88,20 @@ impl Tek { let h_area = self.h_tracks_area(); let st = self.selected().track(); let ss = self.selected().scene(); - let track_scroll = { + let track_scroll = { let offset = self.track_scroll; let length = self.w_tracks_area() as usize; let total = self.w_tracks() as usize; Fill::x(Fixed::y(1, ScrollbarH { offset, length, total })) }; - let scene_scroll = { + let scene_scroll = { let offset = self.scene_scroll; let length = self.h_tracks_area() as usize; let total = self.h_scenes() as usize; Fill::y(Fixed::x(1, ScrollbarV { offset, length, total })) }; - Tui::bg(Reset, Bsp::s(track_scroll, Bsp::e(scene_scroll, Fixed::y(h_area, row(w, h, s, - Map::new( + let row = Tryptich::center(h) + .left(s, Map::new( move||self.scenes_with_colors(editing, h_area), move|(s, scene, y1, y2, prev): SceneWithColor, _|view_scene_name( w_full, @@ -107,15 +113,14 @@ impl Tek { s == self.scenes.len().saturating_sub(1), self.selected().scene(), ) - ), - self.per_track(move|t, track|Map::new( + )) + .middle(w, self.per_track(move|t, track|Map::new( move||self.scenes_with_track_colors(editing, h_area, t), move|(s, scene, y1, y2, prev): SceneWithColor, _|self.view_scene_clip( w, (1 + y2 - y1) as u16, y1 as u16, scene, prev, s, t, editing, st == Some(t), ss) - )), - () - ))))) + ))); + Tui::bg(Reset, Bsp::s(track_scroll, Bsp::e(scene_scroll, Fixed::y(h_area, row)))) } fn view_scene_clip ( @@ -160,76 +165,59 @@ impl Tek { } pub fn view_outputs (&self) -> impl Content + use<'_> { - let fg = Tui::g(224); - let bg = Tui::g(32); - let len = self.midi_outs.len(); - let ed = self.is_editing(); - let ws = self.w_tracks_area(); - let s = self.w_sidebar() as u16; - let ts = move||self.tracks_sizes_scrolled(); - let sel = self.selected().track(); - let ho = self.h_outputs() - 1; - let os = ||self.outputs_sizes(); - let pts = io_ports(fg, bg, os); - let tr = self.tracks.as_ref(); - view_outputs(ws, s, ho, len, ed, sel, tr, ts, os, pts) + let height = self.h_outputs().saturating_sub(1); + let w_mid = self.w_tracks_area(); + let w_side = self.w_sidebar() as u16; + let tracks = ||self.tracks_sizes_scrolled(); + view_outputs( + view_output_nexts(w_mid, w_side, tracks), + view_output_froms(w_mid, w_side, tracks), + view_output_conns(w_mid, w_side, tracks, height, ||self.outputs_sizes()), + view_output_ports(w_mid, w_side, tracks, + self.midi_outs.len(), self.selected().track(), self.is_editing())) } pub fn view_inputs (&self) -> impl Content + use<'_> { - let fg = Tui::g(224); - let bg = Tui::g(32); - let ws = self.w_sidebar() as u16; - let w = (self.size.w() as u16).saturating_sub(2 * ws); - let wt = self.w_tracks_area(); - let ts = move||self.tracks_sizes_scrolled(); - let is = ||self.inputs_sizes(); - let len = self.midi_ins.len(); - let sel = self.selected().track(); - let tr = self.tracks().as_ref(); - let ed = self.is_editing(); - let hi = self.h_inputs() - 1; - let pts = io_ports(fg, bg, is); - let to_conns = move|_, &Track { color, .. }|io_conns(color.dark.rgb, color.darker.rgb, is); - view_inputs(w, ws, wt, ts, - row_top(w, hi, ws, pts, per_track_top(wt, ts, to_conns), ()), - input_ports(w, ws, len, wt, ts, sel, tr, ed)) + let height = self.h_inputs().saturating_sub(1); + let w_mid = self.w_tracks_area(); + let w_side = self.w_sidebar() as u16; + let tracks = ||self.tracks_sizes_scrolled(); + view_inputs( + view_input_intos(w_mid, w_side, tracks), + view_input_routes(w_mid, w_side, tracks, height, ||self.inputs_sizes()), + view_input_ports(w_mid, w_side, tracks, + self.midi_ins.len(), self.selected().track(), self.is_editing())) } /// Render something centered for each track. fn per_track <'a, T: Content + 'a> ( &'a self, f: impl Fn(usize, &'a Track)->T + Send + Sync + 'a ) -> impl Content + 'a { - self.per_track_top( - move|index, track|Fill::y(Align::y(f(index, track))) - ) + self.per_track_top(move|index, track|Fill::y(Align::y(f(index, track)))) } /// Render something top-aligned for each track. fn per_track_top <'a, T: Content + 'a> ( &'a self, callback: impl Fn(usize, &'a Track)->T + Send + Sync + 'a ) -> impl Content + 'a { - per_track_top( - self.w_tracks_area(), - move||self.tracks_sizes_scrolled(), - callback - ) + per_track_top(self.w_tracks_area(), move||self.tracks_sizes_scrolled(), callback) } } fn view_scene_name ( - width: u16, - height: u16, - offset: u16, - index: usize, - scene: &Scene, - prev: Option, - last: bool, - selected: Option, + width: u16, + height: u16, + offset: u16, + index: usize, + scene: &Scene, + prev: Option, + last: bool, + select: Option, ) -> impl Content { Fill::x(map_south(offset, height, Fixed::y(height, scene_cell( last, - selected, + select, true, index, &scene.color, @@ -240,110 +228,50 @@ fn view_scene_name ( )))) } -fn view_inputs <'a, T, U, V, W> ( - ws: u16, - s: u16, - wt: u16, - ts: U, - routes: V, - ports: W, -) -> impl Content + use<'a, T, U, V, W> where - T: TracksSizes<'a>, - U: Fn()->T + Send + Sync + 'a, - V: Content, - W: Content, +fn view_inputs <'a, T, U, V> ( + intos: T, routes: U, ports: V, +) -> impl Content + use<'a, T, U, V> where + T: Content + 'a, + U: Content + 'a, + V: Content + 'a, { - let headers = Bsp::s(Align::e("Input:"), Align::e("Into:")); - let sep = |_, _|Tui::bg(Reset, Align::c(Bsp::s(OctaveVertical::default(), " ------ "))); - let separators = per_track_top(wt, ts, sep); - Bsp::s(Bsp::s(routes, ports), row_top(ws, 2, s, headers, separators, ())) + Bsp::s(Bsp::s(routes, ports), intos) } -fn view_outputs <'a, T, U, V, W, X> ( - ws: u16, - s: u16, - ho: u16, - len: usize, - ed: bool, - sel: Option, - tr: &'a [Track], - ts: U, - os: W, - pts: X, -) -> impl Content + use<'a, T, U, V, W, X> where - T: TracksSizes<'a>, - U: Fn()->T + Send + Sync + 'a, - V: PortsSizes<'a>, - W: Fn()->V + Send + Sync + 'a, - X: Content + 'a -{ - let fg = Tui::g(224); - let conns = row_top(ws, ho, s, pts, per_track_top( - ws, ts, |t, track|io_conns(track.color.dark.rgb, track.color.darker.rgb, os) - ), ()); - let nexts = row_top(ws, 2, s, Align::ne("Next:"), per_track_top(ws, ts, |t, track|Either( - track.player.next_clip.is_some(), - Thunk::new(||Tui::bg(Reset, format!("{:?}", - track.player.next_clip.as_ref() - .map(|(moment, clip)|clip.as_ref() - .map(|clip|clip.read().unwrap().name.clone())) - .flatten().as_ref()))), - Thunk::new(||Tui::bg(Reset, " ------ ")) - )), ()); - let bar = row_top( - ws, - 2, - s, - Align::ne("From:"), - per_track_top( - ws, - ts, - |_, _|Tui::bg(Reset, Align::c(Bsp::s(" ------ ", OctaveVertical::default(),))) - ), - () - ); - let baz = row_top( - ws, - 1, - s, - button_3("o", "midi outs", format!("{}", len), ed), - per_track_top( - ws, - ts, - move|t, track|{ - let mute = false; - let solo = false; - let mute = if mute { White } else { track.color.darkest.rgb }; - let solo = if solo { White } else { track.color.darkest.rgb }; - let bg1 = if sel == Some(t) { track.color.light.rgb } else { track.color.base.rgb }; - let bg2 = if t > 0 { tr[t].color.base.rgb } else { Reset }; - wrap(bg1, fg, Tui::bold(true, Fill::x(Bsp::e( - Tui::fg_bg(mute, bg1, "Play "), - Tui::fg_bg(solo, bg1, "Solo "))))) - } - ), - button_2("O", "add midi out", ed) - ); - Align::n(Bsp::s(Bsp::s(nexts, bar), Bsp::s(baz, conns))) +fn view_input_intos <'a, T: TracksSizes<'a>, U: Fn()->T + Send + Sync + 'a> ( + w_mid: u16, w_side: u16, tracks: U, +) -> impl Content + use<'a, T, U> { + Tryptich::top(2) + .left(w_side, Bsp::s(Align::e("Input:"), Align::e("Into:"))) + .middle(w_mid, per_track_top(w_mid, tracks, |_, _|Tui::bg(Reset, + Align::c(Bsp::s(OctaveVertical::default(), " ------ "))))) } -fn input_ports <'a, T: TracksSizes<'a>, U: Fn()->T + Send + Sync + 'a> ( - w: u16, - s: u16, - midi_ins: usize, - w_tracks_area: u16, - tracks_sizes: U, +fn view_input_routes <'a, T, U, V, W> ( + w_mid: u16, w_side: u16, tracks: U, height: u16, inputs: W +) -> impl Content + use<'a, T, U> where + T: TracksSizes<'a>, U: Fn()->T + Send + Sync + 'a, + V: PortsSizes<'a>, W: Fn()->T + Send + Sync + 'a, +{ + Tryptich::top(height) + .left(w_side, io_ports(Tui::g(224), Tui::g(32), inputs)) + .middle(w_mid, per_track_top(w_mid, tracks, move|_, &Track { color, .. }|{ + io_conns(color.dark.rgb, color.darker.rgb, inputs) + })) +} + +fn view_input_ports <'a, T: TracksSizes<'a>, U: Fn()->T + Send + Sync + 'a> ( + w_mid: u16, + w_side: u16, + tracks: U, + port_count: usize, selected_track: Option, - tracks: &'a [Track], editing: bool, ) -> impl Content + use<'a, T, U> { - let fg = Tui::g(224); - let btn_ins = button_3("i", "midi ins", format!("{}", midi_ins), editing); - let btn_add = button_2("I", "add midi in", editing); - let inputs = per_track_top( - w_tracks_area, - tracks_sizes, - move|t, track|{ + Tryptich::top(1) + .left(w_side, button_3("i", "midi ins", format!("{port_count}"), editing)) + .right(w_side, button_2("I", "add midi in", editing)) + .middle(w_mid, per_track_top(w_mid, tracks, move|t, track|{ let rec = track.player.recording; let mon = track.player.monitoring; let rec = if rec { White } else { track.color.darkest.rgb }; @@ -353,14 +281,87 @@ fn input_ports <'a, T: TracksSizes<'a>, U: Fn()->T + Send + Sync + 'a> ( } else { track.color.base.rgb }; - //let bg2 = if t > 0 { tracks[t - 1].color.base.rgb } else { Reset }; - wrap(bg, fg, Tui::bold(true, Fill::x(Bsp::e( + //let bg2 = if t > 0 { track.color.base.rgb } else { Reset }; + wrap(bg, Tui::g(224), Tui::bold(true, Fill::x(Bsp::e( Tui::fg_bg(rec, bg, "Rec "), - Tui::fg_bg(mon, bg, "Mon ")) - ))) - } - ); - row_top(w, 1, s, btn_ins, inputs, btn_add) + Tui::fg_bg(mon, bg, "Mon "), + )))) + })) +} + +fn view_outputs <'a, T, U, V, W> ( + nexts: T, froms: U, conns: V, outputs: W, +) -> impl Content + use<'a, T, U, V, W> where + T: Content + 'a, + U: Content + 'a, + V: Content + 'a, + W: Content + 'a, +{ + Align::n(Bsp::s(Bsp::s(nexts, froms), Bsp::s(outputs, conns))) +} + +fn view_output_nexts <'a, T: TracksSizes<'a>, U: Fn()->T + Send + Sync + 'a> ( + w_mid: u16, w_side: u16, tracks: U +) -> impl Content + use<'a, T, U> { + Tryptich::top(2) + .left(w_side, Align::ne("From:")) + .middle(w_mid, per_track_top(w_mid, tracks, |_, _|Tui::bg(Reset, + Align::c(Bsp::s(" ------ ", OctaveVertical::default()))))) +} + +fn view_output_froms <'a, T: TracksSizes<'a>, U: Fn()->T + Send + Sync + 'a> ( + w_mid: u16, w_side: u16, tracks: U +) -> impl Content + use<'a, T, U> { + Tryptich::top(2) + .left(w_side, Align::ne("Next:")) + .middle(w_mid, per_track_top(w_mid, tracks, |t, track|Either( + track.player.next_clip.is_some(), + Thunk::new(||Tui::bg(Reset, format!("{:?}", + track.player.next_clip.as_ref() + .map(|(moment, clip)|clip.as_ref() + .map(|clip|clip.read().unwrap().name.clone())) + .flatten().as_ref()))), + Thunk::new(||Tui::bg(Reset, " ------ "))))) +} + +fn view_output_conns <'a, T, U, V, W> ( + w_mid: u16, w_side: u16, tracks: U, height: u16, outputs: W +) -> impl Content + use<'a, T, U, V, W> where + T: TracksSizes<'a>, U: Fn()->T + Send + Sync + 'a, + V: PortsSizes<'a>, W: Fn()->T + Send + Sync + 'a, +{ + Tryptich::top(height) + .left(w_side, + io_ports(Tui::g(224), Tui::g(32), outputs)) + .middle(w_mid, + per_track_top(w_mid, tracks, |_, t|{ + io_conns(t.color.dark.rgb, t.color.darker.rgb, outputs) + })) +} + +fn view_output_ports <'a, T: TracksSizes<'a>, U: Fn()->T + Send + Sync + 'a> ( + w_mid: u16, + w_side: u16, + tracks_sizes: U, + port_count: usize, + selected_track: Option, + editing: bool, +) -> impl Content + use<'a, T, U> { + Tryptich::top(1) + .left(w_side, button_3("o", "midi outs", format!("{port_count}"), editing)) + .right(w_side, button_2("O", "add midi out", editing)) + .middle(w_mid, per_track_top(w_mid, tracks_sizes, move|t, track|{ + let mute = false; + let solo = false; + let mute = if mute { White } else { track.color.darkest.rgb }; + let solo = if solo { White } else { track.color.darkest.rgb }; + let bg1 = if selected_track == Some(t) { track.color.light.rgb } else { track.color.base.rgb }; + let bg2 = if t > 0 { track.color.base.rgb } else { Reset }; + wrap(bg1, Tui::g(224), Tui::bold(true, Fill::x(Bsp::e( + Tui::fg_bg(mute, bg1, "Play "), + Tui::fg_bg(solo, bg1, "Solo "), + )))) + })) } fn per_track_top <'a, T: Content + 'a, U: TracksSizes<'a>> ( @@ -379,15 +380,15 @@ fn per_track_top <'a, T: Content + 'a, U: TracksSizes<'a>> ( } fn scene_cell <'a> ( - is_last: bool, - selected_scene: Option, - same_track: bool, - scene: usize, - color: &ItemPalette, - prev: Option, - name: Option>, - icon: &'a str, - fg: Color, + is_last: bool, + selected: Option, + same_track: bool, + scene: usize, + color: &ItemPalette, + prev: Option, + name: Option>, + icon: &'a str, + fg: Color, ) -> impl Content + use<'a> { Phat { width: 0, @@ -396,26 +397,22 @@ fn scene_cell <'a> ( colors: Tek::colors( color, prev, - same_track && selected_scene == Some(scene), - same_track && scene > 0 && selected_scene == Some(scene - 1), + same_track && selected == Some(scene), + same_track && scene > 0 && selected == Some(scene - 1), is_last ) } } fn track_header <'a> (t: usize, track: &'a Track, active: bool) -> impl Content + use<'a> { - let name = &track.name; - let fg = track.color.lightest.rgb; - let bg = if active { track.color.light.rgb } else { track.color.base.rgb }; + let fg = track.color.lightest.rgb; + let bg = if active { track.color.light.rgb } else { track.color.base.rgb }; let bg2 = Reset;//if t > 0 { self.tracks()[t - 1].color.base.rgb } else { Reset }; - let bfg = if active { Rgb(255,255,255) } else { Rgb(0,0,0) }; - wrap(bg, fg, Tui::bold(true, Fill::x(Align::nw(name)))) + wrap(bg, fg, Tui::bold(true, Fill::x(Align::nw(&track.name)))) } fn io_ports <'a, T: PortsSizes<'a>> ( - fg: Color, - bg: Color, - iter: impl Fn()->T + Send + Sync + 'a + fg: Color, bg: Color, iter: impl Fn()->T + Send + Sync + 'a ) -> impl Content + 'a { Map::new(iter, move|(index, name, connections, y, y2), _|map_south(y as u16, (y2-y) as u16, Bsp::s( @@ -426,9 +423,7 @@ fn io_ports <'a, T: PortsSizes<'a>> ( } fn io_conns <'a, T: PortsSizes<'a>> ( - fg: Color, - bg: Color, - iter: impl Fn()->T + Send + Sync + 'a + fg: Color, bg: Color, iter: impl Fn()->T + Send + Sync + 'a ) -> impl Content + 'a { Map::new(iter, move|(index, name, connections, y, y2), _|map_south(y as u16, (y2-y) as u16, Bsp::s( diff --git a/sampler/src/sampler.rs b/sampler/src/sampler.rs index cba709e0..b90de3f5 100644 --- a/sampler/src/sampler.rs +++ b/sampler/src/sampler.rs @@ -547,10 +547,10 @@ impl AddSampleModal { return Ok(false) } } -pub fn read_sample_data (_: &str) -> Usually<(usize, Vec>)> { +fn read_sample_data (_: &str) -> Usually<(usize, Vec>)> { todo!(); } -pub fn scan (dir: &PathBuf) -> Usually<(Vec, Vec)> { +fn scan (dir: &PathBuf) -> Usually<(Vec, Vec)> { let (mut subdirs, mut files) = std::fs::read_dir(dir)? .fold((vec!["..".into()], vec![]), |(mut subdirs, mut files), entry|{ let entry = entry.expect("failed to read drectory entry"); @@ -566,7 +566,7 @@ pub fn scan (dir: &PathBuf) -> Usually<(Vec, Vec)> { files.sort(); Ok((subdirs, files)) } -pub fn draw_sample ( +fn draw_sample ( to: &mut TuiOut, x: u16, y: u16, note: Option<&u7>, sample: &Sample, focus: bool ) -> Usually { let style = if focus { Style::default().green() } else { Style::default() };