Skip to main content

egui_async/egui/widgets/
popups.rs

1//! Modal-style popup windows designed explicitly for error alerting and user notification.
2
3/// A popup window designed to show errors with a built-in retry mechanism.
4#[must_use = "You should call .show() on this widget to render it"]
5pub struct ErrorPopup<'a> {
6    error: &'a str,
7    id_source: egui::Id,
8    retry_text: String,
9}
10
11impl<'a> ErrorPopup<'a> {
12    /// Creates a new error popup with the given error message.
13    pub fn new(error: &'a str) -> Self {
14        Self {
15            error,
16            id_source: egui::Id::new("egui_async_error_window"),
17            retry_text: "Retry".to_string(),
18        }
19    }
20
21    /// Overrides the default ID source. Useful if you have multiple distinct error popups.
22    pub fn id_source(mut self, id: impl std::hash::Hash) -> Self {
23        self.id_source = egui::Id::new(id);
24        self
25    }
26
27    /// Renders the error popup onto the context.
28    ///
29    /// # Returns
30    /// `true` if the "Retry" button was clicked this frame.
31    #[must_use]
32    pub fn show(self, ctx: &egui::Context) -> bool {
33        let mut retry_clicked = false;
34        let mut open = true;
35
36        egui::Window::new("⚠️ Error")
37            .id(self.id_source)
38            .collapsible(false)
39            .resizable(false)
40            .anchor(egui::Align2::CENTER_CENTER, egui::Vec2::ZERO)
41            .open(&mut open)
42            .show(ctx, |ui| {
43                ui.vertical_centered(|ui| {
44                    ui.add_space(10.0);
45                    ui.label(
46                        egui::RichText::new(self.error)
47                            .color(ui.visuals().error_fg_color)
48                            .size(14.0),
49                    );
50                    ui.add_space(20.0);
51
52                    ui.separator();
53                    ui.add_space(10.0);
54
55                    ui.label("Please retry the request, or contact support if the error persists.");
56                    ui.add_space(10.0);
57
58                    if ui.button(&self.retry_text).clicked() {
59                        retry_clicked = true;
60                    }
61                });
62            });
63
64        retry_clicked
65    }
66}
67
68/// A simple informational popup window requiring user acknowledgment.
69#[must_use = "You should call .show() on this widget to render it"]
70pub struct NotifyPopup<'a> {
71    info: &'a str,
72    id_source: egui::Id,
73    ok_text: String,
74}
75
76impl<'a> NotifyPopup<'a> {
77    /// Creates a new notification popup with the given message.
78    pub fn new(info: &'a str) -> Self {
79        Self {
80            info,
81            id_source: egui::Id::new("egui_async_notify_window"),
82            ok_text: "Ok".to_string(),
83        }
84    }
85
86    /// Renders the notification popup onto the context.
87    ///
88    /// # Returns
89    /// `true` if the acknowledgment button was clicked or the window was closed.
90    #[must_use]
91    pub fn show(self, ctx: &egui::Context) -> bool {
92        let mut ok_clicked = false;
93        let mut open = true;
94
95        egui::Window::new("ℹ Information")
96            .id(self.id_source)
97            .collapsible(false)
98            .resizable(false)
99            .anchor(egui::Align2::CENTER_CENTER, egui::Vec2::ZERO)
100            .open(&mut open)
101            .show(ctx, |ui| {
102                ui.vertical_centered(|ui| {
103                    ui.add_space(10.0);
104                    ui.label(self.info);
105                    ui.add_space(20.0);
106
107                    ui.separator();
108                    ui.add_space(10.0);
109
110                    if ui.button(&self.ok_text).clicked() {
111                        ok_clicked = true;
112                    }
113                });
114            });
115
116        ok_clicked || !open
117    }
118}