mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-09 05:06:43 +01:00
switch toolbar actions; bold borders and titles
This commit is contained in:
parent
7dd5f7f488
commit
31f8ec5362
8 changed files with 103 additions and 116 deletions
44
src/main.rs
44
src/main.rs
|
|
@ -78,9 +78,6 @@ fn run_one (command: &cli::Command) -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
fn run_all () -> Result<(), Box<dyn Error>> {
|
fn run_all () -> Result<(), Box<dyn Error>> {
|
||||||
let mut actions = vec![];
|
let mut actions = vec![];
|
||||||
actions.extend_from_slice(&transport::ACTIONS);
|
|
||||||
actions.extend_from_slice(&mixer::ACTIONS);
|
|
||||||
actions.extend_from_slice(&looper::ACTIONS);
|
|
||||||
main_loop(
|
main_loop(
|
||||||
&mut App {
|
&mut App {
|
||||||
exited: false,
|
exited: false,
|
||||||
|
|
@ -92,23 +89,38 @@ fn run_all () -> Result<(), Box<dyn Error>> {
|
||||||
sequencer: sequencer::Sequencer::new()?,
|
sequencer: sequencer::Sequencer::new()?,
|
||||||
},
|
},
|
||||||
|state, stdout, mut offset| {
|
|state, stdout, mut offset| {
|
||||||
|
actions.clear();
|
||||||
|
actions.extend_from_slice(&transport::ACTIONS);
|
||||||
|
match state.mode {
|
||||||
|
Mode::Transport => {},
|
||||||
|
Mode::Mixer => actions.extend_from_slice(&mixer::ACTIONS),
|
||||||
|
Mode::Looper => actions.extend_from_slice(&looper::ACTIONS),
|
||||||
|
Mode::Sampler => actions.extend_from_slice(&sampler::ACTIONS),
|
||||||
|
Mode::Sequencer => actions.extend_from_slice(&sequencer::ACTIONS),
|
||||||
|
}
|
||||||
|
|
||||||
let (w, h) = render::render_toolbar_vertical(stdout, (offset.0, offset.1 + 1), &actions)?;
|
let (w, h) = render::render_toolbar_vertical(stdout, (offset.0, offset.1 + 1), &actions)?;
|
||||||
offset.0 = offset.0 + w + 1;
|
offset.0 = offset.0 + w + 1;
|
||||||
|
|
||||||
transport::render(&mut state.transport, stdout, (offset.0 + 1, 1))?;
|
transport::render(&mut state.transport, stdout, (offset.0 + 1, 1))?;
|
||||||
render::render_box(stdout, offset.0, 0, 64, 4,
|
render::render_box(stdout, Some("Transport"), offset.0, 0, 70, 4,
|
||||||
state.mode == Mode::Transport)?;
|
state.mode == Mode::Transport)?;
|
||||||
|
|
||||||
mixer::render(&mut state.mixer, stdout, (offset.0 + 1, 6))?;
|
mixer::render(&mut state.mixer, stdout, (offset.0 + 1, 6))?;
|
||||||
render::render_box(stdout, offset.0, 5, 64, 9,
|
render::render_box(stdout, Some("Mixer"), offset.0, 5, 70, 9,
|
||||||
state.mode == Mode::Mixer)?;
|
state.mode == Mode::Mixer)?;
|
||||||
|
|
||||||
looper::render(&mut state.looper, stdout, (offset.0 + 1, 16))?;
|
looper::render(&mut state.looper, stdout, (offset.0 + 1, 16))?;
|
||||||
render::render_box(stdout, offset.0, 15, 64, 6,
|
render::render_box(stdout, Some("Looper"), offset.0, 15, 70, 6,
|
||||||
state.mode == Mode::Looper)?;
|
state.mode == Mode::Looper)?;
|
||||||
|
|
||||||
//sampler::render(sampler, stdout, (1, 46))?;
|
sampler::render(&mut state.sampler, stdout, (offset.0 + 1, 20))?;
|
||||||
//sequencer::render(sequencer, stdout, (1, 66))?;
|
render::render_box(stdout, Some("Sampler"), offset.0, 22, 70, 4,
|
||||||
|
state.mode == Mode::Sampler)?;
|
||||||
|
|
||||||
|
sequencer::render(&mut state.sequencer, stdout, (offset.0 + 1, 25))?;
|
||||||
|
render::render_box(stdout, Some("Sequencer"), offset.0, 27, 70, 6,
|
||||||
|
state.mode == Mode::Sequencer)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
|state, event| {
|
|state, event| {
|
||||||
|
|
@ -122,11 +134,15 @@ fn run_all () -> Result<(), Box<dyn Error>> {
|
||||||
KeyCode::Tab => match state.mode {
|
KeyCode::Tab => match state.mode {
|
||||||
Mode::Transport => state.mode = Mode::Mixer,
|
Mode::Transport => state.mode = Mode::Mixer,
|
||||||
Mode::Mixer => state.mode = Mode::Looper,
|
Mode::Mixer => state.mode = Mode::Looper,
|
||||||
Mode::Looper => state.mode = Mode::Transport,
|
Mode::Looper => state.mode = Mode::Sampler,
|
||||||
|
Mode::Sampler => state.mode = Mode::Sequencer,
|
||||||
|
Mode::Sequencer => state.mode = Mode::Transport,
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
KeyCode::BackTab => match state.mode {
|
KeyCode::BackTab => match state.mode {
|
||||||
Mode::Transport => state.mode = Mode::Looper,
|
Mode::Transport => state.mode = Mode::Sequencer,
|
||||||
|
Mode::Sequencer => state.mode = Mode::Sampler,
|
||||||
|
Mode::Sampler => state.mode = Mode::Looper,
|
||||||
Mode::Looper => state.mode = Mode::Mixer,
|
Mode::Looper => state.mode = Mode::Mixer,
|
||||||
Mode::Mixer => state.mode = Mode::Transport,
|
Mode::Mixer => state.mode = Mode::Transport,
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
@ -141,7 +157,12 @@ fn run_all () -> Result<(), Box<dyn Error>> {
|
||||||
Mode::Looper => looper::handle(
|
Mode::Looper => looper::handle(
|
||||||
&mut state.looper, event
|
&mut state.looper, event
|
||||||
)?,
|
)?,
|
||||||
_ => {},
|
Mode::Sampler => sampler::handle(
|
||||||
|
&mut state.sampler, event
|
||||||
|
)?,
|
||||||
|
Mode::Sequencer => sequencer::handle(
|
||||||
|
&mut state.sequencer, event
|
||||||
|
)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -205,6 +226,7 @@ pub fn main_loop <T: Exitable> (
|
||||||
});
|
});
|
||||||
stdout.queue(Clear(ClearType::All))?.queue(Hide)?.flush()?;
|
stdout.queue(Clear(ClearType::All))?.queue(Hide)?.flush()?;
|
||||||
loop {
|
loop {
|
||||||
|
stdout.queue(Clear(ClearType::All))?;
|
||||||
render(state, &mut stdout, (0, 0))?;
|
render(state, &mut stdout, (0, 0))?;
|
||||||
stdout.flush()?;
|
stdout.flush()?;
|
||||||
handle(state, &input.recv()?)?;
|
handle(state, &input.recv()?)?;
|
||||||
|
|
|
||||||
|
|
@ -22,28 +22,39 @@ pub fn render_toolbar_vertical (
|
||||||
|
|
||||||
pub fn render_box (
|
pub fn render_box (
|
||||||
stdout: &mut std::io::Stdout,
|
stdout: &mut std::io::Stdout,
|
||||||
|
title: Option<&str>,
|
||||||
x: u16,
|
x: u16,
|
||||||
y: u16,
|
y: u16,
|
||||||
w: u16,
|
mut w: u16,
|
||||||
h: u16,
|
h: u16,
|
||||||
active: bool
|
active: bool
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let edge: String = std::iter::repeat("─").take(w.saturating_sub(2) as usize).collect();
|
if let Some(title) = title {
|
||||||
|
w = u16::max(w, title.len() as u16 + 4);
|
||||||
|
}
|
||||||
let back: String = std::iter::repeat(" ").take(w.saturating_sub(2) as usize).collect();
|
let back: String = std::iter::repeat(" ").take(w.saturating_sub(2) as usize).collect();
|
||||||
if active {
|
if active {
|
||||||
stdout.queue(MoveTo(x, y))?.queue(PrintStyledContent(format!("┌{edge}┐").bold().yellow()))?;
|
let edge: String = std::iter::repeat("━").take(w.saturating_sub(2) as usize).collect();
|
||||||
for row in y+1..y+h {
|
stdout.queue(MoveTo(x, y))?.queue(PrintStyledContent(format!("┏{edge}┓").bold().yellow()))?;
|
||||||
stdout.queue(MoveTo(x, row))?.queue(PrintStyledContent("│".bold().yellow()))?;
|
if let Some(title) = title {
|
||||||
stdout.queue(MoveTo(x+w-1, row))?.queue(PrintStyledContent("│".bold().yellow()))?;
|
stdout.queue(MoveTo(x+1, y))?.queue(PrintStyledContent(format!(" {title} ").bold().yellow()))?;
|
||||||
}
|
}
|
||||||
stdout.queue(MoveTo(x, y+h))?.queue(PrintStyledContent(format!("└{edge}┘").bold().yellow()))?;
|
for row in y+1..y+h {
|
||||||
|
stdout.queue(MoveTo(x, row))?.queue(PrintStyledContent("┃".bold().yellow()))?;
|
||||||
|
stdout.queue(MoveTo(x+w-1, row))?.queue(PrintStyledContent("┃".bold().yellow()))?;
|
||||||
|
}
|
||||||
|
stdout.queue(MoveTo(x, y+h))?.queue(PrintStyledContent(format!("┗{edge}┛").bold().yellow()))?;
|
||||||
} else {
|
} else {
|
||||||
stdout.queue(MoveTo(x, y))?.queue(Print(&format!("┌{edge}┐")))?;
|
let edge: String = std::iter::repeat("─").take(w.saturating_sub(2) as usize).collect();
|
||||||
for row in y+1..y+h {
|
stdout.queue(MoveTo(x, y))?.queue(PrintStyledContent(format!("┌{edge}┐").grey().dim()))?;
|
||||||
stdout.queue(MoveTo(x, row))?.queue(Print("│"))?;
|
if let Some(title) = title {
|
||||||
stdout.queue(MoveTo(x+w-1, row))?.queue(Print("│"))?;
|
stdout.queue(MoveTo(x+1, y))?.queue(Print(format!(" {title} ")))?;
|
||||||
}
|
}
|
||||||
stdout.queue(MoveTo(x, y+h))?.queue(Print(&format!("└{edge}┘")))?;
|
for row in y+1..y+h {
|
||||||
|
stdout.queue(MoveTo(x, row))?.queue(PrintStyledContent("│".grey().dim()))?;
|
||||||
|
stdout.queue(MoveTo(x+w-1, row))?.queue(PrintStyledContent("│".grey().dim()))?;
|
||||||
|
}
|
||||||
|
stdout.queue(MoveTo(x, y+h))?.queue(PrintStyledContent(format!("└{edge}┘").grey().dim()))?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,10 @@ pub use self::jack::*;
|
||||||
pub use self::render::*;
|
pub use self::render::*;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub const ACTIONS: [(&'static str, &'static str);0] = [];
|
pub const ACTIONS: [(&'static str, &'static str);2] = [
|
||||||
|
("Enter", "Play sample"),
|
||||||
|
("Ins/Del", "Add/remove sample"),
|
||||||
|
];
|
||||||
|
|
||||||
pub struct Sampler {
|
pub struct Sampler {
|
||||||
exited: bool,
|
exited: bool,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use super::Sampler;
|
||||||
|
|
||||||
pub fn handle (
|
pub fn handle (
|
||||||
state: &mut Sampler,
|
state: &mut Sampler,
|
||||||
event: crossterm::event::Event
|
event: &Event
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
use crossterm::event::{Event, KeyCode, KeyModifiers};
|
use crossterm::event::{Event, KeyCode, KeyModifiers};
|
||||||
if let Event::Key(event) = event {
|
if let Event::Key(event) = event {
|
||||||
|
|
|
||||||
|
|
@ -6,45 +6,21 @@ pub fn render (
|
||||||
stdout: &mut Stdout,
|
stdout: &mut Stdout,
|
||||||
offset: (u16, u16),
|
offset: (u16, u16),
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
render_toolbar(state, stdout, offset)?;
|
|
||||||
render_table(state, stdout, offset)?;
|
render_table(state, stdout, offset)?;
|
||||||
render_meters(state, stdout, offset)?;
|
render_meters(state, stdout, offset)?;
|
||||||
stdout.flush()?;
|
stdout.flush()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_toolbar (
|
|
||||||
state: &mut Sampler,
|
|
||||||
stdout: &mut Stdout,
|
|
||||||
offset: (u16, u16),
|
|
||||||
) -> Result<(), Box<dyn Error>> {
|
|
||||||
stdout
|
|
||||||
.queue(cursor::MoveTo(1, 0))?
|
|
||||||
.queue(PrintStyledContent("Arrows".yellow().bold()))?
|
|
||||||
.queue(cursor::MoveTo(1, 1))?
|
|
||||||
.queue(PrintStyledContent("Navigate".yellow()))?
|
|
||||||
|
|
||||||
.queue(cursor::MoveTo(11, 0))?
|
|
||||||
.queue(PrintStyledContent("Enter".yellow().bold()))?
|
|
||||||
.queue(cursor::MoveTo(11, 1))?
|
|
||||||
.queue(PrintStyledContent("Play sample".yellow()))?
|
|
||||||
|
|
||||||
.queue(cursor::MoveTo(24, 0))?
|
|
||||||
.queue(PrintStyledContent("Ins/Del".yellow().bold()))?
|
|
||||||
.queue(cursor::MoveTo(24, 1))?
|
|
||||||
.queue(PrintStyledContent("Add/remove sample".yellow()))?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_table (
|
fn render_table (
|
||||||
state: &mut Sampler,
|
state: &mut Sampler,
|
||||||
stdout: &mut Stdout,
|
stdout: &mut Stdout,
|
||||||
offset: (u16, u16),
|
offset: (u16, u16),
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
stdout
|
let move_to = |col, row| crossterm::cursor::MoveTo(offset.0 + col, offset.1 + row);
|
||||||
.queue(cursor::MoveTo(0, 3))?
|
stdout.queue(move_to(0, 3))?.queue(
|
||||||
.queue(Print(
|
Print(" Name Rate Trigger Route")
|
||||||
" Name Rate Trigger Route"))?;
|
)?;
|
||||||
for (i, sample) in state.samples.iter().enumerate() {
|
for (i, sample) in state.samples.iter().enumerate() {
|
||||||
let row = 4 + i as u16;
|
let row = 4 + i as u16;
|
||||||
for (j, (column, field)) in [
|
for (j, (column, field)) in [
|
||||||
|
|
@ -53,7 +29,7 @@ fn render_table (
|
||||||
(18, format!(" MIDI C10 36 ")),
|
(18, format!(" MIDI C10 36 ")),
|
||||||
(33, format!(" {:.1}dB -> Output ", sample.gain)),
|
(33, format!(" {:.1}dB -> Output ", sample.gain)),
|
||||||
].into_iter().enumerate() {
|
].into_iter().enumerate() {
|
||||||
stdout.queue(cursor::MoveTo(column, row))?;
|
stdout.queue(move_to(column, row))?;
|
||||||
if state.selected_sample == i && state.selected_column == j {
|
if state.selected_sample == i && state.selected_column == j {
|
||||||
stdout.queue(PrintStyledContent(field.to_string().bold().reverse()))?;
|
stdout.queue(PrintStyledContent(field.to_string().bold().reverse()))?;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -69,11 +45,12 @@ fn render_meters (
|
||||||
stdout: &mut Stdout,
|
stdout: &mut Stdout,
|
||||||
offset: (u16, u16),
|
offset: (u16, u16),
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
let move_to = |col, row| crossterm::cursor::MoveTo(offset.0 + col, offset.1 + row);
|
||||||
for (i, sample) in state.samples.iter().enumerate() {
|
for (i, sample) in state.samples.iter().enumerate() {
|
||||||
let row = 4 + i as u16;
|
let row = 4 + i as u16;
|
||||||
stdout
|
stdout.queue(move_to(32, row))?.queue(
|
||||||
.queue(cursor::MoveTo(32, row))?
|
PrintStyledContent("▁".green())
|
||||||
.queue(PrintStyledContent("▁".green()))?;
|
)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,18 @@ pub use self::jack::*;
|
||||||
pub use self::render::*;
|
pub use self::render::*;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub const ACTIONS: [(&'static str, &'static str);0] = [];
|
pub const ACTIONS: [(&'static str, &'static str);4] = [
|
||||||
|
("+/-", "Zoom"),
|
||||||
|
("A/D", "Add/delete note"),
|
||||||
|
("]/[", "Duration"),
|
||||||
|
("CapsLock", "Auto advance"),
|
||||||
|
];
|
||||||
|
|
||||||
pub struct Sequencer {
|
pub struct Sequencer {
|
||||||
exited: bool,
|
exited: bool,
|
||||||
jack: Jack<Notifications>,
|
jack: Jack<Notifications>,
|
||||||
cursor: (u16, u16),
|
cursor: (u16, u16, u16),
|
||||||
duration: u16,
|
sequence: Vec<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sequencer {
|
impl Sequencer {
|
||||||
|
|
@ -30,10 +35,10 @@ impl Sequencer {
|
||||||
)
|
)
|
||||||
)?;
|
)?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
exited: false,
|
exited: false,
|
||||||
cursor: (0, 0),
|
cursor: (0, 0, 0),
|
||||||
duration: 0,
|
|
||||||
jack,
|
jack,
|
||||||
|
sequence: vec![],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use super::Sequencer;
|
use super::Sequencer;
|
||||||
|
|
||||||
fn handle (
|
pub fn handle (state: &mut Sequencer,event: &Event) -> Result<(), Box<dyn Error>> {
|
||||||
state: &mut Sequencer,
|
|
||||||
event: crossterm::event::Event
|
|
||||||
) -> Result<(), Box<dyn Error>> {
|
|
||||||
use crossterm::event::{Event, KeyCode, KeyModifiers};
|
|
||||||
if let Event::Key(event) = event {
|
if let Event::Key(event) = event {
|
||||||
|
|
||||||
match event.code {
|
match event.code {
|
||||||
KeyCode::Char('c') => {
|
KeyCode::Char('c') => {
|
||||||
if event.modifiers == KeyModifiers::CONTROL {
|
if event.modifiers == KeyModifiers::CONTROL {
|
||||||
|
|
@ -14,12 +12,12 @@ fn handle (
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
KeyCode::Char('[') => {
|
KeyCode::Char('[') => {
|
||||||
if state.duration > 0 {
|
if state.cursor.2 > 0 {
|
||||||
state.duration = state.duration - 1
|
state.cursor.2 = state.cursor.2 - 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
KeyCode::Char(']') => {
|
KeyCode::Char(']') => {
|
||||||
state.duration = state.duration + 1
|
state.cursor.2 = state.cursor.2 + 1
|
||||||
},
|
},
|
||||||
KeyCode::Down => {
|
KeyCode::Down => {
|
||||||
state.cursor.1 = if state.cursor.1 >= 3 {
|
state.cursor.1 = if state.cursor.1 >= 3 {
|
||||||
|
|
@ -49,10 +47,13 @@ fn handle (
|
||||||
state.cursor.0 + 1
|
state.cursor.0 + 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
KeyCode::Char('A') => {
|
||||||
|
},
|
||||||
_ => {
|
_ => {
|
||||||
println!("{event:?}");
|
println!("{event:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,68 +6,36 @@ pub fn render (
|
||||||
stdout: &mut Stdout,
|
stdout: &mut Stdout,
|
||||||
offset: (u16, u16)
|
offset: (u16, u16)
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
render_toolbar(state, stdout, offset)?;
|
//render_toolbar(state, stdout, offset)?;
|
||||||
render_grid(state, stdout, offset)?;
|
render_grid(state, stdout, offset)?;
|
||||||
render_events(state, stdout, offset)?;
|
render_events(state, stdout, offset)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_toolbar (
|
|
||||||
state: &mut Sequencer,
|
|
||||||
stdout: &mut Stdout,
|
|
||||||
offset: (u16, u16)
|
|
||||||
) -> Result<(), Box<dyn Error>> {
|
|
||||||
stdout
|
|
||||||
.queue(MoveTo(1, 0))?
|
|
||||||
.queue(PrintStyledContent("Arrows".yellow().bold()))?
|
|
||||||
.queue(MoveTo(1, 1))?
|
|
||||||
.queue(PrintStyledContent("Navigate".yellow()))?
|
|
||||||
|
|
||||||
.queue(MoveTo(12, 0))?
|
|
||||||
.queue(PrintStyledContent("+/-".yellow().bold()))?
|
|
||||||
.queue(MoveTo(12, 1))?
|
|
||||||
.queue(PrintStyledContent("Zoom".yellow()))?
|
|
||||||
|
|
||||||
.queue(MoveTo(20, 0))?
|
|
||||||
.queue(PrintStyledContent("a/d".yellow().bold()))?
|
|
||||||
.queue(MoveTo(20, 1))?
|
|
||||||
.queue(PrintStyledContent("Add/delete".yellow()))?
|
|
||||||
|
|
||||||
.queue(MoveTo(33, 0))?
|
|
||||||
.queue(PrintStyledContent("[/]".yellow().bold()))?
|
|
||||||
.queue(MoveTo(33, 1))?
|
|
||||||
.queue(PrintStyledContent("Duration".yellow()))?
|
|
||||||
|
|
||||||
.queue(MoveTo(45, 0))?
|
|
||||||
.queue(PrintStyledContent("CapsLock".yellow().bold()))?
|
|
||||||
.queue(MoveTo(45, 1))?
|
|
||||||
.queue(PrintStyledContent("Auto advance".yellow()))?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_grid (
|
fn render_grid (
|
||||||
state: &mut Sequencer,
|
state: &mut Sequencer,
|
||||||
stdout: &mut Stdout,
|
stdout: &mut Stdout,
|
||||||
offset: (u16, u16)
|
offset: (u16, u16)
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
let move_to = |col, row| crossterm::cursor::MoveTo(offset.0 + col, offset.1 + row);
|
||||||
let bg = "┊···············┊···············┊···············┊···············";
|
let bg = "┊···············┊···············┊···············┊···············";
|
||||||
let cursor: String = if state.duration == 0 {
|
let cursor: String = if state.cursor.2 == 0 {
|
||||||
"X".into()
|
"X".into()
|
||||||
} else {
|
} else {
|
||||||
std::iter::repeat("·")
|
std::iter::repeat("·")
|
||||||
.take(state.duration as usize)
|
.take(state.cursor.2 as usize)
|
||||||
.collect()
|
.collect()
|
||||||
};
|
};
|
||||||
stdout
|
stdout
|
||||||
.queue(MoveTo(1, 3))?.queue(Print("1.1"))?
|
.queue(move_to(1, 3))?.queue(Print("1.1"))?
|
||||||
.queue(MoveTo(17, 3))?.queue(Print("1.2"))?
|
.queue(move_to(17, 3))?.queue(Print("1.2"))?
|
||||||
.queue(MoveTo(33, 3))?.queue(Print("1.3"))?
|
.queue(move_to(33, 3))?.queue(Print("1.3"))?
|
||||||
.queue(MoveTo(49, 3))?.queue(Print("1.4"))?
|
.queue(move_to(49, 3))?.queue(Print("1.4"))?
|
||||||
.queue(MoveTo(1, 4))?.queue(PrintStyledContent(bg.grey()))?
|
.queue(move_to(1, 4))?.queue(PrintStyledContent(bg.grey()))?
|
||||||
.queue(MoveTo(1, 5))?.queue(PrintStyledContent(bg.grey()))?
|
.queue(move_to(1, 5))?.queue(PrintStyledContent(bg.grey()))?
|
||||||
.queue(MoveTo(1, 6))?.queue(PrintStyledContent(bg.grey()))?
|
.queue(move_to(1, 6))?.queue(PrintStyledContent(bg.grey()))?
|
||||||
.queue(MoveTo(1, 7))?.queue(PrintStyledContent(bg.grey()))?
|
.queue(move_to(1, 7))?.queue(PrintStyledContent(bg.grey()))?
|
||||||
.queue(MoveTo(1 + state.cursor.0, 4 + state.cursor.1))?
|
.queue(move_to(1 + state.cursor.0, 4 + state.cursor.1))?
|
||||||
.queue(PrintStyledContent(cursor.reverse()))?;
|
.queue(PrintStyledContent(cursor.reverse()))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue