#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub struct MenuId(pub u32);
#[derive(Clone, Debug)]
pub enum MenuItem {
Button {
id: MenuId,
label: String,
enabled: bool,
checked: Option<bool>,
},
Separator,
Submenu {
label: String,
enabled: bool,
items: Vec<MenuItem>,
},
}
impl MenuItem {
pub fn button(id: u32, label: impl Into<String>) -> MenuItem {
MenuItem::Button {
id: MenuId(id),
label: label.into(),
enabled: true,
checked: None,
}
}
pub fn checkbox(id: u32, label: impl Into<String>, checked: bool) -> MenuItem {
MenuItem::Button {
id: MenuId(id),
label: label.into(),
enabled: true,
checked: Some(checked),
}
}
pub fn separator() -> MenuItem {
MenuItem::Separator
}
pub fn submenu(
label: impl Into<String>,
items: impl IntoIterator<Item = MenuItem>,
) -> MenuItem {
MenuItem::Submenu {
label: label.into(),
enabled: true,
items: items.into_iter().collect(),
}
}
pub fn enabled(mut self, value: bool) -> MenuItem {
match &mut self {
MenuItem::Button { enabled, .. } | MenuItem::Submenu { enabled, .. } => {
*enabled = value
}
MenuItem::Separator => {}
}
self
}
}
#[derive(Clone, Debug, Default)]
pub struct Menu {
pub(crate) items: Vec<MenuItem>,
}
impl Menu {
pub fn new() -> Menu {
Menu { items: Vec::new() }
}
pub fn item(mut self, item: MenuItem) -> Menu {
self.items.push(item);
self
}
pub fn items(&self) -> &[MenuItem] {
&self.items
}
pub fn is_empty(&self) -> bool {
self.items.is_empty()
}
}
impl FromIterator<MenuItem> for Menu {
fn from_iter<I: IntoIterator<Item = MenuItem>>(iter: I) -> Menu {
Menu {
items: iter.into_iter().collect(),
}
}
}