Skip to content

Menu

MenuHandle presents structured menu entries from a view anchor or explicit point.

auto menu = UseMenu();
IconButton(images::more, "More actions")
.With(menu.Anchor())
.OnClick([menu] {
menu.Show({
MenuItem(images::edit, "Edit", Edit),
MenuItem("Move to", {
MenuItem("Archive", Archive),
MenuItem("Favorites", AddToFavorites),
}),
MenuSection{},
MenuItem("Delete", Delete),
});
})

Leaf items contain a callback; parent items contain std::vector<MenuEntry> children. Icons use ImageVariant, including ImageResource, ImageAsset, and VectorAsset. .Enabled(bool) and .Checked(bool) add state without changing entry structure. MenuSection marks a logical boundary; the active theme decides whether and how to draw separators.

Natural width follows the widest entry subject to theme and viewport limits. Set MenuOptions::width only when the application requires a fixed width. MenuStyle owns item padding and height, foreground, indication, separators, surface, shadow, and motion.

An open menu publishes a modal Menu collection and semantic MenuItem children. Checked, disabled, and expanded submenu state is exposed to assistive technology, and compatible entries provide activate or expand actions.

  • UseMenu() -> MenuHandle; Anchor() -> LayerAnchor.
  • Show(std::vector<MenuEntry>, MenuOptions = {}) and ShowAt(Point, ...).
  • MenuItem(label, callback) and icon overloads.
  • MenuItem(label, children) and icon overloads for submenus.
  • Enabled(bool) and Checked(bool).
  • MenuEntry, MenuSection, MenuOptions, MenuStyle, and MenuSeparatorMode.

See Popup for arbitrary anchored content.

The menu takes a snapshot of its ordered entries when shown. Checked(false) opts into a visible unchecked state; omitting Checked means the entry has no check state. A checked entry does not automatically toggle application State. Its callback performs that change, and the next Show builds entries from the new value. IconTint(Color) overrides the theme tint for one item.

Capture command inputs by value when callbacks outlive the event that opens the menu. Use domain identifiers rather than references to a temporary row or a vector element that might move. Dismiss(id) closes the matching root menu and its submenu chain and returns false for a stale request. There is no menu Update operation.

Show needs the handle’s anchor modifier on a mounted View; ShowAt takes a point in window DIPs rather than screen pixels. MenuOptions contains placement, gap (4 DIPs), viewport_margin (8 DIPs), offset, optional width, outside/cancel dismissal (both true), and on_dismiss_request. The request callback handles outside/cancel policy; it is not an action-selection event.

Fields Use
background, foreground, icon_tint Surface, label, and icon colors.
item_indication Hover, press, focus, and disabled visuals.
minimum_width, minimum_item_height Natural menu/item sizing floor.
content_padding, item_padding, item_content_spacing, icon_size Surface inset and row composition.
separator_mode, separator_color, separator_thickness, separator_padding Section/item separator policy and geometry.
shadow, corner_radii, motion Surface outline treatment and optional transitions.

MenuSeparatorMode::BetweenSections respects logical MenuSection markers, BetweenItems separates adjacent items, and None paints none. Do not emulate a separator with a tall empty MenuItem: that adds an action-shaped row instead of a semantic boundary.