mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
wip: layout
This commit is contained in:
parent
ac865824cc
commit
d627d257ad
13 changed files with 220 additions and 131 deletions
|
|
@ -36,7 +36,7 @@ pub fn run (device: impl Device + Send + Sync + 'static) -> Result<(), Box<dyn E
|
||||||
if event::poll(poll).is_ok() {
|
if event::poll(poll).is_ok() {
|
||||||
let event = event::read().unwrap();
|
let event = event::read().unwrap();
|
||||||
match event {
|
match event {
|
||||||
crossterm::event::Event::Key(KeyEvent {
|
Event::Key(KeyEvent {
|
||||||
code: KeyCode::Char('c'),
|
code: KeyCode::Char('c'),
|
||||||
modifiers: KeyModifiers::CONTROL,
|
modifiers: KeyModifiers::CONTROL,
|
||||||
..
|
..
|
||||||
|
|
@ -53,7 +53,6 @@ pub fn run (device: impl Device + Send + Sync + 'static) -> Result<(), Box<dyn E
|
||||||
stdout().execute(EnterAlternateScreen)?;
|
stdout().execute(EnterAlternateScreen)?;
|
||||||
enable_raw_mode()?;
|
enable_raw_mode()?;
|
||||||
let mut terminal = ratatui::Terminal::new(CrosstermBackend::new(stdout()))?;
|
let mut terminal = ratatui::Terminal::new(CrosstermBackend::new(stdout()))?;
|
||||||
let sleep = std::time::Duration::from_millis(16);
|
|
||||||
//better_panic::install();
|
//better_panic::install();
|
||||||
let better_panic_handler = better_panic::Settings::auto()
|
let better_panic_handler = better_panic::Settings::auto()
|
||||||
.verbosity(better_panic::Verbosity::Full)
|
.verbosity(better_panic::Verbosity::Full)
|
||||||
|
|
@ -70,6 +69,7 @@ pub fn run (device: impl Device + Send + Sync + 'static) -> Result<(), Box<dyn E
|
||||||
//writeln!(std::io::stderr(), "{:?}", ::backtrace::Backtrace::new())
|
//writeln!(std::io::stderr(), "{:?}", ::backtrace::Backtrace::new())
|
||||||
//.unwrap();
|
//.unwrap();
|
||||||
}));
|
}));
|
||||||
|
let sleep = std::time::Duration::from_millis(16);
|
||||||
loop {
|
loop {
|
||||||
terminal.draw(|frame|{
|
terminal.draw(|frame|{
|
||||||
let area = frame.size();
|
let area = frame.size();
|
||||||
|
|
@ -93,15 +93,15 @@ pub trait Device: Send + Sync {
|
||||||
fn handle (&mut self, _event: &EngineEvent) -> Usually<()> {
|
fn handle (&mut self, _event: &EngineEvent) -> Usually<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn render (&self, _buffer: &mut Buffer, _area: Rect) -> Usually<(u16, u16)> {
|
fn render (&self, _buffer: &mut Buffer, _area: Rect) -> Usually<Rect> {
|
||||||
Ok((0,0))
|
Ok(Rect { x: 0, y: 0, width: 0, height: 0 })
|
||||||
}
|
}
|
||||||
fn process (&mut self, _client: Client, _scope: ProcessScope) {}
|
fn process (&mut self, _client: Client, _scope: ProcessScope) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DynamicDevice<T> {
|
pub struct DynamicDevice<T> {
|
||||||
pub state: Mutex<T>,
|
pub state: Mutex<T>,
|
||||||
pub render: Mutex<Box<dyn FnMut(&T, &mut Buffer, Rect)->Usually<(u16, u16)> + Send>>,
|
pub render: Mutex<Box<dyn FnMut(&T, &mut Buffer, Rect)->Usually<Rect> + Send>>,
|
||||||
pub handle: Mutex<Box<dyn FnMut(&mut T, &EngineEvent)->Usually<()> + Send>>,
|
pub handle: Mutex<Box<dyn FnMut(&mut T, &EngineEvent)->Usually<()> + Send>>,
|
||||||
pub process: Mutex<Box<dyn FnMut(&mut T) + Send>>
|
pub process: Mutex<Box<dyn FnMut(&mut T) + Send>>
|
||||||
}
|
}
|
||||||
|
|
@ -113,7 +113,7 @@ impl<T> DynamicDevice<T> {
|
||||||
process: P,
|
process: P,
|
||||||
state: T
|
state: T
|
||||||
) -> Self where
|
) -> Self where
|
||||||
R: FnMut(&T, &mut Buffer, Rect)->Usually<(u16, u16)> + Send + 'static,
|
R: FnMut(&T, &mut Buffer, Rect)->Usually<Rect> + Send + 'static,
|
||||||
H: FnMut(&mut T, &EngineEvent) -> Result<(), Box<dyn Error>> + Send + 'static,
|
H: FnMut(&mut T, &EngineEvent) -> Result<(), Box<dyn Error>> + Send + 'static,
|
||||||
P: FnMut(&mut T) + Send + 'static
|
P: FnMut(&mut T) + Send + 'static
|
||||||
{
|
{
|
||||||
|
|
@ -133,7 +133,7 @@ impl<T: Send + Sync> Device for DynamicDevice<T> {
|
||||||
fn handle (&mut self, event: &EngineEvent) -> Usually<()> {
|
fn handle (&mut self, event: &EngineEvent) -> Usually<()> {
|
||||||
self.handle.lock().unwrap()(&mut *self.state.lock().unwrap(), event)
|
self.handle.lock().unwrap()(&mut *self.state.lock().unwrap(), event)
|
||||||
}
|
}
|
||||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<(u16, u16)> {
|
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
self.render.lock().unwrap()(&*self.state.lock().unwrap(), buf, area)
|
self.render.lock().unwrap()(&*self.state.lock().unwrap(), buf, area)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ impl Chain {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render (state: &Chain, buf: &mut Buffer, area: Rect)
|
pub fn render (state: &Chain, buf: &mut Buffer, area: Rect)
|
||||||
-> Usually<(u16, u16)>
|
-> Usually<Rect>
|
||||||
{
|
{
|
||||||
let Rect { x, y, width, height } = area;
|
let Rect { x, y, width, height } = area;
|
||||||
let area = Rect { x, y, width: 40, height: 30 };
|
let area = Rect { x, y, width: 40, height: 30 };
|
||||||
|
|
@ -26,25 +26,25 @@ pub fn render (state: &Chain, buf: &mut Buffer, area: Rect)
|
||||||
let mut x = 0u16;
|
let mut x = 0u16;
|
||||||
y = y + 1;
|
y = y + 1;
|
||||||
for device in state.devices.iter() {
|
for device in state.devices.iter() {
|
||||||
let (w, h) = device.render(buf, Rect {
|
let result = device.render(buf, Rect {
|
||||||
x: area.x,
|
x: area.x,
|
||||||
y: area.y + y,
|
y: area.y + y,
|
||||||
width: area.width,
|
width: area.width,
|
||||||
height: area.height - y
|
height: area.height.saturating_sub(y)
|
||||||
})?;
|
})?;
|
||||||
//buf.set_string(area.x, y, format!("{y}---TOP---+{h}"), Style::default().red());
|
//buf.set_string(area.x, y, format!("{y}---TOP---+{h}"), Style::default().red());
|
||||||
x = x.max(w);
|
x = x.max(result.width);
|
||||||
y = y + h;
|
y = y + result.height;
|
||||||
y = y + 1;
|
y = y + 1;
|
||||||
buf.set_string(area.x, y, "│", Style::default().black());
|
buf.set_string(area.x, y, "│", Style::default().black());
|
||||||
buf.set_string(area.x + area.width - 1, y, "│", Style::default().black());
|
buf.set_string(area.x + area.width - 1, y, "│", Style::default().black());
|
||||||
buf.set_string(area.x + 2, y, "Patch in... │ Patch out...", Style::default().dim());
|
buf.set_string(area.x + 2, y, " Patch in ┐ │ └ Patch out", Style::default().dim());
|
||||||
y = y + 1;
|
y = y + 1;
|
||||||
//buf.set_string(area.x, y, format!("{y}---BOT---"), Style::default().red());
|
//buf.set_string(area.x, y, format!("{y}---BOT---"), Style::default().red());
|
||||||
//buf.set_string(area.x + area.width - 1, area.y + 1, "│", Style::default().black());
|
//buf.set_string(area.x + area.width - 1, area.y + 1, "│", Style::default().black());
|
||||||
//buf.set_string(area.x + 2, y, "Patch...", Style::default().dim());
|
//buf.set_string(area.x + 2, y, "Patch...", Style::default().dim());
|
||||||
}
|
}
|
||||||
Ok((x, y))
|
Ok(Rect { x: area.x, y: area.y, width: x, height: y })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle (state: &mut Chain, event: &EngineEvent) -> Result<(), Box<dyn Error>> {
|
pub fn handle (state: &mut Chain, event: &EngineEvent) -> Result<(), Box<dyn Error>> {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,9 @@ impl Launcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render (state: &Launcher, buf: &mut Buffer, area: Rect) {}
|
pub fn render (state: &Launcher, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
|
Ok(Rect::default())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn handle (state: &mut Launcher, event: &Event) -> Result<(), Box<dyn Error>> {
|
pub fn handle (state: &mut Launcher, event: &Event) -> Result<(), Box<dyn Error>> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ impl Looper {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render (state: &Looper, buf: &mut Buffer, area: Rect)
|
pub fn render (state: &Looper, buf: &mut Buffer, area: Rect)
|
||||||
-> Usually<(u16, u16)>
|
-> Usually<Rect>
|
||||||
{
|
{
|
||||||
//let move_to = |col, row| MoveTo(offset.0 + col, offset.1 + row);
|
//let move_to = |col, row| MoveTo(offset.0 + col, offset.1 + row);
|
||||||
//stdout
|
//stdout
|
||||||
|
|
@ -22,7 +22,7 @@ pub fn render (state: &Looper, buf: &mut Buffer, area: Rect)
|
||||||
//.queue(move_to(0, 2))?.queue(PrintStyledContent(" Loop 1 [ ] ████ Track 1".bold()))?
|
//.queue(move_to(0, 2))?.queue(PrintStyledContent(" Loop 1 [ ] ████ Track 1".bold()))?
|
||||||
//.queue(move_to(0, 3))?.queue(PrintStyledContent(" Loop 2 [ ] ████████ Track 2".bold()))?
|
//.queue(move_to(0, 3))?.queue(PrintStyledContent(" Loop 2 [ ] ████████ Track 2".bold()))?
|
||||||
//.queue(move_to(0, 4))?.queue(PrintStyledContent(" Loop 3 [ ] ████████ Track 3".bold()))?;
|
//.queue(move_to(0, 4))?.queue(PrintStyledContent(" Loop 3 [ ] ████████ Track 3".bold()))?;
|
||||||
Ok((20, 10))
|
Ok(Rect::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle (state: &mut Looper, event: &EngineEvent) -> Result<(), Box<dyn Error>> {
|
pub fn handle (state: &mut Looper, event: &EngineEvent) -> Result<(), Box<dyn Error>> {
|
||||||
|
|
|
||||||
|
|
@ -42,10 +42,10 @@ impl Mixer {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render (state: &Mixer, buf: &mut Buffer, mut area: Rect)
|
pub fn render (state: &Mixer, buf: &mut Buffer, mut area: Rect)
|
||||||
-> Usually<(u16, u16)>
|
-> Usually<Rect>
|
||||||
{
|
{
|
||||||
if area.height < 2 {
|
if area.height < 2 {
|
||||||
return Ok((0, 0))
|
return Ok(area)
|
||||||
}
|
}
|
||||||
area.x = area.width.saturating_sub(80) / 2;
|
area.x = area.width.saturating_sub(80) / 2;
|
||||||
area.width = area.width.min(80);
|
area.width = area.width.min(80);
|
||||||
|
|
@ -87,7 +87,7 @@ pub fn render (state: &Mixer, buf: &mut Buffer, mut area: Rect)
|
||||||
//fn render_meters (
|
//fn render_meters (
|
||||||
//state: &mut Mixer,
|
//state: &mut Mixer,
|
||||||
//stdout: &mut Stdout,
|
//stdout: &mut Stdout,
|
||||||
//offset: (u16, u16)
|
//offset: Rect
|
||||||
//) -> Result<(), Box<dyn Error>> {
|
//) -> Result<(), Box<dyn Error>> {
|
||||||
//let move_to = |col, row| crossterm::cursor::MoveTo(offset.0 + col, offset.1 + row);
|
//let move_to = |col, row| crossterm::cursor::MoveTo(offset.0 + col, offset.1 + row);
|
||||||
//for (i, track) in state.tracks.iter().enumerate() {
|
//for (i, track) in state.tracks.iter().enumerate() {
|
||||||
|
|
@ -102,7 +102,7 @@ pub fn render (state: &Mixer, buf: &mut Buffer, mut area: Rect)
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok((20,10))
|
Ok(area)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle (state: &mut Mixer, event: &EngineEvent) -> Result<(), Box<dyn Error>> {
|
pub fn handle (state: &mut Mixer, event: &EngineEvent) -> Result<(), Box<dyn Error>> {
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ impl Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render (state: &Plugin, buf: &mut Buffer, Rect { x, y, width, height }: Rect)
|
pub fn render (state: &Plugin, buf: &mut Buffer, Rect { x, y, width, height }: Rect)
|
||||||
-> Usually<(u16, u16)>
|
-> Usually<Rect>
|
||||||
{
|
{
|
||||||
let style = Style::default().gray();
|
let style = Style::default().gray();
|
||||||
draw_box(buf, Rect { x, y: y, width: 40, height: 8 });
|
draw_box(buf, Rect { x, y, width: 40, height: 8 });
|
||||||
buf.set_string(x + 1, y + 1, &format!(" {}", state.name), style.white().bold());
|
buf.set_string(x + 1, y + 1, &format!(" {}", state.name), style.white().bold());
|
||||||
buf.set_string(x + 13, y + 1, &format!("│ Plugin Name"), style.not_dim());
|
buf.set_string(x + 13, y + 1, &format!("│ Plugin Name"), style.not_dim());
|
||||||
buf.set_string(x + 0, y + 2, &format!("├--------------------------------------┤"), style.dim());
|
buf.set_string(x + 0, y + 2, &format!("├--------------------------------------┤"), style.dim());
|
||||||
|
|
@ -24,7 +24,7 @@ pub fn render (state: &Plugin, buf: &mut Buffer, Rect { x, y, width, height }: R
|
||||||
buf.set_string(x + 1, y + 4, &format!(" Parameter 2 0.0"), style);
|
buf.set_string(x + 1, y + 4, &format!(" Parameter 2 0.0"), style);
|
||||||
buf.set_string(x + 1, y + 5, &format!(" Parameter 3 0.0"), style);
|
buf.set_string(x + 1, y + 5, &format!(" Parameter 3 0.0"), style);
|
||||||
buf.set_string(x + 1, y + 6, &format!(" Parameter 4 0.0"), style);
|
buf.set_string(x + 1, y + 6, &format!(" Parameter 4 0.0"), style);
|
||||||
Ok((40, 7))
|
Ok(Rect { x, y, width: 40, height: 7 })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle (state: &mut Plugin, event: &EngineEvent) -> Result<(), Box<dyn Error>> {
|
pub fn handle (state: &mut Plugin, event: &EngineEvent) -> Result<(), Box<dyn Error>> {
|
||||||
|
|
|
||||||
|
|
@ -107,28 +107,28 @@ impl Sample {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render (state: &Sampler, buf: &mut Buffer, Rect { x, y, width, height }: Rect)
|
pub fn render (state: &Sampler, buf: &mut Buffer, Rect { x, y, width, height }: Rect)
|
||||||
-> Usually<(u16, u16)>
|
-> Usually<Rect>
|
||||||
{
|
{
|
||||||
let style = Style::default().gray();
|
let style = Style::default().gray();
|
||||||
draw_box(buf, Rect { x, y: y, width: 40, height: 12 });
|
draw_box(buf, Rect { x, y: y, width: 40, height: 12 });
|
||||||
buf.set_string(x + 1, y + 1, &format!(" {} │", state.name), style.white().bold());
|
buf.set_string(x + 1, y + 1, &format!(" {} │", state.name), style.white().bold());
|
||||||
buf.set_string(x + 0, y + 2, &format!("├--------------------------------------┤"), style.dim());
|
buf.set_string(x + 0, y + 2, &format!("├--------------------------------------┤"), style.dim());
|
||||||
buf.set_string(x + 2, y + 3, &format!("C0 Sample#000"), style.bold());
|
buf.set_string(x + 2, y + 3, &format!("C4 Sample#000"), style.bold());
|
||||||
buf.set_string(x + 2, y + 4, &format!(" {:.03}s",
|
buf.set_string(x + 2, y + 4, &format!(" {:.03}s",
|
||||||
100000.0/44100.0), style);
|
100000.0/44100.0), style);
|
||||||
buf.set_string(x + 2, y + 5, &format!("C#0 Sample#001"), style.bold());
|
buf.set_string(x + 2, y + 5, &format!("C#4 Sample#001"), style.bold());
|
||||||
buf.set_string(x + 2, y + 6, &format!(" {:.03}-{:.03}s",
|
buf.set_string(x + 2, y + 6, &format!(" {:.03}-{:.03}s",
|
||||||
50000.0/44100.0, 100000.0/44100.0), style);
|
50000.0/44100.0, 100000.0/44100.0), style);
|
||||||
buf.set_string(x + 2, y + 7, &format!("D0 Sample#002"), style.bold());
|
buf.set_string(x + 2, y + 7, &format!("D4 Sample#002"), style.bold());
|
||||||
buf.set_string(x + 2, y + 8, &format!(" {:.03}-{:.03}/{:.03}s",
|
buf.set_string(x + 2, y + 8, &format!(" {:.03}-{:.03}/{:.03}s",
|
||||||
0.0, 50000.0/44100.0, 100000.0/44100.0), style);
|
0.0, 50000.0/44100.0, 100000.0/44100.0), style);
|
||||||
buf.set_string(x + 2, y + 9, &format!("D#0 Sample#003"), style.bold());
|
buf.set_string(x + 2, y + 9, &format!("D#4 Sample#003"), style.bold());
|
||||||
buf.set_string(x + 2, y + 10, &format!(" {:.03}-[{:.03}-{:.03}]/{:.03}s ",
|
buf.set_string(x + 2, y + 10, &format!(" {:.03}-[{:.03}-{:.03}]/{:.03}s ",
|
||||||
10000.0/44100.0, 25000.0/44100.0, 50000.0/44100.0, 100000.0/44100.0), style);
|
10000.0/44100.0, 25000.0/44100.0, 50000.0/44100.0, 100000.0/44100.0), style);
|
||||||
//buf.set_string(x + 1, y + 7 + 6, &format!(" Inputs... │ Outputs... "), style.dim());
|
//buf.set_string(x + 1, y + 7 + 6, &format!(" Inputs... │ Outputs... "), style.dim());
|
||||||
//render_table(state, stdout, offset)?;
|
//render_table(state, stdout, offset)?;
|
||||||
//render_meters(state, stdout, offset)?;
|
//render_meters(state, stdout, offset)?;
|
||||||
Ok((40, 11))
|
Ok(Rect { x, y, width: 40, height: 11 })
|
||||||
}
|
}
|
||||||
|
|
||||||
//fn render_table (
|
//fn render_table (
|
||||||
|
|
|
||||||
|
|
@ -206,52 +206,65 @@ const KEYS_VERTICAL: [&'static str; 6] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
fn render (sequencer: &Sequencer, buf: &mut Buffer, mut area: Rect)
|
fn render (sequencer: &Sequencer, buf: &mut Buffer, mut area: Rect)
|
||||||
-> Usually<(u16, u16)>
|
-> Usually<Rect>
|
||||||
{
|
{
|
||||||
let style = Style::default().gray();
|
let style = Style::default().gray();
|
||||||
area.height = 18;
|
let header = draw_sequencer_header(sequencer, buf, area)?;
|
||||||
|
let piano = draw_sequencer_vertical(sequencer, buf, Rect {
|
||||||
|
x: area.x,
|
||||||
|
y: area.y + header.height,
|
||||||
|
width: area.width,
|
||||||
|
height: area.height - header.height
|
||||||
|
})?;
|
||||||
|
let area = Rect {
|
||||||
|
x: area.x,
|
||||||
|
y: area.y,
|
||||||
|
width: header.width.max(piano.width),
|
||||||
|
height: header.height + piano.height
|
||||||
|
};
|
||||||
|
//draw_box_styled(buf, area, Some(Style::default().red()));
|
||||||
|
Ok(area)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_sequencer_header (sequencer: &Sequencer, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
let Rect { x, y, width, height } = area;
|
let Rect { x, y, width, height } = area;
|
||||||
|
let style = Style::default().gray();
|
||||||
buf.set_string(x + 1, y + 1, &format!(" │ 00:00.00 / 00:00.00"), style);
|
buf.set_string(x + 1, y + 1, &format!(" │ 00:00.00 / 00:00.00"), style);
|
||||||
buf.set_string(x + 2, y + 1, &format!("{}", &sequencer.name), style.white().bold());
|
buf.set_string(x + 2, y + 1, &format!("{}", &sequencer.name), style.white().bold());
|
||||||
buf.set_string(x + 1, y + 2, &format!(" ▶ PLAY │ ⏹ STOP │ ⏺ REC │ ⏺ DUB "), style);
|
buf.set_string(x + 1, y + 2, &format!(" ▶ PLAY │ ⏹ STOP │ ⏺ REC │ ⏺ DUB "), style);
|
||||||
//buf.set_string(x + 1, y + 6, &format!(" │ Outputs... "), style.dim());
|
Ok(Rect { x, y, width, height: 4 })
|
||||||
|
}
|
||||||
|
|
||||||
let mut h = 9;
|
fn draw_sequencer_vertical (sequencer: &Sequencer, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
let toggle = true;
|
let Rect { x, y, .. } = area;
|
||||||
if toggle {
|
let white = Style::default().gray();
|
||||||
for i in 0..16 {
|
let black = Style::default().black();
|
||||||
buf.set_string(x + 2, y + 4 + i, &format!(" "), Style::default().on_black());
|
for i in 0..area.width-4 {
|
||||||
h = h + 1;
|
let color = match i % 12 {
|
||||||
}
|
0 => white,
|
||||||
|
1 => black,
|
||||||
|
2 => white,
|
||||||
|
3 => black,
|
||||||
|
4 => white,
|
||||||
|
5 => white,
|
||||||
|
6 => black,
|
||||||
|
7 => white,
|
||||||
|
8 => black,
|
||||||
|
9 => white,
|
||||||
|
10 => black,
|
||||||
|
11 => white,
|
||||||
|
_ => unreachable!()
|
||||||
|
};
|
||||||
|
buf.set_string(x + 2 + i, y - 1, &format!("▄"), color);
|
||||||
|
buf.set_string(x + 2 + i, y, &format!("▀"), color);
|
||||||
}
|
}
|
||||||
for i in 0..3 {
|
let bg = Style::default().on_black();
|
||||||
buf.set_string(1 + i * 12 + x + 1, y + h - 5, &format!("▄"), Style::default().white());
|
for i in 0..area.height - 8 {
|
||||||
buf.set_string(1 + i * 12 + x + 2, y + h - 5, &format!("▄"), Style::default().black());
|
buf.set_string(x + 2, y + 1 + i, &" ".repeat((area.width-4)as usize), bg);
|
||||||
buf.set_string(1 + i * 12 + x + 3, y + h - 5, &format!("▄"), Style::default().white());
|
|
||||||
buf.set_string(1 + i * 12 + x + 4, y + h - 5, &format!("▄"), Style::default().black());
|
|
||||||
buf.set_string(1 + i * 12 + x + 5, y + h - 5, &format!("▄"), Style::default().white());
|
|
||||||
buf.set_string(1 + i * 12 + x + 6, y + h - 5, &format!("▄"), Style::default().white());
|
|
||||||
buf.set_string(1 + i * 12 + x + 7, y + h - 5, &format!("▄"), Style::default().black());
|
|
||||||
buf.set_string(1 + i * 12 + x + 8, y + h - 5, &format!("▄"), Style::default().white());
|
|
||||||
buf.set_string(1 + i * 12 + x + 9, y + h - 5, &format!("▄"), Style::default().black());
|
|
||||||
buf.set_string(1 + i * 12 + x + 10, y + h - 5, &format!("▄"), Style::default().white());
|
|
||||||
buf.set_string(1 + i * 12 + x + 11, y + h - 5, &format!("▄"), Style::default().black());
|
|
||||||
buf.set_string(1 + i * 12 + x + 12, y + h - 5, &format!("▄"), Style::default().white());
|
|
||||||
buf.set_string(1 + i * 12 + x + 1, y + h - 4, &format!("▀"), Style::default().white());
|
|
||||||
buf.set_string(1 + i * 12 + x + 2, y + h -4, &format!("▀"), Style::default().black());
|
|
||||||
buf.set_string(1 + i * 12 + x + 3, y + h -4, &format!("▀"), Style::default().white());
|
|
||||||
buf.set_string(1 + i * 12 + x + 4, y + h -4, &format!("▀"), Style::default().black());
|
|
||||||
buf.set_string(1 + i * 12 + x + 5, y + h -4, &format!("▀"), Style::default().white());
|
|
||||||
buf.set_string(1 + i * 12 + x + 6, y + h -4, &format!("▀"), Style::default().white());
|
|
||||||
buf.set_string(1 + i * 12 + x + 7, y + h -4, &format!("▀"), Style::default().black());
|
|
||||||
buf.set_string(1 + i * 12 + x + 8, y + h -4, &format!("▀"), Style::default().white());
|
|
||||||
buf.set_string(1 + i * 12 + x + 9, y + h -4, &format!("▀"), Style::default().black());
|
|
||||||
buf.set_string(1 + i * 12 + x + 10, y + h -4, &format!("▀"), Style::default().white());
|
|
||||||
buf.set_string(1 + i * 12 + x + 11, y + h -4, &format!("▀"), Style::default().black());
|
|
||||||
buf.set_string(1 + i * 12 + x + 12, y + h -4, &format!("▀"), Style::default().white());
|
|
||||||
}
|
}
|
||||||
draw_box(buf, Rect { x, y, width: 40, height: h - 2 });
|
Ok(Rect { x, y, width: area.width, height: area.height - 6 })
|
||||||
Ok((40,h-3))
|
}
|
||||||
|
|
||||||
//{
|
//{
|
||||||
//let mut area = area.clone();
|
//let mut area = area.clone();
|
||||||
//area.y = area.y + 3;
|
//area.y = area.y + 3;
|
||||||
|
|
@ -329,7 +342,6 @@ fn render (sequencer: &Sequencer, buf: &mut Buffer, mut area: Rect)
|
||||||
//}
|
//}
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
}
|
|
||||||
|
|
||||||
fn draw_sequence_button (
|
fn draw_sequence_button (
|
||||||
buf: &mut Buffer,
|
buf: &mut Buffer,
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,12 @@ impl Transport {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render (state: &Transport, buf: &mut Buffer, mut area: Rect)
|
pub fn render (state: &Transport, buf: &mut Buffer, mut area: Rect)
|
||||||
-> Usually<(u16, u16)>
|
-> Usually<Rect>
|
||||||
{
|
{
|
||||||
area.x = area.width.saturating_sub(80) / 2;
|
area.x = area.width.saturating_sub(80) / 2;
|
||||||
area.width = area.width.min(80);
|
area.width = area.width.min(80);
|
||||||
area.height = 5;
|
area.height = 5;
|
||||||
draw_box(buf, area);
|
//draw_box(buf, area);
|
||||||
draw_leaf(buf, area, 1, 0, "REC");
|
draw_leaf(buf, area, 1, 0, "REC");
|
||||||
draw_leaf(buf, area, 1, 5, "DUB");
|
draw_leaf(buf, area, 1, 5, "DUB");
|
||||||
draw_leaf(buf, area, 1, 10, "STOP");
|
draw_leaf(buf, area, 1, 10, "STOP");
|
||||||
|
|
@ -91,7 +91,6 @@ pub fn render (state: &Transport, buf: &mut Buffer, mut area: Rect)
|
||||||
draw_leaf(buf, area, 3, 48, &format!("Rate {:>6}Hz", rate));
|
draw_leaf(buf, area, 3, 48, &format!("Rate {:>6}Hz", rate));
|
||||||
draw_leaf(buf, area, 3, 63, &format!("Frame {:>10}", frame));
|
draw_leaf(buf, area, 3, 63, &format!("Frame {:>10}", frame));
|
||||||
}
|
}
|
||||||
Ok((area.width, area.height))
|
|
||||||
//let bbt = position.pos.bbt().map(|mut bbt|*bbt
|
//let bbt = position.pos.bbt().map(|mut bbt|*bbt
|
||||||
//.with_bpm(state.bpm)
|
//.with_bpm(state.bpm)
|
||||||
//.with_timesig(state.timesig.0, state.timesig.1));
|
//.with_timesig(state.timesig.0, state.timesig.1));
|
||||||
|
|
@ -131,6 +130,7 @@ pub fn render (state: &Transport, buf: &mut Buffer, mut area: Rect)
|
||||||
//None => String::from("(none)")
|
//None => String::from("(none)")
|
||||||
//}).render(area.clone().offset(Offset { x: 50, y: 2 }), buf);
|
//}).render(area.clone().offset(Offset { x: 50, y: 2 }), buf);
|
||||||
//}
|
//}
|
||||||
|
Ok(area)
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn render (
|
//pub fn render (
|
||||||
|
|
|
||||||
134
src/layout.rs
134
src/layout.rs
|
|
@ -1,47 +1,123 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub struct Rows(pub Vec<Box<dyn Device>>);
|
pub struct Rows {
|
||||||
|
focused: bool,
|
||||||
|
focus: usize,
|
||||||
|
items: Vec<Box<dyn Device>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Columns(pub Vec<Box<dyn Device>>);
|
impl Rows {
|
||||||
|
pub fn new (focused: bool, items: Vec<Box<dyn Device>>) -> Self {
|
||||||
|
Self { focused, focus: 0, items }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Device for Rows {
|
impl Device for Rows {
|
||||||
fn handle (&mut self, event: &EngineEvent) -> Usually<()> {
|
fn handle (&mut self, event: &EngineEvent) -> Usually<()> {
|
||||||
Ok(())
|
if !self.focused {
|
||||||
}
|
match event {
|
||||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<(u16, u16)> {
|
EngineEvent::Input(Event::Key(KeyEvent { code: KeyCode::Esc, .. })) => {
|
||||||
let mut x = 0u16;
|
self.focused = true;
|
||||||
let mut y = 0u16;
|
Ok(())
|
||||||
for device in self.0.iter() {
|
},
|
||||||
let (w, h) = device.render(buf, Rect {
|
_ => self.items[self.focus].handle(event)
|
||||||
x: area.x,
|
}
|
||||||
y: area.y + y,
|
} else {
|
||||||
width: area.width,
|
match event {
|
||||||
height: area.height - y
|
EngineEvent::Input(event) => match event {
|
||||||
})?;
|
Event::Key(KeyEvent { code: KeyCode::Up, .. }) => {
|
||||||
x = x.max(w);
|
if self.focus == 0 {
|
||||||
y = y + h;
|
self.focus = self.items.len();
|
||||||
|
}
|
||||||
|
self.focus = self.focus - 1;
|
||||||
|
},
|
||||||
|
Event::Key(KeyEvent { code: KeyCode::Down, .. }) => {
|
||||||
|
self.focus = self.focus + 1;
|
||||||
|
if self.focus >= self.items.len() {
|
||||||
|
self.focus = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Event::Key(KeyEvent { code: KeyCode::Enter, .. }) => {
|
||||||
|
self.focused = false;
|
||||||
|
},
|
||||||
|
Event::Key(KeyEvent { code: KeyCode::Esc, .. }) => {
|
||||||
|
self.focused = true;
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
println!("{event:?}");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
Ok((x, y))
|
}
|
||||||
|
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
|
let mut w = 0u16;
|
||||||
|
let mut h = 0u16;
|
||||||
|
for (i, device) in self.items.iter().enumerate() {
|
||||||
|
let result = device.render(buf, Rect {
|
||||||
|
x: area.x,
|
||||||
|
y: area.y + h,
|
||||||
|
width: area.width,
|
||||||
|
height: area.height - h
|
||||||
|
})?;
|
||||||
|
if self.focused && i == self.focus {
|
||||||
|
draw_box_styled(buf, result, Some(Style::default().gray().bold().not_dim()))
|
||||||
|
}
|
||||||
|
w = w.max(result.width);
|
||||||
|
h = h + result.height;
|
||||||
|
}
|
||||||
|
Ok(Rect {
|
||||||
|
x: area.x,
|
||||||
|
y: area.y,
|
||||||
|
width: w,
|
||||||
|
height: h
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Columns {
|
||||||
|
focused: bool,
|
||||||
|
focus: usize,
|
||||||
|
items: Vec<Box<dyn Device>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Columns {
|
||||||
|
pub fn new (focused: bool, items: Vec<Box<dyn Device>>) -> Self {
|
||||||
|
Self { focused, focus: 0, items }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Device for Columns {
|
impl Device for Columns {
|
||||||
fn handle (&mut self, event: &EngineEvent) -> Result<(), Box<dyn Error>> {
|
fn handle (&mut self, event: &EngineEvent) -> Usually<()> {
|
||||||
Ok(())
|
if self.focused {
|
||||||
|
self.items[self.focus].handle(event)
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<(u16, u16)> {
|
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
let mut x = 0u16;
|
let mut w = 0u16;
|
||||||
let mut y = 0u16;
|
let mut h = 0u16;
|
||||||
for device in self.0.iter() {
|
for (i, device) in self.items.iter().enumerate() {
|
||||||
let (w, h) = device.render(buf, Rect {
|
let result = device.render(buf, Rect {
|
||||||
x: area.x + x,
|
x: area.x + w,
|
||||||
y: area.y,
|
y: area.y,
|
||||||
width: area.width - x,
|
width: area.width - w,
|
||||||
height: area.height
|
height: area.height
|
||||||
})?;
|
})?;
|
||||||
x = x + w;
|
if self.focused && i == self.focus {
|
||||||
y = y.max(h);
|
draw_box_styled(buf, result, Some(Style::default().yellow()))
|
||||||
|
}
|
||||||
|
w = w + result.width;
|
||||||
|
h = h.max(result.height);
|
||||||
}
|
}
|
||||||
Ok((x, y))
|
Ok(Rect {
|
||||||
|
x: area.x,
|
||||||
|
y: area.y,
|
||||||
|
width: w,
|
||||||
|
height: h
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
40
src/main.rs
40
src/main.rs
|
|
@ -19,34 +19,22 @@ fn main () -> Result<(), Box<dyn Error>> {
|
||||||
let cli = cli::Cli::parse();
|
let cli = cli::Cli::parse();
|
||||||
let xdg = microxdg::XdgApp::new("dawdle")?;
|
let xdg = microxdg::XdgApp::new("dawdle")?;
|
||||||
crate::config::create_dirs(&xdg)?;
|
crate::config::create_dirs(&xdg)?;
|
||||||
crate::device::run(Rows(vec![
|
crate::device::run(Rows::new(true, vec![
|
||||||
Box::new(Columns(vec![
|
Box::new(Sequencer::new("Rhythm#000")?),
|
||||||
Box::new(Chain::new("Chain#00", vec![
|
|
||||||
Box::new(Sequencer::new("Rhythm#000")?),
|
|
||||||
Box::new(Sampler::new("Sampler#00")?),
|
|
||||||
])?),
|
|
||||||
Box::new(Chain::new("Chain#01", vec![
|
|
||||||
Box::new(Sequencer::new("Melody#000")?),
|
|
||||||
Box::new(Plugin::new("Plugin#000")?),
|
|
||||||
])?),
|
|
||||||
])),
|
|
||||||
Box::new(Mixer::new("Mixer#000")?),
|
|
||||||
Box::new(Transport::new()?),
|
Box::new(Transport::new()?),
|
||||||
]))
|
]))
|
||||||
//crate::device::run(Rows(vec![
|
//crate::device::run(Rows::new(true, vec![
|
||||||
////Box::new(Columns(vec![
|
//Box::new(Columns::new(false, vec![
|
||||||
////Box::new(Chain::new("Chain#00", vec![
|
//Box::new(Chain::new("Chain#00", vec![
|
||||||
////Box::new(Sequencer::new("Rhythm#000")?),
|
//Box::new(Sequencer::new("Rhythm#000")?),
|
||||||
////Box::new(Sampler::new("Sampler#00")?),
|
//Box::new(Sampler::new("Sampler#00")?),
|
||||||
////])?),
|
//])?),
|
||||||
////Box::new(Chain::new("Chain#01", vec![
|
//Box::new(Chain::new("Chain#01", vec![
|
||||||
////Box::new(Sequencer::new("Melody#000")?),
|
//Box::new(Sequencer::new("Melody#000")?),
|
||||||
////Box::new(Plugin::new("Plugin#000")?),
|
//Box::new(Plugin::new("Plugin#000")?),
|
||||||
////])?),
|
//])?),
|
||||||
////Box::new(Chain::new("Chain#02", vec![])?),
|
//])),
|
||||||
////Box::new(Chain::new("Chain#03", vec![])?),
|
//Box::new(Mixer::new("Mixer#000")?),
|
||||||
////])),
|
|
||||||
////Box::new(Mixer::new("Mixer#00")?),
|
|
||||||
//Box::new(Transport::new()?),
|
//Box::new(Transport::new()?),
|
||||||
//]))
|
//]))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,11 +53,7 @@ pub use jack::{
|
||||||
};
|
};
|
||||||
pub type BoxedProcessHandler = Box<dyn FnMut(&Client, &ProcessScope)-> Control + Send>;
|
pub type BoxedProcessHandler = Box<dyn FnMut(&Client, &ProcessScope)-> Control + Send>;
|
||||||
pub type Jack<N> = AsyncClient<N, ClosureProcessHandler<BoxedProcessHandler>>;
|
pub type Jack<N> = AsyncClient<N, ClosureProcessHandler<BoxedProcessHandler>>;
|
||||||
pub use crate::render::{
|
pub use crate::render::*;
|
||||||
draw_box,
|
|
||||||
draw_leaf,
|
|
||||||
draw_focus_corners
|
|
||||||
};
|
|
||||||
pub use crate::device::{
|
pub use crate::device::{
|
||||||
Device,
|
Device,
|
||||||
DynamicDevice,
|
DynamicDevice,
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,21 @@ pub fn draw_box (buffer: &mut Buffer, area: Rect) {
|
||||||
buffer.set_string(area.x, area.y + area.height - 1, bottom, border);
|
buffer.set_string(area.x, area.y + area.height - 1, bottom, border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn draw_box_styled (buffer: &mut Buffer, area: Rect, style: Option<Style>) {
|
||||||
|
if area.width < 1 || area.height < 1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let style = style.unwrap_or(Style::default());
|
||||||
|
let top = format!("╭{}╮", "┅".repeat((area.width - 2).into()));
|
||||||
|
let bottom = format!("╰{}╯", "┅".repeat((area.width - 2).into()));
|
||||||
|
buffer.set_string(area.x, area.y, top, style);
|
||||||
|
for y in (area.y + 1)..(area.y + area.height - 1) {
|
||||||
|
buffer.set_string(area.x, y, format!("┇"), style);
|
||||||
|
buffer.set_string(area.x + area.width - 1, y, format!("┇"), style);
|
||||||
|
}
|
||||||
|
buffer.set_string(area.x, area.y + area.height - 1, bottom, style);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn draw_focus_corners (buffer: &mut Buffer, area: Rect) {
|
pub fn draw_focus_corners (buffer: &mut Buffer, area: Rect) {
|
||||||
let focus = Style::default().yellow().bold().not_dim();
|
let focus = Style::default().yellow().bold().not_dim();
|
||||||
buffer.set_string(area.x, area.y, "╭", focus);
|
buffer.set_string(area.x, area.y, "╭", focus);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue