mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
extract arranger_command and remove arranger_clip
This commit is contained in:
parent
9bed07451f
commit
9776d3e665
5 changed files with 198 additions and 202 deletions
|
|
@ -26,12 +26,12 @@ mod app_arranger; pub(crate) use app_arranger::*;
|
|||
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
mod arranger_clip; pub(crate) use arranger_clip::*;
|
||||
mod arranger_scene; pub(crate) use arranger_scene::*;
|
||||
mod arranger_select; pub(crate) use arranger_select::*;
|
||||
mod arranger_track; pub(crate) use arranger_track::*;
|
||||
mod arranger_mode_h;
|
||||
mod arranger_mode_v; pub(crate) use arranger_mode_v::*;
|
||||
mod arranger_command; pub(crate) use arranger_command::*;
|
||||
mod arranger_scene; pub(crate) use arranger_scene::*;
|
||||
mod arranger_select; pub(crate) use arranger_select::*;
|
||||
mod arranger_track; pub(crate) use arranger_track::*;
|
||||
mod arranger_mode_h;
|
||||
mod arranger_mode_v; pub(crate) use arranger_mode_v::*;
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ mod piano_horizontal; pub(crate) use piano_horizontal::*;
|
|||
mod phrase_length; pub(crate) use phrase_length::*;
|
||||
mod phrase_rename; pub(crate) use phrase_rename::*;
|
||||
mod phrase_list; pub(crate) use phrase_list::*;
|
||||
mod port_select;
|
||||
mod port_select;
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
use crate::*;
|
||||
use ClockCommand::{Play, Pause};
|
||||
use KeyCode::{Char, Delete, Tab};
|
||||
/// Root view for standalone `tek_arranger`
|
||||
pub struct ArrangerTui {
|
||||
jack: Arc<RwLock<JackClient>>,
|
||||
|
|
@ -163,141 +161,6 @@ has_clock!(|self: ArrangerTui|&self.clock);
|
|||
has_phrases!(|self: ArrangerTui|self.phrases.phrases);
|
||||
has_editor!(|self: ArrangerTui|self.editor);
|
||||
handle!(<Tui>|self: ArrangerTui, input|ArrangerCommand::execute_with_state(self, input));
|
||||
#[derive(Clone, Debug)] pub enum ArrangerCommand {
|
||||
Undo,
|
||||
Redo,
|
||||
Clear,
|
||||
StopAll,
|
||||
Color(ItemPalette),
|
||||
Clock(ClockCommand),
|
||||
Scene(ArrangerSceneCommand),
|
||||
Track(ArrangerTrackCommand),
|
||||
Clip(ArrangerClipCommand),
|
||||
Select(ArrangerSelection),
|
||||
Zoom(usize),
|
||||
Phrases(PhrasesCommand),
|
||||
Editor(PhraseCommand),
|
||||
ShowPool(bool),
|
||||
Put(usize, usize, Option<Arc<RwLock<Phrase>>>),
|
||||
}
|
||||
input_to_command!(ArrangerCommand: <Tui>|state: ArrangerTui, input|{
|
||||
use ArrangerSelection as Selected;
|
||||
use ArrangerCommand::*;
|
||||
// WSAD navigation, Q launches, E edits, PgUp/Down pool, Arrows editor
|
||||
match input.event() {
|
||||
// TODO: u: undo
|
||||
key_pat!(Char('u')) => { todo!("undo") },
|
||||
// TODO: Shift-U: redo
|
||||
key_pat!(Char('U')) => { todo!("redo") },
|
||||
// TODO: k: toggle on-screen keyboard
|
||||
key_pat!(Ctrl-Char('k')) => { todo!("keyboard") },
|
||||
// Transport: Play/pause
|
||||
key_pat!(Char(' ')) =>
|
||||
Self::Clock(if state.clock().is_stopped() { Play(None) } else { Pause(None) }),
|
||||
// Transport: Play from start or rewind to start
|
||||
key_pat!(Shift-Char(' ')) =>
|
||||
Self::Clock(if state.clock().is_stopped() { Play(Some(0)) } else { Pause(Some(0)) }),
|
||||
key_pat!(Char('e')) =>
|
||||
Self::Editor(PhraseCommand::Show(Some(state.phrases.phrase().clone()))),
|
||||
key_pat!(Char('l')) =>
|
||||
Self::Clip(ArrangerClipCommand::SetLoop(false)),
|
||||
key_pat!(Ctrl-Char('a')) =>
|
||||
Self::Scene(ArrangerSceneCommand::Add),
|
||||
key_pat!(Ctrl-Char('t')) =>
|
||||
Self::Track(ArrangerTrackCommand::Add),
|
||||
key_pat!(Char('0')) => match state.selected() {
|
||||
Selected::Mix => StopAll,
|
||||
Selected::Track(_t) => return None,
|
||||
Selected::Scene(_s) => return None,
|
||||
Selected::Clip(_t, _s) => return None,
|
||||
},
|
||||
// Tab: Toggle visibility of phrase pool column
|
||||
key_pat!(Tab) =>
|
||||
Self::ShowPool(!state.show_pool),
|
||||
_ => {
|
||||
let t_len = state.tracks.len();
|
||||
let s_len = state.scenes.len();
|
||||
match state.selected() {
|
||||
Selected::Clip(t, s) => match input.event() {
|
||||
key_pat!(Char('g')) => Some(Self::Phrases(PhrasesCommand::Select(0))),
|
||||
key_pat!(Char('p')) => Some(Self::Put(t, s, Some(state.phrases.phrase().clone()))),
|
||||
key_pat!(Char('q')) => { todo!("enqueue") },
|
||||
_ => to_arranger_clip_command(input, t, t_len, s, s_len)
|
||||
},
|
||||
Selected::Scene(s) => to_arranger_scene_command(input, s, s_len),
|
||||
Selected::Track(t) => to_arranger_track_command(input, t, t_len),
|
||||
Selected::Mix => match input.event() {
|
||||
// 0: Enqueue phrase 0 (stop all)
|
||||
key_pat!(Char('0')) => Some(Self::StopAll),
|
||||
key_pat!(Char('s')) => Some(Self::Select(Selected::Scene(0))),
|
||||
key_pat!(Char('d')) => Some(Self::Select(Selected::Track(0))),
|
||||
key_pat!(Delete) => Some(Self::Clear),
|
||||
key_pat!(Char('c')) => Some(Self::Color(ItemPalette::random())),
|
||||
_ => None
|
||||
},
|
||||
}
|
||||
}.or_else(||if let Some(command) = PhraseCommand::input_to_command(&state.editor, input) {
|
||||
Some(Self::Editor(command))
|
||||
} else if let Some(command) = PhrasesCommand::input_to_command(&state.phrases, input) {
|
||||
Some(Self::Phrases(command))
|
||||
} else {
|
||||
None
|
||||
})?
|
||||
}
|
||||
});
|
||||
command!(|self:ArrangerCommand,state:ArrangerTui|{
|
||||
use ArrangerCommand::*;
|
||||
match self {
|
||||
Scene(cmd) => cmd.execute(state)?.map(Scene),
|
||||
Track(cmd) => cmd.execute(state)?.map(Track),
|
||||
Clip(cmd) => cmd.execute(state)?.map(Clip),
|
||||
Editor(cmd) => cmd.execute(&mut state.editor)?.map(Editor),
|
||||
Clock(cmd) => cmd.execute(state)?.map(Clock),
|
||||
Zoom(_) => { todo!(); },
|
||||
Select(selected) => {
|
||||
*state.selected_mut() = selected;
|
||||
None
|
||||
},
|
||||
Color(palette) => {
|
||||
let old = state.color;
|
||||
state.color = palette;
|
||||
Some(Color(old))
|
||||
},
|
||||
ShowPool(show) => {
|
||||
state.show_pool = show;
|
||||
None
|
||||
},
|
||||
Phrases(cmd) => {
|
||||
let mut default = |cmd: PhrasesCommand|cmd
|
||||
.execute(&mut state.phrases)
|
||||
.map(|x|x.map(Phrases));
|
||||
match cmd {
|
||||
// autoselect: automatically load selected phrase in editor
|
||||
PhrasesCommand::Select(_) => {
|
||||
let undo = default(cmd)?;
|
||||
state.editor.set_phrase(Some(state.phrases.phrase()));
|
||||
undo
|
||||
},
|
||||
// update color in all places simultaneously
|
||||
PhrasesCommand::Phrase(PhrasePoolCommand::SetColor(index, _)) => {
|
||||
let undo = default(cmd)?;
|
||||
state.editor.set_phrase(Some(state.phrases.phrase()));
|
||||
undo
|
||||
},
|
||||
_ => default(cmd)?
|
||||
}
|
||||
},
|
||||
Undo => { todo!() },
|
||||
Redo => { todo!() },
|
||||
Clear => { todo!() },
|
||||
StopAll => { todo!() },
|
||||
Put(track, scene, phrase) => {
|
||||
let old = state.scenes[scene].clips[track].clone();
|
||||
state.scenes[scene].clips[track] = phrase;
|
||||
Some(Put(track, scene, old))
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
/// Display mode of arranger
|
||||
#[derive(Clone, PartialEq)]
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
use crate::*;
|
||||
|
||||
pub fn to_arranger_clip_command (input: &TuiInput, t: usize, len_t: usize, s: usize, len_s: usize) -> Option<ArrangerCommand> {
|
||||
use KeyCode::{Char, Delete};
|
||||
use ArrangerCommand as Cmd;
|
||||
use ArrangerSelection as Select;
|
||||
use ArrangerClipCommand as Clip;
|
||||
Some(match input.event() {
|
||||
key_pat!(Char('w')) => Cmd::Select(if s > 0 { Select::Clip(t, s - 1) } else { Select::Track(t) }),
|
||||
key_pat!(Char('s')) => Cmd::Select(Select::Clip(t, (s + 1).min(len_s.saturating_sub(1)))),
|
||||
key_pat!(Char('a')) => Cmd::Select(if t > 0 { Select::Clip(t - 1, s) } else { Select::Scene(s) }),
|
||||
key_pat!(Char('d')) => Cmd::Select(Select::Clip((t + 1).min(len_t.saturating_sub(1)), s)),
|
||||
key_pat!(Char(',')) => Cmd::Clip(Clip::Set(t, s, None)),
|
||||
key_pat!(Char('.')) => Cmd::Clip(Clip::Set(t, s, None)),
|
||||
key_pat!(Char('<')) => Cmd::Clip(Clip::Set(t, s, None)),
|
||||
key_pat!(Char('>')) => Cmd::Clip(Clip::Set(t, s, None)),
|
||||
key_pat!(Delete) => Cmd::Clip(Clip::Set(t, s, None)),
|
||||
//key_pat!(Char('c')) => Cmd::Clip(Clip::Color(t, s, ItemPalette::random())),
|
||||
//key_pat!(Char('g')) => Cmd::Clip(Clip(Clip::Get(t, s))),
|
||||
//key_pat!(Char('s')) => Cmd::Clip(Clip(Clip::Set(t, s))),
|
||||
_ => return None
|
||||
})
|
||||
}
|
||||
|
||||
command!(|self:ArrangerClipCommand, _state:ArrangerTui|match self {
|
||||
_ => None
|
||||
});
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ArrangerClipCommand {
|
||||
Play,
|
||||
Get(usize, usize),
|
||||
Set(usize, usize, Option<Arc<RwLock<Phrase>>>),
|
||||
Edit(Option<Arc<RwLock<Phrase>>>),
|
||||
SetLoop(bool),
|
||||
RandomColor,
|
||||
}
|
||||
191
crates/tek/src/tui/arranger_command.rs
Normal file
191
crates/tek/src/tui/arranger_command.rs
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
use crate::*;
|
||||
use ClockCommand::{Play, Pause};
|
||||
use KeyCode::{Char, Delete, Tab};
|
||||
|
||||
#[derive(Clone, Debug)] pub enum ArrangerCommand {
|
||||
Undo,
|
||||
Redo,
|
||||
Clear,
|
||||
StopAll,
|
||||
Color(ItemPalette),
|
||||
Clock(ClockCommand),
|
||||
Scene(ArrangerSceneCommand),
|
||||
Track(ArrangerTrackCommand),
|
||||
Clip(ArrangerClipCommand),
|
||||
Select(ArrangerSelection),
|
||||
Zoom(usize),
|
||||
Phrases(PhrasesCommand),
|
||||
Editor(PhraseCommand),
|
||||
ShowPool(bool),
|
||||
Put(usize, usize, Option<Arc<RwLock<Phrase>>>),
|
||||
}
|
||||
input_to_command!(ArrangerCommand: <Tui>|state: ArrangerTui, input|{
|
||||
use ArrangerSelection as Selected;
|
||||
use ArrangerSceneCommand as Scene;
|
||||
use ArrangerTrackCommand as Track;
|
||||
use ArrangerClipCommand as Clip;
|
||||
// WSAD navigation, Q launches, E edits, PgUp/Down pool, Arrows editor
|
||||
match input.event() {
|
||||
// TODO: u: undo
|
||||
key_pat!(Char('u')) => { todo!("undo") },
|
||||
// TODO: Shift-U: redo
|
||||
key_pat!(Char('U')) => { todo!("redo") },
|
||||
// TODO: k: toggle on-screen keyboard
|
||||
key_pat!(Ctrl-Char('k')) => { todo!("keyboard") },
|
||||
// Transport: Play/pause
|
||||
key_pat!(Char(' ')) =>
|
||||
Self::Clock(if state.clock().is_stopped() { Play(None) } else { Pause(None) }),
|
||||
// Transport: Play from start or rewind to start
|
||||
key_pat!(Shift-Char(' ')) =>
|
||||
Self::Clock(if state.clock().is_stopped() { Play(Some(0)) } else { Pause(Some(0)) }),
|
||||
key_pat!(Char('e')) =>
|
||||
Self::Editor(PhraseCommand::Show(Some(state.phrases.phrase().clone()))),
|
||||
key_pat!(Char('l')) =>
|
||||
Self::Clip(ArrangerClipCommand::SetLoop(false)),
|
||||
key_pat!(Ctrl-Char('a')) =>
|
||||
Self::Scene(ArrangerSceneCommand::Add),
|
||||
key_pat!(Ctrl-Char('t')) =>
|
||||
Self::Track(ArrangerTrackCommand::Add),
|
||||
key_pat!(Char('0')) => match state.selected() {
|
||||
Selected::Mix => Self::StopAll,
|
||||
Selected::Track(_t) => return None,
|
||||
Selected::Scene(_s) => return None,
|
||||
Selected::Clip(_t, _s) => return None,
|
||||
},
|
||||
// Tab: Toggle visibility of phrase pool column
|
||||
key_pat!(Tab) =>
|
||||
Self::ShowPool(!state.show_pool),
|
||||
_ => {
|
||||
let t_len = state.tracks.len();
|
||||
let s_len = state.scenes.len();
|
||||
match state.selected() {
|
||||
Selected::Clip(t, s) => match input.event() {
|
||||
key_pat!(Char('w')) => Some(Self::Select(if s > 0 { Selected::Clip(t, s - 1) } else { Selected::Track(t) })),
|
||||
key_pat!(Char('s')) => Some(Self::Select(Selected::Clip(t, (s + 1).min(s_len.saturating_sub(1))))),
|
||||
key_pat!(Char('a')) => Some(Self::Select(if t > 0 { Selected::Clip(t - 1, s) } else { Selected::Scene(s) })),
|
||||
key_pat!(Char('d')) => Some(Self::Select(Selected::Clip((t + 1).min(t_len.saturating_sub(1)), s))),
|
||||
key_pat!(Char(',')) => Some(Self::Clip(Clip::Set(t, s, None))),
|
||||
key_pat!(Char('.')) => Some(Self::Clip(Clip::Set(t, s, None))),
|
||||
key_pat!(Char('<')) => Some(Self::Clip(Clip::Set(t, s, None))),
|
||||
key_pat!(Char('>')) => Some(Self::Clip(Clip::Set(t, s, None))),
|
||||
key_pat!(Char('g')) => Some(Self::Phrases(PhrasesCommand::Select(0))),
|
||||
key_pat!(Char('p')) => Some(Self::Put(t, s, Some(state.phrases.phrase().clone()))),
|
||||
key_pat!(Char('q')) => { todo!("enqueue") },
|
||||
key_pat!(Delete) => Some(Self::Clip(Clip::Set(t, s, None))),
|
||||
//key_pat!(Char('c')) => Cmd::Clip(Clip::Color(t, s, ItemPalette::random())),
|
||||
//key_pat!(Char('g')) => Cmd::Clip(Clip(Clip::Get(t, s))),
|
||||
//key_pat!(Char('s')) => Cmd::Clip(Clip(Clip::Set(t, s))),
|
||||
_ => None
|
||||
},
|
||||
Selected::Scene(s) => match input.event() {
|
||||
key_pat!(Char('w')) => Some(Self::Select(if s > 0 { Selected::Scene(s - 1) } else { Selected::Mix })),
|
||||
key_pat!(Char('s')) => Some(Self::Select(Selected::Scene((s + 1).min(s_len.saturating_sub(1))))),
|
||||
key_pat!(Char('d')) => Some(Self::Select(Selected::Clip(0, s))),
|
||||
key_pat!(Char(',')) => Some(Self::Scene(Scene::Swap(s, s - 1))),
|
||||
key_pat!(Char('.')) => Some(Self::Scene(Scene::Swap(s, s + 1))),
|
||||
key_pat!(Char('<')) => Some(Self::Scene(Scene::Swap(s, s - 1))),
|
||||
key_pat!(Char('>')) => Some(Self::Scene(Scene::Swap(s, s + 1))),
|
||||
key_pat!(Char('q')) => Some(Self::Scene(Scene::Play(s))),
|
||||
key_pat!(Char('c')) => Some(Self::Scene(Scene::SetColor(s, ItemPalette::random()))),
|
||||
key_pat!(Delete) => Some(Self::Scene(Scene::Delete(s))),
|
||||
//key_pat!(Char('c')) => Cmd::Track(Scene::Color(s, ItemPalette::random())),
|
||||
_ => None
|
||||
},
|
||||
Selected::Track(t) => match input.event() {
|
||||
key_pat!(Char('s')) => Some(Self::Select(Selected::Clip(t, 0))),
|
||||
key_pat!(Char('a')) => Some(Self::Select(if t > 0 { Selected::Track(t - 1) } else { Selected::Mix })),
|
||||
key_pat!(Char('d')) => Some(Self::Select(Selected::Track((t + 1).min(t_len.saturating_sub(1))))),
|
||||
key_pat!(Char('c')) => Some(Self::Track(Track::SetColor(t, ItemPalette::random()))),
|
||||
key_pat!(Char(',')) => Some(Self::Track(Track::Swap(t, t - 1))),
|
||||
key_pat!(Char('.')) => Some(Self::Track(Track::Swap(t, t + 1))),
|
||||
key_pat!(Char('<')) => Some(Self::Track(Track::Swap(t, t - 1))),
|
||||
key_pat!(Char('>')) => Some(Self::Track(Track::Swap(t, t + 1))),
|
||||
key_pat!(Delete) => Some(Self::Track(Track::Delete(t))),
|
||||
//key_pat!(Char('c')) => Cmd::Track(Track::Color(t, ItemPalette::random())),
|
||||
_ => return None
|
||||
},
|
||||
Selected::Mix => match input.event() {
|
||||
// 0: Enqueue phrase 0 (stop all)
|
||||
key_pat!(Char('0')) => Some(Self::StopAll),
|
||||
key_pat!(Char('s')) => Some(Self::Select(Selected::Scene(0))),
|
||||
key_pat!(Char('d')) => Some(Self::Select(Selected::Track(0))),
|
||||
key_pat!(Delete) => Some(Self::Clear),
|
||||
key_pat!(Char('c')) => Some(Self::Color(ItemPalette::random())),
|
||||
_ => None
|
||||
},
|
||||
}
|
||||
}.or_else(||if let Some(command) = PhraseCommand::input_to_command(&state.editor, input) {
|
||||
Some(Self::Editor(command))
|
||||
} else if let Some(command) = PhrasesCommand::input_to_command(&state.phrases, input) {
|
||||
Some(Self::Phrases(command))
|
||||
} else {
|
||||
None
|
||||
})?
|
||||
}
|
||||
});
|
||||
command!(|self:ArrangerCommand,state:ArrangerTui|{
|
||||
use ArrangerCommand::*;
|
||||
match self {
|
||||
Scene(cmd) => cmd.execute(state)?.map(Scene),
|
||||
Track(cmd) => cmd.execute(state)?.map(Track),
|
||||
Clip(cmd) => cmd.execute(state)?.map(Clip),
|
||||
Editor(cmd) => cmd.execute(&mut state.editor)?.map(Editor),
|
||||
Clock(cmd) => cmd.execute(state)?.map(Clock),
|
||||
Zoom(_) => { todo!(); },
|
||||
Select(selected) => {
|
||||
*state.selected_mut() = selected;
|
||||
None
|
||||
},
|
||||
Color(palette) => {
|
||||
let old = state.color;
|
||||
state.color = palette;
|
||||
Some(Color(old))
|
||||
},
|
||||
ShowPool(show) => {
|
||||
state.show_pool = show;
|
||||
None
|
||||
},
|
||||
Phrases(cmd) => {
|
||||
let mut default = |cmd: PhrasesCommand|cmd
|
||||
.execute(&mut state.phrases)
|
||||
.map(|x|x.map(Phrases));
|
||||
match cmd {
|
||||
// autoselect: automatically load selected phrase in editor
|
||||
PhrasesCommand::Select(_) => {
|
||||
let undo = default(cmd)?;
|
||||
state.editor.set_phrase(Some(state.phrases.phrase()));
|
||||
undo
|
||||
},
|
||||
// update color in all places simultaneously
|
||||
PhrasesCommand::Phrase(PhrasePoolCommand::SetColor(index, _)) => {
|
||||
let undo = default(cmd)?;
|
||||
state.editor.set_phrase(Some(state.phrases.phrase()));
|
||||
undo
|
||||
},
|
||||
_ => default(cmd)?
|
||||
}
|
||||
},
|
||||
Undo => { todo!() },
|
||||
Redo => { todo!() },
|
||||
Clear => { todo!() },
|
||||
StopAll => { todo!() },
|
||||
Put(track, scene, phrase) => {
|
||||
let old = state.scenes[scene].clips[track].clone();
|
||||
state.scenes[scene].clips[track] = phrase;
|
||||
Some(Put(track, scene, old))
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ArrangerClipCommand {
|
||||
Play,
|
||||
Get(usize, usize),
|
||||
Set(usize, usize, Option<Arc<RwLock<Phrase>>>),
|
||||
Edit(Option<Arc<RwLock<Phrase>>>),
|
||||
SetLoop(bool),
|
||||
SetColor(ItemPalette),
|
||||
}
|
||||
command!(|self:ArrangerClipCommand, _state:ArrangerTui|match self {
|
||||
_ => None
|
||||
});
|
||||
|
|
@ -3,33 +3,12 @@ use crate::*;
|
|||
pub enum ArrangerSceneCommand {
|
||||
Add,
|
||||
Delete(usize),
|
||||
RandomColor,
|
||||
Play(usize),
|
||||
Swap(usize, usize),
|
||||
SetSize(usize),
|
||||
SetZoom(usize),
|
||||
SetColor(usize, ItemPalette),
|
||||
}
|
||||
pub fn to_arranger_scene_command (input: &TuiInput, s: usize, len: usize) -> Option<ArrangerCommand> {
|
||||
use KeyCode::{Char, Delete};
|
||||
use ArrangerCommand as Cmd;
|
||||
use ArrangerSelection as Select;
|
||||
use ArrangerSceneCommand as Scene;
|
||||
Some(match input.event() {
|
||||
key_pat!(Char('w')) => Cmd::Select(if s > 0 { Select::Scene(s - 1) } else { Select::Mix }),
|
||||
key_pat!(Char('s')) => Cmd::Select(Select::Scene((s + 1).min(len.saturating_sub(1)))),
|
||||
key_pat!(Char('d')) => Cmd::Select(Select::Clip(0, s)),
|
||||
key_pat!(Char(',')) => Cmd::Scene(Scene::Swap(s, s - 1)),
|
||||
key_pat!(Char('.')) => Cmd::Scene(Scene::Swap(s, s + 1)),
|
||||
key_pat!(Char('<')) => Cmd::Scene(Scene::Swap(s, s - 1)),
|
||||
key_pat!(Char('>')) => Cmd::Scene(Scene::Swap(s, s + 1)),
|
||||
key_pat!(Char('q')) => Cmd::Scene(Scene::Play(s)),
|
||||
key_pat!(Char('c')) => Cmd::Scene(Scene::SetColor(s, ItemPalette::random())),
|
||||
key_pat!(Delete) => Cmd::Scene(Scene::Delete(s)),
|
||||
//key_pat!(Char('c')) => Cmd::Track(Scene::Color(s, ItemPalette::random())),
|
||||
_ => return None
|
||||
})
|
||||
}
|
||||
command!(|self:ArrangerSceneCommand,state:ArrangerTui|match self {
|
||||
//Self::Delete(index) => { state.scene_del(index); },
|
||||
Self::SetColor(index, color) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue