# toolbar — `u_pbt_toolbar` #

← Referência dos componentes · Índice do guia

> Barra de ferramentas plana: várias barras distribuídas por bandas, botões, alternadores, menus pendentes, campos de introdução, excedente automático e deslocação pela pega.

> ▶ Ver ao vivo — Aplicação de demonstração, mosaico Toolbar: a pré-visualização, o código que o produz e esta página, lado a lado.

## Em resumo #

Userobject | `u_pbt_toolbar`
Classes de items | `n_pbt_toolbar_bar` (barra) → `n_pbt_toolbar_item` (ferramenta)
Serve para | Substituir uma barra de ferramentas clássica por uma barra moderna, com tema, em várias filas reorganizáveis
Altura | Intrínseca: a barra ajusta-se sempre às suas filas, nada há para ativar — ver Altura automática

## Início rápido #

    // event open da janela
    n_pbt_toolbar_bar lnv_bar

    // of_bar() devolve a barra por omissao, sempre presente (id = MAIN_BAR)
    lnv_bar = uo_toolbar.of_bar(uo_toolbar.MAIN_BAR)

    lnv_bar.of_add_button(/*id*/ "save", /*texto*/ "", /*imagem*/ "mono:img\save.svg", /*tooltip*/ "Guardar")
    lnv_bar.of_add_button(/*id*/ "find", /*texto*/ "", /*imagem*/ "mono:img\find.svg", /*tooltip*/ "Procurar")
    lnv_bar.of_add_separator()
    lnv_bar.of_add_button(/*id*/ "help", /*texto*/ "Ajuda",  /*imagem*/ "", /*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

## O modelo: barras, bandas, ferramentas #

Uma barra de ferramentas contém uma ou várias barras. Cada barra assenta numa banda (uma fila) e ocupa uma posição nessa fila: duas barras na mesma banda partilham a fila, duas barras em bandas diferentes empilham-se — exatamente como as barras de ferramentas clássicas do Office.

As ferramentas (botões, alternadores, menus, campos) pertencem a uma barra. O respetivo identificador só é único dentro da sua barra: o acesso faz-se, por isso, sempre pelo caminho completo.

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

As adições vivem igualmente no handle do elemento pai: acrescenta-se uma ferramenta a uma barra, não à barra de ferramentas. Ver Base comum · Os items para o princípio geral.

## Propriedades #

Propriedade | Tipo | Predefinição | Função
--- | --- | --- | ---
`is_theme_style` | string | `fluent` | Estilo visual do componente (constantes `THEME_STYLE_*`)
`is_theme_mode` | string | `light` | Variante clara ou escura (constantes `THEME_MODE_*`)
`il_theme_accent` | long | `-1` | Cor de destaque deste componente (`-1` = destaque do tema)
`is_tooltip` | string | `""` | Tooltip simples apresentado ao passar sobre o componente
`is_super_tooltip_title` | string | `""` | Título do tooltip enriquecido (prevalece sobre `is_tooltip`)
`is_super_tooltip_text` | string | `""` | Texto do tooltip enriquecido (aceita marcação enriquecida)
`is_super_tooltip_image` | string | `""` | Imagem do tooltip enriquecido
`ib_reorderable` | boolean | `false` | Permite ao utilizador reorganizar as barras com o rato: as pegas de deslocação aparecem e uma barra pode ser arrastada para outra banda. Desativado por predefinição — uma barra de ferramentas desmontada por acidente é uma chamada ao suporte. O seu código reorganiza-as de qualquer forma (`of_set_layout`, `of_add_bar`): a autorização incide sobre o utilizador, nunca sobre a aplicação

### Constante #

Constante | Valor | Função
--- | --- | ---
`MAIN_BAR` | `"main"` | Identificador da barra por omissão, sempre disponível sem ser necessário criá-la

## Métodos #

Método | Função
--- | ---
`of_bar (string as_id)` → `n_pbt_toolbar_bar` | Devolve o handle de uma barra (criada no primeiro acesso)
`of_add_bar (string as_bar)` → `n_pbt_toolbar_bar` | Acrescenta uma barra e devolve o respetivo handle
`of_add_bar (string as_bar, integer ai_band, integer ai_index)` → `n_pbt_toolbar_bar` | Acrescenta uma barra numa banda e numa posição precisas (ambas contadas a partir de 0)
`of_remove_bar (string as_id)` | Remove uma barra e as suas ferramentas. As outras mantêm o seu estado ativo, e as bandas juntam-se atrás da que sai. Não é o mesmo que ocultá-la (`ib_visible` no seu handle): ocultar mantém-na no modelo, pronta a voltar exatamente onde estava; remover esquece-a
`of_get_layout ()` | Relê a disposição atual em JSON: que barra em que banda, em que posição, e visível ou não. Guarde-a e devolva-a com `of_set_layout`
`of_set_layout (string as_layout_json)` | Restaura uma disposição de barras recebida anteriormente através de `ue_layout_changed`
`of_clear ( )` | Elimina todas as barras e todas as ferramentas
`of_reset ( )` | Esvazia o conteúdo e repõe as propriedades nos respetivos valores por omissão

### Numa barra — `n_pbt_toolbar_bar` #

Membro | Tipo | Predefinição | Função
--- | --- | --- | ---
`ii_band` | integer | `0` | Banda (fila) que suporta a barra; `0` = primeira fila
`ii_index` | integer | `0` | Posição da barra na respetiva banda
`ib_visible` | boolean | `true` | Mostra ou oculta uma barra. Uma barra oculta mantém a sua banda, a sua posição e os seus itens: voltar a mostrá-la coloca-a exatamente onde estava, sem reconstruir nada — é a diferença face a `of_clear`, que os perderia
`of_item (string as_id)` → `n_pbt_toolbar_item` |  |  | Devolve o handle de uma ferramenta desta barra
`of_add_button (as_id, as_text, as_image, as_tooltip)` → `n_pbt_toolbar_item` |  |  | Botão de ação; o clique aciona `ue_clicked`
`of_add_toggle (as_id, as_text, as_image, as_tooltip)` → `n_pbt_toolbar_item` |  |  | Alternador de dois estados; o clique aciona `ue_toggled`
`of_add_dropdown (as_id, as_text, as_image, as_tooltip)` → `n_pbt_toolbar_item` |  |  | Botão com menu pendente; uma escolha aciona `ue_menu_selected`
`of_add_label (as_id, as_text)` → `n_pbt_toolbar_item` |  |  | Etiqueta informativa, não clicável
`of_add_textbox (as_id, as_text, ai_width, as_tooltip)` → `n_pbt_toolbar_item` |  |  | Campo de introdução; Enter ou perda do foco aciona `ue_text_changed`. `ai_width` em píxeis
`of_add_datepicker (as_id, as_date, as_tooltip)` → `n_pbt_toolbar_item` |  |  | Seletor de data; uma escolha aciona `ue_date_changed`. Datas no formato `"aaaa-mm-dd"`
`of_add_separator ( )` |  |  | Traço vertical de separação
`of_insert_button (as_id, as_text, as_image, as_tooltip, ai_index)` → `n_pbt_toolbar_item` |  |  | Botao adicionado na posicao escolhida (primeiro = 0) em vez de no fim
`of_move_item (string as_id, integer ai_index)` |  |  | Move uma ferramenta para outra posicao nesta barra (primeiro = 0). Mantem o seu tipo, o seu menu e o seu estado vivo: a ferramenta muda de lugar, nao e reconstruida. Vale para todos os tipos, por isso os `of_add_*` sem `of_insert_*` inserem adicionando e depois movendo
`of_remove_item (string as_id)` |  |  | Remove uma ferramenta desta barra. A barra permanece, e tudo o resto com ela, incluindo o estado ativo — só sai a ferramenta indicada. Para a fazer ir e vir, `ib_visible` no seu handle mantém-na no modelo

### Numa ferramenta — `n_pbt_toolbar_item` #

Membro | Tipo | Predefinição | Função
--- | --- | --- | ---
`ib_visible` | boolean | `true` | Mostra ou oculta um item. Mantém a sua posição na barra: voltar a mostrá-lo coloca-o exatamente onde estava, não no fim. Não confundir com `ib_enabled`, que o deixa no lugar, esbatido — oculte o que não se aplica, esbata o que está momentaneamente indisponível
`ib_enabled` | boolean | `true` | Ferramenta ativa ou desativada
`ib_checked` | boolean | `false` | Estado de um alternador (sem efeito nos restantes tipos)
`is_text` | string | `""` | Etiqueta, com texto formatado com etiquetas aceite
`is_shortcut` | string | `""` | Atalho de teclado (`"Ctrl+S"`), apresentado no tooltip e ativo
`of_add_menu_item (as_id, as_label, as_image)` |  |  | Entrada do menu de um botão pendente
`of_add_menu_item (as_parent, as_id, as_label, as_image)` |  |  | Entrada em cascata, colocada sob uma entrada existente
`of_add_menu_separator (as_id)` |  |  | Traço de separação no menu

As imagens aceitam todas as formas reconhecidas pela biblioteca: caminho, `mono:`, `tint:`, recurso de DLL.

## Eventos #

Evento | Acionado quando
--- | ---
`ue_clicked (string as_bar, string as_id)` | Um botão é clicado (ou acionado pelo respetivo atalho)
`ue_toggled (string as_bar, string as_id, boolean ab_checked)` | Um alternador muda de estado; `ab_checked` transporta o novo estado
`ue_menu_selected (string as_bar, string as_dropdown, string as_id)` | Uma entrada de menu pendente é escolhida
`ue_text_changed (string as_bar, string as_id, string as_text)` | Um campo de introdução é validado (Enter ou perda do foco)
`ue_date_changed (string as_bar, string as_id, string as_date)` | Uma data é escolhida (`"aaaa-mm-dd"`)
`ue_bar_reordered (string as_id, integer ai_band, integer ai_index)` | O utilizador arrastou uma barra pela sua pega para outra banda ou outro rango (requer `ib_reorderable`). Diz qual barra se moveu e onde aterrou, enquanto `ue_layout_changed` transporta toda a disposição. Banda e rango começam em 1
`ue_layout_changed (string as_layout_json)` | A disposição mudou — o utilizador arrastou uma barra pela pega, ou o seu próprio código moveu ou ocultou uma. Transporta a disposição inteira, não apenas o que se moveu
`ue_auto_height (long al_height)` | A altura ideal mudou e a barra ajustou-se a ela — sempre ativo: o número de filas dita a altura
`ue_ready ( )` | O componente terminou o carregamento; tudo o que foi enviado antes foi reproduzido
`ue_runtime_missing ( )` | O runtime WebView2 está ausente: o componente permanece vazio
`ue_bg_color (long al_color)` | O componente calculou a cor de fundo do respetivo tema; o userobject já a adotou (`backcolor`)

## Exemplos #

### Alternadores previamente ativados e ferramenta desativada #

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

    lnv_bar.of_add_toggle(/*id*/ "bold",   /*texto*/ "", /*imagem*/ "mono:img\bold.svg",   /*tooltip*/ "Negrito")
    lnv_bar.of_add_toggle(/*id*/ "italic", /*texto*/ "", /*imagem*/ "mono:img\italic.svg", /*tooltip*/ "Italico")
    lnv_bar.of_add_separator()
    lnv_bar.of_add_button(/*id*/ "undo",   /*texto*/ "", /*imagem*/ "mono:img\undo.svg",   /*tooltip*/ "Anular")

    // Cada ferramenta e controlada pelo seu handle, obtido a partir da SUA barra
    lnv_bar.of_item("bold").ib_checked = true    // alternador previamente ativado
    lnv_bar.of_item("undo").ib_enabled = false   // nada a anular por agora

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

### Menu pendente em cascata #

    n_pbt_toolbar_bar  lnv_bar
    n_pbt_toolbar_item lnv_menu

    lnv_bar = uo_toolbar.of_bar(uo_toolbar.MAIN_BAR)

    // O menu preenche-se pelo handle devolvido por of_add_dropdown
    lnv_menu = lnv_bar.of_add_dropdown(/*id*/ "export", /*texto*/ "Exportar", &
                                       /*imagem*/ "mono:img\save.svg", /*tooltip*/ "Exportar o processo")
    lnv_menu.of_add_menu_item(/*id*/ "exp_pdf", /*etiqueta*/ "PDF",  /*imagem*/ "")
    lnv_menu.of_add_menu_item(/*id*/ "exp_csv", /*etiqueta*/ "CSV",  /*imagem*/ "")
    lnv_menu.of_add_menu_separator(/*id*/ "sep1")

    // Submenu : indica-se a entrada pai no primeiro argumento
    lnv_menu.of_add_menu_item(/*id*/ "exp_img", /*etiqueta*/ "Imagem...", /*imagem*/ "")
    lnv_menu.of_add_menu_item(/*pai*/ "exp_img", /*id*/ "exp_png", /*etiqueta*/ "PNG", /*imagem*/ "")
    lnv_menu.of_add_menu_item(/*pai*/ "exp_img", /*id*/ "exp_jpg", /*etiqueta*/ "JPEG", /*imagem*/ "")

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

### Campo de pesquisa e seletor de data #

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

    lnv_bar.of_add_button(/*id*/ "save", /*texto*/ "", /*imagem*/ "mono:img\save.svg", /*tooltip*/ "Guardar")
    lnv_bar.of_item("save").is_shortcut = "Ctrl+S"    // atalho ativo e apresentado
    lnv_bar.of_add_separator()

    // 160 px de largura ; o texto introduzido sobe na validacao
    lnv_bar.of_add_textbox(/*id*/ "search", /*texto*/ "", /*largura*/ 160, /*tooltip*/ "Procurar (Enter para validar)")

    lnv_bar.of_add_label(/*id*/ "lbl_due", /*texto*/ "Prazo :")
    lnv_bar.of_add_datepicker(/*id*/ "due", /*data*/ "2026-07-11", /*tooltip*/ "Data limite")

    // 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 no formato "aaaa-mm-dd"
    if as_id = "due" then id_echeance = Date(as_date)

### Duas barras e disposição memorizada #

O utilizador pode agarrar numa barra pela respetiva pega (à esquerda da barra) e deslocá-la para outra banda ou para outra posição. A disposição deve ser conservada ao fechar e reposta ao 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",  /*texto*/ "Novo",  /*imagem*/ "", /*tooltip*/ "")
    lnv_std.of_add_button(/*id*/ "open", /*texto*/ "Abrir", /*imagem*/ "", /*tooltip*/ "")

    // Segunda barra, colocada na banda 1 (segunda fila), na primeira posicao
    lnv_fmt = uo_toolbar.of_add_bar(/*barra*/ "format", /*banda*/ 1, /*indice*/ 0)
    lnv_fmt.of_add_toggle(/*id*/ "bold", /*texto*/ "N", /*imagem*/ "", /*tooltip*/ "Negrito")

    // Tambem e possivel recolocar uma barra a qualquer momento pelas suas propriedades
    uo_toolbar.of_bar("format").ii_band  = 0
    uo_toolbar.of_bar("format").ii_index = 1    // segunda barra da primeira fila

    // event ue_layout_changed de uo_toolbar : conservar a disposicao escolhida
    is_disposition = as_layout_json

    // Na abertura seguinte : repor o que o utilizador tinha organizado
    if is_disposition <> "" then uo_toolbar.of_set_layout(is_disposition)

