mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 04:06:45 +01:00
refactor: device abstraction, layout components
This commit is contained in:
parent
d330d31ce4
commit
788dc1ccde
21 changed files with 1144 additions and 1166 deletions
|
|
@ -1,37 +1,32 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub const ACTIONS: [(&'static str, &'static str);4] = [
|
||||
("?", "Toggle help"),
|
||||
("(Shift-)Tab", "Switch pane"),
|
||||
("Arrows", "Navigate"),
|
||||
("(Shift-)Space", "⯈ Play/pause"),
|
||||
];
|
||||
|
||||
pub struct Transport {
|
||||
exited: bool,
|
||||
title: String,
|
||||
transport: ::jack::Transport,
|
||||
name: String,
|
||||
transport: Option<::jack::Transport>,
|
||||
bpm: f64,
|
||||
timesig: (f32, f32),
|
||||
devices: Vec<Box<dyn Device>>,
|
||||
}
|
||||
|
||||
impl Transport {
|
||||
pub fn new (client: &Client) -> Result<Self, Box<dyn Error>> {
|
||||
let transport = client.transport();
|
||||
Ok(Self {
|
||||
exited: false,
|
||||
title: String::from("Untitled project"),
|
||||
pub fn new (devices: Vec<Box<dyn Device>>)
|
||||
-> Result<DynamicDevice<Self>, Box<dyn Error>>
|
||||
{
|
||||
//let transport = client.transport();
|
||||
Ok(DynamicDevice::new(render, handle, |_|{}, Self {
|
||||
name: "Transport".into(),
|
||||
bpm: 113.0,
|
||||
timesig: (4.0, 4.0),
|
||||
transport,
|
||||
})
|
||||
transport: None,
|
||||
devices
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn play_from_start_or_stop_and_rewind (&mut self) {
|
||||
}
|
||||
|
||||
pub fn play_or_pause (&mut self) -> Result<(), Box<dyn Error>> {
|
||||
match self.transport.query_state()? {
|
||||
match self.transport.as_ref().unwrap().query_state()? {
|
||||
TransportState::Stopped => self.play(),
|
||||
TransportState::Rolling => self.stop(),
|
||||
_ => Ok(())
|
||||
|
|
@ -39,41 +34,27 @@ impl Transport {
|
|||
}
|
||||
|
||||
pub fn play (&mut self) -> Result<(), Box<dyn Error>> {
|
||||
Ok(self.transport.start()?)
|
||||
Ok(self.transport.as_ref().unwrap().start()?)
|
||||
}
|
||||
|
||||
pub fn stop (&mut self) -> Result<(), Box<dyn Error>> {
|
||||
Ok(self.transport.stop()?)
|
||||
Ok(self.transport.as_ref().unwrap().stop()?)
|
||||
}
|
||||
}
|
||||
|
||||
impl Exitable for Transport {
|
||||
fn exit (&mut self) {
|
||||
self.exited = true
|
||||
}
|
||||
fn exited (&self) -> bool {
|
||||
self.exited
|
||||
}
|
||||
}
|
||||
|
||||
impl WidgetRef for Transport {
|
||||
fn render_ref (&self, area: Rect, buf: &mut Buffer) {
|
||||
use ratatui::{layout::*, widgets::*, style::Stylize};
|
||||
draw_leaf(buf, area, 0, 0, "REC");
|
||||
draw_leaf(buf, area, 0, 5, "DUB");
|
||||
draw_leaf(buf, area, 0, 10, "STOP");
|
||||
draw_leaf(buf, area, 0, 16, "PLAY/PAUSE");
|
||||
draw_leaf(buf, area, 0, 28, "START");
|
||||
draw_leaf(buf, area, 0, 35, "Project: Witty Gerbil - Sha Na Na ");
|
||||
let position = self.transport.query().expect("failed to query transport");
|
||||
draw_leaf(buf, area, 2, 0, &format!("BPM {:03}.{:03}",
|
||||
self.bpm as u64,
|
||||
((self.bpm % 1.0) * 1000.0) as u64
|
||||
));
|
||||
//let bbt = position.pos.bbt().map(|mut bbt|*bbt
|
||||
//.with_bpm(self.bpm)
|
||||
//.with_timesig(self.timesig.0, self.timesig.1));
|
||||
//.unwrap();
|
||||
pub fn render (state: &Transport, buf: &mut Buffer, area: Rect) {
|
||||
draw_leaf(buf, area, 0, 0, "REC");
|
||||
draw_leaf(buf, area, 0, 5, "DUB");
|
||||
draw_leaf(buf, area, 0, 10, "STOP");
|
||||
draw_leaf(buf, area, 0, 16, "PLAY/PAUSE");
|
||||
draw_leaf(buf, area, 0, 28, "START");
|
||||
draw_leaf(buf, area, 0, 35, "Project: Witty Gerbil - Sha Na Na ");
|
||||
draw_leaf(buf, area, 2, 0, &format!("BPM {:03}.{:03}",
|
||||
state.bpm as u64,
|
||||
((state.bpm % 1.0) * 1000.0) as u64
|
||||
));
|
||||
let position = state.transport.as_ref().map(|t|t.query());
|
||||
if let Some(Ok(position)) = position {
|
||||
let rate = position.pos.frame_rate().unwrap();
|
||||
let frame = position.pos.frame();
|
||||
let second = (frame as f64) / (rate as f64);
|
||||
|
|
@ -105,42 +86,46 @@ impl WidgetRef for Transport {
|
|||
));
|
||||
draw_leaf(buf, area, 2, 48, &format!("Rate {:>6}Hz", rate));
|
||||
draw_leaf(buf, area, 2, 63, &format!("Frame {:>10}", frame));
|
||||
//Line::from("Project:").render(area, buf);
|
||||
//if let Ok(position) = self.transport.query() {
|
||||
//let frame = position.pos.frame();
|
||||
//let rate = position.pos.frame_rate();
|
||||
//let bbt = position.pos.bbt().map(|mut bbt|*bbt
|
||||
//.with_bpm(self.bpm)
|
||||
//.with_timesig(self.timesig.0, self.timesig.1));
|
||||
//Line::from("Frame:").render(area.clone().offset(Offset { x: 0, y: 1 }), buf);
|
||||
//Line::from(format!("{frame}")).render(area.clone().offset(Offset { x: 0, y: 2 }), buf);
|
||||
//Line::from("Rate:").render(area.clone().offset(Offset { x: 10, y: 1 }), buf);
|
||||
//Line::from(match rate {
|
||||
//Some(rate) => format!("{rate}Hz"),
|
||||
//None => String::from("(none)"),
|
||||
//}).render(area.clone().offset(Offset { x: 10, y: 2 }), buf);
|
||||
//Line::from("Time:").render(area.clone().offset(Offset { x: 20, y: 1 }), buf);
|
||||
//Line::from(match rate {
|
||||
//Some(rate) => format!("{:.03}", frame as f64 / rate as f64),
|
||||
//None => String::from("(none)")
|
||||
//}).render(area.clone().offset(Offset { x: 20, y: 2 }), buf);
|
||||
//Line::from("BPM:").render(area.clone().offset(Offset { x: 30, y: 1 }), buf);
|
||||
//Line::from(match bbt {
|
||||
//Some(bbt) => format!("{:.01}", bbt.bpm),
|
||||
//None => String::from("(none)")
|
||||
//}).render(area.clone().offset(Offset { x: 30, y: 2 }), buf);
|
||||
//Line::from("TimeSig:").render(area.clone().offset(Offset { x: 40, y: 1 }), buf);
|
||||
//Line::from(match bbt {
|
||||
//Some(bbt) => format!("{}/{}", bbt.sig_num, bbt.sig_denom),
|
||||
//None => String::from("(none)")
|
||||
//}).render(area.clone().offset(Offset { x: 40, y: 2 }), buf);
|
||||
//Line::from("Beat:").render(area.clone().offset(Offset { x: 50, y: 1 }), buf);
|
||||
//Line::from(match bbt {
|
||||
//Some(bbt) => format!("{}.{}.{}", bbt.bar, bbt.beat, bbt.tick),
|
||||
//None => String::from("(none)")
|
||||
//}).render(area.clone().offset(Offset { x: 50, y: 2 }), buf);
|
||||
//}
|
||||
}
|
||||
//let bbt = position.pos.bbt().map(|mut bbt|*bbt
|
||||
//.with_bpm(state.bpm)
|
||||
//.with_timesig(state.timesig.0, state.timesig.1));
|
||||
//.unwrap();
|
||||
//Line::from("Project:").render(area, buf);
|
||||
//if let Ok(position) = state.transport.query() {
|
||||
//let frame = position.pos.frame();
|
||||
//let rate = position.pos.frame_rate();
|
||||
//let bbt = position.pos.bbt().map(|mut bbt|*bbt
|
||||
//.with_bpm(state.bpm)
|
||||
//.with_timesig(state.timesig.0, state.timesig.1));
|
||||
//Line::from("Frame:").render(area.clone().offset(Offset { x: 0, y: 1 }), buf);
|
||||
//Line::from(format!("{frame}")).render(area.clone().offset(Offset { x: 0, y: 2 }), buf);
|
||||
//Line::from("Rate:").render(area.clone().offset(Offset { x: 10, y: 1 }), buf);
|
||||
//Line::from(match rate {
|
||||
//Some(rate) => format!("{rate}Hz"),
|
||||
//None => String::from("(none)"),
|
||||
//}).render(area.clone().offset(Offset { x: 10, y: 2 }), buf);
|
||||
//Line::from("Time:").render(area.clone().offset(Offset { x: 20, y: 1 }), buf);
|
||||
//Line::from(match rate {
|
||||
//Some(rate) => format!("{:.03}", frame as f64 / rate as f64),
|
||||
//None => String::from("(none)")
|
||||
//}).render(area.clone().offset(Offset { x: 20, y: 2 }), buf);
|
||||
//Line::from("BPM:").render(area.clone().offset(Offset { x: 30, y: 1 }), buf);
|
||||
//Line::from(match bbt {
|
||||
//Some(bbt) => format!("{:.01}", bbt.bpm),
|
||||
//None => String::from("(none)")
|
||||
//}).render(area.clone().offset(Offset { x: 30, y: 2 }), buf);
|
||||
//Line::from("TimeSig:").render(area.clone().offset(Offset { x: 40, y: 1 }), buf);
|
||||
//Line::from(match bbt {
|
||||
//Some(bbt) => format!("{}/{}", bbt.sig_num, bbt.sig_denom),
|
||||
//None => String::from("(none)")
|
||||
//}).render(area.clone().offset(Offset { x: 40, y: 2 }), buf);
|
||||
//Line::from("Beat:").render(area.clone().offset(Offset { x: 50, y: 1 }), buf);
|
||||
//Line::from(match bbt {
|
||||
//Some(bbt) => format!("{}.{}.{}", bbt.bar, bbt.beat, bbt.tick),
|
||||
//None => String::from("(none)")
|
||||
//}).render(area.clone().offset(Offset { x: 50, y: 2 }), buf);
|
||||
//}
|
||||
}
|
||||
|
||||
//pub fn render (
|
||||
|
|
@ -206,12 +191,17 @@ impl WidgetRef for Transport {
|
|||
//Ok(())
|
||||
//}
|
||||
|
||||
impl HandleInput for self::Transport {
|
||||
fn handle (&mut self, event: &Event) -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
}
|
||||
pub fn handle (state: &mut Transport, event: &EngineEvent) -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub const ACTIONS: [(&'static str, &'static str);4] = [
|
||||
("?", "Toggle help"),
|
||||
("(Shift-)Tab", "Switch pane"),
|
||||
("Arrows", "Navigate"),
|
||||
("(Shift-)Space", "⯈ Play/pause"),
|
||||
];
|
||||
|
||||
struct Notifications;
|
||||
|
||||
impl NotificationHandler for Notifications {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue