# statusbar — `u_pbt_statusbar` #

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

> Barre d'état à panneaux : texte riche, icônes, largeurs fixes ou automatiques, alignement à gauche ou à droite, panneaux cliquables, mini-barre de progression et états colorés.

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

## En bref #

Userobject | `u_pbt_statusbar`
Classe d'items | `n_pbt_statusbar_panel` (panneau)
Sert à | Afficher en bas de fenêtre l'état de l'application : contexte, avancement, alertes discrètes
Options opt-in | —

## Démarrage rapide #

    // event open de la fenetre
    // of_add_panel(id, texte, icone, alignement, largeur)
    // id vide = panneau simplement informatif ; largeur 0 = ajustee au texte
    uo_statut.of_add_panel(/*id*/ "etat",  /*text*/ "Pret",           /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START,  /*width*/ 0)
    uo_statut.of_add_panel(/*id*/ "",      /*text*/ "Ligne 12, Col 4", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START,  /*width*/ 0)
    uo_statut.of_add_panel(/*id*/ "heure", /*text*/ "12:00",          /*icon_file*/ "", /*align*/ uo_statut.ALIGN_END, /*width*/ 140)

    // Mettre un panneau a jour a tout moment, par son identifiant
    uo_statut.of_item("etat").is_text = "Enregistrement en cours..."

## Le modèle : des panneaux à clé #

La barre est une suite de panneaux, ajoutés dans l'ordre. Un panneau reçoit un identifiant à la création : c'est par lui qu'on le retrouve ensuite pour changer son texte, son icône ou son état.

L'identifiant est une clé d'adressage, pas un interrupteur d'interactivité :

- Identifiant renseigné : le panneau est retrouvable — on change son contenu, on lui pose une info-bulle. Il reste inerte : une barre d'état affiche avant tout, et un panneau comme `Ligne 12, Col 4` ne doit pas avoir l'air pressable.
- Identifiant vide : le panneau est purement décoratif. Il n'est ni retrouvable, ni cliquable, et aucune info-bulle ne peut lui être attachée. Donnez un identifiant à tous vos panneaux : ça ne coûte rien et ça garde la porte ouverte.
- Pour rendre un panneau cliquable, demandez-le : `of_item("id").ib_clickable = true`. Un panneau doté d'une liste déroulante (`of_set_panel_menu`) l'est d'office.

    uo_statut.of_item("etat").is_text = "3 enregistrements modifies"

Voir Socle commun · Les items.

## Propriétés #

Propriété | Type | Défaut | Rôle
--- | --- | --- | ---
`ib_show_resize_grip` | boolean | `false` | Affiche la poignée de redimensionnement dans le coin de fin de barre
`is_theme_style` | string | `fluent` | Style visuel du composant (constantes `THEME_STYLE_*`)
`is_theme_mode` | string | `light` | Variante claire ou sombre (constantes `THEME_MODE_*`)
`il_theme_accent` | long | `-1` | Couleur d'accent de ce composant (`-1` = accent 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_add_panel (string as_id, string as_text, string as_icon_file, string as_align, integer ai_width)` | Ajoute un panneau en fin de barre
`of_add_sep ( )` | Insère une rupture de groupe à la position courante. Les panneaux se séparent déjà d'un filet fin : celle-ci est plus large, pour que les panneaux d'avant et d'après se lisent comme deux groupes. À appeler entre deux `of_add_panel`
`of_insert_panel (as_id, as_text, as_icon_file, as_align, ai_width, ai_index)` | Insère un panneau à une position précise (comptée à partir de 0)
`of_move_panel (string as_id, integer ai_index)` | Déplace un panneau existant à une autre position
`of_remove_panel (string as_id)` | Supprime un seul panneau ; les autres conservent leur état
`of_item (string as_id)` → `n_pbt_statusbar_panel` | Rend le handle d'un panneau (créé au premier accès)
`of_flash_panel (string as_id, string as_text, long al_ms)` | Affiche un message pendant `al_ms` millisecondes, puis remet le texte précédent (`al_ms` ≤ 0 = 2 secondes)
`of_set_panel_menu (string as_id, string as_item_ids[], string as_labels[])` | Transforme le panneau en sélecteur : le clic ouvre une liste déroulante, le choix revient par `ue_panel_menu_clicked`. Un identifiant `-` insère un séparateur ; un libellé vide reprend l'identifiant
`of_clear_panel_menu (string as_id)` | Retire la liste déroulante ; le panneau retrouve le comportement que lui donne `ib_clickable`
`of_clear ( )` | Vide la barre : tous les panneaux et tous les séparateurs
`of_reset ( )` | Vide la barre et remet les propriétés à leur défaut

### Les arguments de `of_add_panel` #

Argument | Valeurs | Effet
--- | --- | ---
`as_id` | libre, ou `""` | Clé du panneau, par laquelle on le retrouve ensuite. Vide = panneau décoratif, ni adressable ni cliquable
`as_text` | texte | Contenu du panneau. Le balisage riche est accepté
`as_icon_file` | chemin d'image, ou `""` | Icône affichée avant le texte (formes acceptées)
`as_align` | `ALIGN_START` (défaut) ou `ALIGN_END` | Côté vers lequel le panneau est poussé. Valeurs logiques : `START` = début de lecture (gauche en écriture de gauche à droite). Les alias physiques `"left"` / `"right"` restent acceptés
`ai_width` | pixels, ou `0` | Largeur fixe. `0` = le panneau s'ajuste à son contenu

### Sur un panneau — `n_pbt_statusbar_panel` #

Membre | Type | Défaut | Rôle
--- | --- | --- | ---
`is_text` | string | `""` | Texte du panneau, balisage riche accepté
`is_image` | string | `""` | Icône du panneau, modifiable à tout moment
`ib_enabled` | boolean | `true` | Panneau grisé et non cliquable
`ib_visible` | boolean | `true` | Panneau masqué, sans être retiré de la barre
`ii_progress` | integer | — | Mini-barre de progression dans le panneau, de `0` à `100` ; une valeur négative la fait disparaître
`is_state` | string | `""` | État sémantique du panneau, qui le colore : voir les constantes ci-dessous
`ib_indeterminate` | boolean | `false` | Barre animée sans valeur, pour un traitement dont la durée est inconnue. Indépendante de `ii_progress`, qui reste le pourcentage exact
`ib_clickable` | boolean | `false` | Le panneau réagit-il au clic. Opt-in : un panneau reste inerte tant qu'on ne le demande pas, tout en gardant sa clé — il est piloté et porte une info-bulle. Un panneau à liste déroulante est cliquable d'office

### Constantes d'état #

Constante | Valeur | Usage
--- | --- | ---
`STATE_NONE` | `""` | Aucun état : apparence normale
`STATE_INFO` | `"info"` | Information
`STATE_WARNING` | `"warning"` | Avertissement
`STATE_ERROR` | `"error"` | Erreur
`STATE_SUCCESS` | `"success"` | Succès

Comme pour toute propriété à valeurs prédéfinies, utilisez la constante plutôt que la chaîne :

    n_pbt_statusbar_panel lnv_panneau
    lnv_panneau = uo_statut.of_item("etat")
    lnv_panneau.is_state = lnv_panneau.STATE_WARNING

## Événements #

Événement | Déclenché quand
--- | ---
`ue_panel_clicked (string as_id)` | Un panneau cliquable est cliqué
`ue_panel_double_clicked (string as_id)` | Un panneau cliquable est double-cliqué — le raccourci classique derrière `Ligne 12, Col 4` qui ouvre un « Aller à la ligne »
`ue_panel_rclicked (string as_id, long al_x, long al_y)` | Un panneau reçoit un clic droit. `al_x` et `al_y` sont des pixels écran : à passer tels quels pour ouvrir un menu contextuel là où l'utilisateur a visé
`ue_panel_menu_clicked (string as_id, string as_item_id)` | Une entrée d'une liste déroulante de panneau est choisie (voir `of_set_panel_menu`)
`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`)

## Au clavier #

La barre est un seul arrêt de tabulation : seuls les panneaux faits pour être cliqués y entrent, et les flèches les parcourent.

Touche | Effet
--- | ---
Flèches | Passent au panneau interactif précédent / suivant, en bouclant ; les panneaux d'affichage et les panneaux désactivés sont sautés
Début / Fin | Premier / dernier panneau interactif
Entrée ou Espace | Déclenche le panneau — c'est-à-dire `ue_panel_clicked`, ou l'ouverture de sa liste déroulante s'il en a une

Un panneau qui se contente d'afficher n'est pas un contrôle : il n'est ni focalisable ni annoncé comme tel. Un panneau cliquable mais désactivé reste, lui, annoncé comme indisponible plutôt que de passer pour du texte. Une barre de progression annonce sa valeur, et une progression indéterminée n'en annonce aucune — cette absence est le sens du mot.

Le focus survit à la reconstruction de la barre : elle se redessine à chaque changement de texte, et sans cela le focus tomberait à chaque seconde sur une barre qui affiche une horloge.

## Exemples #

### Largeurs fixes et largeurs automatiques #

    // Largeur 0 : le panneau prend exactement la place de son texte
    uo_statut.of_add_panel(/*id*/ "", /*text*/ "Panneau ajuste au contenu", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)

    // Largeur fixe en pixels : utile quand le texte change souvent,
    // pour que les panneaux voisins ne bougent pas a chaque mise a jour
    uo_statut.of_add_panel(/*id*/ "pos", /*text*/ "Ligne 1, Col 1", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 150)

    // Un panneau pousse a l'extremite opposee
    uo_statut.of_add_panel(/*id*/ "heure", /*text*/ "12:00", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_END, /*width*/ 140)

