Static header, log below it, status at bottom
This commit is contained in:
parent
da3f0b406b
commit
d1bc44a6ca
1 changed files with 60 additions and 26 deletions
86
src/main.rs
86
src/main.rs
|
@ -1,6 +1,6 @@
|
|||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
use std::fs::File;
|
||||
use std::io::stdout;
|
||||
use std::io::{stdout, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::exit;
|
||||
use std::sync::mpsc::{Receiver, Sender};
|
||||
|
@ -12,13 +12,13 @@ use clap::{Parser, Subcommand};
|
|||
use cpal::traits::{DeviceTrait, StreamTrait};
|
||||
use cpal::{self, traits::HostTrait};
|
||||
use cpal::{OutputCallbackInfo, StreamConfig};
|
||||
use crossterm::cursor::{Hide, MoveTo, MoveToColumn, MoveToNextLine, Show};
|
||||
use crossterm::cursor::{Hide, MoveTo, MoveToColumn, MoveToNextLine, MoveToRow, Show};
|
||||
use crossterm::event::{Event, KeyCode, KeyModifiers, MediaKeyCode};
|
||||
use crossterm::execute;
|
||||
use crossterm::style::{Print, PrintStyledContent, Stylize};
|
||||
use crossterm::terminal::{
|
||||
disable_raw_mode, enable_raw_mode, size, Clear, ClearType, EnterAlternateScreen, ScrollUp,
|
||||
disable_raw_mode, enable_raw_mode, size, Clear, ClearType, EnterAlternateScreen,
|
||||
};
|
||||
use crossterm::{execute, queue};
|
||||
use minimp3::Decoder;
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -204,8 +204,9 @@ fn annotate(mut path: Vec<PathBuf>, initial_buffer_size: usize) {
|
|||
let mut stdout = stdout();
|
||||
execute!(stdout, Hide, EnterAlternateScreen).unwrap();
|
||||
|
||||
let (mut _terminal_columns, terminal_rows) = size().unwrap();
|
||||
let terminal_rows = Arc::new(Cell::new(terminal_rows));
|
||||
let (terminal_columns, terminal_rows) = size().unwrap();
|
||||
let terminal_rows = Arc::new(FairMutex::new(terminal_rows));
|
||||
let terminal_columns = Arc::new(FairMutex::new(terminal_columns));
|
||||
|
||||
let (input_tx, input_rx): (Sender<Command>, Receiver<Command>) = mpsc::channel();
|
||||
|
||||
|
@ -257,6 +258,8 @@ fn annotate(mut path: Vec<PathBuf>, initial_buffer_size: usize) {
|
|||
let mp3_channels = Arc::clone(&mp3_channels);
|
||||
let pending_movement = Arc::clone(&pending_movement);
|
||||
let sample_rate = Arc::clone(&sample_rate);
|
||||
let terminal_columns = Arc::clone(&terminal_columns);
|
||||
let terminal_rows = Arc::clone(&terminal_rows);
|
||||
let playback_speed = Arc::clone(&playback_speed);
|
||||
device
|
||||
.build_output_stream(
|
||||
|
@ -317,6 +320,27 @@ fn annotate(mut path: Vec<PathBuf>, initial_buffer_size: usize) {
|
|||
}
|
||||
|
||||
*idx += *playback_speed.read().unwrap() * mp3_channels;
|
||||
|
||||
{
|
||||
let mut stdout = std::io::stdout().lock();
|
||||
|
||||
let status = format!(
|
||||
"{} / {} {:.1}%",
|
||||
*idx,
|
||||
buf.len(),
|
||||
100f64 * *idx as f64 / buf.len() as f64
|
||||
);
|
||||
let padding =
|
||||
" ".repeat(*terminal_columns.lock() as usize - status.len());
|
||||
|
||||
execute!(
|
||||
stdout,
|
||||
MoveTo(0, *terminal_rows.lock()),
|
||||
Print(status),
|
||||
Print(padding)
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
},
|
||||
|err| {
|
||||
|
@ -346,8 +370,7 @@ fn annotate(mut path: Vec<PathBuf>, initial_buffer_size: usize) {
|
|||
|
||||
execute!(
|
||||
stdout,
|
||||
MoveToNextLine(1),
|
||||
MoveToColumn(0),
|
||||
MoveTo(0, 2),
|
||||
Print("🔊"),
|
||||
Print(path.as_ref().unwrap().display())
|
||||
)
|
||||
|
@ -383,13 +406,7 @@ fn annotate(mut path: Vec<PathBuf>, initial_buffer_size: usize) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
execute!(
|
||||
stdout,
|
||||
MoveToNextLine(1),
|
||||
MoveToColumn(0),
|
||||
Print("\t🗃 Annotations Found")
|
||||
)
|
||||
.unwrap();
|
||||
execute!(stdout, MoveTo(0, 2), Print("\t🗃 Annotations Found")).unwrap();
|
||||
}
|
||||
} else {
|
||||
quit();
|
||||
|
@ -438,22 +455,39 @@ fn annotate(mut path: Vec<PathBuf>, initial_buffer_size: usize) {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
// The number of log lines we've written in total
|
||||
let mut log_line = 0usize;
|
||||
let mut log_lines: VecDeque<String> = VecDeque::with_capacity(*terminal_rows.lock() as usize);
|
||||
|
||||
// Add a line to the log area
|
||||
let mut log = {
|
||||
let terminal_columns = Arc::clone(&terminal_columns);
|
||||
let terminal_rows = Arc::clone(&terminal_rows);
|
||||
move |s: &str| {
|
||||
log_line += 1;
|
||||
log_lines.push_back(s.to_string());
|
||||
|
||||
if log_line > terminal_rows.get() as usize {
|
||||
execute!(stdout, ScrollUp(1)).unwrap();
|
||||
} else {
|
||||
execute!(stdout, MoveToNextLine(1)).unwrap();
|
||||
while log_lines.len() > *terminal_rows.lock() as usize - 10 {
|
||||
log_lines.pop_front().unwrap();
|
||||
}
|
||||
|
||||
execute!(stdout, MoveToColumn(0), Print(s)).unwrap();
|
||||
let mut stdout = stdout.lock();
|
||||
|
||||
queue!(stdout, MoveToRow(5)).unwrap();
|
||||
|
||||
for line in log_lines.iter() {
|
||||
let right_pad_len = *terminal_columns.lock() as usize - line.len();
|
||||
|
||||
let padding = " ".repeat(right_pad_len);
|
||||
|
||||
queue!(
|
||||
stdout,
|
||||
MoveToColumn(0),
|
||||
Print(line),
|
||||
Print(padding),
|
||||
MoveToNextLine(1)
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
stdout.flush().unwrap();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -552,8 +586,8 @@ fn annotate(mut path: Vec<PathBuf>, initial_buffer_size: usize) {
|
|||
quit();
|
||||
}
|
||||
Command::ResizeTerminal(columns, rows) => {
|
||||
_terminal_columns = columns;
|
||||
terminal_rows.set(rows);
|
||||
*terminal_columns.lock() = columns;
|
||||
*terminal_rows.lock() = rows;
|
||||
}
|
||||
Command::TogglePlaybackSpeed => {
|
||||
let next = match *playback_speed.read().unwrap() {
|
||||
|
|
Loading…
Reference in a new issue