Static header, log below it, status at bottom

This commit is contained in:
Josh Hansen 2023-07-21 16:58:45 -07:00
parent da3f0b406b
commit d1bc44a6ca

View file

@ -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() {