### Icônes et panneaux cliquables #

    // Un identifiant non vide rend le panneau cliquable
    uo_statut.of_add_panel(/*id*/ "save", /*text*/ "Enregistre", /*icon_file*/ "mono:img\save.svg", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)
    uo_statut.of_add_sep()   // trait de separation entre deux groupes de panneaux
    uo_statut.of_add_panel(/*id*/ "conn", /*text*/ "Connecte",   /*icon_file*/ "mono:img\plug.svg", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)
    uo_statut.of_add_panel(/*id*/ "user", /*text*/ "Guillaume",  /*icon_file*/ "mono:img\user.svg", /*align*/ uo_statut.ALIGN_END, /*width*/ 160)

    // event ue_panel_clicked de uo_statut
    choose case as_id
        case "conn" ; open(w_parametres_connexion)
        case "user" ; open(w_profil)
    end choose

### Texte riche dans un panneau #

Les panneaux acceptent le balisage riche : styles, couleurs et petites images directement dans le texte.

    uo_statut.of_add_panel(/*id*/ "", /*text*/ "Bienvenue [b]dans[/b] [accent]PBToolboxAI[/accent]", &
                           /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)

    uo_statut.of_add_panel(/*id*/ "", /*text*/ "[green]En ligne[/green] [picture=mono:img\plug.svg,14,14]", &
                           /*icon_file*/ "", /*align*/ uo_statut.ALIGN_END, /*width*/ 0)

    // Le texte riche vaut aussi pour les mises a jour
    uo_statut.of_item("etat").is_text = "[b]" + String(ll_modifies) + "[/b] enregistrements modifies"

### Suivre un traitement long #

    n_pbt_statusbar_panel lnv_avance

    uo_statut.of_add_panel(/*id*/ "import", /*text*/ "Import", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 220)
    lnv_avance = uo_statut.of_item("import")

    // Dans la boucle de traitement : la mini-barre suit l'avancement
    lnv_avance.ii_progress = ll_pourcentage
    lnv_avance.is_text     = "Import " + String(ll_pourcentage) + " %"

    // A la fin : masquer la mini-barre et signaler le resultat
    lnv_avance.ii_progress = -1                       // valeur negative = barre masquee
    lnv_avance.is_text     = "Import termine"
    lnv_avance.is_state    = lnv_avance.STATE_SUCCESS

### Signaler une alerte discrète #

    n_pbt_statusbar_panel lnv_panneau
    lnv_panneau = uo_statut.of_item("conn")

    if not ib_connecte then
        lnv_panneau.is_text  = "Hors ligne"
        lnv_panneau.is_state = lnv_panneau.STATE_ERROR
    else
        lnv_panneau.is_text  = "Connecte"
        lnv_panneau.is_state = lnv_panneau.STATE_NONE   // retour a l'apparence normale
    end if

### Adapter la barre au contexte #

    // Masquer un panneau sans le supprimer : il retrouvera sa place plus tard
    uo_statut.of_item("user").ib_visible = ib_utilisateur_identifie

    // Le griser quand l'action correspondante n'a pas de sens
    uo_statut.of_item("save").ib_enabled = ib_document_ouvert

    // Reorganiser : placer le panneau d'etat en tete (positions comptees a partir de 0)
    uo_statut.of_move_panel(/*id*/ "etat", /*index*/ 0)

    // Retirer un panneau devenu inutile
    uo_statut.of_remove_panel(/*id*/ "import")

### La poignée de redimensionnement #

    // Sur une fenetre redimensionnable, la poignee de coin est un repere familier
    uo_statut.ib_show_resize_grip = true

## Bonnes pratiques #

- Donnez une largeur fixe aux panneaux dont le texte change souvent (position du curseur, compteurs) : les panneaux voisins cesseront de sauter à chaque rafraîchissement.
- Laissez l'identifiant vide pour un panneau purement informatif : cela évite un clic sans effet.
- Réservez le côté droit aux informations stables (heure, utilisateur, connexion) et le côté gauche au contexte courant.
- Employez `is_state` plutôt que des couleurs dans le texte : l'état suit le thème clair comme sombre.
- Pensez à repasser `is_state` à `STATE_NONE` et `ii_progress` à une valeur négative dès que l'alerte ou le traitement est terminé.
- Une barre d'état n'est pas un journal : au-delà de cinq ou six panneaux, préférez une notification toaster.
- Si la progression mérite mieux qu'une mini-barre de panneau, passez à la progressbar.

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