diff --git a/app/tek_deps.rs b/app/tek_deps.rs index 0741b40d..f497466f 100644 --- a/app/tek_deps.rs +++ b/app/tek_deps.rs @@ -1,6 +1,6 @@ pub(crate) use ::{ tek_device::*, - tek_device::tengri::{ + tengri::{ Usually, Perhaps, Has, MaybeHas, has, maybe_has, impl_debug, from, dsl::*, input::*, @@ -8,7 +8,9 @@ pub(crate) use ::{ tui::{ *, ratatui::{ - self, prelude::{Style, Stylize, Buffer, Modifier, buffer::Cell, Color::{self, *}} + self, + prelude::{Rect, Style, Stylize, Buffer, Modifier, buffer::Cell, Color::{self, *}}, + widgets::{Widget, canvas::{Canvas, Line}}, }, crossterm::{ self, @@ -31,6 +33,5 @@ pub(crate) use ::{ thread::JoinHandle }, xdg::BaseDirectories, - atomic_float::*, - tengri::tui::ratatui::{prelude::Rect, widgets::{Widget, canvas::{Canvas, Line}}}, + atomic_float::* }; diff --git a/deps/tengri b/deps/tengri index 41fa55fa..8c54510f 160000 --- a/deps/tengri +++ b/deps/tengri @@ -1 +1 @@ -Subproject commit 41fa55fa6ca15abd0a80fd50a30326b1fea6b5f1 +Subproject commit 8c54510f630e8a81b7d7bdca0a51a69cdb9dffcc diff --git a/device/scene.rs b/device/scene.rs index 3db432bd..271daa5d 100644 --- a/device/scene.rs +++ b/device/scene.rs @@ -118,7 +118,7 @@ pub trait ScenesView: }) } fn view_scenes_names (&self) -> impl Content { - Fixed::x(20, Thunk::new(|to: &mut TuiOut|for (index, scene, ..) in self.scenes_with_sizes() { + Fixed::X(20, Thunk::new(|to: &mut TuiOut|for (index, scene, ..) in self.scenes_with_sizes() { to.place(&self.view_scene_name(index, scene)); })) } @@ -182,7 +182,7 @@ impl Scene { match self.clips.get(index) { Some(Some(clip)) => Some(clip), _ => None } } } - //scene_scroll: Fill::Y(Fixed::x(1, ScrollbarV { + //scene_scroll: Fill::Y(Fixed::X(1, ScrollbarV { //offset: arrangement.scene_scroll, //length: h_scenes_area as usize, //total: h_scenes as usize, diff --git a/device/track.rs b/device/track.rs index 438b84a5..c583381c 100644 --- a/device/track.rs +++ b/device/track.rs @@ -1,6 +1,6 @@ use crate::*; -def_sizes_iter!(TracksSizes => Track); +def_sizes_iter!(TracksSizes => Track); impl> + Send + Sync> HasTracks for T {} @@ -36,33 +36,41 @@ pub trait HasTracks: Has> + Send + Sync { const TRACK_SPACING: usize = 0; } -pub trait HasTrackScroll: HasTracks { fn track_scroll (&self) -> usize; } -impl HasTrackScroll for Arrangement { fn track_scroll (&self) -> usize { self.track_scroll } } +pub trait HasTrackScroll: HasTracks { + fn track_scroll (&self) -> usize; +} + +impl HasTrackScroll for Arrangement { + fn track_scroll (&self) -> usize { + self.track_scroll + } +} + +pub trait HasTrack { + fn track (&self) -> Option<&Track>; + fn track_mut (&mut self) -> Option<&mut Track>; + #[cfg(feature = "port")] fn view_midi_ins_status <'a> (&'a self, theme: ItemTheme) -> impl Content + 'a { + self.track().map(move|track|view_ports_status(theme, "MIDI ins: ", &track.sequencer.midi_ins)) + } + #[cfg(feature = "port")] fn view_midi_outs_status (&self, theme: ItemTheme) -> impl Content + '_ { + self.track().map(move|track|view_ports_status(theme, "MIDI outs: ", &track.sequencer.midi_outs)) + } + #[cfg(feature = "port")] fn view_audio_ins_status (&self, theme: ItemTheme) -> impl Content { + self.track().map(move|track|view_ports_status(theme, "Audio ins: ", &track.audio_ins())) + } + #[cfg(feature = "port")] fn view_audio_outs_status (&self, theme: ItemTheme) -> impl Content { + self.track().map(move|track|view_ports_status(theme, "Audio outs:", &track.audio_outs())) + } +} + impl> HasTrack for T { - fn track (&self) -> Option<&Track> { self.get() } - fn track_mut (&mut self) -> Option<&mut Track> { self.get_mut() } + fn track (&self) -> Option<&Track> { + self.get() + } + fn track_mut (&mut self) -> Option<&mut Track> { + self.get_mut() + } } -impl Track { - fn _todo_opt_bool_stub_ (&self) -> Option { todo!() } - fn _todo_usize_stub_ (&self) -> usize { todo!() } - fn _todo_arc_str_stub_ (&self) -> Arc { todo!() } - fn _todo_item_theme_stub (&self) -> ItemTheme { todo!() } -} -def_command!(TrackCommand: |track: Track| { - Stop => { track.sequencer.enqueue_next(None); Ok(None) }, - SetMute { mute: Option } => todo!(), - SetSolo { solo: Option } => todo!(), - SetSize { size: usize } => todo!(), - SetZoom { zoom: usize } => todo!(), - SetName { name: Arc } => - swap_value(&mut track.name, name, |name|Self::SetName { name }), - SetColor { color: ItemTheme } => - swap_value(&mut track.color, color, |color|Self::SetColor { color }), - SetRec { rec: Option } => - toggle_bool(&mut track.sequencer.recording, rec, |rec|Self::SetRec { rec }), - SetMon { mon: Option } => - toggle_bool(&mut track.sequencer.monitoring, mon, |mon|Self::SetMon { mon }), -}); #[derive(Debug, Default)] pub struct Track { @@ -80,13 +88,6 @@ pub struct Track { has!(Clock: |self: Track|self.sequencer.clock); has!(Sequencer: |self: Track|self.sequencer); - -impl HasWidth for Track { - const MIN_WIDTH: usize = 9; - fn width_inc (&mut self) { self.width += 1; } - fn width_dec (&mut self) { if self.width > Track::MIN_WIDTH { self.width -= 1; } } -} - impl Track { /// Create a new track with only the default [Sequencer]. pub fn new ( @@ -105,7 +106,24 @@ impl Track { ..Default::default() }) } + fn audio_ins (&self) -> &[AudioInput] { + self.devices.first().map(|x|x.audio_ins()).unwrap_or_default() + } + fn audio_outs (&self) -> &[AudioOutput] { + self.devices.last().map(|x|x.audio_outs()).unwrap_or_default() + } + fn _todo_opt_bool_stub_ (&self) -> Option { todo!() } + fn _todo_usize_stub_ (&self) -> usize { todo!() } + fn _todo_arc_str_stub_ (&self) -> Arc { todo!() } + fn _todo_item_theme_stub (&self) -> ItemTheme { todo!() } } + +impl HasWidth for Track { + const MIN_WIDTH: usize = 9; + fn width_inc (&mut self) { self.width += 1; } + fn width_dec (&mut self) { if self.width > Track::MIN_WIDTH { self.width -= 1; } } +} + #[cfg(feature = "sampler")] impl Track { /// Create a new track connecting the [Sequencer] to a [Sampler]. @@ -148,23 +166,21 @@ impl Track { None } } - -pub trait HasTrack { - fn track (&self) -> Option<&Track>; - fn track_mut (&mut self) -> Option<&mut Track>; - #[cfg(feature = "port")] fn view_midi_ins_status <'a> (&'a self, theme: ItemTheme) -> impl Content + 'a { - self.track().map(move|track|view_ports_status(theme, "MIDI ins: ", &track.sequencer.midi_ins)) - } - #[cfg(feature = "port")] fn view_midi_outs_status (&self, theme: ItemTheme) -> impl Content + '_ { - self.track().map(move|track|view_ports_status(theme, "MIDI outs: ", &track.sequencer.midi_outs)) - } - #[cfg(feature = "port")] fn view_audio_ins_status (&self, theme: ItemTheme) -> impl Content { - self.track().map(move|track|view_ports_status(theme, "Audio ins: ", &track.audio_ins())) - } - #[cfg(feature = "port")] fn view_audio_outs_status (&self, theme: ItemTheme) -> impl Content { - self.track().map(move|track|view_ports_status(theme, "Audio outs:", &track.audio_outs())) - } -} +def_command!(TrackCommand: |track: Track| { + Stop => { track.sequencer.enqueue_next(None); Ok(None) }, + SetMute { mute: Option } => todo!(), + SetSolo { solo: Option } => todo!(), + SetSize { size: usize } => todo!(), + SetZoom { zoom: usize } => todo!(), + SetName { name: Arc } => + swap_value(&mut track.name, name, |name|Self::SetName { name }), + SetColor { color: ItemTheme } => + swap_value(&mut track.color, color, |color|Self::SetColor { color }), + SetRec { rec: Option } => + toggle_bool(&mut track.sequencer.recording, rec, |rec|Self::SetRec { rec }), + SetMon { mon: Option } => + toggle_bool(&mut track.sequencer.monitoring, mon, |mon|Self::SetMon { mon }), +}); impl ClipsView for T {} @@ -268,13 +284,15 @@ fn view_track_header (theme: ItemTheme, content: impl Content) -> impl C Fixed::X(12, Tui::bg(theme.darker.rgb, Fill::X(Align::e(content)))) } -fn view_ports_status (theme: ItemTheme, title: &str, ports: &[T]) { +fn view_ports_status <'a, T: JackPort> (theme: ItemTheme, title: &'a str, ports: &'a [T]) + -> impl Content + use<'a, T> +{ let ins = ports.len() as u16; let frame = Outer(true, Style::default().fg(Tui::g(96))); let iter = move||ports.iter(); - let names = Map::south(1, iter, |port, index|Fill::Y(Align::w(format!(" {index} {}", port.port_name())))); + let names = Map::south(1, iter, move|port, index|Fill::Y(Align::w(format!(" {index} {}", port.port_name())))); let field = FieldV(theme, title, names); - Fixed::XY(20, 1 + ins, frame.enclose(Fixed::XY(20, 1 + ins, field.content()))) + Fixed::XY(20, 1 + ins, frame.enclose(Fixed::XY(20, 1 + ins, field))) } impl Track {