Skip to main content

egui_charts/ui/replay/
start.rs

1//! Start selection intents; the host supplies history, randomness and saved sessions.
2
3use crate::localization as l10n;
4use crate::ui_kit::{buttons::Button, modal::Modal};
5use chrono::{DateTime, NaiveDate, Utc};
6
7/// A replay start requested by the user.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
9#[non_exhaustive]
10pub enum ReplayStartAction {
11    /// No selection, including cancellation.
12    #[default]
13    None,
14    /// Select the start by clicking a chart bar.
15    SelectBar,
16    /// First available source bar.
17    First,
18    /// A random source bar selected by the host.
19    Random,
20    /// First source bar opening on or after this UTC instant.
21    Date(DateTime<Utc>),
22    /// Restore the host's saved session.
23    Resume,
24}
25
26/// Start selection dialog shared by hosts of the replay controller.
27#[derive(Default)]
28pub struct ReplayStartPicker {
29    /// Whether the dialog is open.
30    pub is_open: bool,
31    date: String,
32}
33
34impl ReplayStartPicker {
35    /// Opens start selection with an optional initial UTC date.
36    pub fn open(&mut self, date: Option<DateTime<Utc>>) {
37        self.date = date.map_or_else(String::new, |time| time.format("%Y-%m-%d").to_string());
38        self.is_open = true;
39    }
40
41    /// Shows start choices. Resume is enabled only when the host has a saved session.
42    pub fn show(&mut self, ctx: &egui::Context, can_resume: bool) -> ReplayStartAction {
43        if !self.is_open {
44            return ReplayStartAction::None;
45        }
46        let mut action = ReplayStartAction::None;
47        Modal::new("replay_start", "Start replay")
48            .width(360.0)
49            .show(ctx, &mut self.is_open, |ui| {
50                ui.label(l10n::text(
51                    ui.ctx(),
52                    "Choose where to begin. Playback starts paused.",
53                ));
54                ui.add_space(8.0);
55                for (label, choice) in [
56                    ("Select a bar on the chart", ReplayStartAction::SelectBar),
57                    ("First available bar", ReplayStartAction::First),
58                    ("Random bar", ReplayStartAction::Random),
59                ] {
60                    if Button::new(label).secondary().show(ui).clicked() {
61                        action = choice;
62                    }
63                }
64                ui.separator();
65                ui.label(l10n::text(ui.ctx(), "Date (UTC, YYYY-MM-DD)"));
66                ui.add(
67                    egui::TextEdit::singleline(&mut self.date).desired_width(ui.available_width()),
68                );
69                let date = NaiveDate::parse_from_str(self.date.trim(), "%Y-%m-%d")
70                    .ok()
71                    .and_then(|date| date.and_hms_opt(0, 0, 0))
72                    .map(|date| date.and_utc());
73                if Button::new("Start at date")
74                    .secondary()
75                    .enabled(date.is_some())
76                    .show(ui)
77                    .clicked()
78                    && let Some(date) = date
79                {
80                    action = ReplayStartAction::Date(date);
81                }
82                ui.separator();
83                if Button::new("Resume saved session")
84                    .secondary()
85                    .enabled(can_resume)
86                    .show(ui)
87                    .clicked()
88                {
89                    action = ReplayStartAction::Resume;
90                }
91            });
92        if action != ReplayStartAction::None {
93            self.is_open = false;
94        }
95        action
96    }
97}