Context menus
UIToolbox.Core.ContextMenu has a general popup menu. ToolBarMenu uses it for its drop-downs.
| Type | Members |
|---|---|
ContextMenuComponent |
AddItem(MenuItem), AddItem(text, callback, shortcut), AddCheckableItem(text, toggled, isChecked), AddRadioItem(text, group, callback, isChecked), AddSubmenu(text), AddSeparator(), AddLabel(text), AttachTo(target, context), DetachFrom(target), ShowDropdown(trigger, side, align, context), ShowAt(anchor, worldPosition, context, keepOpenOn), Hide(), IsVisible, Items, Highlight(item), HighlightedItem, Activate(item), ParentMenu, OwnerItem, events ActionTriggered(string action, object? context) and Closed. |
MenuItem |
Text, Action, Callback, Shortcut, Icon, Checkable, Checked, RadioGroup, Destructive, Enabled, EnabledPredicate, CheckedPredicate, Submenu, HasSubmenu, MatchesShortcut(key, modifiers), static TryParseShortcut(text, out key, out modifiers). |
MenuSeparator |
A line between items. |
MenuLabel |
A heading for the items after it. It takes no click and the arrows skip it. |
MenuSide |
Below, Above, Right, Left: the side of the trigger where a dropdown shows. |
MenuAlign |
Start, Center, End: how a dropdown lines up with its trigger. |
AttachTo(target, context)gives an element the menu with one call. The menu shows on a right click, on the Menu key or Shift+F10 while the focus is in the element, and on a long press (LONG_PRESS_MS, 0.5 s) with touch or a pen. One menu can be attached to many elements, each with its owncontext.DetachFrom(target)removes it.ShowDropdown(trigger, side, align)shows the menu next to an element, such as a button. Below or above the trigger,Startputs the left edges in line andEndthe right edges. Right or left of it,Startputs the top edges in line andEndthe bottom edges. The side flips when it has no room. A second call for the same trigger closes the menu, so call it from the click handler of the button.- A menu that a key or
ShowDropdownopened gives the focus back to the element when a key or an item closes it. - A radio item has a
RadioGroupname and a dot for the check mark. A click checks it and unchecks the other items of the menu with the same group. Destructiveshows an item in the danger color. Use it for an item that deletes.- The menu closes on an item click, a click outside it, or Escape.
Callbackruns, thenActionTriggeredfires, after the menu closes. A checkable item flipsCheckedbefore both. - The predicates get the
contextobject fromShowAteach time the menu opens. - An item with children has a submenu, with an arrow. The submenu opens to the right of the menu on hover, click, Right or Enter. It moves to stay inside the workspace. A click on a submenu item closes all the menus.
- Up and Down move the highlight and skip disabled items. Enter or Space runs the highlighted item. Left closes a submenu.
Shortcutis display text, such asCtrl+Shift+U,Alt+WorF1.ContextMenuComponentshows it;ToolBarMenuruns it.TryParseShortcutreads the modifiersCtrl(orCmd),ShiftandAlt, and aKeyCodename, a letter, a digit,Del,Esc,Ins,PgUporPgDn. Case is ignored.- A
&inTextmarks the access key, underlined; in an open menu that key runs the item.AccessKeyhas the key,FormatAccessKey(text, out key)gives the rich text, andKeyChar(keyCode)gives the letter of a key. - In UXML,
MenuItemhastext,action,shortcut,checkable,checked,radio-group,destructiveandenabled. ChildMenuItem,MenuSeparatorandMenuLabelelements go in the submenu. - Outside a workspace the menu shows on the panel root and loads its styles there.
- A gamepad has no button for the context menu. Give the player another way to the same commands, such as a button that calls
ShowDropdown.
using UIToolbox;
using UIToolbox.Core.ContextMenu;
using UIToolbox.Utils;
using UnityEngine.UIElements;
public static class WindowMenu
{
public static void Attach(VisualElement target, WindowDescriptor window)
{
var menu = new ContextMenuComponent();
menu.AddItem(new MenuItem { Text = "Maximize", Action = "maximize",
EnabledPredicate = ctx => !((WindowDescriptor)ctx!).IsMaximized });
menu.AddSeparator();
menu.AddItem(new MenuItem { Text = "Close", Action = "close", Destructive = true });
menu.ActionTriggered += (action, ctx) =>
{
var w = (WindowDescriptor)ctx!;
if (action == "maximize") AsyncRunner.Run(() => w.MaximizeAsync(), "Menu maximize");
if (action == "close") AsyncRunner.Run(() => w.CloseAsync(), "Menu close");
};
// Right click, the Menu key and a long press
menu.AttachTo(target, window);
}
}
A dropdown menu on a button, with a heading and radio items:
var sort = new ContextMenuComponent();
sort.AddLabel("Sort by");
sort.AddRadioItem("Name", "sort", () => SortBy("name"), isChecked: true);
sort.AddRadioItem("Date", "sort", () => SortBy("date"));
var button = new Button { text = "Sort" };
button.clicked += () => sort.ShowDropdown(button, MenuSide.Below, MenuAlign.End);
Styling
| Class | Element |
|---|---|
tb-context-menu |
The menu. |
tb-menu-item |
An item. Parts: __check, __icon, __label, __shortcut, __arrow. |
tb-menu-item--checked |
A checked item: the check mark or the radio dot shows. |
tb-menu-item--highlighted |
The item that Enter runs. |
tb-menu-item--destructive |
An item with Destructive. |
tb-menu-separator |
The line between items. |
tb-menu-label |
A heading. |
The tab strip uses TabContextMenu (close, close others, close to the right, pin, duplicate, move to a new window). You cannot add items to the tab menu today.