mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 20:26:42 +01:00
wip: refactor pt.8, 512 errors lol
This commit is contained in:
parent
a1818a8504
commit
a784f7a6f2
19 changed files with 238 additions and 183 deletions
|
|
@ -1,28 +1,30 @@
|
|||
use crate::*;
|
||||
use tek_api::Transport;
|
||||
|
||||
/// Stores and displays time-related state.
|
||||
#[derive(Debug)]
|
||||
pub struct TransportView<E: Engine> {
|
||||
_engine: PhantomData<E>,
|
||||
state: TransportToolbar,
|
||||
state: Transport,
|
||||
focus: TransportViewFocus,
|
||||
focused: bool,
|
||||
focus: TransportFocus,
|
||||
}
|
||||
/// Which item of the transport toolbar is focused
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum TransportFocus {
|
||||
Bpm,
|
||||
Sync,
|
||||
PlayPause,
|
||||
Clock,
|
||||
Quant,
|
||||
|
||||
/// JACK process callback for transport app
|
||||
impl<E: Engine> Audio for TransportView<E> {
|
||||
fn process (&mut self, client: &Client, scope: &ProcessScope) -> Control {
|
||||
self.state.process(client, scope);
|
||||
Control::Continue
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine> TransportView<E> {
|
||||
pub fn new (jack: &Arc<RwLock<JackClient>>, clock: Option<&Arc<TransportTime>>) -> Self {
|
||||
pub fn new (jack: &Arc<RwLock<JackClient>>, clock: Option<&Arc<Clock>>) -> Self {
|
||||
Self {
|
||||
_engine: Default::default(),
|
||||
focused: false,
|
||||
focus: TransportFocus::PlayPause,
|
||||
state: TransportToolbar {
|
||||
focus: TransportViewFocus::PlayPause,
|
||||
state: Transport {
|
||||
metronome: false,
|
||||
transport: jack.read().unwrap().transport(),
|
||||
jack: jack.clone(),
|
||||
|
|
@ -30,7 +32,7 @@ impl<E: Engine> TransportView<E> {
|
|||
Some(clock) => clock.clone(),
|
||||
None => {
|
||||
let timebase = Arc::new(Timebase::default());
|
||||
Arc::new(TransportTime {
|
||||
Arc::new(Clock {
|
||||
playing: Some(TransportState::Stopped).into(),
|
||||
quant: 24.into(),
|
||||
sync: (timebase.ppq.get() * 4.).into(),
|
||||
|
|
@ -42,48 +44,13 @@ impl<E: Engine> TransportView<E> {
|
|||
}
|
||||
}
|
||||
}
|
||||
pub fn toggle_play (&mut self) -> Usually<()> {
|
||||
let playing = self.clock.playing.read().unwrap().expect("1st sample has not been processed yet");
|
||||
let playing = match playing {
|
||||
TransportState::Stopped => {
|
||||
self.transport.start()?;
|
||||
Some(TransportState::Starting)
|
||||
},
|
||||
_ => {
|
||||
self.transport.stop()?;
|
||||
self.transport.locate(0)?;
|
||||
Some(TransportState::Stopped)
|
||||
},
|
||||
};
|
||||
*self.clock.playing.write().unwrap() = playing;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl TransportFocus {
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Content for TransportToolbar<Tui> {
|
||||
|
||||
impl Content for TransportView<Tui> {
|
||||
type Engine = Tui;
|
||||
fn content (&self) -> impl Widget<Engine = Tui> {
|
||||
lay!(
|
||||
self.focus.wrap(self.focused, TransportToolbarFocus::PlayPause, &Styled(
|
||||
self.focus.wrap(self.focused, TransportViewFocus::PlayPause, &Styled(
|
||||
None,
|
||||
match *self.clock.playing.read().unwrap() {
|
||||
Some(TransportState::Rolling) => "▶ PLAYING",
|
||||
|
|
@ -94,19 +61,19 @@ impl Content for TransportToolbar<Tui> {
|
|||
).min_xy(11, 2).push_x(1)).align_x().fill_x(),
|
||||
|
||||
row!(
|
||||
self.focus.wrap(self.focused, TransportToolbarFocus::Bpm, &Outset::X(1u16, {
|
||||
self.focus.wrap(self.focused, TransportViewFocus::Bpm, &Outset::X(1u16, {
|
||||
let bpm = self.clock.timebase().bpm.get();
|
||||
row! { "BPM ", format!("{}.{:03}", bpm as usize, (bpm * 1000.0) % 1000.0) }
|
||||
})),
|
||||
//let quant = self.focus.wrap(self.focused, TransportToolbarFocus::Quant, &Outset::X(1u16, row! {
|
||||
//let quant = self.focus.wrap(self.focused, TransportViewFocus::Quant, &Outset::X(1u16, row! {
|
||||
//"QUANT ", ppq_to_name(self.quant as usize)
|
||||
//})),
|
||||
self.focus.wrap(self.focused, TransportToolbarFocus::Sync, &Outset::X(1u16, row! {
|
||||
self.focus.wrap(self.focused, TransportViewFocus::Sync, &Outset::X(1u16, row! {
|
||||
"SYNC ", pulses_to_name(self.clock.sync.get() as usize)
|
||||
}))
|
||||
).align_w().fill_x(),
|
||||
|
||||
self.focus.wrap(self.focused, TransportToolbarFocus::Clock, &{
|
||||
self.focus.wrap(self.focused, TransportViewFocus::Clock, &{
|
||||
let time1 = self.clock.current.format_beat();
|
||||
let time2 = self.clock.current.usec.format_msu();
|
||||
row!("B" ,time1.as_str(), " T", time2.as_str()).outset_x(1)
|
||||
|
|
@ -115,13 +82,3 @@ impl Content for TransportToolbar<Tui> {
|
|||
).fill_x().bg(Color::Rgb(40, 50, 30))
|
||||
}
|
||||
}
|
||||
impl TransportToolbarFocus {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue