mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
wip: refactor pt.31: 41 errors
This commit is contained in:
parent
28e15d3f56
commit
8b5931c321
3 changed files with 98 additions and 89 deletions
|
|
@ -64,7 +64,7 @@ impl InputToCommand<Tui, ArrangerApp<Tui>> for ArrangerAppCommand {
|
||||||
key!(KeyCode::Char(' ')) => {
|
key!(KeyCode::Char(' ')) => {
|
||||||
Self::App(Transport(TransportViewCommand::Transport(TransportCommand::Play(None))))
|
Self::App(Transport(TransportViewCommand::Transport(TransportCommand::Play(None))))
|
||||||
},
|
},
|
||||||
_ => match view.focused() {
|
_ => Self::App(match view.focused() {
|
||||||
Content(ArrangerViewFocus::Transport) => Transport(
|
Content(ArrangerViewFocus::Transport) => Transport(
|
||||||
TransportViewCommand::input_to_command(&view.sequencer.transport, input)?
|
TransportViewCommand::input_to_command(&view.sequencer.transport, input)?
|
||||||
),
|
),
|
||||||
|
|
@ -194,44 +194,17 @@ impl InputToCommand<Tui, ArrangerApp<Tui>> for ArrangerAppCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command<ArrangerApp<Tui>> for ArrangerAppCommand {
|
impl Command<ArrangerApp<Tui>> for ArrangerAppCommand {
|
||||||
fn execute (self, state: &mut ArrangerApp<Tui>) -> Perhaps<Self> {
|
fn execute (self, state: &mut ArrangerApp<Tui>) -> Perhaps<Self> {
|
||||||
|
use AppViewCommand::*;
|
||||||
let undo = match self {
|
let undo = match self {
|
||||||
Self::Focus(cmd) => {
|
Focus(cmd) => { delegate(cmd, Focus, state) },
|
||||||
delegate(cmd, Self::Focus, state)
|
App(cmd) => { delegate(cmd, App, state) }
|
||||||
},
|
|
||||||
Self::App(cmd) => match cmd {
|
|
||||||
ArrangerViewCommand::Phrases(cmd) => {
|
|
||||||
delegate(cmd, |x|Self::App(ArrangerViewCommand::Phrases(x)), &mut state.app)
|
|
||||||
},
|
|
||||||
ArrangerViewCommand::Editor(cmd) => {
|
|
||||||
delegate(cmd, |x|Self::App(ArrangerViewCommand::Editor(x)), &mut state.app)
|
|
||||||
},
|
|
||||||
ArrangerViewCommand::Transport(cmd) => {
|
|
||||||
delegate(cmd, |x|Self::App(ArrangerViewCommand::Transport(x)), &mut state.app)
|
|
||||||
},
|
|
||||||
ArrangerViewCommand::Zoom(zoom) => {
|
|
||||||
todo!();
|
|
||||||
},
|
|
||||||
ArrangerViewCommand::Select(selected) => {
|
|
||||||
state.selected = selected;
|
|
||||||
Ok(None)
|
|
||||||
},
|
|
||||||
ArrangerViewCommand::Edit(command) => {
|
|
||||||
return Ok(command.execute(&mut state.model)?.map(ArrangerViewCommand::Edit))
|
|
||||||
},
|
|
||||||
ArrangerViewCommand::EditPhrase(phrase) => {
|
|
||||||
app.sequencer.editor.phrase = phrase.clone();
|
|
||||||
state.focus(ArrangerViewFocus::PhraseEditor);
|
|
||||||
state.focus_enter();
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {todo!()}
|
_ => {todo!()}
|
||||||
}?;
|
}?;
|
||||||
state.show_phrase();
|
state.show_phrase();
|
||||||
|
|
@ -240,6 +213,28 @@ impl Command<ArrangerApp<Tui>> for ArrangerAppCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Command<ArrangerApp<Tui>> for ArrangerViewCommand {
|
||||||
|
fn execute (self, state: &mut ArrangerApp<Tui>) -> Perhaps<Self> {
|
||||||
|
use ArrangerViewCommand::*;
|
||||||
|
match self {
|
||||||
|
Phrases(cmd) => { delegate(cmd, Phrases, &mut state.app) },
|
||||||
|
Editor(cmd) => { delegate(cmd, Editor, &mut state.app) },
|
||||||
|
Transport(cmd) => { delegate(cmd, Transport, &mut state.app) },
|
||||||
|
Zoom(zoom) => { todo!(); },
|
||||||
|
Select(selected) => { state.selected = selected; Ok(None) },
|
||||||
|
Edit(command) => {
|
||||||
|
return Ok(command.execute(&mut state.model)?.map(ArrangerViewCommand::Edit))
|
||||||
|
},
|
||||||
|
EditPhrase(phrase) => {
|
||||||
|
state.sequencer.editor.phrase = phrase.clone();
|
||||||
|
state.focus(ArrangerViewFocus::PhraseEditor);
|
||||||
|
state.focus_enter();
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Root view for standalone `tek_arranger`
|
/// Root view for standalone `tek_arranger`
|
||||||
pub struct ArrangerView<E: Engine> {
|
pub struct ArrangerView<E: Engine> {
|
||||||
pub model: ArrangerModel,
|
pub model: ArrangerModel,
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,7 @@ const NTH_OCTAVE: [&'static str; 11] = [
|
||||||
"-2", "-1", "0", "1", "2", "3", "4", "5", "6", "7", "8",
|
"-2", "-1", "0", "1", "2", "3", "4", "5", "6", "7", "8",
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub enum PhraseEditorCommand {
|
pub enum PhraseEditorCommand {
|
||||||
// TODO: 1-9 seek markers that by default start every 8th of the phrase
|
// TODO: 1-9 seek markers that by default start every 8th of the phrase
|
||||||
ToggleDirection,
|
ToggleDirection,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,22 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
impl TryFrom<&Arc<RwLock<JackClient>>> for SequencerApp<Tui> {
|
||||||
|
type Error = Box<dyn std::error::Error>;
|
||||||
|
fn try_from (jack: &Arc<RwLock<JackClient>>) -> Usually<Self> {
|
||||||
|
let clock = Arc::new(Clock::from(Instant::default()));
|
||||||
|
Ok(Self::new(SequencerModel {
|
||||||
|
phrases: vec![],
|
||||||
|
player: MIDIPlayer::new(jack, &clock, "preview")?,
|
||||||
|
transport: TransportModel {
|
||||||
|
metronome: false,
|
||||||
|
transport: jack.read().unwrap().transport(),
|
||||||
|
jack: jack.clone(),
|
||||||
|
clock: clock.clone()
|
||||||
|
},
|
||||||
|
}.into(), None, None))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type SequencerApp<E: Engine> = AppView<
|
pub type SequencerApp<E: Engine> = AppView<
|
||||||
E,
|
E,
|
||||||
SequencerView<E>,
|
SequencerView<E>,
|
||||||
|
|
@ -7,13 +24,52 @@ pub type SequencerApp<E: Engine> = AppView<
|
||||||
SequencerStatusBar,
|
SequencerStatusBar,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
impl Handle<Tui> for SequencerApp<Tui> {
|
||||||
|
fn handle (&mut self, i: &TuiInput) -> Perhaps<bool> {
|
||||||
|
SequencerAppCommand::execute_with_state(self, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type SequencerAppCommand = AppViewCommand<SequencerViewCommand>;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum SequencerViewCommand {
|
pub enum SequencerViewCommand {
|
||||||
Transport(TransportCommand),
|
Transport(TransportCommand),
|
||||||
Phrases(PhrasePoolViewCommand),
|
Phrases(PhrasePoolViewCommand),
|
||||||
Editor(PhraseEditorCommand),
|
Editor(PhraseEditorCommand),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InputToCommand<Tui, SequencerApp<Tui>> for SequencerAppCommand {
|
||||||
|
fn input_to_command (state: &SequencerApp<Tui>, input: &TuiInput) -> Option<Self> {
|
||||||
|
use AppViewFocus::*;
|
||||||
|
use FocusCommand::*;
|
||||||
|
use SequencerViewCommand::*;
|
||||||
|
match input.event() {
|
||||||
|
key!(KeyCode::Tab) => Some(Self::Focus(Next)),
|
||||||
|
key!(Shift-KeyCode::Tab) => Some(Self::Focus(Prev)),
|
||||||
|
key!(KeyCode::BackTab) => Some(Self::Focus(Prev)),
|
||||||
|
key!(Shift-KeyCode::BackTab) => Some(Self::Focus(Prev)),
|
||||||
|
key!(KeyCode::Up) => Some(Self::Focus(Up)),
|
||||||
|
key!(KeyCode::Down) => Some(Self::Focus(Down)),
|
||||||
|
key!(KeyCode::Left) => Some(Self::Focus(Left)),
|
||||||
|
key!(KeyCode::Right) => Some(Self::Focus(Right)),
|
||||||
|
_ => Some(Self::App(match state.focused() {
|
||||||
|
Content(SequencerFocus::Transport) =>
|
||||||
|
TransportCommand::input_to_command(&state.transport, input)
|
||||||
|
.map(Transport),
|
||||||
|
Content(SequencerFocus::PhrasePool) =>
|
||||||
|
PhrasePoolViewCommand::input_to_command(&state.phrases, input)
|
||||||
|
.map(Phrases),
|
||||||
|
Content(SequencerFocus::PhraseEditor) =>
|
||||||
|
PhraseEditorCommand::input_to_command(&state.editor, input)
|
||||||
|
.map(Editor),
|
||||||
|
_ => return None,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Root view for standalone `tek_sequencer`.
|
/// Root view for standalone `tek_sequencer`.
|
||||||
pub struct SequencerView<E: Engine> {
|
pub struct SequencerView<E: Engine> {
|
||||||
pub model: SequencerModel,
|
pub model: SequencerModel,
|
||||||
|
|
@ -46,23 +102,6 @@ pub enum SequencerStatusBar {
|
||||||
PhraseEditor,
|
PhraseEditor,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&Arc<RwLock<JackClient>>> for SequencerApp<Tui> {
|
|
||||||
type Error = Box<dyn std::error::Error>;
|
|
||||||
fn try_from (jack: &Arc<RwLock<JackClient>>) -> Usually<Self> {
|
|
||||||
let clock = Arc::new(Clock::from(Instant::default()));
|
|
||||||
Ok(Self::new(SequencerModel {
|
|
||||||
phrases: vec![],
|
|
||||||
player: MIDIPlayer::new(jack, &clock, "preview")?,
|
|
||||||
transport: TransportModel {
|
|
||||||
metronome: false,
|
|
||||||
transport: jack.read().unwrap().transport(),
|
|
||||||
jack: jack.clone(),
|
|
||||||
clock: clock.clone()
|
|
||||||
},
|
|
||||||
}.into(), None, None))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: Engine> From<SequencerModel> for SequencerView<E> {
|
impl<E: Engine> From<SequencerModel> for SequencerView<E> {
|
||||||
fn from (model: SequencerModel) -> Self {
|
fn from (model: SequencerModel) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -88,7 +127,7 @@ impl Content for SequencerView<Tui> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Audio for SequencerView<Tui> {
|
impl<E: Engine> Audio for SequencerView<E> {
|
||||||
fn process (&mut self, client: &Client, scope: &ProcessScope) -> Control {
|
fn process (&mut self, client: &Client, scope: &ProcessScope) -> Control {
|
||||||
self.model.process(client, scope)
|
self.model.process(client, scope)
|
||||||
}
|
}
|
||||||
|
|
@ -112,48 +151,23 @@ impl Content for SequencerStatusBar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Handle<Tui> for SequencerApp<Tui> {
|
impl Command<SequencerApp<Tui>> for SequencerAppCommand {
|
||||||
fn handle (&mut self, i: &TuiInput) -> Perhaps<bool> {
|
fn execute (self, state: &mut SequencerApp<Tui>) -> Perhaps<Self> {
|
||||||
SequencerViewCommand::execute_with_state(self, i)
|
use AppViewCommand::*;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: Engine> Command<SequencerApp<E>> for SequencerViewCommand {
|
|
||||||
fn execute (self, state: &mut SequencerApp<E>) -> Perhaps<Self> {
|
|
||||||
match self {
|
match self {
|
||||||
Self::Focus(cmd) => delegate(cmd, Self::Focus, state),
|
Focus(cmd) => delegate(cmd, Focus, state),
|
||||||
Self::Phrases(cmd) => delegate(cmd, Self::Phrases, &mut state.phrases),
|
App(cmd) => delegate(cmd, App, state),
|
||||||
Self::Editor(cmd) => delegate(cmd, Self::Editor, &mut state.editor),
|
|
||||||
Self::Transport(cmd) => delegate(cmd, Self::Transport, &mut state.transport)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputToCommand<Tui, SequencerApp<Tui>> for SequencerViewCommand {
|
impl Command<SequencerApp<Tui>> for SequencerViewCommand {
|
||||||
fn input_to_command (state: &SequencerApp<Tui>, input: &TuiInput) -> Option<Self> {
|
fn execute (self, state: &mut SequencerApp<Tui>) -> Perhaps<Self> {
|
||||||
use AppViewFocus::*;
|
use SequencerViewCommand::*;
|
||||||
use FocusCommand::*;
|
match self {
|
||||||
match input.event() {
|
Phrases(cmd) => delegate(cmd, Phrases, &mut state.phrases),
|
||||||
key!(KeyCode::Tab) => Some(Self::Focus(Next)),
|
Editor(cmd) => delegate(cmd, Editor, &mut state.editor),
|
||||||
key!(Shift-KeyCode::Tab) => Some(Self::Focus(Prev)),
|
Transport(cmd) => delegate(cmd, Transport, &mut state.transport)
|
||||||
key!(KeyCode::BackTab) => Some(Self::Focus(Prev)),
|
|
||||||
key!(Shift-KeyCode::BackTab) => Some(Self::Focus(Prev)),
|
|
||||||
key!(KeyCode::Up) => Some(Self::Focus(Up)),
|
|
||||||
key!(KeyCode::Down) => Some(Self::Focus(Down)),
|
|
||||||
key!(KeyCode::Left) => Some(Self::Focus(Left)),
|
|
||||||
key!(KeyCode::Right) => Some(Self::Focus(Right)),
|
|
||||||
_ => match state.focused() {
|
|
||||||
Content(SequencerFocus::Transport) =>
|
|
||||||
TransportViewCommand::input_to_command(&state.transport, input)
|
|
||||||
.map(Self::Transport),
|
|
||||||
Content(SequencerFocus::PhrasePool) =>
|
|
||||||
PhrasePoolViewCommand::input_to_command(&state.phrases, input)
|
|
||||||
.map(Self::Phrases),
|
|
||||||
Content(SequencerFocus::PhraseEditor) =>
|
|
||||||
PhraseEditorCommand::input_to_command(&state.editor, input)
|
|
||||||
.map(Self::Editor),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue