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::*;
|
use crate::*;
|
||||||
|
|
||||||
|
const CORNERS: Corners = Corners(NOT_DIM_GREEN);
|
||||||
|
|
||||||
/// Stores and displays time-related state.
|
/// Stores and displays time-related state.
|
||||||
pub struct TransportToolbar<E: Engine> {
|
pub struct TransportToolbar<E: Engine> {
|
||||||
/// Enable metronome?
|
/// Enable metronome?
|
||||||
|
|
@ -187,6 +189,36 @@ impl<E: Engine> Audio for TransportToolbar<E> {
|
||||||
Control::Continue
|
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 struct TransportPlayPauseButton<E: Engine> {
|
||||||
pub _engine: PhantomData<E>,
|
pub _engine: PhantomData<E>,
|
||||||
|
|
@ -202,6 +234,8 @@ impl Focusable<Tui> for TransportPlayPauseButton<Tui> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub struct TransportBPM<E: Engine> {
|
pub struct TransportBPM<E: Engine> {
|
||||||
pub _engine: PhantomData<E>,
|
pub _engine: PhantomData<E>,
|
||||||
pub value: f64,
|
pub value: f64,
|
||||||
|
|
@ -215,156 +249,21 @@ impl Focusable<Tui> for TransportBPM<Tui> {
|
||||||
self.focused = focused
|
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> {
|
impl Handle<Tui> for TransportBPM<Tui> {
|
||||||
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
|
||||||
//TransportFocus::BPM => {
|
match from.event() {
|
||||||
//transport.timebase.bpm.fetch_add(1.0, Ordering::Relaxed);
|
key!(KeyCode::Char(',')) => {
|
||||||
//},
|
self.bpm().fetch_sub(1.0, Ordering::Relaxed);
|
||||||
//TransportFocus::BPM => {
|
Ok(Some(true))
|
||||||
//transport.timebase.bpm.fetch_sub(1.0, Ordering::Relaxed);
|
},
|
||||||
//},
|
key!(KeyCode::Char('.')) => {
|
||||||
Ok(None)
|
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> {
|
impl Widget for TransportBPM<Tui> {
|
||||||
type Engine = Tui;
|
type Engine = Tui;
|
||||||
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
|
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> {
|
impl Widget for TransportQuantize<Tui> {
|
||||||
type Engine = Tui;
|
type Engine = Tui;
|
||||||
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
|
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> {
|
impl Widget for TransportSync<Tui> {
|
||||||
type Engine = Tui;
|
type Engine = Tui;
|
||||||
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
|
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> {
|
impl Widget for TransportClock<Tui> {
|
||||||
type Engine = Tui;
|
type Engine = Tui;
|
||||||
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
|
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
|
||||||
|
|
@ -462,3 +444,34 @@ impl Widget for TransportClock<Tui> {
|
||||||
Ok(Some(area))
|
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