toaster — n_pbt_toaster #
← Riferimento dei componenti · Sommario della guida
Notifiche « toast » in un angolo dello schermo: un messaggio che appare, informa e scompare senza bloccare l'utente né interrompere la sua digitazione.
▶ Vederlo dal vivo — Applicazione dimostrativa, riquadro Toaster: l'anteprima, il codice che lo produce e questa pagina, affiancati.
In breve #
| Oggetto | n_pbt_toaster — non visuale: niente da collocare nella finestra |
| Serve per | Confermare un'azione riuscita, segnalare un avviso o un errore, senza interrompere il lavoro in corso |
| Ritorno | Non bloccante: of_show() restituisce subito il controllo; le reazioni dell'utente tornano tramite event |
Il toast è una finestra staccata: fluttua sopra la Sua applicazione (o sopra tutto lo schermo) e si chiude da solo.
// Variabili locali
n_pbt_toaster lnv_toast
// Creare il notificatore
lnv_toast = create n_pbt_toaster
// ... configurazione ...
// Distruggerlo alla fine
destroy lnv_toast
Avvio rapido #
// Variabili locali
n_pbt_toaster lnv_toast
// Creare il notificatore
lnv_toast = create n_pbt_toaster
// Configurare, poi mostrare
lnv_toast.ipo_owner = this // finestra a cui il toast si aggancia
lnv_toast.is_kind = lnv_toast.KIND_SUCCESS // icona verde + bordino di successo
lnv_toast.is_text = "Le Sue modifiche sono state [b]salvate[/b]."
lnv_toast.of_show()
// Distruggerlo alla fine
destroy lnv_toast
Tutto si configura tramite proprietà, poi of_show() — che non accetta alcun argomento — fa apparire la notifica. Il toaster qui sopra viene distrutto subito: non torna nulla, ed è quanto basta per una semplice conferma. Per ricevere i ritorni di un toast, vedere « Dove scrivere gli event ».
Proprietà #
Da impostare prima di of_show.
| Proprietà | Tipo | Predefinito | Ruolo |
|---|---|---|---|
is_text | string | "" | Corpo del messaggio. Accetta il testo formattato con tag |
is_kind | string | KIND_INFO | Livello: governa l'icona e il colore del bordino. Costanti KIND_* |
is_position | string | POSITION_BOTTOM_RIGHT | Angolo di ancoraggio. Costanti POSITION_* |
ib_screen | boolean | false | false = ancorato all'angolo della finestra; true = ancorato all'angolo dello schermo, fluttuante sopra tutto. I toast ancorati allo schermo si impilano per monitor: due finestre che ne mostrano uno ciascuna non si sovrappongono più |
il_timeout | long | TIMEOUT_AUTO | Durata di visualizzazione in millisecondi prima della chiusura automatica. TIMEOUT_AUTO (-1, il valore predefinito) vale 4 s per un'informazione ma fino al clic per un errore — un errore che sparisce dopo quattro secondi è un errore perduto. TIMEOUT_UNTIL_CLICKED (0) rende persistente qualunque toast; una durata esplicita viene rispettata così com'è. Finché il puntatore resta sul toast il conto alla rovescia è sospeso, e una barra mostra il tempo restante |
is_title | string | "" | Riga di titolo in grassetto sopra il messaggio (toast avanzato) |
is_image | string | "" | Immagine illustrativa a sinistra, al posto dell'icona di livello (forme accettate: percorso, mono:, risorsa di DLL) |
is_key | string | "" | Chiave del toast: rimostrare la stessa chiave aggiorna il toast già a schermo invece di aprirne un secondo. È ciò di cui ha bisogno una notifica di avanzamento («Export 3/10» poi «4/10»): chiudere e riaprire farebbe ripartire l'animazione e scomporrebbe la pila. Lasci vuoto per un toast ordinario. La chiave appartiene al toaster: un altro toaster che mostra la stessa chiave apre un proprio toast. Un aggiornamento riprende anche il nuovo angolo, l'ancoraggio allo schermo e la finestra di ancoraggio. La chiave torna come as_key negli eventi ue_toast_* |
is_sound | string | SOUND_AUTO | Suono di sistema del toast, riprodotto quando viene richiesto. SOUND_AUTO (il predefinito): un errore o un avviso suona, un'informazione o un successo resta muto; SOUND_ALWAYS: ogni tipo; SOUND_NEVER: silenzio |
il_max_visible | long | 0 | Numero massimo di toast a schermo nello stesso angolo (da 1 a 20). Oltre, i successivi aspettano e compaiono man mano che si libera posto: un ciclo di elaborazione che emette un toast per riga impilava altrimenti le finestre fuori dallo schermo. Questo limite è comune a tutti i toaster dell'applicazione: vale l'ultimo valore impostato; 0 (il predefinito) lo lascia com'è — 5 finché nessuno lo imposta. Una pila è lo stesso angolo della stessa finestra — oppure, per un toast ancorato allo schermo o senza ipo_owner, lo stesso angolo dello stesso monitor, qualunque sia la finestra che l'ha mostrato. Anche un toast che non entrerebbe più nello schermo aspetta, e un toast non è mai più alto dello schermo: il suo testo scorre |
ipo_owner | powerobject | — | L'oggetto visuale a cui il toast è agganciato (l'angolo dell'area client della sua finestra serve da riferimento: sotto la barra del titolo; in una cornice MDI, l'area client della cornice, barre degli strumenti e MicroHelp lasciate libere). È l'unico collegamento da fare: gli eventi del toast sono attivati sul toaster stesso. Finché quella finestra è ridotta a icona, il toast aspetta: non si mostra e il suo conto alla rovescia non scorre finché la finestra non torna |
ipo_receiver | powerobject | — | Opzionale, retaggio: se impostato, la sua finestra riceve un pbm_custom02 a ogni evento di toast (per un codice meno recente che lo aveva collegato). Lo lasci vuoto — il toaster consegna i suoi eventi da solo, su se stesso |
Costanti #
| Costante | Valore | Uso |
|---|---|---|
KIND_INFO | "info" | Informazione neutra |
KIND_SUCCESS | "success" | Operazione riuscita |
KIND_WARNING | "warning" | Avviso |
KIND_ERROR | "error" | Fallimento |
POSITION_TOP_LEFT | "top-left" | Angolo in alto a sinistra |
POSITION_TOP_CENTER | "top-center" | In alto, centrato |
POSITION_TOP_RIGHT | "top-right" | Angolo in alto a destra |
POSITION_BOTTOM_LEFT | "bottom-left" | Angolo in basso a sinistra |
POSITION_BOTTOM_CENTER | "bottom-center" | In basso, centrato |
POSITION_BOTTOM_RIGHT | "bottom-right" | Angolo in basso a destra (predefinito) |
SOUND_AUTO | "auto" | Suono solo per un errore o un avviso (predefinito) |
SOUND_ALWAYS | "always" | Suono per ogni tipo |
SOUND_NEVER | "never" | Mai un suono |
REASON_TIMEOUT | "timeout" | ue_toast_dismissed: il suo conto alla rovescia è terminato |
REASON_USER | "user" | ue_toast_dismissed: l'utente ha cliccato la sua croce |
REASON_CODE | "code" | ue_toast_dismissed: of_close o of_close_all lo ha chiuso |
REASON_OWNER_CLOSED | "owner" | ue_toast_dismissed: la finestra a cui era ancorato si è chiusa |
Perché
LEFT/RIGHTqui, eSTART/ENDaltrove? Il toast è una finestra di sistema posizionata in pixel dello schermo, non un contenuto che segue un senso di lettura: un angolo dello schermo non ha un « inizio ». Queste costanti restano quindi volutamente fisiche e non cambiano lato quando l'applicazione passa alla scrittura da destra a sinistra. Vedere Lingua e RTL.
Metodi #
| Metodo | Ruolo |
|---|---|
of_show ( ) → long | Visualizza la notifica costruita a partire dalle proprietà. Restituisce l'identificatore del toast (> 0) — anche un toast che attende il suo posto (il_max_visible) riceve subito il suo —, oppure un valore negativo in caso di errore. Non blocca. -5 (e non si mostra nulla) per un'impostazione fuori dai suoi limiti: un is_kind, is_position o is_sound che non è nessuna delle sue costanti, il_max_visible fuori da 0 a 20, il_timeout sotto TIMEOUT_AUTO; -4: non mostrato questa volta — il motore di visualizzazione non è ancora pronto (riprovare), oppure la coda d'attesa è piena; -6: runtime WebView2 mancante. of_get_last_error dice perché |
of_close ( long al_id ) → long | Chiude un toast di questo toaster, indicato dall'identificatore restituito da of_show — visualizzato, non ancora disegnato, o ancora in attesa del suo posto. Ogni toast chiuso così attiva ue_toast_dismissed con REASON_CODE, anche se chiuso subito dopo of_show. Restituisce 0, oppure -5 (of_get_last_error dice perché) se l’identificatore è vuoto, indica un toast già scomparso o già in chiusura, o un toast di un altro toaster |
of_close_all ( ) → long | Chiude tutti i toast di questo toaster — visualizzati, non ancora disegnati o in attesa — e nulla di un altro toaster. Ciascuno attiva ue_toast_dismissed con REASON_CODE. Restituisce il numero di toast chiusi (0 se non ce n'era nessuno) |
of_get_last_error ( ) → string | Perché l'ultimo of_show o of_close ha rifiutato — "" se non ha rifiutato nulla. Da leggere dopo un ritorno negativo: un'impostazione fuori dai suoi limiti, il motore di visualizzazione non ancora pronto, un toast di un altro toaster… |
of_reset ( ) → long | Riporta tutte le proprietà di contenuto ai valori predefiniti e cancella i pulsanti (ipo_owner e ipo_receiver vengono conservati: sono collegamenti, non contenuto) Rende 0 una volta fatto. |
of_process_events ( ) | Svuota la coda dei ritorni del toast e attiva i corrispondenti event ue_toast_*. Il componente la chiama da solo finché un toast è a schermo: normalmente non devi farlo — vedere più avanti |
of_add_button (string as_key, string as_label {, string as_image }) → long | Aggiunge un pulsante d'azione (al massimo 3). Un clic emette ue_toast_action(id, chiave, azione); of_reset azzera i pulsanti. Un'etichetta può contenere qualunque carattere — una virgola, un segno di uguale — senza essere tagliata. Restituisce 0, oppure -5 (nulla viene aggiunto) per una chiave vuota, una chiave già presa, una chiave che contiene / o una barra verticale, o un quarto pulsante |
of_count ( ) → long | Restituisce il numero di pulsanti d'azione che porta la notifica |
of_keys_at ( long al_index ) → string | La chiave del pulsante di rango al_index (a partire da 1), oppure "" oltre l'uno o l'altro estremo |
of_has ( string as_key ) → boolean | È stato aggiunto un pulsante sotto questa chiave? of_add_button rifiuta (-5) una chiave già presa: chiedere prima dice perché |
Più toast visualizzati nello stesso angolo si impilano automaticamente. Ciascuno porta una croce di chiusura; l'identificatore restituito da of_show permette di distinguerli negli event e di chiuderli dal Suo codice.
Il conto alla rovescia si sospende finché il puntatore è sul toast: una notifica non deve svanire sotto gli occhi di chi la legge. Una sottile barra in basso mostra il tempo restante — e quindi spiega la sua sparizione. Un clic sul corpo risponde e chiude.
Una notifica impostata con il_timeout = 0 resta a schermo finché nessuno la chiude: conservi il suo identificatore per poterla rimuovere quando l'attività che annuncia è terminata.
// Variabili locali
long ll_toast
// Notifica persistente : restera visualizzata fino a of_close.
inv_toaster.is_text = "Esportazione in corso..."
inv_toaster.il_timeout = /*ms, 0 = nessuna chiusura automatica*/ 0
ll_toast = inv_toaster.of_show()
// ... elaborazione lunga ...
// Chiudere il toast a lavoro finito
inv_toaster.of_close(/*id*/ ll_toast)
Event — il toast Le risponde #
Una notifica non è un semplice « visualizza e dimentica »: può dirLe che è stata cliccata, che è stato scelto un pulsante d'azione, o che si è chiusa.
Non devi collegare nulla: imposta ipo_owner (la finestra a cui il toast è ancorato) e gestisci gli eventi. Il componente li preleva da solo finché un toast è a schermo e li solleva sull'oggetto — nessun ricevitore, nessun timer.
Dove scrivere gli event #
PowerBuilder offre gli event di un oggetto non visuale solo in due posti: un discendente di n_pbt_toaster (i suoi event portano i Suoi script), oppure un toaster collocato sulla finestra come ogni oggetto non visuale (nel painter della finestra, Insert > Object, poi n_pbt_toaster: i suoi event si scrivono nella finestra). Una variabile n_pbt_toaster creata con create non ha alcuno script: i suoi toast si mostrano, ma i loro ritorni non arrivano a nessuno. E un toaster distrutto non riferisce più nulla: i suoi toast persistenti e quelli con pulsanti si chiudono con lui, gli altri finiscono da soli, muti. Con un discendente n_my_toaster, la finestra ne tiene uno in una variabile di istanza inv_toaster:
// event open della finestra : creare il toaster una volta e ancorarlo
inv_toaster = create n_my_toaster
inv_toaster.ipo_owner = this
1. Impostare ipo_owner sulla finestra a cui il toast è ancorato:
// Ancorare i toast a questa finestra
inv_toaster.ipo_owner = this // la finestra a cui il toast e ancorato
2. Trattare gli event attivati sul toaster:
| Event | Attivato quando |
|---|---|
ue_toast_clicked (long al_id, string as_key) | Viene cliccato il corpo del toast (non un pulsante). al_id è l'identificatore restituito da of_show, as_key il is_key del toast (vuoto senza chiave) |
ue_toast_action (long al_id, string as_key, string as_action) | Viene cliccato un pulsante d'azione; as_action contiene la chiave passata a of_add_button. al_id è l'identificatore restituito da of_show, as_key il is_key del toast (vuoto senza chiave) |
ue_toast_dismissed (long al_id, string as_key, string as_reason) | Il toast si chiude; as_reason dice perché: REASON_TIMEOUT (tempo scaduto), REASON_USER (croce di chiusura), REASON_CODE (of_close o of_close_all, che il toast sia visualizzato, non ancora disegnato o in attesa), REASON_OWNER_CLOSED (la finestra di ancoraggio si è chiusa). Un clic sul corpo attiva ue_toast_clicked, un pulsante ue_toast_action. al_id è l'identificatore restituito da of_show, as_key il is_key del toast (vuoto senza chiave) |
Se non ti aspetti alcun ritorno — nessun pulsante d'azione, nessun clic sul corpo — non hai nessuno di questi eventi da gestire: la notifica appare e scompare da sola. È la modalità più semplice, perfetta per una semplice conferma.
Esempi #
I quattro livelli #
// Info : un messaggio neutro
inv_toaster.of_reset()
inv_toaster.is_kind = inv_toaster.KIND_INFO
inv_toaster.is_text = "Operazione terminata."
inv_toaster.of_show()
// Successo : e andato a buon fine
inv_toaster.of_reset()
inv_toaster.is_kind = inv_toaster.KIND_SUCCESS
inv_toaster.is_text = "Le Sue modifiche sono state [b]salvate[/b]."
inv_toaster.of_show()
// Avviso : da guardare
inv_toaster.of_reset()
inv_toaster.is_kind = inv_toaster.KIND_WARNING
inv_toaster.il_timeout = 5000 // un po' piu lungo
inv_toaster.is_text = "Spazio su disco insufficiente sull'unità C:."
inv_toaster.of_show()
// Errore : non e riuscito ; resta fino al clic
inv_toaster.of_reset()
inv_toaster.is_kind = inv_toaster.KIND_ERROR
inv_toaster.is_text = "Impossibile contattare il server."
inv_toaster.of_show()
Scegliere l'angolo, nella finestra o sullo schermo #
// Ancorato all'angolo in alto a destra della FINESTRA (predefinito : segue l'applicazione)
inv_toaster.is_position = inv_toaster.POSITION_TOP_RIGHT
inv_toaster.ib_screen = false
inv_toaster.is_text = "Ancorato all'angolo della finestra."
inv_toaster.of_show()
// Staccato : ancorato all'angolo dello SCHERMO, visibile anche se la finestra e ridotta a icona
inv_toaster.is_position = inv_toaster.POSITION_TOP_RIGHT
inv_toaster.ib_screen = true
inv_toaster.is_text = "Elaborazione notturna terminata."
inv_toaster.of_show()
Toast avanzato: titolo, immagine e durata #
// Ripartire dalle impostazioni predefinite
inv_toaster.of_reset()
// Un titolo, un testo e un'immagine
inv_toaster.is_title = "Backup completato"
inv_toaster.is_text = "1 240 file copiati in [b]\\server\backup[/b]."
inv_toaster.is_image = "mono:img\backup.svg"
inv_toaster.il_timeout = 8000 // resta 8 secondi
inv_toaster.of_show()
Notifica con pulsanti d'azione #
// event open : ancorare il toaster una volta per tutte ; i ritorni arrivano da soli
inv_toaster.ipo_owner = this
// Proporre due azioni ; timeout 0 = il toast attende la decisione dell'utente
inv_toaster.of_reset()
// Titolo, testo e due pulsanti, poi mostrare
inv_toaster.is_title = "Aggiornamento disponibile"
inv_toaster.is_text = "La versione 2.0 è pronta per essere installata."
inv_toaster.il_timeout = 0
inv_toaster.of_add_button(/*key*/ "install", /*label*/ "Installa")
inv_toaster.of_add_button(/*key*/ "later", /*label*/ "Piu tardi")
inv_toaster.of_show()
// event ue_toast_action di inv_toaster : (long al_id, string as_key, string as_action)
choose case as_action
case "install" ; of_start_update()
case "later" ; of_remind_later()
end choose
Reagire al clic sul messaggio #
// event ue_toast_clicked di inv_toaster : (long al_id, string as_key)
// L'utente ha cliccato il corpo del toast : aprire la schermata interessata
Open(w_import_log)
Sapere perché un toast si è chiuso, chiuderli tutti #
// event ue_toast_dismissed di inv_toaster : (long al_id, string as_key, string as_reason)
// Solo un toast chiuso dall'utente vuol dire non ora : ricordarlo piu tardi
if as_reason = n_pbt_toaster.REASON_USER then of_remind_later()
// Inizia una nuova importazione : le notifiche della precedente se ne vanno
inv_toaster.of_close_all()
Notificare da un'elaborazione lunga #
// Variabili locali
long ll_rows, ll_errors
// Righe caricate ed errori incontrati dall'importazione
ll_rows = of_rows_loaded()
ll_errors = of_errors_met()
// Fine di un'importazione : informare senza bloccare la schermata di digitazione
inv_toaster.of_reset()
// Tipo e testo seguono l'esito
if ll_errors = 0 then
inv_toaster.is_kind = inv_toaster.KIND_SUCCESS
inv_toaster.is_text = "Importazione terminata : [b]" + String(ll_rows) + " righe[/b] integrate."
else
inv_toaster.is_kind = inv_toaster.KIND_ERROR
inv_toaster.il_timeout = 0 // un errore deve essere letto
inv_toaster.is_text = "Importazione interrotta : " + String(ll_errors) + " errori."
end if
// Mostrare il toast
inv_toaster.of_show()
Buone pratiche #
- Un toaster per finestra, collocato sulla finestra o tenuto da una variabile di istanza di un discendente (vedere « Dove scrivere gli event »), invece di una creazione/distruzione a ogni messaggio: l'ancoraggio
ipo_ownerresta in essere e i ritorni arrivano. Un toaster distrutto non riceve più nulla: i suoi toast persistenti e quelli con pulsanti si chiudono con lui, gli altri finiscono da soli, muti. - Chiami
of_reset()prima di ogni notifica: senza di esso il titolo, l'immagine o i pulsanti della precedente restano impostati. - Riservi
il_timeout = 0ai messaggi che esigono una decisione (errore bloccante, azione proposta): un toast che non se ne va da solo finisce per infastidire. - Usi
ib_screen = truesoltanto per ciò che deve restare visibile quando l'applicazione è in secondo piano (fine di un'elaborazione lunga, attività notturna). - Un toast è un messaggio transitorio: se serve assolutamente una risposta prima di continuare, usi messagebox, che blocca e restituisce la scelta.
- Per uno stato permanente invece di una notifica, preferisca statusbar.