statusbar — u_pbt_statusbar #
← Component reference · Guide contents
Status bar made of panels: rich text, icons, fixed or automatic widths, alignment to the left or to the right, clickable panels, a mini progress bar and colored states.
▶ See it live — Demo application, Statusbar tile: the preview, the code behind it and this page, side by side.
At a glance #
| Userobject | u_pbt_statusbar |
| Item class | n_pbt_statusbar_panel (panel) · n_pbt_statusbar_menu_item (drop-down entry) |
| Used for | Showing the state of the application at the bottom of the window: context, progress, discreet alerts |
| Opt-in options | — |
Quick start #
// window open event
// of_add_panel(id, text, icon, alignment, width)
// empty id = purely informative panel ; width 0 = fitted to the text
uo_statut.of_add_panel(/*key*/ "etat", /*text*/ "Ready", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)
uo_statut.of_add_panel(/*key*/ "", /*text*/ "Line 12, Col 4", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)
uo_statut.of_add_panel(/*key*/ "heure", /*text*/ "12:00", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_END, /*width*/ 140)
// Update a panel at any time, through its identifier
uo_statut.of_panel("etat").is_text = "Saving..."
The model: panels with keys #
The bar is a sequence of panels, added in order. A panel is given an identifier when it is created: that is how you find it later to change its text, its icon or its state.
The identifier is an addressing key, not an interactivity switch:
- Identifier supplied: the panel can be found again — you change its content, you give it a tooltip. It stays inert: a status bar shows things above all, and a panel like
Line 12, Col 4must not look pressable. - Empty identifier: the panel is purely decorative. It cannot be found, cannot be clicked, and no tooltip can be attached to it. Give every panel an identifier: it costs nothing and keeps the door open.
- To make a panel clickable, ask for it:
of_panel("id").ib_clickable = true. A panel carrying a drop-down list (of_add_menu_item) already is.
uo_statut.of_panel("etat").is_text = "3 records changed"
See Shared foundation · Items.
Properties #
| Property | Type | Default | Purpose |
|---|---|---|---|
ib_show_resize_grip | boolean | false | Shows the resize grip in the corner at the end of the bar |
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 color of this component (-1 = the theme accent) |
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 |
Methods #
| Method | Purpose |
|---|---|
of_add_panel (string as_key, string as_text, string as_icon_file, string as_align, integer ai_width) | Adds a panel at the end of the bar. Returns 0 once applied, -2 when the component is not created |
of_add_sep ( ) | Adds a vertical separator line between two groups of panels. Returns 0 once applied, -2 when the component is not created |
of_insert_panel (as_keys, as_text, as_icon_file, as_align, ai_width, ai_index) | Inserts a panel at a specific position (counted from 0). Returns 0 once applied, -2 when the component is not created |
of_move_panel (string as_key, integer ai_index) | Moves an existing panel to another position. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_remove_panel (string as_key) | Removes a single panel; the others keep their state. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_panel (string as_key) → n_pbt_statusbar_panel | Returns the handle to a panel (created on first access) |
of_flash_panel (string as_key, string as_text, long al_ms) | Shows a message for al_ms milliseconds, then puts the previous text back (al_ms ≤ 0 = 2 seconds). Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_add_menu_item (string as_keys, string as_label) · (as_keys, as_label, as_image) | Adds an entry to the drop-down list of a panel: as_keys has two levels, the panel then the entry ("enc/utf8"). From the first entry on the panel is a chooser: clicking it opens the list, and the choice comes back through ue_panel_menu_clicked with the same address. An empty label falls back to the key. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_insert_menu_item (string as_keys, string as_label, integer ai_index) · (as_keys, as_label, as_image, ai_index) | Inserts an entry at a given position (counted from 0). Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_add_menu_separator (string as_key) | Separator line in the list of panel as_key. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_remove_menu_item (string as_keys) | Removes a single entry; the last one gone, the panel goes back to the behaviour ib_clickable gives it. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_move_menu_item (string as_keys, integer ai_index) | Moves an entry to another position in its list. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_menu_item (string as_keys) → n_pbt_statusbar_menu_item | Returns the handle to an entry (created on first access), to grey it, tick it or rename it |
of_clear_menu (string as_key) | Removes the whole drop-down list; the panel goes back to the behaviour ib_clickable gives it. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_clear ( ) | Empties the bar: every panel and every separator. Returns 0 once applied, -2 when the component is not created |
of_reset ( ) | Empties the bar and resets every property to its default. Returns 0 once applied, -2 when the component is not created |
The arguments of of_add_panel #
| Argument | Values | Effect |
|---|---|---|
as_keys | free, or "" | Key of the panel, the one you find it by later. Empty = a decorative panel, neither addressable nor clickable |
as_text | text | Content of the panel. Rich text markup is accepted |
as_icon_file | image path, or "" | Icon displayed before the text (accepted forms) |
as_align | ALIGN_START (default) or ALIGN_END | Side the panel is pushed toward. Logical values: START = start of the reading direction (left in left-to-right writing). The physical aliases "left" / "right" are still accepted |
ai_width | pixels, or 0 | Fixed width. 0 = the panel fits its content |
On a panel — n_pbt_statusbar_panel #
| Member | Type | Default | Purpose |
|---|---|---|---|
is_text | string | "" | Text of the panel, rich text markup accepted |
is_image | string | "" | Icon of the panel, which can be changed at any time |
ib_enabled | boolean | true | Panel grayed out and not clickable |
ib_visible | boolean | true | Panel hidden, without being removed from the bar |
ii_progress | integer | — | Mini progress bar inside the panel, from 0 to 100; a negative value makes it disappear |
is_state | string | "" | Semantic state of the panel, which colors it: see the constants below |
ib_indeterminate | boolean | false | Bar animated without a value, for a task whose duration is unknown. Independent of ii_progress, which stays the exact percentage |
ib_clickable | boolean | false | Does the panel answer the click. Opt-in: a panel stays inert until you ask, while keeping its key — it is driven and carries a tooltip. A panel with a drop-down list is clickable already |
On a drop-down entry — n_pbt_statusbar_menu_item #
Obtained through of_menu_item("enc/utf8"): the address has two levels, the panel then the entry. The list is a native menu: a property changed while it is open shows at the next opening.
| Member | Type | Default | Purpose |
|---|---|---|---|
is_label | string | "" | Text of the entry |
is_image | string | "" | Image before the text, which can be changed at any time |
ib_enabled | boolean | true | Entry greyed out: shown, but impossible to pick |
ib_checked | boolean | false | Check mark before the entry, for the value in use |
ib_visible | boolean | true | Entry left out of the list without being removed: showing it again needs nothing more |
uo_statut.of_add_menu_item("enc/utf8", "UTF-8")
uo_statut.of_add_menu_item("enc/ansi", "ANSI")
uo_statut.of_menu_item("enc/utf8").ib_checked = true // la valeur en cours
uo_statut.of_menu_item("enc/ansi").ib_enabled = false // pas disponible ici
State constants #
| Constant | Value | Use |
|---|---|---|
STATE_NONE | "" | No state: normal appearance |
STATE_INFO | "info" | Information |
STATE_WARNING | "warning" | Warning |
STATE_ERROR | "error" | Error |
STATE_SUCCESS | "success" | Success |
As with every property that takes predefined values, use the constant rather than the string:
uo_statut.of_panel("etat").is_state = n_pbt_statusbar_panel.STATE_WARNING
Events #
| Event | Raised when |
|---|---|
ue_panel_clicked (string as_key) | A panel whose identifier is supplied is clicked |
ue_panel_double_clicked (string as_key) | A clickable panel was double-clicked — the classic shortcut behind Line 12, Col 4 that opens a "Go to line" |
ue_panel_rclicked (string as_key, long al_x, long al_y) | A panel received a right click. al_x and al_y are screen pixels: pass them straight through to open a context menu where the user aimed |
ue_panel_menu_clicked (string as_keys) | An entry of a panel drop-down list was picked (see of_add_menu_item). as_keys carries both levels: the panel, then the entry — "clock/utc" |
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) |
Keyboard #
The bar is a single tab stop: only the panels meant to be clicked enter it, and the arrows walk them.
| Key | Effect |
|---|---|
| Arrows | Move to the previous / next interactive panel, wrapping around; display panels and disabled panels are skipped |
| Home / End | First / last interactive panel |
| Enter or Space | Triggers the panel — that is, ue_panel_clicked, or the opening of its dropdown if it has one |
A panel that merely displays is not a control: it is neither focusable nor announced as one. A clickable but disabled panel, on the other hand, stays announced as unavailable rather than passing for text. A progress bar announces its value, and an indeterminate one announces none — that absence is the meaning of the word.
The focus survives the rebuild of the bar: it is redrawn on every text change, and without this the focus would drop every second on a bar showing a clock.
Examples #
Fixed widths and automatic widths #
// Width 0 : the panel takes exactly the room its text needs
uo_statut.of_add_panel(/*key*/ "", /*text*/ "Panel fitted to its content", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)
// Fixed width in pixels : useful when the text changes often,
// so that the neighboring panels do not move on every update
uo_statut.of_add_panel(/*key*/ "pos", /*text*/ "Line 1, Col 1", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 150)
// A panel pushed to the opposite end
uo_statut.of_add_panel(/*key*/ "heure", /*text*/ "12:00", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_END, /*width*/ 140)
Icons and clickable panels #
// A non-empty identifier makes the panel clickable
uo_statut.of_add_panel(/*key*/ "save", /*text*/ "Saved", /*icon_file*/ "mono:img\save.svg", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)
uo_statut.of_add_sep() // separator line between two groups of panels
uo_statut.of_add_panel(/*key*/ "conn", /*text*/ "Connected", /*icon_file*/ "mono:img\plug.svg", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)
uo_statut.of_add_panel(/*key*/ "user", /*text*/ "Guillaume", /*icon_file*/ "mono:img\user.svg", /*align*/ uo_statut.ALIGN_END, /*width*/ 160)
// ue_panel_clicked event of uo_statut
choose case as_keys
case "conn" ; open(w_parametres_connexion)
case "user" ; open(w_profil)
end choose
Rich text in a panel #
Panels accept rich text markup: styles, colors and small images right inside the text.
uo_statut.of_add_panel(/*key*/ "", /*text*/ "Welcome [b]to[/b] [accent]PBToolboxAI[/accent]", &
/*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)
uo_statut.of_add_panel(/*key*/ "", /*text*/ "[green]Online[/green] [picture=mono:img\plug.svg,14,14]", &
/*icon_file*/ "", /*align*/ uo_statut.ALIGN_END, /*width*/ 0)
// Rich text works for updates too
uo_statut.of_panel("etat").is_text = "[b]" + String(ll_modifies) + "[/b] records changed"
Following a long operation #
n_pbt_statusbar_panel lnv_avance
uo_statut.of_add_panel(/*key*/ "import", /*text*/ "Import", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 220)
lnv_avance = uo_statut.of_panel("import")
// Inside the processing loop : the mini bar follows the progress
lnv_avance.ii_progress = ll_pourcentage
lnv_avance.is_text = "Import " + String(ll_pourcentage) + " %"
// At the end : hide the mini bar and report the result
lnv_avance.ii_progress = -1 // negative value = bar hidden
lnv_avance.is_text = "Import complete"
lnv_avance.is_state = lnv_avance.STATE_SUCCESS
Raising a discreet alert #
n_pbt_statusbar_panel lnv_panneau
lnv_panneau = uo_statut.of_panel("conn")
if not ib_connecte then
lnv_panneau.is_text = "Offline"
lnv_panneau.is_state = lnv_panneau.STATE_ERROR
else
lnv_panneau.is_text = "Connected"
lnv_panneau.is_state = lnv_panneau.STATE_NONE // back to the normal appearance
end if
Adapting the bar to the context #
// Hide a panel without deleting it : it will find its place again later
uo_statut.of_panel("user").ib_visible = ib_utilisateur_identifie
// Gray it out when the matching action makes no sense
uo_statut.of_panel("save").ib_enabled = ib_document_ouvert
// Reorder : move the status panel to the front (positions counted from 0)
uo_statut.of_move_panel(/*key*/ "etat", /*index*/ 0)
// Remove a panel that is no longer needed
uo_statut.of_remove_panel(/*key*/ "import")
The resize grip #
// On a resizable window, the corner grip is a familiar landmark
uo_statut.ib_show_resize_grip = true
Best practices #
- Give a fixed width to panels whose text changes often (cursor position, counters): the neighboring panels will stop jumping on every refresh.
- Leave the identifier empty for a purely informative panel: that avoids a click that does nothing.
- Save the right-hand side for stable information (time, user, connection) and the left-hand side for the current context.
- Use
is_staterather than colors in the text: the state follows both the light and the dark theme. - Remember to set
is_stateback toSTATE_NONEandii_progressback to a negative value as soon as the alert or the operation is over. - A status bar is not a log: beyond five or six panels, prefer a toaster notification.
- If the progress deserves more than a panel-sized mini bar, move up to the progressbar.
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.