menubar — u_pbt_menubar #
← Component reference · Guide contents
Application menu bar: menus, submenus, checkable items, separators, icons and shortcuts — all drawn by the library, with no Windows menu involved.
▶ See it live — Demo application, Menu bar tile: the preview, the code behind it and this page, side by side.
At a glance #
| Userobject | u_pbt_menubar |
| Item class | n_pbt_menubar_item (one item) |
| Used for | Giving your window the application menu bar, themed like everything else |
| Principle | You declare the menus, then their items; every item is found again by its address menu/id |
Quick start #
// window open event
uo_menus.of_add_menu(/*key*/ "file", /*text*/ "File")
uo_menus.of_add_item(/*keys*/ "file/open", /*text*/ "Open")
uo_menus.of_add_item(/*keys*/ "file/save", /*text*/ "Save")
// event ue_item_selected : (string as_keys)
choose case as_keys
case "open"; of_ouvrir()
case "save"; of_enregistrer()
end choose
The model: three levels, one key per level #
A menu bar has three levels, and each is addressed by its key:
| Level | Added by | Key |
|---|---|---|
| The menu on the bar | of_add_menu | its id |
| The item of a menu | of_add_item | the address menu/id |
| The sub-item of an item | of_add_item | the address menu/item/sub-item — three levels |
An item id is unique within its menu only: that is why of_item asks for two. Two menus can therefore each have their own "open" item without clashing.
A separator has no key:
of_add_separatordraws a line where you call it, and there is nothing to read back afterwards.
Properties #
| Property | Type | Default | Role |
|---|---|---|---|
is_theme_style | string | fluent | Visual style of the component (THEME_STYLE_* constants) |
is_theme_mode | string | light | Light or dark variant (THEME_MODE_* constants) |
il_theme_accent | long | -1 | Accent colour of this component (-1 = the theme's accent) |
is_tooltip | string | "" | Plain tooltip shown when hovering the component |
is_super_tooltip_title | string | "" | Title of the rich tooltip (takes precedence over is_tooltip) |
is_super_tooltip_text | string | "" | Body of the rich tooltip (rich markup accepted) |
is_super_tooltip_image | string | "" | Image of the rich tooltip |
Item properties — n_pbt_menubar_item #
Obtained through of_item(menu/id):
| Property | Type | Default | Role |
|---|---|---|---|
is_text | string | — | Changes the item's label, live |
ib_enabled | boolean | true | Item is active; a greyed item no longer answers clicks |
ib_visible | boolean | true | Entry taken out of the list without being removed — submenu and shortcut asleep with it; it keeps its key and comes back as it was |
is_shortcut | string | "" | The accelerator displayed at the right of the item (Ctrl+S) — and armed: the chord raises ue_item_selected for that item wherever the focus is. A menu is where people learn the shortcuts of an application; a key shown that does nothing teaches the wrong thing. An empty string takes both away |
ib_checked | boolean | false | Check mark in front of the item — for an option that goes on and off |
is_tooltip | string | "" | Tooltip of this item |
is_super_tooltip_title | string | "" | Title of its rich tooltip |
is_super_tooltip_text | string | "" | Body of its rich tooltip (rich markup accepted) |
is_super_tooltip_image | string | "" | Image of its rich tooltip |
Methods #
| Method | Role |
|---|---|
of_add_menu (string as_key, string as_text) | Adds a menu to the bar. Returns 0 once applied, -2 when the component is not created |
of_add_item (string as_keys, string as_text) | Adds an item to a menu. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_add_item (string as_keys, string as_text, string as_image, boolean ab_checked) | The same, with the icon, the check mark and the initial state. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_add_separator (string as_keys) | Draws a separating line at the end of the menu so far. Returns 0 once applied, -2 when the component is not created |
of_item (string as_keys) → n_pbt_menubar_item | Handle of an item, to set its properties. as_key takes both spellings: the bare leaf id, and the full path with its keys joined by / — of_item("file", "export/pdf"). The path is what ue_item_selected hands back: its two arguments go straight back in here. A bare leaf id is only unique inside its own submenu — two Export submenus may each hold a pdf, and only the path tells them apart |
of_menu (string as_key) → n_pbt_menubar_menu | Handle of a top-level menu, to rename it or grey it out. of_add_menu could only do it at creation: greying Admin when the user logs out meant rebuilding the whole bar; ib_visible takes it out of the bar, entries and shortcuts asleep with it |
of_remove_item (string as_keys) → long | Removes one item; the others stay. as_key takes both spellings of of_item: the full path (export/pdf) or the bare leaf id. Without it there was only of_clear, which empties everything — the commonest dynamic menu of all, a recent files list, meant razing the whole bar on every document opened. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_remove_menu (string as_key) → long | Removes a top-level menu, its items with it. The bar is redrawn and its height re-announced. Returns 0 once applied, -2 when the component is not created |
of_clear ( ) | Empties the bar — menus and items. Returns 0 once applied, -2 when the component is not created |
of_reset ( ) | Empties the bar and puts every property back to its default. Returns 0 once applied, -2 when the component is not created |
of_set_redraw (boolean) | Groups a burst of changes into a single render. Returns 0 once applied, -2 when the component is not created |
of_save_as_png (string) · of_save_as_jpg (string) | Exports the rendering as an image. Returns 0 once the image is written, -4 when writing fails, -2 when the component is not created |
Events #
| Event | Raised when |
|---|---|
ue_menu_opening (string as_key) | Raised the instant a top-level menu is clicked, before its dropdown is built. This is the moment to enable, grey or fill its items just in time — without it the whole bar had to be kept in step with the application state at all times, or show items that lie |
ue_item_selected (string as_keys) | The user picked an item. as_key is a path as soon as the entry is nested — export/pdf, not pdf: the leaf alone does not say which submenu it came out of, and two submenus may each hold their own. A top-level entry keeps its bare id. That same string can be handed straight back to of_item |
ue_auto_height (long al_height) | The bar announces the height it needs — move whatever sits below it |
ue_ready ( ) | The component has finished loading; everything sent before was replayed |
ue_runtime_missing ( ) | The WebView2 runtime is missing: the component stays empty |
ue_bg_color (long al_color) | The component computed its theme background; the userobject already adopted it (backcolor) |
The height is not set, it is announced. A menu bar does not scroll: a fixed height can only produce empty space under the bar or truncated menus. It always fits itself, and
ue_auto_heighttells you by how much.
From the keyboard #
| Key | Effect |
|---|---|
| Alt | Gives the focus to the bar, as in any Windows application |
| Arrows | Walk the menus and their items; right opens a sub-item, left goes back up |
| Enter or Space | Picks the focused item (ue_item_selected) |
| Escape | Closes the open menu, then hands the focus back |
Examples #
A complete menu bar #
uo_menus.of_set_redraw(false)
// The File menu, with an icon on Open and a line before Quit
uo_menus.of_add_menu(/*key*/ "file", /*text*/ "F")
uo_menus.of_add_item(/*keys*/ "file/open", /*text*/ "O", /*image*/ "mono:img\packimages.dll:svg/samples/folder-open", /*checked*/ false)
uo_menus.of_add_separator(/*keys*/ "file")
uo_menus.of_add_item(/*keys*/ "file/quit", /*text*/ "Q")
// A submenu: Export, then its two formats
uo_menus.of_add_item(/*keys*/ "file/export", /*text*/ "E")
uo_menus.of_add_item(/*keys*/ "file/export/csv", /*text*/ "CSV")
uo_menus.of_add_item(/*keys*/ "file/export/pdf", /*text*/ "PDF")
// The View menu: an option that checks
uo_menus.of_add_menu(/*key*/ "view", /*text*/ "V")
uo_menus.of_add_item(/*keys*/ "view/grid", /*text*/ "G", /*image*/ "", /*checked*/ true)
uo_menus.of_set_redraw(true)
Check, uncheck, grey out #
// The user toggled the grid display
uo_menus.of_item(/*keys*/ "view/grid").ib_checked = not uo_menus.of_item(/*keys*/ "view/grid").ib_checked
// An item that no longer applies is greyed, not removed:
// the user has to be able to see that it exists
uo_menus.of_item(/*keys*/ "file/save").ib_enabled = false
Rebuilding the bar #
// Switching workspace: empty, then fill again
// of_set_redraw avoids repainting on every line
uo_menus.of_set_redraw(false)
uo_menus.of_clear()
uo_menus.of_add_menu(/*key*/ "tools", /*text*/ "T")
uo_menus.of_set_redraw(true)
Best practices #
- Give every item a stable business id (
"save"): that is what you get inue_item_selected, not a label that changes with the language. - Grey out rather than remove: a missing item leaves the user searching, a greyed one tells them it exists and that something is missing.
- Wrap the build in
of_set_redraw(false)/of_set_redraw(true): a complete bar is thirty calls in no time. - Move whatever sits under the bar in
ue_auto_height— the height depends on the theme and the font size, it is not the same everywhere. - For the labels, go through
of_set_translationif your application is multilingual: see the language chapter.
Inherited from the common base #
These members exist on every visual component — they are not specific to this one. They are detailed once, in the transverse chapters; this table only says where to read them.
| Members | Role | Detailed in |
|---|---|---|
of_count · of_keys_at · of_has | Walk what the component holds | 3.2 Items |
of_reset | Put the component back to zero | 3.6 Resetting a component: of_reset() |
of_register_shortcut · of_clear_shortcuts | The component's keyboard chords | 3.5 Keyboard shortcuts |
of_is_created · of_is_ready · of_get_last_error | Whether it was born, whether it is ready, what failed | 3.7 Diagnostics |
of_save_as_png · of_save_as_jpg | Export the rendering as an image | 3.8 Exporting the rendering as an image |
of_set_redraw | Group changes into a single repaint | 3.10 Best practices |
of_preload_icons | Icons shown with no delay | Instant display: of_icon |
of_set_translation | Translate one of the component's labels | 5.2 Adapting a label: of_set_translation |
of_focus_webview | Give the component the focus | 6.4 Keyboard and focus |
of_print · of_print_to_pdf | Print, or write a PDF | 6.9 Printing |
Two helpers are not inherited: of_icon and of_escape_markup live on n_pbt_utils. Declare one — n_pbt_utils lnv_utils, nothing to create — and call them on it.