mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-08 12:46:42 +01:00
wip: scaffold PhrasePool, PhraseEditor
This commit is contained in:
parent
ea3edec96b
commit
d821787fcf
8 changed files with 1549 additions and 1536 deletions
121
crates/tek_sequencer/src/transport_tui.rs
Normal file
121
crates/tek_sequencer/src/transport_tui.rs
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
use crate::*;
|
||||
|
||||
impl TransportToolbar<Tui> {
|
||||
fn handle_bpm (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
||||
match from.event() {
|
||||
key!(KeyCode::Char(',')) => { self.bpm -= 1.0; },
|
||||
key!(KeyCode::Char('.')) => { self.bpm += 1.0; },
|
||||
key!(KeyCode::Char('<')) => { self.bpm -= 0.001; },
|
||||
key!(KeyCode::Char('>')) => { self.bpm += 0.001; },
|
||||
_ => return Ok(None)
|
||||
}
|
||||
Ok(Some(true))
|
||||
}
|
||||
fn handle_quant (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
||||
match from.event() {
|
||||
key!(KeyCode::Char(',')) => {
|
||||
self.quant = prev_note_length(self.quant);
|
||||
Ok(Some(true))
|
||||
},
|
||||
key!(KeyCode::Char('.')) => {
|
||||
self.quant = next_note_length(self.quant);
|
||||
Ok(Some(true))
|
||||
},
|
||||
_ => Ok(None)
|
||||
}
|
||||
}
|
||||
fn handle_sync (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
||||
match from.event() {
|
||||
key!(KeyCode::Char(',')) => {
|
||||
self.sync = prev_note_length(self.sync);
|
||||
Ok(Some(true))
|
||||
},
|
||||
key!(KeyCode::Char('.')) => {
|
||||
self.sync = next_note_length(self.sync);
|
||||
Ok(Some(true))
|
||||
},
|
||||
_ => Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Handle<Tui> for TransportToolbar<Tui> {
|
||||
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
||||
match from.event() {
|
||||
key!(KeyCode::Left) => { self.focus.prev(); },
|
||||
key!(KeyCode::Right) => { self.focus.next(); },
|
||||
_ => match self.focus {
|
||||
TransportToolbarFocus::PlayPause => self.toggle_play().map(|_|())?,
|
||||
TransportToolbarFocus::Bpm => self.handle_bpm(from).map(|_|())?,
|
||||
TransportToolbarFocus::Quant => self.handle_quant(from).map(|_|())?,
|
||||
TransportToolbarFocus::Sync => self.handle_sync(from).map(|_|())?,
|
||||
TransportToolbarFocus::Clock => {/*todo*/},
|
||||
}
|
||||
}
|
||||
Ok(Some(true))
|
||||
}
|
||||
}
|
||||
|
||||
impl Content for TransportToolbar<Tui> {
|
||||
type Engine = Tui;
|
||||
fn content (&self) -> impl Widget<Engine = Tui> {
|
||||
row!(
|
||||
self.focus.wrap(self.focused, TransportToolbarFocus::PlayPause, &Styled(
|
||||
match self.playing {
|
||||
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.playing {
|
||||
Some(TransportState::Rolling) => "▶ PLAYING",
|
||||
Some(TransportState::Starting) => "READY ...",
|
||||
Some(TransportState::Stopped) => "⏹ STOPPED",
|
||||
_ => unreachable!(),
|
||||
}
|
||||
).min_xy(11, 2).push_x(1)),
|
||||
self.focus.wrap(self.focused, TransportToolbarFocus::Bpm, &Outset::X(1u16, col! {
|
||||
"BPM", format!("{}.{:03}", self.bpm as usize, (self.bpm * 1000.0) % 1000.0)
|
||||
})),
|
||||
self.focus.wrap(self.focused, TransportToolbarFocus::Quant, &Outset::X(1u16, col! {
|
||||
"QUANT", ppq_to_name(self.quant as usize)
|
||||
})),
|
||||
self.focus.wrap(self.focused, TransportToolbarFocus::Sync, &Outset::X(1u16, col! {
|
||||
"SYNC", ppq_to_name(self.sync as usize)
|
||||
})),
|
||||
self.focus.wrap(self.focused, TransportToolbarFocus::Clock, &{
|
||||
let Self { frame: _frame, pulse, ppq, usecs, .. } = self;
|
||||
let (beats, pulses) = if *ppq > 0 { (pulse / ppq, pulse % ppq) } else { (0, 0) };
|
||||
let (bars, beats) = ((beats / 4) + 1, (beats % 4) + 1);
|
||||
let (seconds, msecs) = (usecs / 1000000, usecs / 1000 % 1000);
|
||||
let (minutes, seconds) = (seconds / 60, seconds % 60);
|
||||
let time1 = format!("{bars}.{beats}.{pulses:02}");
|
||||
let time2 = format!("{minutes}:{seconds:02}:{msecs:03}");
|
||||
col!(time1.as_str(), time2.as_str()).outset_x(1)
|
||||
}),
|
||||
).fill_x().bg(Color::Rgb(40, 50, 30))
|
||||
}
|
||||
}
|
||||
|
||||
impl Focusable<Tui> for TransportToolbar<Tui> {
|
||||
fn is_focused (&self) -> bool {
|
||||
self.focused
|
||||
}
|
||||
fn set_focused (&mut self, focused: bool) {
|
||||
self.focused = focused
|
||||
}
|
||||
}
|
||||
|
||||
impl TransportToolbarFocus {
|
||||
pub fn wrap <'a, W: Widget<Engine = Tui>> (
|
||||
self, parent_focus: bool, focus: Self, widget: &'a W
|
||||
) -> impl Widget<Engine = Tui> + 'a {
|
||||
Layers::new(move |add|{
|
||||
if parent_focus && focus == self {
|
||||
add(&CORNERS)?;
|
||||
add(&Background(Color::Rgb(60, 70, 50)))?;
|
||||
}
|
||||
add(widget)
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue