#menu #windowing #desktop-applications #utilities #fork #accelerator #events

muda-win

Menu Utilities for Desktop Applications on Windows (fork of tauri-apps/muda)

4 releases

new 0.1.3 Dec 20, 2024
0.1.2 Dec 20, 2024
0.1.1 Dec 19, 2024
0.1.0 Dec 19, 2024

#502 in GUI

Download history

73 downloads per month
Used in tray-icon-win

Apache-2.0 OR MIT

180KB
4K SLoC

muda-win

Menu Utilities library for Desktop Applications on Windows.

This is a personal fork of muda. For general use, please consider using the original.

Documentation

Notes:

Cargo Features

  • common-controls-v6: Use TaskDialogIndirect API from ComCtl32.dll v6 on Windows for showing the predefined About menu item dialog.
  • serde: Enables de/serializing the dpi types.

Example

Create the menu and add your items

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.

// --snip--
unsafe { menu.init_for_hwnd(window.hwnd() as isize) };

Context menus (Popup menus)

You can also use a Menu or a Submenu show a context menu.

// --snip--
let position = muda_win::PhysicalPosition { x: 100., y: 120. };
unsafe { menu.show_context_menu_for_hwnd(window.hwnd() as isize, 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

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.

enum UserEvent {
  MenuEvent(muda::MenuEvent)
}

let event_loop = EventLoop::<UserEvent>::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));
}));

License

MIT APACHE-2.0

Dependencies

~10–18MB
~246K SLoC