tilesbox — u_pbt_tilesbox #
← Component reference · Guide contents
Panel of grouped tiles in home-screen style: four tile sizes, colors, badges, live tiles, collapsible groups and mouse rearranging.
▶ See it live — Demo application, Tiles box tile: the preview, the code behind it and this page, side by side.
At a glance #
| Userobject | u_pbt_tilesbox |
| Item classes | n_pbt_tilesbox_group (group) → n_pbt_tilesbox_tile (tile) |
| Used for | Offering a home screen or a feature launcher: clickable tiles, readable from a distance, arranged by topic |
| Opt-in options | — |
Quick start #
// window open event
// A tile is added at its ADDRESS : the group, then its own id
uo_tuiles.of_add_group(/*key*/ "gestion", /*title*/ "Management")
uo_tuiles.of_add_tile(/*keys*/ "gestion/clients", /*label*/ "Customers", /*icon_file*/ "mono:img\clients.svg", /*size*/ "medium")
uo_tuiles.of_add_tile(/*keys*/ "gestion/factures", /*label*/ "Invoices", /*icon_file*/ "mono:img\factures.svg", /*size*/ "medium")
uo_tuiles.of_add_tile(/*keys*/ "gestion/stock", /*label*/ "Stock", /*icon_file*/ "mono:img\stock.svg", /*size*/ "small")
// ue_tile_clicked event of uo_tuiles : (string as_keys)
choose case as_keys
case "gestion/clients" ; open(w_clients)
case "gestion/factures" ; open(w_factures)
case "gestion/stock" ; open(w_stock)
end choose
The model: groups and tiles #
The panel contains groups, each with its title and its collapsible header. Tiles belong to a group: their identifier is only unique within that group. Access therefore always goes through the full path. Additions live on the component: a handle carries properties and nothing else.
// Mandatory path : group then tile
uo_tuiles.of_tile("gestion/factures").is_badge = "12"
Events carry the full address as well (as_keys, the group then the tile). See Shared foundation · Items.
Properties #
| Property | Type | Default | Purpose |
|---|---|---|---|
ib_reorderable | boolean | false | Lets users move the tiles with the mouse (raises ue_tile_moved) |
is_scroll | string | SCROLL_VERTICAL | Scrolling direction: SCROLL_VERTICAL (tiles wrap onto the next line) or SCROLL_HORIZONTAL (columns, home-screen style) |
ib_show_group_headers | boolean | true | false hides the group headers. Handy when the panel holds only one group: there is nothing to name and the header just eats up height. Without a header there is no chevron either: the groups always show expanded |
ii_anim_duration | integer | 180 | Duration in milliseconds of the collapse / expand animation of a group; 0 = instant |
ii_tile_unit | integer | 0 | Base size of a tile, in pixels: every tile size (small, medium, wide, large) is a multiple of it, so one value makes the whole board denser or airier. 0 gives it back to the theme |
ii_badge_size | integer | 0 | Tile badge height in pixels, for the whole box (0 = the size that comes from the theme). The font size follows on its own. A badge color belongs to the tile because it carries a meaning; its size does not |
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_group (string as_key) → n_pbt_tilesbox_group | Returns the handle of a group (created on first access) |
of_add_group (string as_key, string as_title) → long | Adds a group and returns 0 (-5 on an invalid argument, -2 when the component is not created) |
of_add_tile (string as_keys, string as_text, string as_image, string as_size) → long | Adds a tile at its address, "gestion/clients": the group it lands in, then its own id. Returns 0 (-5 on an invalid argument, -2 when the component is not created) — -5 if the parent is not a group. An overload omits the icon and the size |
of_tile (string as_keys) → n_pbt_tilesbox_tile | Returns the handle of one tile, by its address (created on first access) |
of_add_live_item (string as_keys, string as_text) → long | Adds a face to the live band of a tile, at its address; from two faces on, the tile cycles between them. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_clear_live_items (string as_keys) → long | Clears the live band of one tile: it stops cycling and goes back to its plain face. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_remove_group (string as_key) | Removes a group and all of its tiles. Returns 0 once applied, -2 when the component is not created |
of_insert_tile (string as_keys, string as_text, integer ai_index) | Inserts a tile at a precise position within its group (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_tile (string as_keys, string as_text, string as_image, string as_size, integer ai_index) | Same, with the icon and the size (small / medium / wide / large): a tile is a picture with a label under it, and its size shows in the grid. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_move_tile (string as_keys, integer ai_index) | Moves an existing tile to another position within its group, keeping its state. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_remove_tile (string as_keys) | Removes a single tile, the rest of the panel is preserved. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_clear ( ) | Empties the panel (groups and tiles). Returns 0 once applied, -2 when the component is not created |
of_get_layout ( ) | Reads the current arrangement back as JSON: groups, tiles, order and sizes. Store it, then hand it back with of_set_layout |
of_set_layout (string as_state_json) | Restores an arrangement read with of_get_layout or received with ue_layout_changed. Returns 0 once applied, -5 on an invalid argument (empty key, wrong address), -2 when the component is not created |
of_reset ( ) | Clears the content and resets every property to its default. Returns 0 once applied, -2 when the component is not created |
On a group — n_pbt_tilesbox_group #
| Member | Type | Default | Purpose |
|---|---|---|---|
is_title | string | "" | Title shown in the header, rich text markup accepted |
ib_collapsed | boolean | false | Collapsed group: its tiles are hidden under the header |
ib_enabled | boolean | true | Whole group grayed out and inert |
ib_visible | boolean | true | Group hidden, without being removed from the model |
On a tile — n_pbt_tilesbox_tile #
| Member | Type | Default | Purpose |
|---|---|---|---|
is_title | string | "" | Text shown on the tile. Set by of_add_tile; writing here changes it, reading tells what the tile shows right now |
is_image | string | "" | Icon of the tile (disk path or resources.dll:name). An empty string takes the icon away |
is_size | string | SIZE_MEDIUM | Size: SIZE_SMALL, SIZE_MEDIUM, SIZE_WIDE, SIZE_LARGE |
il_back_color · il_text_color | long | -1 | Background and text of this tile, as RGB(r,g,b) (-1 = whatever the theme gives) |
il_back_color_hover · il_text_color_hover | long | -1 | The same two, but under the pointer |
is_badge | string | "" | Badge shown in the corner of the tile (a counter, a short status) |
il_badge_color | long | 0 | Badge background, as a PowerBuilder RGB value (0 = the color that comes from the theme) |
is_live_text | string | "" | Text overlaid on the tile, rich text markup accepted |
ib_enabled | boolean | true | Tile grayed out and not clickable |
ib_visible | boolean | true | Tile hidden, without being removed from its group |
Icons accept every form recognized by the library: path, mono:, tint:, DLL resource. On a large tile, prefer a crisp high-resolution image or an SVG.
The four sizes #
| Size | Footprint | Typical use |
|---|---|---|
small | 1 cell | Secondary shortcut; the caption is not shown, the tooltip takes over |
medium | 2 × 2 cells | Reference size: icon and caption |
wide | 4 × 2 cells | Elongated tile, ideal for live text |
large | 4 × 4 cells | Flagship tile of the screen |
Events #
| Event | Raised when |
|---|---|
ue_tile_clicked (string as_keys) | A tile is clicked |
ue_tile_moved (string as_keys, string as_to_keys, long al_index) | A tile has been moved: as_keys is the address it came from, as_to_keys the destination group, al_index the new position |
ue_group_toggled (string as_key, boolean ab_collapsed) | A group is collapsed or expanded from its header |
ue_tile_context (string as_keys) | Right-click on a tile |
ue_tile_resized (string as_keys, string as_size) | The size of a tile has changed; as_size carries the new size |
ue_layout_changed (string as_layout_json) | The arrangement changed — the user moved or resized a tile. Carries the whole layout, not just what moved |
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 #
Mixed sizes within a single group #
uo_tuiles.of_clear()
uo_tuiles.of_add_group(/*key*/ "accueil", /*title*/ "Home")
uo_tuiles.of_add_tile(/*keys*/ "accueil/tableau", /*label*/ "Dashboard", /*icon_file*/ "mono:img\chart.svg", /*size*/ "large")
uo_tuiles.of_add_tile(/*keys*/ "accueil/clients", /*label*/ "Customers", /*icon_file*/ "mono:img\users.svg", /*size*/ "medium")
uo_tuiles.of_add_tile(/*keys*/ "accueil/agenda", /*label*/ "Calendar", /*icon_file*/ "mono:img\cal.svg", /*size*/ "wide")
uo_tuiles.of_add_tile(/*keys*/ "accueil/aide", /*label*/ "Help", /*icon_file*/ "mono:img\help.svg", /*size*/ "small")
Badge, color and live tile #
n_pbt_tilesbox_tile lnv_tuile
// A badge signals a number of pending items
uo_tuiles.of_group("accueil").of_tile("clients").is_badge = String(ll_nouveaux)
// Red when the backlog becomes critical, theme color otherwise (0)
if ll_nouveaux > 50 then
uo_tuiles.of_group("accueil").of_tile("clients").il_badge_color = RGB(200, 30, 30)
else
uo_tuiles.of_group("accueil").of_tile("clients").il_badge_color = 0
end if
// A dedicated color brings a tile forward : background, text, and what each
// becomes under the pointer
lnv_tuile = uo_tuiles.of_group("accueil").of_tile("tableau")
lnv_tuile.il_back_color = RGB(0, 103, 192)
lnv_tuile.il_back_color_hover = RGB(0, 80, 150)
lnv_tuile.il_text_color = RGB(255, 255, 255)
// LIVE tile : each face added cycles in turn on the tile
lnv_tuile = uo_tuiles.of_group("accueil").of_tile("agenda")
lnv_tuile.of_clear_live_items()
lnv_tuile.of_add_live_item(/*text*/ "3 appointments today")
lnv_tuile.of_add_live_item(/*text*/ "Team meeting at 2:00 PM")
lnv_tuile.of_add_live_item(/*text*/ "2 overdue follow-ups")
Fixed text rather than a cycling banner #
// is_live_text puts ONE permanent text on the tile (rich text markup accepted)
uo_tuiles.of_group("accueil").of_tile("tableau").is_live_text = "[b]48[/b] orders today"
Collapsible groups #
uo_tuiles.of_add_group(/*key*/ "admin", /*title*/ "Administration")
uo_tuiles.of_add_tile(/*keys*/ "admin/users", /*label*/ "Users", /*icon_file*/ "mono:img\users.svg", /*size*/ "medium")
uo_tuiles.of_add_tile(/*keys*/ "admin/params", /*label*/ "Settings", /*icon_file*/ "mono:img\gear.svg", /*size*/ "medium")
// This group starts collapsed : users open it if they need it
lnv_admin.ib_collapsed = true
// A whole group can also be grayed out according to permissions
lnv_admin.ib_enabled = (is_profil = "ADMIN")
// ue_group_toggled event of uo_tuiles
if as_keys = "admin" and not ab_collapsed then of_tracer("Administration pane opened")
A single-group panel, without a header #
// A single group has nothing to name : its header just eats up height.
// Without a header there is no chevron either : the tiles always stay visible.
uo_tuiles.ib_show_group_headers = false
uo_tuiles.of_add_group(/*key*/ "tout", /*title*/ "")
Moving a tile between two groups #
With ib_reorderable = true, users drag a tile wherever they want, including from one group to another. The ue_tile_moved event delivers both groups and the new position.
uo_tuiles.ib_reorderable = true // false by default : ask for it
// ue_tile_moved event of uo_tuiles
// as_keys = where it comes from, as_to_keys = where it goes, al_index = position
n_pbt_utils lnv_utils // autoinstantiate : nothing to create, nothing to destroy
if as_keys <> as_to_keys then
of_tracer("Tile " + lnv_utils.of_leaf(as_keys) + " moved from " + lnv_utils.of_parent(as_keys) + " to " + as_to_keys)
end if
uo_tuiles.of_get_layout() // request the layout in order to store it
// ue_layout_changed event of uo_tuiles : store the chosen layout
is_disposition = as_layout_json
// On the next opening : restore the screen the way the user had arranged it
if is_disposition <> "" then uo_tuiles.of_set_layout(is_disposition)
To freeze the screen, simply turn rearranging off:
uo_tuiles.ib_reorderable = false
Rearranging from code #
// Put the "aide" tile at the head of its group (positions counted from 0)
uo_tuiles.of_move_tile(/*group*/ "accueil", /*key*/ "aide", /*index*/ 0)
// Insert a new tile in second position
uo_tuiles.of_insert_tile(/*group*/ "accueil", /*key*/ "devis", /*text*/ "Quotes", /*index*/ 1)
// Remove a tile without touching the rest
uo_tuiles.of_remove_tile(/*group*/ "accueil", /*key*/ "aide")
Reacting to a right-click #
// ue_tile_context event of uo_tuiles : (as_keys)
// Remember the targeted tile, then open your own context menu
n_pbt_utils lnv_utils // autoinstantiate : nothing to create, nothing to destroy
// One address : split it if you need the two halves.
is_groupe_vise = lnv_utils.of_parent(as_keys)
is_tuile_visee = lnv_utils.of_leaf(as_keys)
of_ouvrir_menu_tuile(PointerX(), PointerY())
Best practices #
- One
largetile per screen is enough: it is the main entry point, the rest must stay readable. smalltiles do not show their caption — always fill in the tooltip of the item.- Reserve
il_back_colorfor the tiles that must stand out: beyond two or three colors, the screen loses its hierarchy. And when you set a pale background, setil_text_colorwith it — the theme's text is not guaranteed readable on top of it. - Prefer
of_add_live_item(cycling) overis_live_text(fixed text) when you have several pieces of information to convey on the same tile. - If you leave rearranging active, store the layout through
of_get_layout/ue_layout_changedand replayof_set_layouton opening. - Use
ib_visibleandib_enabled(group or tile) to adapt the panel to the user's permissions, rather than rebuilding it. - When there is not enough room for tiles, prefer the compact side navigation of listbar; for frequent actions, the toolbar.
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.