use std::time::Instant; use eframe::{ egui::{self, Frame}, epaint::Color32, Frame as EFrame, }; use super::{state::*, Timer}; use crate::{MAX_REPAINT, MIN_REPAINT}; const STARTING_COLOR: &[f32; 3] = &[10.0, 4.0, 14.0]; const UNIT_COLOR: &[f32; 3] = &[0.986, 0.154, 0.055]; // [160, 125, 9].normalize() impl eframe::App for Timer { fn update(&mut self, ctx: &egui::Context, frame: &mut EFrame) { ctx.request_repaint_after(MAX_REPAINT); let height = ctx.input().screen_rect().height(); let t = self.done.powi(3); let color = get_color(t); egui::CentralPanel::default() .frame(Frame::none().fill(color)) .show(ctx, |ui| { match self.state { TimerState::Unstarted => self.unstarted(ui, height), TimerState::Running(cs) => { let dur = Instant::now() - cs.updated; let dur = MIN_REPAINT.saturating_sub(dur); ctx.request_repaint_after(dur); self.running(ui, height, cs); } TimerState::Paused(cs) => self.paused(ui, height, cs), 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) { frame.close(); } }); } } fn get_color(t: f32) -> Color32 { let [sr, sg, sb] = STARTING_COLOR; let [ur, ug, ub] = UNIT_COLOR; let mag = t * 162.0; let (r, g, b) = ( (sr + (mag * ur).round()) as u8, (sg + (mag * ug).round()) as u8, (sb + (mag * ub).round()) as u8, ); // when t is 1.0, then the final color is roughly 170, 29, 23. Color32::from_rgb(r, g, b) }