PBToolboxAI v4 ← Site

breadcrumb — u_pbt_breadcrumb #

← Référence des composants · Sommaire du guide

Fil d'Ariane : le chemin cliquable qui dit à l'utilisateur où il est, et qui le ramène d'un clic à n'importe quel niveau au-dessus.

▶ Le voir en vrai — Application de démonstration, tuile Breadcrumb : l'aperçu, le code qui le produit et cette page, côte à côte.


En bref #

Userobjectu_pbt_breadcrumb
Classe d'itemsn_pbt_breadcrumb_item (of_item(adresse)) · n_pbt_breadcrumb_child (of_child(adresse))
Sert àDire où l'on est dans une arborescence, et permettre d'en remonter
PrincipeVous décrivez le chemin ; le repli, le menu et la mise en page sont à nous

Démarrage rapide #

// A chaque fois que l'utilisateur descend d'un niveau
uo_crumbs.of_add_item(/*keys*/ "home",                /*text*/ "H")
uo_crumbs.of_add_item(/*keys*/ "home/clients",        /*text*/ "C")
uo_crumbs.of_add_item(/*keys*/ "home/clients/dupont", /*text*/ "D")

// Le dernier ajoute devient le lieu courant - et il repond au clic

Un segment se nomme par son adresse : les clés depuis la racine, jointes par / — "home/clients/dupont". Une clé nue ne suffit plus dès qu'elle se répète à deux niveaux du même fil : le composant refuse alors de deviner, plutôt que de vous emmener ailleurs.

C'est exactement ce que ue_item_clicked vous rend, et exactement ce que of_truncate, of_item ou of_add_child reprennent : ce que vous recevez se réinjecte tel quel.


Un clic rapporte, il ne coupe pas #

Cliquer un segment ne raccourcit pas le fil. Remonter, c'est quitter un écran, et quitter un écran veut souvent dire enregistrer d'abord — ce qu'aucun clic ne peut décider. Le composant vous dit ce qui a été cliqué ; c'est vous qui coupez, par of_truncate, une fois vos contrôles passés.

C'est la même répartition des rôles que sur la stepbar, et pour la même raison. Un composant qui se déplace tout seul oblige l'application à défaire un mouvement déjà fait, au lieu de simplement choisir s'il a lieu.

Deux segments ne rapportent jamais rien : un segment désactivé, un segment caché. Le dernier — là où l'on est — répond comme les autres, jusqu'à ce que ib_last_clickable dise non.

// event ue_item_clicked : (string as_keys)
// Vos controles d'abord - c'est vous qui decidez de quitter l'ecran
if not of_can_leave() then return
uo_crumbs.of_truncate(/*keys*/ as_keys)
of_open_screen(as_keys)

Quand le chemin est trop long #

Un chemin est aussi long que les données le font, et la largeur est ce qu'elle est. is_overflow_mode dit ce qui cède.

ConstanteCe qui se passe
OVERFLOW_COLLAPSELe milieu se replie dans un … qui ouvre ce qu'il cache — le défaut
OVERFLOW_SCROLLLes libellés restent entiers, la bande glisse (la molette la fait glisser aussi)
OVERFLOW_SHRINKLes segments du milieu cèdent du terrain, jusqu'à une lettre et des points de suspension ; le premier et le lieu courant ne cèdent qu'en dernier. Avec de la place, rien n'est coupé

Ni le premier segment ni le dernier ne se replient jamais. Perdre la racine, c'est perdre l'ancre où tout le monde revient ; perdre la fin, c'est perdre l'endroit où l'on est.

Un segment replié rapporte exactement comme les autres : le choisir dans le … lève le même ue_item_clicked. Être caché par la largeur ne change pas ce qu'un segment veut dire.

ii_max_visible impose un plafond ferme, quelle que soit la place. Laissez-le à 0 — le défaut — pour que la largeur décide, ce qu'un fil d'Ariane devrait normalement suivre.


Le menu de fratrie #

of_add_child donne à un segment son propre menu déroulant : les autres branches de ce niveau. C'est ce qui évite de remonter à la racine pour redescendre dans le dossier d'à côté.

Le chevron qui suit le segment devient alors le bouton qui les ouvre — c'est le même que le séparateur, comme dans l'explorateur Windows : un seul chevron, un seul sens à apprendre. Choisir une branche lève ue_child_clicked, et là encore le fil ne bouge pas de lui-même. Au clavier, Flèche bas sur un segment ouvre ses branches, et sur le … ce qu'il cache.

// Two branches under Clients : its chevron lists them
uo_crumbs.of_add_child(/*keys*/ "home/clients/durand", /*text*/ "D")
uo_crumbs.of_add_child(/*keys*/ "home/clients/martin", /*text*/ "M")

Les branches à la demande #

Poser toutes les branches à l'avance ne tient pas sur un arbre profond, ni sur une base de données. L'explorateur Windows ne lit un dossier que quand on ouvre son chevron ; le fil fait pareil : marquez un segment avec ib_has_children, son chevron s'affiche aussitôt, et l'ouvrir lève ue_children_needed. Vous posez les branches dans cet événement, et le menu s'ouvre à son retour avec ce que le segment porte à cet instant. Un gros dossier ne pose pas de problème : ajouter 30 000 branches ne relit rien, et dans le menu ouvert, taper les premières lettres (« Win ») saute à la première branche qui commence ainsi, comme dans l'explorateur.

// Le segment promet : le chevron s'affiche, rien n'est lu
uo_crumbs.of_item(/*keys*/ "home/clients").ib_has_children = true

// Dans ue_children_needed(as_keys) : lu maintenant, puis le menu s'ouvre
uo_crumbs.of_clear_children(/*keys*/ as_keys)
uo_crumbs.of_add_child(/*keys*/ as_keys + "/durand", /*text*/ "Durand SARL")

Saisir le chemin #

Avec ib_editable, la partie vide de la barre se comporte comme la barre d'adresse de l'explorateur Windows : un clic (ou F2, ou of_edit) change le fil en champ de texte qui porte l'adresse affichée — les clés jointes par /, ce que of_path rend. Entrée lève ue_path_entered avec le texte tel que tapé ; Échap annule. Le fil ne bouge pas de lui-même, pour la même raison qu'un clic ne le raccourcit pas : seule votre application sait ce que les mots veulent dire. ii_edit_skip laisse les premiers segments hors du champ — la racine qui nomme la machine — et les remet devant ce qui a été tapé au moment du rapport.


Propriétés #

PropriétéTypeDéfautRôle
is_separatorstringchevronLe glyphe entre les segments (constantes SEPARATOR_*). Il se retourne tout seul dans une langue qui s'écrit de droite à gauche : choisissez un sens, pas une direction. Un séparateur qui ouvre des branches garde le glyphe choisi : c'est le survol et le curseur qui disent qu'il s'ouvre
is_overflow_modestringcollapseCe qui cède quand le chemin ne tient plus (constantes OVERFLOW_*). En scroll, la bande suit le lieu courant
ii_max_visibleinteger0Plafond ferme du nombre de segments affichés, le … non compté. 0 laisse décider la largeur
ib_last_clickablebooleantrueLe dernier segment — là où l'on est — répond-il au clic ? Vrai par défaut : un fil sert aussi à recharger ce qu'on regarde, et ce que le clic fait est l'affaire de votre application. Mettez-le à faux quand votre fil ne fait que naviguer
ib_editablebooleanfalseLe chemin peut-il être saisi ? Vrai : un clic sur la partie vide de la barre (ou F2, ou of_edit) change le fil en champ de texte qui porte l'adresse du lieu courant (ce que rend of_path) ; Entrée lève ue_path_entered, quitter le champ après l'avoir modifié aussi, Échap annule. Un champ quitté sans changement ne dit rien ; cliquer un autre contrôle de l'application valide le texte, passer à une autre application garde la saisie. Le fil ne bouge jamais de lui-même
ib_allow_dropbooleanfalseOpt-in : accepte les fichiers déposés depuis l'Explorateur Windows sur un segment. Le segment sous le curseur s'allume pendant le glissement, et ue_drop_files le nomme avec les chemins complets
ii_edit_skipinteger0Nombre de segments de tête laissés hors du champ de saisie — une racine qui nomme la machine ne se tape pas. Ils sont remis devant ce qui a été tapé au moment du rapport : l'adresse reste complète
is_theme_stylestring""Style visuel du composant (constantes THEME_STYLE_*) ; vide = celui de l'application, suivi à chaque changement
is_theme_modestring""Variante claire ou sombre (constantes THEME_MODE_*) ; vide = celle de l'application, suivie à chaque changement
il_theme_accentlong-1Couleur d'accent de ce composant (-1 = l'accent de l'application, ou celui du thème)
is_tooltipstring""Info-bulle simple affichée au survol du composant
is_super_tooltip_titlestring""Titre de l'info-bulle enrichie (prend le pas sur is_tooltip)
is_super_tooltip_textstring""Texte de l'info-bulle enrichie (balisage riche accepté)
is_super_tooltip_imagestring""Image de l'info-bulle enrichie

Méthodes #

MéthodeRôle
of_add_item (string as_keys, string as_text)Ajoute un segment à la fin : il devient le lieu courant. as_keys est une clé nue ou une adresse ; une adresse n'est acceptée que si elle atterrit là où elle le dit — ses niveaux au-dessus du dernier doivent être l'adresse du dernier segment. Renvoie 0 une fois appliqué, -5 sur une clé vide, une clé qui contient ` ou une adresse qui atterrirait ailleurs, -2` si le composant n'est pas créé
of_add_item (string as_keys, string as_text, string as_image)Même chose, avec l'icône affichée avant le libellé — troisième argument, comme partout ailleurs dans la bibliothèque. Un libellé vide donne un segment à icône seule (la maison de la racine). Renvoie 0 une fois appliqué, -5 sur une clé vide, une clé qui contient ` ou une adresse qui atterrirait ailleurs, -2` si le composant n'est pas créé
of_insert_item (string as_keys, string as_text, integer ai_index)Insère à la position choisie (première position = 1). Une surcharge prend aussi l'icône. Une adresse n'est acceptée que si ses niveaux au-dessus du dernier sont l'adresse du segment qu'elle suit. Les segments qui suivent descendent d'un niveau : leurs adresses changent, leurs poignées sont libérées, leurs couleurs et infobulles les suivent. Renvoie 0 une fois appliqué, -5 sur une clé vide, une clé qui contient ` ou une adresse qui atterrirait ailleurs, -2` si le composant n'est pas créé
of_remove_item (string as_keys)Retire un segment, par son adresse ; les autres gardent leur état. Ceux qui le suivaient remontent d'un niveau : les poignées du segment retiré et de tout ce qui le suivait sont libérées. Renvoie 0 une fois appliqué, -5 si l'adresse ne désigne aucun segment (inconnue, ou clé nue répétée), -2 si le composant n'est pas créé
of_truncate (string as_keys)Supprime tout ce qui suit ce segment, qui devient le lieu courant. C'est le geste pour lequel un fil d'Ariane existe ; une adresse inconnue ou une clé nue répétée ne change rien et renvoie -5. Les poignées des segments supprimés sont libérées. Renvoie 0 une fois appliqué, -5 si l'adresse ne désigne aucun segment, -2 si le composant n'est pas créé
of_clear ( )Vide le fil ; les poignées données pour ses segments et ses branches sont libérées. Renvoie 0 une fois appliqué, -2 si le composant n'est pas créé
of_add_child (string as_keys, string as_text)Ajoute une branche sœur à l'adresse donnée : le segment au-dessus gagne un chevron qui les ouvre. Une surcharge prend aussi l'icône. Renvoie 0 une fois appliqué, -5 si le segment au-dessus n'existe pas, si la clé de la branche est déjà prise sous lui ou contient `, -2` si le composant n'est pas créé
of_add_children (string as_keys, string as_child_keys[], string as_texts[])Ajoute toute une rangée de branches sœurs sous le segment as_keys, en un seul appel : chaque texte de as_texts (et chaque image, dans la surcharge qui prend aussi une liste d'images) va avec la clé de même rang dans as_child_keys ; un texte absent montre la clé. Les mêmes branches qu'une boucle de of_add_child, sans un aller-retour chacune : un dossier de 30 000 sous-dossiers ouvre son menu aussitôt. Renvoie 0 une fois appliqué (une liste vide n'ajoute rien), -5 si l'adresse ne désigne aucun segment, ou si une clé est vide, contient / ou `, est déjà prise sous le segment ou revient deux fois dans la liste — rien n'est ajouté alors, -2` si le composant n'est pas créé
of_clear_children (string as_keys)Retire les branches sœurs d'un segment, et leurs poignées ; son séparateur redevient un simple trait. Renvoie 0 une fois appliqué, -5 si l'adresse ne désigne aucun segment, -2 si le composant n'est pas créé
of_remove_child (string as_keys)Retire une branche sœur, par sa propre adresse, et sa poignée ; la dernière partie, le chevron redevient un simple trait. Renvoie 0 une fois appliqué, -5 si le segment ou la branche n'existe pas, -2 si le composant n'est pas créé
of_child (string as_keys)La poignée d'une branche sœur — l'adresse que of_add_child a prise — pour la renommer, la griser ou la cacher. Le menu est un popup natif : il dessine texte, image, grisé et masqué, rien d'autre — l'infobulle et les couleurs héritées d'une poignée y sont ignorées. Une adresse à un seul niveau n'a pas de segment au-dessus : sa poignée est inerte
of_path ( )Où l'on est, sous forme d'adresse : les clés de tous les segments jusqu'au dernier visible, séparées par /. Un segment masqué y reste — il fait partie de l'adresse — et le plafond de la version de démonstration ne la coupe jamais : of_truncate(of_path()) tombe toujours juste. Lu en direct : une application qui reconstruirait cette chaîne à la main finirait par ne plus dire la même chose que le fil
of_edit ( )Ouvre le champ de saisie du chemin — le même qu'un clic sur la partie vide de la barre — depuis une entrée de menu ou un bouton à vous. Demande ib_editable. Renvoie 0 une fois appliqué, -4 si ib_editable est faux (rien ne s'ouvre), -2 si le composant n'est pas créé
of_item (string as_keys)La poignée d'un segment, pour le renommer, le griser ou le cacher plus tard. Elle vit autant que son segment : of_clear, of_remove_item et of_truncate libèrent les poignées des segments qu'ils retirent
of_set_redraw (boolean)Regroupe une rafale de modifications en un seul rendu. Renvoie 0 une fois appliqué, -2 si le composant n'est pas créé
of_save_as_png (string) · of_save_as_jpg (string)Exporte le rendu en image. Renvoie 0 une fois l'image écrite, -4 si l'écriture échoue, -2 si le composant n'est pas créé

Événements #

ÉvénementDéclenché quand
ue_item_clicked (string as_keys)Un segment a été cliqué — dans le fil, ou dans le … qui le cache. Le fil ne se raccourcit pas : appelez of_truncate quand vos contrôles sont passés
ue_item_rclicked (string as_keys)Clic droit sur un segment — un menu contextuel à vous, en général. as_keys est son adresse complète, comme dans ue_item_clicked
ue_child_clicked (string as_keys)Une branche sœur a été choisie dans le menu d'un segment ; as_keys est l'adresse de la branche, prête à repartir dans of_add_item
ue_children_needed (string as_keys)Le chevron d'un segment marqué ib_has_children s'ouvre : posez ses branches maintenant (of_add_child), le menu s'ouvre au retour de l'événement, avec ce que le segment porte à cet instant. Demandé à chaque ouverture : videz et reposez quand les branches ont pu changer, ne faites rien quand ce qui est là tient toujours
ue_path_entered (string as_path)L'utilisateur a saisi un chemin dans la barre (ib_editable) et pressé Entrée — ou quitté le champ après l'avoir modifié ; as_path est le texte tel que tapé, les ii_edit_skip premiers segments remis devant. Cliquer un autre contrôle de l'application compte comme quitter le champ. Échap, un champ inchangé ou une autre application passée au premier plan ne rapportent rien. Le fil ne bouge pas de lui-même : vérifiez les mots, puis reconstruisez-le avec of_clear et of_add_item si vous êtes d'accord
ue_drop_files (string as_keys, string as_files[])Des fichiers ont été déposés depuis l'Explorateur sur un segment (ib_allow_drop) : as_keys est l'adresse du segment sous le curseur, vide si le dépôt est tombé à côté du fil ; as_files les chemins complets
ue_drag_enter ( ) · ue_drag_leave ( )Un glissement de fichiers depuis l'Explorateur est entré dans le composant, ou en est sorti sans déposer — un dépôt lève ue_drop_files seul
ue_auto_height (long al_height)La barre annonce la hauteur qu'il lui faut — une rangée, décidée par la police et le thème ; l'userobject est déjà redimensionné, repositionnez ce qui se trouve dessous
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)

Le fil ne navigue pas. Il dit où l'on est et rapporte ce qu'on lui demande ; c'est votre application qui ouvre l'écran — la même action, lancée depuis un menu ou depuis le fil, passe donc par le même code.


Propriétés d'item #

PropriétéTypeDéfautRôle
is_textstring""Le libellé du segment, modifiable sans reconstruire le fil (balisage riche accepté : un libellé venu des DONNÉES — un nom de dossier — passe d'abord par of_escape_markup de n_pbt_utils, sinon [b]Brouillons s'afficherait en gras sans ses crochets)
is_imagestring""L'icône affichée avant le libellé (préfixes mono: et tint: acceptés)
ib_enabledbooleantrueUn segment désactivé est grisé et ne rapporte rien : le niveau existe dans le chemin, mais on ne peut pas y remonter (droits, fiche en cours de saisie). Son chevron n'ouvre rien non plus, et un glissement de fichiers ne l'allume pas
ib_visiblebooleantrueUn segment caché quitte le fil, séparateur compris — utile pour un niveau technique que l'utilisateur n'a pas à voir. Il est conservé : le remontrer ne demande aucune reconstruction
ib_has_childrenbooleanfalseMarqué : il y a quelque chose sous ce segment. Son chevron s'affiche sans rien derrière, et l'ouvrir lève ue_children_needed, où les branches sont lues à cet instant. Un segment dont les branches ont été posées par of_add_child n'a pas besoin du marqueur

