mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
shorten key bindings
This commit is contained in:
parent
95dd61811e
commit
5ccc55a76f
1 changed files with 197 additions and 253 deletions
|
|
@ -1,250 +1,196 @@
|
|||
use crate::*;
|
||||
|
||||
fn to_focus_command (input: &TuiInput) -> Option<FocusCommand> {
|
||||
use KeyCode::{Tab, BackTab, Up, Down, Left, Right, Enter, Esc};
|
||||
Some(match input.event() {
|
||||
key!(Tab) => FocusCommand::Next,
|
||||
key!(Shift-Tab) => FocusCommand::Prev,
|
||||
key!(BackTab) => FocusCommand::Prev,
|
||||
key!(Shift-BackTab) => FocusCommand::Prev,
|
||||
key!(Up) => FocusCommand::Up,
|
||||
key!(Down) => FocusCommand::Down,
|
||||
key!(Left) => FocusCommand::Left,
|
||||
key!(Right) => FocusCommand::Right,
|
||||
key!(Enter) => FocusCommand::Enter,
|
||||
key!(Esc) => FocusCommand::Exit,
|
||||
_ => return None
|
||||
})
|
||||
}
|
||||
|
||||
impl<T: TransportControl> InputToCommand<Tui, T> for TransportCommand {
|
||||
fn input_to_command (state: &T, input: &TuiInput) -> Option<Self> {
|
||||
use KeyCode::Char;
|
||||
use ClockCommand::{SetBpm, SetQuant, SetSync};
|
||||
use TransportFocus as Focused;
|
||||
use TransportCommand::{Focus, Clock};
|
||||
let focused = state.transport_focused().unwrap();
|
||||
use KeyCode::{Enter, Left, Right, Char};
|
||||
Some(match input.event() {
|
||||
key!(Left) => Focus(FocusCommand::Prev),
|
||||
key!(Right) => Focus(FocusCommand::Next),
|
||||
key!(Char('.')) => match focused {
|
||||
Focused::Bpm => Clock(SetBpm(state.bpm().get() + 1.0)),
|
||||
Focused::Quant => Clock(SetQuant(state.next_quant())),
|
||||
Focused::Sync => Clock(SetSync(state.next_sync())),
|
||||
Focused::PlayPause => Clock(todo!()),
|
||||
Focused::Clock => Clock(todo!()),
|
||||
_ => {todo!()}
|
||||
},
|
||||
key!(Char(',')) => match focused {
|
||||
Focused::Bpm => Clock(SetBpm(state.bpm().get() - 1.0)),
|
||||
Focused::Quant => Clock(SetQuant(state.prev_quant())),
|
||||
Focused::Sync => Clock(SetSync(state.prev_sync())),
|
||||
Focused::PlayPause => Clock(todo!()),
|
||||
Focused::Clock => Clock(todo!()),
|
||||
_ => {todo!()}
|
||||
},
|
||||
key!(Char('>')) => match focused {
|
||||
Focused::Bpm => Clock(SetBpm(state.bpm().get() + 0.001)),
|
||||
Focused::Quant => Clock(SetQuant(state.next_quant())),
|
||||
Focused::Sync => Clock(SetSync(state.next_sync())),
|
||||
Focused::PlayPause => Clock(todo!()),
|
||||
Focused::Clock => Clock(todo!()),
|
||||
_ => {todo!()}
|
||||
},
|
||||
key!(Char('<')) => match focused {
|
||||
Focused::Bpm => Clock(SetBpm(state.bpm().get() - 0.001)),
|
||||
Focused::Quant => Clock(SetQuant(state.prev_quant())),
|
||||
Focused::Sync => Clock(SetSync(state.prev_sync())),
|
||||
Focused::PlayPause => Clock(todo!()),
|
||||
Focused::Clock => Clock(todo!()),
|
||||
_ => {todo!()}
|
||||
},
|
||||
_ => return None
|
||||
key!(Char(' ')) => todo!("toolbar space"),
|
||||
key!(Shift-Char(' ')) => todo!("toolbar shift-space"),
|
||||
_ => match state.transport_focused().unwrap() {
|
||||
TransportFocus::Bpm => match input.event() {
|
||||
key!(Char(',')) => Clock(SetBpm(state.bpm().get() - 1.0)),
|
||||
key!(Char('.')) => Clock(SetBpm(state.bpm().get() + 1.0)),
|
||||
key!(Char('<')) => Clock(SetBpm(state.bpm().get() - 0.001)),
|
||||
key!(Char('>')) => Clock(SetBpm(state.bpm().get() + 0.001)),
|
||||
_ => return None,
|
||||
},
|
||||
TransportFocus::Quant => match input.event() {
|
||||
key!(Char(',')) => Clock(SetQuant(state.prev_quant())),
|
||||
key!(Char('.')) => Clock(SetQuant(state.next_quant())),
|
||||
key!(Char('<')) => Clock(SetQuant(state.prev_quant())),
|
||||
key!(Char('>')) => Clock(SetQuant(state.next_quant())),
|
||||
_ => return None,
|
||||
},
|
||||
TransportFocus::Sync => match input.event() {
|
||||
key!(Char(',')) => Clock(SetSync(state.prev_sync())),
|
||||
key!(Char('.')) => Clock(SetSync(state.next_sync())),
|
||||
key!(Char('<')) => Clock(SetSync(state.prev_sync())),
|
||||
key!(Char('>')) => Clock(SetSync(state.next_sync())),
|
||||
_ => return None,
|
||||
},
|
||||
TransportFocus::Clock => match input.event() {
|
||||
key!(Char(',')) => todo!("transport seek bar"),
|
||||
key!(Char('.')) => todo!("transport seek bar"),
|
||||
key!(Char('<')) => todo!("transport seek beat"),
|
||||
key!(Char('>')) => todo!("transport seek beat"),
|
||||
_ => return None,
|
||||
},
|
||||
TransportFocus::PlayPause => match input.event() {
|
||||
key!(Enter) => todo!("transport play toggle"),
|
||||
key!(Shift-Enter) => todo!("transport shift-play toggle"),
|
||||
_ => return None,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl InputToCommand<Tui, SequencerTui> for SequencerCommand {
|
||||
fn input_to_command (state: &SequencerTui, input: &TuiInput) -> Option<Self> {
|
||||
use FocusCommand::*;
|
||||
use SequencerCommand::*;
|
||||
Some(match input.event() {
|
||||
key!(KeyCode::Tab) => Self::Focus(Next),
|
||||
key!(Shift-KeyCode::Tab) => Self::Focus(Prev),
|
||||
key!(KeyCode::BackTab) => Self::Focus(Prev),
|
||||
key!(Shift-KeyCode::BackTab) => Self::Focus(Prev),
|
||||
key!(KeyCode::Up) => Self::Focus(Up),
|
||||
key!(KeyCode::Down) => Self::Focus(Down),
|
||||
key!(KeyCode::Left) => Self::Focus(Left),
|
||||
key!(KeyCode::Right) => Self::Focus(Right),
|
||||
_ => match state.focused() {
|
||||
Some(if state.entered() {
|
||||
match state.focused() {
|
||||
AppFocus::Menu => todo!(),
|
||||
AppFocus::Content(SequencerFocus::Transport(_)) => {
|
||||
use TransportCommand::{Clock, Focus};
|
||||
match TransportCommand::input_to_command(state, input)? {
|
||||
Clock(command) => { todo!() },
|
||||
Focus(command) => { todo!() },
|
||||
Clock(_) => { todo!() },
|
||||
Focus(_) => { todo!() },
|
||||
}
|
||||
},
|
||||
AppFocus::Content(SequencerFocus::Phrases) =>
|
||||
Phrases(PhrasesCommand::input_to_command(state, input)?),
|
||||
AppFocus::Content(SequencerFocus::PhraseEditor) =>
|
||||
Editor(PhraseCommand::input_to_command(state, input)?),
|
||||
_ => return None,
|
||||
}
|
||||
} else if let Some(command) = to_focus_command(input) {
|
||||
Self::Focus(command)
|
||||
} else {
|
||||
return None
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl InputToCommand<Tui, ArrangerTui> for ArrangerCommand {
|
||||
fn input_to_command (state: &ArrangerTui, input: &TuiInput) -> Option<Self> {
|
||||
use FocusCommand::*;
|
||||
use ArrangerCommand::*;
|
||||
Some(match input.event() {
|
||||
key!(KeyCode::Tab) => Self::Focus(Next),
|
||||
key!(Shift-KeyCode::Tab) => Self::Focus(Prev),
|
||||
key!(KeyCode::BackTab) => Self::Focus(Prev),
|
||||
key!(Shift-KeyCode::BackTab) => Self::Focus(Prev),
|
||||
key!(KeyCode::Up) => Self::Focus(Up),
|
||||
key!(KeyCode::Down) => Self::Focus(Down),
|
||||
key!(KeyCode::Left) => Self::Focus(Left),
|
||||
key!(KeyCode::Right) => Self::Focus(Right),
|
||||
key!(KeyCode::Enter) => Self::Focus(Enter),
|
||||
key!(KeyCode::Esc) => Self::Focus(Exit),
|
||||
key!(KeyCode::Char(' ')) => Self::Clock(ClockCommand::Play(None)),
|
||||
_ => match state.focused() {
|
||||
Some(if state.entered() {
|
||||
match state.focused() {
|
||||
AppFocus::Menu => todo!(),
|
||||
AppFocus::Content(ArrangerFocus::Transport(_)) => {
|
||||
use TransportCommand::{Clock, Focus};
|
||||
match TransportCommand::input_to_command(state, input)? {
|
||||
Clock(command) => { todo!() },
|
||||
Focus(command) => { todo!() }
|
||||
Clock(_) => { todo!() },
|
||||
Focus(_) => { todo!() }
|
||||
}
|
||||
},
|
||||
AppFocus::Content(ArrangerFocus::PhraseEditor) => Editor(
|
||||
PhraseCommand::input_to_command(state, input)?
|
||||
),
|
||||
AppFocus::Content(ArrangerFocus::PhraseEditor) => {
|
||||
Self::Editor(PhraseCommand::input_to_command(state, input)?)
|
||||
},
|
||||
AppFocus::Content(ArrangerFocus::Phrases) => match input.event() {
|
||||
key!(KeyCode::Char('e')) => EditPhrase(state.phrase_editing().clone()),
|
||||
_ => Phrases(PhrasesCommand::input_to_command(state, input)?)
|
||||
key!(KeyCode::Char('e')) => {
|
||||
Self::EditPhrase(state.phrase_editing().clone())
|
||||
},
|
||||
_ => {
|
||||
Self::Phrases(PhrasesCommand::input_to_command(state, input)?)
|
||||
}
|
||||
},
|
||||
AppFocus::Content(ArrangerFocus::Arranger) => {
|
||||
use ArrangerSelection as Select;
|
||||
use ArrangerTrackCommand as Track;
|
||||
use ArrangerClipCommand as Clip;
|
||||
use ArrangerSceneCommand as Scene;
|
||||
use KeyCode::{Char, Up, Down, Left, Right, Enter, Delete};
|
||||
match input.event() {
|
||||
key!(KeyCode::Char('e')) => EditPhrase(state.phrase_editing().clone()),
|
||||
_ => match input.event() {
|
||||
// FIXME: boundary conditions
|
||||
|
||||
key!(KeyCode::Up) => match state.selected() {
|
||||
Select::Mix => return None,
|
||||
Select::Track(t) => return None,
|
||||
Select::Scene(s) => if s > 0 {
|
||||
Select(Select::Scene(s - 1))
|
||||
} else {
|
||||
Select(Select::Mix)
|
||||
},
|
||||
Select::Clip(t, s) => if s > 0 {
|
||||
Select(Select::Clip(t, s - 1))
|
||||
} else {
|
||||
Select(Select::Track(t))
|
||||
},
|
||||
key!(Char('e')) => Self::EditPhrase(state.phrase_editing().clone()),
|
||||
key!(Char('l')) => Self::Clip(Clip::SetLoop(false)),
|
||||
key!(Char('+')) => Self::Zoom(0), // TODO
|
||||
key!(Char('=')) => Self::Zoom(0), // TODO
|
||||
key!(Char('_')) => Self::Zoom(0), // TODO
|
||||
key!(Char('-')) => Self::Zoom(0), // TODO
|
||||
key!(Char('`')) => { todo!("toggle state mode") },
|
||||
key!(Ctrl-Char('a')) => Self::Scene(Scene::Add),
|
||||
key!(Ctrl-Char('t')) => Self::Track(Track::Add),
|
||||
_ => match state.selected() {
|
||||
Select::Mix => match input.event() {
|
||||
key!(Down) => Self::Select(Select::Scene(0)),
|
||||
key!(Right) => Self::Select(Select::Track(0)),
|
||||
key!(Char(',')) => Self::Zoom(0),
|
||||
key!(Char('.')) => Self::Zoom(0),
|
||||
key!(Char('<')) => Self::Zoom(0),
|
||||
key!(Char('>')) => Self::Zoom(0),
|
||||
key!(Delete) => Self::Clear,
|
||||
key!(Char('c')) => Self::Color(ItemColor::random()),
|
||||
_ => return None
|
||||
},
|
||||
|
||||
key!(KeyCode::Down) => match state.selected() {
|
||||
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)),
|
||||
Select::Track(t) => match input.event() {
|
||||
key!(Down) => Self::Select(Select::Clip(t, 0)),
|
||||
key!(Left) => Self::Select(if t > 0 { Select::Track(t - 1) } else { Select::Mix }),
|
||||
key!(Right) => Self::Select(Select::Track(t + 1)),
|
||||
key!(Char(',')) => Self::Track(Track::Swap(t, t - 1)),
|
||||
key!(Char('.')) => Self::Track(Track::Swap(t, t + 1)),
|
||||
key!(Char('<')) => Self::Track(Track::Swap(t, t - 1)),
|
||||
key!(Char('>')) => Self::Track(Track::Swap(t, t + 1)),
|
||||
key!(Delete) => Self::Track(Track::Delete(t)),
|
||||
//key!(Char('c')) => Self::Track(Track::Color(t, ItemColor::random())),
|
||||
_ => return None
|
||||
},
|
||||
|
||||
key!(KeyCode::Left) => match state.selected() {
|
||||
Select::Mix => return None,
|
||||
Select::Track(t) => if t > 0 {
|
||||
Select(Select::Track(t - 1))
|
||||
} else {
|
||||
Select(Select::Mix)
|
||||
},
|
||||
Select::Scene(s) => return None,
|
||||
Select::Clip(t, s) => if t > 0 {
|
||||
Select(Select::Clip(t - 1, s))
|
||||
} else {
|
||||
Select(Select::Scene(s))
|
||||
},
|
||||
Select::Scene(s) => match input.event() {
|
||||
key!(Up) => Self::Select(if s > 0 { Select::Scene(s - 1) } else { Select::Mix }),
|
||||
key!(Down) => Self::Select(Select::Scene(s + 1)),
|
||||
key!(Right) => Self::Select(Select::Clip(0, s)),
|
||||
key!(Char(',')) => Self::Scene(Scene::Swap(s, s - 1)),
|
||||
key!(Char('.')) => Self::Scene(Scene::Swap(s, s + 1)),
|
||||
key!(Char('<')) => Self::Scene(Scene::Swap(s, s - 1)),
|
||||
key!(Char('>')) => Self::Scene(Scene::Swap(s, s + 1)),
|
||||
key!(Enter) => Self::Scene(Scene::Play(s)),
|
||||
key!(Delete) => Self::Scene(Scene::Delete(s)),
|
||||
//key!(Char('c')) => Self::Track(Scene::Color(s, ItemColor::random())),
|
||||
_ => return None
|
||||
},
|
||||
|
||||
key!(KeyCode::Right) => match state.selected() {
|
||||
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)),
|
||||
Select::Clip(t, s) => match input.event() {
|
||||
key!(Up) => Self::Select(if s > 0 { Select::Clip(t, s - 1) } else { Select::Track(t) }),
|
||||
key!(Down) => Self::Select(Select::Clip(t, s + 1)),
|
||||
key!(Left) => Self::Select(if t > 0 { Select::Clip(t - 1, s) } else { Select::Scene(s) }),
|
||||
key!(Right) => Self::Select(Select::Clip(t + 1, s)),
|
||||
key!(Char(',')) => Self::Clip(Clip::Set(t, s, None)),
|
||||
key!(Char('.')) => Self::Clip(Clip::Set(t, s, None)),
|
||||
key!(Char('<')) => Self::Clip(Clip::Set(t, s, None)),
|
||||
key!(Char('>')) => Self::Clip(Clip::Set(t, s, None)),
|
||||
key!(Delete) => Self::Clip(Clip::Set(t, s, None)),
|
||||
//key!(Char('c')) => Self::Clip(Clip::Color(t, s, ItemColor::random())),
|
||||
//key!(Char('g')) => Self::Clip(Clip(Clip::Get(t, s))),
|
||||
//key!(Char('s')) => Self::Clip(Clip(Clip::Set(t, s))),
|
||||
_ => return None
|
||||
},
|
||||
|
||||
key!(KeyCode::Char('+')) => Zoom(0),
|
||||
|
||||
key!(KeyCode::Char('=')) => Zoom(0),
|
||||
|
||||
key!(KeyCode::Char('_')) => Zoom(0),
|
||||
|
||||
key!(KeyCode::Char('-')) => Zoom(0),
|
||||
|
||||
key!(KeyCode::Char('`')) => { todo!("toggle state mode") },
|
||||
|
||||
key!(KeyCode::Char(',')) => match state.selected() {
|
||||
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 state.selected() {
|
||||
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 state.selected() {
|
||||
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 state.selected() {
|
||||
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 state.selected() {
|
||||
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 state.selected() {
|
||||
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')) => match state.selected() {
|
||||
Select::Mix => Color(ItemColor::random()),
|
||||
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('s')) => match state.selected() {
|
||||
Select::Clip(t, s) => Clip(Clip::Set(t, s, None)),
|
||||
_ => return None,
|
||||
},
|
||||
|
||||
key!(KeyCode::Char('g')) => match state.selected() {
|
||||
Select::Clip(t, s) => Clip(Clip::Get(t, s)),
|
||||
_ => return None,
|
||||
},
|
||||
|
||||
key!(Ctrl-KeyCode::Char('a')) => Scene(Scene::Add),
|
||||
|
||||
key!(Ctrl-KeyCode::Char('t')) => Track(Track::Add),
|
||||
|
||||
key!(KeyCode::Char('l')) => Clip(Clip::SetLoop(false)),
|
||||
|
||||
_ => return None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if let Some(command) = to_focus_command(input) {
|
||||
Self::Focus(command)
|
||||
} else {
|
||||
return None
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -254,64 +200,60 @@ impl<T: PhrasesControl> InputToCommand<Tui, T> for PhrasesCommand {
|
|||
use PhrasePoolCommand as Phrase;
|
||||
use PhraseRenameCommand as Rename;
|
||||
use PhraseLengthCommand as Length;
|
||||
use KeyCode::{Up, Down, Delete, Char};
|
||||
let index = state.phrase_index();
|
||||
let count = state.phrases().len();
|
||||
match input.event() {
|
||||
key!(KeyCode::Up) => Some(Self::Select(0)),
|
||||
key!(KeyCode::Down) => Some(Self::Select(0)),
|
||||
key!(KeyCode::Char(',')) => {
|
||||
if index > 1 {
|
||||
state.set_phrase_index(state.phrase_index().saturating_sub(1));
|
||||
Some(Self::Phrase(Phrase::Swap(index - 1, index)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
Some(match input.event() {
|
||||
key!(Up) => Self::Select(0),
|
||||
key!(Down) => Self::Select(0),
|
||||
key!(Char(',')) => if index > 1 {
|
||||
state.set_phrase_index(state.phrase_index().saturating_sub(1));
|
||||
Self::Phrase(Phrase::Swap(index - 1, index))
|
||||
} else {
|
||||
return None
|
||||
},
|
||||
key!(KeyCode::Char('.')) => {
|
||||
if index < count.saturating_sub(1) {
|
||||
state.set_phrase_index(state.phrase_index() + 1);
|
||||
Some(Self::Phrase(Phrase::Swap(index + 1, index)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
key!(Char('.')) => if index < count.saturating_sub(1) {
|
||||
state.set_phrase_index(state.phrase_index() + 1);
|
||||
Self::Phrase(Phrase::Swap(index + 1, index))
|
||||
} else {
|
||||
return None
|
||||
},
|
||||
key!(KeyCode::Delete) => {
|
||||
if index > 0 {
|
||||
state.set_phrase_index(index.min(count.saturating_sub(1)));
|
||||
Some(Self::Phrase(Phrase::Delete(index)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
key!(Delete) => if index > 0 {
|
||||
state.set_phrase_index(index.min(count.saturating_sub(1)));
|
||||
Self::Phrase(Phrase::Delete(index))
|
||||
} else {
|
||||
return None
|
||||
},
|
||||
key!(KeyCode::Char('a')) => Some(Self::Phrase(Phrase::Add(count))),
|
||||
key!(KeyCode::Char('i')) => Some(Self::Phrase(Phrase::Add(index + 1))),
|
||||
key!(KeyCode::Char('d')) => Some(Self::Phrase(Phrase::Duplicate(index))),
|
||||
key!(KeyCode::Char('c')) => Some(Self::Phrase(Phrase::Color(index, ItemColor::random()))),
|
||||
key!(KeyCode::Char('n')) => Some(Self::Rename(Rename::Begin)),
|
||||
key!(KeyCode::Char('t')) => Some(Self::Length(Length::Begin)),
|
||||
key!(Char('a')) => Self::Phrase(Phrase::Add(count)),
|
||||
key!(Char('i')) => Self::Phrase(Phrase::Add(index + 1)),
|
||||
key!(Char('d')) => Self::Phrase(Phrase::Duplicate(index)),
|
||||
key!(Char('c')) => Self::Phrase(Phrase::Color(index, ItemColor::random())),
|
||||
key!(Char('n')) => Self::Rename(Rename::Begin),
|
||||
key!(Char('t')) => Self::Length(Length::Begin),
|
||||
_ => match state.phrases_mode() {
|
||||
Some(PhrasesMode::Rename(..)) => {
|
||||
Rename::input_to_command(state, input).map(Self::Rename)
|
||||
Self::Rename(Rename::input_to_command(state, input)?)
|
||||
},
|
||||
Some(PhrasesMode::Length(..)) => {
|
||||
Length::input_to_command(state, input).map(Self::Length)
|
||||
Self::Length(Length::input_to_command(state, input)?)
|
||||
},
|
||||
_ => None
|
||||
_ => return None
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PhrasesControl> InputToCommand<Tui, T> for PhraseLengthCommand {
|
||||
fn input_to_command (state: &T, from: &TuiInput) -> Option<Self> {
|
||||
use KeyCode::{Up, Down, Right, Left, Enter, Esc};
|
||||
if let Some(PhrasesMode::Length(_, length, _)) = state.phrases_mode() {
|
||||
Some(match from.event() {
|
||||
key!(KeyCode::Up) => Self::Inc,
|
||||
key!(KeyCode::Down) => Self::Dec,
|
||||
key!(KeyCode::Right) => Self::Next,
|
||||
key!(KeyCode::Left) => Self::Prev,
|
||||
key!(KeyCode::Enter) => Self::Set(*length),
|
||||
key!(KeyCode::Esc) => Self::Cancel,
|
||||
key!(Up) => Self::Inc,
|
||||
key!(Down) => Self::Dec,
|
||||
key!(Right) => Self::Next,
|
||||
key!(Left) => Self::Prev,
|
||||
key!(Enter) => Self::Set(*length),
|
||||
key!(Esc) => Self::Cancel,
|
||||
_ => return None
|
||||
})
|
||||
} else {
|
||||
|
|
@ -322,20 +264,21 @@ impl<T: PhrasesControl> InputToCommand<Tui, T> for PhraseLengthCommand {
|
|||
|
||||
impl<T: PhrasesControl> InputToCommand<Tui, T> for PhraseRenameCommand {
|
||||
fn input_to_command (state: &T, from: &TuiInput) -> Option<Self> {
|
||||
use KeyCode::{Char, Backspace, Enter, Esc};
|
||||
if let Some(PhrasesMode::Rename(_, ref old_name)) = state.phrases_mode() {
|
||||
Some(match from.event() {
|
||||
key!(KeyCode::Char(c)) => {
|
||||
key!(Char(c)) => {
|
||||
let mut new_name = old_name.clone();
|
||||
new_name.push(*c);
|
||||
Self::Set(new_name)
|
||||
},
|
||||
key!(KeyCode::Backspace) => {
|
||||
key!(Backspace) => {
|
||||
let mut new_name = old_name.clone();
|
||||
new_name.pop();
|
||||
Self::Set(new_name)
|
||||
},
|
||||
key!(KeyCode::Enter) => Self::Confirm,
|
||||
key!(KeyCode::Esc) => Self::Cancel,
|
||||
key!(Enter) => Self::Confirm,
|
||||
key!(Esc) => Self::Cancel,
|
||||
_ => return None
|
||||
})
|
||||
} else {
|
||||
|
|
@ -347,39 +290,40 @@ impl<T: PhrasesControl> InputToCommand<Tui, T> for PhraseRenameCommand {
|
|||
impl<T: PhraseEditorControl + HasEnter> InputToCommand<Tui, T> for PhraseCommand {
|
||||
fn input_to_command (state: &T, from: &TuiInput) -> Option<Self> {
|
||||
use PhraseCommand::*;
|
||||
use KeyCode::{Char, Enter, Esc, Up, Down, PageUp, PageDown, Left, Right};
|
||||
Some(match from.event() {
|
||||
key!(KeyCode::Char('`')) => ToggleDirection,
|
||||
key!(KeyCode::Enter) => EnterEditMode,
|
||||
key!(KeyCode::Esc) => ExitEditMode,
|
||||
key!(KeyCode::Char('a')) => NoteAppend,
|
||||
key!(KeyCode::Char('s')) => NoteSet,
|
||||
key!(KeyCode::Char('[')) => NoteLengthSet(prev_note_length(state.note_len())),
|
||||
key!(KeyCode::Char(']')) => NoteLengthSet(next_note_length(state.note_len())),
|
||||
key!(KeyCode::Char('-')) => TimeZoomSet(next_note_length(state.time_axis().read().unwrap().scale)),
|
||||
key!(KeyCode::Char('_')) => TimeZoomSet(next_note_length(state.time_axis().read().unwrap().scale)),
|
||||
key!(KeyCode::Char('=')) => TimeZoomSet(prev_note_length(state.time_axis().read().unwrap().scale)),
|
||||
key!(KeyCode::Char('+')) => TimeZoomSet(prev_note_length(state.time_axis().read().unwrap().scale)),
|
||||
key!(KeyCode::Up) => match state.phrase_editor_entered() {
|
||||
key!(Char('`')) => ToggleDirection,
|
||||
key!(Enter) => EnterEditMode,
|
||||
key!(Esc) => ExitEditMode,
|
||||
key!(Char('a')) => NoteAppend,
|
||||
key!(Char('s')) => NoteSet,
|
||||
key!(Char('[')) => NoteLengthSet(prev_note_length(state.note_len())),
|
||||
key!(Char(']')) => NoteLengthSet(next_note_length(state.note_len())),
|
||||
key!(Char('-')) => TimeZoomSet(next_note_length(state.time_axis().read().unwrap().scale)),
|
||||
key!(Char('_')) => TimeZoomSet(next_note_length(state.time_axis().read().unwrap().scale)),
|
||||
key!(Char('=')) => TimeZoomSet(prev_note_length(state.time_axis().read().unwrap().scale)),
|
||||
key!(Char('+')) => TimeZoomSet(prev_note_length(state.time_axis().read().unwrap().scale)),
|
||||
key!(Up) => match state.phrase_editor_entered() {
|
||||
true => NoteCursorSet(state.note_axis().write().unwrap().point_plus(1)),
|
||||
false => NoteScrollSet(state.note_axis().write().unwrap().start_plus(1)),
|
||||
},
|
||||
key!(KeyCode::Down) => match state.phrase_editor_entered() {
|
||||
key!(Down) => match state.phrase_editor_entered() {
|
||||
true => NoteCursorSet(state.note_axis().write().unwrap().point_minus(1)),
|
||||
false => NoteScrollSet(state.note_axis().write().unwrap().start_minus(1)),
|
||||
},
|
||||
key!(KeyCode::PageUp) => match state.phrase_editor_entered() {
|
||||
key!(PageUp) => match state.phrase_editor_entered() {
|
||||
true => NoteCursorSet(state.note_axis().write().unwrap().point_plus(3)),
|
||||
false => NoteScrollSet(state.note_axis().write().unwrap().start_plus(3)),
|
||||
},
|
||||
key!(KeyCode::PageDown) => match state.phrase_editor_entered() {
|
||||
key!(PageDown) => match state.phrase_editor_entered() {
|
||||
true => NoteCursorSet(state.note_axis().write().unwrap().point_minus(3)),
|
||||
false => NoteScrollSet(state.note_axis().write().unwrap().start_minus(3)),
|
||||
},
|
||||
key!(KeyCode::Left) => match state.phrase_editor_entered() {
|
||||
key!(Left) => match state.phrase_editor_entered() {
|
||||
true => TimeCursorSet(state.note_axis().write().unwrap().point_minus(1)),
|
||||
false => TimeScrollSet(state.note_axis().write().unwrap().start_minus(1)),
|
||||
},
|
||||
key!(KeyCode::Right) => match state.phrase_editor_entered() {
|
||||
key!(Right) => match state.phrase_editor_entered() {
|
||||
true => TimeCursorSet(state.note_axis().write().unwrap().point_plus(1)),
|
||||
false => TimeScrollSet(state.note_axis().write().unwrap().start_plus(1)),
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue