mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
reorder unified transport widgets
This commit is contained in:
parent
77519dbb5c
commit
630974d394
1 changed files with 159 additions and 146 deletions
|
|
@ -1,5 +1,7 @@
|
|||
use crate::*;
|
||||
|
||||
const CORNERS: Corners = Corners(NOT_DIM_GREEN);
|
||||
|
||||
/// Stores and displays time-related state.
|
||||
pub struct TransportToolbar<E: Engine> {
|
||||
/// Enable metronome?
|
||||
|
|
@ -187,6 +189,36 @@ impl<E: Engine> Audio for TransportToolbar<E> {
|
|||
Control::Continue
|
||||
}
|
||||
}
|
||||
impl Handle<Tui> for TransportToolbar<Tui> {
|
||||
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
||||
match from.event() {
|
||||
key!(KeyCode::Left) => {
|
||||
self.focus_prev();
|
||||
Ok(Some(true))
|
||||
},
|
||||
key!(KeyCode::Right) => {
|
||||
self.focus_next();
|
||||
Ok(Some(true))
|
||||
},
|
||||
_ => self.focused_mut().handle(from)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Content for TransportToolbar<Tui> {
|
||||
type Engine = Tui;
|
||||
fn content (&self) -> impl Widget<Engine = Tui> {
|
||||
Split::right(|add|{
|
||||
add(&self.playing)?;
|
||||
add(&self.bpm)?;
|
||||
add(&self.quant)?;
|
||||
add(&self.sync)?;
|
||||
add(&self.clock)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub struct TransportPlayPauseButton<E: Engine> {
|
||||
pub _engine: PhantomData<E>,
|
||||
|
|
@ -202,6 +234,8 @@ impl Focusable<Tui> for TransportPlayPauseButton<Tui> {
|
|||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub struct TransportBPM<E: Engine> {
|
||||
pub _engine: PhantomData<E>,
|
||||
pub value: f64,
|
||||
|
|
@ -215,156 +249,21 @@ impl Focusable<Tui> for TransportBPM<Tui> {
|
|||
self.focused = focused
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TransportQuantize<E: Engine> {
|
||||
pub _engine: PhantomData<E>,
|
||||
pub value: usize,
|
||||
pub focused: bool
|
||||
}
|
||||
impl Focusable<Tui> for TransportQuantize<Tui> {
|
||||
fn is_focused (&self) -> bool {
|
||||
self.focused
|
||||
}
|
||||
fn set_focused (&mut self, focused: bool) {
|
||||
self.focused = focused
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TransportSync<E: Engine> {
|
||||
pub _engine: PhantomData<E>,
|
||||
pub value: usize,
|
||||
pub focused: bool
|
||||
}
|
||||
impl Focusable<Tui> for TransportSync<Tui> {
|
||||
fn is_focused (&self) -> bool {
|
||||
self.focused
|
||||
}
|
||||
fn set_focused (&mut self, focused: bool) {
|
||||
self.focused = focused
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TransportClock<E: Engine> {
|
||||
pub _engine: PhantomData<E>,
|
||||
pub frame: usize,
|
||||
pub pulse: usize,
|
||||
pub ppq: usize,
|
||||
pub usecs: usize,
|
||||
pub focused: bool,
|
||||
}
|
||||
impl Focusable<Tui> for TransportClock<Tui> {
|
||||
fn is_focused (&self) -> bool {
|
||||
self.focused
|
||||
}
|
||||
fn set_focused (&mut self, focused: bool) {
|
||||
self.focused = focused
|
||||
}
|
||||
}
|
||||
|
||||
impl Handle<Tui> for TransportToolbar<Tui> {
|
||||
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
||||
Ok(None)
|
||||
//Ok(
|
||||
//from.key(KeyCode::Right).does(||self.focus_next())?
|
||||
//||
|
||||
//from.key(KeyCode::Left).does(||self.focus_prev())?
|
||||
//||
|
||||
//from.key(KeyCode::Char(' ')).does(||self.toggle_play())?
|
||||
//)
|
||||
}
|
||||
}
|
||||
|
||||
impl Handle<Tui> for TransportPlayPauseButton<Tui> {
|
||||
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
impl Handle<Tui> for TransportBPM<Tui> {
|
||||
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
||||
//TransportFocus::BPM => {
|
||||
//transport.timebase.bpm.fetch_add(1.0, Ordering::Relaxed);
|
||||
//},
|
||||
//TransportFocus::BPM => {
|
||||
//transport.timebase.bpm.fetch_sub(1.0, Ordering::Relaxed);
|
||||
//},
|
||||
Ok(None)
|
||||
match from.event() {
|
||||
key!(KeyCode::Char(',')) => {
|
||||
self.bpm().fetch_sub(1.0, Ordering::Relaxed);
|
||||
Ok(Some(true))
|
||||
},
|
||||
key!(KeyCode::Char('.')) => {
|
||||
self.bpm().fetch_add(1.0, Ordering::Relaxed);
|
||||
Ok(Some(true))
|
||||
},
|
||||
_ => Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Handle<Tui> for TransportQuantize<Tui> {
|
||||
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
||||
//TransportFocus::Quant => {
|
||||
//transport.quant.value = next_note_length(transport.quant)
|
||||
//},
|
||||
//TransportFocus::Quant => {
|
||||
//transport.quant.value = prev_note_length(transport.quant);
|
||||
//},
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
impl Handle<Tui> for TransportSync<Tui> {
|
||||
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
||||
//TransportFocus::Sync => {
|
||||
//transport.sync.value = next_note_length(transport.sync)
|
||||
//},
|
||||
//TransportFocus::Sync => {
|
||||
//transport.sync.value = prev_note_length(transport.sync);
|
||||
//},
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
impl Handle<Tui> for TransportClock<Tui> {
|
||||
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
||||
//TransportFocus::Sync => {
|
||||
//transport.sync.value = next_note_length(transport.sync)
|
||||
//},
|
||||
//TransportFocus::Sync => {
|
||||
//transport.sync.value = prev_note_length(transport.sync);
|
||||
//},
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
const CORNERS: Corners = Corners(NOT_DIM_GREEN);
|
||||
|
||||
impl Content for TransportToolbar<Tui> {
|
||||
type Engine = Tui;
|
||||
fn content (&self) -> impl Widget<Engine = Tui> {
|
||||
Split::right(|add|{
|
||||
add(&self.playing)?;
|
||||
add(&self.bpm)?;
|
||||
add(&self.quant)?;
|
||||
add(&self.sync)?;
|
||||
add(&self.clock)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Content for TransportPlayPauseButton<Tui> {
|
||||
type Engine = Tui;
|
||||
fn content (&self) -> impl Widget<Engine = Tui> {
|
||||
Layers::new(|add|{
|
||||
//add(&self.focused.then_some(CORNERS))?;
|
||||
add(&Styled(match self.value {
|
||||
Some(TransportState::Stopped) => Some(GRAY_DIM.bold()),
|
||||
Some(TransportState::Starting) => Some(GRAY_NOT_DIM_BOLD),
|
||||
Some(TransportState::Rolling) => Some(WHITE_NOT_DIM_BOLD),
|
||||
_ => unreachable!(),
|
||||
}, match self.value {
|
||||
Some(TransportState::Rolling) => "▶ PLAYING",
|
||||
Some(TransportState::Starting) => "READY ...",
|
||||
Some(TransportState::Stopped) => "⏹ STOPPED",
|
||||
_ => unreachable!(),
|
||||
}))?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for TransportBPM<Tui> {
|
||||
type Engine = Tui;
|
||||
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
|
||||
|
|
@ -389,6 +288,36 @@ impl Widget for TransportBPM<Tui> {
|
|||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub struct TransportQuantize<E: Engine> {
|
||||
pub _engine: PhantomData<E>,
|
||||
pub value: usize,
|
||||
pub focused: bool
|
||||
}
|
||||
impl Focusable<Tui> for TransportQuantize<Tui> {
|
||||
fn is_focused (&self) -> bool {
|
||||
self.focused
|
||||
}
|
||||
fn set_focused (&mut self, focused: bool) {
|
||||
self.focused = focused
|
||||
}
|
||||
}
|
||||
impl Handle<Tui> for TransportQuantize<Tui> {
|
||||
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
||||
match from.event() {
|
||||
key!(KeyCode::Char(',')) => {
|
||||
transport.quant.value = prev_note_length(transport.quant);
|
||||
Ok(Some(true))
|
||||
},
|
||||
key!(KeyCode::Char('.')) => {
|
||||
transport.quant.value = next_note_length(transport.quant);
|
||||
Ok(Some(true))
|
||||
},
|
||||
_ => Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Widget for TransportQuantize<Tui> {
|
||||
type Engine = Tui;
|
||||
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
|
||||
|
|
@ -412,6 +341,36 @@ impl Widget for TransportQuantize<Tui> {
|
|||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub struct TransportSync<E: Engine> {
|
||||
pub _engine: PhantomData<E>,
|
||||
pub value: usize,
|
||||
pub focused: bool
|
||||
}
|
||||
impl Focusable<Tui> for TransportSync<Tui> {
|
||||
fn is_focused (&self) -> bool {
|
||||
self.focused
|
||||
}
|
||||
fn set_focused (&mut self, focused: bool) {
|
||||
self.focused = focused
|
||||
}
|
||||
}
|
||||
impl Handle<Tui> for TransportSync<Tui> {
|
||||
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
||||
match from.event() {
|
||||
key!(KeyCode::Char(',')) => {
|
||||
transport.sync.value = prev_note_length(transport.quant);
|
||||
Ok(Some(true))
|
||||
},
|
||||
key!(KeyCode::Char('.')) => {
|
||||
transport.sync.value = next_note_length(transport.quant);
|
||||
Ok(Some(true))
|
||||
},
|
||||
_ => Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Widget for TransportSync<Tui> {
|
||||
type Engine = Tui;
|
||||
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
|
||||
|
|
@ -435,6 +394,29 @@ impl Widget for TransportSync<Tui> {
|
|||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub struct TransportClock<E: Engine> {
|
||||
pub _engine: PhantomData<E>,
|
||||
pub frame: usize,
|
||||
pub pulse: usize,
|
||||
pub ppq: usize,
|
||||
pub usecs: usize,
|
||||
pub focused: bool,
|
||||
}
|
||||
impl Focusable<Tui> for TransportClock<Tui> {
|
||||
fn is_focused (&self) -> bool {
|
||||
self.focused
|
||||
}
|
||||
fn set_focused (&mut self, focused: bool) {
|
||||
self.focused = focused
|
||||
}
|
||||
}
|
||||
impl Handle<Tui> for TransportClock<Tui> {
|
||||
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
impl Widget for TransportClock<Tui> {
|
||||
type Engine = Tui;
|
||||
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
|
||||
|
|
@ -462,3 +444,34 @@ impl Widget for TransportClock<Tui> {
|
|||
Ok(Some(area))
|
||||
}
|
||||
}
|
||||
impl Handle<Tui> for TransportPlayPauseButton<Tui> {
|
||||
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
||||
match from.event() {
|
||||
key!(KeyCode::Enter) => {
|
||||
self.toggle();
|
||||
Ok(Some(true))
|
||||
}
|
||||
_ => Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Content for TransportPlayPauseButton<Tui> {
|
||||
type Engine = Tui;
|
||||
fn content (&self) -> impl Widget<Engine = Tui> {
|
||||
Layers::new(|add|{
|
||||
//add(&self.focused.then_some(CORNERS))?;
|
||||
add(&Styled(match self.value {
|
||||
Some(TransportState::Stopped) => Some(GRAY_DIM.bold()),
|
||||
Some(TransportState::Starting) => Some(GRAY_NOT_DIM_BOLD),
|
||||
Some(TransportState::Rolling) => Some(WHITE_NOT_DIM_BOLD),
|
||||
_ => unreachable!(),
|
||||
}, match self.value {
|
||||
Some(TransportState::Rolling) => "▶ PLAYING",
|
||||
Some(TransportState::Starting) => "READY ...",
|
||||
Some(TransportState::Stopped) => "⏹ STOPPED",
|
||||
_ => unreachable!(),
|
||||
}))?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue