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