old school music tracker
at dev 140 lines 3.6 kB view raw
1pub mod confirm; 2pub mod page_menu; 3pub mod slider_dialog; 4 5use winit::event::{KeyEvent, Modifiers}; 6 7use crate::{ 8 EventQueue, 9 dialog::{confirm::ConfirmDialog, page_menu::MainMenu, slider_dialog::SliderDialog}, 10 draw_buffer::DrawBuffer, 11}; 12 13#[derive(PartialEq, Eq)] 14pub enum DialogResponse { 15 RequestRedraw, 16 // should also close all Dialogs 17 // SwitchToPage(PagesEnum), 18 Close, 19 /// (global_event to be sent, should close the current dialog) 20 // GlobalEvent(GlobalEvent, bool), 21 None, 22} 23 24pub trait Dialog { 25 fn draw(&self, draw_buffer: &mut DrawBuffer); 26 fn process_input( 27 &mut self, 28 key_event: &KeyEvent, 29 modifiers: &Modifiers, 30 events: &mut EventQueue<'_>, 31 ) -> DialogResponse; 32 #[cfg(feature = "accesskit")] 33 fn build_tree( 34 &self, 35 tree: &mut Vec<(accesskit::NodeId, accesskit::Node)>, 36 ) -> crate::AccessResponse; 37} 38 39pub struct DialogManager { 40 stack: Vec<DialogEnum>, 41} 42 43pub enum DialogEnum { 44 Main(MainMenu), 45 Slider(SliderDialog), 46 Confirm(ConfirmDialog), 47} 48 49impl DialogEnum { 50 fn get_mut(&mut self) -> &mut dyn Dialog { 51 match self { 52 DialogEnum::Main(d) => d, 53 DialogEnum::Slider(d) => d, 54 DialogEnum::Confirm(d) => d, 55 } 56 } 57 58 fn get(&self) -> &dyn Dialog { 59 match self { 60 DialogEnum::Main(d) => d, 61 DialogEnum::Slider(d) => d, 62 DialogEnum::Confirm(d) => d, 63 } 64 } 65} 66 67impl Dialog for DialogEnum { 68 fn draw(&self, draw_buffer: &mut DrawBuffer) { 69 match self { 70 DialogEnum::Main(d) => d.draw(draw_buffer), 71 DialogEnum::Slider(d) => d.draw(draw_buffer), 72 DialogEnum::Confirm(d) => d.draw(draw_buffer), 73 } 74 } 75 76 fn process_input( 77 &mut self, 78 key_event: &KeyEvent, 79 modifiers: &Modifiers, 80 events: &mut EventQueue<'_>, 81 ) -> DialogResponse { 82 match self { 83 DialogEnum::Main(d) => d.process_input(key_event, modifiers, events), 84 DialogEnum::Slider(d) => d.process_input(key_event, modifiers, events), 85 DialogEnum::Confirm(d) => d.process_input(key_event, modifiers, events), 86 } 87 } 88 89 #[cfg(feature = "accesskit")] 90 fn build_tree( 91 &self, 92 tree: &mut Vec<(accesskit::NodeId, accesskit::Node)>, 93 ) -> crate::AccessResponse { 94 match self { 95 DialogEnum::Main(d) => d.build_tree(tree), 96 DialogEnum::Slider(d) => d.build_tree(tree), 97 DialogEnum::Confirm(d) => d.build_tree(tree), 98 } 99 } 100} 101 102impl DialogManager { 103 pub fn new() -> Self { 104 // try to match the capacity to the actually used maximum depth 105 Self { 106 stack: Vec::with_capacity(3), 107 } 108 } 109 110 pub fn active_dialog_mut(&mut self) -> Option<&mut dyn Dialog> { 111 self.stack.last_mut().map(|d| d.get_mut()) 112 } 113 114 pub fn active_dialog(&self) -> Option<&dyn Dialog> { 115 self.stack.last().map(|d| d.get()) 116 } 117 118 pub fn is_active(&self) -> bool { 119 !self.stack.is_empty() 120 } 121 122 pub fn open_dialog(&mut self, dialog: DialogEnum) { 123 self.stack.push(dialog); 124 } 125 126 pub fn close_dialog(&mut self) { 127 self.stack.pop(); 128 } 129 130 pub fn close_all(&mut self) { 131 self.stack.clear(); 132 } 133 134 /// draws all currently open dialogs 135 pub fn draw(&self, draw_buffer: &mut DrawBuffer) { 136 self.stack 137 .iter() 138 .for_each(|dialog| dialog.draw(draw_buffer)); 139 } 140}