Propriétés d'un enfant #

Obtenue par of_child(adresse). Le menu est un popup natif : une propriété changée pendant qu'il est ouvert se voit à l'ouverture suivante.

PropriétéTypeDéfautRôle
is_textstring""Le libellé de la branche dans le menu
is_imagestring""L'icône affichée avant le libellé
ib_enabledbooleantrueUne branche grisée reste dans le menu et ne peut pas être choisie — pas de droits sur cette branche
ib_visiblebooleantrueUne branche cachée quitte le menu sans être retirée ; la dernière cachée referme le chevron

Exemples #

Le suivre au fil de la navigation #

// Rebuild the trail in a single redraw : freeze, clear, add, insert, redraw
uo_crumbs.of_set_redraw(/*on*/ false)
uo_crumbs.of_clear()
uo_crumbs.of_add_item(/*keys*/ "home", /*text*/ "H", /*image*/ "mono:img\packimages.dll:svg/samples/folder-open")
uo_crumbs.of_insert_item(/*keys*/ "home/region", /*text*/ "R", /*index*/ 2)
uo_crumbs.of_set_redraw(/*on*/ true)

Remonter sur un clic #

// Cut the trail after Clients, then read the path that remains
uo_crumbs.of_truncate(/*keys*/ "home/clients")
ls_path = uo_crumbs.of_path()

Un niveau interdit, un niveau caché #

// Le niveau existe, mais on ne peut pas y remonter
uo_crumbs.of_item(/*keys*/ "home/clients/orders").ib_enabled = false

// Et celui-la ne regarde pas l'utilisateur : hors du fil, separateur compris
uo_crumbs.of_item(/*keys*/ "home").ib_visible = false
// Slash separator, scrolling on overflow, at most 4 segments shown, last one not clickable
uo_crumbs.is_separator = uo_crumbs.SEPARATOR_SLASH
uo_crumbs.is_overflow_mode = uo_crumbs.OVERFLOW_SCROLL
uo_crumbs.ii_max_visible = 4
uo_crumbs.ib_last_clickable = false

// Remove one segment, then the branches offered under another
uo_crumbs.of_remove_item(/*keys*/ "home/region")
uo_crumbs.of_clear_children(/*keys*/ "home/clients")

Bonnes pratiques #

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.

MembresRôleDétaillé dans
of_count · of_keys_at · of_hasParcourir ce que le composant contient3.2 Les items
of_resetRemettre le composant à zéro3.6 Remettre un composant à zéro : of_reset()
of_register_shortcut · of_clear_shortcutsRaccourcis clavier du composant3.5 Les raccourcis clavier
of_is_created · of_is_ready · of_get_last_errorS'il est né, s'il est prêt, ce qui a échoué3.7 Diagnostic
of_save_as_png · of_save_as_jpgExporter le rendu en image3.8 Exporter le rendu en image
of_set_redrawGrouper les modifications en un seul repaint3.10 Bonnes pratiques
of_preload_iconsIcônes affichées sans délaiAffichage instantané : of_icon
of_set_translationTraduire un libellé du composant5.2 Adapter un libellé : of_set_translation
of_focus_webviewDonner le focus au composant6.4 Clavier et focus
of_print · of_print_to_pdfImprimer, ou écrire un PDF6.9 Imprimer
of_set_property · of_get_property · of_component_namePiloter une propriété par son nom3.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.


← Référence des composants · Sommaire du guide