diff --git a/config/config_arranger.edn b/config/config_arranger.edn index fb40e339..43a6577d 100644 --- a/config/config_arranger.edn +++ b/config/config_arranger.edn @@ -17,11 +17,14 @@ (layer "./keys_arranger.edn") (layer "./keys_global.edn")) -(view (bsp/a :view-dialog - (bsp/s - :view-status-h2 - (bsp/n (fill/x (align/w :view-arranger-inputs)) - (bsp/n (fill/x (align/w :view-arranger-devices)) - (bsp/s (fill/x (align/w :view-arranger-outputs)) - (bsp/s (fill/x (align/w :view-arranger-tracks)) - :view-arranger-scenes))))))) +(view + (bsp/a :view-dialog + (bsp/w :view-meters-output + (bsp/e :view-meters-input + (bsp/s + :view-status-h2 + (bsp/n (fill/x (align/w :view-tracks-inputs)) + (bsp/n (fill/x (align/w :view-tracks-devices)) + (bsp/s (fill/x (align/w :view-tracks-outputs)) + (bsp/s (fill/x (align/w :view-tracks-tracks)) + :view-tracks-scenes))))))))) diff --git a/config/keys_arranger.edn b/config/keys_arranger.edn index 23da3a49..1953e0c4 100644 --- a/config/keys_arranger.edn +++ b/config/keys_arranger.edn @@ -3,10 +3,11 @@ (@t select :select-track-header) (@s select :select-scene-header) (@tab edit :clip-selected) -(@shift-I input add) -(@shift-O output add) -(@shift-S scene add) -(@shift-T track add) +(@enter edit :clip-selected) +(@shift-I project input-add) +(@shift-O project output-add) +(@shift-S project scene-add) +(@shift-T project track-add) (@shift-D toggle-dialog :dialog-device) (@up select :select-scene-prev) diff --git a/crates/app/src/view.rs b/crates/app/src/view.rs index 35239af1..90d9983e 100644 --- a/crates/app/src/view.rs +++ b/crates/app/src/view.rs @@ -108,50 +108,23 @@ impl App { pub fn view_audio_outs_status (&self) -> impl Content + use<'_> { self.project.view_audio_outs_status(self.color) } - pub fn view_arranger_scenes (&self) -> impl Content + use<'_> { + pub fn view_tracks_scenes (&self) -> impl Content + use<'_> { Bsp::e( Fixed::x(20, Align::nw(self.project.view_scenes_names())), Bsp::w(self.view_pool(), self.project.view_scenes_clips()), ) } - pub fn view_arranger_inputs <'a> (&'a self) -> impl Content + use<'a> { - Fixed::y(3, self.project.view_track_inputs(self.color)) + pub fn view_tracks_inputs <'a> (&'a self) -> impl Content + use<'a> { + Fixed::y(2, self.project.view_track_inputs(self.color)) } - pub fn view_arranger_outputs <'a> (&'a self) -> impl Content + use<'a> { + pub fn view_tracks_outputs <'a> (&'a self) -> impl Content + use<'a> { Fixed::y(3, self.project.view_track_outputs(self.color)) } - pub fn view_arranger_devices <'a> (&'a self) -> impl Content + use<'a> { + pub fn view_tracks_devices <'a> (&'a self) -> impl Content + use<'a> { Fixed::y(3, self.project.view_track_devices(self.color)) } - pub fn view_arranger_tracks <'a> (&'a self) -> impl Content + use<'a> { - Fixed::y(3, self.project.view_track_names(self.color)) - } - pub fn view_arranger_track_names (&self) -> impl Content + use<'_> { - self.project.view_track_names(self.color) - } - pub fn view_arranger_track_outputs <'a> (&'a self) -> impl Content + use<'a> { - self.project.view_track_outputs(self.color) - } - pub fn view_arranger_track_inputs <'a> (&'a self) -> impl Content + use<'a> { - self.project.view_track_inputs(self.color) - } - pub fn view_arranger_track_devices <'a> (&'a self) -> impl Content + use<'a> { - self.project.view_track_devices(self.color) - } - pub fn view_arranger_track_scenes <'a> (&'a self) -> impl Content + use<'a> { - let mut max_devices = 0u16; - for track in self.project.tracks.iter() { - max_devices = max_devices.max(track.devices.len() as u16); - } - Bsp::w( - Fixed::x(20, Tui::bg(self.color.darkest.rgb, - col!(Tui::bold(true, "Devices"), "[d] Select", "[D] Add"))), - Fixed::y(max_devices + 1, Tui::bg(self.color.darker.rgb, Align::w(Fill::x(Map::new( - ||self.project.tracks_with_sizes_scrolled(), - move|(index, track, x1, x2): (usize, &'a Track, usize, usize), _| - Push::x(x2 as u16, Fixed::xy(track.width as u16, max_devices + 1, - Align::nw(Map::south(1, ||track.devices.iter(), - |device, index|format!("{index}: {}", device.name()))))))))))) + pub fn view_tracks_tracks <'a> (&'a self) -> impl Content + use<'a> { + Fixed::y(1, self.project.view_track_names(self.color)) } pub fn view_pool (&self) -> impl Content + use<'_> { Fixed::x(20, Bsp::s( diff --git a/crates/device/src/arranger/arranger_view.rs b/crates/device/src/arranger/arranger_view.rs index 90240754..ea42c575 100644 --- a/crates/device/src/arranger/arranger_view.rs +++ b/crates/device/src/arranger/arranger_view.rs @@ -3,6 +3,8 @@ use crate::*; impl TracksView for T where T: ScenesView + HasMidiIns + HasMidiOuts + HasSize + HasTrackScroll + HasSelection + HasMidiIns + HasEditor {} +impl ClipsView for T {} + pub trait TracksView: ScenesView + HasMidiIns + HasMidiOuts + HasSize + HasTrackScroll + HasSelection + HasMidiIns + HasEditor { @@ -39,7 +41,7 @@ pub trait TracksView: Fixed::x(4, button_add), Bsp::e( Fixed::x(20, Align::w(button)), - content + Fill::xy(Align::c(content)) ) ) } @@ -53,10 +55,10 @@ pub trait TracksView: theme, button_2("t", "rack", false), button_2("T", "+", false), - Fixed::y(1, Align::w(Tui::bg(theme.darker.rgb, Align::w(Fill::x( + Tui::bg(theme.darker.rgb, Fixed::y(1, Fill::x( Stack::east(move|add: &mut dyn FnMut(&dyn Render)|{ for (index, track, x1, x2) in self.tracks_with_sizes() { - add(&Fixed::x(track.width as u16, + add(&Fixed::x(self.track_width(index, track), Tui::bg(if self.selection().track() == Some(index) { track.color.light.rgb } else { @@ -66,7 +68,7 @@ pub trait TracksView: Tui::fg(Rgb(255, 255, 255), Tui::bold(true, &track.name)) ))))); } - }))))))) + }))))) } fn view_track_outputs <'a> (&'a self, theme: ItemTheme) -> impl Content { let mut h = 0u16; @@ -81,16 +83,17 @@ pub trait TracksView: Tui::bg(theme.darker.rgb, Align::w(Fill::x( Stack::east(move|add: &mut dyn FnMut(&dyn Render)|{ for (index, track, x1, x2) in self.tracks_with_sizes() { - add(&Fixed::x(track.width as u16, Align::nw(Bsp::n( - Tui::bg(if self.selection().track() == Some(index) { - track.color.light.rgb - } else { - track.color.base.rgb - }, Fill::x(Align::w(format!("·mute ·solo")))), - Map::south(2, ||track.sequencer.midi_outs.iter(), - |port, index|Tui::fg(Rgb(255, 255, 255), - Fixed::y(2, Tui::bg(track.color.dark.rgb, Fill::x(Align::w( - format!("·o{index:02} {}", port.name()))))))))))); + add(&Fixed::x(self.track_width(index, track), + Align::nw(Bsp::n( + Tui::bg(if self.selection().track() == Some(index) { + track.color.light.rgb + } else { + track.color.base.rgb + }, Fill::x(Align::w(format!("·mute ·solo")))), + Map::south(2, ||track.sequencer.midi_outs.iter(), + |port, index|Tui::fg(Rgb(255, 255, 255), + Fixed::y(2, Tui::bg(track.color.dark.rgb, Fill::x(Align::w( + format!("·o{index:02} {}", port.name()))))))))))); } }))))))) } @@ -106,7 +109,7 @@ pub trait TracksView: Fixed::y(h, Tui::bg(theme.darker.rgb, Align::w(Fill::x(Stack::east( move|add: &mut dyn FnMut(&dyn Render)|{ for (index, track, x1, x2) in self.tracks_with_sizes() { - add(&Fixed::xy(track.width as u16, h + 1, + add(&Fixed::xy(self.track_width(index, track), h + 1, Tui::bg(track.color.dark.rgb, Align::nw(Map::south(1, move||0..h, |_, index|format!("·d{index:02} {}", "--------")))))); } @@ -124,7 +127,7 @@ pub trait TracksView: Tui::bg(theme.darker.rgb, Align::w(Fill::x( Stack::east(move|add: &mut dyn FnMut(&dyn Render)|{ for (index, track, x1, x2) in self.tracks_with_sizes() { - add(&Fixed::xy(track.width as u16, h + 1, + add(&Fixed::xy(self.track_width(index, track), h + 1, Align::nw(Bsp::s( Tui::bg(track.color.base.rgb, Fill::x(Align::w(format!("·mon ·rec ·dub")))), @@ -133,6 +136,15 @@ pub trait TracksView: Fill::x(Align::w(format!("·i{index:02} {}", port.name()))))))))); }}))))) } + fn track_width (&self, index: usize, track: &Track) -> u16 { + (if self.selection().track() == Some(index) + && let Some(editor) = self.editor() + { + editor.width().max(24).max(track.width) + } else { + track.width + }) as u16 + } } pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + Send + Sync { @@ -173,10 +185,7 @@ pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + Send + Sync { } } -impl ClipsView for T {} - pub trait ClipsView: TracksView + ScenesView + Send + Sync { - fn view_scenes_clips <'a> (&'a self) -> impl Content + 'a { @@ -185,7 +194,7 @@ pub trait ClipsView: TracksView + ScenesView + Send + Sync { //column(&Fixed::x(5, Fill::xy(Tui::bg(Green, "kyp")))); column(&Fixed::x( if self.selection().track() == Some(track_index) - && let Some(editor) = self.editor () + && let Some(editor) = self.editor() { editor.width().max(24).max(track.width) } else { @@ -245,82 +254,9 @@ pub trait ClipsView: TracksView + ScenesView + Send + Sync { Fill::xy(When(self.selection().track() == Some(track_index) && self.selection().scene() == Some(scene_index) && self.is_editing(), self.editor()))))))); - //let (name, theme) = if let Some(clip) = &scene.clips.get(track_index).flatten() { - //let clip = clip.read().unwrap(); - //(Some(clip.name.clone()), clip.color) - //} else { - //(None, ItemTheme::G[32]) - //}; - //let content = Fill::x(Align::w(Tui::bold(true, Bsp::e(" ⏹ ", name)))); - //let same_track = self.track_selected() == Some(track_index); - //let selected = same_track && self.scene_selected() == Some(s); - //let neighbor = same_track && s > 0 && self.scene_selected() == Some(s - 1); - //let is_last = self.scenes().len().saturating_sub(1) == s; - //let fg = theme.lightest.rgb; - //let bg = if selected { theme.light } else { theme.base }.rgb; - //let hi = if let Some(previous) = previous { - //if neighbor { previous.light.rgb } else { previous.base.rgb } - //} else { - //Reset - //}; - //let lo = if is_last { - //Reset - //} else if selected { - //theme.light.rgb - //} else { - //theme.base.rgb - //}; - //let height = (1 + y2 - y1) as u16; - //let is_editing = false; //FIXME - //let editor = (); //FIXME - //cell(&Fixed::xy(track.width as u16, 2, Bsp::b(Fixed::y(height, Phat { - //width: 0, height: 0, content, colors: [fg, bg, hi, lo] - //}), When( - //is_editing && same_track && self.scene_selected() == Some(s), - //editor - //)))) } }) } - - fn scenes_clips_2 <'a> ( - &'a self, - theme: ItemTheme - ) -> impl Content + 'a { - Fixed::y(self.scenes().len() as u16 * 2, Tui::bg(theme.darker.rgb, - Align::w(Fill::x(Map::new(||self.scenes().iter().skip(self.scene_scroll()), - move|scene: &'a Scene, index|self.track_scenes(index, scene)))))) - } - - fn track_scenes <'a> ( - &'a self, - scene_index: usize, - scene: &'a Scene - ) -> impl Content + 'a { - Push::y(scene_index as u16 * 2u16, Fixed::xy(20, 2, Map::new( - move||scene.clips.iter().skip(self.track_scroll()), - move|clip: &'a Option>>, track_index| - self.track_scene_clip(scene_index, scene, track_index, clip)))) - } - - fn track_scene_clip ( - &self, - scene_index: usize, - scene: &Scene, - track_index: usize, - clip: &Option>> - ) -> impl Content { - let (theme, text) = if let Some(clip) = clip { - let clip = clip.read().unwrap(); - (clip.color, clip.name.clone()) - } else { - (scene.color, Default::default()) - }; - Push::x(track_index as u16 * 14, Tui::bg(theme.dark.rgb, Bsp::e( - format!(" {scene_index:2} {track_index:2} "), - Tui::fg(Rgb(255, 255, 255), - Tui::bold(true, format!("{}", text)))))) - } } pub trait HasWidth {