diff --git a/crates/app/src/api.rs b/crates/app/src/api.rs index 17ef811a..430a520b 100644 --- a/crates/app/src/api.rs +++ b/crates/app/src/api.rs @@ -47,13 +47,27 @@ handle!(TuiIn: |self: App, input|Ok(if let Some(command) = self.config.keys.comm Ok(None) } fn select (app: &mut App, selection: Selection) -> Perhaps { - app.select(selection); + app.arranger.select(selection); + if let Some(ref mut editor) = app.editor { + editor.set_clip(match app.arranger.selected { + Some(Selection::TrackClip { track, scene }) + if let Some(Some(Some(clip))) = app + .arranger + .scenes.get(scene) + .map(|s|s.clips.get(track)) + => + Some(clip), + _ => + None + }); + } Ok(None) //("select" [t: usize, s: usize] Some(match (t.expect("no track"), s.expect("no scene")) { //(0, 0) => Self::Select(Selection::Mix), //(t, 0) => Self::Select(Selection::Track(t)), //(0, s) => Self::Select(Selection::Scene(s)), //(t, s) => Self::Select(Selection::TrackClip { track: t, scene: s }) }))) + // autoedit: load focused clip in editor. } fn stop_all (app: &mut App) -> Perhaps { app.stop_all(); diff --git a/crates/device/src/arranger/arranger_api.rs b/crates/device/src/arranger/arranger_api.rs index 9034baca..6f3210b9 100644 --- a/crates/device/src/arranger/arranger_api.rs +++ b/crates/device/src/arranger/arranger_api.rs @@ -14,16 +14,6 @@ impl ArrangementCommand { /// Set the selection fn select (arranger: &mut Arrangement, s: Option) -> Perhaps { arranger.selected = s; - // autoedit: load focused clip in editor. - if let Some(ref mut editor) = arranger.editor { - editor.set_clip(match arranger.selected { - Some(Selection::TrackClip { track, scene }) - if let Some(Some(Some(clip))) = arranger - .scenes.get(scene) - .map(|s|s.clips.get(track)) => Some(clip), - _ => None - }); - } Ok(None) } /// Launch a clip or scene diff --git a/crates/device/src/arranger/arranger_clip.rs b/crates/device/src/arranger/arranger_clip.rs index b0ad719a..98dd7ba7 100644 --- a/crates/device/src/arranger/arranger_clip.rs +++ b/crates/device/src/arranger/arranger_clip.rs @@ -33,38 +33,4 @@ impl ClipCommand { impl Arrangement { - /// Put a clip in a slot - pub(crate) fn clip_put ( - &mut self, track: usize, scene: usize, clip: Option>> - ) -> Option>> { - let old = self.scenes[scene].clips[track].clone(); - self.scenes[scene].clips[track] = clip; - old - } - - /// Change the color of a clip, returning the previous one - pub(crate) fn clip_set_color ( - &self, track: usize, scene: usize, color: ItemTheme - ) -> Option { - self.scenes[scene].clips[track].as_ref().map(|clip|{ - let mut clip = clip.write().unwrap(); - let old = clip.color.clone(); - clip.color = color.clone(); - panic!("{color:?} {old:?}"); - old - }) - } - - /// Get the active clip - pub(crate) fn clip (&self) -> Option>> { - self.scene()?.clips.get(self.selected.track()?)?.clone() - } - - /// Toggle looping for the active clip - pub(crate) fn toggle_loop (&mut self) { - if let Some(clip) = self.clip() { - clip.write().unwrap().toggle_loop() - } - } - } diff --git a/crates/device/src/arranger/arranger_model.rs b/crates/device/src/arranger/arranger_model.rs index d2f3246c..7d59ed67 100644 --- a/crates/device/src/arranger/arranger_model.rs +++ b/crates/device/src/arranger/arranger_model.rs @@ -119,16 +119,66 @@ impl Arrangement { 2 //1 + self.devices_with_sizes().last().map(|(_, _, _, _, y)|y as u16).unwrap_or(0) } + /// Get the active track + fn get_track (&self) -> Option<&Track> { + let index = self.selection()?.track()?; + Has::>::get(self).get(index) + } + /// Get a mutable reference to the active track + fn get_track_mut (&mut self) -> Option<&mut Track> { + let index = self.selection()?.track()?; + Has::>::get_mut(self).get_mut(index) + } + /// Get the active scene + fn get_scene (&self) -> Option<&Scene> { + let index = self.selection()?.scene()?; + Has::>::get(self).get(index) + } + /// Get a mutable reference to the active scene + fn get_scene_mut (&mut self) -> Option<&mut Scene> { + let index = self.selection()?.scene()?; + Has::>::get_mut(self).get_mut(index) + } + /// Get the active clip + fn get_clip (&self) -> Option>> { + self.get_scene()?.clips.get(self.selection()?.track()?)?.clone() + } + /// Put a clip in a slot + pub(crate) fn clip_put ( + &mut self, track: usize, scene: usize, clip: Option>> + ) -> Option>> { + let old = self.scenes[scene].clips[track].clone(); + self.scenes[scene].clips[track] = clip; + old + } + /// Change the color of a clip, returning the previous one + pub(crate) fn clip_set_color (&self, track: usize, scene: usize, color: ItemTheme) + -> Option + { + self.scenes[scene].clips[track].as_ref().map(|clip|{ + let mut clip = clip.write().unwrap(); + let old = clip.color.clone(); + clip.color = color.clone(); + panic!("{color:?} {old:?}"); + old + }) + } + /// Toggle looping for the active clip + pub(crate) fn toggle_loop (&mut self) { + if let Some(clip) = self.get_clip() { + clip.write().unwrap().toggle_loop() + } + } } #[cfg(feature = "sampler")] impl Arrangement { /// Get the first sampler of the active track pub fn sampler (&self) -> Option<&Sampler> { - self.track().map(|t|t.sampler(0)).flatten() + self.get_track()?.sampler(0) } /// Get the first sampler of the active track pub fn sampler_mut (&mut self) -> Option<&mut Sampler> { - self.track_mut().map(|t|t.sampler_mut(0)).flatten() + self.get_track_mut()?.sampler_mut(0) } } diff --git a/crates/device/src/arranger/arranger_select.rs b/crates/device/src/arranger/arranger_select.rs index 8330faf2..81a2f7a1 100644 --- a/crates/device/src/arranger/arranger_select.rs +++ b/crates/device/src/arranger/arranger_select.rs @@ -1,40 +1,17 @@ use crate::*; -impl> HasSelection for T {} +impl>> HasSelection for T {} -pub trait HasSelection: Has { - fn selection (&self) -> &Selection { - self.get() +pub trait HasSelection: Has> { + fn selection (&self) -> Option<&Selection> { + self.get().as_ref() } - fn selection_mut (&mut self) -> &mut Selection { + fn selection_mut (&mut self) -> &mut Option { self.get_mut() } } -impl Has> for Arrangement { - fn get (&self) -> &Option { - let selection: Selection = Has::>::get(self)?; - let index: Option = selection.track()?; - let track: Track = Has::>::get(self).get(index)?; - } - fn get_mut (&mut self) -> &mut Option { - Has::>::get(self) - .and_then(|selection|selection.track()) - .and_then(|index|Has::>::get_mut(self).get_mut(index)) - } -} - -impl Has> for Arrangement { - fn get (&self) -> &Option { - Has::>::get(self) - .and_then(|selection|selection.track()) - .and_then(|index|Has::>::get(self).get(index)) - } - fn get_mut (&mut self) -> &mut Option { - Has::>::get(self) - .and_then(|selection|selection.track()) - .and_then(|index|Has::>::get_mut(self).get_mut(index).as_deref()) - } +impl Arrangement { } /// Represents the current user selection in the arranger diff --git a/crates/device/src/arranger/arranger_tracks.rs b/crates/device/src/arranger/arranger_tracks.rs index 7863a9e7..56fce892 100644 --- a/crates/device/src/arranger/arranger_tracks.rs +++ b/crates/device/src/arranger/arranger_tracks.rs @@ -81,11 +81,9 @@ impl<'a> ArrangerView<'a> { } } -impl AddTrack for T {} - -pub trait AddTrack: HasTracks + HasScenes + HasClock + HasJack { +impl Arrangement { /// Add multiple tracks - fn tracks_add ( + pub fn tracks_add ( &mut self, count: usize, width: Option, @@ -106,7 +104,7 @@ pub trait AddTrack: HasTracks + HasScenes + HasClock + HasJack { } /// Add a track - fn track_add ( + pub fn track_add ( &mut self, name: Option<&str>, color: Option, diff --git a/crates/engine/src/lib.rs b/crates/engine/src/lib.rs index 55b8d382..8f891e4c 100644 --- a/crates/engine/src/lib.rs +++ b/crates/engine/src/lib.rs @@ -37,6 +37,14 @@ impl>> MaybeHas for U { }; } +#[macro_export] macro_rules! as_ref { + ($T:ty: |$self:ident : $S:ty| $x:expr) => { + impl AsRef<$T> for $S { + fn as_ref (&$self) -> &$T { &$x } + } + }; +} + pub trait HasN: Send + Sync { fn get_nth (&self, key: usize) -> &T; fn get_nth_mut (&mut self, key: usize) -> &mut T;