diff --git a/Cargo.toml b/Cargo.toml index 2c357f4..65357c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,5 +12,5 @@ eframe = { version = "0.19", features = ["wgpu"] } egui = { version = "0.19", features = ["bytemuck"] } egui_extras = "0.19" naga = { version = "0.10", features = ["spv-out", "wgsl-out", "wgsl-in"] } -rodio = "0.16" +rodio = { version = "0.16" } wgpu = { version = "0.14", features = ["naga", "spirv"] } diff --git a/src/cli.rs b/src/cli.rs index 532c72c..13dd50e 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,19 +1,19 @@ use clap::Parser; #[derive(Debug, Parser)] -#[clap(author, version, about)] +#[clap(author, version, about, disable_help_flag = true)] pub struct Cli { /// Hours to count down. - #[clap(long, default_value_t = 0)] - pub hours: u64, + #[clap(long, short)] + pub hours: Option, /// Minutes to count down. - #[clap(long, short, default_value_t = 0)] - pub minutes: u64, + #[clap(long, short)] + pub minutes: Option, /// Seconds to count down. - #[clap(long, short, default_value_t = 0)] - pub seconds: u64, + #[clap(long, short)] + pub seconds: Option, /// Audio file to play at the end of the countdown. #[clap(long, short)] @@ -30,4 +30,8 @@ pub struct Cli { /// Use the Predator font. #[clap(long, short)] pub predator: bool, + + /// Print this help. + #[clap(long, short = 'H', action = clap::ArgAction::Help)] + pub help: Option, } diff --git a/src/timer.rs b/src/timer.rs index 520a743..fd2be9c 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -7,7 +7,7 @@ use egui_extras::{Size, StripBuilder}; use crate::{cli::Cli, util::*}; -const MIN_REPAINT: Duration = Duration::from_millis(183); // one frame before 200ms +const MIN_REPAINT: Duration = Duration::from_millis(200); // one frame before 200ms const MAX_REPAINT: Duration = Duration::from_millis(500); const DIGIT_FACTOR: f32 = 0.4; @@ -26,7 +26,6 @@ pub struct Timer { state: TimerState, tstart: Instant, // so we can blink alarm: Option, - height: Option, } #[derive(Debug, Clone, Copy)] @@ -60,20 +59,18 @@ struct ChronoState { impl App for Timer { fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) { ctx.request_repaint_after(MAX_REPAINT); + let height = ctx.input().screen_rect().height(); egui::CentralPanel::default().show(ctx, |ui| { - let vsize = self.height.unwrap_or(500.0); - match self.state { - TimerState::Unstarted => self.unstarted(ui, vsize), + TimerState::Unstarted => self.unstarted(ui, height), TimerState::Running(cs) => { - if (Instant::now() - cs.updated) > MIN_REPAINT { - ctx.request_repaint(); - } - self.running(ui, vsize); + let dur = Instant::now() - cs.updated; + let dur = MIN_REPAINT.saturating_sub(dur); + ctx.request_repaint_after(dur); + self.running(ui, height); } - TimerState::Paused(_) => self.paused(ui, vsize), - - TimerState::Finished => self.finished(ui, vsize), + TimerState::Paused(_) => self.paused(ui, height), + TimerState::Finished => self.finished(ui, height), } // check for quit key if ui.input().key_pressed(egui::Key::Q) || ui.input().key_pressed(egui::Key::Escape) { @@ -87,7 +84,9 @@ impl Timer { pub fn new(ctx: &CreationContext) -> Self { let cli = Cli::parse(); let predator = cli.predator; - let seconds = cli.hours * 3600 + cli.minutes * 60 + cli.seconds; + let seconds = cli.hours.unwrap_or(0) * 3600 + + cli.minutes.unwrap_or(0) * 60 + + cli.seconds.unwrap_or(0); let duration = Duration::from_secs(seconds); let direction = if cli.count_up { @@ -116,7 +115,6 @@ impl Timer { state: TimerState::Unstarted, tstart: Instant::now(), alarm: cli.alarm, - height: None, }; if cli.running { let cs = ChronoState { @@ -133,11 +131,10 @@ impl Timer { let tsize = size * 0.5; let start = RichText::new("START") .font(FontId::monospace(tsize)) - .size(tsize) .color(Color32::WHITE) .background_color(Color32::LIGHT_GREEN); - let height = StripBuilder::new(ui) + StripBuilder::new(ui) .size(Size::remainder()) .cell_layout(Layout::centered_and_justified(egui::Direction::TopDown)) .horizontal(|mut strip| { @@ -150,17 +147,13 @@ impl Timer { }); } }); - }) - .rect - .height(); - self.height = Some(height); + }); } fn running(&mut self, ui: &mut Ui, size: f32) { let tsize = size * TEXT_FACTOR; let text = RichText::new("PAUSE") .font(FontId::monospace(tsize)) - .size(tsize) .color(Color32::GOLD); let elapsed; @@ -175,7 +168,7 @@ impl Timer { let remaining = remaining.saturating_sub(elapsed); - let height = StripBuilder::new(ui) + StripBuilder::new(ui) .size(Size::relative(0.3333)) .size(Size::remainder()) .cell_layout(Layout::centered_and_justified(Direction::LeftToRight)) @@ -197,11 +190,7 @@ impl Timer { let tsize = size * DIGIT_FACTOR; display_digits(&mut strip, remaining, color, tsize); - }) - .rect - .height(); - - self.height = Some(height); + }); if remaining.is_zero() { if let Some(alarm_file) = &self.alarm { @@ -238,7 +227,7 @@ impl Timer { } let remaining = elapsed; - let height = StripBuilder::new(ui) + StripBuilder::new(ui) .size(Size::relative(0.33333)) .size(Size::remainder()) .cell_layout(Layout::centered_and_justified(Direction::LeftToRight)) @@ -251,8 +240,7 @@ impl Timer { pstrip.cell(|ui| { let resume = RichText::new("RESUME") .color(Color32::GREEN) - .font(FontId::monospace(tsize)) - .size(tsize); + .font(FontId::monospace(tsize)); if ui.button(resume).clicked() { is_running = true; } @@ -260,8 +248,7 @@ impl Timer { pstrip.cell(|ui| { let reset = RichText::new("RESET") .color(Color32::RED) - .font(FontId::monospace(tsize)) - .size(tsize); + .font(FontId::monospace(tsize)); if ui.button(reset).clicked() { self.state = TimerState::Unstarted; } @@ -282,10 +269,7 @@ impl Timer { CountDirection::Up => self.duration - remaining, }; display_digits(&mut strip, remaining, color, vsize * DIGIT_FACTOR); - }) - .rect - .height(); - self.height = Some(height); + }); if is_running { let cs = ChronoState { @@ -315,8 +299,7 @@ impl Timer { let tsize = vsize * 0.3; let reset = RichText::new("RESTART") .color(Color32::DARK_GREEN) - .font(FontId::monospace(tsize)) - .size(tsize); + .font(FontId::monospace(tsize)); if ui.button(reset).clicked() { self.state = TimerState::Unstarted; }