From 59f09dcd3a025641ba6898e2fa796dd8149fdfeb Mon Sep 17 00:00:00 2001 From: Pihkaal Date: Sun, 21 Jan 2024 00:45:20 +0100 Subject: [PATCH] feat: add chronometer mode --- src/main.rs | 78 ++++++++++++++++++++++++++++++++++---------------- src/symbols.rs | 39 +++++++++++++------------ 2 files changed, 75 insertions(+), 42 deletions(-) diff --git a/src/main.rs b/src/main.rs index 4749298..3d8a226 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,11 +4,11 @@ use std::{ path::PathBuf, sync::atomic::Ordering, thread, - time::Duration, + time::{self, Duration}, }; use atomic_enum::atomic_enum; -use chrono::Local; +use chrono; use clap::{Parser, Subcommand}; use config::{write_default_config, Config}; use crossterm::{ @@ -46,6 +46,7 @@ struct Cli { #[derive(Subcommand, Debug)] enum Commands { Debug {}, + Chrono {}, } #[atomic_enum] @@ -53,6 +54,7 @@ enum Commands { pub enum AppMode { Clock = 0, Debug, + Chrono, } static APP_MODE: AtomicAppMode = AtomicAppMode::new(AppMode::Debug); @@ -72,7 +74,8 @@ fn main() -> io::Result<()> { Some(Commands::Debug {}) => { set_app_mode(AppMode::Debug); } - _ => {} + Some(Commands::Chrono {}) => set_app_mode(AppMode::Chrono), + _ => set_app_mode(AppMode::Clock), } // Load config @@ -118,8 +121,8 @@ fn main() -> io::Result<()> { let mut config = config::load_from_file(config_file); let mut stdout = io::stdout(); - match &cli.command { - Some(Commands::Debug {}) => { + match get_app_mode() { + AppMode::Debug => { print_debug_infos(&mut config)?; return Ok(()); } @@ -130,6 +133,8 @@ fn main() -> io::Result<()> { execute!(stdout, terminal::EnterAlternateScreen, cursor::Hide)?; let _ = terminal::enable_raw_mode()?; + let start_time = time::Instant::now(); + // Main loop let mut quit = false; while !quit { @@ -153,7 +158,11 @@ fn main() -> io::Result<()> { queue!(stdout, terminal::Clear(ClearType::All))?; // Render - render_frame(&config)?; + match get_app_mode() { + AppMode::Clock => render_clock(&config)?, + AppMode::Chrono => render_chrono(&config, &start_time)?, + AppMode::Debug => unreachable!(), + }; config.color.update(); @@ -174,31 +183,36 @@ fn main() -> io::Result<()> { return Ok(()); } -fn render_frame(config: &Config) -> io::Result<()> { - let (width, height) = terminal::size()?; +fn render_clock(config: &Config) -> io::Result<()> { + let color = config.color.get_value(); - let date_time = Local::now(); + let date_time = chrono::Local::now(); // Display time let time = date_time.time().format(&config.time_format).to_string(); - - let text_width = draw_time_width(&time); - let text_height = 5; - let color = config.color.get_value(); - - let x = width / 2 - text_width / 2; - let y = height / 2 - text_height / 2; - draw_time(&time, x, y, color)?; + draw_time(&time, color)?; // Display date let date = date_time .date_naive() .format(&config.date_format.to_owned()) .to_string(); + draw_date(&date, color)?; - let x = width / 2 - (date.len() as u16) / 2; - let y = height / 2 + text_height / 2 + 2; - draw_date(&date, x, y, color)?; + return Ok(()); +} + +fn render_chrono(config: &Config, start_time: &time::Instant) -> io::Result<()> { + let color = config.color.get_value(); + + // Display time + let seconds = start_time.elapsed().as_secs(); + 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)?; return Ok(()); } @@ -210,14 +224,25 @@ fn draw_time_width(time: &str) -> u16 { let mut w = 0; for c in time.chars() { - w += if c == ':' { 6 } else { 7 }; + w += if c == ':' { + symbols::SYMBOL_HEIGHT + } else { + symbols::SYMBOL_WIDTH + 1 + }; } w -= if time.len() == 1 { 1 } else { 2 }; - return w; + return w.try_into().unwrap(); } -fn draw_time(time: &str, mut x: u16, y: u16, color: Color) -> io::Result<()> { +fn draw_time(time: &str, color: Color) -> io::Result<()> { + let (width, height) = terminal::size()?; + + let text_width = draw_time_width(&time); + let text_height = 5; + + let mut x = width / 2 - text_width / 2; + let y = height / 2 - text_height / 2; for c in time.chars() { if c == ':' { x -= 1; @@ -260,9 +285,14 @@ fn draw_time_symbol(symbol: char, x: u16, y: u16, color: Color) -> io::Result<() return Ok(()); } -fn draw_date(date: &str, x: u16, y: u16, color: Color) -> io::Result<()> { +fn draw_date(date: &str, color: Color) -> io::Result<()> { 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!( stdout, cursor::MoveTo(x, y), diff --git a/src/symbols.rs b/src/symbols.rs index 6f5c013..a14b8a7 100644 --- a/src/symbols.rs +++ b/src/symbols.rs @@ -1,4 +1,7 @@ -pub fn symbol_to_render_data(ch: char) -> [[bool; 6]; 5] { +pub const SYMBOL_WIDTH: usize = 6; +pub const SYMBOL_HEIGHT: usize = 5; + +pub fn symbol_to_render_data(ch: char) -> [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] { match ch { '1' => ONE, '2' => TWO, @@ -23,7 +26,7 @@ pub fn symbol_to_render_data(ch: char) -> [[bool; 6]; 5] { const O: bool = false; const X: bool = true; -const ONE: [[bool; 6]; 5] = [ +const ONE: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [O, O, O, O, X, X], [O, O, O, O, X, X], [O, O, O, O, X, X], @@ -31,7 +34,7 @@ const ONE: [[bool; 6]; 5] = [ [O, O, O, O, X, X], ]; -const TWO: [[bool; 6]; 5] = [ +const TWO: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [X, X, X, X, X, X], [O, O, O, O, X, X], [X, X, X, X, X, X], @@ -39,7 +42,7 @@ const TWO: [[bool; 6]; 5] = [ [X, X, X, X, X, X], ]; -const THREE: [[bool; 6]; 5] = [ +const THREE: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [X, X, X, X, X, X], [O, O, O, O, X, X], [X, X, X, X, X, X], @@ -47,7 +50,7 @@ const THREE: [[bool; 6]; 5] = [ [X, X, X, X, X, X], ]; -const FOUR: [[bool; 6]; 5] = [ +const FOUR: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [X, X, O, O, X, X], [X, X, O, O, X, X], [X, X, X, X, X, X], @@ -55,7 +58,7 @@ const FOUR: [[bool; 6]; 5] = [ [O, O, O, O, X, X], ]; -const FIVE: [[bool; 6]; 5] = [ +const FIVE: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [X, X, X, X, X, X], [X, X, O, O, O, O], [X, X, X, X, X, X], @@ -63,7 +66,7 @@ const FIVE: [[bool; 6]; 5] = [ [X, X, X, X, X, X], ]; -const SIX: [[bool; 6]; 5] = [ +const SIX: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [X, X, X, X, X, X], [X, X, O, O, O, O], [X, X, X, X, X, X], @@ -71,7 +74,7 @@ const SIX: [[bool; 6]; 5] = [ [X, X, X, X, X, X], ]; -const SEVEN: [[bool; 6]; 5] = [ +const SEVEN: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [X, X, X, X, X, X], [O, O, O, O, X, X], [O, O, O, O, X, X], @@ -79,7 +82,7 @@ const SEVEN: [[bool; 6]; 5] = [ [O, O, O, O, X, X], ]; -const EIGHT: [[bool; 6]; 5] = [ +const EIGHT: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [X, X, X, X, X, X], [X, X, O, O, X, X], [X, X, X, X, X, X], @@ -87,7 +90,7 @@ const EIGHT: [[bool; 6]; 5] = [ [X, X, X, X, X, X], ]; -const NINE: [[bool; 6]; 5] = [ +const NINE: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [X, X, X, X, X, X], [X, X, O, O, X, X], [X, X, X, X, X, X], @@ -95,7 +98,7 @@ const NINE: [[bool; 6]; 5] = [ [X, X, X, X, X, X], ]; -const ZERO: [[bool; 6]; 5] = [ +const ZERO: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [X, X, X, X, X, X], [X, X, O, O, X, X], [X, X, O, O, X, X], @@ -103,7 +106,7 @@ const ZERO: [[bool; 6]; 5] = [ [X, X, X, X, X, X], ]; -const DIV: [[bool; 6]; 5] = [ +const DIV: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [O, O, O, O, O, O], [O, O, X, X, O, O], [O, O, O, O, O, O], @@ -111,7 +114,7 @@ const DIV: [[bool; 6]; 5] = [ [O, O, O, O, O, O], ]; -const DASH: [[bool; 6]; 5] = [ +const DASH: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [O, O, O, O, O, O], [O, O, O, O, O, O], [O, X, X, X, X, O], @@ -119,7 +122,7 @@ const DASH: [[bool; 6]; 5] = [ [O, O, O, O, O, O], ]; -const ERR: [[bool; 6]; 5] = [ +const ERR: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [X, X, O, O, X, X], [O, X, X, X, X, O], [O, O, X, X, O, O], @@ -127,7 +130,7 @@ const ERR: [[bool; 6]; 5] = [ [X, X, O, O, X, X], ]; -const SPACE: [[bool; 6]; 5] = [ +const SPACE: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [O, O, O, O, O, O], [O, O, O, O, O, O], [O, O, O, O, O, O], @@ -135,7 +138,7 @@ const SPACE: [[bool; 6]; 5] = [ [O, O, O, O, O, O], ]; -const A: [[bool; 6]; 5] = [ +const A: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [X, X, X, X, X, X], [X, X, O, O, X, X], [X, X, X, X, X, X], @@ -143,7 +146,7 @@ const A: [[bool; 6]; 5] = [ [X, X, O, O, X, X], ]; -const P: [[bool; 6]; 5] = [ +const P: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [X, X, X, X, X, X], [X, X, O, O, X, X], [X, X, X, X, X, X], @@ -151,7 +154,7 @@ const P: [[bool; 6]; 5] = [ [X, X, O, O, O, O], ]; -const M: [[bool; 6]; 5] = [ +const M: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [ [X, X, X, X, X, X], [X, X, O, X, O, X], [X, X, O, X, O, X],