mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-09-10 23:45:46 +03:00
parent
b231f4c2e5
commit
c8065744d0
5
.changes/menu-item-builder-generics.md
Normal file
5
.changes/menu-item-builder-generics.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri": "patch:breaking"
|
||||
---
|
||||
|
||||
Added `<R: Runtime>` generic on `MenuItemBuilder`, `CheckMenuItemBuilder` and `IconMenuItemBuilder` and removed ite from `build` method.
|
6
.changes/menu-item-builders-handler.md
Normal file
6
.changes/menu-item-builders-handler.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri": "patch:feat"
|
||||
---
|
||||
|
||||
Add `handler` method on `MenuItemBuilder`, `CheckMenuItemBuilder` and `IconMenuItemBuilder`.
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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> {
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
@ -25,6 +29,7 @@ impl CheckMenuItemBuilder {
|
||||
enabled: true,
|
||||
checked: true,
|
||||
accelerator: None,
|
||||
handler: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,6 +44,7 @@ impl CheckMenuItemBuilder {
|
||||
enabled: true,
|
||||
checked: true,
|
||||
accelerator: None,
|
||||
handler: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,9 +72,18 @@ 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,
|
||||
@ -76,7 +91,7 @@ impl CheckMenuItemBuilder {
|
||||
self.enabled,
|
||||
self.checked,
|
||||
self.accelerator,
|
||||
)
|
||||
)?
|
||||
} else {
|
||||
CheckMenuItem::new(
|
||||
manager,
|
||||
@ -84,7 +99,21 @@ impl CheckMenuItemBuilder {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
@ -31,6 +32,7 @@ impl<'a> IconMenuItemBuilder<'a> {
|
||||
icon: None,
|
||||
native_icon: None,
|
||||
accelerator: None,
|
||||
handler: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,6 +48,7 @@ impl<'a> IconMenuItemBuilder<'a> {
|
||||
icon: None,
|
||||
native_icon: None,
|
||||
accelerator: None,
|
||||
handler: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
@ -98,7 +110,7 @@ impl<'a> IconMenuItemBuilder<'a> {
|
||||
self.enabled,
|
||||
self.icon,
|
||||
self.accelerator,
|
||||
)
|
||||
)?
|
||||
} else {
|
||||
IconMenuItem::new(
|
||||
manager,
|
||||
@ -106,7 +118,7 @@ impl<'a> IconMenuItemBuilder<'a> {
|
||||
self.enabled,
|
||||
self.icon,
|
||||
self.accelerator,
|
||||
)
|
||||
)?
|
||||
}
|
||||
} else if let Some(id) = self.id {
|
||||
IconMenuItem::with_id_and_native_icon(
|
||||
@ -116,7 +128,7 @@ impl<'a> IconMenuItemBuilder<'a> {
|
||||
self.enabled,
|
||||
self.native_icon,
|
||||
self.accelerator,
|
||||
)
|
||||
)?
|
||||
} else {
|
||||
IconMenuItem::with_native_icon(
|
||||
manager,
|
||||
@ -124,7 +136,21 @@ impl<'a> IconMenuItemBuilder<'a> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
@ -23,6 +27,7 @@ impl MenuItemBuilder {
|
||||
text: text.as_ref().to_string(),
|
||||
enabled: true,
|
||||
accelerator: None,
|
||||
handler: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +41,7 @@ impl MenuItemBuilder {
|
||||
text: text.as_ref().to_string(),
|
||||
enabled: true,
|
||||
accelerator: None,
|
||||
handler: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user