diff --git a/README.md b/README.md index 08ccabe..e59f7e9 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,29 @@ if let Ok(event) = MenuEvent::receiver().try_recv() { } ``` +### Note for [winit] or [tao] users: + +You should use [`MenuEvent::set_event_handler`] and forward +the menu events to the event loop by using [`EventLoopProxy`] +so that the event loop is awakened on each menu event. + +```rust +enum UserEvent { + MenuEvent(muda::MenuEvent) +} + +let event_loop = EventLoop::::with_user_event().build().unwrap(); + +let proxy = event_loop.create_proxy(); +muda::MenuEvent::set_event_handler(Some(move |event| { + proxy.send_event(UserEvent::MenuEvent(event)); +})); +``` + +[`EventLoopProxy`]: https://docs.rs/winit/latest/winit/event_loop/struct.EventLoopProxy.html +[winit]: https://docs.rs/winit +[tao]: https://docs.rs/tao + ## License Apache-2.0/MIT diff --git a/examples/tao.rs b/examples/tao.rs index 465a524..afa95f6 100644 --- a/examples/tao.rs +++ b/examples/tao.rs @@ -21,11 +21,16 @@ use tao::{ window::{Window, WindowBuilder}, }; +enum UserEvent { + MenuEvent(muda::MenuEvent), +} + fn main() { - let mut event_loop_builder = EventLoopBuilder::new(); + let mut event_loop_builder = EventLoopBuilder::::with_user_event(); let menu_bar = Menu::new(); + // setup accelerator handler on Windows #[cfg(target_os = "windows")] { let menu_bar = menu_bar.clone(); @@ -41,6 +46,12 @@ fn main() { let event_loop = event_loop_builder.build(); + // set a menu event handler that wakes up the event loop + let proxy = event_loop.create_proxy(); + muda::MenuEvent::set_event_handler(Some(move |event| { + proxy.send_event(UserEvent::MenuEvent(event)); + })); + let window = WindowBuilder::new() .with_title("Window 1") .build(&event_loop) @@ -201,19 +212,14 @@ fn main() { Event::MainEventsCleared => { window.request_redraw(); } - _ => (), - } - if let Ok(event) = menu_channel.try_recv() { - if event.id == custom_i_1.id() { - custom_i_1 - .set_accelerator(Some(Accelerator::new(Some(Modifiers::SHIFT), Code::KeyF))); - file_m.insert( - &MenuItem::with_id("new-menu-id", "New Menu Item", true, None), - 2, - ); + Event::UserEvent(UserEvent::MenuEvent(event)) => { + if event.id == custom_i_1.id() { + file_m.insert(&MenuItem::new("New Menu Item", true, None), 2); + } + println!("{event:?}"); } - println!("{event:?}"); + _ => (), } }) } diff --git a/examples/winit.rs b/examples/winit.rs index 2b82d72..5914c00 100644 --- a/examples/winit.rs +++ b/examples/winit.rs @@ -19,11 +19,16 @@ use winit::{ window::{Window, WindowBuilder}, }; +enum UserEvent { + MenuEvent(muda::MenuEvent), +} + fn main() { - let mut event_loop_builder = EventLoopBuilder::new(); + let mut event_loop_builder = EventLoopBuilder::::with_user_event(); let menu_bar = Menu::new(); + // setup accelerator handler on Windows #[cfg(target_os = "windows")] { let menu_bar = menu_bar.clone(); @@ -41,6 +46,12 @@ fn main() { let event_loop = event_loop_builder.build().unwrap(); + // set a menu event handler that wakes up the event loop + let proxy = event_loop.create_proxy(); + muda::MenuEvent::set_event_handler(Some(move |event| { + proxy.send_event(UserEvent::MenuEvent(event)); + })); + let window = WindowBuilder::new() .with_title("Window 1") .build(&event_loop) @@ -188,14 +199,14 @@ fn main() { ); use_window_pos = !use_window_pos; } - _ => (), - } - if let Ok(event) = menu_channel.try_recv() { - if event.id == custom_i_1.id() { - file_m.insert(&MenuItem::new("New Menu Item", true, None), 2); + Event::UserEvent(UserEvent::MenuEvent(event)) => { + if event.id == custom_i_1.id() { + file_m.insert(&MenuItem::new("New Menu Item", true, None), 2); + } + println!("{event:?}"); } - println!("{event:?}"); + _ => (), } }); } diff --git a/examples/wry.rs b/examples/wry.rs index e2b05ce..c2ed00f 100644 --- a/examples/wry.rs +++ b/examples/wry.rs @@ -26,11 +26,16 @@ use tao::{ use wry::WebViewBuilderExtUnix; use wry::{http::Request, WebViewBuilder}; +enum UserEvent { + MenuEvent(muda::MenuEvent), +} + fn main() -> wry::Result<()> { - let mut event_loop_builder = EventLoopBuilder::new(); + let mut event_loop_builder = EventLoopBuilder::::with_user_event(); let menu_bar = Menu::new(); + // setup accelerator handler on Windows #[cfg(target_os = "windows")] { let menu_bar = menu_bar.clone(); @@ -46,6 +51,12 @@ fn main() -> wry::Result<()> { let event_loop = event_loop_builder.build(); + // set a menu event handler that wakes up the event loop + let proxy = event_loop.create_proxy(); + muda::MenuEvent::set_event_handler(Some(move |event| { + proxy.send_event(UserEvent::MenuEvent(event)); + })); + let window = WindowBuilder::new() .with_title("Window 1") .build(&event_loop) @@ -281,24 +292,19 @@ fn main() -> wry::Result<()> { event_loop.run(move |event, _, control_flow| { *control_flow = ControlFlow::Wait; - if let Event::WindowEvent { - event: WindowEvent::CloseRequested, - .. - } = event - { - *control_flow = ControlFlow::Exit; - } + match event { + Event::WindowEvent { + event: WindowEvent::CloseRequested, + .. + } => *control_flow = ControlFlow::Exit, - if let Ok(event) = menu_channel.try_recv() { - if event.id == custom_i_1.id() { - custom_i_1 - .set_accelerator(Some(Accelerator::new(Some(Modifiers::SHIFT), Code::KeyF))) - .unwrap(); - file_m - .insert(&MenuItem::new("New Menu Item", true, None), 2) - .unwrap(); + Event::UserEvent(UserEvent::MenuEvent(event)) => { + if event.id == custom_i_1.id() { + file_m.insert(&MenuItem::new("New Menu Item", true, None), 2); + } + println!("{event:?}"); } - println!("{event:?}"); + _ => {} } }) } diff --git a/src/lib.rs b/src/lib.rs index d0a9177..667667c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -128,6 +128,30 @@ //! } //! } //! ``` +//! +//! ### Note for [winit] or [tao] users: +//! +//! You should use [`MenuEvent::set_event_handler`] and forward +//! the menu events to the event loop by using [`EventLoopProxy`] +//! so that the event loop is awakened on each menu event. +//! +//! ```no_run +//! # use winit::event_loop::EventLoop; +//! enum UserEvent { +//! MenuEvent(muda::MenuEvent) +//! } +//! +//! let event_loop = EventLoop::::with_user_event().build().unwrap(); +//! +//! let proxy = event_loop.create_proxy(); +//! muda::MenuEvent::set_event_handler(Some(move |event| { +//! proxy.send_event(UserEvent::MenuEvent(event)); +//! })); +//! ``` +//! +//! [`EventLoopProxy`]: https://docs.rs/winit/latest/winit/event_loop/struct.EventLoopProxy.html +//! [winit]: https://docs.rs/winit +//! [tao]: https://docs.rs/tao use crossbeam_channel::{unbounded, Receiver, Sender}; use once_cell::sync::{Lazy, OnceCell};