modal -> dialog; extract dialog, selection, editor

This commit is contained in:
🪞👃🪞 2025-05-04 18:57:31 +03:00
parent 6286d69824
commit a3beab0f36
7 changed files with 391 additions and 377 deletions

View file

@ -0,0 +1,147 @@
use crate::*;
pub trait HasSelection {
fn selected (&self) -> &Selection;
fn selected_mut (&mut self) -> &mut Selection;
}
/// Represents the current user selection in the arranger
#[derive(PartialEq, Clone, Copy, Debug, Default)]
pub enum Selection {
/// The whole mix is selected
#[default] Mix,
/// A MIDI input is selected.
Input(usize),
/// A MIDI output is selected.
Output(usize),
/// A scene is selected.
Scene(usize),
/// A track is selected.
Track(usize),
/// A clip (track × scene) is selected.
TrackClip { track: usize, scene: usize },
/// A track's MIDI input connection is selected.
TrackInput { track: usize, port: usize },
/// A track's MIDI output connection is selected.
TrackOutput { track: usize, port: usize },
/// A track device slot is selected.
TrackDevice { track: usize, device: usize },
}
/// Focus identification methods
impl Selection {
pub fn is_mix (&self) -> bool {
matches!(self, Self::Mix)
}
pub fn is_track (&self) -> bool {
matches!(self, Self::Track(_))
}
pub fn is_scene (&self) -> bool {
matches!(self, Self::Scene(_))
}
pub fn is_clip (&self) -> bool {
matches!(self, Self::TrackClip {..})
}
pub fn track (&self) -> Option<usize> {
use Selection::*;
match self {
Track(track)
| TrackClip { track, .. }
| TrackInput { track, .. }
| TrackOutput { track, .. }
| TrackDevice { track, .. } => Some(*track),
_ => None
}
}
pub fn track_next (&self, len: usize) -> Self {
use Selection::*;
match self {
Mix => Track(0),
Scene(s) => TrackClip { track: 0, scene: *s },
Track(t) => if t + 1 < len {
Track(t + 1)
} else {
Mix
},
TrackClip {track, scene} => if track + 1 < len {
TrackClip { track: track + 1, scene: *scene }
} else {
Scene(*scene)
},
_ => todo!()
}
}
pub fn track_prev (&self) -> Self {
use Selection::*;
match self {
Mix => Mix,
Scene(s) => Scene(*s),
Track(0) => Mix,
Track(t) => Track(t - 1),
TrackClip { track: 0, scene } => Scene(*scene),
TrackClip { track: t, scene } => TrackClip { track: t - 1, scene: *scene },
_ => todo!()
}
}
pub fn scene (&self) -> Option<usize> {
use Selection::*;
match self {
Scene(scene) | TrackClip { scene, .. } => Some(*scene),
_ => None
}
}
pub fn scene_next (&self, len: usize) -> Self {
use Selection::*;
match self {
Mix => Scene(0),
Track(t) => TrackClip { track: *t, scene: 0 },
Scene(s) => if s + 1 < len {
Scene(s + 1)
} else {
Mix
},
TrackClip { track, scene } => if scene + 1 < len {
TrackClip { track: *track, scene: scene + 1 }
} else {
Track(*track)
},
_ => todo!()
}
}
pub fn scene_prev (&self) -> Self {
use Selection::*;
match self {
Mix | Scene(0) => Mix,
Scene(s) => Scene(s - 1),
Track(t) => Track(*t),
TrackClip { track, scene: 0 } => Track(*track),
TrackClip { track, scene } => TrackClip { track: *track, scene: scene - 1 },
_ => todo!()
}
}
pub fn describe (&self, tracks: &[Track], scenes: &[Scene]) -> Arc<str> {
use Selection::*;
format!("{}", match self {
Mix => "Everything".to_string(),
Scene(s) => scenes.get(*s)
.map(|scene|format!("S{s}: {}", &scene.name))
.unwrap_or_else(||"S??".into()),
Track(t) => tracks.get(*t)
.map(|track|format!("T{t}: {}", &track.name))
.unwrap_or_else(||"T??".into()),
TrackClip { track, scene } => match (tracks.get(*track), scenes.get(*scene)) {
(Some(_), Some(s)) => match s.clip(*track) {
Some(clip) => format!("T{track} S{scene} C{}", &clip.read().unwrap().name),
None => format!("T{track} S{scene}: Empty")
},
_ => format!("T{track} S{scene}: Empty"),
},
_ => todo!()
}).into()
}
}
impl HasSelection for Tek {
fn selected (&self) -> &Selection { &self.selected }
fn selected_mut (&mut self) -> &mut Selection { &mut self.selected }
}