From 1060afa4f30d3dcc9196d07047337d6b9494591b Mon Sep 17 00:00:00 2001 From: unspeaker Date: Mon, 25 Nov 2024 17:41:50 +0100 Subject: [PATCH] remove TransportViewState --- crates/tek_tui/src/tui_content.rs | 29 +++++---- crates/tek_tui/src/tui_view.rs | 100 ++++++++++++++++-------------- crates/tek_tui/src/tui_widget.rs | 4 +- 3 files changed, 69 insertions(+), 64 deletions(-) diff --git a/crates/tek_tui/src/tui_content.rs b/crates/tek_tui/src/tui_content.rs index 55e0c102..efacae38 100644 --- a/crates/tek_tui/src/tui_content.rs +++ b/crates/tek_tui/src/tui_content.rs @@ -1,14 +1,13 @@ use crate::*; -impl<'a, T: TransportViewState> Content for TransportView<'a, T> { +impl Content for TransportView { type Engine = Tui; fn content (&self) -> impl Widget { - let state = self.0; - let selected = state.transport_selected(); + let Self { state, selected, focused, bpm, sync, quant, beat, msu, } = self; row!( selected.wrap(TransportFocus::PlayPause, &Styled( None, - match *state.transport_state().read().unwrap() { + match *state { Some(TransportState::Rolling) => "▶ PLAYING", Some(TransportState::Starting) => "READY ...", Some(TransportState::Stopped) => "⏹ STOPPED", @@ -16,19 +15,19 @@ impl<'a, T: TransportViewState> Content for TransportView<'a, T> { } ).min_xy(11, 2).push_x(1)), selected.wrap(TransportFocus::Bpm, &Outset::X(1u16, { - let bpm = state.transport_bpm_value(); - row! { "BPM ", format!("{}.{:03}", bpm as usize, (bpm * 1000.0) % 1000.0) } + row! { + "BPM ", + format!("{}.{:03}", *bpm as usize, (bpm * 1000.0) % 1000.0) + } + })), + selected.wrap(TransportFocus::Quant, &Outset::X(1u16, row! { + "QUANT ", pulses_to_name(*quant as usize) })), - //let quant = state.focus().wrap(state.focused(), TransportFocus::Quant, &Outset::X(1u16, row! { - //"QUANT ", ppq_to_name(state.0.quant as usize) - //})), selected.wrap(TransportFocus::Sync, &Outset::X(1u16, row! { - "SYNC ", pulses_to_name(state.transport_sync_value() as usize) + "SYNC ", pulses_to_name(*sync as usize) })), selected.wrap(TransportFocus::Clock, &{ - let time1 = state.transport_format_beat(); - let time2 = state.transport_format_msu(); - row!("B" ,time1.as_str(), " T", time2.as_str()).outset_x(1) + row!("B" , beat.as_str(), " T", msu.as_str()).outset_x(1) }).align_e().fill_x(), ).fill_x().bg(Color::Rgb(40, 50, 30)) } @@ -39,7 +38,7 @@ impl Content for SequencerTui { fn content (&self) -> impl Widget { lay!( col!( - widget(&TransportView(self)), + TransportView::from(self), Split::right(20, widget(&PhrasesView(self)), widget(&PhraseView(self)), @@ -83,7 +82,7 @@ impl Content for ArrangerTui { let arranger_focused = self.arranger_focused(); Split::down( 1, - TransportView(self), + TransportView::from(self), Split::down( self.splits[0], lay!( diff --git a/crates/tek_tui/src/tui_view.rs b/crates/tek_tui/src/tui_view.rs index 3c4ccb04..ac29aad0 100644 --- a/crates/tek_tui/src/tui_view.rs +++ b/crates/tek_tui/src/tui_view.rs @@ -1,57 +1,63 @@ use crate::*; -pub struct TransportView<'a, T: TransportViewState>(pub &'a T); +pub struct TransportView { + pub(crate) state: Option, + pub(crate) selected: Option, + pub(crate) focused: bool, + pub(crate) bpm: f64, + pub(crate) sync: f64, + pub(crate) quant: f64, + pub(crate) beat: String, + pub(crate) msu: String, +} +impl<'a, T> From<&'a T> for TransportView +where + T: ClockApi, + Option: From<&'a T> +{ + fn from (state: &'a T) -> Self { + let selected = state.into(); + Self { + selected, + focused: selected.is_some(), + state: state.transport_state().read().unwrap().clone(), + bpm: state.bpm().get(), + sync: state.sync().get(), + quant: state.quant().get(), + beat: state.current().format_beat(), + msu: state.current().usec.format_msu(), + } + } +} +impl From<&TransportTui> for Option { + fn from (state: &TransportTui) -> Self { + match state.focus.inner() { + AppFocus::Content(focus) => Some(focus), + _ => None + } + } +} +impl From<&SequencerTui> for Option { + fn from (state: &SequencerTui) -> Self { + match state.focus.inner() { + AppFocus::Content(SequencerFocus::Transport(focus)) => Some(focus), + _ => None + } + } +} +impl From<&ArrangerTui> for Option { + fn from (state: &ArrangerTui) -> Self { + match state.focus.inner() { + AppFocus::Content(ArrangerFocus::Transport(focus)) => Some(focus), + _ => None + } + } +} pub struct PhrasesView<'a, T: PhrasesViewState>(pub &'a T); pub struct PhraseView<'a, T: PhraseViewState>(pub &'a T); -pub trait TransportViewState: ClockApi + Send + Sync { - fn transport_selected (&self) -> Option; - fn transport_focused (&self) -> bool { - self.transport_selected().is_some() - } - fn transport_bpm_value (&self) -> f64 { - self.bpm().get() - } - fn transport_sync_value (&self) -> f64 { - self.sync().get() - } - fn transport_format_beat (&self) -> String { - self.current().format_beat() - } - fn transport_format_msu (&self) -> String { - self.current().usec.format_msu() - } -} -impl TransportViewState for TransportTui { - fn transport_selected (&self) -> Option { - if let AppFocus::Content(focus) = self.focus.inner() { - Some(focus) - } else { - None - } - } -} -impl TransportViewState for SequencerTui { - fn transport_selected (&self) -> Option { - if let AppFocus::Content(SequencerFocus::Transport(focus)) = self.focus.inner() { - Some(focus) - } else { - None - } - } -} -impl TransportViewState for ArrangerTui { - fn transport_selected (&self) -> Option { - if let AppFocus::Content(ArrangerFocus::Transport(focus)) = self.focus.inner() { - Some(focus) - } else { - None - } - } -} - pub trait ArrangerViewState { fn arranger_focused (&self) -> bool; } diff --git a/crates/tek_tui/src/tui_widget.rs b/crates/tek_tui/src/tui_widget.rs index dbc98113..d15106e6 100644 --- a/crates/tek_tui/src/tui_widget.rs +++ b/crates/tek_tui/src/tui_widget.rs @@ -3,10 +3,10 @@ use crate::*; impl Widget for TransportTui { type Engine = Tui; fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> { - TransportView(self).layout(to) + TransportView::from(self).layout(to) } fn render (&self, to: &mut TuiOutput) -> Usually<()> { - TransportView(self).render(to) + TransportView::from(self).render(to) } }