toolbar — u_pbt_toolbar #
← Component reference · Guide contents
Flat toolbar: several bars spread over bands, buttons, toggles, drop-down menus, input fields, automatic overflow and drag-by-handle repositioning.
▶ See it live — Demo application, Toolbar tile: the preview, the code behind it and this page, side by side.
At a glance #
| Userobject | u_pbt_toolbar |
| Item classes | n_pbt_toolbar_bar (bar) → n_pbt_toolbar_item (tool) → n_pbt_toolbar_menu_item (menu entry) |
| Used for | Replacing a classic toolbar with a modern, themed one spread over several rearrangeable rows |
| Height | Intrinsic: the bar always fits itself to its rows, nothing to enable — see Automatic height |
Quick start #
// open event of the window
// MAIN_BAR is the default bar, always present : the address starts from it
uo_toolbar.of_add_button(/*keys*/ uo_toolbar.MAIN_BAR + "/save", /*text*/ "", /*image*/ "mono:img\save.svg", /*tooltip*/ "Save")
uo_toolbar.of_add_button(/*keys*/ uo_toolbar.MAIN_BAR + "/find", /*text*/ "", /*image*/ "mono:img\find.svg", /*tooltip*/ "Find")
uo_toolbar.of_add_separator(/*keys*/ uo_toolbar.MAIN_BAR)
uo_toolbar.of_add_button(/*keys*/ uo_toolbar.MAIN_BAR + "/help", /*text*/ "Help", /*image*/ "", /*tooltip*/ "About")
// ue_clicked event of uo_toolbar : (string as_keys)
choose case as_keys
case "main/save" ; of_save()
case "main/find" ; of_find()
case "main/help" ; of_help()
end choose
The model: bars, bands, tools #
A toolbar contains one or more bars. Each bar sits on a band (a row) and occupies a position within that row: two bars on the same band share the row, two bars on different bands stack up — exactly like classic Office toolbars.
Tools (buttons, toggles, menus, fields) belong to a bar. Their identifier is only unique inside their own bar, so access always goes through the full path.
// Gray out a tool, or one entry of its menu
uo_toolbar.of_item(/*keys*/ "main/save").ib_enabled = false
uo_toolbar.of_menu_item(/*keys*/ "main/export/pdf").ib_enabled = false
Everything is done from the component, by addresses: a tool is added at its own (of_add_button("main/save", …)), a menu entry at its own ("main/export/pdf", one level more per cascade), and each level has its getter — of_bar, of_item, of_menu_item. See Shared foundation · Items for the general principle.
Drop-down lists #
A drop-down list (of_add_combo) is a field and its arrow, like the ribbon's combo. Not editable, the user chooses in the list (a click on the field, Enter, F4 or Alt+Down opens it); editable, he may also type a value of his own. Every choice comes back in ue_combo_changed; folded into the chevron of a bar that is too narrow, the list stays a working list.
// A font the user only chooses, a size he may also type
uo_toolbar.of_add_combo(/*keys*/ "main/font", /*width*/ 130, /*editable*/ false, /*tooltip*/ "Font")
uo_toolbar.of_add_combo_item(/*keys*/ "main/font", /*label*/ "Segoe UI")
uo_toolbar.of_add_combo_item(/*keys*/ "main/font", /*label*/ "Arial")
uo_toolbar.of_item(/*keys*/ "main/font").is_text = "Segoe UI"
uo_toolbar.of_add_combo(/*keys*/ "main/size", /*width*/ 60, /*editable*/ true, /*tooltip*/ "Size")
uo_toolbar.of_add_combo_item(/*keys*/ "main/size", /*label*/ "10")
uo_toolbar.of_add_combo_item(/*keys*/ "main/size", /*label*/ "12")
// ue_combo_changed (string as_keys, string as_text) of uo_toolbar
st_status.Text = as_keys + " = " + as_text
Properties #
| Property | Type | Default | Purpose |
|---|---|---|---|
is_theme_style | string | "" | Visual style of the component (THEME_STYLE_* constants); empty = the application's, followed at every change |
is_theme_mode | string | "" | Light or dark variant (THEME_MODE_* constants); empty = the application's, followed at every change |
il_theme_accent | long | -1 | Accent colour of this component (-1 = the application accent, or the theme's) |
is_tooltip | string | "" | Simple 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 | "" | Text of the rich tooltip (rich markup accepted) |
is_super_tooltip_image | string | "" | Image of the rich tooltip |
ib_reorderable | boolean | false | Lets the user rearrange the bars with the mouse: the move grips appear and a bar can be dragged to another band. Off by default — a toolbar taken apart by accident is a support call. Your code rearranges them either way (of_set_layout, of_add_bar): the switch restrains the user, never the application |
Constant #
| Constant | Value | Purpose |
|---|---|---|
MAIN_BAR | "main" | Id of the default bar, addressed without having been created: it comes into being at its first tool. To place it, add it first — of_add_bar(MAIN_BAR, 1, 1) |
Methods #
| Method | Purpose | |
|---|---|---|
of_bar (string as_key) → n_pbt_toolbar_bar | Returns the handle of a bar (created on first access): ii_band, ii_index, ib_visible | |
of_add_button (string as_keys, string as_text, string as_image, string as_tooltip) → long | Action button at its address, "main/save": the bar, then its own identifier. A click fires ue_clicked. Returns 0 once added, -5 when the address is refused (not bar/tool, a bar never added — main excepted —, an address already taken), -2 when the component is not created | |
of_item (string as_keys) → n_pbt_toolbar_item | Returns the handle of one tool, by its bar/tool address. An address of another depth designates no tool: a bar is of_bar, a menu entry of_menu_item | |
of_menu_item (string as_keys) → n_pbt_toolbar_menu_item | Returns the handle of one entry of a drop-down menu, by its bar/dropdown/entry address — one level more per cascade. Two cascades may each hold their own pdf: the address designates one of them, never both | |
of_add_bar (string as_key) → long | Adds a bar, on a band of its own after the others. Returns 0 once added, -5 when the key is refused (empty, holding / or ` | , starting with __, or already taken), -2 when the component is not created. The default bar main comes into being at its first tool: to place it, add it **before** any tool (of_add_bar(MAIN_BAR, 1, 1)); after that it is taken (-5) and moves through of_bar(MAIN_BAR)` |
of_add_bar (string as_key, integer ai_band, integer ai_index) → long | Adds a bar at a precise band and position (both counted from 1); the bar that held that rank moves one step right. Same codes as above | |
of_remove_bar (string as_key) → long | Removes one bar and its tools, with their handles and their shortcuts. The others keep their live state, and the bands close ranks behind the one that leaves. This is not hiding it (ib_visible on its handle): hiding keeps it in the model, ready to come back exactly where it was; removing forgets it. Returns 0 once removed, -5 for a bar that does not exist, -2 when the component is not created | |
of_get_layout () → string | Reads the current layout back as JSON: which bar on which band, at which rank, and visible or not. Bands and ranks count from 1, like ii_band / ii_index: store it as it comes, then hand it back to of_set_layout — a round trip gives the same string | |
of_set_layout (string as_layout_json) → long | Restores a layout read with of_get_layout or received through ue_layout_changed, handed back as it came. A bar it does not name stays where it is. ue_layout_changed is raised, as for any change of the layout. Returns 0 once applied, -5 on an empty string, -2 when the component is not created. A text that is not JSON returns -5 as well | |
of_clear ( ) → long | Removes every bar, tool and menu, with the handles handed out and the shortcuts of the tools and entries; every address can be added again. Returns 0 once applied, -2 when the component is not created | |
of_reset ( ) | Clears the content and restores the properties to their defaults. Returns 0 once applied, -2 when the component is not created | |
of_add_toggle (string as_keys, string as_text, string as_image, string as_tooltip) → long | Two-state toggle; a click fires ue_toggled. Returns 0 once added, -5 when the address is refused (not bar/tool, a bar never added — main excepted —, an address already taken), -2 when the component is not created | |
of_add_dropdown (string as_keys, string as_text, string as_image, string as_tooltip) → long | Drop-down menu button, filled with of_add_menu_item; a choice fires ue_menu_selected. Returns 0 once added, -5 when the address is refused (not bar/tool, a bar never added — main excepted —, an address already taken), -2 when the component is not created. A drop-down with no visible entry is drawn greyed | |
of_add_split_button (string as_keys, string as_text, string as_image, string as_tooltip) → long | Split button: its main part is a button (ue_clicked), its arrow opens a menu filled by of_add_menu_item like a drop-down's (ue_menu_selected). Its shortcut fires the main part; folded into the chevron, it opens a list whose first line is its own action. Returns 0 once added, -5 when the address is refused (not bar/tool, a bar never added — main excepted —, an address already taken), -2 when the component is not created | |
of_add_label (string as_keys, string as_text) → long | Informative label, not clickable. Returns 0 once added, -5 when the address is refused (not bar/tool, a bar never added — main excepted —, an address already taken), -2 when the component is not created | |
of_add_textbox (string as_keys, string as_text, integer ai_width, string as_tooltip) → long | Input field; Enter or losing the focus fires ue_text_changed, Escape gives back the validated text. ai_width in pixels. Returns 0 once added, -5 when the address is refused (not bar/tool, a bar never added — main excepted —, an address already taken), -2 when the component is not created | |
of_add_combo (string as_keys, integer ai_width, boolean ab_editable, string as_tooltip) → long | Drop-down list (combo): a field and its arrow, the ribbon's combo. ab_editable = false, the user only chooses in the list; true, he may also type a value of his own, validated by Enter or by leaving the field. Fill the list with of_add_combo_item; a choice fires ue_combo_changed, is_text sets and reads the value. ai_width in pixels (0 = the default width). Folded into the chevron, it stays a working list. Returns 0 once added, -5 when the address is refused (not bar/tool, a bar never added — main excepted —, an address already taken), -2 when the component is not created | |
of_add_combo_item (string as_keys, string as_label) → long | Adds a choice to the list of a drop-down list: as_keys names the list ("main/zoom"). A choice is keyed by its label, so its address is "main/zoom/150%" (of_remove_combo_item, of_has); of_count and of_keys_at on the list walk its choices. In demo mode the list shows 6 choices. Returns 0 once added, -5 when as_keys is not a drop-down list, or the label is empty, holds / or ` | , or is already in the list, -2` when the component is not created |
of_add_datepicker (string as_keys, string as_date, string as_tooltip) → long | Date picker; a choice fires ue_date_changed, is_date reads and sets the date. Dates as "yyyy-mm-dd". Returns 0 once added, -5 when the address is refused (not bar/tool, a bar never added — main excepted —, an address already taken), -2 when the component is not created | |
of_add_separator (string as_keys) → long | Vertical separator line in a bar (as_keys names it). A separator has no key and holds no rank. Returns 0 once added, -5 for a bar never added (main excepted), -2 when the component is not created. A separator that hidden tools would leave leading, trailing or doubled is not drawn | |
of_insert_button (string as_keys, string as_text, string as_image, string as_tooltip, integer ai_index) → long | Button added at the chosen position (first = 1) rather than at the end. Returns 0 once added, -5 when the address is refused (not bar/tool, a bar never added — main excepted —, an address already taken), -2 when the component is not created | |
of_move_item (string as_keys, integer ai_index) → long | Moves a tool to another position in its bar (first = 1; the rank counts the tools, a separator holds none). It keeps its kind, its menu and its live state: the tool changes place, it is not rebuilt. Returns 0 once applied, -5 when no tool lives at that address, -2 when the component is not created | |
of_remove_item (string as_keys) → long | Removes one tool ("main/save") or one menu entry ("main/export/pdf", its cascade with it), with its handles and its shortcut. Everything else stays, live state included. To make a tool come and go, ib_visible on its handle keeps it in the model. Returns 0 once removed, -5 when nothing lives at that address, -2 when the component is not created | |
of_remove_combo_item (string as_keys) → long | Removes one choice of a drop-down list, named by its address "main/zoom/150%"; the value shown stays. of_remove_item does the same. Returns 0 once removed, -5 when that list has no such choice, -2 when the component is not created | |
of_add_menu_item (string as_keys, string as_label, string as_image) → long | Entry of the menu of a drop-down button, at its address bar/dropdown/entry; every level more nests it in cascade under the entry before, at any depth. An empty label shows the key. Returns 0 once added, -5 when the address is refused (a level empty or holding ` | , a drop-down or parent entry never added, an address already taken), -2 when the component is not created. The same goes for the menu of a split button (of_add_split_button`) |
of_add_menu_separator (string as_keys) → long | Separator line at the end of the menu of a drop-down ("main/export"), or of the cascade of an entry ("main/export/img"). Returns 0 once added, -5 when the address names neither, -2 when the component is not created. The same goes for the menu of a split button (of_add_split_button) | |
of_clear_menu (string as_keys) → long | Empties the menu of a drop-down ("main/recent") and keeps the button: the way to rebuild a list of recent files. The handles and shortcuts of its entries go with them. Returns 0 once applied, -5 when the address names no drop-down, -2 when the component is not created. The same goes for the menu of a split button (of_add_split_button) | |
of_clear_combo (string as_keys) → long | Empties the list of a drop-down list ("main/zoom"); the value shown stays. The way to rebuild a list that follows the document. Returns 0 once applied, -5 when as_keys is not a drop-down list, -2 when the component is not created | |
of_register_shortcut (string as_chord, string as_keys) → long | On a toolbar the shortcut takes the address of what it fires: a tool (bar/tool — like is_shortcut on its handle) or a menu entry (bar/dropdown/entry). It answers wherever the focus is in the window and shows in the tooltip or at the right of the entry; "" removes it. A toolbar has nothing to fire for itself: the one-argument form returns -5. Returns 0 once applied, -5 when the address names no tool and no entry, or names a label, -2 when the component is not created | |
of_clear_shortcuts ( ) → long | Drops every shortcut of the toolbar — those of its tools and of its menu entries: they no longer answer, no longer show, and is_shortcut reads back "". Returns 0 once applied, -2 when the component is not created |
On a bar — n_pbt_toolbar_bar #
| Member | Type | Default | Purpose |
|---|---|---|---|
ii_band | integer | 1 | Band (row) carrying the bar; 1 = first row |
ii_index | integer | 1 | Position of the bar within its band; 1 = the first |
ib_visible | boolean | true | Shows or hides one bar. A hidden bar keeps its band, its rank and its items: showing it again puts it back exactly where it was, with nothing to rebuild — that is the difference with of_clear, which would lose them |
On a tool — n_pbt_toolbar_item #
| Member | Type | Default | Purpose |
|---|---|---|---|
ib_visible | boolean | true | Shows or hides one item. It keeps its rank in the bar: showing it again puts it back exactly where it was, not at the end. Not to be confused with ib_enabled, which leaves it in place, greyed — hide what does not apply, grey what is momentarily unavailable |
ib_enabled | boolean | true | Tool active or grayed out |
ib_checked | boolean | false | State of a toggle (no effect on the other types) |
is_text | string | "" | Label, rich markup accepted |
is_shortcut | string | "" | Keyboard shortcut ("Ctrl+S"), shown in the tooltip and active; read back as written. A hidden or greyed tool, or one past the demo cap, does not answer it. It needs Ctrl or Alt (Shift adds to them), or is F1 to F24: a bare key — a letter, Delete, Enter — is typing, never a shortcut. A button or a toggle fires; a text box takes the caret, its text selected; a date picker opens its calendar; a label takes none |
is_date | string | "" | Date of a date picker, "yyyy-mm-dd" ("" empties the field). Reads the date on screen — the one the user picked as much as the one set here. A malformed date is ignored; other kinds of tool have no date and read "" |
is_image | string | "" | Icon of the tool (same forms as at the add: path, mono:, tint:…); "" takes it away. A Play toggle turning to Pause, a button turning to an error icon — without removing and re-adding the tool |
is_group | string | "" | Group of a toggle: the toggles of one bar that share a group are exclusive, like the alignment buttons of an editor — pressing one releases the others, pressing the one already down leaves it down. Only the toggle pressed raises ue_toggled. ib_checked = true set by your code releases the others too, without an event. "" (default): no group |
ib_editable | boolean | false | A drop-down list (of_add_combo): true, the user may type a value of his own besides the choices of the list; false, he only chooses. Any other tool reads false and ignores it |
On a menu entry — n_pbt_toolbar_menu_item #
| Member | Type | Default | Purpose |
|---|---|---|---|
ib_enabled | boolean | true | Greyed, the entry stays in the menu and can no longer be chosen — by the mouse, the keyboard or its shortcut |
ib_visible | boolean | true | Hidden, the entry leaves the menu (its cascade with it); it keeps its place and its state, and comes back where it was |
ib_checked | boolean | false | A tick in front of the entry. The application decides it: choosing the entry does not flip it |
is_text | string | "" | Caption of the entry, rich markup accepted; reads back the key when the entry was added without a label |
is_shortcut | string | "" | Shortcut shown at the right of the entry and active: it chooses it wherever the focus is and raises ue_menu_selected like a click — not when the entry, a level above it or its drop-down is greyed or hidden. Read back as written; "" removes it. Same rule as for a tool: Ctrl or Alt, or F1 to F24 |
is_image | string | "" | Icon of the entry, shown at the next opening of the menu; "" takes it away |
Images accept every form the library recognizes: path, mono:, tint:, DLL resource. A menu entry takes the five item colours (il_back_color, il_text_color, their hover variants, il_accent), drawn in the menu; it shows no tooltip — a native menu has none.
Events #
| Event | Raised when |
|---|---|
ue_clicked (string as_keys) | A button — or the main part of a split button — is fired: by a click, by its shortcut, or from the chevron panel when it is folded. as_keys is its address, "main/save" |
ue_toggled (string as_keys, boolean ab_checked) | A toggle changes state; ab_checked carries the new state. Raised by a gesture of the user only: setting ib_checked does not raise it. In a group (is_group), only the toggle pressed raises it |
ue_menu_selected (string as_keys) | A drop-down menu entry is chosen — by the mouse, the keyboard or its shortcut, in the bar as in the chevron panel. as_keys is its full address, "main/export/img/png". Holds for the menu of a split button as for a drop-down's; the entry itself is the last level of the address |
ue_text_changed (string as_keys, string as_text) | An input field is validated (Enter or losing the focus); Enter stops at the field and does not press the window's default button. Escape gives the field back its text without raising it, and setting is_text does not raise it |
ue_date_changed (string as_keys, string as_date) | A date is picked ("yyyy-mm-dd"). Raised by a choice of the user in the calendar only; setting is_date does not raise it |
ue_combo_changed (string as_keys, string as_text) | The user chose a value in the list of a drop-down list, or typed one in an editable list and validated it (Enter, or by leaving the field) — in the bar or in the chevron panel. as_text is the value, as_keys = bar/tool. A typed value raises it only when it changed; Escape gives the value back without raising it; is_text set by your code raises nothing. The ribbon's event: same name, same meaning |
ue_bar_reordered (string as_key, integer ai_band, integer ai_index) | The user dragged a bar by its grip to another band or another rank (needs ib_reorderable). Says which bar moved and where it landed, where ue_layout_changed carries the whole arrangement. Band and rank start at 1, like ii_band and ii_index |
ue_layout_changed (string as_layout_json) | The arrangement changed — the user dragged a bar by its grip, or your own code moved or hid one, or put a layout back with of_set_layout. Carries the whole layout, not just what moved, bands and ranks counted from 1: to store as it comes and hand back to of_set_layout. Adding a bar that pushes another aside raises it too; nothing is raised when nothing moved (showing a bar already visible) |
ue_item_rclicked (string as_keys) | Right click on a tool (a greyed one says nothing); as_keys is its address. Open your own context menu from here. A right click outside any tool raises ue_rclicked instead — never both |
ue_rclicked ( ) | Right click on the tray outside any tool (a right click on a tool raises ue_item_rclicked alone) |
ue_mouse_enter ( ) | The mouse enters the tray |
ue_mouse_leave ( ) | The mouse leaves the tray |
ue_auto_height (long al_height) | The ideal height has changed and the bar has adjusted to it — always active: the number of rows dictates the height |
ue_ready ( ) | The component has finished loading; everything sent beforehand has been replayed |
ue_runtime_missing ( ) | The WebView2 runtime is missing: the component stays empty |
ue_bg_color (long al_color) | The component has computed its theme background color; the userobject has already adopted it (backcolor) |
Examples #
Pre-checked toggles and a grayed-out tool #
// Two toggles, a separator and a button
uo_toolbar.of_add_toggle(/*keys*/ uo_toolbar.MAIN_BAR + "/bold", /*text*/ "", /*image*/ "mono:img\bold.svg", /*tooltip*/ "Bold")
uo_toolbar.of_add_toggle(/*keys*/ uo_toolbar.MAIN_BAR + "/italic", /*text*/ "", /*image*/ "mono:img\italic.svg", /*tooltip*/ "Italic")
uo_toolbar.of_add_separator(/*keys*/ uo_toolbar.MAIN_BAR)
uo_toolbar.of_add_button(/*keys*/ uo_toolbar.MAIN_BAR + "/undo", /*text*/ "", /*image*/ "mono:img\undo.svg", /*tooltip*/ "Undo")
// Every tool is driven through its handle, obtained from ITS bar
uo_toolbar.of_item(/*keys*/ uo_toolbar.MAIN_BAR + "/bold").ib_checked = true // toggle checked up front
uo_toolbar.of_item(/*keys*/ uo_toolbar.MAIN_BAR + "/undo").ib_enabled = false // nothing to undo yet
// ue_toggled event of uo_toolbar
if as_keys = "main/bold" then of_apply_bold(ab_checked)
Cascading drop-down menu #
// The menu is filled from the component : three levels, bar/dropdown/entry
uo_toolbar.of_add_dropdown(/*keys*/ uo_toolbar.MAIN_BAR + "/export", /*text*/ "Export", &
/*image*/ "mono:img\save.svg", /*tooltip*/ "Export the file")
uo_toolbar.of_add_menu_item(/*keys*/ uo_toolbar.MAIN_BAR + "/export/exp_pdf", /*label*/ "PDF", /*image*/ "")
uo_toolbar.of_add_menu_item(/*keys*/ uo_toolbar.MAIN_BAR + "/export/exp_csv", /*label*/ "CSV", /*image*/ "")
uo_toolbar.of_add_menu_separator(/*keys*/ uo_toolbar.MAIN_BAR + "/export")
// Submenu : a FOURTH level, the entry it nests under
uo_toolbar.of_add_menu_item(/*keys*/ uo_toolbar.MAIN_BAR + "/export/exp_img", /*label*/ "Image...", /*image*/ "")
uo_toolbar.of_add_menu_item(/*keys*/ uo_toolbar.MAIN_BAR + "/export/exp_img/exp_png", /*label*/ "PNG", /*image*/ "")
uo_toolbar.of_add_menu_item(/*keys*/ uo_toolbar.MAIN_BAR + "/export/exp_img/exp_jpg", /*label*/ "JPEG", /*image*/ "")
// An entry is driven through ITS handle, at its address
uo_toolbar.of_menu_item(/*keys*/ uo_toolbar.MAIN_BAR + "/export/exp_csv").ib_enabled = false
// ue_menu_selected event of uo_toolbar : (as_keys)
n_pbt_utils lnv_utils // autoinstantiate : nothing to create, nothing to destroy
string ls_ids[]
// An entry of the Export menu : its leaf names the format
if lnv_utils.of_split_path(/*keys*/ as_keys, /*out*/ ls_ids) >= 3 then
if ls_ids[2] = "export" then of_export(ls_ids[UpperBound(ls_ids)])
end if
Search field and date picker #
// A button with its shortcut, then a separator
uo_toolbar.of_add_button(/*keys*/ uo_toolbar.MAIN_BAR + "/save", /*text*/ "", /*image*/ "mono:img\save.svg", /*tooltip*/ "Save")
uo_toolbar.of_item(/*keys*/ uo_toolbar.MAIN_BAR + "/save").is_shortcut = "Ctrl+S" // shortcut active and displayed
uo_toolbar.of_add_separator(/*keys*/ uo_toolbar.MAIN_BAR)
// 160 px wide ; the text is reported on validation
uo_toolbar.of_add_textbox(/*keys*/ uo_toolbar.MAIN_BAR + "/search", /*text*/ "", /*width*/ 160, /*tooltip*/ "Find (Enter to validate)")
// A label in front of a date picker
uo_toolbar.of_add_label(/*keys*/ uo_toolbar.MAIN_BAR + "/lbl_due", /*text*/ "Due date:")
uo_toolbar.of_add_datepicker(/*keys*/ uo_toolbar.MAIN_BAR + "/due", /*date*/ "2026-07-11", /*tooltip*/ "Due date")
// ue_text_changed event of uo_toolbar
if as_keys = "main/search" then of_filter(as_text)
// ue_date_changed event of uo_toolbar : as_date in "yyyy-mm-dd" format
if as_keys = "main/due" then id_due_date = Date(as_date)
Two bars and a remembered layout #
With ib_reorderable = true, the user can grab a bar by its handle (to the left of the bar) and move it to another band or another position. Keep the layout when the window closes, and restore it when it opens.
// Without this line there is no grip : the user cannot move anything
uo_toolbar.ib_reorderable = true
// The main bar and its two buttons
uo_toolbar.of_add_button(/*keys*/ uo_toolbar.MAIN_BAR + "/new", /*text*/ "New", /*image*/ "", /*tooltip*/ "")
uo_toolbar.of_add_button(/*keys*/ uo_toolbar.MAIN_BAR + "/open", /*text*/ "Open", /*image*/ "", /*tooltip*/ "")
// Second bar, placed on band 2 (second row), in first position
uo_toolbar.of_add_bar(/*key*/ "format", /*band*/ 2, /*index*/ 1)
uo_toolbar.of_add_toggle(/*keys*/ "format/bold", /*text*/ "B", /*image*/ "", /*tooltip*/ "Bold")
// A bar can also be moved at any time through its properties
uo_toolbar.of_bar(/*key*/ "format").ii_band = 1
uo_toolbar.of_bar(/*key*/ "format").ii_index = 2 // second bar of the first row
// ue_layout_changed event of uo_toolbar : keep the chosen layout
is_layout = as_layout_json
// Next time the window opens : restore what the user had arranged
if is_layout <> "" then uo_toolbar.of_set_layout(/*layout_json*/ is_layout)
Split button and exclusive toggles #
// Paste : the main part pastes at once, the arrow offers the other ways
uo_toolbar.of_add_split_button(/*keys*/ "edit/paste", /*text*/ "", /*image*/ "mono:img\paste.svg", /*tooltip*/ "Paste")
uo_toolbar.of_add_menu_item(/*keys*/ "edit/paste/plain", /*label*/ "Plain text", /*image*/ "")
uo_toolbar.of_add_menu_item(/*keys*/ "edit/paste/special", /*label*/ "Paste special...", /*image*/ "")
// The alignment toggles share a group : one pressed at a time
uo_toolbar.of_add_toggle(/*keys*/ "edit/left", /*text*/ "", /*image*/ "mono:img\left.svg", /*tooltip*/ "Left")
uo_toolbar.of_add_toggle(/*keys*/ "edit/center", /*text*/ "", /*image*/ "mono:img\center.svg", /*tooltip*/ "Center")
uo_toolbar.of_add_toggle(/*keys*/ "edit/right", /*text*/ "", /*image*/ "mono:img\right.svg", /*tooltip*/ "Right")
uo_toolbar.of_item(/*keys*/ "edit/left").is_group = "align"
uo_toolbar.of_item(/*keys*/ "edit/center").is_group = "align"
uo_toolbar.of_item(/*keys*/ "edit/right").is_group = "align"
uo_toolbar.of_item(/*keys*/ "edit/left").ib_checked = true
// event ue_clicked of uo_toolbar : the main part of the split button
if as_keys = "edit/paste" then of_paste()
// event ue_toggled of uo_toolbar : only the toggle pressed raises it
if ab_checked and Left(as_keys, 5) = "edit/" then of_align(Mid(as_keys, 6))
Overflow: "More tools" #
When the width is no longer enough, the tools that do not fit are folded into a More tools menu marked by a chevron at the end of the bar. This is automatic and requires no code: the folded tools stay clickable and raise the same events. A folded field — text box or date picker — stays a real field: you type in it, you pick a date in it, and the event is raised exactly as if the tool had stayed in the bar.
Automatic height #
Nothing to enable: the number of rows (of_set_layout) dictates the height, the bar adjusts to it on its own and notifies you.
// ue_auto_height event of uo_toolbar
uo_content.y = uo_toolbar.y + al_height
uo_content.height = parent.workspaceheight() - uo_content.y
See Shared foundation.
Best practices #
- Use
MAIN_BARas long as one bar is enough: it comes into being at its first tool, no need to add it. To place it anywhere but after the other bars, add it before any tool —of_add_bar(MAIN_BAR, 1, 1); once born,of_add_bar(MAIN_BAR)returns-5and it moves throughof_bar(MAIN_BAR).ii_band. - On a toolbar,
of_register_shortcuttakes the address of the tool or entry it fires. A shortcut needs Ctrl or Alt, or a key F1 to F24: a bare key stays with typing. - Always reach a tool through its path —
of_item("main/save")— never through its identifier alone: that is what makes identifiers reusable from one bar to the next. - Group related tools with
of_add_separator("main")rather than with extra bars. - On icon-only buttons, always fill in the tooltip: it is the only label the user has.
- If you let users rearrange the bars, remember
ue_layout_changedand replayof_set_layoutat startup, otherwise their effort is lost every time the application launches. - Call
of_reset()before rebuilding the toolbar from scratch for another context. - When the commands become too numerous for a bar, move up to the ribbon, organized into tabs and groups.
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 |
of_set_property · of_get_property · of_component_name | Driving a property by its name | 3.1 The property engine |
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.