mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
wip: refactor pt.10, 165 errors
This commit is contained in:
parent
1405b82341
commit
355b34c738
9 changed files with 96 additions and 204 deletions
|
|
@ -117,4 +117,37 @@ impl ArrangementScene {
|
||||||
//clips,
|
//clips,
|
||||||
//})
|
//})
|
||||||
//}
|
//}
|
||||||
|
pub fn ppqs (scenes: &[Self], factor: usize) -> Vec<(usize, usize)> {
|
||||||
|
let mut total = 0;
|
||||||
|
if factor == 0 {
|
||||||
|
scenes.iter().map(|scene|{
|
||||||
|
let pulses = scene.pulses().max(PPQ);
|
||||||
|
total = total + pulses;
|
||||||
|
(pulses, total - pulses)
|
||||||
|
}).collect()
|
||||||
|
} else {
|
||||||
|
(0..=scenes.len()).map(|i|{
|
||||||
|
(factor*PPQ, factor*PPQ*i)
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn longest_name (scenes: &[Self]) -> usize {
|
||||||
|
scenes.iter().map(|s|s.name.read().unwrap().len()).fold(0, usize::max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ArrangementTrack {
|
||||||
|
pub fn longest_name (tracks: &[Self]) -> usize {
|
||||||
|
tracks.iter().map(|s|s.name.read().unwrap().len()).fold(0, usize::max)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const MIN_WIDTH: usize = 3;
|
||||||
|
pub fn width_inc (&mut self) {
|
||||||
|
self.width += 1;
|
||||||
|
}
|
||||||
|
pub fn width_dec (&mut self) {
|
||||||
|
if self.width > Self::MIN_WIDTH {
|
||||||
|
self.width -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@ submod! {
|
||||||
tui_pool_length
|
tui_pool_length
|
||||||
tui_pool_rename
|
tui_pool_rename
|
||||||
|
|
||||||
tui_sampler
|
//tui_sampler // TODO
|
||||||
tui_sampler_cmd
|
//tui_sampler_cmd
|
||||||
|
|
||||||
tui_sequencer
|
tui_sequencer
|
||||||
tui_sequencer_bar
|
tui_sequencer_bar
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ where
|
||||||
C: Command<T>,
|
C: Command<T>,
|
||||||
U: From<Arc<RwLock<T>>> + Widget<Engine = E> + Handle<E>,
|
U: From<Arc<RwLock<T>>> + Widget<Engine = E> + Handle<E>,
|
||||||
A: From<Arc<RwLock<T>>> + Audio,
|
A: From<Arc<RwLock<T>>> + Audio,
|
||||||
S: From<Arc<RwLock<T>>> + Widget<Engine = E>
|
S: From<Arc<RwLock<T>>> + StatusBar<E>
|
||||||
{
|
{
|
||||||
fn from (model: T) -> Self {
|
fn from (model: T) -> Self {
|
||||||
let model = Arc::new(RwLock::new(model));
|
let model = Arc::new(RwLock::new(model));
|
||||||
|
|
@ -35,7 +35,7 @@ where
|
||||||
menu_bar: None,
|
menu_bar: None,
|
||||||
status_bar: None,
|
status_bar: None,
|
||||||
history: vec![],
|
history: vec![],
|
||||||
size: (0, 0).into(),
|
size: Measure::new(),
|
||||||
ui: U::from(model.clone()),
|
ui: U::from(model.clone()),
|
||||||
audio: A::from(model.clone()),
|
audio: A::from(model.clone()),
|
||||||
model,
|
model,
|
||||||
|
|
|
||||||
|
|
@ -447,28 +447,6 @@ impl<E: Engine> Arrangement<E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ArrangementTrack {
|
|
||||||
pub fn new (
|
|
||||||
jack: &Arc<RwLock<JackClient>>,
|
|
||||||
clock: &Arc<Clock>,
|
|
||||||
name: &str,
|
|
||||||
color: Option<ItemColor>
|
|
||||||
) -> Usually<Self> {
|
|
||||||
Ok(Self {
|
|
||||||
name: Arc::new(RwLock::new(name.into())),
|
|
||||||
width: name.len() + 2,
|
|
||||||
color: color.unwrap_or_else(ItemColor::random),
|
|
||||||
player: PhrasePlayer::new(&jack, clock, name)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
pub fn longest_name (tracks: &[Self]) -> usize {
|
|
||||||
tracks.iter().map(|s|s.name.read().unwrap().len()).fold(0, usize::max)
|
|
||||||
}
|
|
||||||
pub const MIN_WIDTH: usize = 3;
|
|
||||||
pub fn width_inc (&mut self) { self.width += 1; }
|
|
||||||
pub fn width_dec (&mut self) { if self.width > Self::MIN_WIDTH { self.width -= 1; } }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Arranger display mode can be cycled
|
/// Arranger display mode can be cycled
|
||||||
impl ArrangementEditorMode {
|
impl ArrangementEditorMode {
|
||||||
/// Cycle arranger display mode
|
/// Cycle arranger display mode
|
||||||
|
|
@ -482,33 +460,3 @@ impl ArrangementEditorMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl ArrangementScene {
|
|
||||||
pub fn new (
|
|
||||||
name: impl AsRef<str>,
|
|
||||||
clips: impl AsRef<[Option<Arc<RwLock<Phrase>>>]>,
|
|
||||||
color: Option<ItemColor>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
name: Arc::new(RwLock::new(name.as_ref().into())),
|
|
||||||
clips: clips.as_ref().iter().map(|x|x.clone()).collect(),
|
|
||||||
color: color.unwrap_or_else(ItemColor::random),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn ppqs (scenes: &[Self], factor: usize) -> Vec<(usize, usize)> {
|
|
||||||
let mut total = 0;
|
|
||||||
if factor == 0 {
|
|
||||||
scenes.iter().map(|scene|{
|
|
||||||
let pulses = scene.pulses().max(PPQ);
|
|
||||||
total = total + pulses;
|
|
||||||
(pulses, total - pulses)
|
|
||||||
}).collect()
|
|
||||||
} else {
|
|
||||||
(0..=scenes.len()).map(|i|{
|
|
||||||
(factor*PPQ, factor*PPQ*i)
|
|
||||||
}).collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn longest_name (scenes: &[Self]) -> usize {
|
|
||||||
scenes.iter().map(|s|s.name.read().unwrap().len()).fold(0, usize::max)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,6 @@ impl Content for ArrangerStatusBar {
|
||||||
//.cmd("s", "Save project", ArrangerViewCommand::Arrangement(Save))
|
//.cmd("s", "Save project", ArrangerViewCommand::Arrangement(Save))
|
||||||
//})
|
//})
|
||||||
//.add({
|
//.add({
|
||||||
//use TransportViewCommand::*;
|
|
||||||
//Menu::new("Transport")
|
//Menu::new("Transport")
|
||||||
//.cmd("p", "Play", TransportCommand::Transport(Play(None)))
|
//.cmd("p", "Play", TransportCommand::Transport(Play(None)))
|
||||||
//.cmd("P", "Play from start", TransportCommand::Transport(Play(Some(0))))
|
//.cmd("P", "Play from start", TransportCommand::Transport(Play(Some(0))))
|
||||||
|
|
|
||||||
|
|
@ -3,27 +3,16 @@ use crate::*;
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum ArrangerViewCommand {
|
pub enum ArrangerViewCommand {
|
||||||
Focus(FocusCommand),
|
Focus(FocusCommand),
|
||||||
Transport(TransportCommand),
|
|
||||||
Arrangement(ArrangementEditorCommand),
|
Arrangement(ArrangementEditorCommand),
|
||||||
EditPhrase(Option<Arc<RwLock<Phrase>>>),
|
Transport(TransportCommand),
|
||||||
Phrases(PhrasePoolCommand),
|
Phrases(PhrasePoolCommand),
|
||||||
Editor(PhraseEditorCommand),
|
Editor(PhraseEditorCommand),
|
||||||
|
EditPhrase(Option<Arc<RwLock<Phrase>>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle top-level events in standalone arranger.
|
/// Handle top-level events in standalone arranger.
|
||||||
impl Handle<Tui> for ArrangerView<Tui> {
|
impl Handle<Tui> for ArrangerView<Tui> {
|
||||||
fn handle (&mut self, i: &TuiInput) -> Perhaps<bool> {
|
fn handle (&mut self, i: &TuiInput) -> Perhaps<bool> {
|
||||||
if let Some(entered) = self.entered() {
|
|
||||||
use ArrangerViewFocus::*;
|
|
||||||
if let Some(true) = match entered {
|
|
||||||
Transport => self.sequencer.transport.map(|t|t.handle(i)).transpose()?.flatten(),
|
|
||||||
Arrangement => self.arrangement.handle(i)?,
|
|
||||||
PhrasePool => self.sequencer.phrases.handle(i)?,
|
|
||||||
PhraseEditor => self.sequencer.editor.handle(i)?,
|
|
||||||
} {
|
|
||||||
return Ok(Some(true))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ArrangerViewCommand::execute_with_state(self, i)
|
ArrangerViewCommand::execute_with_state(self, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -70,87 +59,28 @@ impl InputToCommand<Tui, ArrangerView<Tui>> for ArrangerViewCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//impl ArrangerView<Tui> {
|
|
||||||
///// Helper for event passthru to focused component
|
|
||||||
//fn handle_focused (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
|
||||||
//match self.focused() {
|
|
||||||
//ArrangerViewFocus::Transport => self.transport.handle(from),
|
|
||||||
//ArrangerViewFocus::PhrasePool => self.handle_pool(from),
|
|
||||||
//ArrangerViewFocus::PhraseEditor => self.editor.handle(from),
|
|
||||||
//ArrangerViewFocus::Arrangement => self.handle_arrangement(from)
|
|
||||||
//.and_then(|result|{self.show_phrase();Ok(result)}),
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
///// Helper for phrase event passthru when phrase pool is focused
|
|
||||||
//fn handle_pool (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
|
||||||
//match from.event() {
|
|
||||||
//key!(KeyCode::Char('<')) => {
|
|
||||||
//self.phrases_split = self.phrases_split.saturating_sub(1).max(12);
|
|
||||||
//},
|
|
||||||
//key!(KeyCode::Char('>')) => {
|
|
||||||
//self.phrases_split = self.phrases_split + 1;
|
|
||||||
//},
|
|
||||||
//_ => return self.phrases.handle(from)
|
|
||||||
//}
|
|
||||||
//Ok(Some(true))
|
|
||||||
//}
|
|
||||||
///// Helper for phrase event passthru when arrangement is focused
|
|
||||||
//fn handle_arrangement (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
|
||||||
//let mut handle_phrase = ||{
|
|
||||||
//let result = self.phrases.handle(from);
|
|
||||||
//self.arrangement.phrase_put();
|
|
||||||
//result
|
|
||||||
//};
|
|
||||||
//match from.event() {
|
|
||||||
//key!(KeyCode::Char('a')) => return handle_phrase(),
|
|
||||||
//key!(KeyCode::Char('i')) => return handle_phrase(),
|
|
||||||
//key!(KeyCode::Char('d')) => return handle_phrase(),
|
|
||||||
//key!(KeyCode::Char('<')) => if self.arrangement.selected == ArrangementFocus::Mix {
|
|
||||||
//self.arrangement_split = self.arrangement_split.saturating_sub(1).max(12);
|
|
||||||
//} else {
|
|
||||||
//return self.arrangement.handle(from)
|
|
||||||
//},
|
|
||||||
//key!(KeyCode::Char('>')) => if self.arrangement.selected == ArrangementFocus::Mix {
|
|
||||||
//self.arrangement_split = self.arrangement_split + 1;
|
|
||||||
//} else {
|
|
||||||
//return self.arrangement.handle(from)
|
|
||||||
//},
|
|
||||||
//_ => return self.arrangement.handle(from)
|
|
||||||
//}
|
|
||||||
//self.show_phrase();
|
|
||||||
//Ok(Some(true))
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
|
|
||||||
impl<E: Engine> Command<ArrangerView<E>> for ArrangerViewCommand {
|
impl<E: Engine> Command<ArrangerView<E>> for ArrangerViewCommand {
|
||||||
fn execute (self, state: &mut ArrangerView<E>) -> Perhaps<Self> {
|
fn execute (self, view: &mut ArrangerView<E>) -> Perhaps<Self> {
|
||||||
let undo = match self {
|
let undo = match self {
|
||||||
Self::Focus(cmd) => {
|
Self::Focus(cmd) =>
|
||||||
delegate(cmd, Self::Focus, state)
|
delegate(cmd, Self::Focus, view),
|
||||||
},
|
Self::Phrases(cmd) =>
|
||||||
Self::Phrases(cmd) => {
|
delegate(cmd, Self::Phrases, &mut view.sequencer.phrases),
|
||||||
delegate(cmd, Self::Phrases, &mut*state.sequencer.phrases.write().unwrap())
|
Self::Editor(cmd) =>
|
||||||
},
|
delegate(cmd, Self::Editor, &mut view.sequencer.editor),
|
||||||
Self::Editor(cmd) => {
|
Self::Transport(cmd) =>
|
||||||
delegate(cmd, Self::Editor, &mut state.sequencer.editor)
|
delegate(cmd, Self::Transport, &mut view.sequencer.transport.state),
|
||||||
},
|
Self::Arrangement(cmd) =>
|
||||||
Self::Arrangement(cmd) => {
|
delegate(cmd, Self::Arrangement, &mut view.arrangement),
|
||||||
delegate(cmd, Self::Arrangement, &mut state.arrangement)
|
|
||||||
},
|
|
||||||
Self::Transport(cmd) => if let Some(ref transport) = state.sequencer.transport {
|
|
||||||
delegate(cmd, Self::Transport, &mut*transport.write().unwrap())
|
|
||||||
} else {
|
|
||||||
Ok(None)
|
|
||||||
},
|
|
||||||
Self::EditPhrase(phrase) => {
|
Self::EditPhrase(phrase) => {
|
||||||
state.sequencer.editor.phrase = phrase.clone();
|
view.sequencer.editor.phrase = phrase.clone();
|
||||||
state.focus(ArrangerViewFocus::PhraseEditor);
|
view.focus(ArrangerViewFocus::PhraseEditor);
|
||||||
state.focus_enter();
|
view.focus_enter();
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}?;
|
}?;
|
||||||
state.sequencer.show_phrase();
|
view.sequencer.show_phrase();
|
||||||
state.sequencer.update_status();
|
view.sequencer.update_status();
|
||||||
return Ok(undo);
|
return Ok(undo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,77 +3,55 @@ use crate::*;
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub enum SequencerViewCommand {
|
pub enum SequencerViewCommand {
|
||||||
Focus(FocusCommand),
|
Focus(FocusCommand),
|
||||||
Transport(TransportCommand),
|
Transport(TransportViewCommand),
|
||||||
Phrases(PhrasePoolCommand),
|
Phrases(PhrasePoolViewCommand),
|
||||||
Editor(PhraseEditorCommand),
|
Editor(PhraseEditorCommand),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Handle<Tui> for SequencerView<Tui> {
|
impl Handle<Tui> for SequencerView<Tui> {
|
||||||
fn handle (&mut self, i: &TuiInput) -> Perhaps<bool> {
|
fn handle (&mut self, i: &TuiInput) -> Perhaps<bool> {
|
||||||
if let Some(entered) = self.entered() {
|
SequencerViewCommand::execute_with_state(self, i)
|
||||||
use SequencerFocus::*;
|
|
||||||
if let Some(true) = match entered {
|
|
||||||
Transport => self.transport.as_mut().map(|t|t.handle(i)).transpose()?.flatten(),
|
|
||||||
PhrasePool => self.phrases.write().unwrap().handle(i)?,
|
|
||||||
PhraseEditor => self.editor.handle(i)?,
|
|
||||||
} {
|
|
||||||
return Ok(Some(true))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(command) = SequencerCommand::input_to_command(self, i) {
|
|
||||||
let _undo = command.execute(self)?;
|
|
||||||
return Ok(Some(true))
|
|
||||||
}
|
|
||||||
Ok(None)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine> Command<SequencerView<E>> for SequencerViewCommand {
|
impl<E: Engine> Command<SequencerView<E>> for SequencerViewCommand {
|
||||||
fn execute (self, state: &mut SequencerView<E>) -> Perhaps<Self> {
|
fn execute (self, state: &mut SequencerView<E>) -> Perhaps<Self> {
|
||||||
match self {
|
match self {
|
||||||
Self::Focus(cmd) => {
|
Self::Focus(cmd) =>
|
||||||
return delegate(cmd, Self::Focus, state)
|
delegate(cmd, Self::Focus, state),
|
||||||
},
|
Self::Phrases(cmd) =>
|
||||||
Self::Phrases(cmd) => {
|
delegate(cmd, Self::Phrases, &mut state.phrases),
|
||||||
return delegate(cmd, Self::Phrases, &mut*state.phrases.write().unwrap())
|
Self::Editor(cmd) =>
|
||||||
},
|
delegate(cmd, Self::Editor, &mut state.editor),
|
||||||
Self::Editor(cmd) => {
|
Self::Transport(cmd) =>
|
||||||
return delegate(cmd, Self::Editor, &mut state.editor)
|
delegate(cmd, Self::Transport, &mut state.transport)
|
||||||
},
|
|
||||||
Self::Transport(cmd) => if let Some(ref transport) = state.transport {
|
|
||||||
return delegate(cmd, Self::Transport, &mut*transport.write().unwrap())
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
Ok(None)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputToCommand<Tui, SequencerView<Tui>> for SequencerViewCommand {
|
impl InputToCommand<Tui, SequencerView<Tui>> for SequencerViewCommand {
|
||||||
fn input_to_command (state: &SequencerView<Tui>, input: &TuiInput) -> Option<Self> {
|
fn input_to_command (state: &SequencerView<Tui>, input: &TuiInput) -> Option<Self> {
|
||||||
use SequencerViewCommand::*;
|
|
||||||
use FocusCommand::*;
|
use FocusCommand::*;
|
||||||
match input.event() {
|
match input.event() {
|
||||||
key!(KeyCode::Tab) => Some(Focus(Next)),
|
key!(KeyCode::Tab) => Some(Self::Focus(Next)),
|
||||||
key!(Shift-KeyCode::Tab) => Some(Focus(Prev)),
|
key!(Shift-KeyCode::Tab) => Some(Self::Focus(Prev)),
|
||||||
key!(KeyCode::BackTab) => Some(Focus(Prev)),
|
key!(KeyCode::BackTab) => Some(Self::Focus(Prev)),
|
||||||
key!(Shift-KeyCode::BackTab) => Some(Focus(Prev)),
|
key!(Shift-KeyCode::BackTab) => Some(Self::Focus(Prev)),
|
||||||
key!(KeyCode::Up) => Some(Focus(Up)),
|
key!(KeyCode::Up) => Some(Self::Focus(Up)),
|
||||||
key!(KeyCode::Down) => Some(Focus(Down)),
|
key!(KeyCode::Down) => Some(Self::Focus(Down)),
|
||||||
key!(KeyCode::Left) => Some(Focus(Left)),
|
key!(KeyCode::Left) => Some(Self::Focus(Left)),
|
||||||
key!(KeyCode::Right) => Some(Focus(Right)),
|
key!(KeyCode::Right) => Some(Self::Focus(Right)),
|
||||||
//key!(KeyCode::Char(' ')) => Some(Transport(TransportViewCommand::PlayToggle)),
|
|
||||||
_ => match state.focused() {
|
_ => match state.focused() {
|
||||||
SequencerFocus::Transport => if let Some(t) = state.transport.as_ref() {
|
SequencerFocus::Transport => TransportViewCommand::input_to_command(
|
||||||
TransportViewCommand::input_to_command(&*t.read().unwrap(), input).map(Transport)
|
&state.transport, input
|
||||||
} else {
|
).map(Self::Transport),
|
||||||
None
|
SequencerFocus::PhrasePool => PhrasePoolViewCommand::input_to_command(
|
||||||
},
|
&state.phrases, input
|
||||||
SequencerFocus::PhrasePool =>
|
).map(Self::Phrases),
|
||||||
PhrasePoolCommand::input_to_command(&*state.phrases.read().unwrap(), input)
|
SequencerFocus::PhraseEditor => PhraseEditorCommand::input_to_command(
|
||||||
.map(Phrases),
|
&state.editor, input
|
||||||
SequencerFocus::PhraseEditor =>
|
).map(Self::Editor),
|
||||||
PhraseEditorCommand::input_to_command(&state.editor, input)
|
|
||||||
.map(Editor),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use crate::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Focus layout of sequencer app
|
/// Focus layout of sequencer app
|
||||||
impl<E: Engine> FocusGrid for Sequencer<E> {
|
impl<E: Engine> FocusGrid for SequencerView<E> {
|
||||||
type Item = SequencerFocus;
|
type Item = SequencerFocus;
|
||||||
fn cursor (&self) -> (usize, usize) {
|
fn cursor (&self) -> (usize, usize) {
|
||||||
self.focus_cursor
|
self.focus_cursor
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
pub enum TransportViewCommand {
|
pub enum TransportViewCommand {
|
||||||
Focus(FocusCommand),
|
Focus(FocusCommand),
|
||||||
Transport(TransportCommand),
|
Transport(TransportCommand),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Handle<Tui> for TransportView<Tui> {
|
impl Handle<Tui> for TransportView<Tui> {
|
||||||
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
||||||
TransportViewCommand::execute_with_state(self, from)
|
TransportViewCommand::execute_with_state(self, from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputToCommand<Tui, TransportView<Tui>> for TransportViewCommand {
|
impl InputToCommand<Tui, TransportView<Tui>> for TransportViewCommand {
|
||||||
fn input_to_command (state: &TransportView<Tui>, input: &TuiInput) -> Option<Self> {
|
fn input_to_command (state: &TransportView<Tui>, input: &TuiInput) -> Option<Self> {
|
||||||
use TransportViewFocus as Focus;
|
use TransportViewFocus as Focus;
|
||||||
|
|
@ -55,15 +58,16 @@ impl InputToCommand<Tui, TransportView<Tui>> for TransportViewCommand {
|
||||||
|
|
||||||
impl<E: Engine> Command<TransportView<E>> for TransportViewCommand {
|
impl<E: Engine> Command<TransportView<E>> for TransportViewCommand {
|
||||||
fn execute (self, state: &mut TransportView<E>) -> Perhaps<Self> {
|
fn execute (self, state: &mut TransportView<E>) -> Perhaps<Self> {
|
||||||
Ok(match self {
|
Ok(Some(match self {
|
||||||
Self::Focus(command) => {
|
Self::Focus(command) => Self::Focus({
|
||||||
use FocusCommand::*;
|
use FocusCommand::*;
|
||||||
match command {
|
match command {
|
||||||
Next => { todo!() },
|
Next => { todo!() },
|
||||||
Prev => { todo!() },
|
Prev => { todo!() },
|
||||||
|
_ => { todo!() }
|
||||||
}
|
}
|
||||||
},
|
}),
|
||||||
Self::Transport(command) => {
|
Self::Transport(command) => Self::Transport({
|
||||||
use TransportCommand::*;
|
use TransportCommand::*;
|
||||||
match command {
|
match command {
|
||||||
SetBpm(bpm) => SetBpm(state.state.clock.timebase().bpm.set(bpm)),
|
SetBpm(bpm) => SetBpm(state.state.clock.timebase().bpm.set(bpm)),
|
||||||
|
|
@ -71,7 +75,7 @@ impl<E: Engine> Command<TransportView<E>> for TransportViewCommand {
|
||||||
SetSync(sync) => SetSync(state.state.clock.sync.set(sync)),
|
SetSync(sync) => SetSync(state.state.clock.sync.set(sync)),
|
||||||
_ => { todo!() }
|
_ => { todo!() }
|
||||||
}
|
}
|
||||||
},
|
}),
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue