PBToolboxAI v1 ← Site

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 #

Userobjectu_pbt_tilesbox
Item classesn_pbt_tilesbox_group (group) → n_pbt_tilesbox_tile (tile)
Used forOffering a home screen or a feature launcher: clickable tiles, readable from a distance, arranged by topic
Opt-in options

Quick start #

// window open event
n_pbt_tilesbox_group lnv_grp

// of_add_group returns the handle of the group : you attach its tiles to it
lnv_grp = uo_tuiles.of_add_group(/*group_id*/ "gestion", /*title*/ "Management")

lnv_grp.of_add_tile(/*id*/ "clients",   /*label*/ "Customers",   /*icon_file*/ "mono:img\clients.svg",   /*size*/ "medium")
lnv_grp.of_add_tile(/*id*/ "factures",  /*label*/ "Invoices",  /*icon_file*/ "mono:img\factures.svg",  /*size*/ "medium")
lnv_grp.of_add_tile(/*id*/ "stock",     /*label*/ "Stock",     /*icon_file*/ "mono:img\stock.svg",     /*size*/ "small")
// ue_tile_clicked event of uo_tuiles : (string as_group, string as_id)
choose case as_group + "/" + as_id
    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, and additions live on the group handle.

// Mandatory path : group then tile
uo_tuiles.of_group("gestion").of_tile("factures").is_badge = "12"

Events carry the full path as well (as_group then as_id). See Shared foundation · Items.


Properties #

PropertyTypeDefaultPurpose
ib_reorderablebooleanfalseLets users move the tiles with the mouse (raises ue_tile_moved)
is_scrollstringSCROLL_VERTICALScrolling direction: SCROLL_VERTICAL (tiles wrap onto the next line) or SCROLL_HORIZONTAL (columns, home-screen style)
ib_show_group_headersbooleantruefalse 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_durationinteger180Duration in milliseconds of the collapse / expand animation of a group; 0 = instant
ii_tile_unitinteger0Base 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_sizeinteger0Tile 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_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

Methods #

MethodPurpose
of_group (string as_id)n_pbt_tilesbox_groupReturns the handle of a group (created on first access)
of_add_group (string as_group_id, string as_title)n_pbt_tilesbox_groupAdds a group and returns its handle
of_remove_group (string as_id)Removes a group and all of its tiles
of_insert_tile (string as_group, string as_id, string as_text, integer ai_index)Inserts a tile at a precise position within its group (position counted from 0)
of_insert_tile (string as_group, string as_id, 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
of_move_tile (string as_group, string as_id, integer ai_index)Moves an existing tile to another position within its group, keeping its state
of_remove_tile (string as_group, string as_id)Removes a single tile, the rest of the panel is preserved
of_clear ( )Empties the panel (groups and tiles)
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
of_reset ( )Clears the content and resets every property to its default

On a group — n_pbt_tilesbox_group #

MemberTypeDefaultPurpose
is_titlestring""Title shown in the header, rich text markup accepted
ib_collapsedbooleanfalseCollapsed group: its tiles are hidden under the header
ib_enabledbooleantrueWhole group grayed out and inert
ib_visiblebooleantrueGroup hidden, without being removed from the model
of_tile (string as_id)n_pbt_tilesbox_tileReturns the handle of a tile of this group
of_add_tile (as_id, as_label, as_icon_file, as_size)n_pbt_tilesbox_tileAdds a tile to this group and returns its handle

On a tile — n_pbt_tilesbox_tile #

MemberTypeDefaultPurpose
is_sizestringSIZE_MEDIUMSize: SIZE_SMALL, SIZE_MEDIUM, SIZE_WIDE, SIZE_LARGE
il_back_color · il_text_colorlong-1Background and text of this tile, as RGB(r,g,b) (-1 = whatever the theme gives)
il_back_color_hover · il_text_color_hoverlong-1The same two, but under the pointer
is_badgestring""Badge shown in the corner of the tile (a counter, a short status)
il_badge_colorlong0Badge background, as a PowerBuilder RGB value (0 = the color that comes from the theme)
is_live_textstring""Text overlaid on the tile, rich text markup accepted
ib_enabledbooleantrueTile grayed out and not clickable
ib_visiblebooleantrueTile hidden, without being removed from its group
of_add_live_item (string as_text)Adds a face to the live banner; from two faces on, the tile cycles through them
of_clear_live_items ( )Clears the live banner: the tile stops cycling

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 #

SizeFootprintTypical use
small1 cellSecondary shortcut; the caption is not shown, the tooltip takes over
medium2 × 2 cellsReference size: icon and caption
wide4 × 2 cellsElongated tile, ideal for live text
large4 × 4 cellsFlagship tile of the screen

Events #

EventRaised when
ue_tile_clicked (string as_group, string as_id)A tile is clicked
ue_tile_moved (string as_group, string as_id, string as_to_group, long al_index)A tile has been moved: as_group is the source group, as_to_group the destination group, al_index the new position
ue_group_toggled (string as_group, boolean ab_collapsed)A group is collapsed or expanded from its header
ue_tile_context (string as_group, string as_id)Right-click on a tile
ue_tile_resized (string as_group, string as_id, 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 #

n_pbt_tilesbox_group lnv_grp

uo_tuiles.of_clear()
lnv_grp = uo_tuiles.of_add_group(/*group_id*/ "accueil", /*title*/ "Home")

lnv_grp.of_add_tile(/*id*/ "tableau", /*label*/ "Dashboard", /*icon_file*/ "mono:img\chart.svg",  /*size*/ "large")
lnv_grp.of_add_tile(/*id*/ "clients", /*label*/ "Customers",         /*icon_file*/ "mono:img\users.svg",  /*size*/ "medium")
lnv_grp.of_add_tile(/*id*/ "agenda",  /*label*/ "Calendar",          /*icon_file*/ "mono:img\cal.svg",    /*size*/ "wide")
lnv_grp.of_add_tile(/*id*/ "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 #

n_pbt_tilesbox_group lnv_admin

lnv_admin = uo_tuiles.of_add_group(/*group_id*/ "admin", /*title*/ "Administration")
lnv_admin.of_add_tile(/*id*/ "users",  /*label*/ "Users", /*icon_file*/ "mono:img\users.svg", /*size*/ "medium")
lnv_admin.of_add_tile(/*id*/ "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_group = "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(/*group_id*/ "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_group = source group, as_to_group = destination group, al_index = position
if as_group <> as_to_group then
    of_tracer("Tile " + as_id + " moved from " + as_group + " to " + as_to_group)
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", /*id*/ "aide", /*index*/ 0)

// Insert a new tile in second position
uo_tuiles.of_insert_tile(/*group*/ "accueil", /*id*/ "devis", /*text*/ "Quotes", /*index*/ 1)

// Remove a tile without touching the rest
uo_tuiles.of_remove_tile(/*group*/ "accueil", /*id*/ "aide")

Reacting to a right-click #

// ue_tile_context event of uo_tuiles : (as_group, as_id)
// Remember the targeted tile, then open your own context menu
is_groupe_vise = as_group
is_tuile_visee = as_id
of_ouvrir_menu_tuile(PointerX(), PointerY())

Best practices #


← Component reference · Guide contents