toaster — n_pbt_toaster #
← Referencia de componentes · Índice de la guía
Notificaciones «toast» en una esquina de la pantalla: un mensaje que aparece, informa y desaparece sin bloquear al usuario ni interrumpir lo que está escribiendo.
▶ Verlo en vivo — Aplicación de demostración, mosaico Toaster: la vista previa, el código que lo genera y esta página, uno al lado del otro.
De un vistazo #
| Objeto | n_pbt_toaster — no visual: no hay nada que colocar en la ventana |
| Sirve para | Confirmar una acción realizada con éxito, señalar una advertencia o un error, sin detener el trabajo en curso |
| Retorno | No bloqueante: of_show() devuelve el control de inmediato; las reacciones del usuario vuelven por eventos |
El toast es una ventana independiente: flota por encima de su aplicación (o de toda la pantalla) y se cierra solo.
n_pbt_toaster lnv_toast
lnv_toast = create n_pbt_toaster
// ... configuracion ...
destroy lnv_toast
Inicio rápido #
n_pbt_toaster lnv_toast
lnv_toast = create n_pbt_toaster
lnv_toast.ipo_owner = this // ventana a la que se engancha el toast
lnv_toast.is_kind = lnv_toast.KIND_SUCCESS // icono verde + filete de exito
lnv_toast.is_text = "Sus modificaciones se han [b]guardado[/b]."
lnv_toast.of_show()
destroy lnv_toast
Todo se configura mediante propiedades, y luego of_show() — que no acepta ningún argumento — hace aparecer la notificación.
Propiedades #
Deben establecerse antes de of_show.
| Propiedad | Tipo | Predeterminado | Función |
|---|---|---|---|
is_text | string | "" | Cuerpo del mensaje. Admite el texto enriquecido con etiquetas |
is_kind | string | KIND_INFO | Nivel: gobierna el icono y el color del filete. Constantes KIND_* |
is_position | string | POSITION_BOTTOM_RIGHT | Esquina de anclaje. Constantes POSITION_* |
ib_screen | boolean | false | false = anclado a la esquina de la ventana; true = anclado a la esquina de la pantalla, flotando por encima de todo |
il_timeout | long | TIMEOUT_AUTO | Tiempo de visualización en milisegundos antes del cierre automático. TIMEOUT_AUTO (-1, el valor predeterminado) vale 4 s para una información pero hasta el clic para un error — un error que se borra en cuatro segundos es un error perdido. TIMEOUT_UNTIL_CLICKED (0) hace persistente cualquier toast; una duración explícita se respeta tal cual. Mientras el puntero permanece sobre un toast su cuenta atrás está suspendida, y una barra muestra el tiempo restante |
is_title | string | "" | Línea de título en negrita encima del mensaje (toast enriquecido) |
is_image | string | "" | Imagen ilustrativa a la izquierda, en lugar del icono de nivel (formas admitidas: ruta, mono:, recurso de DLL) |
is_key | string | "" | Clave del toast: volver a mostrar la misma clave actualiza el toast ya en pantalla en lugar de abrir un segundo. Es lo que necesita una notificación de progreso («Exportación 3/10» y luego «4/10»): cerrar y reabrir reiniciaría la animación y descolocaría la pila. Déjela vacía para un toast corriente |
il_max_visible | long | 5 | Número máximo de toasts en pantalla en la misma esquina (1 a 20). Más allá, los siguientes esperan y aparecen a medida que se libera sitio: un bucle de proceso que emite un toast por fila apilaba si no las ventanas fuera de la pantalla |
ipo_owner | powerobject | — | El objeto visual al que está enganchado el toast (su esquina de ventana sirve de referencia) |
ipo_receiver | powerobject | — | El objeto visual que recibe los eventos del toast. Déjelo vacío para una notificación sin retorno |
Constantes #
| Constante | Valor | Uso |
|---|---|---|
KIND_INFO | "info" | Información neutra |
KIND_SUCCESS | "success" | Operación realizada con éxito |
KIND_WARNING | "warning" | Advertencia |
KIND_ERROR | "error" | Fallo |
POSITION_TOP_LEFT | "top-left" | Esquina superior izquierda |
POSITION_TOP_CENTER | "top-center" | Arriba, centrado |
POSITION_TOP_RIGHT | "top-right" | Esquina superior derecha |
POSITION_BOTTOM_LEFT | "bottom-left" | Esquina inferior izquierda |
POSITION_BOTTOM_CENTER | "bottom-center" | Abajo, centrado |
POSITION_BOTTOM_RIGHT | "bottom-right" | Esquina inferior derecha (predeterminado) |
¿Por qué
LEFT/RIGHTaquí ySTART/ENDen el resto? El toast es una ventana del sistema colocada en píxeles de pantalla, no un contenido que siga un sentido de lectura: una esquina de la pantalla no tiene «inicio». Por eso estas constantes siguen siendo deliberadamente físicas y no cambian de lado cuando la aplicación pasa a escritura de derecha a izquierda. Véase Idioma y RTL.
Métodos #
| Método | Función |
|---|---|
of_show ( ) → long | Muestra la notificación construida a partir de las propiedades. Devuelve el identificador del toast (> 0), o un valor negativo en caso de error. No bloquea |
of_close ( long al_id ) → long | Cierra un toast todavía visible, designado por el identificador devuelto por of_show. Devuelve 0, o -5 si el identificador está vacío o designa un toast que ya ha desaparecido |
of_reset ( ) | Devuelve todas las propiedades de contenido a su valor predeterminado y borra los botones (ipo_owner e ipo_receiver se conservan: son conexiones, no contenido) |
of_process_events ( ) | Vacía la cola de retornos del toast y activa los eventos ue_toast_* correspondientes — véase más abajo |
of_add_button (string as_key, string as_label {, string as_image }) → long | Añade un botón de acción (3 como máximo) y devuelve cuántos hay. Un clic emite ue_toast_action(id, clave); of_reset borra los botones. Una etiqueta puede contener cualquier carácter — una coma, un signo igual — sin ser cortada |
Varios toasts mostrados en la misma esquina se apilan automáticamente. Cada uno lleva un aspa de cierre; el identificador devuelto por of_show permite distinguirlos en los eventos y cerrarlos desde su código.
La cuenta atrás se detiene mientras el puntero está sobre el toast: una notificación no debe desvanecerse ante los ojos de quien la lee. Una fina barra en la parte inferior muestra el tiempo restante — y explica así su desaparición. Un clic en el cuerpo responde y cierra, en ambos modos de alojamiento.
Una notificación creada con il_timeout = 0 permanece en pantalla mientras nadie la cierre: conserve su identificador para poder retirarla cuando termine la tarea que anuncia.
long ll_toast
// Notificacion persistente : permanecera visible hasta of_close.
inv_toaster.is_text = "Exportación en curso..."
inv_toaster.il_timeout = /*ms, 0 = sin cierre automatico*/ 0
ll_toast = inv_toaster.of_show()
// ... procesamiento largo ...
inv_toaster.of_close(/*id*/ ll_toast)
Eventos — el toast le responde #
Una notificación no es un simple «mostrar y olvidar»: puede decirle que se ha hecho clic en ella, que se ha elegido un botón de acción, o que se ha cerrado.
Como el toast vive en una ventana independiente, la conexión se hace en tres pasos.
1. Designar el objeto visual destinatario:
inv_toaster.ipo_owner = this
inv_toaster.ipo_receiver = this // este userobject / esta ventana recibira los retornos
ipo_receiverdebe ser un objeto visual (ventana o userobject). Un objeto no visual no puede recibir notificaciones del sistema.
2. Declarar en ese objeto visual un event asignado a pbm_custom02, que vacía la cola:
// event ue_toast_notified, asignado a pbm_custom02
if IsValid(inv_toaster) then inv_toaster.of_process_events()
3. Tratar los eventos activados en el toaster:
| Evento | Se activa cuando |
|---|---|
ue_toast_clicked (string as_id) | Se hace clic en el cuerpo del toast (no en un botón) |
ue_toast_action (string as_id, string as_action) | Se hace clic en un botón de acción; as_action contiene la clave pasada a of_add_button |
ue_toast_dismissed (string as_id) | El toast se cierra: tiempo agotado, aspa de cierre, o después de una acción |
Sin ipo_receiver, la notificación aparece y desaparece sin devolver nunca nada — es el modo más sencillo, perfecto para una simple confirmación.
Ejemplos #
Los cuatro niveles #
inv_toaster.of_reset()
inv_toaster.is_kind = inv_toaster.KIND_INFO
inv_toaster.is_text = "Operación terminada."
inv_toaster.of_show()
inv_toaster.of_reset()
inv_toaster.is_kind = inv_toaster.KIND_SUCCESS
inv_toaster.is_text = "Sus modificaciones se han [b]guardado[/b]."
inv_toaster.of_show()
inv_toaster.of_reset()
inv_toaster.is_kind = inv_toaster.KIND_WARNING
inv_toaster.il_timeout = 5000 // un poco mas largo
inv_toaster.is_text = "Poco espacio en disco en la unidad 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 = "No se puede contactar con el servidor."
inv_toaster.of_show()
Elegir la esquina, en la ventana o en la pantalla #
// Anclado a la esquina superior derecha de la VENTANA (predeterminado : sigue a la aplicacion)
inv_toaster.is_position = inv_toaster.POSITION_TOP_RIGHT
inv_toaster.ib_screen = false
inv_toaster.is_text = "Anclado a la esquina de la ventana."
inv_toaster.of_show()
// Independiente : anclado a la esquina de la PANTALLA, visible aunque la ventana este minimizada
inv_toaster.is_position = inv_toaster.POSITION_TOP_RIGHT
inv_toaster.ib_screen = true
inv_toaster.is_text = "Proceso nocturno terminado."
inv_toaster.of_show()
Toast enriquecido: título, imagen y duración #
inv_toaster.of_reset()
inv_toaster.is_title = "Copia de seguridad terminada"
inv_toaster.is_text = "1 240 ficheros copiados en [b]\\servidor\backup[/b]."
inv_toaster.is_image = "mono:img\backup.svg"
inv_toaster.il_timeout = 8000 // permanece 8 segundos
inv_toaster.of_show()
Notificación con botones de acción #
// event open : conectar el retorno una vez por todas
inv_toaster.ipo_owner = this
inv_toaster.ipo_receiver = this
// Proponer dos acciones ; timeout 0 = el toast espera la decision del usuario
inv_toaster.of_reset()
inv_toaster.is_title = "Actualización disponible"
inv_toaster.is_text = "La versión 2.0 está lista para instalarse."
inv_toaster.il_timeout = 0
inv_toaster.of_add_button(/*clave*/ "installer", /*etiqueta*/ "Instalar")
inv_toaster.of_add_button(/*clave*/ "plus_tard", /*etiqueta*/ "Mas tarde")
inv_toaster.of_show()
// event ue_toast_notified de la ventana, asignado a 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
Reaccionar al clic en el mensaje #
// event ue_toast_clicked de inv_toaster : (string as_id)
// El usuario ha hecho clic en el cuerpo del toast : abrir la pantalla correspondiente
Open(w_journal_import)
Notificar desde un procesamiento largo #
// Fin de una importacion : informar sin bloquear la pantalla de entrada de datos
inv_toaster.of_reset()
if ll_erreurs = 0 then
inv_toaster.is_kind = inv_toaster.KIND_SUCCESS
inv_toaster.is_text = "Importación terminada : [b]" + String(ll_lignes) + " líneas[/b] integradas."
else
inv_toaster.is_kind = inv_toaster.KIND_ERROR
inv_toaster.il_timeout = 0 // un error debe leerse
inv_toaster.is_text = "Importación interrumpida : " + String(ll_erreurs) + " errores."
end if
inv_toaster.of_show()
Buenas prácticas #
- Una instancia persistente por ventana (variable de instancia creada en la apertura) en lugar de una creación/destrucción con cada mensaje: la conexión
ipo_receiverpermanece en su sitio y los retornos llegan. - Llame a
of_reset()antes de cada notificación: de lo contrario, el título, la imagen o los botones de la anterior seguirán puestos. - Reserve
il_timeout = 0para los mensajes que exigen una decisión (error bloqueante, acción propuesta): un toast que no se va solo acaba resultando molesto. - Utilice
ib_screen = trueúnicamente para lo que deba seguir siendo visible cuando la aplicación está en segundo plano (fin de un procesamiento largo, tarea nocturna). - Un toast es un mensaje transitorio: si es imprescindible obtener una respuesta antes de continuar, utilice messagebox, que bloquea y devuelve la elección.
- Para un estado permanente en lugar de una notificación, prefiera statusbar.