Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add handler method on menu item builders #9380

Draft
wants to merge 1 commit into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/menu-item-builder-generics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri": "patch:breaking"
---

Added `<R: Runtime>` generic on `MenuItemBuilder`, `CheckMenuItemBuilder` and `IconMenuItemBuilder` and removed ite from `build` method.
6 changes: 6 additions & 0 deletions .changes/menu-item-builders-handler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri": "patch:feat"
---

Add `handler` method on `MenuItemBuilder`, `CheckMenuItemBuilder` and `IconMenuItemBuilder`.

8 changes: 7 additions & 1 deletion core/tauri/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1860,7 +1860,13 @@ fn on_event_loop_event<R: Runtime>(
{
listener(app_handle, e.clone());
}
for (label, listener) in &*app_handle.manager.menu.event_listeners.lock().unwrap() {
for (label, listener) in &*app_handle
.manager
.menu
.window_event_listeners
.lock()
.unwrap()
{
if let Some(w) = app_handle.manager().get_window(label) {
listener(&w, e.clone());
}
Expand Down
18 changes: 17 additions & 1 deletion core/tauri/src/manager/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ pub struct MenuManager<R: Runtime> {
/// Menu event listeners to all windows.
pub global_event_listeners: Mutex<Vec<crate::app::GlobalMenuEventListener<AppHandle<R>>>>,
/// Menu event listeners to specific windows.
pub event_listeners: Mutex<HashMap<String, crate::app::GlobalMenuEventListener<Window<R>>>>,
pub window_event_listeners:
Mutex<HashMap<String, crate::app::GlobalMenuEventListener<Window<R>>>>,
/// Menu event listeners to specific windows.
pub item_event_listeners:
Mutex<HashMap<MenuId, crate::app::GlobalMenuEventListener<AppHandle<R>>>>,
}

impl<R: Runtime> MenuManager<R> {
Expand Down Expand Up @@ -95,4 +99,16 @@ impl<R: Runtime> MenuManager<R> {
.unwrap()
.push(Box::new(handler));
}

pub fn on_menu_item_event<F: Fn(&AppHandle<R>, MenuEvent) + Send + Sync + 'static>(
&self,
id: MenuId,
handler: F,
) {
self
.item_event_listeners
.lock()
.unwrap()
.insert(id, Box::new(handler));
}
}
3 changes: 2 additions & 1 deletion core/tauri/src/manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,8 @@ impl<R: Runtime> AppManager<R> {
menus: Default::default(),
menu: Default::default(),
global_event_listeners: Default::default(),
event_listeners: Mutex::new(window_menu_event_listeners),
window_event_listeners: Mutex::new(window_menu_event_listeners),
item_event_listeners: Default::default(),
},
plugins: Mutex::new(plugins),
listeners: Listeners::default(),
Expand Down
45 changes: 37 additions & 8 deletions core/tauri/src/menu/builders/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use crate::{menu::CheckMenuItem, menu::MenuId, Manager, Runtime};
use crate::{
menu::{CheckMenuItem, MenuEvent, MenuId},
Manager, Runtime,
};

/// A builder type for [`CheckMenuItem`]
pub struct CheckMenuItemBuilder {
pub struct CheckMenuItemBuilder<R: Runtime> {
id: Option<MenuId>,
text: String,
enabled: bool,
checked: bool,
accelerator: Option<String>,
handler: Option<Box<dyn Fn(&CheckMenuItem<R>, MenuEvent) + Send + Sync + 'static>>,
}

impl CheckMenuItemBuilder {
impl<R: Runtime> CheckMenuItemBuilder<R> {
/// Create a new menu item builder.
///
/// - `text` could optionally contain an `&` before a character to assign this character as the mnemonic
Expand All @@ -25,6 +29,7 @@ impl CheckMenuItemBuilder {
enabled: true,
checked: true,
accelerator: None,
handler: None,
}
}

Expand All @@ -39,6 +44,7 @@ impl CheckMenuItemBuilder {
enabled: true,
checked: true,
accelerator: None,
handler: None,
}
}

Expand Down Expand Up @@ -66,25 +72,48 @@ impl CheckMenuItemBuilder {
self
}

/// Set a handler to be called when this item is activated.
pub fn handler<F: Fn(&CheckMenuItem<R>, MenuEvent) + Send + Sync + 'static>(
mut self,
handler: F,
) -> Self {
self.handler.replace(Box::new(handler));
self
}

/// Build the menu item
pub fn build<R: Runtime, M: Manager<R>>(self, manager: &M) -> crate::Result<CheckMenuItem<R>> {
if let Some(id) = self.id {
pub fn build<M: Manager<R>>(self, manager: &M) -> crate::Result<CheckMenuItem<R>> {
let i = if let Some(id) = self.id {
CheckMenuItem::with_id(
manager,
id,
self.text,
self.enabled,
self.checked,
self.accelerator,
)
)?
} else {
CheckMenuItem::new(
manager,
self.text,
self.enabled,
self.checked,
self.accelerator,
)
}
)?
};

if let Some(handler) = self.handler {
let i = i.clone();
manager
.manager()
.menu
.on_menu_item_event(i.id().clone(), move |_app, e| {
if e.id == i.id() {
handler(&i, e)
}
});
};

Ok(i)
}
}
46 changes: 36 additions & 10 deletions core/tauri/src/menu/builders/icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@

use crate::{
image::Image,
menu::{IconMenuItem, MenuId, NativeIcon},
menu::{IconMenuItem, MenuEvent, MenuId, NativeIcon},
Manager, Runtime,
};

