From 48603e48128f13a9e85d3c02c4dd3e2bfe21eda2 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 17 May 2025 12:22:43 +0300 Subject: [PATCH] arranger: spawning clips once again!1 --- config/keys_arranger.edn | 2 +- crates/app/src/api.rs | 14 ++++++++++++ crates/app/src/model.rs | 22 +++++++++---------- crates/device/src/arranger/arranger_model.rs | 4 ++-- crates/device/src/arranger/arranger_scenes.rs | 2 +- crates/device/src/arranger/arranger_view.rs | 15 ++++++++++--- 6 files changed, 41 insertions(+), 18 deletions(-) diff --git a/config/keys_arranger.edn b/config/keys_arranger.edn index 40ffc742..0199a07b 100644 --- a/config/keys_arranger.edn +++ b/config/keys_arranger.edn @@ -1,7 +1,7 @@ (@c color) (@q launch) (@t select :select-track-header) -(@tab edit :clip) +(@tab edit :clip-selected) (@shift-I input add) (@shift-O output add) (@shift-S scene add) diff --git a/crates/app/src/api.rs b/crates/app/src/api.rs index 6b04fe75..3a4516dd 100644 --- a/crates/app/src/api.rs +++ b/crates/app/src/api.rs @@ -18,6 +18,20 @@ handle!(TuiIn: |self: App, input|Ok(if let Some(command) = self.config.keys.comm })); #[tengri_proc::command(App)] impl AppCommand { + fn edit (app: &mut App) -> Perhaps { + let selection = app.selection().clone(); + Ok(match selection { + Selection::TrackClip { track, scene } => { + let clip = &mut app.scenes_mut()[scene].clips[track]; + if clip.is_none() { + *clip = Some(Default::default()); + } + app.editor = clip.as_ref().map(|c|c.into()); + None + } + _ => None + }) + } fn dialog (app: &mut App, dialog: Option) -> Perhaps { app.toggle_dialog(dialog); Ok(None) diff --git a/crates/app/src/model.rs b/crates/app/src/model.rs index 8145df39..df8b5ce8 100644 --- a/crates/app/src/model.rs +++ b/crates/app/src/model.rs @@ -3,25 +3,25 @@ use crate::*; #[derive(Default, Debug)] pub struct App { /// Must not be dropped for the duration of the process - pub jack: Jack, + pub jack: Jack, /// Port handles pub ports: std::collections::BTreeMap>, /// Display size pub size: Measure, /// Performance counter pub perf: PerfModel, - // View and input definition - pub config: Configuration, + pub config: Configuration, + /// Contains all recently created clips. + pub pool: Pool, /// Contains the currently edited musical arrangement pub project: Arrangement, /// Undo history pub history: Vec, // Dialog overlay - pub dialog: Option, + pub dialog: Option, /// Contains the currently edited MIDI clip - pub editor: Option, - + pub editor: Option, // Cache of formatted strings pub view_cache: Arc>, /// Base color. @@ -29,6 +29,7 @@ pub struct App { } has!(Jack: |self: App|self.jack); +has!(Pool: |self: App|self.pool); has!(Clock: |self: App|self.project.clock); has!(Selection: |self: App|self.project.selection); has!(Vec: |self: App|self.project.midi_ins); @@ -39,16 +40,15 @@ has!(Measure: |self: App|self.size); maybe_has!(Track: |self: App| { MaybeHas::::get(&self.project) }; { MaybeHas::::get_mut(&mut self.project) }); +impl HasTrackScroll for App { + fn track_scroll (&self) -> usize { self.project.track_scroll() } +} maybe_has!(Scene: |self: App| { MaybeHas::::get(&self.project) }; { MaybeHas::::get_mut(&mut self.project) }); impl HasSceneScroll for App { fn scene_scroll (&self) -> usize { self.project.scene_scroll() } } -impl HasTrackScroll for App { - fn track_scroll (&self) -> usize { self.project.track_scroll() } -} - has_clips!(|self: App|self.project.pool.clips); has_editor!(|self: App|{ editor = self.editor; @@ -312,7 +312,7 @@ impl App { fn select_track_prev (&self) -> Selection { self.selection().track_prev() } - fn clip_selection (&self) -> Option>> { + fn clip_selected (&self) -> Option>> { match self.selection() { Selection::TrackClip { track, scene } => self.scenes()[*scene].clips[*track].clone(), _ => None diff --git a/crates/device/src/arranger/arranger_model.rs b/crates/device/src/arranger/arranger_model.rs index 3a9b5f56..a1c8a407 100644 --- a/crates/device/src/arranger/arranger_model.rs +++ b/crates/device/src/arranger/arranger_model.rs @@ -168,11 +168,11 @@ impl Arrangement { mins: &[PortConnect], mouts: &[PortConnect], ) -> Usually<(usize, &mut Track)> { - self.track_last += 1; let name: Arc = name.map_or_else( - ||format!("Track{:02}", self.track_last).into(), + ||format!("t{:02}", self.track_last).into(), |x|x.to_string().into() ); + self.track_last += 1; let mut track = Track { width: (name.len() + 2).max(12), color: color.unwrap_or_else(ItemTheme::random), diff --git a/crates/device/src/arranger/arranger_scenes.rs b/crates/device/src/arranger/arranger_scenes.rs index 8420e23a..0aca0946 100644 --- a/crates/device/src/arranger/arranger_scenes.rs +++ b/crates/device/src/arranger/arranger_scenes.rs @@ -28,7 +28,7 @@ pub trait HasScenes: Has> + Send + Sync { } /// Generate the default name for a new scene fn scene_default_name (&self) -> Arc { - format!("Sc{:3>}", self.scenes().len() + 1).into() + format!("s{:3>}", self.scenes().len() + 1).into() } fn scene_longest_name (&self) -> usize { self.scenes().iter().map(|s|s.name.len()).fold(0, usize::max) diff --git a/crates/device/src/arranger/arranger_view.rs b/crates/device/src/arranger/arranger_view.rs index 1f4d7468..b45b09ed 100644 --- a/crates/device/src/arranger/arranger_view.rs +++ b/crates/device/src/arranger/arranger_view.rs @@ -207,8 +207,12 @@ pub trait TracksView: HasSize + HasTrackScroll + HasSelection + HasMidiI .tracks_with_sizes(&self.selection(), None) .skip(self.track_scroll()) { - (add)(&Fixed::x(track.width as u16, - Tui::bg(track.color.base.rgb, Align::nw(Tui::fg( + add(&Fixed::x(track.width as u16, + Tui::bg(if self.selection().track() == Some(index) { + track.color.light.rgb + } else { + track.color.base.rgb + }, Align::nw(Tui::fg( Rgb(255, 255, 255), Tui::bold(true, format!("{}", track.name))))))); } @@ -424,18 +428,23 @@ pub trait ClipsView: TracksView + ScenesView + Send + Sync { (None, ItemTheme::G[32]) }; let fg = theme.lightest.rgb; + let mut outline = theme.base.rgb; let bg = if self.selection().track() == Some(track_index) && self.selection().scene() == Some(scene_index) { + outline = theme.lightest.rgb; theme.light.rgb } else if self.selection().track() == Some(track_index) || self.selection().scene() == Some(scene_index) { + outline = theme.darkest.rgb; theme.base.rgb } else { theme.dark.rgb }; - cell(&Fixed::xy(track.width as u16, 2, Tui::fg_bg(fg, bg, Align::nw(name.unwrap_or(" ---- ".into()))))); + cell(&Fixed::xy(track.width as u16, 2, Bsp::b( + Fill::xy(Outer(true, Style::default().fg(outline))), + Fill::xy(Align::nw(Tui::fg_bg(fg, bg, Align::nw(name.unwrap_or(" ---- ".into())))))))); //let (name, theme) = if let Some(clip) = &scene.clips.get(track_index).flatten() { //let clip = clip.read().unwrap(); //(Some(clip.name.clone()), clip.color)