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.
// Variables locales
n_pbt_toaster lnv_toast
// Crear el notificador
lnv_toast = create n_pbt_toaster
// ... configuracion ...
// Destruirlo al terminar
destroy lnv_toast
Inicio rápido #
// Variables locales
n_pbt_toaster lnv_toast
// Crear el notificador
lnv_toast = create n_pbt_toaster
// Configurar y luego mostrar
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()
// Destruirlo al terminar
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. Los toasts anclados a la pantalla se apilan por monitor: dos ventanas que muestran uno cada una ya no se superponen |
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. La clave pertenece al toaster: otro toaster que muestra la misma clave abre su propio toast. Una actualización toma también la nueva esquina, el anclaje a la pantalla y la ventana de anclaje. La clave vuelve como as_key en los eventos ue_toast_* |
is_sound | string | SOUND_AUTO | Sonido del sistema del toast, reproducido cuando se solicita. SOUND_AUTO (el predeterminado): un error o una advertencia suena, una información o un éxito queda en silencio; SOUND_ALWAYS: todos los tipos; SOUND_NEVER: silencio |
il_max_visible | long | 0 | 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. Este límite es común a todos los toasters de la aplicación: gana el último valor establecido; 0 (el predeterminado) lo deja como está — 5 mientras nadie lo establezca. Una pila es la misma esquina de la misma ventana — o, para un toast anclado a la pantalla o sin ipo_owner, la misma esquina del mismo monitor, sea cual sea la ventana que lo mostró |
ipo_owner | powerobject | — | El objeto visual al que está enganchado el toast (su esquina de ventana sirve de referencia). Es la única conexión que hacer: los eventos del toast se activan en el propio toaster. Mientras esa ventana está minimizada, el toast espera: no se muestra y su cuenta atrás no corre hasta que la ventana vuelva |
ipo_receiver | powerobject | — | Opcional, heredado: si se establece, su ventana recibe un pbm_custom02 en cada evento de toast (para un código antiguo que lo había conectado). Déjelo vacío — el toaster entrega sus eventos él mismo, sobre sí mismo |
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) |
SOUND_AUTO | "auto" | Sonido solo para un error o una advertencia (predeterminado) |
SOUND_ALWAYS | "always" | Sonido para todos los tipos |
SOUND_NEVER | "never" | Nunca un sonido |
¿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) — un toast que espera su sitio (il_max_visible) también recibe el suyo enseguida —, o un valor negativo en caso de error. No bloquea. -5 (y no se muestra nada) para un ajuste fuera de sus límites: un is_kind, is_position o is_sound que no es ninguna de sus constantes, il_max_visible fuera de 0 a 20, il_timeout por debajo de TIMEOUT_AUTO |
of_close ( long al_id ) → long | Cierra un toast todavía visible — o que aún espera su sitio —, designado por el identificador devuelto por of_show. Un toast VISIBLE cerrado así activa ue_toast_dismissed, como su aspa; uno que aún espera nunca se vio y no activa nada. 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. El componente la llama él mismo mientras un toast está en pantalla: normalmente no tiene que hacerlo — 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). Un clic emite ue_toast_action(id, clave, acción); of_reset borra los botones. Una etiqueta puede contener cualquier carácter — una coma, un signo igual — sin ser cortada. Devuelve 0, o -5 (no se añade nada) para una clave vacía, una clave ya ocupada, una clave que contiene / o una barra vertical, o un cuarto botón |
of_count ( ) → long | Devuelve el número de botones de acción que lleva la notificación |
of_keys_at ( long al_index ) → string | La clave del botón en la posición al_index (desde 1), o "" más allá de cualquiera de los extremos |
of_has ( string as_key ) → boolean | ¿Se añadió un botón bajo esta clave? of_add_button rechaza (-5) una clave ya ocupada: preguntar antes dice por qué |
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.
// Variables locales
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 ...
// Cerrar el toast al terminar el trabajo
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.
No tiene que cablear nada: fije ipo_owner (la ventana a la que se ancla el toast) y trate los eventos. El componente los recoge él mismo mientras un toast está en pantalla y los lanza en el objeto — sin receptor, sin temporizador.
1. Fijar ipo_owner en la ventana a la que se ancla el toast:
// Anclar los toasts a esta ventana
inv_toaster.ipo_owner = this // la ventana a la que se ancla el toast
2. Tratar los eventos activados en el toaster:
| Evento | Se activa cuando |
|---|---|
ue_toast_clicked (long al_id, string as_key) | Se hace clic en el cuerpo del toast (no en un botón). al_id es el identificador devuelto por of_show, as_key el is_key del toast (vacío sin clave) |
ue_toast_action (long al_id, string as_key, string as_action) | Se hace clic en un botón de acción; as_action contiene la clave pasada a of_add_button. al_id es el identificador devuelto por of_show, as_key el is_key del toast (vacío sin clave) |
ue_toast_dismissed (long al_id, string as_key) | El toast se cierra: tiempo agotado, aspa de cierre, u of_close mientras está visible (un toast que aún espera no activa nada). Un clic en el cuerpo activa ue_toast_clicked, un botón ue_toast_action. al_id es el identificador devuelto por of_show, as_key el is_key del toast (vacío sin clave) |
Si no espera ninguna respuesta — ni botón de acción, ni clic en el cuerpo — no tiene ninguno de estos eventos que tratar: la notificación aparece y desaparece sola. Es el modo más sencillo, perfecto para una simple confirmación.
Ejemplos #
Los cuatro niveles #
// Info : un mensaje neutro
inv_toaster.of_reset()
inv_toaster.is_kind = inv_toaster.KIND_INFO
inv_toaster.is_text = "Operación terminada."
inv_toaster.of_show()
// Exito : se ha hecho
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()
// Aviso : merece una mirada
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()
// Error : ha fallado
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 #
// Partir de los ajustes por defecto
inv_toaster.of_reset()
// Un titulo, un texto y una imagen
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 : anclar el toaster una vez por todas ; los retornos llegan solos
inv_toaster.ipo_owner = this
// Proponer dos acciones ; timeout 0 = el toast espera la decision del usuario
inv_toaster.of_reset()
// Titulo, texto y dos botones, luego mostrar
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(/*key*/ "installer", /*label*/ "Instalar")
inv_toaster.of_add_button(/*key*/ "later", /*label*/ "Mas tarde")
inv_toaster.of_show()
// event ue_toast_action de inv_toaster : (long al_id, string as_key, string as_action)
choose case as_action
case "installer" ; of_start_update()
case "later" ; of_reporter(1)
end choose
Reaccionar al clic en el mensaje #
// event ue_toast_clicked de inv_toaster : (long al_id, string as_key)
// 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()
// El tipo y el texto siguen el resultado
if ll_errors = 0 then
inv_toaster.is_kind = inv_toaster.KIND_SUCCESS
inv_toaster.is_text = "Importación terminada : [b]" + String(ll_rows) + " 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_errors) + " errores."
end if
// Mostrar el toast
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: el anclaje
ipo_ownerpermanece en su sitio y los retornos llegan. Un toaster destruido ya no recibe nada: sus toasts siguen en pantalla, mudos. - 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.