### Excedente: «Mais ferramentas» #

Quando a largura deixa de ser suficiente, as ferramentas que não cabem são recolhidas num menu Mais ferramentas assinalado por um galão no fim da barra. É automático, não há nada a programar: as ferramentas recolhidas continuam clicáveis e acionam os mesmos eventos. Um campo recolhido — caixa de texto ou seletor de data — continua a ser um campo real: escreve-se nele, escolhe-se nele uma data, e o evento é acionado como se a ferramenta tivesse ficado na barra.

### Altura automática #

Não há nada para ativar: o número de filas (`of_set_layout`) dita a altura, a barra ajusta-se sozinha e avisa-o.

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

Ver Base comum.

## Boas práticas #

- Usar `MAIN_BAR` enquanto uma única barra for suficiente: já existe, não é necessário acrescentá-la.
- Aceder sempre a uma ferramenta pelo seu caminho — `of_bar(...).of_item(...)` — e não apenas pelo identificador: é isso que torna os identificadores reutilizáveis de uma barra para outra.
- Agrupar as ferramentas afins com `of_add_separator()` em vez de recorrer a barras suplementares.
- Nos botões apenas com ícone, preencher sempre o tooltip: é a única etiqueta de que o utilizador dispõe.
- Se for permitido ao utilizador reorganizar as barras, memorizar `ue_layout_changed` e voltar a aplicar `of_set_layout` na abertura, caso contrário o esforço perde-se em cada arranque.
- Chamar `of_reset()` antes de reconstruir integralmente a barra de ferramentas para outro contexto.
- Quando os comandos se tornam demasiado numerosos para uma barra, passar para o ribbon, organizado por separadores e grupos.

← Referência dos componentes · Índice do guia