wip: refactor pt.41 (52e)

This commit is contained in:
🪞👃🪞 2024-11-15 20:58:16 +01:00
parent 8856353eab
commit 79895fe3f6
4 changed files with 133 additions and 80 deletions

View file

@ -12,6 +12,14 @@ impl TryFrom<&Arc<RwLock<JackClient>>> for ArrangerApp<Tui> {
transport: jack.read().unwrap().transport(),
clock: Arc::new(Clock::from(Instant::default())),
jack: jack.clone(),
sequencer: SequencerView::from(&model.sequencer),
split: 20,
selected: ArrangerSelection::Clip(0, 0),
mode: ArrangerMode::Vertical(2),
color: Color::Rgb(28, 35, 25).into(),
size: Measure::new(),
focused: false,
entered: false,
}.into(), None, None))
}
}
@ -40,6 +48,7 @@ pub type ArrangerAppCommand = AppViewCommand<ArrangerViewCommand>;
#[derive(Clone, Debug)]
pub enum ArrangerViewCommand {
Clear,
Scene(ArrangerSceneCommand),
Track(ArrangerTrackCommand),
Clip(ArrangerClipCommand),
@ -69,7 +78,7 @@ impl InputToCommand<Tui, ArrangerApp<Tui>> for ArrangerAppCommand {
key!(KeyCode::Enter) => Self::Focus(Enter),
key!(KeyCode::Esc) => Self::Focus(Exit),
key!(KeyCode::Char(' ')) => {
Self::App(Transport(TransportCommand::Play(None)))
Self::App(Playhead(PlayheadCommand::Play(None)))
},
_ => Self::App(match view.focused() {
Content(ArrangerViewFocus::Transport) => Transport(
@ -87,8 +96,7 @@ impl InputToCommand<Tui, ArrangerApp<Tui>> for ArrangerAppCommand {
)
},
Content(ArrangerViewFocus::Arranger) => {
use ArrangerSelection as Focus;
use ArrangerCommand as Model;
use ArrangerSelection as Select;
use ArrangerTrackCommand as Track;
use ArrangerClipCommand as Clip;
use ArrangerSceneCommand as Scene;
@ -100,31 +108,31 @@ impl InputToCommand<Tui, ArrangerApp<Tui>> for ArrangerAppCommand {
// FIXME: boundary conditions
key!(KeyCode::Up) => match view.selected {
ArrangerSelection::Mix => return None,
ArrangerSelection::Track(t) => return None,
ArrangerSelection::Scene(s) => Select(Focus::Scene(s - 1)),
ArrangerSelection::Clip(t, s) => Select(Focus::Clip(t, s - 1)),
Select::Mix => return None,
Select::Track(t) => return None,
Select::Scene(s) => Select(Select::Scene(s - 1)),
Select::Clip(t, s) => Select(Select::Clip(t, s - 1)),
},
key!(KeyCode::Down) => match view.selected {
ArrangerSelection::Mix => Select(Focus::Scene(0)),
ArrangerSelection::Track(t) => Select(Focus::Clip(t, 0)),
ArrangerSelection::Scene(s) => Select(Focus::Scene(s + 1)),
ArrangerSelection::Clip(t, s) => Select(Focus::Clip(t, s + 1)),
Select::Mix => Select(Select::Scene(0)),
Select::Track(t) => Select(Select::Clip(t, 0)),
Select::Scene(s) => Select(Select::Scene(s + 1)),
Select::Clip(t, s) => Select(Select::Clip(t, s + 1)),
},
key!(KeyCode::Left) => match view.selected {
ArrangerSelection::Mix => return None,
ArrangerSelection::Track(t) => Select(Focus::Track(t - 1)),
ArrangerSelection::Scene(s) => return None,
ArrangerSelection::Clip(t, s) => Select(Focus::Clip(t - 1, s)),
Select::Mix => return None,
Select::Track(t) => Select(Select::Track(t - 1)),
Select::Scene(s) => return None,
Select::Clip(t, s) => Select(Select::Clip(t - 1, s)),
},
key!(KeyCode::Right) => match view.selected {
ArrangerSelection::Mix => return None,
ArrangerSelection::Track(t) => Select(Focus::Track(t + 1)),
ArrangerSelection::Scene(s) => Select(Focus::Clip(0, s)),
ArrangerSelection::Clip(t, s) => Select(Focus::Clip(t, s - 1)),
Select::Mix => return None,
Select::Track(t) => Select(Select::Track(t + 1)),
Select::Scene(s) => Select(Select::Clip(0, s)),
Select::Clip(t, s) => Select(Select::Clip(t, s - 1)),
},
key!(KeyCode::Char('+')) => Zoom(0),
@ -138,56 +146,56 @@ impl InputToCommand<Tui, ArrangerApp<Tui>> for ArrangerAppCommand {
key!(KeyCode::Char('`')) => { todo!("toggle view mode") },
key!(KeyCode::Char(',')) => match view.selected {
ArrangerSelection::Mix => Zoom(0),
ArrangerSelection::Track(t) => Track(Track::Swap(t, t - 1)),
ArrangerSelection::Scene(s) => Scene(Scene::Swap(s, s - 1)),
ArrangerSelection::Clip(t, s) => Clip(Clip::Set(t, s, None)),
Select::Mix => Zoom(0),
Select::Track(t) => Track(Track::Swap(t, t - 1)),
Select::Scene(s) => Scene(Scene::Swap(s, s - 1)),
Select::Clip(t, s) => Clip(Clip::Set(t, s, None)),
},
key!(KeyCode::Char('.')) => match view.selected {
ArrangerSelection::Mix => Zoom(0),
ArrangerSelection::Track(t) => Track(Track::Swap(t, t + 1)),
ArrangerSelection::Scene(s) => Scene(Scene::Swap(s, s + 1)),
ArrangerSelection::Clip(t, s) => Clip(Clip::Set(t, s, None)),
Select::Mix => Zoom(0),
Select::Track(t) => Track(Track::Swap(t, t + 1)),
Select::Scene(s) => Scene(Scene::Swap(s, s + 1)),
Select::Clip(t, s) => Clip(Clip::Set(t, s, None)),
},
key!(KeyCode::Char('<')) => match view.selected {
ArrangerSelection::Mix => Zoom(0),
ArrangerSelection::Track(t) => Track(Track::Swap(t, t - 1)),
ArrangerSelection::Scene(s) => Scene(Scene::Swap(s, s - 1)),
ArrangerSelection::Clip(t, s) => Clip(Clip::Set(t, s, None)),
Select::Mix => Zoom(0),
Select::Track(t) => Track(Track::Swap(t, t - 1)),
Select::Scene(s) => Scene(Scene::Swap(s, s - 1)),
Select::Clip(t, s) => Clip(Clip::Set(t, s, None)),
},
key!(KeyCode::Char('>')) => match view.selected {
ArrangerSelection::Mix => Zoom(0),
ArrangerSelection::Track(t) => Track(Track::Swap(t, t + 1)),
ArrangerSelection::Scene(s) => Scene(Scene::Swap(s, s + 1)),
ArrangerSelection::Clip(t, s) => Clip(Clip::Set(t, s, None)),
Select::Mix => Zoom(0),
Select::Track(t) => Track(Track::Swap(t, t + 1)),
Select::Scene(s) => Scene(Scene::Swap(s, s + 1)),
Select::Clip(t, s) => Clip(Clip::Set(t, s, None)),
},
key!(KeyCode::Enter) => match view.selected {
ArrangerSelection::Mix => return None,
ArrangerSelection::Track(t) => return None,
ArrangerSelection::Scene(s) => Scene(Scene::Play(s)),
ArrangerSelection::Clip(t, s) => return None,
Select::Mix => return None,
Select::Track(t) => return None,
Select::Scene(s) => Scene(Scene::Play(s)),
Select::Clip(t, s) => return None,
},
key!(KeyCode::Delete) => match view.selected {
ArrangerSelection::Mix => Edit(Model::Clear),
ArrangerSelection::Track(t) => Track(Track::Delete(t)),
ArrangerSelection::Scene(s) => Scene(Scene::Delete(s)),
ArrangerSelection::Clip(t, s) => Clip(Clip::Set(t, s, None)),
Select::Mix => Clear,
Select::Track(t) => Track(Track::Delete(t)),
Select::Scene(s) => Scene(Scene::Delete(s)),
Select::Clip(t, s) => Clip(Clip::Set(t, s, None)),
},
key!(KeyCode::Char('c')) => Clip(Clip::RandomColor),
key!(KeyCode::Char('s')) => match view.selected {
ArrangerSelection::Clip(t, s) => Clip(Clip::Set(t, s, None)),
Select::Clip(t, s) => Clip(Clip::Set(t, s, None)),
_ => return None,
},
key!(KeyCode::Char('g')) => match view.selected {
ArrangerSelection::Clip(t, s) => Clip(Clip::Get(t, s)),
Select::Clip(t, s) => Clip(Clip::Get(t, s)),
_ => return None,
},
@ -275,9 +283,15 @@ impl HasJack for ArrangerView<Tui> {
}
}
impl HasClock for ArrangerView<Tui> {
fn clock (&self) -> &Arc<Clock> {
&self.transport.clock()
impl ClockApi for ArrangerView<Tui> {
fn current (&self) -> &Instant {
&self.current
}
fn quant (&self) -> &Quantize {
&self.quant
}
fn sync (&self) -> &LaunchSync {
&self.sync
}
}
@ -302,10 +316,10 @@ impl HasTracks<ArrangerTrack> for ArrangerView<Tui> {
{
let name = name.map_or_else(||self.track_default_name(), |x|x.to_string());
let track = ArrangerTrack {
width: name.len() + 2,
color: color.unwrap_or_else(||ItemColor::random()),
player: MIDIPlayer::new(&self.jack(), &self.clock(), name.as_str())?,
name: Arc::new(name.into()),
color: color.unwrap_or_else(||ItemColor::random()),
width: name.len() + 2,
//player: MIDIPlayer::new(&self.jack(), &self.clock(), name.as_str())?,
};
self.tracks_mut().push(track);
let index = self.tracks().len() - 1;
@ -389,24 +403,6 @@ pub enum ArrangerStatusBar {
PhraseEdit,
}
impl<E: Engine> From<ArrangerModel> for ArrangerView<E> {
fn from (model: ArrangerModel) -> Self {
let mut view = Self {
model,
sequencer: SequencerView::from(&model.sequencer),
split: 20,
selected: ArrangerSelection::Clip(0, 0),
mode: ArrangerMode::Vertical(2),
color: Color::Rgb(28, 35, 25).into(),
size: Measure::new(),
focused: false,
entered: false,
};
//view.update_focus();
view
}
}
/// Arranger display mode can be cycled
impl ArrangerMode {
/// Cycle arranger display mode
@ -1380,7 +1376,17 @@ pub struct ArrangerScene {
pub color: ItemColor,
}
impl ArrangerSceneApi for ArrangerTrack {}
impl ArrangerSceneApi for ArrangerTrack {
fn name (&self) -> &Arc<RwLock<String>> {
&self.name
}
fn clips (&self) -> &Vec<Option<Arc<RwLock<Phrase>>>> {
&self.clips
}
fn color (&self) -> ItemColor {
self.color
}
}
#[derive(Debug)]
pub struct ArrangerTrack {
@ -1416,4 +1422,36 @@ pub struct ArrangerTrack {
notes_out: Arc<RwLock<[bool; 128]>>,
}
impl ArrangerTrackApi for ArrangerTrack {}
impl ArrangerTrackApi for ArrangerTrack {
/// Name of track
fn name (&self) -> &Arc<RwLock<String>> {
&self.name
}
/// Preferred width of track column
fn width (&self) -> usize {
self.width
}
/// Preferred width of track column
fn width_mut (&mut self) -> &mut usize {
&mut self.width
}
/// Identifying color of track
fn color (&self) -> ItemColor {
self.color
}
}
impl HasMidiBuffer for ArrangerTrack {
}
impl HasPhrase for ArrangerTrack {
}
impl MidiInputApi for ArrangerTrack {
}
impl MidiOutputApi for ArrangerTrack {
}
impl PlayerApi for ArrangerTrack {
}