/// A builder type for [`IconMenuItem`]
pub struct IconMenuItemBuilder<'a> {
pub struct IconMenuItemBuilder<'a, R: Runtime> {
id: Option<MenuId>,
text: String,
enabled: bool,
icon: Option<Image<'a>>,
native_icon: Option<NativeIcon>,
accelerator: Option<String>,
handler: Option<Box<dyn Fn(&IconMenuItem<R>, MenuEvent) + Send + Sync + 'static>>,
}

impl<'a> IconMenuItemBuilder<'a> {
impl<'a, R: Runtime> IconMenuItemBuilder<'a, R> {
/// Create a new menu item builder.
///
/// - `text` could optionally contain an `&` before a character to assign this character as the mnemonic
Expand All @@ -31,6 +32,7 @@ impl<'a> IconMenuItemBuilder<'a> {
icon: None,
native_icon: None,
accelerator: None,
handler: None,
}
}

Expand All @@ -46,6 +48,7 @@ impl<'a> IconMenuItemBuilder<'a> {
icon: None,
native_icon: None,
accelerator: None,
handler: None,
}
}

Expand Down Expand Up @@ -87,9 +90,18 @@ impl<'a> IconMenuItemBuilder<'a> {
self
}

/// Set a handler to be called when this item is activated.
pub fn handler<F: Fn(&IconMenuItem<R>, MenuEvent) + Send + Sync + 'static>(
mut self,
handler: F,
) -> Self {
self.handler.replace(Box::new(handler));
self
}

/// Build the menu item
pub fn build<R: Runtime, M: Manager<R>>(self, manager: &M) -> crate::Result<IconMenuItem<R>> {
if self.icon.is_some() {
pub fn build<M: Manager<R>>(self, manager: &M) -> crate::Result<IconMenuItem<R>> {
let i = if self.icon.is_some() {
if let Some(id) = self.id {
IconMenuItem::with_id(
manager,
Expand All @@ -98,15 +110,15 @@ impl<'a> IconMenuItemBuilder<'a> {
self.enabled,
self.icon,
self.accelerator,
)
)?
} else {
IconMenuItem::new(
manager,
self.text,
self.enabled,
self.icon,
self.accelerator,
)
)?
}
} else if let Some(id) = self.id {
IconMenuItem::with_id_and_native_icon(
Expand All @@ -116,15 +128,29 @@ impl<'a> IconMenuItemBuilder<'a> {
self.enabled,
self.native_icon,
self.accelerator,
)
)?
} else {
IconMenuItem::with_native_icon(
manager,
self.text,
self.enabled,
self.native_icon,
self.accelerator,
)
}
)?
};

if let Some(handler) = self.handler {
let i = i.clone();
manager
.manager()
.menu
.on_menu_item_event(i.id().clone(), move |_app, e| {
if e.id == i.id() {
handler(&i, e)
}
});
};

Ok(i)
}
}
45 changes: 37 additions & 8 deletions core/tauri/src/menu/builders/normal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use crate::{menu::MenuId, menu::MenuItem, Manager, Runtime};
use crate::{
menu::{MenuEvent, MenuId, MenuItem},
Manager, Runtime,
};

/// A builder type for [`MenuItem`]
pub struct MenuItemBuilder {
pub struct MenuItemBuilder<R: Runtime> {
id: Option<MenuId>,
text: String,
enabled: bool,
accelerator: Option<String>,
handler: Option<Box<dyn Fn(&MenuItem<R>, MenuEvent) + Send + Sync + 'static>>,
}

impl MenuItemBuilder {
impl<R: Runtime> MenuItemBuilder<R> {
/// Create a new menu item builder.
///
/// - `text` could optionally contain an `&` before a character to assign this character as the mnemonic
Expand All @@ -23,6 +27,7 @@ impl MenuItemBuilder {
text: text.as_ref().to_string(),
enabled: true,
accelerator: None,
handler: None,
}
}

Expand All @@ -36,6 +41,7 @@ impl MenuItemBuilder {
text: text.as_ref().to_string(),
enabled: true,
accelerator: None,
handler: None,
}
}

Expand All @@ -57,12 +63,35 @@ impl MenuItemBuilder {
self
}

/// Set a handler to be called when this item is activated.
pub fn handler<F: Fn(&MenuItem<R>, MenuEvent) + Send + Sync + 'static>(
mut self,
handler: F,
) -> Self {
self.handler.replace(Box::new(handler));
self
}

/// Build the menu item
pub fn build<R: Runtime, M: Manager<R>>(self, manager: &M) -> crate::Result<MenuItem<R>> {
if let Some(id) = self.id {
MenuItem::with_id(manager, id, self.text, self.enabled, self.accelerator)
pub fn build<M: Manager<R>>(self, manager: &M) -> crate::Result<MenuItem<R>> {
let i = if let Some(id) = self.id {
MenuItem::with_id(manager, id, self.text, self.enabled, self.accelerator)?
} else {
MenuItem::new(manager, self.text, self.enabled, self.accelerator)
}
MenuItem::new(manager, self.text, self.enabled, self.accelerator)?
};

if let Some(handler) = self.handler {
let i = i.clone();
manager
.manager()
.menu
.on_menu_item_event(i.id().clone(), move |_app, e| {
if e.id == i.id() {
handler(&i, e)
}
});
};

Ok(i)
}
}
2 changes: 1 addition & 1 deletion core/tauri/src/window/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1105,7 +1105,7 @@ tauri::Builder::default()
self
.manager
.menu
.event_listeners
.window_event_listeners
.lock()
.unwrap()
.insert(self.label().to_string(), Box::new(f));
Expand Down