feat(chrono): implement lapses

This commit is contained in:
Pihkaal
2024-01-21 01:41:53 +01:00
parent 16a73291c1
commit a2a6697afd

View File

@@ -1,5 +1,6 @@
use core::panic; use core::panic;
use std::{ use std::{
cmp::min,
io::{self, Write}, io::{self, Write},
path::PathBuf, path::PathBuf,
sync::atomic::Ordering, sync::atomic::Ordering,
@@ -67,6 +68,11 @@ pub fn set_app_mode(mode: AppMode) {
return APP_MODE.store(mode, Ordering::Relaxed); return APP_MODE.store(mode, Ordering::Relaxed);
} }
struct Lapse {
pub time: time::Duration,
pub delta: time::Duration,
}
fn main() -> io::Result<()> { fn main() -> io::Result<()> {
let cli = Cli::parse(); let cli = Cli::parse();
@@ -133,7 +139,9 @@ fn main() -> io::Result<()> {
execute!(stdout, terminal::EnterAlternateScreen, cursor::Hide)?; execute!(stdout, terminal::EnterAlternateScreen, cursor::Hide)?;
let _ = terminal::enable_raw_mode()?; let _ = terminal::enable_raw_mode()?;
// For the chronometer
let start_time = time::Instant::now(); let start_time = time::Instant::now();
let mut lapses: Vec<Lapse> = vec![];
// Main loop // Main loop
let mut quit = false; let mut quit = false;
@@ -142,12 +150,25 @@ fn main() -> io::Result<()> {
while event::poll(Duration::ZERO)? { while event::poll(Duration::ZERO)? {
match event::read()? { match event::read()? {
Event::Key(e) => match e.code { Event::Key(e) => match e.code {
KeyCode::Char(x) => { // Handle CTRL-C
// Handle CTRL-C KeyCode::Char('c') => {
if x == 'c' && e.modifiers.contains(KeyModifiers::CONTROL) { if e.modifiers.contains(KeyModifiers::CONTROL) {
quit = true; quit = true;
} }
} }
// Handle lapse
KeyCode::Char(' ') => {
if get_app_mode() == AppMode::Chrono {
let time = start_time.elapsed();
let delta = if let Some(last_lap) = lapses.last() {
time::Duration::from_secs(time.as_secs() - last_lap.time.as_secs())
} else {
time
};
lapses.push(Lapse { time, delta });
}
}
_ => {} _ => {}
}, },
_ => {} _ => {}
@@ -160,7 +181,7 @@ fn main() -> io::Result<()> {
// Render // Render
match get_app_mode() { match get_app_mode() {
AppMode::Clock => render_clock(&config)?, AppMode::Clock => render_clock(&config)?,
AppMode::Chrono => render_chrono(&config, &start_time)?, AppMode::Chrono => render_chrono(&config, start_time, &lapses)?,
AppMode::Debug => unreachable!(), AppMode::Debug => unreachable!(),
}; };
@@ -175,10 +196,6 @@ fn main() -> io::Result<()> {
let _ = terminal::disable_raw_mode().unwrap(); let _ = terminal::disable_raw_mode().unwrap();
execute!(stdout, terminal::LeaveAlternateScreen, cursor::Show)?; execute!(stdout, terminal::LeaveAlternateScreen, cursor::Show)?;
if get_app_mode() == AppMode::Chrono {
println!("Elapsed time: {:?}", start_time.elapsed());
}
// Be polite // Be polite
if config.be_polite { if config.be_polite {
println!("CTRL-C pressed, bye!\n"); println!("CTRL-C pressed, bye!\n");
@@ -201,23 +218,40 @@ fn render_clock(config: &Config) -> io::Result<()> {
.date_naive() .date_naive()
.format(&config.date_format.to_owned()) .format(&config.date_format.to_owned())
.to_string(); .to_string();
draw_date(&date, color)?;
let (width, height) = terminal::size()?;
let x = width / 2 - (date.len() as u16) / 2;
let y = height / 2 + symbols::SYMBOL_HEIGHT as u16 / 2 + 2;
draw_text(&date, x, y, color)?;
return Ok(()); return Ok(());
} }
fn render_chrono(config: &Config, start_time: &time::Instant) -> io::Result<()> { fn render_chrono(
config: &Config,
start_time: time::Instant,
lapses: &Vec<Lapse>,
) -> io::Result<()> {
let color = config.color.get_value(); let color = config.color.get_value();
// Display time // Display time
let seconds = start_time.elapsed().as_secs(); let elapsed = format_duration(start_time.elapsed());
let hours = seconds / 3600;
let minutes = (seconds % 3600) / 60;
let seconds = seconds % 60;
let elapsed = format!("{:02}:{:02}:{:02}", hours, minutes, seconds);
draw_time(&elapsed, color)?; draw_time(&elapsed, color)?;
// Display lapses
let (width, height) = terminal::size()?;
let y = height / 2 + symbols::SYMBOL_HEIGHT as u16 / 2 + 2;
let max_items = min(10, height - y) as usize;
for (i, lapse) in lapses.iter().rev().take(max_items).enumerate() {
let delta = format_duration(lapse.delta);
let time = format_duration(lapse.time);
let lapse = format!("#0{} -- +{} -- {}", lapses.len() - i, delta, time);
let x = width / 2 - (lapse.len() as u16) / 2;
draw_text(&lapse, x, y + i as u16, color)?;
}
return Ok(()); return Ok(());
} }
@@ -289,21 +323,25 @@ fn draw_time_symbol(symbol: char, x: u16, y: u16, color: Color) -> io::Result<()
return Ok(()); return Ok(());
} }
fn draw_date(date: &str, color: Color) -> io::Result<()> { fn draw_text(string: &str, x: u16, y: u16, color: Color) -> io::Result<()> {
let mut stdout = io::stdout(); let mut stdout = io::stdout();
let (width, height) = terminal::size()?;
let x = width / 2 - (date.len() as u16) / 2;
let y = height / 2 + symbols::SYMBOL_HEIGHT as u16 / 2 + 2;
queue!( queue!(
stdout, stdout,
cursor::MoveTo(x, y), cursor::MoveTo(x, y),
style::SetForegroundColor(color), style::SetForegroundColor(color),
style::SetAttribute(Attribute::Bold) style::SetAttribute(Attribute::Bold)
)?; )?;
write!(stdout, "{}", date)?; write!(stdout, "{}", string)?;
return Ok(()); return Ok(());
} }
fn format_duration(duration: time::Duration) -> String {
let seconds = duration.as_secs();
let hours = seconds / 3600;
let minutes = (seconds % 3600) / 60;
let seconds = seconds % 60;
return format!("{:02}:{:02}:{:02}", hours, minutes, seconds);
}