toaster — n_pbt_toaster #
← Référence des composants · Sommaire du guide
Notifications « toast » en coin d'écran : un message qui apparaît, informe et disparaît sans bloquer l'utilisateur ni interrompre sa saisie.
▶ Le voir en vrai — Application de démonstration, tuile Toaster : l'aperçu, le code qui le produit et cette page, côte à côte.
En bref #
| Objet | n_pbt_toaster — non visuel : rien à poser dans la fenêtre |
| Sert à | Confirmer une action réussie, signaler un avertissement ou une erreur, sans arrêter le travail en cours |
| Retour | Non bloquant : of_show() rend la main immédiatement ; les réactions de l'utilisateur reviennent par événements |
Le toast est une fenêtre détachée : il flotte au-dessus de votre application (ou de tout l'écran) et se referme tout seul.
n_pbt_toaster lnv_toast
lnv_toast = create n_pbt_toaster
// ... configuration ...
destroy lnv_toast
Démarrage rapide #
n_pbt_toaster lnv_toast
lnv_toast = create n_pbt_toaster
lnv_toast.ipo_owner = this // fenetre a laquelle le toast s'accroche
lnv_toast.is_kind = lnv_toast.KIND_SUCCESS // icone verte + lisere de succes
lnv_toast.is_text = "Vos modifications ont ete [b]enregistrees[/b]."
lnv_toast.of_show()
destroy lnv_toast
Tout se configure par propriétés, puis of_show() — qui ne prend aucun argument — fait apparaître la notification.
Propriétés #
À poser avant of_show.
| Propriété | Type | Défaut | Rôle |
|---|---|---|---|
is_text | string | "" | Corps du message. Accepte le balisage riche |
is_kind | string | KIND_INFO | Niveau : pilote l'icône et la couleur du liseré. Constantes KIND_* |
is_position | string | POSITION_BOTTOM_RIGHT | Coin d'ancrage. Constantes POSITION_* |
ib_screen | boolean | false | false = ancré au coin de la fenêtre ; true = ancré au coin de l'écran, flottant au-dessus de tout |
il_timeout | long | TIMEOUT_AUTO | Durée d'affichage en millisecondes avant fermeture automatique. TIMEOUT_AUTO (-1, le défaut) vaut 4 s pour une information mais jusqu'au clic pour une erreur — une erreur qui s'efface en quatre secondes est une erreur perdue. TIMEOUT_UNTIL_CLICKED (0) rend n'importe quel toast persistant ; une durée explicite est respectée telle quelle. Tant que le pointeur reste sur un toast, son compte à rebours est suspendu, et une barre montre le temps restant |
is_title | string | "" | Ligne de titre en gras au-dessus du message (toast enrichi) |
is_image | string | "" | Image d'illustration à gauche, à la place de l'icône de niveau (formes acceptées : chemin, mono:, ressource de DLL) |
is_key | string | "" | Clé du toast : réafficher la même clé met à jour le toast déjà à l'écran au lieu d'en ouvrir un second. C'est ce dont une notification de progression a besoin (« Export 3/10 » puis « 4/10 ») : fermer et rouvrir relancerait l'animation et ferait sauter la pile. Laissez vide pour un toast ordinaire |
il_max_visible | long | 5 | Nombre maximal de toasts à l'écran au même coin (1 à 20). Au-delà, les suivants attendent et apparaissent à mesure que la place se libère : une boucle de traitement qui émet un toast par ligne empilait sinon les fenêtres hors de l'écran |
ipo_owner | powerobject | — | L'objet visuel auquel le toast est accroché (son coin de fenêtre sert de repère) |
ipo_receiver | powerobject | — | L'objet visuel qui reçoit les événements du toast. Laissez-le vide pour une notification sans retour |
Constantes #
| Constante | Valeur | Usage |
|---|---|---|
KIND_INFO | "info" | Information neutre |
KIND_SUCCESS | "success" | Opération réussie |
KIND_WARNING | "warning" | Avertissement |
KIND_ERROR | "error" | Échec |
POSITION_TOP_LEFT | "top-left" | Coin haut gauche |
POSITION_TOP_CENTER | "top-center" | Haut, centré |
POSITION_TOP_RIGHT | "top-right" | Coin haut droit |
POSITION_BOTTOM_LEFT | "bottom-left" | Coin bas gauche |
POSITION_BOTTOM_CENTER | "bottom-center" | Bas, centré |
POSITION_BOTTOM_RIGHT | "bottom-right" | Coin bas droit (défaut) |
Pourquoi
LEFT/RIGHTici, etSTART/ENDailleurs ? Le toast est une fenêtre système posée en pixels écran, pas un contenu qui suit un sens de lecture : un coin d'écran n'a pas de « début ». Ces constantes restent donc volontairement physiques, et ne changent pas de côté quand l'application passe en écriture de droite à gauche. Voir Langue et RTL.
Méthodes #
| Méthode | Rôle |
|---|---|
of_show ( ) → long | Affiche la notification construite à partir des propriétés. Renvoie l'identifiant du toast (> 0), ou une valeur négative en cas d'erreur. Ne bloque pas |
of_close ( long al_id ) → long | Ferme un toast encore affiché, désigné par l'identifiant rendu par of_show. Renvoie 0, ou -5 si l’identifiant est vide ou désigne un toast déjà disparu |
of_reset ( ) | Remet toutes les propriétés de contenu à leur défaut et efface les boutons (ipo_owner et ipo_receiver sont conservés : ce sont des branchements, pas du contenu) |
of_process_events ( ) | Vide la file des retours du toast et lève les événements ue_toast_* correspondants — voir ci-dessous |
of_add_button (string as_cle, string as_libelle {, string as_image }) → long | Ajoute un bouton d'action (3 au plus) et renvoie leur nombre. Un clic dessus émet ue_toast_action(id, cle) ; of_reset efface les boutons. Un libellé peut contenir n'importe quel caractère — une virgule, un signe égal — sans être coupé |
Plusieurs toasts affichés au même coin s'empilent automatiquement. Chacun porte une croix de fermeture ; l'identifiant renvoyé par of_show permet de les distinguer dans les événements et de les fermer depuis votre code.
Le compte à rebours se met en pause tant que le pointeur est sur le toast : une notification ne doit pas s'évanouir sous les yeux de qui la lit. Une fine barre en bas du toast montre le temps restant — et explique donc sa disparition. Un clic sur le corps répond et ferme, dans les deux modes d'hébergement.
Une notification posée avec il_timeout = 0 reste à l'écran tant que personne ne la ferme : gardez son identifiant pour pouvoir la retirer quand la tâche qu'elle annonce est terminée.
long ll_toast
// Notification persistante : elle restera affichee jusqu'a of_close.
inv_toaster.is_text = "Export en cours..."
inv_toaster.il_timeout = /*ms, 0 = pas de fermeture auto*/ 0
ll_toast = inv_toaster.of_show()
// ... traitement long ...
inv_toaster.of_close(/*id*/ ll_toast)
Événements — le toast vous répond #
Une notification n'est pas un simple « affiche et oublie » : elle peut vous dire qu'elle a été cliquée, qu'un bouton d'action a été choisi, ou qu'elle s'est fermée.
Comme le toast vit dans une fenêtre détachée, le branchement se fait en trois étapes.
1. Désigner l'objet visuel destinataire :
inv_toaster.ipo_owner = this
inv_toaster.ipo_receiver = this // ce userobject / cette fenetre recevra les retours
ipo_receiverdoit être un objet visuel (fenêtre ou userobject). Un objet non visuel ne peut pas recevoir de notification système.
2. Déclarer sur cet objet visuel un event mappé sur pbm_custom02, qui vide la file :
// event ue_toast_notified, mappe sur pbm_custom02
if IsValid(inv_toaster) then inv_toaster.of_process_events()
3. Traiter les événements levés sur le toaster :
| Événement | Déclenché quand |
|---|---|
ue_toast_clicked (string as_id) | Le corps du toast est cliqué (pas un bouton) |
ue_toast_action (string as_id, string as_action) | Un bouton d'action est cliqué ; as_action vaut la clé passée à of_add_button |
ue_toast_dismissed (string as_id) | Le toast se ferme : délai écoulé, croix de fermeture, ou après une action |
Sans ipo_receiver, la notification s'affiche et disparaît sans jamais rien renvoyer — c'est le mode le plus simple, parfait pour une simple confirmation.
Exemples #
Les quatre niveaux #
inv_toaster.of_reset()
inv_toaster.is_kind = inv_toaster.KIND_INFO
inv_toaster.is_text = "Operation terminee."
inv_toaster.of_show()
inv_toaster.of_reset()
inv_toaster.is_kind = inv_toaster.KIND_SUCCESS
inv_toaster.is_text = "Vos modifications ont ete [b]enregistrees[/b]."
inv_toaster.of_show()
inv_toaster.of_reset()
inv_toaster.is_kind = inv_toaster.KIND_WARNING
inv_toaster.il_timeout = 5000 // un peu plus long
inv_toaster.is_text = "Espace disque faible sur le lecteur C:."
inv_toaster.of_show()
inv_toaster.of_reset()
inv_toaster.is_kind = inv_toaster.KIND_ERROR
inv_toaster.il_timeout = 6000
inv_toaster.is_text = "Impossible de joindre le serveur."
inv_toaster.of_show()
Choisir le coin, dans la fenêtre ou sur l'écran #
// Ancre au coin haut droit de la FENETRE (defaut : suit l'application)
inv_toaster.is_position = inv_toaster.POSITION_TOP_RIGHT
inv_toaster.ib_screen = false
inv_toaster.is_text = "Ancre au coin de la fenetre."
inv_toaster.of_show()
// Detache : ancre au coin de l'ECRAN, visible meme si la fenetre est reduite
inv_toaster.is_position = inv_toaster.POSITION_TOP_RIGHT
inv_toaster.ib_screen = true
inv_toaster.is_text = "Traitement de nuit termine."
inv_toaster.of_show()
Toast enrichi : titre, image et durée #
inv_toaster.of_reset()
inv_toaster.is_title = "Sauvegarde terminee"
inv_toaster.is_text = "1 240 fichiers copies vers [b]\\serveur\backup[/b]."
inv_toaster.is_image = "mono:img\backup.svg"
inv_toaster.il_timeout = 8000 // reste 8 secondes
inv_toaster.of_show()
Notification avec boutons d'action #
// event open : brancher le retour une fois pour toutes
inv_toaster.ipo_owner = this
inv_toaster.ipo_receiver = this
// Proposer deux actions ; timeout 0 = le toast attend la decision de l'utilisateur
inv_toaster.of_reset()
inv_toaster.is_title = "Mise a jour disponible"
inv_toaster.is_text = "La version 2.0 est prete a etre installee."
inv_toaster.il_timeout = 0
inv_toaster.of_add_button(/*cle*/ "installer", /*libelle*/ "Installer")
inv_toaster.of_add_button(/*cle*/ "plus_tard", /*libelle*/ "Plus tard")
inv_toaster.of_show()
// event ue_toast_notified de la fenetre, mappe sur pbm_custom02
if IsValid(inv_toaster) then inv_toaster.of_process_events()
// event ue_toast_action de inv_toaster : (string as_id, string as_action)
choose case as_action
case "installer" ; of_lancer_mise_a_jour()
case "plus_tard" ; of_reporter(1)
end choose
Réagir au clic sur le message #
// event ue_toast_clicked de inv_toaster : (string as_id)
// L'utilisateur a clique le corps du toast : ouvrir l'ecran concerne
Open(w_journal_import)
Notifier depuis un traitement long #
// Fin d'un import : informer sans bloquer l'ecran de saisie
inv_toaster.of_reset()
if ll_erreurs = 0 then
inv_toaster.is_kind = inv_toaster.KIND_SUCCESS
inv_toaster.is_text = "Import termine : [b]" + String(ll_lignes) + " lignes[/b] integrees."
else
inv_toaster.is_kind = inv_toaster.KIND_ERROR
inv_toaster.il_timeout = 0 // une erreur doit etre lue
inv_toaster.is_text = "Import interrompu : " + String(ll_erreurs) + " erreurs."
end if
inv_toaster.of_show()
Bonnes pratiques #
- Une instance persistante par fenêtre (variable d'instance créée à l'ouverture) plutôt qu'une création/destruction à chaque message : le branchement
ipo_receiverreste en place et les retours arrivent. - Appelez
of_reset()avant chaque notification : sans cela le titre, l'image ou les boutons de la précédente restent posés. - Réservez
il_timeout = 0aux messages qui exigent une décision (erreur bloquante, action proposée) : un toast qui ne part pas tout seul finit par agacer. - Utilisez
ib_screen = trueuniquement pour ce qui doit rester visible quand l'application est en arrière-plan (fin de traitement long, tâche de nuit). - Un toast est un message transitoire : s'il faut absolument une réponse avant de continuer, utilisez messagebox, qui bloque et renvoie le choix.
- Pour un statut permanent plutôt qu'une notification, préférez statusbar.