pub mod confirm; pub mod page_menu; pub mod slider_dialog; use winit::event::{KeyEvent, Modifiers}; use crate::{ EventQueue, dialog::{confirm::ConfirmDialog, page_menu::MainMenu, slider_dialog::SliderDialog}, draw_buffer::DrawBuffer, }; #[derive(PartialEq, Eq)] pub enum DialogResponse { RequestRedraw, // should also close all Dialogs // SwitchToPage(PagesEnum), Close, /// (global_event to be sent, should close the current dialog) // GlobalEvent(GlobalEvent, bool), None, } pub trait Dialog { fn draw(&self, draw_buffer: &mut DrawBuffer); fn process_input( &mut self, key_event: &KeyEvent, modifiers: &Modifiers, events: &mut EventQueue<'_>, ) -> DialogResponse; #[cfg(feature = "accesskit")] fn build_tree( &self, tree: &mut Vec<(accesskit::NodeId, accesskit::Node)>, ) -> crate::AccessResponse; } pub struct DialogManager { stack: Vec, } pub enum DialogEnum { Main(MainMenu), Slider(SliderDialog), Confirm(ConfirmDialog), } impl DialogEnum { fn get_mut(&mut self) -> &mut dyn Dialog { match self { DialogEnum::Main(d) => d, DialogEnum::Slider(d) => d, DialogEnum::Confirm(d) => d, } } fn get(&self) -> &dyn Dialog { match self { DialogEnum::Main(d) => d, DialogEnum::Slider(d) => d, DialogEnum::Confirm(d) => d, } } } impl Dialog for DialogEnum { fn draw(&self, draw_buffer: &mut DrawBuffer) { match self { DialogEnum::Main(d) => d.draw(draw_buffer), DialogEnum::Slider(d) => d.draw(draw_buffer), DialogEnum::Confirm(d) => d.draw(draw_buffer), } } fn process_input( &mut self, key_event: &KeyEvent, modifiers: &Modifiers, events: &mut EventQueue<'_>, ) -> DialogResponse { match self { DialogEnum::Main(d) => d.process_input(key_event, modifiers, events), DialogEnum::Slider(d) => d.process_input(key_event, modifiers, events), DialogEnum::Confirm(d) => d.process_input(key_event, modifiers, events), } } #[cfg(feature = "accesskit")] fn build_tree( &self, tree: &mut Vec<(accesskit::NodeId, accesskit::Node)>, ) -> crate::AccessResponse { match self { DialogEnum::Main(d) => d.build_tree(tree), DialogEnum::Slider(d) => d.build_tree(tree), DialogEnum::Confirm(d) => d.build_tree(tree), } } } impl DialogManager { pub fn new() -> Self { // try to match the capacity to the actually used maximum depth Self { stack: Vec::with_capacity(3), } } pub fn active_dialog_mut(&mut self) -> Option<&mut dyn Dialog> { self.stack.last_mut().map(|d| d.get_mut()) } pub fn active_dialog(&self) -> Option<&dyn Dialog> { self.stack.last().map(|d| d.get()) } pub fn is_active(&self) -> bool { !self.stack.is_empty() } pub fn open_dialog(&mut self, dialog: DialogEnum) { self.stack.push(dialog); } pub fn close_dialog(&mut self) { self.stack.pop(); } pub fn close_all(&mut self) { self.stack.clear(); } /// draws all currently open dialogs pub fn draw(&self, draw_buffer: &mut DrawBuffer) { self.stack .iter() .for_each(|dialog| dialog.draw(draw_buffer)); } }