#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MenuItem {
pub id: u32,
pub label: String,
pub command_string: Option<String>,
pub is_separator: bool,
pub is_disabled: bool,
pub is_checked: bool,
pub is_default: bool,
pub submenu: Option<Vec<MenuItem>>,
}
impl MenuItem {
pub(crate) fn separator() -> Self {
Self {
id: 0,
label: String::new(),
command_string: None,
is_separator: true,
is_disabled: false,
is_checked: false,
is_default: false,
submenu: None,
}
}
}
impl std::fmt::Display for MenuItem {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.is_separator {
write!(f, "---separator---")
} else {
write!(f, "{}", self.label)?;
if let Some(ref cmd) = self.command_string {
write!(f, " [{}]", cmd)?;
}
Ok(())
}
}
}
pub(crate) type Invoker = Box<dyn FnOnce(Option<InvokeParams>) -> crate::error::Result<()>>;
pub struct SelectedItem {
pub(crate) menu_item: MenuItem,
pub(crate) command_id: u32,
pub(crate) invoker: Option<Invoker>,
pub(crate) _hidden_window: Option<crate::hidden_window::HiddenWindow>,
}
impl SelectedItem {
pub fn menu_item(&self) -> &MenuItem {
&self.menu_item
}
pub fn command_id(&self) -> u32 {
self.command_id
}
pub fn execute(self) -> crate::error::Result<()> {
if let Some(invoker) = self.invoker {
invoker(None)
} else {
Ok(())
}
}
pub fn execute_with(self, params: InvokeParams) -> crate::error::Result<()> {
if let Some(invoker) = self.invoker {
invoker(Some(params))
} else {
Ok(())
}
}
}
impl std::fmt::Debug for SelectedItem {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SelectedItem")
.field("menu_item", &self.menu_item)
.field("command_id", &self.command_id)
.finish_non_exhaustive()
}
}
#[derive(Debug, Clone, Default)]
pub struct InvokeParams {
pub directory: Option<String>,
pub show_cmd: Option<i32>,
}