# toolbar — `u_pbt_toolbar` #

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

> Barra de herramientas plana: varias barras repartidas en bandas, botones, conmutadores, menús desplegables, campos de entrada, desbordamiento automático y desplazamiento mediante el asa.

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

## De un vistazo #

Userobject | `u_pbt_toolbar`
Clases de items | `n_pbt_toolbar_bar` (barra) → `n_pbt_toolbar_item` (herramienta)
Sirve para | Sustituir una barra de herramientas clásica por una barra moderna, con tema, repartida en varias filas reorganizables
Altura | Intrínseca: la barra se ajusta siempre a sus filas, no hay nada que activar — véase Altura automática

## Inicio rápido #

    // event open de la ventana
    n_pbt_toolbar_bar lnv_bar

    // of_bar() devuelve la barra predeterminada, siempre presente (id = MAIN_BAR)
    lnv_bar = uo_toolbar.of_bar(uo_toolbar.MAIN_BAR)

    lnv_bar.of_add_button(/*id*/ "save", /*text*/ "", /*image*/ "mono:img\save.svg", /*tooltip*/ "Guardar")
    lnv_bar.of_add_button(/*id*/ "find", /*text*/ "", /*image*/ "mono:img\find.svg", /*tooltip*/ "Buscar")
    lnv_bar.of_add_separator()
    lnv_bar.of_add_button(/*id*/ "help", /*text*/ "Ayuda",  /*image*/ "", /*tooltip*/ "Acerca de")

    // event ue_clicked de uo_toolbar : (string as_bar, string as_id)
    choose case as_bar + "/" + as_id
        case "main/save" ; of_enregistrer()
        case "main/find" ; of_rechercher()
        case "main/help" ; of_aide()
    end choose

## El modelo: barras, bandas, herramientas #

Una barra de herramientas contiene una o varias barras. Cada barra se coloca sobre una banda (una fila) y ocupa una posición dentro de esa fila: dos barras en la misma banda se reparten la fila, dos barras en bandas distintas se apilan — exactamente como las barras de herramientas clásicas de Office.

Las herramientas (botones, conmutadores, menús, campos) pertenecen a una barra. Su identificador solo es único dentro de su propia barra: por lo tanto, el acceso pasa siempre por la ruta completa.

    uo_toolbar.of_bar("main").of_item("save").ib_enabled = false

Las adiciones también se hacen sobre el handle del elemento padre: se añade una herramienta a una barra, no a la barra de herramientas. Consulte Base común · Los items para el principio general.

## Propiedades #

Propiedad | Tipo | Predeterminado | Función
--- | --- | --- | ---
`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
`ib_reorderable` | boolean | `false` | Permite al usuario reorganizar las barras con el ratón: los tiradores de desplazamiento aparecen y una barra puede arrastrarse a otra banda. Desactivado de forma predeterminada — una barra de herramientas desmontada por accidente es una llamada al soporte. Su código las reorganiza en cualquier caso (`of_set_layout`, `of_add_bar`): la autorización afecta al usuario, nunca a la aplicación

### Constante #

Constante | Valor | Función
--- | --- | ---
`MAIN_BAR` | `"main"` | Identificador de la barra predeterminada, siempre disponible sin necesidad de crearla

## Métodos #

Método | Función
--- | ---
`of_bar (string as_id)` → `n_pbt_toolbar_bar` | Devuelve el handle de una barra (creada en el primer acceso)
`of_add_bar (string as_bar)` → `n_pbt_toolbar_bar` | Añade una barra y devuelve su handle
`of_add_bar (string as_bar, integer ai_band, integer ai_index)` → `n_pbt_toolbar_bar` | Añade una barra en una banda y una posición determinadas (ambas contadas a partir de 0)
`of_remove_bar (string as_id)` | Elimina una barra y sus herramientas. Las demás conservan su estado activo, y las bandas se juntan detrás de la que se va. No es lo mismo que ocultarla (`ib_visible` en su handle): ocultar la mantiene en el modelo, lista para volver exactamente donde estaba; eliminar la olvida
`of_get_layout ()` | Vuelve a leer la disposición actual en JSON: qué barra en qué banda, en qué rango y visible o no. Guárdela y devuélvala con `of_set_layout`
`of_set_layout (string as_layout_json)` | Restaura una disposición de barras recibida anteriormente mediante `ue_layout_changed`
`of_clear ( )` | Elimina todas las barras y todas las herramientas
`of_reset ( )` | Vacía el contenido y restablece las propiedades a sus valores predeterminados

### En una barra — `n_pbt_toolbar_bar` #

Miembro | Tipo | Predeterminado | Función
--- | --- | --- | ---
`ii_band` | integer | `0` | Banda (fila) que aloja la barra; `0` = primera fila
`ii_index` | integer | `0` | Posición de la barra dentro de su banda
`ib_visible` | boolean | `true` | Muestra u oculta una barra. Una barra oculta conserva su banda, su rango y sus elementos: volver a mostrarla la devuelve exactamente a donde estaba, sin reconstruir nada — esa es la diferencia con `of_clear`, que los perdería
`of_item (string as_id)` → `n_pbt_toolbar_item` |  |  | Devuelve el handle de una herramienta de esta barra
`of_add_button (as_id, as_text, as_image, as_tooltip)` → `n_pbt_toolbar_item` |  |  | Botón de acción; el clic activa `ue_clicked`
`of_add_toggle (as_id, as_text, as_image, as_tooltip)` → `n_pbt_toolbar_item` |  |  | Conmutador de dos estados; el clic activa `ue_toggled`
`of_add_dropdown (as_id, as_text, as_image, as_tooltip)` → `n_pbt_toolbar_item` |  |  | Botón con menú desplegable; una elección activa `ue_menu_selected`
`of_add_label (as_id, as_text)` → `n_pbt_toolbar_item` |  |  | Etiqueta informativa, no se puede pulsar
`of_add_textbox (as_id, as_text, ai_width, as_tooltip)` → `n_pbt_toolbar_item` |  |  | Campo de entrada; Intro o pérdida del foco activa `ue_text_changed`. `ai_width` en píxeles
`of_add_datepicker (as_id, as_date, as_tooltip)` → `n_pbt_toolbar_item` |  |  | Selector de fecha; una elección activa `ue_date_changed`. Fechas con el formato `"aaaa-mm-dd"`
`of_add_separator ( )` |  |  | Trazo vertical de separación
`of_insert_button (as_id, as_text, as_image, as_tooltip, ai_index)` → `n_pbt_toolbar_item` |  |  | Boton anadido en la posicion elegida (primero = 0) en lugar de al final
`of_move_item (string as_id, integer ai_index)` |  |  | Mueve una herramienta a otra posicion en esta barra (primero = 0). Conserva su tipo, su menu y su estado vivo: la herramienta cambia de sitio, no se reconstruye. Vale para todos los tipos, asi que los `of_add_*` sin `of_insert_*` insertan anadiendo y luego moviendo
`of_remove_item (string as_id)` |  |  | Elimina una herramienta de esta barra. La barra permanece, y todo lo demás con ella, incluido el estado activo — solo se va la herramienta indicada. Para hacerla ir y venir, `ib_visible` en su handle la mantiene en el modelo

### En una herramienta — `n_pbt_toolbar_item` #

Miembro | Tipo | Predeterminado | Función
--- | --- | --- | ---
`ib_visible` | boolean | `true` | Muestra u oculta un elemento. Conserva su rango en la barra: volver a mostrarlo lo devuelve exactamente a donde estaba, no al final. No confundir con `ib_enabled`, que lo deja en su sitio, atenuado — oculte lo que no se aplica, atenúe lo que está momentáneamente no disponible
`ib_enabled` | boolean | `true` | Herramienta activa o atenuada
`ib_checked` | boolean | `false` | Estado de un conmutador (sin efecto en los demás tipos)
`is_text` | string | `""` | Etiqueta, se admite texto enriquecido con etiquetas
`is_shortcut` | string | `""` | Atajo de teclado (`"Ctrl+S"`), mostrado en el tooltip y activo
`of_add_menu_item (as_id, as_label, as_image)` |  |  | Entrada del menú de un botón desplegable
`of_add_menu_item (as_parent, as_id, as_label, as_image)` |  |  | Entrada en cascada, colocada bajo una entrada existente
`of_add_menu_separator (as_id)` |  |  | Trazo de separación en el menú

Las imágenes admiten todas las formas reconocidas por la biblioteca: ruta, `mono:`, `tint:`, recurso de una DLL.

## Eventos #

Evento | Se activa cuando
--- | ---
`ue_clicked (string as_bar, string as_id)` | Se pulsa un botón (o se activa mediante su atajo)
`ue_toggled (string as_bar, string as_id, boolean ab_checked)` | Un conmutador cambia de estado; `ab_checked` contiene el nuevo estado
`ue_menu_selected (string as_bar, string as_dropdown, string as_id)` | Se elige una entrada de un menú desplegable
`ue_text_changed (string as_bar, string as_id, string as_text)` | Se confirma un campo de entrada (Intro o pérdida del foco)
`ue_date_changed (string as_bar, string as_id, string as_date)` | Se elige una fecha (`"aaaa-mm-dd"`)
`ue_bar_reordered (string as_id, integer ai_band, integer ai_index)` | El usuario ha arrastrado una barra por su tirador a otra banda u otro rango (requiere `ib_reorderable`). Indica qué barra se ha movido y dónde ha aterrizado, mientras que `ue_layout_changed` lleva toda la disposición. Banda y rango empiezan en 1
`ue_layout_changed (string as_layout_json)` | La disposición ha cambiado — el usuario ha arrastrado una barra por su asa, o su propio código ha movido u ocultado una. Lleva la disposición entera, no solo lo que se movió
`ue_auto_height (long al_height)` | La altura ideal ha cambiado y la barra se ha ajustado a ella — siempre activo: el número de filas dicta la altura
`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`)

## Ejemplos #

### Conmutadores ya marcados y herramienta atenuada #

    n_pbt_toolbar_bar lnv_bar
    lnv_bar = uo_toolbar.of_bar(uo_toolbar.MAIN_BAR)

    lnv_bar.of_add_toggle(/*id*/ "bold",   /*text*/ "", /*image*/ "mono:img\bold.svg",   /*tooltip*/ "Negrita")
    lnv_bar.of_add_toggle(/*id*/ "italic", /*text*/ "", /*image*/ "mono:img\italic.svg", /*tooltip*/ "Cursiva")
    lnv_bar.of_add_separator()
    lnv_bar.of_add_button(/*id*/ "undo",   /*text*/ "", /*image*/ "mono:img\undo.svg",   /*tooltip*/ "Deshacer")

    // Cada herramienta se controla por su handle, obtenido desde SU barra
    lnv_bar.of_item("bold").ib_checked = true    // conmutador ya marcado
    lnv_bar.of_item("undo").ib_enabled = false   // por ahora no hay nada que deshacer

    // event ue_toggled de uo_toolbar
    if as_id = "bold" then of_appliquer_gras(ab_checked)

### Menú desplegable en cascada #

    n_pbt_toolbar_bar  lnv_bar
    n_pbt_toolbar_item lnv_menu

    lnv_bar = uo_toolbar.of_bar(uo_toolbar.MAIN_BAR)

    // El menu se rellena mediante el handle devuelto por of_add_dropdown
    lnv_menu = lnv_bar.of_add_dropdown(/*id*/ "export", /*text*/ "Exportar", &
                                       /*image*/ "mono:img\save.svg", /*tooltip*/ "Exportar el expediente")
    lnv_menu.of_add_menu_item(/*id*/ "exp_pdf", /*label*/ "PDF",  /*image*/ "")
    lnv_menu.of_add_menu_item(/*id*/ "exp_csv", /*label*/ "CSV",  /*image*/ "")
    lnv_menu.of_add_menu_separator(/*id*/ "sep1")

    // Submenu : se indica la entrada padre como primer argumento
    lnv_menu.of_add_menu_item(/*id*/ "exp_img", /*label*/ "Imagen...", /*image*/ "")
    lnv_menu.of_add_menu_item(/*parent*/ "exp_img", /*id*/ "exp_png", /*label*/ "PNG", /*image*/ "")
    lnv_menu.of_add_menu_item(/*parent*/ "exp_img", /*id*/ "exp_jpg", /*label*/ "JPEG", /*image*/ "")

    // event ue_menu_selected de uo_toolbar : (as_bar, as_dropdown, as_id)
    if as_dropdown = "export" then of_exporter(as_id)

### Campo de búsqueda y selector de fecha #

    n_pbt_toolbar_bar lnv_bar
    lnv_bar = uo_toolbar.of_bar(uo_toolbar.MAIN_BAR)

    lnv_bar.of_add_button(/*id*/ "save", /*text*/ "", /*image*/ "mono:img\save.svg", /*tooltip*/ "Guardar")
    lnv_bar.of_item("save").is_shortcut = "Ctrl+S"    // atajo activo y mostrado
    lnv_bar.of_add_separator()

    // 160 px de ancho ; la entrada se notifica al confirmar
    lnv_bar.of_add_textbox(/*id*/ "search", /*text*/ "", /*width*/ 160, /*tooltip*/ "Buscar (Intro para confirmar)")

    lnv_bar.of_add_label(/*id*/ "lbl_due", /*text*/ "Vencimiento:")
    lnv_bar.of_add_datepicker(/*id*/ "due", /*date*/ "2026-07-11", /*tooltip*/ "Fecha de vencimiento")

    // event ue_text_changed de uo_toolbar
    if as_id = "search" then of_filtrer(as_text)

    // event ue_date_changed de uo_toolbar : as_date con el formato "aaaa-mm-dd"
    if as_id = "due" then id_echeance = Date(as_date)

### Dos barras y disposición memorizada #

El usuario puede agarrar una barra por su asa (a la izquierda de la barra) y desplazarla a otra banda o a otra posición. Conserve la disposición al cerrar y restitúyala al abrir.

    n_pbt_toolbar_bar lnv_std, lnv_fmt

    lnv_std = uo_toolbar.of_bar(uo_toolbar.MAIN_BAR)
    lnv_std.of_add_button(/*id*/ "new",  /*text*/ "Nuevo", /*image*/ "", /*tooltip*/ "")
    lnv_std.of_add_button(/*id*/ "open", /*text*/ "Abrir",  /*image*/ "", /*tooltip*/ "")

    // Segunda barra, colocada en la banda 1 (segunda fila), en primera posicion
    lnv_fmt = uo_toolbar.of_add_bar(/*bar*/ "format", /*band*/ 1, /*index*/ 0)
    lnv_fmt.of_add_toggle(/*id*/ "bold", /*text*/ "N", /*image*/ "", /*tooltip*/ "Negrita")

    // Tambien se puede recolocar una barra en cualquier momento mediante sus propiedades
    uo_toolbar.of_bar("format").ii_band  = 0
    uo_toolbar.of_bar("format").ii_index = 1    // segunda barra de la primera fila

    // event ue_layout_changed de uo_toolbar : conservar la disposicion elegida
    is_disposition = as_layout_json

    // En la siguiente apertura : restituir lo que el usuario habia organizado
    if is_disposition <> "" then uo_toolbar.of_set_layout(is_disposition)

### Desbordamiento: «Más herramientas» #

Cuando el ancho ya no es suficiente, las herramientas que no caben se recogen en un menú Más herramientas señalado por un galón al final de la barra. Es automático, no hay nada que programar: las herramientas recogidas se pueden seguir pulsando y activan los mismos eventos. Un campo recogido —cuadro de texto o selector de fecha— sigue siendo un campo real: se escribe en él, se elige una fecha en él, y el evento se activa igual que si la herramienta se hubiera quedado en la barra.

### Altura automática #

No hay nada que activar: el número de filas (`of_set_layout`) dicta la altura, la barra se ajusta sola y le avisa.

    // event ue_auto_height de uo_toolbar
    uo_contenu.y      = uo_toolbar.y + al_height
    uo_contenu.height = parent.workspaceheight() - uo_contenu.y

Consulte Base común.

## Buenas prácticas #

- Utilice `MAIN_BAR` mientras una sola barra sea suficiente: ya existe, no hace falta añadirla.
- Acceda siempre a una herramienta por su ruta — `of_bar(...).of_item(...)` — y nunca solo por su identificador: es lo que hace que los identificadores sean reutilizables de una barra a otra.
- Agrupe las herramientas afines con `of_add_separator()` en lugar de con barras adicionales.
- En los botones con solo icono, rellene siempre el tooltip: es la única etiqueta de la que dispone el usuario.
- Si deja que el usuario reorganice las barras, memorice `ue_layout_changed` y reproduzca `of_set_layout` al abrir; de lo contrario, el esfuerzo se pierde en cada arranque.
- Llame a `of_reset()` antes de reconstruir por completo la barra de herramientas para otro contexto.
- Cuando los comandos son demasiado numerosos para una barra, pase a la cinta de opciones, organizada por pestañas y grupos.

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