ui/
dialogs.rs

1//! Contains the trait for defining dialogs, as well as the resource that tracks all "open" dialogs
2//! currently active in the UI.
3
4mod new_project;
5mod open_project;
6
7use bevy::prelude::Resource;
8use egui::Context;
9
10use crate::dialogs::open_project::OpenProject;
11pub use new_project::NewProject;
12
13/// Contains all dialogs in the UI.
14///
15/// A field that's set to `None` will not be rendered.
16#[derive(Default, Resource)]
17pub struct Dialogs {
18    /// An optional reference to the new project dialog to render.
19    new_project: Option<NewProject>,
20    /// An optional reference to the open project dialog to render.
21    open_project: Option<OpenProject>,
22}
23
24impl Dialogs {
25    /// Calls `render` on each currently active dialog in the queue.
26    ///
27    /// Also removes dialogs that indicated they shouldn't be kept open.
28    pub fn render(&mut self, context: &mut Context) {
29        if let Some(new_project) = self.new_project.as_mut() {
30            if !new_project.render(context) {
31                self.new_project = None;
32            }
33        }
34
35        if let Some(open_project) = self.open_project.as_mut() {
36            if !open_project.render(context) {
37                self.open_project = None;
38            }
39        }
40    }
41
42    /// Instruct the UI to start rendering the new project dialog if it's not shown yet.
43    pub fn show_new_project(&mut self) {
44        if self.new_project.is_none() {
45            self.new_project = Some(NewProject::default());
46        }
47    }
48
49    /// Instruct the UI to start rendering the new project dialog if it's not shown yet.
50    pub fn show_open_project(&mut self) {
51        if self.open_project.is_none() {
52            self.open_project = Some(OpenProject::default());
53        }
54    }
55}
56
57/// A small trait to define that a dialog struct can be rendered.
58trait RenderableDialog: Send + Sync + 'static {
59    /// Called once per render, the struct should render itself as a window in the given `context`.
60    ///
61    /// If the returned boolean is false, the dialog will automatically be removed from the render queue.
62    fn render(&mut self, context: &mut Context) -> bool;
63}