wip: refactor pt.32: 89 errors, traits

This commit is contained in:
🪞👃🪞 2024-11-15 00:17:36 +01:00
parent 8b5931c321
commit ce78b95d8a
28 changed files with 946 additions and 822 deletions

View file

@ -62,21 +62,21 @@ 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(TransportViewCommand::Transport(TransportCommand::Play(None))))
Self::App(Transport(TransportCommand::Play(None)))
},
_ => Self::App(match view.focused() {
Content(ArrangerViewFocus::Transport) => Transport(
TransportViewCommand::input_to_command(&view.sequencer.transport, input)?
TransportCommand::input_to_command(&view.app.sequencer.transport, input)?
),
Content(ArrangerViewFocus::PhraseEditor) => Editor(
PhraseEditorCommand::input_to_command(&view.sequencer.editor, input)?
PhraseEditorCommand::input_to_command(&view.app.sequencer.editor, input)?
),
Content(ArrangerViewFocus::PhrasePool) => match input.event() {
key!(KeyCode::Char('e')) => EditPhrase(
Some(view.sequencer.phrases.phrase().clone())
Some(view.app.phrases.phrase().clone())
),
_ => Phrases(
PhrasePoolViewCommand::input_to_command(&view.sequencer.phrases, input)?
PhrasePoolViewCommand::input_to_command(&view.app.phrases, input)?
)
},
Content(ArrangerViewFocus::Arranger) => {
@ -237,23 +237,23 @@ impl Command<ArrangerApp<Tui>> for ArrangerViewCommand {
/// Root view for standalone `tek_arranger`
pub struct ArrangerView<E: Engine> {
pub model: ArrangerModel,
/// Sequencer component
pub sequencer: SequencerView<E>,
/// Height of arrangement
pub split: u16,
/// Currently selected element.
pub selected: ArrangerSelection,
/// Display mode of arranger
pub mode: ArrangerMode,
/// Background color of arrangement
pub color: ItemColor,
/// Whether the arranger is currently focused
pub focused: bool,
/// Whether this is currently in edit mode
pub entered: bool,
/// Width and height of arrangement area at last render
pub size: Measure<E>,
jack: Arc<RwLock<JackClient>>,
clock: Arc<Clock>,
transport: jack::Transport,
metronome: bool,
transport: TransportModel,
phrases: Vec<Arc<RwLock<Phrase>>>,
tracks: Vec<ArrangerTrack>,
scenes: Vec<ArrangerScene>,
name: Arc<RwLock<String>>,
sequencer: SequencerView<E>,
splits: [u16;2],
selected: ArrangerSelection,
mode: ArrangerMode,
color: ItemColor,
focused: bool,
entered: bool,
size: Measure<E>,
}
/// Display mode of arranger

View file

@ -72,15 +72,15 @@ impl InputToCommand<Tui, SequencerApp<Tui>> for SequencerAppCommand {
/// Root view for standalone `tek_sequencer`.
pub struct SequencerView<E: Engine> {
pub model: SequencerModel,
/// Displays the JACK transport.
pub transport: TransportView<E>,
/// Displays the phrase pool
pub phrases: PhrasePoolView<E>,
/// Displays the phrase editor
pub editor: PhraseEditor<E>,
/// Width of phrase pool
pub split: u16,
jack: Arc<RwLock<JackClient>>,
clock: Arc<Clock>,
transport: jack::Transport,
metronome: bool,
phrases: Vec<Arc<RwLock<Phrase>>>,
player: MIDIPlayer,
phrases: PhrasePoolView<E>,
editor: PhraseEditor<E>,
split: u16,
}
/// Sections in the sequencer app that may be focused

View file

@ -32,48 +32,57 @@ pub type TransportAppCommand = AppViewCommand<TransportCommand>;
impl InputToCommand<Tui, TransportApp<Tui>> for TransportAppCommand {
fn input_to_command (app: &TransportApp<Tui>, input: &TuiInput) -> Option<Self> {
use TransportViewFocus as Focus;
use FocusCommand as FocusCmd;
use TransportCommand as Cmd;
use KeyCode::{Left, Right};
use FocusCommand::{Prev, Next};
use AppViewCommand::{Focus, App};
Some(match input.event() {
key!(Left) => Focus(Prev),
key!(Right) => Focus(Next),
_ => TransportCommand::input_to_command(app.app, input).map(App)
})
}
}
impl InputToCommand<Tui, TransportApp<Tui>> for TransportCommand {
fn input_to_command (app: &TransportApp<Tui>, input: &TuiInput) -> Option<Self> {
use KeyCode::Char;
use AppViewFocus::Content;
use TransportCommand::{SetBpm, SetQuant, SetSync};
use TransportViewFocus::{Bpm, Quant, Sync, PlayPause, Clock};
let clock = app.app.model.clock();
Some(match input.event() {
key!(KeyCode::Left) => Self::Focus(FocusCmd::Prev),
key!(KeyCode::Right) => Self::Focus(FocusCmd::Next),
key!(KeyCode::Char('.')) => Self::App(match app.focused() {
AppViewFocus::Content(Focus::Bpm) => Cmd::SetBpm(clock.timebase().bpm.get() + 1.0),
AppViewFocus::Content(Focus::Quant) => Cmd::SetQuant(next_note_length(clock.quant.get()as usize)as f64),
AppViewFocus::Content(Focus::Sync) => Cmd::SetSync(next_note_length(clock.sync.get()as usize)as f64+1.),
AppViewFocus::Content(Focus::PlayPause) => {todo!()},
AppViewFocus::Content(Focus::Clock) => {todo!()},
key!(Char('.')) => match app.focused() {
Content(Bpm) => SetBpm(clock.timebase().bpm.get() + 1.0),
Content(Quant) => SetQuant(next_note_length(clock.quant.get()as usize)as f64),
Content(Sync) => SetSync(next_note_length(clock.sync.get()as usize)as f64+1.),
Content(PlayPause) => {todo!()},
Content(Clock) => {todo!()},
_ => {todo!()}
}),
key!(KeyCode::Char(',')) => Self::App(match app.focused() {
AppViewFocus::Content(Focus::Bpm) => Cmd::SetBpm(clock.timebase().bpm.get() - 1.0),
AppViewFocus::Content(Focus::Quant) => Cmd::SetQuant(prev_note_length(clock.quant.get()as usize)as f64),
AppViewFocus::Content(Focus::Sync) => Cmd::SetSync(prev_note_length(clock.sync.get()as usize)as f64+1.),
AppViewFocus::Content(Focus::PlayPause) => {todo!()},
AppViewFocus::Content(Focus::Clock) => {todo!()}
},
key!(KeyCode::Char(',')) => match app.focused() {
Content(Bpm) => SetBpm(clock.timebase().bpm.get() - 1.0),
Content(Quant) => SetQuant(prev_note_length(clock.quant.get()as usize)as f64),
Content(Sync) => SetSync(prev_note_length(clock.sync.get()as usize)as f64+1.),
Content(PlayPause) => {todo!()},
Content(Clock) => {todo!()}
_ => {todo!()}
}),
key!(KeyCode::Char('>')) => Self::App(match app.focused() {
AppViewFocus::Content(Focus::Bpm) => Cmd::SetBpm(clock.timebase().bpm.get() + 0.001),
AppViewFocus::Content(Focus::Quant) => Cmd::SetQuant(next_note_length(clock.quant.get()as usize)as f64),
AppViewFocus::Content(Focus::Sync) => Cmd::SetSync(next_note_length(clock.sync.get()as usize)as f64+1.),
AppViewFocus::Content(Focus::PlayPause) => {todo!()},
AppViewFocus::Content(Focus::Clock) => {todo!()}
},
key!(KeyCode::Char('>')) => match app.focused() {
Content(Bpm) => SetBpm(clock.timebase().bpm.get() + 0.001),
Content(Quant) => SetQuant(next_note_length(clock.quant.get()as usize)as f64),
Content(Sync) => SetSync(next_note_length(clock.sync.get()as usize)as f64+1.),
Content(PlayPause) => {todo!()},
Content(Clock) => {todo!()}
_ => {todo!()}
}),
key!(KeyCode::Char('<')) => Self::App(match app.focused() {
AppViewFocus::Content(Focus::Bpm) => Cmd::SetBpm(clock.timebase().bpm.get() - 0.001),
AppViewFocus::Content(Focus::Quant) => Cmd::SetQuant(prev_note_length(clock.quant.get()as usize)as f64),
AppViewFocus::Content(Focus::Sync) => Cmd::SetSync(prev_note_length(clock.sync.get()as usize)as f64+1.),
AppViewFocus::Content(Focus::PlayPause) => {todo!()},
AppViewFocus::Content(Focus::Clock) => {todo!()}
},
key!(KeyCode::Char('<')) => match app.focused() {
Content(Bpm) => SetBpm(clock.timebase().bpm.get() - 0.001),
Content(Quant) => SetQuant(prev_note_length(clock.quant.get()as usize)as f64),
Content(Sync) => SetSync(prev_note_length(clock.sync.get()as usize)as f64+1.),
Content(PlayPause) => {todo!()},
Content(Clock) => {todo!()}
_ => {todo!()}
}),
},
_ => return None
})
}
@ -81,32 +90,37 @@ impl InputToCommand<Tui, TransportApp<Tui>> for TransportAppCommand {
impl Command<TransportApp<Tui>> for TransportAppCommand {
fn execute (self, state: &mut TransportApp<Tui>) -> Perhaps<Self> {
let clock = state.app.model.clock();
use AppViewCommand::{Focus, App};
use FocusCommand::{Next, Prev};
Ok(Some(match self {
Self::Focus(command) => Self::Focus({
use FocusCommand::*;
match command {
Next => { todo!() },
Prev => { todo!() },
_ => { todo!() }
}
}),
Self::App(command) => Self::App({
use TransportCommand::*;
match command {
SetBpm(bpm) => SetBpm(clock.timebase().bpm.set(bpm)),
SetQuant(quant) => SetQuant(clock.quant.set(quant)),
SetSync(sync) => SetSync(clock.sync.set(sync)),
_ => {
todo!()
}
}
App(command) => if let Some(undo) = TransportCommand::execute(command, state)? {
App(undo)
} else {
return Ok(None)
},
Focus(command) => Focus(match command {
Next => { todo!() },
Prev => { todo!() },
_ => { todo!() }
}),
_ => todo!()
}))
}
}
impl Command<TransportApp<Tui>> for TransportCommand {
fn execute (self, state: &mut TransportApp<Tui>) -> Perhaps<Self> {
use TransportCommand::{SetBpm, SetQuant, SetSync};
let clock = state.app.model.clock();
Ok(Some(match self {
SetBpm(bpm) => SetBpm(clock.timebase().bpm.set(bpm)),
SetQuant(quant) => SetQuant(clock.quant.set(quant)),
SetSync(sync) => SetSync(clock.sync.set(sync)),
_ => return Ok(None)
}))
}
}
impl<E: Engine> From<TransportModel> for TransportView<E> {
fn from (model: TransportModel) -> Self {
Self {
@ -122,11 +136,17 @@ impl<E: Engine> From<TransportModel> for TransportView<E> {
/// Stores and displays time-related info.
#[derive(Debug)]
pub struct TransportView<E: Engine> {
_engine: PhantomData<E>,
pub model: TransportModel,
pub focus: TransportViewFocus,
pub focused: bool,
pub size: Measure<E>,
_engine: PhantomData<E>,
jack: Arc<RwLock<JackClient>>,
/// Current sample rate, tempo, and PPQ.
clock: Arc<Clock>,
/// JACK transport handle.
transport: jack::Transport,
/// Enable metronome?
metronome: bool,
focus: TransportViewFocus,
focused: bool,
size: Measure<E>,
}
/// Which item of the transport toolbar is focused