mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
feat: draw bpm and bbt
This commit is contained in:
parent
c06b9d16e2
commit
b1df7bf4e6
3 changed files with 100 additions and 90 deletions
|
|
@ -7,6 +7,7 @@ pub struct Launcher {
|
|||
monitoring: bool,
|
||||
recording: bool,
|
||||
overdub: bool,
|
||||
position: usize,
|
||||
cursor: (usize, usize),
|
||||
tracks: Vec<DynamicDevice<Sequencer>>,
|
||||
chains: Vec<DynamicDevice<Chain>>,
|
||||
|
|
@ -14,6 +15,7 @@ pub struct Launcher {
|
|||
show_help: bool,
|
||||
view: LauncherView,
|
||||
}
|
||||
#[derive(PartialEq)]
|
||||
pub enum LauncherView {
|
||||
Tracks,
|
||||
Sequencer,
|
||||
|
|
@ -49,6 +51,7 @@ impl Launcher {
|
|||
overdub: true,
|
||||
transport,
|
||||
cursor: (1, 2),
|
||||
position: 0,
|
||||
scenes: vec![
|
||||
Scene::new(&"Scene#01", &[Some(0), None, None, None]),
|
||||
Scene::new(&"Scene#02", &[None, None, None, None]),
|
||||
|
|
@ -126,16 +129,19 @@ impl Launcher {
|
|||
}
|
||||
impl DevicePorts for Launcher {}
|
||||
pub fn process (state: &mut Launcher, _: &Client, _: &ProcessScope) -> Control {
|
||||
state.playing = state.transport.query_state().unwrap();
|
||||
let transport = state.transport.query().unwrap();
|
||||
state.playing = transport.state;
|
||||
state.position = transport.pos.frame() as usize;
|
||||
Control::Continue
|
||||
}
|
||||
pub fn render (state: &Launcher, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
let Rect { x, y, width, height } = area;
|
||||
crate::device::sequencer::draw_timer(buf, x + width - 1, y, 0, 0, 0, 0);
|
||||
crate::device::sequencer::draw_play_stop(buf, x + 1, y, &state.playing);
|
||||
crate::device::sequencer::draw_rec(buf, x + 12, y, state.recording);
|
||||
crate::device::sequencer::draw_mon(buf, x + 19, y, state.monitoring);
|
||||
crate::device::sequencer::draw_dub(buf, x + 26, y, state.overdub);
|
||||
draw_bpm(buf, x + 33, y, state.timebase.tempo());
|
||||
draw_timer(buf, x + width - 1, y, &state.timebase, state.position);
|
||||
let track_area = Rect { x: x, y: y+1, width, height: 22 };
|
||||
let seq_area = Rect { x: x, y: y+22, width, height: 20 };
|
||||
let chain_area = Rect { x: x, y: y+41, width, height: 21 };
|
||||
|
|
@ -154,20 +160,28 @@ pub fn render (state: &Launcher, buf: &mut Buffer, area: Rect) -> Usually<Rect>
|
|||
let style = Some(Style::default().green().dim());
|
||||
let chain = &*state.chains[0].state();
|
||||
let (_, plugins) = crate::device::chain::draw_as_row(chain, buf, chain_area, style)?;
|
||||
match state.view {
|
||||
LauncherView::Tracks => draw_box_styled(buf, track_area, style),
|
||||
LauncherView::Sequencer => draw_box_styled(buf, seq_area, style),
|
||||
LauncherView::Chains => draw_box_styled(buf, Rect { height: 18, ..chain_area }, style),
|
||||
};
|
||||
|
||||
if state.view == LauncherView::Tracks {
|
||||
draw_box_styled(buf, track_area, style);
|
||||
}
|
||||
draw_highlight(state, buf, &track_highlight, match state.view {
|
||||
LauncherView::Tracks => Style::default().green().not_dim(),
|
||||
_ => Style::default().green().dim()
|
||||
});
|
||||
|
||||
if state.view == LauncherView::Chains {
|
||||
draw_box_styled(buf, Rect { height: 18, ..chain_area }, style);
|
||||
}
|
||||
draw_highlight(state, buf, &Some(plugins[chain.focus]), match state.view {
|
||||
LauncherView::Chains => Style::default().green().not_dim(),
|
||||
_ => Style::default().green().dim()
|
||||
});
|
||||
|
||||
if state.view == LauncherView::Sequencer {
|
||||
draw_box_styled(buf, seq_area, style);
|
||||
}
|
||||
draw_sequencer(state, buf, seq_area.x, seq_area.y + 1, seq_area.width, seq_area.height - 2)?;
|
||||
|
||||
if state.show_help {
|
||||
let style = Some(Style::default().bold().white().not_dim().on_black().italic());
|
||||
let hide = "[Left/Right] Track [Up/Down] Scene [,/.] Value [F1] Toggle help ";
|
||||
|
|
@ -175,6 +189,20 @@ pub fn render (state: &Launcher, buf: &mut Buffer, area: Rect) -> Usually<Rect>
|
|||
}
|
||||
Ok(area)
|
||||
}
|
||||
fn draw_bpm (buf: &mut Buffer, x: u16, y: u16, tempo: usize) {
|
||||
let style = Style::default().not_dim();
|
||||
"BPM"
|
||||
.blit(buf, x, y, Some(style));
|
||||
format!("{:03}.{:03}", tempo / 1000, tempo % 1000)
|
||||
.blit(buf, x + 4, y, Some(style.bold()));
|
||||
}
|
||||
fn draw_timer (buf: &mut Buffer, x: u16, y: u16, timebase: &Arc<Timebase>, frame: usize) {
|
||||
let tick = (frame as f64 / timebase.frames_per_tick()) as usize;
|
||||
let (beats, ticks) = (tick / timebase.ppq(), tick % timebase.ppq());
|
||||
let (bars, beats) = (beats / 4, beats % 4);
|
||||
let timer = format!("{}.{}.{ticks:02}", bars + 1, beats + 1);
|
||||
timer.blit(buf, x - timer.len() as u16, y, Some(Style::default().not_dim()));
|
||||
}
|
||||
fn draw_scenes (
|
||||
state: &Launcher, buf: &mut Buffer, x: u16, y: u16,
|
||||
) -> Rect {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue