tilesbox — u_pbt_tilesbox #
← Référence des composants · Sommaire du guide
Panneau de tuiles groupées façon écran d'accueil : quatre tailles de tuile, couleurs, pastilles, tuiles animées, groupes repliables et réorganisation à la souris.
▶ Le voir en vrai — Application de démonstration, tuile Tiles box : l'aperçu, le code qui le produit et cette page, côte à côte.
En bref #
| Userobject | u_pbt_tilesbox |
| Classes d'items | n_pbt_tilesbox_group (groupe) → n_pbt_tilesbox_tile (tuile) |
| Sert à | Offrir un écran d'accueil ou un lanceur de fonctions : des tuiles cliquables, lisibles de loin, rangées par thème |
| Options opt-in | ib_reorderable : déplacer et redimensionner les tuiles à la souris |
Démarrage rapide #
// event open de la fenetre
// Une tuile s ajoute a son ADRESSE : le groupe, puis son propre identifiant
uo_tiles.of_add_group(/*key*/ "office", /*title*/ "Gestion")
// Puis ses tuiles, chacune avec sa tailleuo_tiles.of_add_tile(/*keys*/ "office/clients", /*label*/ "Clients", /*icon_file*/ "mono:img\clients.svg", /*size*/ "medium")
uo_tiles.of_add_tile(/*keys*/ "office/invoices", /*text*/ "Factures", /*image*/ "mono:img\factures.svg", /*size*/ "medium")
uo_tiles.of_add_tile(/*keys*/ "office/stock", /*text*/ "Stock", /*image*/ "mono:img\stock.svg", /*size*/ "small")
// event ue_tile_clicked de uo_tiles : (string as_keys)
choose case as_keys
case "office/clients" ; open(w_clients)
case "office/invoices" ; open(w_invoices)
case "office/stock" ; open(w_stock)
end choose
Le modèle : groupes et tuiles #
Le panneau contient des groupes, chacun avec son titre et son entête repliable. Les tuiles appartiennent à un groupe : leur identifiant n'est unique qu'à l'intérieur de ce groupe. L'accès passe donc toujours par le chemin complet. Les ajouts, eux, vivent sur le composant : un handle ne porte que des propriétés.
// Chemin obligatoire : groupe puis tuile
uo_tiles.of_tile(/*keys*/ "office/invoices").is_badge = "12"
Les events portent eux aussi l'adresse complete (as_keys, le groupe puis la tuile). Voir Socle commun · Les items.
Propriétés #
| Propriété | Type | Défaut | Rôle |
|---|---|---|---|
ib_reorderable | boolean | false | Autorise l'utilisateur à réorganiser les tuiles : à la souris, ou au clavier par Ctrl+Gauche/Droite (une place dans le groupe, dans le sens de lecture) et Ctrl+Haut/Bas (vers le groupe précédent ou suivant) ; le clic droit redimensionne. Souris et clavier déclenchent le même ue_tile_moved |
is_scroll | string | SCROLL_HORIZONTAL | Sens de défilement : SCROLL_VERTICAL (les tuiles passent à la ligne) ou SCROLL_HORIZONTAL (colonnes façon écran d'accueil) |
ib_show_group_headers | boolean | true | false masque les entêtes de groupe. Utile quand le panneau ne contient qu'un seul groupe : il n'y a rien à nommer et l'entête ne fait que manger de la hauteur. Sans entête il n'y a plus de chevron : les groupes s'affichent toujours dépliés |
ii_anim_duration | integer | 180 | Durée en millisecondes de l'animation de repli / dépli d'un groupe ; 0 = instantané |
ii_tile_unit | integer | 0 | Taille de base d une tuile, en pixels : chaque format (petite, moyenne, large, grande) en est un multiple, donc une valeur rend tout le tableau plus dense ou plus aéré. 0 la rend au thème |
ii_badge_size | integer | 0 | Hauteur des pastilles de tuile en pixels, pour toute la boîte (0 = la taille qui vient du thème). La taille de la police suit toute seule. La couleur d une pastille appartient à la tuile parce qu elle veut dire quelque chose ; sa taille, non |
is_theme_style | string | "" | Style visuel du composant (constantes THEME_STYLE_*) ; vide = celui de l'application, suivi à chaque changement |
is_theme_mode | string | "" | Variante claire ou sombre (constantes THEME_MODE_*) ; vide = celle de l'application, suivie à chaque changement |
il_theme_accent | long | -1 | Couleur d'accent de ce composant (-1 = l'accent de l'application, ou celui du thème) |
is_tooltip | string | "" | Info-bulle simple affichée au survol du composant |
is_super_tooltip_title | string | "" | Titre de l'info-bulle enrichie (prend le pas sur is_tooltip) |
is_super_tooltip_text | string | "" | Texte de l'info-bulle enrichie (balisage riche accepté) |
is_super_tooltip_image | string | "" | Image de l'info-bulle enrichie |
Méthodes #
| Méthode | Rôle | |
|---|---|---|
of_group (string as_key) → n_pbt_tilesbox_group | Rend le handle d'un groupe (créé au premier accès). Sur un groupe qui n'existe pas, il n'écrit rien — il ne crée jamais le groupe, of_add_group le fait ; une clé qui ne peut pas nommer un groupe (vide, avec / ou ` | `) rend un handle inerte qui se relit vide |
of_add_group (string as_key, string as_title) → long | Ajoute un groupe. Renvoie 0 une fois appliqué, -5 si la clé est vide, contient un / ou un ` | , ou est déjà prise, -2` si le composant n'est pas créé |
of_add_tile (string as_keys, string as_text, string as_image, string as_size) → long | Ajoute une tuile à son adresse, "office/clients" : le groupe où elle atterrit, puis son propre identifiant. Renvoie 0 une fois appliqué, -5 si l'adresse n'est pas groupe/tuile, si le groupe n'a pas été ajouté par of_add_group, si la clé est déjà prise dans ce groupe (ou vide, ou contient un ` | ), -2` si le composant n'est pas créé. Une surcharge omet l'icône et la taille |
of_tile (string as_keys) → n_pbt_tilesbox_tile | Rend le handle d'une tuile, par son adresse (créé au premier accès). Une adresse qui n'est pas groupe/tuile rend un handle inerte : il n'écrit rien et se lit vide | |
of_add_live_item (string as_keys, string as_text) → long | Ajoute une face au bandeau animé d'une tuile, à son adresse ; à partir de deux faces, la tuile les fait défiler. La première face efface is_live_text ; of_tile(adresse).of_count() lit le nombre de faces. Renvoie 0 une fois appliqué, -5 sur un texte vide ou si aucune tuile ne vit à cette adresse, -2 si le composant n'est pas créé | |
of_clear_live_items (string as_keys) → long | Vide le bandeau animé d'une tuile : elle cesse de défiler et retrouve sa face simple. Renvoie 0 une fois appliqué, -5 si aucune tuile ne vit à cette adresse, -2 si le composant n'est pas créé | |
of_remove_group (string as_key) | Supprime un groupe et toutes ses tuiles. Renvoie 0 une fois appliqué, -5 s'il n'existe pas de tel groupe, -2 si le composant n'est pas créé | |
of_insert_tile (string as_keys, string as_text, integer ai_index) | Insère une tuile à une position précise dans son groupe (position comptée à partir de 1). Renvoie 0 une fois appliqué, -5 pour les mêmes refus que of_add_tile, -2 si le composant n'est pas créé | |
of_insert_tile (string as_keys, string as_text, string as_image, string as_size, integer ai_index) | Idem, avec l’icône et la taille (small / medium / wide / large) : une tuile est une image avec un libellé dessous, et sa taille se voit dans la grille. Renvoie 0 une fois appliqué, -5 pour les mêmes refus que of_add_tile, -2 si le composant n'est pas créé | |
of_move_tile (string as_keys, integer ai_index) | Déplace une tuile existante à une autre position de son groupe, en conservant son état. Renvoie 0 une fois appliqué, -5 si aucune tuile ne vit à cette adresse, -2 si le composant n'est pas créé | |
of_remove_tile (string as_keys) | Supprime une seule tuile, le reste du panneau est préservé. Renvoie 0 une fois appliqué, -5 si aucune tuile ne vit à cette adresse, -2 si le composant n'est pas créé | |
of_clear ( ) | Vide le panneau (groupes et tuiles) ; les handles donnés pour eux sont libérés. Renvoie 0 une fois appliqué, -2 si le composant n'est pas créé | |
of_get_layout ( ) | Relit la disposition courante en JSON : les groupes dans leur ordre, repliés ou non, visibles ou non, et leurs tuiles dans leur ordre avec leur taille et leur visibilité. Un texte opaque : à stocker tel quel, puis à rendre par of_set_layout | |
of_set_layout (string as_state_json) | Restaure une disposition lue avec of_get_layout ou reçue par ue_layout_changed : ordre, groupes repliés, tailles et visibilité. Une tuile se retrouve par son groupe et sa clé ; ce que la disposition ne nomme pas garde sa place. Ne lève aucun événement. Renvoie 0 une fois appliqué, -5 sur un texte vide ou qui n'est pas du JSON, -2 si le composant n'est pas créé | |
of_reset ( ) | Vide le contenu et remet les propriétés à leur défaut. Renvoie 0 une fois appliqué, -2 si le composant n'est pas créé |
Sur un groupe — n_pbt_tilesbox_group #
| Membre | Type | Défaut | Rôle |
|---|---|---|---|
is_title | string | la clé | Titre affiché dans l'entête, balisage riche accepté |
ib_collapsed | boolean | false | Groupe replié : ses tuiles sont masquées sous l'entête. Le poser lève ue_group_toggled quand l'état change, comme un clic sur l'entête |
ib_enabled | boolean | true | Groupe entier grisé et inerte : son entête ne le replie plus, ses tuiles ne répondent plus, aucune tuile n'y tombe |
ib_visible | boolean | true | Groupe masqué, sans être supprimé du modèle |
il_back_color · il_text_color · il_back_color_hover · il_text_color_hover · il_accent | long | -1 | Couleurs de l'entête du groupe — fond, titre, les deux sous le pointeur, et un filet d'accent sous l'entête. Elles ne descendent pas sur les tuiles, qui gardent les leurs |
Sur une tuile — n_pbt_tilesbox_tile #
| Membre | Type | Défaut | Rôle |
|---|---|---|---|
is_title | string | "" | Texte affiché sur la tuile. Posé par of_add_tile ; l'écrire ici le change, le lire dit ce que la tuile affiche en ce moment |
is_image | string | "" | Icône de la tuile (chemin disque ou resources.dll:nom). Une chaîne vide retire l'icône |
is_size | string | SIZE_MEDIUM | Taille : SIZE_SMALL, SIZE_MEDIUM, SIZE_WIDE, SIZE_LARGE |
il_back_color · il_text_color | long | -1 | Fond et texte propres à la tuile, en RGB(r,v,b) (-1 = ce que donne le thème) |
il_back_color_hover · il_text_color_hover | long | -1 | Les deux mêmes, mais sous le pointeur |
is_badge | string | "" | Pastille affichée dans l'angle de la tuile (un compteur, un état court) |
il_badge_color | long | -1 | Fond de la pastille, en RGB PowerBuilder (-1 = la couleur qui vient du thème ; 0 est le noir) |
is_live_text | string | "" | Texte fixe superposé à la tuile ; la première face de of_add_live_item l'efface (il se relit alors vide), balisage riche accepté |
ib_enabled | boolean | true | Tuile grisée et non cliquable |
ib_visible | boolean | true | Tuile masquée, sans être retirée de son groupe |
Les icônes acceptent toutes les formes reconnues par la bibliothèque : chemin, mono:, tint:, ressource de DLL. Sur une grande tuile, préférez une image nette en haute définition ou un SVG.
Les quatre tailles #
| Taille | Encombrement | Usage typique |
|---|---|---|
small | 1 case | Raccourci secondaire ; le libellé n'est pas affiché, l'info-bulle prend le relais |
medium | 2 × 2 cases | Taille de référence : icône et libellé |
wide | 4 × 2 cases | Tuile allongée, idéale pour un texte animé |
large | 4 × 4 cases | Tuile vedette de l'écran |
Événements #
| Événement | Déclenché quand |
|---|---|
ue_tile_clicked (string as_keys) | Une tuile est cliquée |
ue_tile_moved (string as_keys, string as_to_key, long al_index) | L'utilisateur a déplacé une tuile, à la souris ou par Ctrl+flèches (of_move_tile ne lève rien) : as_keys est l'adresse de départ, as_to_key le groupe d'arrivée, al_index la nouvelle position |
ue_group_toggled (string as_key, boolean ab_collapsed) | Un groupe est replié ou déplié : depuis son entête, ou par son ib_collapsed posé par votre code (rien quand il est déjà dans cet état) |
ue_tile_context (string as_keys) | Clic droit sur une tuile |
ue_tile_resized (string as_keys, string as_size) | L'utilisateur a donné une autre taille à une tuile depuis son menu du clic droit (affiché seulement quand ib_reorderable vaut true) ; as_size porte la nouvelle taille |
ue_layout_changed (string as_layout_json) | L'utilisateur a changé l'arrangement : une tuile déplacée, une tuile redimensionnée depuis son menu, un groupe replié ou déplié depuis son entête. Porte la disposition entière, le même texte que of_get_layout. Ce que l'application change par le code ne le lève pas (le ib_collapsed d'un groupe lève seulement ue_group_toggled) |
ue_ready ( ) | Le composant a fini de charger ; tout ce qui a été envoyé avant a été rejoué |
ue_runtime_missing ( ) | Le runtime WebView2 est absent : le composant reste vide |
ue_bg_color (long al_color) | Le composant a calculé sa couleur de fond de thème ; l'userobject l'a déjà adoptée (backcolor) |
Exemples #
Tailles mélangées dans un même groupe #
// Repartir d'une boite vide, avec un groupe
uo_tiles.of_clear()
uo_tiles.of_add_group(/*key*/ "home", /*title*/ "Accueil")
// Quatre tuiles, de quatre tailles
uo_tiles.of_add_tile(/*keys*/ "home/dashboard", /*text*/ "Tableau de bord", /*image*/ "mono:img\chart.svg", /*size*/ "large")
uo_tiles.of_add_tile(/*keys*/ "home/clients", /*text*/ "Clients", /*image*/ "mono:img\users.svg", /*size*/ "medium")
uo_tiles.of_add_tile(/*keys*/ "home/agenda", /*text*/ "Agenda", /*image*/ "mono:img\cal.svg", /*size*/ "wide")
uo_tiles.of_add_tile(/*keys*/ "home/help", /*text*/ "Aide", /*image*/ "mono:img\help.svg", /*size*/ "small")
Pastille, couleur et tuile animée #
// Local variables
n_pbt_tilesbox_tile lnv_tile
// Une pastille signale un nombre d'elements en attente
uo_tiles.of_tile(/*keys*/ "home/clients").is_badge = String(ll_new_count)
// Rouge quand le retard devient critique, couleur du theme sinon (-1)
if ll_new_count > 50 then
uo_tiles.of_tile(/*keys*/ "home/clients").il_badge_color = RGB(/*red*/ 200, /*green*/ 30, /*blue*/ 30)
else
uo_tiles.of_tile(/*keys*/ "home/clients").il_badge_color = -1
end if
// Une couleur propre met une tuile en avant : fond, texte, et ce que
// chacun devient sous le pointeur
lnv_tile = uo_tiles.of_tile(/*keys*/ "home/dashboard")
lnv_tile.il_back_color = RGB(/*red*/ 0, /*green*/ 103, /*blue*/ 192)
lnv_tile.il_back_color_hover = RGB(/*red*/ 0, /*green*/ 80, /*blue*/ 150)
lnv_tile.il_text_color = RGB(/*red*/ 255, /*green*/ 255, /*blue*/ 255)
// Tuile ANIMEE : chaque face ajoutee defile a son tour sur la tuile. Une face
// s ajoute depuis le COMPOSANT, a l adresse de la tuile
uo_tiles.of_clear_live_items(/*keys*/ "home/agenda")
uo_tiles.of_add_live_item(/*keys*/ "home/agenda", /*text*/ "3 rendez-vous aujourd'hui")
uo_tiles.of_add_live_item(/*keys*/ "home/agenda", /*text*/ "Reunion equipe a 14h00")
uo_tiles.of_add_live_item(/*keys*/ "home/agenda", /*text*/ "2 relances en retard")
Un texte fixe plutôt qu'un défilement #
// is_live_text pose UN texte permanent sur la tuile (balisage riche accepte)
uo_tiles.of_tile(/*keys*/ "home/dashboard").is_live_text = "[b]48[/b] commandes du jour"
Groupes repliables #
// Local variables
n_pbt_tilesbox_group lnv_admin
// Un groupe et ses deux tuiles, puis une poignee sur le groupe
uo_tiles.of_add_group(/*key*/ "admin", /*title*/ "Administration")
uo_tiles.of_add_tile(/*keys*/ "admin/users", /*text*/ "Utilisateurs", /*image*/ "mono:img\users.svg", /*size*/ "medium")
uo_tiles.of_add_tile(/*keys*/ "admin/params", /*text*/ "Parametres", /*image*/ "mono:img\gear.svg", /*size*/ "medium")
lnv_admin = uo_tiles.of_group(/*key*/ "admin")
// Ce groupe demarre replie : l'utilisateur l'ouvre s'il en a besoin
lnv_admin.ib_collapsed = true
// Un groupe entier peut aussi etre grise selon les droits
lnv_admin.ib_enabled = (is_profile = "ADMIN")
// event ue_group_toggled de uo_tiles
if as_key = "admin" and not ab_collapsed then of_trace("Ouverture du volet administration")
Un panneau à groupe unique, sans entête #
// Un seul groupe n'a rien a nommer : son entete ne fait que manger de la hauteur.
// Sans entete, plus de chevron non plus : les tuiles restent toujours visibles.
uo_tiles.ib_show_group_headers = false
uo_tiles.of_add_group(/*key*/ "all", /*title*/ "")
Déplacer une tuile entre deux groupes #
Avec ib_reorderable = true, l'utilisateur fait glisser une tuile où il veut, y compris d'un groupe vers un autre. L'event ue_tile_moved livre les deux groupes et la nouvelle position. Au clavier, la tuile qui a le focus avance ou recule d'une place par Ctrl+Gauche/Droite (dans le sens de lecture : inversé en droite à gauche) et passe au groupe précédent ou suivant par Ctrl+Haut/Bas — même ue_tile_moved, mêmes refus (clé déjà prise, groupe désactivé ou replié). La touche Tab ne s'arrête qu'une fois par groupe : les flèches parcourent les tuiles.
// Laisser l'utilisateur reorganiser les tuiles : faux par defaut, a demander
uo_tiles.ib_reorderable = true
// event ue_tile_moved de uo_tiles
// as_keys = d'ou elle vient, as_to_key = ou elle va, al_index = position
n_pbt_utils lnv_utils // autoinstantiate : rien a creer, rien a detruire
if lnv_utils.of_parent(/*keys*/ as_keys) <> as_to_key then
of_trace("Tuile " + lnv_utils.of_leaf(/*keys*/ as_keys) + " deplacee de " + lnv_utils.of_parent(/*keys*/ as_keys) + " vers " + as_to_key)
end if
// event ue_layout_changed de uo_tiles : conserver la disposition choisie
is_layout_json = as_layout_json
// A l'ouverture suivante : restituer l'ecran tel que l'utilisateur l'avait range
if is_layout_json <> "" then uo_tiles.of_set_layout(/*state_json*/ is_layout_json)
Pour figer l'écran, il suffit de couper la réorganisation :
// Freeze the screen : the tiles stay where they are
uo_tiles.ib_reorderable = false
Réorganiser depuis le code #
// Placer la tuile "help" en tete de son groupe (positions comptees a partir de 1)
uo_tiles.of_move_tile(/*keys*/ "home/help", /*index*/ 1)
// Inserer une nouvelle tuile en deuxieme position
uo_tiles.of_insert_tile(/*keys*/ "home/quotes", /*text*/ "Devis", /*index*/ 2)
// Retirer une tuile sans toucher au reste
uo_tiles.of_remove_tile(/*keys*/ "home/help")
// Chaque appel rend -5 si l adresse ne nomme rien (ou, a l insertion, une cle deja prise)
Réagir au clic droit #
// event ue_tile_context de uo_tiles : (as_keys)
// Retenir la tuile visee, puis ouvrir votre propre menu contextuel
n_pbt_utils lnv_utils // autoinstantiate : rien a creer, rien a detruire
// Une seule adresse : la decouper si les deux moities servent.
is_target_group = lnv_utils.of_parent(/*keys*/ as_keys)
is_target_tile = lnv_utils.of_leaf(/*keys*/ as_keys)
of_open_tile_menu(PointerX(), PointerY())
Bonnes pratiques #
- Une tuile
largepar écran suffit : c'est le point d'entrée principal, le reste doit rester lisible. - Les tuiles
smalln'affichent pas leur libellé — renseignez systématiquement l'info-bulle de l'item. - Réservez
il_back_coloraux tuiles qui doivent trancher : au-delà de deux ou trois couleurs, l'écran perd sa hiérarchie. Et si vous posez un fond clair, posezil_text_coloravec — le texte du thème n'est pas garanti lisible dessus. - Préférez
of_add_live_item(défilement) àis_live_text(texte fixe) quand vous avez plusieurs informations à faire passer sur la même tuile. - Si vous laissez la réorganisation active, conservez la disposition via
of_get_layout/ue_layout_changedet rejouezof_set_layoutà l'ouverture. - Utilisez
ib_visibleetib_enabled(groupe ou tuile) pour l'adapter aux droits de l'utilisateur, plutôt que de reconstruire le panneau. - Quand l'espace manque pour des tuiles, préférez la navigation latérale compacte du listbar ; pour les actions fréquentes, la toolbar.
Hérité du socle commun #
Ces membres existent sur tous les composants visuels — ils ne sont pas propres à celui-ci. Ils sont détaillés une seule fois, dans les chapitres transverses ; cette table dit seulement où les lire.
| Membres | Rôle | Détaillé dans |
|---|---|---|
of_count · of_keys_at · of_has | Parcourir ce que le composant contient | 3.2 Les items |
of_reset | Remettre le composant à zéro | 3.6 Remettre un composant à zéro : of_reset() |
of_register_shortcut · of_clear_shortcuts | Raccourcis clavier du composant | 3.5 Les raccourcis clavier |
of_is_created · of_is_ready · of_get_last_error | S'il est né, s'il est prêt, ce qui a échoué | 3.7 Diagnostic |
of_save_as_png · of_save_as_jpg | Exporter le rendu en image | 3.8 Exporter le rendu en image |
of_set_redraw | Grouper les modifications en un seul repaint | 3.10 Bonnes pratiques |
of_preload_icons | Icônes affichées sans délai | Affichage instantané : of_icon |
of_set_translation | Traduire un libellé du composant | 5.2 Adapter un libellé : of_set_translation |
of_focus_webview | Donner le focus au composant | 6.4 Clavier et focus |
of_print · of_print_to_pdf | Imprimer, ou écrire un PDF | 6.9 Imprimer |
of_set_property · of_get_property · of_component_name | Piloter une propriété par son nom | 3.1 Le moteur de propriétés |
Deux aides ne sont pas héritées : of_icon et of_escape_markup vivent sur n_pbt_utils. Déclarez-en une — n_pbt_utils lnv_utils, rien à créer — et appelez-les dessus.