Skip to main content

par_term/
quit_confirmation_ui.rs

1//! Quit confirmation dialog for the application.
2//!
3//! Shows a confirmation dialog when the user attempts to close the window
4//! while there are active terminal sessions. Allows the user to either
5//! quit the application or cancel the close operation.
6
7/// Action returned by the quit confirmation dialog
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum QuitConfirmAction {
10    /// User confirmed - quit the application
11    Quit,
12    /// User cancelled - keep the window open
13    Cancel,
14    /// No action yet (dialog not showing or still showing)
15    None,
16}
17
18/// State for the quit confirmation dialog
19pub struct QuitConfirmationUI {
20    /// Whether the dialog is visible
21    visible: bool,
22    /// Number of active sessions to display
23    session_count: usize,
24}
25
26impl Default for QuitConfirmationUI {
27    fn default() -> Self {
28        Self::new()
29    }
30}
31
32impl QuitConfirmationUI {
33    /// Create a new quit confirmation UI
34    pub fn new() -> Self {
35        Self {
36            visible: false,
37            session_count: 0,
38        }
39    }
40
41    /// Check if the dialog is currently visible
42    pub fn is_visible(&self) -> bool {
43        self.visible
44    }
45
46    /// Show the confirmation dialog with the number of active sessions
47    pub fn show_confirmation(&mut self, session_count: usize) {
48        self.visible = true;
49        self.session_count = session_count;
50    }
51
52    /// Hide the dialog and clear state
53    fn hide(&mut self) {
54        self.visible = false;
55        self.session_count = 0;
56    }
57
58    /// Render the dialog and return any action
59    pub fn show(&mut self, ctx: &egui::Context) -> QuitConfirmAction {
60        if !self.visible {
61            return QuitConfirmAction::None;
62        }
63
64        let mut action = QuitConfirmAction::None;
65
66        egui::Window::new("Quit par-term?")
67            .collapsible(false)
68            .resizable(false)
69            .order(egui::Order::Foreground)
70            .anchor(egui::Align2::CENTER_CENTER, [0.0, 0.0])
71            .show(ctx, |ui| {
72                ui.vertical_centered(|ui| {
73                    ui.add_space(10.0);
74
75                    ui.label(
76                        egui::RichText::new("⚠ Quit Application?")
77                            .color(egui::Color32::YELLOW)
78                            .size(18.0)
79                            .strong(),
80                    );
81                    ui.add_space(10.0);
82
83                    let session_text = if self.session_count == 1 {
84                        "There is 1 active session.".to_string()
85                    } else {
86                        format!("There are {} active sessions.", self.session_count)
87                    };
88                    ui.label(&session_text);
89                    ui.add_space(5.0);
90
91                    ui.label(
92                        egui::RichText::new("All sessions will be terminated.")
93                            .color(egui::Color32::GRAY),
94                    );
95                    ui.add_space(15.0);
96
97                    // Buttons
98                    ui.horizontal(|ui| {
99                        let quit_button = egui::Button::new(
100                            egui::RichText::new("Quit").color(egui::Color32::WHITE),
101                        )
102                        .fill(egui::Color32::from_rgb(180, 50, 50));
103
104                        if ui.add(quit_button).clicked() {
105                            action = QuitConfirmAction::Quit;
106                        }
107
108                        ui.add_space(10.0);
109
110                        if ui.button("Cancel").clicked() {
111                            action = QuitConfirmAction::Cancel;
112                        }
113                    });
114                    ui.add_space(10.0);
115                });
116            });
117
118        // Handle escape key to cancel
119        if ctx.input(|i| i.key_pressed(egui::Key::Escape)) {
120            action = QuitConfirmAction::Cancel;
121        }
122
123        // Handle enter key to confirm quit
124        if ctx.input(|i| i.key_pressed(egui::Key::Enter)) {
125            action = QuitConfirmAction::Quit;
126        }
127
128        // Hide dialog on any action
129        if !matches!(action, QuitConfirmAction::None) {
130            self.hide();
131        }
132
133        action
134    }
135}