# statusbar — `u_pbt_statusbar` #

← Referencia de componentes · Índice de la guía

> Barra de estado con paneles: texto enriquecido, iconos, anchuras fijas o automáticas, alineación a la izquierda o a la derecha, paneles en los que se puede hacer clic, mini barra de progreso y estados con color.

> ▶ Verlo en vivo — Aplicación de demostración, mosaico Statusbar: la vista previa, el código que lo genera y esta página, uno al lado del otro.

## De un vistazo #

Userobject | `u_pbt_statusbar`
Clase de items | `n_pbt_statusbar_panel` (panel)
Sirve para | Mostrar en la parte inferior de la ventana el estado de la aplicación: contexto, avance, avisos discretos
Opciones opt-in | —

## Inicio rápido #

    // event open de la ventana
    // of_add_panel(id, texto, icono, alineacion, anchura)
    // id vacio = panel meramente informativo ; anchura 0 = ajustada al texto
    uo_statut.of_add_panel(/*id*/ "etat",  /*text*/ "Listo",           /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START,  /*width*/ 0)
    uo_statut.of_add_panel(/*id*/ "",      /*text*/ "Línea 12, Col 4", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START,  /*width*/ 0)
    uo_statut.of_add_panel(/*id*/ "heure", /*text*/ "12:00",          /*icon_file*/ "", /*align*/ uo_statut.ALIGN_END, /*width*/ 140)

    // Actualizar un panel en cualquier momento, mediante su identificador
    uo_statut.of_item("etat").is_text = "Guardando..."

## El modelo: paneles con clave #

La barra es una sucesión de paneles, añadidos por orden. Un panel recibe un identificador al crearse: es por él como se le encuentra después para cambiar su texto, su icono o su estado.

El identificador es una clave de direccionamiento, no un interruptor de interactividad:

- Identificador indicado: el panel se puede volver a encontrar — se cambia su contenido, se le pone una información sobre herramientas. Sigue siendo inerte: una barra de estado muestra ante todo, y un panel como `Línea 12, Col 4` no debe parecer pulsable.
- Identificador vacío: el panel es puramente decorativo. No se puede encontrar ni pulsar, y no se le puede adjuntar ninguna información sobre herramientas. Dé un identificador a todos sus paneles: no cuesta nada y deja la puerta abierta.
- Para hacer un panel pulsable, pídalo: `of_item("id").ib_clickable = true`. Un panel dotado de una lista desplegable (`of_set_panel_menu`) ya lo es.

    uo_statut.of_item("etat").is_text = "3 registros modificados"

Véase Base común · Los items.

## Propiedades #

Propiedad | Tipo | Predeterminado | Función
--- | --- | --- | ---
`ib_show_resize_grip` | boolean | `false` | Muestra el asa de redimensionamiento en la esquina del final de la barra
`is_theme_style` | string | `fluent` | Estilo visual del componente (constantes `THEME_STYLE_*`)
`is_theme_mode` | string | `light` | Variante clara u oscura (constantes `THEME_MODE_*`)
`il_theme_accent` | long | `-1` | Color de acento de este componente (`-1` = acento del tema)
`is_tooltip` | string | `""` | Tooltip simple mostrado al pasar el ratón por el componente
`is_super_tooltip_title` | string | `""` | Título del tooltip enriquecido (prevalece sobre `is_tooltip`)
`is_super_tooltip_text` | string | `""` | Texto del tooltip enriquecido (se acepta el marcado enriquecido)
`is_super_tooltip_image` | string | `""` | Imagen del tooltip enriquecido

## Métodos #

Método | Función
--- | ---
`of_add_panel (string as_id, string as_text, string as_icon_file, string as_align, integer ai_width)` | Añade un panel al final de la barra
`of_add_sep ( )` | Añade una línea vertical de separación entre dos grupos de paneles
`of_insert_panel (as_id, as_text, as_icon_file, as_align, ai_width, ai_index)` | Inserta un panel en una posición concreta (contada a partir de 0)
`of_move_panel (string as_id, integer ai_index)` | Desplaza un panel existente a otra posición
`of_remove_panel (string as_id)` | Elimina un solo panel; los demás conservan su estado
`of_item (string as_id)` → `n_pbt_statusbar_panel` | Devuelve el handle de un panel (creado en el primer acceso)
`of_flash_panel (string as_id, string as_text, long al_ms)` | Muestra un mensaje durante `al_ms` milisegundos y luego repone el texto anterior (`al_ms` ≤ 0 = 2 segundos)
`of_set_panel_menu (string as_id, string as_item_ids[], string as_labels[])` | Convierte el panel en un selector: el clic abre una lista desplegable y la elección vuelve por `ue_panel_menu_clicked`. Un identificador `-` inserta un separador; una etiqueta vacía retoma el identificador
`of_clear_panel_menu (string as_id)` | Retira la lista desplegable; el panel recupera el comportamiento que le da `ib_clickable`
`of_clear ( )` | Vacía la barra: todos los paneles y todos los separadores
`of_reset ( )` | Vacía la barra y devuelve las propiedades a su valor predeterminado

