tek/crates/tek_tui/src/tui_arranger_foc.rs

171 lines
5.8 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use crate::*;
/// Sections in the arranger app that may be focused
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum ArrangerViewFocus {
/// The transport (toolbar) is focused
Transport,
/// The arrangement (grid) is focused
Arrangement,
/// The phrase list (pool) is focused
PhrasePool,
/// The phrase editor (sequencer) is focused
PhraseEditor,
}
/// Focus layout of arranger app
impl<E: Engine> FocusGrid for ArrangerView<E> {
type Item = ArrangerViewFocus;
fn cursor (&self) -> (usize, usize) { self.focus_cursor }
fn cursor_mut (&mut self) -> &mut (usize, usize) { &mut self.focus_cursor }
fn focus_enter (&mut self) {
let focused = self.focused();
if !self.entered {
self.entered = true;
use ArrangerViewFocus::*;
if let Some(transport) = self.transport.as_ref() {
//transport.write().unwrap().entered = focused == Transport
}
self.arrangement.entered = focused == Arrangement;
self.phrases.write().unwrap().entered = focused == PhrasePool;
self.editor.entered = focused == PhraseEditor;
}
}
fn focus_exit (&mut self) {
if self.entered {
self.entered = false;
self.arrangement.entered = false;
self.editor.entered = false;
self.phrases.write().unwrap().entered = false;
}
}
fn entered (&self) -> Option<ArrangerViewFocus> {
if self.entered {
Some(self.focused())
} else {
None
}
}
fn layout (&self) -> &[&[ArrangerViewFocus]] {
use ArrangerViewFocus::*;
&[
&[Transport, Transport],
&[Arrangement, Arrangement],
&[PhrasePool, PhraseEditor],
]
}
fn update_focus (&mut self) {
use ArrangerViewFocus::*;
let focused = self.focused();
self.arrangement.focused = focused == Arrangement;
self.sequencer.transport.focused = focused == Transport;
self.sequencer.phrases.focused = focused == PhrasePool;
self.sequencer.editor.focused = focused == PhraseEditor;
//self.update_status();
}
}
#[derive(PartialEq, Clone, Copy)]
/// Represents the current user selection in the arranger
pub enum ArrangementEditorFocus {
/// The whole mix is selected
Mix,
/// A track is selected.
Track(usize),
/// A scene is selected.
Scene(usize),
/// A clip (track × scene) is selected.
Clip(usize, usize),
}
/// Focus identification methods
impl ArrangementEditorFocus {
pub fn description <E: Engine> (
&self,
tracks: &Vec<ArrangementTrack>,
scenes: &Vec<ArrangementScene>,
) -> String {
format!("Selected: {}", match self {
Self::Mix => format!("Everything"),
Self::Track(t) => match tracks.get(*t) {
Some(track) => format!("T{t}: {}", &track.name.read().unwrap()),
None => format!("T??"),
},
Self::Scene(s) => match scenes.get(*s) {
Some(scene) => format!("S{s}: {}", &scene.name.read().unwrap()),
None => format!("S??"),
},
Self::Clip(t, s) => match (tracks.get(*t), scenes.get(*s)) {
(Some(_), Some(scene)) => match scene.clip(*t) {
Some(clip) => format!("T{t} S{s} C{}", &clip.read().unwrap().name),
None => format!("T{t} S{s}: Empty")
},
_ => format!("T{t} S{s}: Empty"),
}
})
}
pub fn is_mix (&self) -> bool {
match self { Self::Mix => true, _ => false }
}
pub fn is_track (&self) -> bool {
match self { Self::Track(_) => true, _ => false }
}
pub fn is_scene (&self) -> bool {
match self { Self::Scene(_) => true, _ => false }
}
pub fn is_clip (&self) -> bool {
match self { Self::Clip(_, _) => true, _ => false }
}
pub fn track (&self) -> Option<usize> {
use ArrangementEditorFocus::*;
match self {
Clip(t, _) => Some(*t),
Track(t) => Some(*t),
_ => None
}
}
pub fn scene (&self) -> Option<usize> {
use ArrangementEditorFocus::*;
match self {
Clip(_, s) => Some(*s),
Scene(s) => Some(*s),
_ => None
}
}
}
//pub fn track_next (&mut self, last_track: usize) {
//use ArrangementEditorFocus::*;
//*self = match self {
//Mix => Track(0),
//Track(t) => Track(last_track.min(*t + 1)),
//Scene(s) => Clip(0, *s),
//Clip(t, s) => Clip(last_track.min(*t + 1), *s),
//}
//}
//pub fn track_prev (&mut self) {
//use ArrangementEditorFocus::*;
//*self = match self {
//Mix => Mix,
//Scene(s) => Scene(*s),
//Track(t) => if *t == 0 { Mix } else { Track(*t - 1) },
//Clip(t, s) => if *t == 0 { Scene(*s) } else { Clip(t.saturating_sub(1), *s) }
//}
//}
//pub fn scene_next (&mut self, last_scene: usize) {
//use ArrangementEditorFocus::*;
//*self = match self {
//Mix => Scene(0),
//Track(t) => Clip(*t, 0),
//Scene(s) => Scene(last_scene.min(*s + 1)),
//Clip(t, s) => Clip(*t, last_scene.min(*s + 1)),
//}
//}
//pub fn scene_prev (&mut self) {
//use ArrangementEditorFocus::*;
//*self = match self {
//Mix => Mix,
//Track(t) => Track(*t),
//Scene(s) => if *s == 0 { Mix } else { Scene(*s - 1) },
//Clip(t, s) => if *s == 0 { Track(*t) } else { Clip(*t, s.saturating_sub(1)) }
//}
//}