Add flag to hide fractional seconds on timer

This commit is contained in:
Wesley Moore 2022-08-03 18:30:37 +10:00
parent 08fb4d0328
commit 3032cc4bec
No known key found for this signature in database
GPG key ID: BF67766C0BC2D0EE
4 changed files with 38 additions and 10 deletions

View file

@ -8,6 +8,7 @@ use tui::style::Style;
use tui::Frame; use tui::Frame;
use self::modes::Clock; use self::modes::Clock;
use self::modes::DurationFormat;
use self::modes::Stopwatch; use self::modes::Stopwatch;
use self::modes::Timer; use self::modes::Timer;
@ -28,6 +29,10 @@ pub(crate) enum Mode {
Timer { Timer {
#[clap(short, long, value_parser = parse_duration, default_value = "5m")] #[clap(short, long, value_parser = parse_duration, default_value = "5m")]
duration: Duration, duration: Duration,
/// Hide milliseconds
#[clap(long = "no-millis", takes_value = false)]
no_millis: bool,
}, },
/// The stopwatch mode displays the elapsed time since it was started. /// The stopwatch mode displays the elapsed time since it was started.
Stopwatch, Stopwatch,
@ -38,7 +43,7 @@ pub(crate) enum Mode {
pub(crate) struct App { pub(crate) struct App {
#[clap(subcommand)] #[clap(subcommand)]
pub mode: Option<Mode>, pub mode: Option<Mode>,
/// Forground color of the clock, possible values are: /// Foreground color of the clock, possible values are:
/// a) Any one of: Black, Red, Green, Yellow, Blue, Magenta, Cyan, Gray, DarkGray, LightRed, LightGreen, LightYellow, LightBlue, LightMagenta, LightCyan, White. /// a) Any one of: Black, Red, Green, Yellow, Blue, Magenta, Cyan, Gray, DarkGray, LightRed, LightGreen, LightYellow, LightBlue, LightMagenta, LightCyan, White.
/// b) Hexadecimal color code: #RRGGBB. /// b) Hexadecimal color code: #RRGGBB.
#[clap(short, long, value_parser = parse_color, default_value = "green")] #[clap(short, long, value_parser = parse_color, default_value = "green")]
@ -71,8 +76,16 @@ impl App {
show_millis: millis.to_owned(), show_millis: millis.to_owned(),
}); });
} }
Mode::Timer { duration } => { Mode::Timer {
self.timer = Some(Timer::new(duration.to_owned(), self.size, style)); duration,
no_millis,
} => {
let format = if *no_millis {
DurationFormat::HourMinSec
} else {
DurationFormat::HourMinSecDeci
};
self.timer = Some(Timer::new(duration.to_owned(), self.size, style, format));
} }
Mode::Stopwatch => { Mode::Stopwatch => {
self.stopwatch = Some(Stopwatch::new(self.size, style)); self.stopwatch = Some(Stopwatch::new(self.size, style));

View file

@ -17,7 +17,15 @@ use tui::{
widgets::{Paragraph, Widget}, widgets::{Paragraph, Widget},
}; };
fn format_duration(duration: Duration) -> String { #[derive(Copy, Clone)]
pub(crate) enum DurationFormat {
/// Hours, minutes, seconds, deciseconds
HourMinSecDeci,
/// Hours, minutes, seconds
HourMinSec,
}
fn format_duration(duration: Duration, format: DurationFormat) -> String {
let millis = duration.num_milliseconds(); let millis = duration.num_milliseconds();
let seconds = millis / 1000; let seconds = millis / 1000;
let minutes = seconds / 60; let minutes = seconds / 60;
@ -31,7 +39,12 @@ fn format_duration(duration: Duration) -> String {
result.push_str(&format!("{}:", hours % 24)); result.push_str(&format!("{}:", hours % 24));
} }
result.push_str(&format!("{}:", minutes % 60)); result.push_str(&format!("{}:", minutes % 60));
result.push_str(&format!("{:02}.{}", seconds % 60, (millis % 1000) / 100)); match format {
DurationFormat::HourMinSecDeci => {
result.push_str(&format!("{:02}.{}", seconds % 60, (millis % 1000) / 100))
}
DurationFormat::HourMinSec => result.push_str(&format!("{:02}", seconds % 60)),
}
result result
} }

View file

@ -2,7 +2,7 @@ use chrono::{DateTime, Duration, Local};
use clock_tui::bricks_text::BricksText; use clock_tui::bricks_text::BricksText;
use tui::{buffer::Buffer, layout::Rect, style::Style, widgets::Widget}; use tui::{buffer::Buffer, layout::Rect, style::Style, widgets::Widget};
use super::{format_duration, render_centered}; use super::{format_duration, render_centered, DurationFormat};
pub struct Stopwatch { pub struct Stopwatch {
pub size: u16, pub size: u16,
@ -51,7 +51,7 @@ impl Stopwatch {
impl Widget for &Stopwatch { impl Widget for &Stopwatch {
fn render(self, area: Rect, buf: &mut Buffer) { fn render(self, area: Rect, buf: &mut Buffer) {
let time_str = format_duration(self.total_time()); let time_str = format_duration(self.total_time(), DurationFormat::HourMinSecDeci);
let text = BricksText::new(time_str.as_str(), self.size, self.size, self.style); let text = BricksText::new(time_str.as_str(), self.size, self.size, self.style);
let footer = if self.is_paused() { let footer = if self.is_paused() {
Some("PAUSED (press <SPACE> to resume)".to_string()) Some("PAUSED (press <SPACE> to resume)".to_string())

View file

@ -2,21 +2,23 @@ use chrono::{DateTime, Duration, Local};
use clock_tui::bricks_text::BricksText; use clock_tui::bricks_text::BricksText;
use tui::{buffer::Buffer, layout::Rect, style::Style, widgets::Widget}; use tui::{buffer::Buffer, layout::Rect, style::Style, widgets::Widget};
use super::{format_duration, render_centered}; use super::{format_duration, render_centered, DurationFormat};
pub struct Timer { pub struct Timer {
pub size: u16, pub size: u16,
pub style: Style, pub style: Style,
format: DurationFormat,
duration: Duration, duration: Duration,
ended_at: Option<DateTime<Local>>, ended_at: Option<DateTime<Local>>,
} }
impl Timer { impl Timer {
pub(crate) fn new(duration: Duration, size: u16, style: Style) -> Self { pub(crate) fn new(duration: Duration, size: u16, style: Style, format: DurationFormat) -> Self {
Self { Self {
duration, duration,
size, size,
style, style,
format,
ended_at: Some(Local::now() + duration), ended_at: Some(Local::now() + duration),
} }
} }
@ -58,7 +60,7 @@ impl Timer {
impl Widget for &Timer { impl Widget for &Timer {
fn render(self, area: Rect, buf: &mut Buffer) { fn render(self, area: Rect, buf: &mut Buffer) {
let time_str = format_duration(self.remaining_time()); let time_str = format_duration(self.remaining_time(), self.format);
let text = BricksText::new(time_str.as_str(), self.size, self.size, self.style); let text = BricksText::new(time_str.as_str(), self.size, self.size, self.style);
let footer = if self.is_paused() { let footer = if self.is_paused() {
Some("PAUSED (press <SPACE> to resume)".to_string()) Some("PAUSED (press <SPACE> to resume)".to_string())