### Los argumentos de `of_add_panel` #

Argumento | Valores | Efecto
--- | --- | ---
`as_id` | libre, o `""` | Clave del panel, con la que se le vuelve a encontrar después. Vacío = panel decorativo, ni direccionable ni pulsable
`as_text` | texto | Contenido del panel. Se acepta el texto enriquecido con etiquetas
`as_icon_file` | ruta de imagen, o `""` | Icono mostrado antes del texto (formas aceptadas)
`as_align` | `ALIGN_START` (predeterminado) o `ALIGN_END` | Lado hacia el que se empuja el panel. Valores lógicos: `START` = inicio de la lectura (izquierda en escritura de izquierda a derecha). Los alias físicos `"left"` / `"right"` siguen aceptándose
`ai_width` | píxeles, o `0` | Anchura fija. `0` = el panel se ajusta a su contenido

### En un panel — `n_pbt_statusbar_panel` #

Miembro | Tipo | Predeterminado | Función
--- | --- | --- | ---
`is_text` | string | `""` | Texto del panel, se acepta el texto enriquecido con etiquetas
`is_image` | string | `""` | Icono del panel, modificable en cualquier momento
`ib_enabled` | boolean | `true` | Panel atenuado y sin clic
`ib_visible` | boolean | `true` | Panel oculto, sin ser retirado de la barra
`ii_progress` | integer | — | Mini barra de progreso dentro del panel, de `0` a `100`; un valor negativo la hace desaparecer
`is_state` | string | `""` | Estado semántico del panel, que lo colorea: véanse las constantes más abajo
`ib_indeterminate` | boolean | `false` | Barra animada sin valor, para un tratamiento de duración desconocida. Independiente de `ii_progress`, que sigue siendo el porcentaje exacto
`ib_clickable` | boolean | `false` | ¿Reacciona el panel al clic? Opt-in: un panel permanece inerte mientras no se pida, conservando su clave — se pilota y lleva una información sobre herramientas. Un panel con lista desplegable ya es pulsable

### Constantes de estado #

Constante | Valor | Uso
--- | --- | ---
`STATE_NONE` | `""` | Ningún estado: apariencia normal
`STATE_INFO` | `"info"` | Información
`STATE_WARNING` | `"warning"` | Advertencia
`STATE_ERROR` | `"error"` | Error
`STATE_SUCCESS` | `"success"` | Éxito

Como para toda propiedad con valores predefinidos, utilice la constante en lugar de la cadena:

    n_pbt_statusbar_panel lnv_panneau
    lnv_panneau = uo_statut.of_item("etat")
    lnv_panneau.is_state = lnv_panneau.STATE_WARNING

## Eventos #

Evento | Se activa cuando
--- | ---
`ue_panel_clicked (string as_id)` | Se hace clic en un panel cuyo identificador está informado
`ue_panel_double_clicked (string as_id)` | Un panel pulsable recibe un doble clic — el atajo clásico detrás de `Línea 12, Col 4` que abre un "Ir a la línea"
`ue_panel_rclicked (string as_id, long al_x, long al_y)` | Un panel recibe un clic derecho. `al_x` y `al_y` son píxeles de pantalla: páselos tal cual para abrir un menú contextual donde el usuario apuntó
`ue_panel_menu_clicked (string as_id, string as_item_id)` | Se ha elegido una entrada de una lista desplegable de panel (véase `of_set_panel_menu`)
`ue_ready ( )` | El componente ha terminado de cargarse; todo lo enviado antes se ha reproducido
`ue_runtime_missing ( )` | El runtime WebView2 está ausente: el componente permanece vacío
`ue_bg_color (long al_color)` | El componente ha calculado el color de fondo de su tema; el userobject ya lo ha adoptado (`backcolor`)

## Con el teclado #

La barra es una sola parada de tabulación: solo entran en ella los paneles hechos para ser pulsados, y las flechas los recorren.

Tecla | Efecto
--- | ---
Flechas | Pasan al panel interactivo anterior / siguiente, en bucle; los paneles de visualización y los desactivados se saltan
Inicio / Fin | Primer / último panel interactivo
Intro o Espacio | Dispara el panel — es decir, `ue_panel_clicked`, o la apertura de su lista desplegable si la tiene

Un panel que se limita a mostrar no es un control: no es enfocable ni se anuncia como tal. Un panel pulsable pero desactivado sí permanece anunciado como no disponible, en lugar de pasar por texto. Una barra de progreso anuncia su valor, y una indeterminada no anuncia ninguno — esa ausencia es el sentido de la palabra.

El foco sobrevive a la reconstrucción de la barra: se redibuja en cada cambio de texto, y sin esto el foco caería cada segundo en una barra que muestra un reloj.

## Ejemplos #

### Anchuras fijas y anchuras automáticas #

    // Anchura 0 : el panel ocupa exactamente el espacio de su texto
    uo_statut.of_add_panel(/*id*/ "", /*text*/ "Panel ajustado al contenido", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)

    // Anchura fija en pixeles : util cuando el texto cambia a menudo,
    // para que los paneles vecinos no se muevan en cada actualizacion
    uo_statut.of_add_panel(/*id*/ "pos", /*text*/ "Línea 1, Col 1", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 150)

    // Un panel empujado al extremo opuesto
    uo_statut.of_add_panel(/*id*/ "heure", /*text*/ "12:00", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_END, /*width*/ 140)

### Iconos y paneles con clic #

    // Un identificador no vacio hace que se pueda hacer clic en el panel
    uo_statut.of_add_panel(/*id*/ "save", /*text*/ "Guardado", /*icon_file*/ "mono:img\save.svg", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)
    uo_statut.of_add_sep()   // linea de separacion entre dos grupos de paneles
    uo_statut.of_add_panel(/*id*/ "conn", /*text*/ "Conectado",   /*icon_file*/ "mono:img\plug.svg", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)
    uo_statut.of_add_panel(/*id*/ "user", /*text*/ "Guillaume",  /*icon_file*/ "mono:img\user.svg", /*align*/ uo_statut.ALIGN_END, /*width*/ 160)

    // event ue_panel_clicked de uo_statut
    choose case as_id
        case "conn" ; open(w_parametres_connexion)
        case "user" ; open(w_profil)
    end choose

### Texto enriquecido en un panel #

Los paneles aceptan el texto enriquecido con etiquetas: estilos, colores y pequeñas imágenes directamente en el texto.

    uo_statut.of_add_panel(/*id*/ "", /*text*/ "Bienvenido [b]a[/b] [accent]PBToolboxAI[/accent]", &
                           /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)

    uo_statut.of_add_panel(/*id*/ "", /*text*/ "[green]En línea[/green] [picture=mono:img\plug.svg,14,14]", &
                           /*icon_file*/ "", /*align*/ uo_statut.ALIGN_END, /*width*/ 0)

    // El texto enriquecido vale tambien para las actualizaciones
    uo_statut.of_item("etat").is_text = "[b]" + String(ll_modifies) + "[/b] registros modificados"

### Seguir un proceso largo #

    n_pbt_statusbar_panel lnv_avance

    uo_statut.of_add_panel(/*id*/ "import", /*text*/ "Importación", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 220)
    lnv_avance = uo_statut.of_item("import")

    // En el bucle de proceso : la mini barra sigue el avance
    lnv_avance.ii_progress = ll_pourcentage
    lnv_avance.is_text     = "Importación " + String(ll_pourcentage) + " %"

    // Al final : ocultar la mini barra y senalar el resultado
    lnv_avance.ii_progress = -1                       // valor negativo = barra oculta
    lnv_avance.is_text     = "Importación finalizada"
    lnv_avance.is_state    = lnv_avance.STATE_SUCCESS

### Señalar un aviso discreto #

    n_pbt_statusbar_panel lnv_panneau
    lnv_panneau = uo_statut.of_item("conn")

    if not ib_connecte then
        lnv_panneau.is_text  = "Sin conexión"
        lnv_panneau.is_state = lnv_panneau.STATE_ERROR
    else
        lnv_panneau.is_text  = "Conectado"
        lnv_panneau.is_state = lnv_panneau.STATE_NONE   // vuelta a la apariencia normal
    end if

### Adaptar la barra al contexto #

    // Ocultar un panel sin eliminarlo : mas tarde recuperara su sitio
    uo_statut.of_item("user").ib_visible = ib_utilisateur_identifie

    // Atenuarlo cuando la accion correspondiente no tiene sentido
    uo_statut.of_item("save").ib_enabled = ib_document_ouvert

    // Reorganizar : colocar el panel de estado al principio (posiciones contadas a partir de 0)
    uo_statut.of_move_panel(/*id*/ "etat", /*index*/ 0)

    // Retirar un panel que ya no sirve
    uo_statut.of_remove_panel(/*id*/ "import")

### El asa de redimensionamiento #

    // En una ventana redimensionable, el asa de esquina es una referencia familiar
    uo_statut.ib_show_resize_grip = true

## Buenas prácticas #

- Dé una anchura fija a los paneles cuyo texto cambia a menudo (posición del cursor, contadores): los paneles vecinos dejarán de saltar en cada actualización.
- Deje el identificador vacío para un panel meramente informativo: así se evita un clic sin efecto.
- Reserve el lado derecho a la información estable (hora, usuario, conexión) y el lado izquierdo al contexto actual.
- Emplee `is_state` en lugar de colores en el texto: el estado sigue tanto el tema claro como el oscuro.
- Recuerde devolver `is_state` a `STATE_NONE` y `ii_progress` a un valor negativo en cuanto el aviso o el proceso haya terminado.
- Una barra de estado no es un registro: más allá de cinco o seis paneles, es preferible una notificación toaster.
- Si el avance merece más que una mini barra de panel, pase a la progressbar.

← Referencia de componentes · Índice de la guía