use crate::*; impl<'a> ArrangerView<'a> { /// Render input matrix. pub(crate) fn inputs (&'a self) -> impl Content + 'a { inputs_layout( input_intos( self.width_mid, self.width_side, self.tracks_with_sizes(), ), input_routes( self.width_mid, self.width_side, self.tracks_with_sizes(), self.inputs_height, self.inputs_with_sizes(), ), input_ports( self.width_mid, self.width_side, self.tracks_with_sizes(), self.inputs_count, self.track_selected, self.is_editing ) ) } /// Render output matrix. pub(crate) fn outputs (&'a self) -> impl Content + 'a { outputs_layout( output_nexts( self.width_mid, self.width_side, self.tracks_sizes ), output_froms( self.width_mid, self.width_side, self.tracks_sizes ), output_conns( self.width_mid, self.width_side, self.tracks_sizes, self.outputs_height, self.outputs_sizes ), output_ports( self.width_mid, self.width_side, self.tracks_sizes, self.outputs_count, self.track_selected, self.is_editing ) ) } } fn inputs_layout <'a> ( intos: impl Content, routes: impl Content, ports: impl Content, ) -> impl Content + 'a { Bsp::s(Bsp::s(routes, ports), intos) } fn input_intos <'a> ( w_mid: u16, w_side: u16, tracks: impl TracksSizes<'a>, ) -> impl Content + use<'a> { 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_routes <'a> ( w_mid: u16, w_side: u16, tracks: impl TracksSizes<'a>, height: u16, inputs: impl PortsSizes<'a> ) -> impl Content { 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 input_ports <'a> ( w_mid: u16, w_side: u16, tracks: impl TracksSizes<'a>, port_count: usize, selected_track: Option, editing: bool, ) -> impl Content + 'a { 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 }; let mon = if mon { White } else { track.color.darkest.rgb }; let bg = 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(bg, Tui::g(224), Tui::bold(true, Fill::x(Bsp::e( Tui::fg_bg(rec, bg, "Rec "), Tui::fg_bg(mon, bg, "Mon "), )))) })) } fn outputs_layout <'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 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 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 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: PortsSizes<'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 output_ports <'a, T, U> ( w_mid: u16, w_side: u16, tracks_sizes: U, port_count: usize, selected_track: Option, editing: bool, ) -> impl Content + use<'a, T, U> where T: TracksSizes<'a>, U: Fn()->T + Send + Sync + 'a { 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|i, t|{ let mute = false; let solo = false; let mute = if mute { White } else { t.color.darkest.rgb }; let solo = if solo { White } else { t.color.darkest.rgb }; let bg_1 = if selected_track == Some(i) { t.color.light.rgb } else { t.color.base.rgb }; let bg_2 = if i > 0 { t.color.base.rgb } else { Reset }; let mute = Tui::fg_bg(mute, bg_1, "Play "); let solo = Tui::fg_bg(solo, bg_1, "Solo "); wrap(bg_1, Tui::g(224), Tui::bold(true, Fill::x(Bsp::e(mute, solo)))) })) } #[cfg(test)] #[test] fn test_inputs () { let mut output = TuiOut::default(); output.area[2] = 9; output.area[3] = 9; Content::render(&inputs(), &mut output); } #[cfg(test)] #[test] fn test_outputs () { let mut output = TuiOut::default(); output.area[2] = 9; output.area[3] = 9; Content::render(&outputs(), &mut output); }