use crate::*; /// Various possible dialog modes. #[derive(Debug, Clone, Default, PartialEq)] pub enum Dialog { #[default] None, Help(usize), Menu(usize, MenuItems), Device(usize), Message(Arc), Browse(BrowseTarget, Arc), Options, } #[derive(Debug, Clone, Default, PartialEq)] pub struct MenuItems(pub Arc<[MenuItem]>); impl AsRef> for MenuItems { fn as_ref (&self) -> &Arc<[MenuItem]> { &self.0 } } #[derive(Clone)] pub struct MenuItem( /// Label pub Arc, /// Callback pub ArcUsually<()> + Send + Sync>> ); impl Default for MenuItem { fn default () -> Self { Self("".into(), Arc::new(Box::new(|_|Ok(())))) } } impl_debug!(MenuItem |self, w| { write!(w, "{}", &self.0) }); impl PartialEq for MenuItem { fn eq (&self, other: &Self) -> bool { self.0 == other.0 } } impl Dialog { pub fn welcome () -> Self { Self::Menu(1, MenuItems([ MenuItem("Resume session".into(), Arc::new(Box::new(|_|Ok(())))), MenuItem("Create new session".into(), Arc::new(Box::new(|app|Ok({ app.dialog = Dialog::None; app.mode = app.config.modes.clone().read().unwrap().get(":arranger").cloned().unwrap(); })))), MenuItem("Load old session".into(), Arc::new(Box::new(|_|Ok(())))), ].into())) } pub fn menu_next (&self) -> Self { match self { Self::Menu(index, items) => Self::Menu(wrap_inc(*index, items.0.len()), items.clone()), _ => Self::None } } pub fn menu_prev (&self) -> Self { match self { Self::Menu(index, items) => Self::Menu(wrap_dec(*index, items.0.len()), items.clone()), _ => Self::None } } pub fn menu_selected (&self) -> Option { if let Self::Menu(selected, _) = self { Some(*selected) } else { None } } pub fn device_kind (&self) -> Option { if let Self::Device(index) = self { Some(*index) } else { None } } pub fn device_kind_next (&self) -> Option { self.device_kind().map(|index|(index + 1) % device_kinds().len()) } pub fn device_kind_prev (&self) -> Option { self.device_kind().map(|index|index.overflowing_sub(1).0.min(device_kinds().len().saturating_sub(1))) } pub fn message (&self) -> Option<&str> { todo!() } pub fn browser (&self) -> Option<&Arc> { todo!() } pub fn browser_target (&self) -> Option<&BrowseTarget> { todo!() } }