use crate::application::app;
use crate::result::Result;
use js_sys::Function;
use nw_sys::prelude::*;
use wasm_bindgen::prelude::*;
use workflow_wasm::prelude::*;
pub fn menu_separator() -> nw_sys::MenuItem {
nw_sys::MenuItem::new(&nw_sys::menu_item::Type::Separator.into())
}
pub struct MenubarBuilder {
pub mac_options: nw_sys::menu::MacOptions,
pub app_name: String,
pub menubar: nw_sys::Menu,
pub menu_items: Vec<nw_sys::MenuItem>,
pub is_macos: bool,
}
impl MenubarBuilder {
pub fn new(app_name: &str, is_macos: bool) -> Self {
Self {
mac_options: nw_sys::menu::MacOptions::new(),
app_name: app_name.to_string(),
menubar: nw_sys::Menu::new_with_options(&nw_sys::menu::Type::Menubar.into()),
menu_items: vec![],
is_macos,
}
}
pub fn mac_hide_edit(mut self, hide: bool) -> Self {
if self.is_macos {
self.mac_options = self.mac_options.hide_edit(hide);
}
self
}
pub fn mac_hide_window(mut self, hide: bool) -> Self {
if self.is_macos {
self.mac_options = self.mac_options.hide_window(hide);
}
self
}
pub fn append(mut self, menu_item: nw_sys::MenuItem) -> Self {
self.menu_items.push(menu_item);
self
}
pub fn build(self, attach: bool) -> Result<nw_sys::Menu> {
if self.is_macos {
self.menubar
.create_mac_builtin_with_options(&self.app_name, &self.mac_options);
}
for item in self.menu_items {
self.menubar.append(&item);
}
if attach {
nw_sys::window::get().set_menu(&self.menubar);
}
Ok(self.menubar)
}
}
pub struct MenuItemBuilder {
pub options: nw_sys::menu_item::Options,
pub callback: Option<Callback<CallbackClosure<JsValue>>>,
}
impl Default for MenuItemBuilder {
fn default() -> Self {
Self::new()
}
}
impl MenuItemBuilder {
pub fn new() -> Self {
Self {
options: nw_sys::menu_item::Options::new(),
callback: None,
}
}
fn set(mut self, key: &str, value: JsValue) -> Self {
self.options = self.options.set(key, value);
self
}
pub fn set_type(self, t: MenuItemType) -> Self {
self.set("type", t.into())
}
pub fn label(self, label: &str) -> Self {
self.set("label", JsValue::from(label))
}
pub fn icon(self, icon: &str) -> Self {
self.set("icon", JsValue::from(icon))
}
pub fn tooltip(self, tooltip: &str) -> Self {
self.set("tooltip", JsValue::from(tooltip))
}
pub fn callback<F>(mut self, callback: F) -> Self
where
F: FnMut(JsValue) -> std::result::Result<(), JsValue> + 'static,
{
let callback = Callback::new(callback);
let cb: &Function = callback.as_ref(); self = self.set("click", JsValue::from(cb));
self.callback = Some(callback);
self
}
pub fn enabled(self, enabled: bool) -> Self {
self.set("enabled", JsValue::from(enabled))
}
pub fn checked(self, checked: bool) -> Self {
self.set("checked", JsValue::from(checked))
}
pub fn submenu(self, submenu: &Menu) -> Self {
self.set("submenu", JsValue::from(submenu))
}
pub fn submenus(self, items: Vec<MenuItem>) -> Self {
let submenu = nw_sys::Menu::new();
for menu_item in items {
submenu.append(&menu_item);
}
self.set("submenu", JsValue::from(submenu))
}
pub fn key(self, key: &str) -> Self {
self.set("key", JsValue::from(key))
}
pub fn modifiers(self, modifiers: &str) -> Self {
self.set("modifiers", JsValue::from(modifiers))
}
pub fn build(self) -> Result<nw_sys::MenuItem> {
if let Some(callback) = self.callback {
let app = match app() {
Some(app) => app,
None => return Err("app is not initialized".to_string().into()),
};
app.callbacks.retain(callback)?;
}
let menu_item = nw_sys::MenuItem::new(&self.options);
Ok(menu_item)
}
pub fn finalize(
self,
) -> Result<(nw_sys::MenuItem, Option<Callback<CallbackClosure<JsValue>>>)> {
let menu_item = nw_sys::MenuItem::new(&self.options);
Ok((menu_item, self.callback))
}
}