Skip to main content

dais_ui/presenter/
timer.rs

1//! Timer display widget.
2//!
3//! Shows elapsed/countdown time with color coding based on `TimerPhase`.
4//! Clickable to toggle start/pause.
5
6use dais_core::state::{TimerPhase, TimerState};
7
8fn format_duration(duration: std::time::Duration) -> String {
9    let secs = duration.as_secs();
10    let mins = secs / 60;
11    let remaining_secs = secs % 60;
12    format!("{mins:02}:{remaining_secs:02}")
13}
14
15/// Render the timer in a status-bar area. Returns true if clicked (toggle).
16pub fn show_timer(ui: &mut egui::Ui, timer: &TimerState) -> bool {
17    let time_str = format_duration(timer.display_time());
18
19    let phase = timer.phase();
20    let color = match phase {
21        TimerPhase::Normal => egui::Color32::WHITE,
22        TimerPhase::Warning => egui::Color32::YELLOW,
23        TimerPhase::Overrun => egui::Color32::from_rgb(255, 80, 80),
24    };
25
26    let running_icon = if timer.running { "⏸" } else { "▶" };
27    let label = if let Some(duration) = timer.duration {
28        format!("{running_icon} {time_str} / {}", format_duration(duration))
29    } else {
30        format!("{running_icon} {time_str}")
31    };
32
33    let response = ui.add(
34        egui::Label::new(egui::RichText::new(label).size(16.0).color(color))
35            .sense(egui::Sense::click()),
36    );
37
38    if response.hovered() {
39        ui.ctx().set_cursor_icon(egui::CursorIcon::PointingHand);
40    }
41
42    response.clicked()
43}
44
45/// Render the per-slide elapsed timer.
46pub fn show_slide_timer(ui: &mut egui::Ui, elapsed: std::time::Duration) {
47    ui.label(
48        egui::RichText::new(format!("Slide {}", format_duration(elapsed)))
49            .size(14.0)
50            .color(egui::Color32::LIGHT_GRAY),
51    );
52}