stepbar — u_pbt_stepbar #
← Component reference · Guide contents
Step trail for a wizard: the steps already completed, the current one and the ones still ahead, horizontally or vertically.
▶ See it live — Demo application, Stepbar tile: the preview, the code behind it and this page, side by side.
At a glance #
| Userobject | u_pbt_stepbar |
| Item class | n_pbt_stepbar_step (one step) |
| Used for | Showing users where they stand in a wizard, a multi-page form or an approval process |
| Principle | You declare the steps, then you move ii_current: the states work themselves out |
Quick start #
// window open event
uo_etapes.of_add_step(/*key*/ "compte", /*label*/ "Account")
uo_etapes.of_add_step(/*key*/ "profil", /*label*/ "Profile")
uo_etapes.of_add_step(/*key*/ "paiement", /*label*/ "Payment")
uo_etapes.of_add_step(/*key*/ "fin", /*label*/ "Confirmation")
// Current step (1 = the first one)
uo_etapes.ii_current = 1
// Next button of the wizard
uo_etapes.ii_current = uo_etapes.ii_current + 1
The model: one step, three automatic states #
A step has no state for you to manage by hand. It is derived from its position relative to ii_current:
| Position | State | Rendering |
|---|---|---|
| Before the current step | done — completed | Checked badge |
| The current step | current — in progress | Highlighted badge |
| After the current step | todo — upcoming | Numbered badge, subdued shade |
A fourth state, error, is never reached automatically: you force it on a step that has failed (see below).
Properties #
| Property | Type | Default | Purpose |
|---|---|---|---|
ii_current | integer | 1 | Current step, numbered from 1 |
is_position | string | "top" | Orientation: top / bottom (horizontal trail) or start / end (vertical trail) — constants POSITION_TOP, POSITION_BOTTOM, POSITION_START, POSITION_END. START/END are logical and follow the writing direction |
is_navigation_mode | string | "free" | What a click may reach: NAV_FREE (any step, the default), NAV_BACKWARD (only the steps already passed — go back, never jump ahead) or NAV_NONE (nothing: a plain progress indicator, driven by your code alone). Whatever stays clickable raises ue_step_clicked; the bar itself never moves on a click |
is_overflow_mode | string | "auto" | Too many steps for the width: OVERFLOW_AUTO compacts the bar below a readable floor per step (every step becomes a dot, only the current one keeps its label, and all of them stay clickable), OVERFLOW_SCROLL keeps the labels and scrolls, keeping the current step in view, OVERFLOW_SHRINK squeezes them until they ellipsize. A vertical trail never compacts |
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 |
Properties of a step — n_pbt_stepbar_step #
Obtained through of_step(id):
| Property | Type | Default | Purpose |
|---|---|---|---|
is_state | string | STATE_TODO | Forces the state of the step: STATE_TODO, STATE_CURRENT, STATE_DONE, STATE_ERROR. STATE_AUTO = back to automatic computation; reading it back returns the step's effective state, not the forced one |
is_text | string | — | Changes the caption of the step, rich text markup accepted |
is_description | string | "" | Second line of the step — Optional, a date, an amount. Rich text markup accepted. Announced to a screen reader as the step's description, after its name. An empty string removes it; a compacted bar drops it to stay one line tall |
is_image | string | "" | Icon displayed in place of the step's rank (accepted forms) |
ib_enabled | boolean | true | Step enabled; a disabled step no longer responds to clicks |
ib_visible | boolean | true | Hides the step without removing it from the model |
Methods #
| Method | Purpose |
|---|---|
of_add_step (string as_key, string as_label) | Adds a step at the end of the trail. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_add_step (string as_key, string as_label, string as_icon_file) | The same, with the icon shown in place of the step's rank. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_add_step (string as_key, string as_label, string as_icon_file, string as_desc) | The same, with the icon and the second line. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_insert_step (string as_key, string as_label, integer ai_index) | Inserts a step at the 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_insert_step (string as_key, string as_label, string as_icon_file, integer ai_index) | The same, with the icon. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_insert_step (string as_key, string as_label, string as_icon_file, string as_desc, integer ai_index) | The same, with the icon and the second line. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_move_step (string as_key, integer ai_index) | Moves an existing step. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_next ( ) | Moves to the next step, skipping the hidden and the disabled ones — the ones ii_current + 1 would land on. Stops on the last one it can reach. The navigation mode is not consulted: it restricts the user, not your code. No question is asked, but ue_step_changed is raised. Returns 0 once applied, -2 when the component is not created |
of_previous ( ) | Moves back to the previous step, same rules. From the "everything done" position it comes back to the last step. Returns 0 once applied, -2 when the component is not created |
of_remove_step (string as_key) | Removes a step; 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_clear_steps ( ) | Empties the trail. Returns 0 once applied, -2 when the component is not created |
of_step (string as_key) → n_pbt_stepbar_step | Handle to a step, to set its properties |
of_reset ( ) | Clears the steps and resets every property 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 |
The third argument is the icon, as everywhere else in the library (
of_add_itemof the listbar,of_add_panelof the statusbar,of_add_tileof the tilesbox). The second line comes after it.
Events #
| Event | Raised when |
|---|---|
ue_step_clicked (integer ai_index, string as_key) | The user clicked a step. The bar does not move: script this event, run your checks, then set ii_current if you agree |
ue_step_changed (integer ai_from_index, string as_from_key, integer ai_index, string as_key) | The bar has moved: ii_current was set, or of_next / of_previous was called. A click never lands here |
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) |
The bar does NOT navigate on its own. A click reports (ue_step_clicked) and nothing else: the bar stays where it is. You are the one who moves it, by setting ii_current or by calling of_next / of_previous — and those moves announce themselves through ue_step_changed.
This split is not a constraint, it is what the component means: a step bar mirrors a workflow your application drives. Reaching step 3 usually means a form was valid and a record was saved; no click can decide that for you.
ue_step_clicked carries the step aimed at, ue_step_changed also carries the step left — by business identifier as much as by rank. That pair is what lets you write "going back is allowed, jumping ahead is not" in one line.
is_navigation_modestays the filter on the click:NAV_NONEraises nothing at all,NAV_BACKWARDonly lets the already-completed steps be clicked.
Keyboard #
The bar is a single tab stop: once reached, it is entirely navigable from the keyboard.
| Key | Effect |
|---|---|
| Arrows | Move the focus from one step to the next, wrapping around; hidden, disabled or out-of-reach steps (see is_navigation_mode) are skipped |
| Home / End | First / last reachable step |
| Enter or Space | Reports a click on the focused step (ue_step_clicked) — the bar does not move |
The arrows do not select, unlike the tabs of a dockcontainer. Reaching a step asks your application a question: walking an eight-step bar would send eight of them, and a refusal halfway through would leave the focus and the current step out of sync.
Every step is a real button: it carries its label and its state in its spoken name ("Account - completed"), the current step is marked aria-current="step", and a disabled step is a disabled button — not merely greyed-out text. The numbered bullet is not read aloud: a rank teaches nothing.
Examples #
Moving through the wizard #
uo_etapes.of_add_step(/*key*/ "compte", /*label*/ "Account")
uo_etapes.of_add_step(/*key*/ "profil", /*label*/ "Profile")
uo_etapes.of_add_step(/*key*/ "paiement", /*label*/ "Payment")
uo_etapes.of_add_step(/*key*/ "fin", /*label*/ "Confirmation")
// Steps 1 and 2 automatically switch to "completed" (checked)
uo_etapes.ii_current = 3
Flagging a step in error #
// The state of a step is forced through its handle
uo_etapes.of_step(/*key*/ "profil").is_state = n_pbt_stepbar_step.STATE_ERROR
// Once the problem is fixed, hand control back to automatic computation
uo_etapes.of_step(/*key*/ "profil").is_state = n_pbt_stepbar_step.STATE_AUTO
Vertical trail #
// left / right : the trail is drawn vertically, ideal alongside a form
uo_etapes.is_position = uo_etapes.POSITION_START
// The THIRD argument is the icon : it takes the place of the step rank
uo_etapes.of_add_step(/*key*/ "compte", /*label*/ "Account", /*icon*/ "mono:img\packimages.dll:svg/samples/folder-open")
Rich captions on two lines #
// The caption of a step accepts rich text markup
uo_etapes.of_add_step("compte", "[b]Account[/b][br][size=9](sign-in)")
uo_etapes.of_add_step("profil", "[b]Profile[/b][br][size=9](your details)")
uo_etapes.of_add_step("paiement", "[b]Payment[/b][br][size=9](card)")
uo_etapes.of_add_step("fin", "[accent][b]Done[/b][/accent]")
uo_etapes.ii_current = 2
Click navigation #
// event ue_step_clicked de uo_etapes : (integer ai_index, string as_key)
// The bar has NOT moved : this is where you decide.
if ai_index > uo_etapes.ii_current then
MessageBox("Wizard", "Finish the current step before moving on.")
return
end if
uo_etapes.ii_current = ai_index
Conditional step #
// A returning customer has no "Profile" step to fill in
uo_etapes.of_step("profil").ib_visible = false
Best practices #
- Give every step a stable business identifier (
"paiement"): that is what you receive inue_step_clickedandue_step_changed, not a number that shifts on the slightest insertion. - Let the component compute the states; force
is_stateonly for errors. - Clicking a step is just a signal: it is up to you to allow (or refuse) the jump, especially towards a step not yet reached.
- Wrap the declaration of the steps in
of_set_redraw(false)/of_set_redraw(true)when there are many of them. - Call
of_reset()before reusing the same trail for another wizard.
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.