Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tauri-apps/muda
Menu Utilities for Desktop Applications in Rust.
https://github.com/tauri-apps/muda
gui menu rust windowing
Last synced: 1 day ago
JSON representation
Menu Utilities for Desktop Applications in Rust.
- Host: GitHub
- URL: https://github.com/tauri-apps/muda
- Owner: tauri-apps
- License: apache-2.0
- Created: 2022-05-05T11:51:19.000Z (over 2 years ago)
- Default Branch: dev
- Last Pushed: 2024-10-12T03:17:47.000Z (2 months ago)
- Last Synced: 2024-10-29T15:44:13.386Z (about 2 months ago)
- Topics: gui, menu, rust, windowing
- Language: Rust
- Homepage:
- Size: 592 KB
- Stars: 257
- Watchers: 12
- Forks: 26
- Open Issues: 14
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
### muda
Menu Utilities library for Desktop Applications.
[![Documentation](https://img.shields.io/docsrs/muda)](https://docs.rs/muda/latest/muda/)
## Platforms supported:
- Windows
- macOS
- Linux (gtk Only)## Platform-specific notes:
- On Windows, accelerators don't work unless the win32 message loop calls
[`TranslateAcceleratorW`](https://docs.rs/windows-sys/latest/windows_sys/Win32/UI/WindowsAndMessaging/fn.TranslateAcceleratorW.html).
See [`Menu::init_for_hwnd`](https://docs.rs/muda/latest/x86_64-pc-windows-msvc/muda/struct.Menu.html#method.init_for_hwnd) for more details### Cargo Features
- `common-controls-v6`: Use `TaskDialogIndirect` API from `ComCtl32.dll` v6 on Windows for showing the predefined `About` menu item dialog.
- `libxdo`: Enables linking to `libxdo` on Linux which is used for the predfined `Copy`, `Cut`, `Paste` and `SelectAll` menu item.
- `serde`: Enables de/serializing the dpi types.## Dependencies (Linux Only)
`gtk` is used for menus and `libxdo` is used to make the predfined `Copy`, `Cut`, `Paste` and `SelectAll` menu items work. Be sure to install following packages before building:
#### Arch Linux / Manjaro:
```sh
pacman -S gtk3 xdotool
```#### Debian / Ubuntu:
```sh
sudo apt install libgtk-3-dev libxdo-dev
```## Example
Create the menu and add your items
```rs
let menu = Menu::new();
let menu_item2 = MenuItem::new("Menu item #2", false, None);
let submenu = Submenu::with_items("Submenu Outer", true,&[
&MenuItem::new("Menu item #1", true, Some(Accelerator::new(Some(Modifiers::ALT), Code::KeyD))),
&PredefinedMenuItem::separator(),
&menu_item2,
&MenuItem::new("Menu item #3", true, None),
&PredefinedMenuItem::separator(),
&Submenu::with_items("Submenu Inner", true,&[
&MenuItem::new("Submenu item #1", true, None),
&PredefinedMenuItem::separator(),
&menu_item2,
])
]);```
Then add your root menu to a Window on Windows and Linux
or use it as your global app menu on macOS```rs
// --snip--
#[cfg(target_os = "windows")]
unsafe { menu.init_for_hwnd(window.hwnd() as isize) };
#[cfg(target_os = "linux")]
menu.init_for_gtk_window(>k_window, Some(&vertical_gtk_box));
#[cfg(target_os = "macos")]
menu.init_for_nsapp();
```## Context menus (Popup menus)
You can also use a [`Menu`] or a [`Submenu`] show a context menu.
```rs
// --snip--
let position = muda::PhysicalPosition { x: 100., y: 120. };
#[cfg(target_os = "windows")]
unsafe { menu.show_context_menu_for_hwnd(window.hwnd() as isize, Some(position.into())) };
#[cfg(target_os = "linux")]
menu.show_context_menu_for_gtk_window(>k_window, Some(position.into()));
#[cfg(target_os = "macos")]
unsafe { menu.show_context_menu_for_nsview(nsview, Some(position.into())) };
```## Processing menu events
You can use `MenuEvent::receiver` to get a reference to the `MenuEventReceiver`
which you can use to listen to events when a menu item is activated```rs
if let Ok(event) = MenuEvent::receiver().try_recv() {
match event.id {
_ if event.id == save_item.id() => {
println!("Save menu item activated");
},
_ => {}
}
}
```### 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