use crate::application::app;
use crate::result::Result;
use nw_sys::prelude::*;
use nw_sys::{menu_item::MenuItem, tray::Options, Menu, Tray};
use wasm_bindgen::prelude::*;
use web_sys::MouseEvent;
use workflow_wasm::prelude::*;
pub struct TrayMenuBuilder {
pub options: Options,
pub menu: Option<Menu>,
pub tooltip: Option<String>,
pub callback: Option<Callback<CallbackClosure<MouseEvent>>>,
}
impl Default for TrayMenuBuilder {
fn default() -> Self {
Self::new()
}
}
impl TrayMenuBuilder {
pub fn new() -> Self {
Self {
options: Options::new(),
menu: None,
tooltip: None,
callback: None,
}
}
pub fn set(mut self, key: &str, value: JsValue) -> Self {
self.options = self.options.set(key, value);
self
}
pub fn title(self, title: &str) -> Self {
self.set("title", JsValue::from(title))
}
pub fn tooltip(mut self, tooltip: &str) -> Self {
self = self.set("tooltip", JsValue::from(tooltip));
self.tooltip = Some(tooltip.to_string());
self
}
pub fn icon(self, icon: &str) -> Self {
self.set("icon", JsValue::from(icon))
}
pub fn alticon(self, alticon: &str) -> Self {
self.set("alticon", JsValue::from(alticon))
}
pub fn icons_are_templates(self, icons_are_templates: bool) -> Self {
self.set("iconsAreTemplates", JsValue::from(icons_are_templates))
}
pub fn menu(mut self, menu: Menu) -> Self {
self.menu = Some(menu);
self
}
pub fn callback<F>(mut self, callback: F) -> Self
where
F: FnMut(MouseEvent) -> std::result::Result<(), JsValue> + 'static,
{
self.callback = Some(Callback::new(callback));
self
}
pub fn submenus(self, items: Vec<MenuItem>) -> Self {
let submenu = nw_sys::Menu::new();
for menu_item in items {
submenu.append(&menu_item);
}
self.menu(submenu)
}
pub fn build_impl(self) -> Result<(Tray, Option<Callback<CallbackClosure<MouseEvent>>>)> {
let tray = Tray::new(&self.options);
if let Some(menu) = self.menu {
tray.set_menu(&menu);
}
if let Some(tooltip) = self.tooltip {
tray.set_tooltip(&tooltip);
}
if let Some(callback) = self.callback {
tray.on("click", callback.as_ref());
Ok((tray, Some(callback)))
} else {
Ok((tray, None))
}
}
pub fn build(self) -> Result<Tray> {
let (tray, callback) = self.build_impl()?;
if let Some(callback) = callback {
let app = match app() {
Some(app) => app,
None => return Err("app is not initialized".to_string().into()),
};
app.callbacks.retain(callback)?;
}
Ok(tray)
}
pub fn finalize(self) -> Result<(Tray, Option<Callback<CallbackClosure<MouseEvent>>>)> {
let (tray, callback) = self.build_impl()?;
Ok((tray, callback))
}
}