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}