group devices

This commit is contained in:
🪞👃🪞 2024-06-07 18:16:23 +03:00
parent 60627ac3e5
commit 5afed6f055
8 changed files with 147 additions and 267 deletions

View file

@ -1,242 +0,0 @@
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,
bpm: f64,
timesig: (f32, f32),
}
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"),
bpm: 113.0,
timesig: (4.0, 4.0),
transport,
})
}
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()? {
TransportState::Stopped => self.play(),
TransportState::Rolling => self.stop(),
_ => Ok(())
}
}
pub fn play (&mut self) -> Result<(), Box<dyn Error>> {
Ok(self.transport.start()?)
}
pub fn stop (&mut self) -> Result<(), Box<dyn Error>> {
Ok(self.transport.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();
draw_leaf(buf, area, 2, 13, &format!("BBT {}.{}.{}",
0,
0,
0,
));
let rate = position.pos.frame_rate().unwrap();
let frame = position.pos.frame();
let time = frame as f64 / rate as f64;
let seconds = time % 60.0;
let msec = seconds % 1.0;
let minutes = (time / 60.0) % 60.0;
let hours = time / 3600.0;
draw_leaf(buf, area, 2, 27, &format!(
"Time {:02}:{:02}:{:02}.{:03}",
hours as u64,
minutes as u64,
seconds as u64,
(msec * 1000.0) as u64
));
draw_leaf(buf, area, 2, 46, &format!("Rate {:>6}Hz", rate));
draw_leaf(buf, area, 2, 61, &format!("Frame {:>12}", 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);
//}
}
}
//pub fn render (
//state: &mut Transport,
//stdout: &mut Stdout,
//mut offset: (u16, u16)
//) -> Result<(), Box<dyn Error>> {
//let move_to = |col, row| MoveTo(offset.0 + col, offset.1 + row);
//stdout.queue(move_to( 1, 0))?.queue(
//Print("Project: ")
//)?.queue(move_to(10, 0))?.queue(
//PrintStyledContent(state.title.clone().white().bold())
//)?;
//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));
//stdout
//.queue(move_to( 1, 1))?.queue(Print("Frame: "))?
//.queue(move_to( 1, 2))?.queue(
//PrintStyledContent(
//format!("{frame}").white().bold(),
//))?
//.queue(move_to(11, 1))?.queue(Print("Rate: "))?
//.queue(move_to(11, 2))?.queue(
//PrintStyledContent(match rate {
//Some(rate) => format!("{rate}Hz"),
//None => String::from("(none)"),
//}.white().bold())
//)?
//.queue(move_to(20, 1))?.queue(Print("Time: "))?
//.queue(move_to(20, 2))?.queue(
//PrintStyledContent(match rate {
//Some(rate) => format!("{:.03}", frame as f64 / rate as f64),
//None => String::from("(none)")
//}.white().bold())
//)?
//.queue(move_to(30, 1))?.queue(Print("BPM: "))?
//.queue(move_to(30, 2))?.queue(
//PrintStyledContent(match bbt {
//Some(bbt) => format!("{:.01}", bbt.bpm),
//None => String::from("(none)")
//}.white().bold())
//)?
//.queue(move_to(39, 1))?.queue(Print("Timesig: "))?
//.queue(move_to(39, 2))?.queue(
//PrintStyledContent(match bbt {
//Some(bbt) => format!("{}/{}", bbt.sig_num, bbt.sig_denom),
//None => String::from("(none)")
//}.white().bold())
//)?
//.queue(move_to(50, 1))?.queue(Print("Beat: "))?
//.queue(move_to(50, 2))?.queue(
//PrintStyledContent(match bbt {
//Some(bbt) => format!("{}.{}.{}", bbt.bar, bbt.beat, bbt.tick),
//None => String::from("(none)")
//}.white().bold())
//)?;
//}
//Ok(())
//}
impl HandleInput for self::Transport {
fn handle (&mut self, event: &Event) -> Result<(), Box<dyn Error>> {
Ok(())
}
}
struct Notifications;
impl NotificationHandler for Notifications {
fn thread_init (&self, _: &Client) {
}
fn shutdown (&mut self, status: ClientStatus, reason: &str) {
}
fn freewheel (&mut self, _: &Client, is_enabled: bool) {
}
fn sample_rate (&mut self, _: &Client, _: Frames) -> Control {
Control::Quit
}
fn client_registration (&mut self, _: &Client, name: &str, is_reg: bool) {
}
fn port_registration (&mut self, _: &Client, port_id: PortId, is_reg: bool) {
}
fn port_rename (&mut self, _: &Client, id: PortId, old: &str, new: &str) -> Control {
Control::Continue
}
fn ports_connected (&mut self, _: &Client, id_a: PortId, id_b: PortId, are: bool) {
}
fn graph_reorder (&mut self, _: &Client) -> Control {
Control::Continue
}
fn xrun (&mut self, _: &Client) -> Control {
Control::Continue
}
}