# statusbar — `u_pbt_statusbar` #

← Referência dos componentes · Índice do guia

> Barra de estado com painéis: texto rico, ícones, larguras fixas ou automáticas, alinhamento à esquerda ou à direita, painéis clicáveis, mini-barra de progresso e estados coloridos.

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

## Em resumo #

Userobject | `u_pbt_statusbar`
Classe de items | `n_pbt_statusbar_panel` (painel)
Serve para | Apresentar no fundo da janela o estado da aplicação: contexto, progresso, alertas discretos
Opções opt-in | —

## Início rápido #

    // event open da janela
    // of_add_panel(id, texto, icone, alinhamento, largura)
    // id vazio = painel meramente informativo ; largura 0 = ajustada ao texto
    uo_statut.of_add_panel(/*id*/ "etat",  /*text*/ "Pronto",         /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START,  /*width*/ 0)
    uo_statut.of_add_panel(/*id*/ "",      /*text*/ "Linha 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)

    // Atualizar um painel a qualquer momento, pelo seu identificador
    uo_statut.of_item("etat").is_text = "A guardar..."

## O modelo: painéis com chave #

A barra é uma sequência de painéis, adicionados por ordem. Um painel recebe um identificador na criação: é através dele que se volta a encontrá-lo mais tarde, para mudar o seu texto, o seu ícone ou o seu estado.

O identificador é uma chave de endereçamento, não um interruptor de interatividade:

- Identificador indicado: o painel pode ser reencontrado — muda-se o seu conteúdo, dá-se-lhe uma dica. Mantém-se inerte: uma barra de estado mostra acima de tudo, e um painel como `Linha 12, Col 4` não deve parecer premível.
- Identificador vazio: o painel é puramente decorativo. Não pode ser reencontrado nem clicado, e nenhuma dica lhe pode ser associada. Dê um identificador a todos os seus painéis: não custa nada e mantém a porta aberta.
- Para tornar um painel clicável, peça-o: `of_item("id").ib_clickable = true`. Um painel com uma lista pendente (`of_set_panel_menu`) já o é.

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

Ver Base comum · Os items.

## Propriedades #

Propriedade | Tipo | Predefinição | Função
--- | --- | --- | ---
`ib_show_resize_grip` | boolean | `false` | Apresenta a pega de redimensionamento no canto final da barra
`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

## Métodos #

Método | Função
--- | ---
`of_add_panel (string as_id, string as_text, string as_icon_file, string as_align, integer ai_width)` | Acrescenta um painel no fim da barra
`of_add_sep ( )` | Acrescenta um traço vertical de separação entre dois grupos de painéis
`of_insert_panel (as_id, as_text, as_icon_file, as_align, ai_width, ai_index)` | Insere um painel numa posição precisa (contada a partir de 0)
`of_move_panel (string as_id, integer ai_index)` | Desloca um painel existente para outra posição
`of_remove_panel (string as_id)` | Remove um único painel; os restantes conservam o seu estado
`of_item (string as_id)` → `n_pbt_statusbar_panel` | Devolve o handle de um painel (criado no primeiro acesso)
`of_flash_panel (string as_id, string as_text, long al_ms)` | Mostra uma mensagem durante `al_ms` milissegundos e repõe depois o texto anterior (`al_ms` ≤ 0 = 2 segundos)
`of_set_panel_menu (string as_id, string as_item_ids[], string as_labels[])` | Transforma o painel num seletor: o clique abre uma lista pendente e a escolha volta por `ue_panel_menu_clicked`. Um identificador `-` insere um separador; uma etiqueta vazia retoma o identificador
`of_clear_panel_menu (string as_id)` | Retira a lista pendente; o painel recupera o comportamento que `ib_clickable` lhe dá
`of_clear ( )` | Esvazia a barra: todos os painéis e todos os separadores
`of_reset ( )` | Esvazia a barra e repõe as propriedades nos seus valores predefinidos

### Os argumentos de `of_add_panel` #

Argumento | Valores | Efeito
--- | --- | ---
`as_id` | livre, ou `""` | Chave do painel, aquela pela qual se volta a encontrá-lo. Vazio = painel decorativo, nem endereçável nem clicável
`as_text` | texto | Conteúdo do painel. As etiquetas de texto rico são aceites
`as_icon_file` | caminho de imagem, ou `""` | Ícone apresentado antes do texto (formas aceites)
`as_align` | `ALIGN_START` (predefinição) ou `ALIGN_END` | Lado para o qual o painel é empurrado. Valores lógicos: `START` = início da leitura (esquerda na escrita da esquerda para a direita). Os aliases físicos `"left"` / `"right"` continuam a ser aceites
`ai_width` | píxeis, ou `0` | Largura fixa. `0` = o painel ajusta-se ao seu conteúdo

### Sobre um painel — `n_pbt_statusbar_panel` #

Membro | Tipo | Predefinição | Função
--- | --- | --- | ---
`is_text` | string | `""` | Texto do painel, etiquetas de texto rico aceites
`is_image` | string | `""` | Ícone do painel, modificável a qualquer momento
`ib_enabled` | boolean | `true` | Painel esbatido e não clicável
`ib_visible` | boolean | `true` | Painel ocultado, sem ser retirado da barra
`ii_progress` | integer | — | Mini-barra de progresso no painel, de `0` a `100`; um valor negativo fá-la desaparecer
`is_state` | string | `""` | Estado semântico do painel, que o colore: ver as constantes abaixo
`ib_indeterminate` | boolean | `false` | Barra animada sem valor, para um processamento de duração desconhecida. Independente de `ii_progress`, que continua a ser a percentagem exata
`ib_clickable` | boolean | `false` | O painel reage ao clique. Opt-in: um painel mantém-se inerte enquanto não for pedido, conservando a sua chave — é pilotado e traz uma dica. Um painel com lista pendente já é clicável

### Constantes de estado #

Constante | Valor | Utilização
--- | --- | ---
`STATE_NONE` | `""` | Nenhum estado: aspeto normal
`STATE_INFO` | `"info"` | Informação
`STATE_WARNING` | `"warning"` | Aviso
`STATE_ERROR` | `"error"` | Erro
`STATE_SUCCESS` | `"success"` | Sucesso

Tal como para qualquer propriedade com valores predefinidos, deve utilizar-se a constante em vez da cadeia de caracteres:

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

## Eventos #

Evento | Acionado quando
--- | ---
`ue_panel_clicked (string as_id)` | Um painel cujo identificador está preenchido é clicado
`ue_panel_double_clicked (string as_id)` | Um painel clicável recebe um duplo clique — o atalho clássico por trás de `Linha 12, Col 4` que abre um "Ir para a linha"
`ue_panel_rclicked (string as_id, long al_x, long al_y)` | Um painel recebe um clique direito. `al_x` e `al_y` são píxeis de ecrã: passe-os tal como estão para abrir um menu de contexto onde o utilizador apontou
`ue_panel_menu_clicked (string as_id, string as_item_id)` | Foi escolhida uma entrada de uma lista pendente de painel (ver `of_set_panel_menu`)
`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`)

## Com o teclado #

A barra é uma única paragem de tabulação: só entram nela os painéis feitos para serem clicados, e as setas percorrem-nos.

Tecla | Efeito
--- | ---
Setas | Passam ao painel interativo anterior / seguinte, em ciclo; os painéis de apresentação e os desativados são saltados
Home / End | Primeiro / último painel interativo
Enter ou Espaço | Aciona o painel — ou seja, `ue_panel_clicked`, ou a abertura da respetiva lista pendente, se a tiver

Um painel que se limita a apresentar não é um controlo: não é focável nem anunciado como tal. Um painel clicável mas desativado permanece, esse sim, anunciado como indisponível em vez de passar por texto. Uma barra de progresso anuncia o seu valor, e uma indeterminada não anuncia nenhum — essa ausência é o sentido da palavra.

O foco sobrevive à reconstrução da barra: ela é redesenhada a cada mudança de texto e, sem isto, o foco cairia a cada segundo numa barra que apresenta um relógio.

## Exemplos #

### Larguras fixas e larguras automáticas #

    // Largura 0 : o painel ocupa exatamente o espaco do seu texto
    uo_statut.of_add_panel(/*id*/ "", /*text*/ "Painel ajustado ao conteúdo", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)

    // Largura fixa em pixeis : util quando o texto muda com frequencia,
    // para que os paineis vizinhos nao se desloquem a cada atualizacao
    uo_statut.of_add_panel(/*id*/ "pos", /*text*/ "Linha 1, Col 1", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 150)

    // Um painel empurrado para a extremidade oposta
    uo_statut.of_add_panel(/*id*/ "heure", /*text*/ "12:00", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_END, /*width*/ 140)

### Ícones e painéis clicáveis #

    // Um identificador nao vazio torna o painel clicavel
    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()   // traco de separacao entre dois grupos de paineis
    uo_statut.of_add_panel(/*id*/ "conn", /*text*/ "Ligado",   /*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 rico num painel #

Os painéis aceitam as etiquetas de texto rico: estilos, cores e pequenas imagens diretamente no texto.

    uo_statut.of_add_panel(/*id*/ "", /*text*/ "Bem-vindo [b]ao[/b] [accent]PBToolboxAI[/accent]", &
                           /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 0)

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

    // O texto rico vale igualmente para as atualizacoes
    uo_statut.of_item("etat").is_text = "[b]" + String(ll_modifies) + "[/b] registos modificados"

### Acompanhar um processamento demorado #

    n_pbt_statusbar_panel lnv_avance

    uo_statut.of_add_panel(/*id*/ "import", /*text*/ "Importação", /*icon_file*/ "", /*align*/ uo_statut.ALIGN_START, /*width*/ 220)
    lnv_avance = uo_statut.of_item("import")

    // No ciclo de processamento : a mini-barra acompanha o progresso
    lnv_avance.ii_progress = ll_pourcentage
    lnv_avance.is_text     = "Importação " + String(ll_pourcentage) + " %"

    // No fim : ocultar a mini-barra e assinalar o resultado
    lnv_avance.ii_progress = -1                       // valor negativo = barra ocultada
    lnv_avance.is_text     = "Importação concluída"
    lnv_avance.is_state    = lnv_avance.STATE_SUCCESS

### Assinalar um alerta discreto #

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

    if not ib_connecte then
        lnv_panneau.is_text  = "Sem ligação"
        lnv_panneau.is_state = lnv_panneau.STATE_ERROR
    else
        lnv_panneau.is_text  = "Ligado"
        lnv_panneau.is_state = lnv_panneau.STATE_NONE   // regresso ao aspeto normal
    end if

### Adaptar a barra ao contexto #

    // Ocultar um painel sem o suprimir : voltara a ocupar o seu lugar mais tarde
    uo_statut.of_item("user").ib_visible = ib_utilisateur_identifie

    // Esbate-lo quando a acao correspondente nao faz sentido
    uo_statut.of_item("save").ib_enabled = ib_document_ouvert

    // Reorganizar : colocar o painel de estado a cabeca (posicoes contadas a partir de 0)
    uo_statut.of_move_panel(/*id*/ "etat", /*index*/ 0)

    // Retirar um painel que se tornou inutil
    uo_statut.of_remove_panel(/*id*/ "import")

### A pega de redimensionamento #

    // Numa janela redimensionavel, a pega de canto e uma referencia familiar
    uo_statut.ib_show_resize_grip = true

## Boas práticas #

- Atribua uma largura fixa aos painéis cujo texto muda com frequência (posição do cursor, contadores): os painéis vizinhos deixarão de saltar a cada atualização.
- Deixe o identificador vazio para um painel meramente informativo: assim evita-se um clique sem efeito.
- Reserve o lado direito para as informações estáveis (hora, utilizador, ligação) e o lado esquerdo para o contexto atual.
- Utilize `is_state` em vez de cores no texto: o estado acompanha tanto o tema claro como o escuro.
- Não se esqueça de repor `is_state` em `STATE_NONE` e `ii_progress` num valor negativo assim que o alerta ou o processamento terminar.
- Uma barra de estado não é um registo de eventos: para além de cinco ou seis painéis, é preferível uma notificação toaster.
- Se o progresso merece mais do que uma mini-barra de painel, deve passar-se à progressbar.

← Referência dos componentes · Índice do guia