use tray_icon::menu;
use tray_icon::menu::accelerator::Accelerator;
use tray_icon::menu::{IsMenuItem, MenuId, PredefinedMenuItem, Submenu};
use crate::resource::Menu;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum MenuItem {
Common {
id: MenuId,
text: String,
enabled: bool,
accelerator: Option<Accelerator>,
},
SubMenu {
id: MenuId,
text: String,
enabled: bool,
menu: Menu,
},
Separator,
}
impl MenuItem {
#[inline]
pub fn common(
id: impl Into<MenuId>,
text: impl Into<String>,
enabled: bool,
accelerator: Option<Accelerator>,
) -> Self {
Self::Common {
id: id.into(),
text: text.into(),
enabled,
accelerator,
}
}
#[inline]
pub const fn separator() -> Self {
Self::Separator
}
#[inline]
pub fn submenu(
id: impl Into<MenuId>,
text: impl Into<String>,
enabled: bool,
menu: Menu,
) -> Self {
Self::SubMenu {
id: id.into(),
text: text.into(),
enabled,
menu,
}
}
pub(super) fn as_dyn(&self) -> Box<dyn IsMenuItem> {
match self {
MenuItem::Separator => Box::new(PredefinedMenuItem::separator()),
MenuItem::SubMenu {
id,
text,
enabled,
menu,
} => {
let sub_menu = Submenu::with_id(&id.0, text, *enabled);
for item in menu.0.iter().map(|item| item.as_dyn()) {
sub_menu.append(&*item).unwrap();
}
Box::new(sub_menu)
}
MenuItem::Common {
id,
text,
enabled,
accelerator,
} => {
let item = menu::MenuItem::with_id(&id.0, text, *enabled, *accelerator);
Box::new(item)
}
}
}
}