From b49625a9731d033a6c864d9717ee1dba16203dbd Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Thu, 13 Oct 2022 17:11:50 -0700 Subject: [PATCH] works --- src/main.rs | 4 +- src/timer.rs | 165 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 117 insertions(+), 52 deletions(-) diff --git a/src/main.rs b/src/main.rs index d5271b9..53bf7af 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,15 @@ +use egui::Vec2; use katabastird::timer::Timer; fn main() { let options = eframe::NativeOptions { renderer: eframe::Renderer::Wgpu, + initial_window_size: Some(Vec2::new(1400.0, 800.0)), ..Default::default() }; eframe::run_native( - "eframe template", + "katabastird", options, Box::new(|_cc| Box::new(Timer::default())), ); diff --git a/src/timer.rs b/src/timer.rs index 7dc8b09..804eba7 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -20,8 +20,8 @@ pub struct Timer { #[derive(Debug, Clone, Copy)] enum State { Unstarted, - Paused(Duration), // time remaining - Running(RunningState), // time remaining + Paused(ChronoState), // time remaining + Running(ChronoState), // time remaining } impl PartialEq for State { @@ -38,7 +38,7 @@ impl PartialEq for State { impl Eq for State {} #[derive(Debug, Clone, Copy)] -struct RunningState { +struct ChronoState { started: Instant, remaining: Duration, } @@ -49,35 +49,51 @@ impl Default for Timer { Self { direction: CountDirection::Down, duration: dur, - //state: State::Running(dur), state: State::Unstarted, } } } impl App for Timer { - fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) { + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { ctx.request_repaint_after(Duration::from_secs(1)); egui::CentralPanel::default().show(ctx, |ui| { let size = ctx.used_size(); let vsize = if size[1].is_normal() { size[1].abs() } else { - 200.0 + 600.0 }; match self.state { - State::Running(_) => self.running(ui, vsize), - State::Paused(_) => {} - State::Unstarted => { - self.unstarted(ui, vsize); - } + State::Unstarted => self.unstarted(ui, vsize), + _ => self.running(ui, vsize), } }); } } impl Timer { + pub fn new(duration: Duration, direction: CountDirection, paused: bool) -> Self { + if paused { + Timer { + duration, + direction, + state: State::Unstarted, + } + } else { + let cs = ChronoState { + remaining: duration, + started: Instant::now(), + }; + Timer { + duration, + direction, + state: State::Running(cs), + } + } + } + fn unstarted(&mut self, ui: &mut Ui, size: f32) { let start = RichText::new("START") .font(FontId::monospace(size * 0.9)) @@ -91,7 +107,7 @@ impl Timer { strip.cell(|ui| { if ui.button(start).clicked() { let dur = self.duration; - self.state = State::Running(RunningState { + self.state = State::Running(ChronoState { started: Instant::now(), remaining: dur, }); @@ -100,66 +116,113 @@ impl Timer { }); } - fn paused(&mut self, ui: &mut Ui, size: f32) { - todo!() - } - fn running(&mut self, ui: &mut Ui, size: f32) { - let tsize = size * 0.2; + let tsize = size * 0.3; let text = RichText::new("PAUSE") .font(FontId::monospace(tsize)) .color(Color32::GOLD); let elapsed; let started; + let mut is_paused; if let State::Running(rs) = self.state { elapsed = Instant::now() - rs.started; started = rs.started; + is_paused = false; + } else if let State::Paused(cs) = self.state { + elapsed = cs.remaining; + started = Instant::now() - (self.duration - elapsed); + is_paused = true; } else { unreachable!() } - let remaining = self.duration.saturating_sub(elapsed); + let remaining = if is_paused { + elapsed + } else { + self.duration.saturating_sub(elapsed) + }; - // StripBuilder::vertical(); StripBuilder::new(ui) + .size(Size::relative(0.3333)) .size(Size::remainder()) .cell_layout(Layout::centered_and_justified(Direction::LeftToRight)) - .horizontal(|mut strip| { - strip.cell(|ui| { - if ui.button(text).clicked() { - self.state = State::Paused(remaining); - } + .vertical(|mut strip| { + if is_paused { + strip.strip(|pstrip| { + pstrip + .sizes(Size::remainder(), 2) + .cell_layout(Layout::centered_and_justified(Direction::TopDown)) + .horizontal(|mut pstrip| { + pstrip.cell(|ui| { + let resume = RichText::new("RESUME") + .color(Color32::GREEN) + .font(FontId::monospace(tsize)); + if ui.button(resume).clicked() { + is_paused = false; + } + }); + pstrip.cell(|ui| { + let reset = RichText::new("RESET") + .color(Color32::RED) + .font(FontId::monospace(tsize)); + if ui.button(reset).clicked() { + self.state = State::Unstarted; + is_paused = true; + } + }); + }); + }); + } else { + // first the pause + strip.cell(|ui| { + if ui.button(text).clicked() { + is_paused = true; + } + }); + } + + let remaining = match self.direction { + CountDirection::Down => remaining, + _ => self.duration - remaining, + }; + + // now the numbers + let hours = remaining.as_secs() / 3600; + let minutes = (remaining.as_secs() / 60) % 60; + let seconds = remaining.as_secs() % 60; + let tsize = size * 0.7; + let hours = RichText::new(format!("{:02}", hours)).font(FontId::monospace(tsize)); + let minutes = + RichText::new(format!("{:02}", minutes)).font(FontId::monospace(tsize)); + let seconds = + RichText::new(format!("{:02}", seconds)).font(FontId::monospace(tsize)); + strip.strip(|strip| { + strip + .sizes(Size::relative(0.33), 3) + .cell_layout(Layout::centered_and_justified(Direction::TopDown)) + .horizontal(|mut strip| { + strip.cell(|ui| { + ui.label(hours); + }); + strip.cell(|ui| { + ui.label(minutes); + }); + strip.cell(|ui| { + ui.label(seconds); + }); + }); }); }); - if let State::Paused(_) = self.state { - return; + let cs = ChronoState { remaining, started }; + if is_paused { + if self.state == State::Unstarted { + return; + } + self.state = State::Paused(cs); + } else { + self.state = State::Running(cs); } - - self.state = State::Running(RunningState { started, remaining }); - - let hours = remaining.as_secs() / 3600; - let minutes = (remaining.as_secs() / 60) % 60; - let seconds = remaining.as_secs() % 60; - let tsize = size * 0.7; - let hours = RichText::new(format!("{:02}", hours)).font(FontId::monospace(tsize)); - let minutes = RichText::new(format!("{:02}", minutes)).font(FontId::monospace(tsize)); - let seconds = RichText::new(format!("{:02}", seconds)).font(FontId::monospace(tsize)); - - StripBuilder::new(ui) - .sizes(Size::relative(0.33), 3) - .cell_layout(Layout::centered_and_justified(Direction::TopDown)) - .horizontal(|mut strip| { - strip.cell(|ui| { - ui.label(hours); - }); - strip.cell(|ui| { - ui.label(minutes); - }); - strip.cell(|ui| { - ui.label(seconds); - }); - }); } }