mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-08 04:36:45 +01:00
use those macros in some places, a few more to go
This commit is contained in:
parent
fdafd15a01
commit
17efdb9b8e
3 changed files with 192 additions and 193 deletions
|
|
@ -218,23 +218,16 @@ pub enum TransportCommand {
|
||||||
Clock(ClockCommand),
|
Clock(ClockCommand),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command<TransportTui> for TransportCommand {
|
command!(|self:TransportCommand,state:TransportTui|match self {
|
||||||
fn execute (self, state: &mut TransportTui) -> Perhaps<Self> {
|
//Self::Focus(cmd) => cmd.execute(state)?.map(Self::Focus),
|
||||||
Ok(match self {
|
Self::Clock(cmd) => cmd.execute(state)?.map(Self::Clock),
|
||||||
Self::Focus(cmd) => cmd.execute(state)?.map(Self::Focus),
|
_ => unreachable!(),
|
||||||
Self::Clock(cmd) => cmd.execute(state)?.map(Self::Clock),
|
});
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Command<TransportTui> for FocusCommand<TransportFocus> {
|
//command!(|self:TransportFocus,state:TransportTui|{
|
||||||
fn execute (self, state: &mut TransportTui) -> Perhaps<FocusCommand<TransportFocus>> {
|
//if let FocusCommand::Set(to) = self { state.set_focused(to); }
|
||||||
if let FocusCommand::Set(to) = self {
|
//Ok(None)
|
||||||
state.set_focused(to);
|
//});
|
||||||
}
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InputToCommand<Tui, TransportTui> for TransportCommand {
|
impl InputToCommand<Tui, TransportTui> for TransportCommand {
|
||||||
fn input_to_command (state: &TransportTui, input: &TuiInput) -> Option<Self> {
|
fn input_to_command (state: &TransportTui, input: &TuiInput) -> Option<Self> {
|
||||||
|
|
@ -262,34 +255,10 @@ where
|
||||||
Pause(Some(0))
|
Pause(Some(0))
|
||||||
}),
|
}),
|
||||||
_ => match state.transport_focused().unwrap() {
|
_ => match state.transport_focused().unwrap() {
|
||||||
TransportFocus::Bpm => match input.event() {
|
TransportFocus::Bpm => to_bpm_command(input, state.clock().bpm().get())?,
|
||||||
key_pat!(Char(',')) => Clock(SetBpm(state.clock().bpm().get() - 1.0)),
|
TransportFocus::Quant => to_quant_command(input, &state.clock().quant)?,
|
||||||
key_pat!(Char('.')) => Clock(SetBpm(state.clock().bpm().get() + 1.0)),
|
TransportFocus::Sync => to_sync_command(input, &state.clock().sync)?,
|
||||||
key_pat!(Char('<')) => Clock(SetBpm(state.clock().bpm().get() - 0.001)),
|
TransportFocus::Clock => to_seek_command(input)?,
|
||||||
key_pat!(Char('>')) => Clock(SetBpm(state.clock().bpm().get() + 0.001)),
|
|
||||||
_ => return None,
|
|
||||||
},
|
|
||||||
TransportFocus::Quant => match input.event() {
|
|
||||||
key_pat!(Char(',')) => Clock(SetQuant(state.clock().quant.prev())),
|
|
||||||
key_pat!(Char('.')) => Clock(SetQuant(state.clock().quant.next())),
|
|
||||||
key_pat!(Char('<')) => Clock(SetQuant(state.clock().quant.prev())),
|
|
||||||
key_pat!(Char('>')) => Clock(SetQuant(state.clock().quant.next())),
|
|
||||||
_ => return None,
|
|
||||||
},
|
|
||||||
TransportFocus::Sync => match input.event() {
|
|
||||||
key_pat!(Char(',')) => Clock(SetSync(state.clock().sync.prev())),
|
|
||||||
key_pat!(Char('.')) => Clock(SetSync(state.clock().sync.next())),
|
|
||||||
key_pat!(Char('<')) => Clock(SetSync(state.clock().sync.prev())),
|
|
||||||
key_pat!(Char('>')) => Clock(SetSync(state.clock().sync.next())),
|
|
||||||
_ => return None,
|
|
||||||
},
|
|
||||||
TransportFocus::Clock => match input.event() {
|
|
||||||
key_pat!(Char(',')) => todo!("transport seek bar"),
|
|
||||||
key_pat!(Char('.')) => todo!("transport seek bar"),
|
|
||||||
key_pat!(Char('<')) => todo!("transport seek beat"),
|
|
||||||
key_pat!(Char('>')) => todo!("transport seek beat"),
|
|
||||||
_ => return None,
|
|
||||||
},
|
|
||||||
TransportFocus::PlayPause => match input.event() {
|
TransportFocus::PlayPause => match input.event() {
|
||||||
key_pat!(Enter) => Clock(
|
key_pat!(Enter) => Clock(
|
||||||
if state.clock().is_stopped() {
|
if state.clock().is_stopped() {
|
||||||
|
|
@ -310,3 +279,43 @@ where
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn to_bpm_command (input: &TuiInput, bpm: f64) -> Option<TransportCommand> {
|
||||||
|
Some(match input.event() {
|
||||||
|
key_pat!(Char(',')) => Clock(SetBpm(bpm - 1.0)),
|
||||||
|
key_pat!(Char('.')) => Clock(SetBpm(bpm + 1.0)),
|
||||||
|
key_pat!(Char('<')) => Clock(SetBpm(bpm - 0.001)),
|
||||||
|
key_pat!(Char('>')) => Clock(SetBpm(bpm + 0.001)),
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_quant_command (input: &TuiInput, quant: &Quantize) -> Option<TransportCommand> {
|
||||||
|
Some(match input.event() {
|
||||||
|
key_pat!(Char(',')) => Clock(SetQuant(quant.prev())),
|
||||||
|
key_pat!(Char('.')) => Clock(SetQuant(quant.next())),
|
||||||
|
key_pat!(Char('<')) => Clock(SetQuant(quant.prev())),
|
||||||
|
key_pat!(Char('>')) => Clock(SetQuant(quant.next())),
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_sync_command (input: &TuiInput, sync: &LaunchSync) -> Option<TransportCommand> {
|
||||||
|
Some(match input.event() {
|
||||||
|
key_pat!(Char(',')) => Clock(SetSync(sync.prev())),
|
||||||
|
key_pat!(Char('.')) => Clock(SetSync(sync.next())),
|
||||||
|
key_pat!(Char('<')) => Clock(SetSync(sync.prev())),
|
||||||
|
key_pat!(Char('>')) => Clock(SetSync(sync.next())),
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_seek_command (input: &TuiInput) -> Option<TransportCommand> {
|
||||||
|
Some(match input.event() {
|
||||||
|
key_pat!(Char(',')) => todo!("transport seek bar"),
|
||||||
|
key_pat!(Char('.')) => todo!("transport seek bar"),
|
||||||
|
key_pat!(Char('<')) => todo!("transport seek beat"),
|
||||||
|
key_pat!(Char('>')) => todo!("transport seek beat"),
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,100 +95,94 @@ pub enum FileBrowserCommand {
|
||||||
Filter(String),
|
Filter(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command<PhraseListModel> for FileBrowserCommand {
|
command!(|self: FileBrowserCommand, state: PhraseListModel|{
|
||||||
fn execute (self, state: &mut PhraseListModel) -> Perhaps<Self> {
|
let mode = state.phrases_mode_mut();
|
||||||
let mode = state.phrases_mode_mut();
|
match mode {
|
||||||
match mode {
|
Some(Import(index, ref mut browser)) => match self {
|
||||||
Some(Import(index, ref mut browser)) => match self {
|
Cancel => {
|
||||||
Cancel => {
|
*mode = None;
|
||||||
*mode = None;
|
|
||||||
},
|
|
||||||
Chdir(cwd) => {
|
|
||||||
*mode = Some(Import(*index, FileBrowser::new(Some(cwd))?));
|
|
||||||
},
|
|
||||||
Select(index) => {
|
|
||||||
browser.index = index;
|
|
||||||
},
|
|
||||||
Confirm => {
|
|
||||||
if browser.is_file() {
|
|
||||||
let index = *index;
|
|
||||||
let path = browser.path();
|
|
||||||
*mode = None;
|
|
||||||
PhrasePoolCommand::Import(index, path).execute(state)?;
|
|
||||||
} else if browser.is_dir() {
|
|
||||||
*mode = Some(Import(*index, browser.chdir()?));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => todo!(),
|
|
||||||
},
|
},
|
||||||
Some(PhraseListMode::Export(index, ref mut browser)) => match self {
|
Chdir(cwd) => {
|
||||||
Cancel => {
|
*mode = Some(Import(*index, FileBrowser::new(Some(cwd))?));
|
||||||
*mode = None;
|
|
||||||
},
|
|
||||||
Chdir(cwd) => {
|
|
||||||
*mode = Some(PhraseListMode::Export(*index, FileBrowser::new(Some(cwd))?));
|
|
||||||
},
|
|
||||||
Select(index) => {
|
|
||||||
browser.index = index;
|
|
||||||
},
|
|
||||||
_ => unreachable!()
|
|
||||||
},
|
},
|
||||||
_ => unreachable!(),
|
Select(index) => {
|
||||||
};
|
browser.index = index;
|
||||||
Ok(None)
|
},
|
||||||
}
|
Confirm => {
|
||||||
}
|
if browser.is_file() {
|
||||||
|
let index = *index;
|
||||||
|
let path = browser.path();
|
||||||
|
*mode = None;
|
||||||
|
PhrasePoolCommand::Import(index, path).execute(state)?;
|
||||||
|
} else if browser.is_dir() {
|
||||||
|
*mode = Some(Import(*index, browser.chdir()?));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => todo!(),
|
||||||
|
},
|
||||||
|
Some(PhraseListMode::Export(index, ref mut browser)) => match self {
|
||||||
|
Cancel => {
|
||||||
|
*mode = None;
|
||||||
|
},
|
||||||
|
Chdir(cwd) => {
|
||||||
|
*mode = Some(PhraseListMode::Export(*index, FileBrowser::new(Some(cwd))?));
|
||||||
|
},
|
||||||
|
Select(index) => {
|
||||||
|
browser.index = index;
|
||||||
|
},
|
||||||
|
_ => unreachable!()
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
None
|
||||||
|
});
|
||||||
|
|
||||||
impl InputToCommand<Tui, PhraseListModel> for FileBrowserCommand {
|
input_to_command!(FileBrowserCommand:<Tui>|state:PhraseListModel,from|{
|
||||||
fn input_to_command (state: &PhraseListModel, from: &TuiInput) -> Option<Self> {
|
if let Some(PhraseListMode::Import(_index, browser)) = state.phrases_mode() {
|
||||||
if let Some(PhraseListMode::Import(_index, browser)) = state.phrases_mode() {
|
Some(match from.event() {
|
||||||
Some(match from.event() {
|
key_pat!(Up) => Select(
|
||||||
key_pat!(Up) => Select(
|
browser.index.overflowing_sub(1).0.min(browser.len().saturating_sub(1))
|
||||||
browser.index.overflowing_sub(1).0.min(browser.len().saturating_sub(1))
|
),
|
||||||
),
|
key_pat!(Down) => Select(
|
||||||
key_pat!(Down) => Select(
|
browser.index.saturating_add(1) % browser.len()
|
||||||
browser.index.saturating_add(1) % browser.len()
|
),
|
||||||
),
|
key_pat!(Right) => Chdir(browser.cwd.clone()),
|
||||||
key_pat!(Right) => Chdir(browser.cwd.clone()),
|
key_pat!(Left) => Chdir(browser.cwd.clone()),
|
||||||
key_pat!(Left) => Chdir(browser.cwd.clone()),
|
key_pat!(Enter) => Confirm,
|
||||||
key_pat!(Enter) => Confirm,
|
key_pat!(Char(_)) => { todo!() },
|
||||||
key_pat!(Char(_)) => { todo!() },
|
key_pat!(Backspace) => { todo!() },
|
||||||
key_pat!(Backspace) => { todo!() },
|
key_pat!(Esc) => Self::Cancel,
|
||||||
key_pat!(Esc) => Self::Cancel,
|
_ => return None
|
||||||
_ => return None
|
})
|
||||||
})
|
} else if let Some(PhraseListMode::Export(_index, browser)) = state.phrases_mode() {
|
||||||
} else if let Some(PhraseListMode::Export(_index, browser)) = state.phrases_mode() {
|
Some(match from.event() {
|
||||||
Some(match from.event() {
|
key_pat!(Up) => Select(browser.index.overflowing_sub(1).0.min(browser.len())),
|
||||||
key_pat!(Up) => Select(browser.index.overflowing_sub(1).0.min(browser.len())),
|
key_pat!(Down) => Select(browser.index.saturating_add(1) % browser.len()),
|
||||||
key_pat!(Down) => Select(browser.index.saturating_add(1) % browser.len()),
|
key_pat!(Right) => Chdir(browser.cwd.clone()),
|
||||||
key_pat!(Right) => Chdir(browser.cwd.clone()),
|
key_pat!(Left) => Chdir(browser.cwd.clone()),
|
||||||
key_pat!(Left) => Chdir(browser.cwd.clone()),
|
key_pat!(Enter) => Confirm,
|
||||||
key_pat!(Enter) => Confirm,
|
key_pat!(Char(_)) => { todo!() },
|
||||||
key_pat!(Char(_)) => { todo!() },
|
key_pat!(Backspace) => { todo!() },
|
||||||
key_pat!(Backspace) => { todo!() },
|
key_pat!(Esc) => Self::Cancel,
|
||||||
key_pat!(Esc) => Self::Cancel,
|
_ => return None
|
||||||
_ => return None
|
})
|
||||||
})
|
} else {
|
||||||
} else {
|
unreachable!()
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
impl InputToCommand<Tui, PhraseListModel> for PhraseLengthCommand {
|
input_to_command!(PhraseLengthCommand:<Tui>|state:PhraseListModel,from|{
|
||||||
fn input_to_command (state: &PhraseListModel, from: &TuiInput) -> Option<Self> {
|
if let Some(PhraseListMode::Length(_, length, _)) = state.phrases_mode() {
|
||||||
if let Some(PhraseListMode::Length(_, length, _)) = state.phrases_mode() {
|
Some(match from.event() {
|
||||||
Some(match from.event() {
|
key_pat!(Up) => Self::Inc,
|
||||||
key_pat!(Up) => Self::Inc,
|
key_pat!(Down) => Self::Dec,
|
||||||
key_pat!(Down) => Self::Dec,
|
key_pat!(Right) => Self::Next,
|
||||||
key_pat!(Right) => Self::Next,
|
key_pat!(Left) => Self::Prev,
|
||||||
key_pat!(Left) => Self::Prev,
|
key_pat!(Enter) => Self::Set(*length),
|
||||||
key_pat!(Enter) => Self::Set(*length),
|
key_pat!(Esc) => Self::Cancel,
|
||||||
key_pat!(Esc) => Self::Cancel,
|
_ => return None
|
||||||
_ => return None
|
})
|
||||||
})
|
} else {
|
||||||
} else {
|
unreachable!()
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
|
||||||
|
|
@ -50,68 +50,64 @@ pub enum PhrasesCommand {
|
||||||
Export(Browse),
|
Export(Browse),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command<PhraseListModel> for PhrasesCommand {
|
command!(|self:PhrasesCommand, state:PhraseListModel|{
|
||||||
fn execute (self, state: &mut PhraseListModel) -> Perhaps<Self> {
|
use PhrasesCommand::*;
|
||||||
use PhrasesCommand::*;
|
match self {
|
||||||
Ok(match self {
|
Phrase(command) => command.execute(state)?.map(Phrase),
|
||||||
Phrase(command) => command.execute(state)?.map(Phrase),
|
Rename(command) => match command {
|
||||||
Rename(command) => match command {
|
PhraseRenameCommand::Begin => {
|
||||||
PhraseRenameCommand::Begin => {
|
let length = state.phrases()[state.phrase_index()].read().unwrap().length;
|
||||||
let length = state.phrases()[state.phrase_index()].read().unwrap().length;
|
*state.phrases_mode_mut() = Some(
|
||||||
*state.phrases_mode_mut() = Some(
|
PhraseListMode::Length(state.phrase_index(), length, PhraseLengthFocus::Bar)
|
||||||
PhraseListMode::Length(state.phrase_index(), length, PhraseLengthFocus::Bar)
|
);
|
||||||
);
|
|
||||||
None
|
|
||||||
},
|
|
||||||
_ => command.execute(state)?.map(Rename)
|
|
||||||
},
|
|
||||||
Length(command) => match command {
|
|
||||||
PhraseLengthCommand::Begin => {
|
|
||||||
let name = state.phrases()[state.phrase_index()].read().unwrap().name.clone();
|
|
||||||
*state.phrases_mode_mut() = Some(
|
|
||||||
PhraseListMode::Rename(state.phrase_index(), name)
|
|
||||||
);
|
|
||||||
None
|
|
||||||
},
|
|
||||||
_ => command.execute(state)?.map(Length)
|
|
||||||
},
|
|
||||||
Import(command) => match command {
|
|
||||||
FileBrowserCommand::Begin => {
|
|
||||||
*state.phrases_mode_mut() = Some(
|
|
||||||
PhraseListMode::Import(state.phrase_index(), FileBrowser::new(None)?)
|
|
||||||
);
|
|
||||||
None
|
|
||||||
},
|
|
||||||
_ => command.execute(state)?.map(Import)
|
|
||||||
},
|
|
||||||
Export(command) => match command {
|
|
||||||
FileBrowserCommand::Begin => {
|
|
||||||
*state.phrases_mode_mut() = Some(
|
|
||||||
PhraseListMode::Export(state.phrase_index(), FileBrowser::new(None)?)
|
|
||||||
);
|
|
||||||
None
|
|
||||||
},
|
|
||||||
_ => command.execute(state)?.map(Export)
|
|
||||||
},
|
|
||||||
Select(phrase) => {
|
|
||||||
state.set_phrase_index(phrase);
|
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
})
|
_ => command.execute(state)?.map(Rename)
|
||||||
|
},
|
||||||
|
Length(command) => match command {
|
||||||
|
PhraseLengthCommand::Begin => {
|
||||||
|
let name = state.phrases()[state.phrase_index()].read().unwrap().name.clone();
|
||||||
|
*state.phrases_mode_mut() = Some(
|
||||||
|
PhraseListMode::Rename(state.phrase_index(), name)
|
||||||
|
);
|
||||||
|
None
|
||||||
|
},
|
||||||
|
_ => command.execute(state)?.map(Length)
|
||||||
|
},
|
||||||
|
Import(command) => match command {
|
||||||
|
FileBrowserCommand::Begin => {
|
||||||
|
*state.phrases_mode_mut() = Some(
|
||||||
|
PhraseListMode::Import(state.phrase_index(), FileBrowser::new(None)?)
|
||||||
|
);
|
||||||
|
None
|
||||||
|
},
|
||||||
|
_ => command.execute(state)?.map(Import)
|
||||||
|
},
|
||||||
|
Export(command) => match command {
|
||||||
|
FileBrowserCommand::Begin => {
|
||||||
|
*state.phrases_mode_mut() = Some(
|
||||||
|
PhraseListMode::Export(state.phrase_index(), FileBrowser::new(None)?)
|
||||||
|
);
|
||||||
|
None
|
||||||
|
},
|
||||||
|
_ => command.execute(state)?.map(Export)
|
||||||
|
},
|
||||||
|
Select(phrase) => {
|
||||||
|
state.set_phrase_index(phrase);
|
||||||
|
None
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
impl InputToCommand<Tui, PhraseListModel> for PhrasesCommand {
|
input_to_command!(PhrasesCommand:<Tui>|state:PhraseListModel,input|{
|
||||||
fn input_to_command (state: &PhraseListModel, input: &TuiInput) -> Option<Self> {
|
Some(match state.phrases_mode() {
|
||||||
Some(match state.phrases_mode() {
|
Some(PhraseListMode::Rename(..)) => Self::Rename(Rename::input_to_command(state, input)?),
|
||||||
Some(PhraseListMode::Rename(..)) => Self::Rename(Rename::input_to_command(state, input)?),
|
Some(PhraseListMode::Length(..)) => Self::Length(Length::input_to_command(state, input)?),
|
||||||
Some(PhraseListMode::Length(..)) => Self::Length(Length::input_to_command(state, input)?),
|
Some(PhraseListMode::Import(..)) => Self::Import(Browse::input_to_command(state, input)?),
|
||||||
Some(PhraseListMode::Import(..)) => Self::Import(Browse::input_to_command(state, input)?),
|
Some(PhraseListMode::Export(..)) => Self::Export(Browse::input_to_command(state, input)?),
|
||||||
Some(PhraseListMode::Export(..)) => Self::Export(Browse::input_to_command(state, input)?),
|
_ => to_phrases_command(state, input)?
|
||||||
_ => to_phrases_command(state, input)?
|
})
|
||||||
})
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_phrases_command (state: &PhraseListModel, input: &TuiInput) -> Option<PhrasesCommand> {
|
fn to_phrases_command (state: &PhraseListModel, input: &TuiInput) -> Option<PhrasesCommand> {
|
||||||
use KeyCode::{Up, Down, Delete, Char};
|
use KeyCode::{Up, Down, Delete, Char};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue