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(
47    ui: &mut egui::Ui,
48    elapsed: std::time::Duration,
49    target: Option<std::time::Duration>,
50) {
51    let over_target = target.is_some_and(|duration| elapsed > duration);
52    let color =
53        if over_target { egui::Color32::from_rgb(255, 80, 80) } else { egui::Color32::LIGHT_GRAY };
54    let label = if let Some(target) = target {
55        format!("Slide {} / {}", format_duration(elapsed), format_duration(target))
56    } else {
57        format!("Slide {}", format_duration(elapsed))
58    };
59
60    ui.label(egui::RichText::new(label).size(14.0).color(color));
61}