mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 20:26:42 +01:00
wip: refactor pt.30: 74 errors
This commit is contained in:
parent
ab85a86b6b
commit
28e15d3f56
12 changed files with 631 additions and 622 deletions
|
|
@ -1,12 +1,6 @@
|
|||
use crate::*;
|
||||
|
||||
pub type TransportApp<E: Engine> = AppView<
|
||||
E,
|
||||
TransportView<E>,
|
||||
TransportViewCommand,
|
||||
TransportStatusBar
|
||||
>;
|
||||
|
||||
/// Create app state from JACK handle.
|
||||
impl TryFrom<&Arc<RwLock<JackClient>>> for TransportApp<Tui> {
|
||||
type Error = Box<dyn std::error::Error>;
|
||||
fn try_from (jack: &Arc<RwLock<JackClient>>) -> Usually<Self> {
|
||||
|
|
@ -19,14 +13,98 @@ impl TryFrom<&Arc<RwLock<JackClient>>> for TransportApp<Tui> {
|
|||
}
|
||||
}
|
||||
|
||||
/// 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>,
|
||||
/// Root type of application.
|
||||
pub type TransportApp<E: Engine> = AppView<
|
||||
E,
|
||||
TransportView<E>,
|
||||
TransportAppCommand,
|
||||
TransportStatusBar
|
||||
>;
|
||||
|
||||
/// Handle input.
|
||||
impl Handle<Tui> for TransportApp<Tui> {
|
||||
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
||||
TransportAppCommand::execute_with_state(self, from)
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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!()},
|
||||
_ => {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!()}
|
||||
_ => {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!()}
|
||||
_ => {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!()}
|
||||
_ => {todo!()}
|
||||
}),
|
||||
|
||||
_ => return None
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Command<TransportApp<Tui>> for TransportAppCommand {
|
||||
fn execute (self, state: &mut TransportApp<Tui>) -> Perhaps<Self> {
|
||||
let clock = state.app.model.clock();
|
||||
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!()
|
||||
}
|
||||
}
|
||||
}),
|
||||
_ => todo!()
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine> From<TransportModel> for TransportView<E> {
|
||||
|
|
@ -41,6 +119,58 @@ 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>,
|
||||
}
|
||||
|
||||
/// Which item of the transport toolbar is focused
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum TransportViewFocus {
|
||||
Bpm,
|
||||
Sync,
|
||||
PlayPause,
|
||||
Clock,
|
||||
Quant,
|
||||
}
|
||||
|
||||
impl TransportViewFocus {
|
||||
pub fn next (&mut self) {
|
||||
*self = match self {
|
||||
Self::PlayPause => Self::Bpm,
|
||||
Self::Bpm => Self::Quant,
|
||||
Self::Quant => Self::Sync,
|
||||
Self::Sync => Self::Clock,
|
||||
Self::Clock => Self::PlayPause,
|
||||
}
|
||||
}
|
||||
pub fn prev (&mut self) {
|
||||
*self = match self {
|
||||
Self::PlayPause => Self::Clock,
|
||||
Self::Bpm => Self::PlayPause,
|
||||
Self::Quant => Self::Bpm,
|
||||
Self::Sync => Self::Quant,
|
||||
Self::Clock => Self::Sync,
|
||||
}
|
||||
}
|
||||
pub fn wrap <'a, W: Widget<Engine = Tui>> (
|
||||
self, parent_focus: bool, focus: Self, widget: &'a W
|
||||
) -> impl Widget<Engine = Tui> + 'a {
|
||||
let focused = parent_focus && focus == self;
|
||||
let corners = focused.then_some(CORNERS);
|
||||
let highlight = focused.then_some(Background(Color::Rgb(60, 70, 50)));
|
||||
lay!(corners, highlight, *widget)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct TransportStatusBar;
|
||||
|
||||
impl Content for TransportView<Tui> {
|
||||
type Engine = Tui;
|
||||
fn content (&self) -> impl Widget<Engine = Tui> {
|
||||
|
|
@ -84,9 +214,6 @@ impl Audio for TransportView<Tui> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct TransportStatusBar;
|
||||
|
||||
impl StatusBar for TransportStatusBar {
|
||||
type State = ();
|
||||
fn hotkey_fg () -> Color {
|
||||
|
|
@ -105,129 +232,6 @@ impl Content for TransportStatusBar {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum TransportViewCommand {
|
||||
Focus(FocusCommand),
|
||||
Transport(TransportCommand),
|
||||
}
|
||||
|
||||
impl Handle<Tui> for TransportView<Tui> {
|
||||
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
||||
TransportViewCommand::execute_with_state(self, from)
|
||||
}
|
||||
}
|
||||
|
||||
impl InputToCommand<Tui, TransportView<Tui>> for TransportViewCommand {
|
||||
fn input_to_command (view: &TransportView<Tui>, input: &TuiInput) -> Option<Self> {
|
||||
use TransportViewFocus as Focus;
|
||||
use FocusCommand as FocusCmd;
|
||||
use TransportCommand as Cmd;
|
||||
let clock = view.model.clock();
|
||||
Some(match input.event() {
|
||||
|
||||
key!(KeyCode::Left) => Self::Focus(FocusCmd::Prev),
|
||||
key!(KeyCode::Right) => Self::Focus(FocusCmd::Next),
|
||||
|
||||
key!(KeyCode::Char('.')) => Self::Transport(match view.focus {
|
||||
Focus::Bpm => Cmd::SetBpm(clock.timebase().bpm.get() + 1.0),
|
||||
Focus::Quant => Cmd::SetQuant(next_note_length(clock.quant.get()as usize)as f64),
|
||||
Focus::Sync => Cmd::SetSync(next_note_length(clock.sync.get()as usize)as f64+1.),
|
||||
Focus::PlayPause => {todo!()},
|
||||
Focus::Clock => {todo!()}
|
||||
}),
|
||||
key!(KeyCode::Char(',')) => Self::Transport(match view.focus {
|
||||
Focus::Bpm => Cmd::SetBpm(clock.timebase().bpm.get() - 1.0),
|
||||
Focus::Quant => Cmd::SetQuant(prev_note_length(clock.quant.get()as usize)as f64),
|
||||
Focus::Sync => Cmd::SetSync(prev_note_length(clock.sync.get()as usize)as f64+1.),
|
||||
Focus::PlayPause => {todo!()},
|
||||
Focus::Clock => {todo!()}
|
||||
}),
|
||||
key!(KeyCode::Char('>')) => Self::Transport(match view.focus {
|
||||
Focus::Bpm => Cmd::SetBpm(clock.timebase().bpm.get() + 0.001),
|
||||
Focus::Quant => Cmd::SetQuant(next_note_length(clock.quant.get()as usize)as f64),
|
||||
Focus::Sync => Cmd::SetSync(next_note_length(clock.sync.get()as usize)as f64+1.),
|
||||
Focus::PlayPause => {todo!()},
|
||||
Focus::Clock => {todo!()}
|
||||
}),
|
||||
key!(KeyCode::Char('<')) => Self::Transport(match view.focus {
|
||||
Focus::Bpm => Cmd::SetBpm(clock.timebase().bpm.get() - 0.001),
|
||||
Focus::Quant => Cmd::SetQuant(prev_note_length(clock.quant.get()as usize)as f64),
|
||||
Focus::Sync => Cmd::SetSync(prev_note_length(clock.sync.get()as usize)as f64+1.),
|
||||
Focus::PlayPause => {todo!()},
|
||||
Focus::Clock => {todo!()}
|
||||
}),
|
||||
|
||||
_ => return None
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine> Command<TransportView<E>> for TransportViewCommand {
|
||||
fn execute (self, view: &mut TransportView<E>) -> Perhaps<Self> {
|
||||
let clock = view.model.clock();
|
||||
Ok(Some(match self {
|
||||
Self::Focus(command) => Self::Focus({
|
||||
use FocusCommand::*;
|
||||
match command {
|
||||
Next => { todo!() },
|
||||
Prev => { todo!() },
|
||||
_ => { todo!() }
|
||||
}
|
||||
}),
|
||||
Self::Transport(command) => Self::Transport({
|
||||
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!()
|
||||
}
|
||||
}
|
||||
}),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl TransportViewFocus {
|
||||
pub fn next (&mut self) {
|
||||
*self = match self {
|
||||
Self::PlayPause => Self::Bpm,
|
||||
Self::Bpm => Self::Quant,
|
||||
Self::Quant => Self::Sync,
|
||||
Self::Sync => Self::Clock,
|
||||
Self::Clock => Self::PlayPause,
|
||||
}
|
||||
}
|
||||
pub fn prev (&mut self) {
|
||||
*self = match self {
|
||||
Self::PlayPause => Self::Clock,
|
||||
Self::Bpm => Self::PlayPause,
|
||||
Self::Quant => Self::Bpm,
|
||||
Self::Sync => Self::Quant,
|
||||
Self::Clock => Self::Sync,
|
||||
}
|
||||
}
|
||||
pub fn wrap <'a, W: Widget<Engine = Tui>> (
|
||||
self, parent_focus: bool, focus: Self, widget: &'a W
|
||||
) -> impl Widget<Engine = Tui> + 'a {
|
||||
let focused = parent_focus && focus == self;
|
||||
let corners = focused.then_some(CORNERS);
|
||||
let highlight = focused.then_some(Background(Color::Rgb(60, 70, 50)));
|
||||
lay!(corners, highlight, *widget)
|
||||
}
|
||||
}
|
||||
|
||||
/// Which item of the transport toolbar is focused
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum TransportViewFocus {
|
||||
Bpm,
|
||||
Sync,
|
||||
PlayPause,
|
||||
Clock,
|
||||
Quant,
|
||||
}
|
||||
|
||||
impl FocusGrid for TransportApp<Tui> {
|
||||
type Item = AppViewFocus<TransportViewFocus>;
|
||||
fn cursor (&self) -> (usize, usize) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue