PBToolboxAI v1 ← Site

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 #

Userobjectu_pbt_toolbar
Item classesn_pbt_toolbar_bar (bar) → n_pbt_toolbar_item (tool)
Used forReplacing a classic toolbar with a modern, themed one spread over several rearrangeable rows
HeightIntrinsic: the bar always fits itself to its rows, nothing to enable — see Automatic height

Quick start #

// open event of the window
n_pbt_toolbar_bar lnv_bar

// of_bar() returns the default bar, always present (id = MAIN_BAR)
lnv_bar = uo_toolbar.of_bar(uo_toolbar.MAIN_BAR)

lnv_bar.of_add_button(/*id*/ "save", /*text*/ "", /*image*/ "mono:img\save.svg", /*tooltip*/ "Save")
lnv_bar.of_add_button(/*id*/ "find", /*text*/ "", /*image*/ "mono:img\find.svg", /*tooltip*/ "Find")
lnv_bar.of_add_separator()
lnv_bar.of_add_button(/*id*/ "help", /*text*/ "Help",  /*image*/ "", /*tooltip*/ "About")
// ue_clicked event of uo_toolbar : (string as_bar, string as_id)
choose case as_bar + "/" + as_id
    case "main/save" ; of_enregistrer()
    case "main/find" ; of_rechercher()
    case "main/help" ; of_aide()
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.

uo_toolbar.of_bar("main").of_item("save").ib_enabled = false

Additions live on the parent handle too: you add a tool to a bar, not to the toolbar. See Shared foundation · Items for the general principle.


Properties #

PropertyTypeDefaultPurpose
is_theme_stylestringfluentVisual style of the component (THEME_STYLE_* constants)
is_theme_modestringlightLight or dark variant (THEME_MODE_* constants)
il_theme_accentlong-1Accent color of this component (-1 = the theme accent)
is_tooltipstring""Simple tooltip shown when hovering the component
is_super_tooltip_titlestring""Title of the rich tooltip (takes precedence over is_tooltip)
is_super_tooltip_textstring""Text of the rich tooltip (rich markup accepted)
is_super_tooltip_imagestring""Image of the rich tooltip
ib_reorderablebooleanfalseLets 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 #

ConstantValuePurpose
MAIN_BAR"main"Identifier of the default bar, always available without having to create it

Methods #

MethodPurpose
of_bar (string as_id)n_pbt_toolbar_barReturns the handle of a bar (created on first access)
of_add_bar (string as_bar)n_pbt_toolbar_barAdds a bar and returns its handle
of_add_bar (string as_bar, integer ai_band, integer ai_index)n_pbt_toolbar_barAdds a bar at a specific band and position (both counted from 0)
of_remove_bar (string as_id)Removes one bar and its tools. 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
of_get_layout ()Reads the current arrangement back as JSON: which bar on which band, at which rank, and visible or not. Store it, then hand it back with of_set_layout
of_set_layout (string as_layout_json)Restores a bar layout previously received through ue_layout_changed
of_clear ( )Removes every bar and every tool
of_reset ( )Clears the content and restores the properties to their defaults

On a bar — n_pbt_toolbar_bar #

MemberTypeDefaultPurpose
ii_bandinteger0Band (row) carrying the bar; 0 = first row
ii_indexinteger0Position of the bar within its band
ib_visiblebooleantrueShows 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
of_item (string as_id)n_pbt_toolbar_itemReturns the handle of a tool of this bar
of_add_button (as_id, as_text, as_image, as_tooltip)n_pbt_toolbar_itemAction button; clicking it raises ue_clicked
of_add_toggle (as_id, as_text, as_image, as_tooltip)n_pbt_toolbar_itemTwo-state toggle; clicking it raises ue_toggled
of_add_dropdown (as_id, as_text, as_image, as_tooltip)n_pbt_toolbar_itemDrop-down menu button; picking an entry raises ue_menu_selected
of_add_label (as_id, as_text)n_pbt_toolbar_itemInformational label, not clickable
of_add_textbox (as_id, as_text, ai_width, as_tooltip)n_pbt_toolbar_itemInput field; Enter or loss of focus raises ue_text_changed. ai_width in pixels
of_add_datepicker (as_id, as_date, as_tooltip)n_pbt_toolbar_itemDate picker; picking a date raises ue_date_changed. Dates in "yyyy-mm-dd" format
of_add_separator ( )Vertical separator rule
of_insert_button (as_id, as_text, as_image, as_tooltip, ai_index)n_pbt_toolbar_itemButton added at the position you choose (first = 0) instead of at the end
of_move_item (string as_id, integer ai_index)Moves a tool to another position within this bar (first = 0). It keeps its kind, its menu and its live state: the tool changes place, it is not rebuilt. Works for every kind, so the of_add_* without an of_insert_* insert by adding then moving
of_remove_item (string as_id)Removes one tool from this bar. The bar stays, and so does everything else in it, live state included — only the named tool goes. To make it come and go instead, ib_visible on its handle keeps it in the model

On a tool — n_pbt_toolbar_item #

MemberTypeDefaultPurpose
ib_visiblebooleantrueShows 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_enabledbooleantrueTool active or grayed out
ib_checkedbooleanfalseState of a toggle (no effect on the other types)
is_textstring""Label, rich markup accepted
is_shortcutstring""Keyboard shortcut ("Ctrl+S"), shown in the tooltip and active
of_add_menu_item (as_id, as_label, as_image)Entry in the menu of a drop-down button
of_add_menu_item (as_parent, as_id, as_label, as_image)Cascading entry, filed under an existing entry
of_add_menu_separator (as_id)Separator rule inside the menu

Images accept every form the library recognizes: path, mono:, tint:, DLL resource.


Events #

EventRaised when
ue_clicked (string as_bar, string as_id)A button is clicked (or triggered by its shortcut)
ue_toggled (string as_bar, string as_id, boolean ab_checked)A toggle changes state; ab_checked carries the new state
ue_menu_selected (string as_bar, string as_dropdown, string as_id)A drop-down menu entry is picked
ue_text_changed (string as_bar, string as_id, string as_text)An input field is validated (Enter or loss of focus)
ue_date_changed (string as_bar, string as_id, string as_date)A date is picked ("yyyy-mm-dd")
ue_bar_reordered (string as_id, 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
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. Carries the whole layout, not just what moved
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 #

n_pbt_toolbar_bar lnv_bar
lnv_bar = uo_toolbar.of_bar(uo_toolbar.MAIN_BAR)

lnv_bar.of_add_toggle(/*id*/ "bold",   /*text*/ "", /*image*/ "mono:img\bold.svg",   /*tooltip*/ "Bold")
lnv_bar.of_add_toggle(/*id*/ "italic", /*text*/ "", /*image*/ "mono:img\italic.svg", /*tooltip*/ "Italic")
lnv_bar.of_add_separator()
lnv_bar.of_add_button(/*id*/ "undo",   /*text*/ "", /*image*/ "mono:img\undo.svg",   /*tooltip*/ "Undo")

// Every tool is driven through its handle, obtained from ITS bar
lnv_bar.of_item("bold").ib_checked = true    // toggle checked up front
lnv_bar.of_item("undo").ib_enabled = false   // nothing to undo yet
// ue_toggled event of uo_toolbar
if as_id = "bold" then of_appliquer_gras(ab_checked)

Cascading drop-down menu #

n_pbt_toolbar_bar  lnv_bar
n_pbt_toolbar_item lnv_menu

lnv_bar = uo_toolbar.of_bar(uo_toolbar.MAIN_BAR)

// The menu is filled through the handle returned by of_add_dropdown
lnv_menu = lnv_bar.of_add_dropdown(/*id*/ "export", /*text*/ "Export", &
                                   /*image*/ "mono:img\save.svg", /*tooltip*/ "Export the file")
lnv_menu.of_add_menu_item(/*id*/ "exp_pdf", /*label*/ "PDF",  /*image*/ "")
lnv_menu.of_add_menu_item(/*id*/ "exp_csv", /*label*/ "CSV",  /*image*/ "")
lnv_menu.of_add_menu_separator(/*id*/ "sep1")

// Submenu : name the parent entry as the first argument
lnv_menu.of_add_menu_item(/*id*/ "exp_img", /*label*/ "Image...", /*image*/ "")
lnv_menu.of_add_menu_item(/*parent*/ "exp_img", /*id*/ "exp_png", /*label*/ "PNG", /*image*/ "")
lnv_menu.of_add_menu_item(/*parent*/ "exp_img", /*id*/ "exp_jpg", /*label*/ "JPEG", /*image*/ "")
// ue_menu_selected event of uo_toolbar : (as_bar, as_dropdown, as_id)
if as_dropdown = "export" then of_exporter(as_id)

Search field and date picker #

n_pbt_toolbar_bar lnv_bar
lnv_bar = uo_toolbar.of_bar(uo_toolbar.MAIN_BAR)

lnv_bar.of_add_button(/*id*/ "save", /*text*/ "", /*image*/ "mono:img\save.svg", /*tooltip*/ "Save")
lnv_bar.of_item("save").is_shortcut = "Ctrl+S"    // shortcut active and displayed
lnv_bar.of_add_separator()

// 160 px wide ; the text is reported on validation
lnv_bar.of_add_textbox(/*id*/ "search", /*text*/ "", /*width*/ 160, /*tooltip*/ "Find (Enter to validate)")

lnv_bar.of_add_label(/*id*/ "lbl_due", /*text*/ "Due date:")
lnv_bar.of_add_datepicker(/*id*/ "due", /*date*/ "2026-07-11", /*tooltip*/ "Due date")
// ue_text_changed event of uo_toolbar
if as_id = "search" then of_filtrer(as_text)
// ue_date_changed event of uo_toolbar : as_date in "yyyy-mm-dd" format
if as_id = "due" then id_echeance = Date(as_date)

Two bars and a remembered layout #

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.

n_pbt_toolbar_bar lnv_std, lnv_fmt

lnv_std = uo_toolbar.of_bar(uo_toolbar.MAIN_BAR)
lnv_std.of_add_button(/*id*/ "new",  /*text*/ "New", /*image*/ "", /*tooltip*/ "")
lnv_std.of_add_button(/*id*/ "open", /*text*/ "Open",  /*image*/ "", /*tooltip*/ "")

// Second bar, placed on band 1 (second row), in first position
lnv_fmt = uo_toolbar.of_add_bar(/*bar*/ "format", /*band*/ 1, /*index*/ 0)
lnv_fmt.of_add_toggle(/*id*/ "bold", /*text*/ "B", /*image*/ "", /*tooltip*/ "Bold")

// A bar can also be moved at any time through its properties
uo_toolbar.of_bar("format").ii_band  = 0
uo_toolbar.of_bar("format").ii_index = 1    // second bar of the first row
// ue_layout_changed event of uo_toolbar : keep the chosen layout
is_disposition = as_layout_json
// Next time the window opens : restore what the user had arranged
if is_disposition <> "" then uo_toolbar.of_set_layout(is_disposition)

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_contenu.y      = uo_toolbar.y + al_height
uo_contenu.height = parent.workspaceheight() - uo_contenu.y

See Shared foundation.


Best practices #


← Component reference · Guide contents