Initial commit
This commit is contained in:
105
src/main.rs
Normal file
105
src/main.rs
Normal file
@ -0,0 +1,105 @@
|
||||
use std::process::Command;
|
||||
use terminal_size::{Width, Height, terminal_size};
|
||||
use colored::{Color, Colorize};
|
||||
use std::io::{self, Write, stdout};
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
use structopt::StructOpt;
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt()]
|
||||
struct Opt {
|
||||
/// Set number of columns in terminal
|
||||
#[structopt(short, long)]
|
||||
cols: Option<u16>,
|
||||
|
||||
/// Set number of rows in column
|
||||
#[structopt(short, long)]
|
||||
rows: Option<u16>,
|
||||
|
||||
/// Set number of rows in column
|
||||
#[structopt(short, long)]
|
||||
timeout: Option<u64>,
|
||||
}
|
||||
|
||||
const COLORS: &[Color] = &[
|
||||
Color::Green,
|
||||
Color::Blue,
|
||||
Color::Yellow,
|
||||
Color::Red,
|
||||
];
|
||||
|
||||
const BLOCK_CHARS: &[char] = &[
|
||||
' ',
|
||||
'▁',
|
||||
'▂',
|
||||
'▃',
|
||||
'▄',
|
||||
'▅',
|
||||
'▆',
|
||||
'▇',
|
||||
'█',
|
||||
];
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let opt = Opt::from_args();
|
||||
|
||||
let (Width(calc_max_cols), Height(calc_max_rows)) = terminal_size().unwrap();
|
||||
let calc_max_rows = calc_max_rows.min(4);
|
||||
|
||||
let max_cols = opt.cols.unwrap_or(calc_max_cols);
|
||||
let max_rows = opt.rows.unwrap_or(calc_max_rows);
|
||||
|
||||
|
||||
let output = Command::new("pamixer")
|
||||
.args(&["--get-volume"])
|
||||
.output()?;
|
||||
|
||||
let out = std::str::from_utf8(&output.stdout)
|
||||
.expect("failed to parse paxmixer output as utf-8");
|
||||
|
||||
let volume: u16 = out.trim().parse().expect("failed to parse pamixer output as u16");
|
||||
let percentage = volume as f64 / 100.0;
|
||||
|
||||
let num_cols = ((max_cols as f64 * percentage) as u16).min(max_cols);
|
||||
let max_chars = max_cols / 2;
|
||||
let num_chars = num_cols / 2;
|
||||
|
||||
|
||||
let mut lines = vec![vec![]; max_rows as usize];
|
||||
|
||||
for i in 0..num_chars {
|
||||
let color = i * COLORS.len() as u16 / max_chars;
|
||||
let color = COLORS[color as usize];
|
||||
|
||||
let mut block_height = i * BLOCK_CHARS.len() as u16 * max_rows / max_chars;
|
||||
|
||||
for row in 0..max_rows {
|
||||
let bc = BLOCK_CHARS[block_height.min(BLOCK_CHARS.len() as u16 - 1) as usize];
|
||||
block_height = block_height.saturating_sub(BLOCK_CHARS.len() as u16);
|
||||
|
||||
lines[row as usize].push((bc, color));
|
||||
}
|
||||
}
|
||||
lines.reverse();
|
||||
|
||||
let stdout = stdout();
|
||||
let mut handle = stdout.lock();
|
||||
|
||||
let mut char_buf = [0u8; 4];
|
||||
for line in &lines {
|
||||
writeln!(&mut handle)?;
|
||||
for &(bc, color) in line {
|
||||
let bc = bc.encode_utf8(&mut char_buf);
|
||||
write!(&mut handle, " {}", bc.color(color))?;
|
||||
}
|
||||
}
|
||||
|
||||
handle.flush()?;
|
||||
|
||||
if let Some(millis) = opt.timeout {
|
||||
sleep(Duration::from_millis(millis));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user