Module druid::menu

source ·
Expand description

Window, application, and context menus

Menus in Druid follow a data-driven design similar to that of the main widget tree. The main types are Menu (representing a tree of menus and submenus) and MenuItem (representing a single “leaf” element).

Menu items can be associated with callbacks, which are triggered when a user selects that menu item. Each callback has access to the application data, and also gets access to a MenuEventCtx, which allows for submitting Commands.

Refreshing and rebuilding

Menus, like widgets, update themselves based on changes in the data. There are two different ways that the menus update themselves:

  • a “refresh” is when the menu items update their text or their status (e.g. disabled, selected) based on changes to the data. Menu refreshes are handled for you automatically. For example, if you create a menu item whose title is a LabelText::Dynamic then that title will be kept up-to-date for you.

    The limitation of a “refresh” is that it cannot change the structure of the menus (e.g. by adding new items or moving things around).

  • a “rebuild” is when the menu is rebuilt from scratch. When you first set a menu (e.g. using WindowDesc::menu), you provide a callback for building the menu from data; a rebuild is when the menu decides to rebuild itself by invoking that callback again.

    Rebuilds have none of the limitations of refreshes, but Druid does not automatically decide when to do them. You need to use Menu::rebuild_on to decide when rebuild should occur.

The macOS app menu

On macOS, the main menu belongs to the application, not to the window.

In Druid, whichever window is frontmost will have its menu displayed as the application menu.

Examples

Creating the default app menu for macOS:

use druid::commands;
use druid::{Data, LocalizedString, Menu, MenuItem, SysMods};

fn macos_application_menu<T: Data>() -> Menu<T> {
    Menu::new(LocalizedString::new("macos-menu-application-menu"))
        .entry(
            MenuItem::new(LocalizedString::new("macos-menu-about-app"))
                // You need to handle the SHOW_ABOUT command yourself (or else do something
                // directly to the data here instead of using a command).
                .command(commands::SHOW_ABOUT),
        )
        .separator()
        .entry(
            MenuItem::new(LocalizedString::new("macos-menu-preferences"))
                // You need to handle the SHOW_PREFERENCES command yourself (or else do something
                // directly to the data here instead of using a command).
                .command(commands::SHOW_PREFERENCES)
                .hotkey(SysMods::Cmd, ","),
        )
        .separator()
        .entry(MenuItem::new(LocalizedString::new("macos-menu-services")))
        .entry(
            MenuItem::new(LocalizedString::new("macos-menu-hide-app"))
                // Druid handles the HIDE_APPLICATION command automatically
                .command(commands::HIDE_APPLICATION)
                .hotkey(SysMods::Cmd, "h"),
        )
        .entry(
            MenuItem::new(LocalizedString::new("macos-menu-hide-others"))
                // Druid handles the HIDE_OTHERS command automatically
                .command(commands::HIDE_OTHERS)
                .hotkey(SysMods::AltCmd, "h"),
        )
        .entry(
            MenuItem::new(LocalizedString::new("macos-menu-show-all"))
                // You need to handle the SHOW_ALL command yourself (or else do something
                // directly to the data here instead of using a command).
                .command(commands::SHOW_ALL)
        )
        .separator()
        .entry(
            MenuItem::new(LocalizedString::new("macos-menu-quit-app"))
                // Druid handles the QUIT_APP command automatically
                .command(commands::QUIT_APP)
                .hotkey(SysMods::Cmd, "q"),
        )
}

Modules

  • Pre-configured, platform appropriate menus and menu items.

Structs

  • A menu.
  • An entry in a menu.
  • This context is available to the callback that is called when a menu item is activated.
  • An item in a menu.
  • A wrapper for a menu item (or submenu) to give it access to a part of its parent data.