PBToolboxAI v1 ← Site

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 #

Objetn_pbt_toasternon 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
RetourNon 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éTypeDéfautRôle
is_textstring""Corps du message. Accepte le balisage riche
is_kindstringKIND_INFONiveau : pilote l'icône et la couleur du liseré. Constantes KIND_*
is_positionstringPOSITION_BOTTOM_RIGHTCoin d'ancrage. Constantes POSITION_*
ib_screenbooleanfalsefalse = ancré au coin de la fenêtre ; true = ancré au coin de l'écran, flottant au-dessus de tout
il_timeoutlongTIMEOUT_AUTODuré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_titlestring""Ligne de titre en gras au-dessus du message (toast enrichi)
is_imagestring""Image d'illustration à gauche, à la place de l'icône de niveau (formes acceptées : chemin, mono:, ressource de DLL)
is_keystring""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_visiblelong5Nombre 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_ownerpowerobjectL'objet visuel auquel le toast est accroché (son coin de fenêtre sert de repère)
ipo_receiverpowerobjectL'objet visuel qui reçoit les événements du toast. Laissez-le vide pour une notification sans retour

Constantes #

ConstanteValeurUsage
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/RIGHT ici, et START/END ailleurs ? 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éthodeRôle
of_show ( ) → longAffiche 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 ) → longFerme 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 }) → longAjoute 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_receiver doit ê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énementDé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 #


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