mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-10 13:46:42 +01:00
refactor(transport): make widgets focusable
This commit is contained in:
parent
2106a7c044
commit
b8ac83b019
9 changed files with 204 additions and 132 deletions
|
|
@ -4,9 +4,6 @@ use crate::*;
|
|||
pub struct TransportToolbar {
|
||||
/// Enable metronome?
|
||||
pub metronome: bool,
|
||||
pub focused: bool,
|
||||
pub entered: bool,
|
||||
pub selected: TransportFocus,
|
||||
/// Current sample rate, tempo, and PPQ.
|
||||
pub timebase: Arc<Timebase>,
|
||||
/// JACK client handle (needs to not be dropped for standalone mode to work).
|
||||
|
|
@ -14,28 +11,66 @@ pub struct TransportToolbar {
|
|||
/// JACK transport handle.
|
||||
pub transport: Option<Transport>,
|
||||
/// Quantization factor
|
||||
pub quant: usize,
|
||||
/// Global sync quant
|
||||
pub sync: usize,
|
||||
/// Current transport state
|
||||
pub playing: Option<TransportState>,
|
||||
/// Current position according to transport
|
||||
pub playhead: usize,
|
||||
/// Global frame and usec at which playback started
|
||||
pub started: Option<(usize, usize)>,
|
||||
|
||||
pub focused: bool,
|
||||
pub focus: usize,
|
||||
pub playing: TransportPlayPauseButton,
|
||||
pub bpm: TransportBPM,
|
||||
pub quant: TransportQuantize,
|
||||
pub sync: TransportSync,
|
||||
pub clock: TransportClock,
|
||||
}
|
||||
|
||||
focusable!(TransportToolbar);
|
||||
|
||||
focus!(TransportToolbar (focus) : 5 => [
|
||||
playing, bpm, quant, sync, clock
|
||||
]);
|
||||
process!(TransportToolbar |self, _client, scope| {
|
||||
self.update(&scope);
|
||||
Control::Continue
|
||||
});
|
||||
|
||||
pub struct TransportPlayPauseButton {
|
||||
pub value: Option<TransportState>,
|
||||
pub focused: bool
|
||||
}
|
||||
focusable!(TransportPlayPauseButton);
|
||||
|
||||
pub struct TransportBPM {
|
||||
pub value: f64,
|
||||
pub focused: bool
|
||||
}
|
||||
focusable!(TransportBPM);
|
||||
|
||||
pub struct TransportQuantize {
|
||||
pub value: usize,
|
||||
pub focused: bool
|
||||
}
|
||||
focusable!(TransportQuantize);
|
||||
|
||||
pub struct TransportSync {
|
||||
pub value: usize,
|
||||
pub focused: bool
|
||||
}
|
||||
focusable!(TransportSync);
|
||||
|
||||
pub struct TransportClock {
|
||||
pub frame: usize,
|
||||
pub pulse: usize,
|
||||
pub ppq: usize,
|
||||
pub usecs: usize,
|
||||
pub focused: bool,
|
||||
}
|
||||
focusable!(TransportClock);
|
||||
|
||||
impl TransportToolbar {
|
||||
|
||||
pub fn standalone () -> Usually<Arc<RwLock<Self>>> {
|
||||
let mut transport = Self::new(None);
|
||||
transport.focused = true;
|
||||
transport.entered = true;
|
||||
let jack = JackClient::Inactive(
|
||||
Client::new("tek_transport", ClientOptions::NO_START_SERVER)?.0
|
||||
);
|
||||
|
|
@ -55,24 +90,44 @@ impl TransportToolbar {
|
|||
pub fn new (transport: Option<Transport>) -> Self {
|
||||
let timebase = Arc::new(Timebase::default());
|
||||
Self {
|
||||
selected: TransportFocus::BPM,
|
||||
metronome: false,
|
||||
focused: false,
|
||||
entered: false,
|
||||
playhead: 0,
|
||||
playing: Some(TransportState::Stopped),
|
||||
focus: 0,
|
||||
started: None,
|
||||
quant: 24,
|
||||
sync: timebase.ppq() as usize * 4,
|
||||
jack: None,
|
||||
transport,
|
||||
|
||||
playing: TransportPlayPauseButton {
|
||||
value: Some(TransportState::Stopped),
|
||||
focused: true
|
||||
},
|
||||
bpm: TransportBPM {
|
||||
value: timebase.bpm(),
|
||||
focused: false
|
||||
},
|
||||
quant: TransportQuantize {
|
||||
value: 24,
|
||||
focused: false
|
||||
},
|
||||
sync: TransportSync {
|
||||
value: timebase.ppq() as usize * 4,
|
||||
focused: false
|
||||
},
|
||||
clock: TransportClock {
|
||||
frame: 0,
|
||||
pulse: 0,
|
||||
ppq: 0,
|
||||
usecs: 0,
|
||||
focused: false
|
||||
},
|
||||
|
||||
timebase,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle_play (&mut self) -> Usually<()> {
|
||||
let transport = self.transport.as_ref().unwrap();
|
||||
self.playing = match self.playing.expect("1st frame has not been processed yet") {
|
||||
self.playing.value = match self.playing.value.expect("1st frame has not been processed yet") {
|
||||
TransportState::Stopped => {
|
||||
transport.start()?;
|
||||
Some(TransportState::Starting)
|
||||
|
|
@ -95,9 +150,9 @@ impl TransportToolbar {
|
|||
} = scope.cycle_times().unwrap();
|
||||
let chunk_size = scope.n_frames() as usize;
|
||||
let transport = self.transport.as_ref().unwrap().query().unwrap();
|
||||
self.playhead = transport.pos.frame() as usize;
|
||||
self.clock.frame = transport.pos.frame() as usize;
|
||||
let mut reset = false;
|
||||
if self.playing != Some(transport.state) {
|
||||
if self.playing.value != Some(transport.state) {
|
||||
match transport.state {
|
||||
TransportState::Rolling => {
|
||||
self.started = Some((
|
||||
|
|
@ -112,7 +167,7 @@ impl TransportToolbar {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
self.playing = Some(transport.state);
|
||||
self.playing.value = Some(transport.state);
|
||||
(
|
||||
reset,
|
||||
current_frames as usize,
|
||||
|
|
@ -132,11 +187,11 @@ impl TransportToolbar {
|
|||
}
|
||||
|
||||
pub fn pulse (&self) -> usize {
|
||||
self.timebase.frame_to_pulse(self.playhead as f64) as usize
|
||||
self.timebase.frame_to_pulse(self.clock.frame as f64) as usize
|
||||
}
|
||||
|
||||
pub fn usecs (&self) -> usize {
|
||||
self.timebase.frame_to_usec(self.playhead as f64) as usize
|
||||
self.timebase.frame_to_usec(self.clock.frame as f64) as usize
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue