feat: add chronometer mode

This commit is contained in:
Pihkaal
2024-01-21 00:45:20 +01:00
parent f5ae5df561
commit 59f09dcd3a
2 changed files with 75 additions and 42 deletions

View File

@@ -4,11 +4,11 @@ use std::{
path::PathBuf, path::PathBuf,
sync::atomic::Ordering, sync::atomic::Ordering,
thread, thread,
time::Duration, time::{self, Duration},
}; };
use atomic_enum::atomic_enum; use atomic_enum::atomic_enum;
use chrono::Local; use chrono;
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use config::{write_default_config, Config}; use config::{write_default_config, Config};
use crossterm::{ use crossterm::{
@@ -46,6 +46,7 @@ struct Cli {
#[derive(Subcommand, Debug)] #[derive(Subcommand, Debug)]
enum Commands { enum Commands {
Debug {}, Debug {},
Chrono {},
} }
#[atomic_enum] #[atomic_enum]
@@ -53,6 +54,7 @@ enum Commands {
pub enum AppMode { pub enum AppMode {
Clock = 0, Clock = 0,
Debug, Debug,
Chrono,
} }
static APP_MODE: AtomicAppMode = AtomicAppMode::new(AppMode::Debug); static APP_MODE: AtomicAppMode = AtomicAppMode::new(AppMode::Debug);
@@ -72,7 +74,8 @@ fn main() -> io::Result<()> {
Some(Commands::Debug {}) => { Some(Commands::Debug {}) => {
set_app_mode(AppMode::Debug); set_app_mode(AppMode::Debug);
} }
_ => {} Some(Commands::Chrono {}) => set_app_mode(AppMode::Chrono),
_ => set_app_mode(AppMode::Clock),
} }
// Load config // Load config
@@ -118,8 +121,8 @@ fn main() -> io::Result<()> {
let mut config = config::load_from_file(config_file); let mut config = config::load_from_file(config_file);
let mut stdout = io::stdout(); let mut stdout = io::stdout();
match &cli.command { match get_app_mode() {
Some(Commands::Debug {}) => { AppMode::Debug => {
print_debug_infos(&mut config)?; print_debug_infos(&mut config)?;
return Ok(()); return Ok(());
} }
@@ -130,6 +133,8 @@ 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()?;
let start_time = time::Instant::now();
// Main loop // Main loop
let mut quit = false; let mut quit = false;
while !quit { while !quit {
@@ -153,7 +158,11 @@ fn main() -> io::Result<()> {
queue!(stdout, terminal::Clear(ClearType::All))?; queue!(stdout, terminal::Clear(ClearType::All))?;
// Render // 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(); config.color.update();
@@ -174,31 +183,36 @@ fn main() -> io::Result<()> {
return Ok(()); return Ok(());
} }
fn render_frame(config: &Config) -> io::Result<()> { fn render_clock(config: &Config) -> io::Result<()> {
let (width, height) = terminal::size()?; let color = config.color.get_value();
let date_time = Local::now(); let date_time = chrono::Local::now();
// Display time // Display time
let time = date_time.time().format(&config.time_format).to_string(); let time = date_time.time().format(&config.time_format).to_string();
draw_time(&time, color)?;
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)?;
// Display date // Display date
let date = date_time let date = date_time
.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 x = width / 2 - (date.len() as u16) / 2; return Ok(());
let y = height / 2 + text_height / 2 + 2; }
draw_date(&date, x, y, color)?;
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(()); return Ok(());
} }
@@ -210,14 +224,25 @@ fn draw_time_width(time: &str) -> u16 {
let mut w = 0; let mut w = 0;
for c in time.chars() { 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 }; 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() { for c in time.chars() {
if c == ':' { if c == ':' {
x -= 1; x -= 1;
@@ -260,9 +285,14 @@ fn draw_time_symbol(symbol: char, x: u16, y: u16, color: Color) -> io::Result<()
return Ok(()); 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 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),

View File

@@ -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 { match ch {
'1' => ONE, '1' => ONE,
'2' => TWO, '2' => TWO,
@@ -23,7 +26,7 @@ pub fn symbol_to_render_data(ch: char) -> [[bool; 6]; 5] {
const O: bool = false; const O: bool = false;
const X: bool = true; 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], [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], [O, O, O, O, X, X],
]; ];
const TWO: [[bool; 6]; 5] = [ const TWO: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [
[X, X, X, X, X, X], [X, X, X, X, X, X],
[O, O, O, O, X, X], [O, O, O, O, X, X],
[X, X, X, X, X, X], [X, X, X, X, X, X],
@@ -39,7 +42,7 @@ const TWO: [[bool; 6]; 5] = [
[X, X, X, X, X, X], [X, X, X, X, X, X],
]; ];
const THREE: [[bool; 6]; 5] = [ const THREE: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [
[X, X, X, X, X, X], [X, X, X, X, X, X],
[O, O, O, O, X, X], [O, O, O, O, X, X],
[X, X, X, X, X, X], [X, X, X, X, X, X],
@@ -47,7 +50,7 @@ const THREE: [[bool; 6]; 5] = [
[X, X, X, X, X, X], [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, O, O, X, X], [X, X, O, O, X, X],
[X, X, X, X, X, X], [X, X, X, X, X, X],
@@ -55,7 +58,7 @@ const FOUR: [[bool; 6]; 5] = [
[O, O, O, O, X, X], [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, X, X, X, X],
[X, X, O, O, O, O], [X, X, O, O, O, O],
[X, X, X, X, X, X], [X, X, X, X, X, X],
@@ -63,7 +66,7 @@ const FIVE: [[bool; 6]; 5] = [
[X, X, X, X, X, X], [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, X, X, X, X],
[X, X, O, O, O, O], [X, X, O, O, O, O],
[X, X, X, X, X, X], [X, X, X, X, X, X],
@@ -71,7 +74,7 @@ const SIX: [[bool; 6]; 5] = [
[X, X, X, X, X, X], [X, X, X, X, X, X],
]; ];
const SEVEN: [[bool; 6]; 5] = [ const SEVEN: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [
[X, X, X, X, X, X], [X, X, X, X, X, X],
[O, O, O, O, X, X], [O, O, O, O, 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], [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, X, X, X, X],
[X, X, O, O, X, X], [X, X, O, O, X, X],
[X, X, X, X, X, X], [X, X, X, X, X, X],
@@ -87,7 +90,7 @@ const EIGHT: [[bool; 6]; 5] = [
[X, X, X, X, X, X], [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, X, X, X, X],
[X, X, O, O, X, X], [X, X, O, O, X, X],
[X, X, X, X, X, X], [X, X, X, X, X, X],
@@ -95,7 +98,7 @@ const NINE: [[bool; 6]; 5] = [
[X, X, X, X, X, X], [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, X, X, X, X],
[X, X, O, O, X, X], [X, X, O, O, 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], [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, O, O, O, O],
[O, O, X, X, O, O], [O, O, X, X, O, O],
[O, O, O, O, O, O], [O, O, O, O, O, O],
@@ -111,7 +114,7 @@ const DIV: [[bool; 6]; 5] = [
[O, O, O, O, O, O], [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, O, O, O, O, O], [O, O, O, O, O, O],
[O, X, X, X, X, O], [O, X, X, X, X, O],
@@ -119,7 +122,7 @@ const DASH: [[bool; 6]; 5] = [
[O, O, O, O, O, O], [O, O, O, O, O, O],
]; ];
const ERR: [[bool; 6]; 5] = [ const ERR: [[bool; SYMBOL_WIDTH]; SYMBOL_HEIGHT] = [
[X, X, O, O, X, X], [X, X, O, O, X, X],
[O, X, X, X, X, O], [O, X, X, X, X, O],
[O, O, X, X, O, O], [O, O, X, X, O, O],
@@ -127,7 +130,7 @@ const ERR: [[bool; 6]; 5] = [
[X, X, O, O, X, X], [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], [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], [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, X, X, X, X],
[X, X, O, O, X, X], [X, X, O, O, X, X],
[X, X, X, X, X, X], [X, X, X, X, X, X],
@@ -143,7 +146,7 @@ const A: [[bool; 6]; 5] = [
[X, X, O, O, X, X], [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, X, X, X, X],
[X, X, O, O, X, X], [X, X, O, O, X, X],
[X, X, X, X, X, X], [X, X, X, X, X, X],
@@ -151,7 +154,7 @@ const P: [[bool; 6]; 5] = [
[X, X, O, O, O, O], [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, X, X, X, X],
[X, X, O, X, O, X], [X, X, O, X, O, X],
[X, X, O, X, O, X], [X, X, O, X, O, X],