# ribbon — `u_pbt_ribbon` #

← Referência dos componentes · Índice do guia

> Faixa de opções ao estilo Office: separadores, grupos, doze tipos de controlos ricos, menu da aplicação, barra de acesso rápido, separadores contextuais com faixa e keytips.

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

## Em resumo #

Userobject | `u_pbt_ribbon`
Classes de items | `n_pbt_ribbon_tab` (separador), `n_pbt_ribbon_group` (grupo), `n_pbt_ribbon_item` (controlo), `n_pbt_ribbon_menu_item` (entrada de menu), `n_pbt_ribbon_ctx_group` (grupo de separadores contextuais)
Serve para | Substituir uma barra de menus e as respetivas barras de ferramentas por uma interface de comando moderna, legível e hierarquizada
Altura | Intrínseca: a faixa de opções ajusta-se sempre ao seu conteúdo, nada há para ativar — ver Altura automática
Limite no modo de demonstração | 2 separadores no máximo — ver o modo de demonstração

### A regra de ouro: tudo passa pelo caminho #

A faixa de opções é uma hierarquia de quatro níveis: separador → grupo → controlo → entrada de menu. Não há qualquer identificador global a gerir: cada objeto é alcançado pelo caminho que a ele conduz e cada adição é feita sobre o handle do elemento pai.

    // Ler ou comandar um controlo: o caminho completo, sempre
    uo_ruban.of_tab("accueil").of_group("presse_papier").of_item("coller").ib_enabled = false

Daqui resultam duas consequências práticas e confortáveis: dois grupos diferentes podem utilizar o mesmo identificador de controlo sem colidirem, e os eventos entregam o caminho completo — sabe-se sempre de onde vem o clique.

## Início rápido #

    // event open da window
    n_pbt_ribbon_tab   lnv_onglet
    n_pbt_ribbon_group lnv_groupe

    lnv_onglet = uo_ruban.of_add_tab("accueil", "Início")

    lnv_groupe = lnv_onglet.of_add_group("presse_papier", "Área de transferência")
    lnv_groupe.of_add_big_button("coller", "Colar", "mono:img\paste.svg")
    lnv_groupe.of_add_button("couper", "Cortar", "mono:img\cut.svg")
    lnv_groupe.of_add_button("copier", "Copiar", "mono:img\copy.svg")

    uo_ruban.of_select_tab("accueil")

    // event ue_clicked de uo_ruban: (string as_tab, string as_group, string as_id)
    choose case as_id
        case "coller" ; of_coller()
        case "couper" ; of_couper()
        case "copier" ; of_copier()
    end choose

## Propriedades #

Propriedade | Tipo | Predefinição | Função
--- | --- | --- | ---
`is_app_button` | string | `""` | Rótulo do botão da aplicação, no canto superior esquerdo, que abre o menu da aplicação. Vazio = rótulo `File`
`ib_minimized` | boolean | `false` | `true` recolhe a faixa de opções, deixando apenas os cabeçalhos dos separadores; um clique num separador expande-a temporariamente (aciona `ue_minimized`)
`ib_veto_gallery` | boolean | `true` | Perguntar antes de um mosaico de galeria ser retido (aciona `ue_gallery_selection_changing`, que pode recusar). Ativo por predefinição: não programar nada deixa sempre passar. Coloque-o a `false` para eliminar a ida e volta ao PowerBuilder (~35 ms) onde se notaria
`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

Constante — `ACCENT_LIGHT` (`-1`): deve ser passada como cor de um separador ou de um grupo contextual para que este siga o acento do tema, mais claro, em vez de uma cor fixa.

### Propriedades de um separador — `n_pbt_ribbon_tab` #

Obtidas através de `of_tab(id)`, podem ser alteradas em tempo real.

Propriedade | Tipo | Predefinição | Função
--- | --- | --- | ---
`ib_visible` | boolean | `true` | `false` oculta o separador sem o eliminar — o próprio mecanismo dos separadores contextuais
`is_keytip` | string | `""` | Letra de acesso rápido apresentada após premir Alt (`"A"` para Início)

### Propriedades de um grupo — `n_pbt_ribbon_group` #

Obtidas através de `of_tab(id).of_group(id)`.

Propriedade | Tipo | Predefinição | Função
--- | --- | --- | ---
`ib_visible` | boolean | `true` | `false` oculta o grupo e todos os seus controlos
`ib_launcher` | boolean | `false` | Apresenta a pequena seta no canto inferior direito do grupo — o iniciador de caixa de diálogo (aciona `ue_launcher`). A seta vive na barra de título do grupo, e um grupo que a faixa teve de recolher por falta de espaço mantém-na no mesmo lugar — viaja ainda para o painel que o grupo recolhido abre.

Constantes de modo do seletor de cor: `COLORMODE_PALETTE` (paleta de pastilhas, modo predefinido) e `COLORMODE_OPEN` (paleta completa com validação).

### Propriedades de um controlo — `n_pbt_ribbon_item` #

Obtidas através de `of_tab(id).of_group(id).of_item(id)`. Aplicam-se a todos os tipos de controlos; as propriedades sem pertinência para um dado tipo são simplesmente ignoradas.

Propriedade | Tipo | Predefinição | Função
--- | --- | --- | ---
`is_label` | string | `""` | Rótulo do controlo. Aceita a formatação com etiquetas
`ib_enabled` | boolean | `true` | `false` desativa o controlo a cinzento e bloqueia a sua ativação
`ib_checked` | boolean | `false` | Estado premido de um alternador ou assinalado de uma caixa de verificação
`ib_visible` | boolean | `true` | `false` oculta o controlo; os vizinhos aproximam-se
`is_text` | string | `""` | Texto introduzido ou selecionado numa caixa de lista modificável
`id_value` | double | `0` | Valor numérico de um contador
`il_color` | long | `-1` | Cor atual de um seletor de cor
`ii_visible_items` | integer | `3` | Apenas galeria: número de mosaicos que a faixa recolhida mostra de uma só vez. Os restantes continuam acessíveis através das setas, ou na grelha expandida
`is_keytip` | string | `""` | Letra de acesso rápido do controlo, apresentada após premir Alt
`is_tooltip` | string | `""` | Tooltip simples apresentado ao passar sobre o item
`is_super_tooltip_title` | string | `""` | Título do tooltip enriquecido do item (prevalece sobre `is_tooltip`)
`is_super_tooltip_text` | string | `""` | Texto do tooltip enriquecido do item (aceita marcação enriquecida)
`is_super_tooltip_image` | string | `""` | Imagem do tooltip enriquecido do item

### Propriedades de uma entrada de menu — `n_pbt_ribbon_menu_item` #

Obtidas através de `of_tab(id).of_group(id).of_item(id).of_menu_item(id)`.

Propriedade | Tipo | Predefinição | Função
--- | --- | --- | ---
`ib_enabled` | boolean | `true` | `false` apresenta a entrada a cinzento
`ib_checked` | boolean | `false` | Marca de uma entrada criada por `of_add_menu_check`

## Os doze tipos de controlos #

Todos são adicionados sobre o handle de um grupo e devolvem o handle do controlo criado — é assim possível encadear de seguida o preenchimento de um menu ou de uma lista.

Método do grupo | Controlo obtido | Evento
--- | --- | ---
`of_add_big_button (id, label, image)` | Botão grande de altura total, ícone por cima do rótulo | `ue_clicked`
`of_add_big_split (id, label, image)` | Botão grande dividido: a parte superior atua, a seta abre o menu | `ue_clicked` · `ue_menu_selected`
`of_add_big_dropdown (id, label, image)` | Botão grande com menu pendente | `ue_menu_selected`
`of_add_button (id, label, image)` | Botão pequeno (empilhado em colunas de três) | `ue_clicked`
`of_add_toggle (id, label, image)` | Pequeno alternador que permanece premido | `ue_toggled`
`of_add_dropdown (id, label, image)` | Botão pequeno com menu pendente | `ue_menu_selected`
`of_add_checkbox (id, label)` | Caixa de verificação | `ue_toggled`
`of_add_separator ( )` | Separador vertical entre dois blocos de controlos | —
`of_add_combo (id, largeur_px, modifiable)` | Caixa de lista, editável ou não | `ue_combo_changed`
`of_add_spinner (id, largeur_px, mini, maxi, pas, valeur)` | Contador numérico com setas | `ue_value_changed`
`of_add_colorpicker (id, label, image, couleur)` | Botão de cor dividido: o clique reaplica, a seta abre a paleta | `ue_clicked` · `ue_color_changed`
`of_add_gallery (id, largura_px, largura_mosaico, altura_mosaico)` | Faixa deslizante de mosaicos ilustrados | `ue_gallery_selection_changed`

`of_add_colorpicker` aceita um quinto argumento `as_mode`: `COLORMODE_PALETTE` (paleta de pastilhas) ou `COLORMODE_OPEN` (paleta completa com botões Validar e Cancelar).

## Métodos #

### Construir a faixa de opções #

Método | Função
--- | ---
`of_add_tab (string as_id, string as_title)` | Adiciona um separador e devolve o respetivo handle: encadeie os grupos sobre ele
`of_insert_tab (string as_id, string as_title, integer ai_index)` | Adiciona um separador na posição que você escolhe (`0` = à cabeça) em vez de no fim, e devolve o respetivo handle como `of_add_tab`. Um id já ocupado é recusado
`of_tab (string as_id)` | Handle de um separador existente (criado no primeiro acesso)
`of_add_group (string as_id, string as_title)` | Sobre um handle de separador: adiciona um grupo intitulado e devolve o respetivo handle
`of_group (string as_id)` | Sobre um handle de separador: handle de um grupo existente
`of_item (string as_id)` | Sobre um handle de grupo: handle de um controlo existente
`of_select_tab (string as_id)` | Ativa um separador — estritamente equivalente a um clique do utilizador (aciona `ue_selection_changed`)
`of_selected_key ( )` | Identificador do separador ativo, `""` se não existir nenhum. Mantido atualizado por `ue_selection_changed`, portanto correto desde o arranque
`of_remove_group (string as_id)` | Sobre um handle de separador: remove um grupo e todos os seus controlos
`of_remove_item (string as_id)` | Sobre um handle de grupo: remove um controlo
`of_remove_tab (string as_id)` | Remove um separador e todo o seu conteúdo
`of_clear ( )` | Esvazia por completo a faixa de opções: separadores, grupos, controlos, barra de acesso rápido, menu da aplicação

### Preencher os menus e as listas #

Todos estes métodos são invocados sobre o handle de um controlo.

Método | Função
--- | ---
`of_add_menu_item (string as_id, string as_label, string as_image)` | Entrada de raiz do menu de um botão pendente ou dividido
`of_add_menu_item (string as_parent, string as_id, string as_label, string as_image)` | Entrada em cascata: `as_parent` designa uma entrada existente desse menu
`of_add_menu_check (string as_id, string as_label)` · `(id, label, image)` | Entrada assinalável: o clique alterna o seu estado e comunica-o em `ue_menu_selected`
`of_add_menu_header (string as_label)` | Linha de título não clicável, para dividir um menu extenso
`of_add_menu_separator ( )` | Linha de separação no menu
`of_menu_item (string as_id)` | Handle de uma entrada de menu, para a desativar ou assinalar em tempo real
`of_add_combo_item (string as_label)` | Adiciona uma opção à lista de uma caixa de lista
`of_add_gallery_item (string as_id, string as_image, string as_label)` | Adiciona um mosaico a uma galeria
`of_select_item (string as_id)` | Seleciona um mosaico de galeria por programação (sem levantar qualquer evento)
`of_open ( )` | Abre por programação o menu, a lista ou a paleta do controlo

### Menu da aplicação e barra de acesso rápido #

Método | Função
--- | ---
`of_add_app_menu_item (string as_id, string as_label, string as_image)` | Entrada de raiz do menu da aplicação (aquele que o botão `is_app_button` abre)
`of_add_app_menu_item (string as_parent, string as_id, string as_label, string as_image)` | Entrada em cascata do menu da aplicação
`of_add_app_menu_separator (string as_id)` | Linha de separação no menu da aplicação
`of_add_qat (string as_id, string as_image, string as_tooltip)` | Botão da barra de acesso rápido, por cima dos separadores, e devolve o respetivo handle
`of_qat_item (string as_id)` | Handle de um botão de acesso rápido, para o desativar ou ocultar em tempo real

### Separadores contextuais #

Método | Função
--- | ---
`of_add_contextual_tab (string as_id, string as_title, long al_color)` | Separador contextual isolado: criado oculto, assinalado por um filete colorido. Passe `ACCENT_LIGHT` para seguir o acento do tema
`of_add_contextual_group (string as_id, string as_title)` · `(id, title, al_color)` | Grupo de separadores contextuais: uma faixa intitulada e colorida encima os seus separadores. Devolve o respetivo handle
`of_ctx_group (string as_id)` | Recupera o handle de um grupo contextual já criado — útil quando não se conservou o que foi devolvido na criação
`of_add_tab (string as_id, string as_title)` | Sobre um handle de grupo contextual: adiciona um separador encimado pela faixa, criado oculto
`of_tab (string as_id)` | Sobre um handle de grupo contextual: handle de um dos seus separadores
`il_color` (propriedade) | Sobre um handle de grupo contextual: recolore a faixa em tempo real (`ACCENT_LIGHT` para regressar ao acento)

### Comuns #

Método | Função
--- | ---
`of_reset ( )` | Esvazia a faixa de opções e repõe o seu estado inicial, propriedades incluídas
`of_set_redraw (boolean)` | Agrupa uma sucessão de alterações numa única representação
`of_preload_icons (string as_icons[])` | Pré-aquece um lote de ícones no arranque: um separador aberto mais tarde apresenta os seus instantaneamente
`of_save_as_png (string)` · `of_save_as_jpg (string)` | Exporta a representação como imagem

## Eventos #

Todos os eventos de controlo transportam o caminho completo: nunca é necessário um identificador único em toda a aplicação.

Evento | Acionado quando
--- | ---
`ue_clicked (string as_tab, string as_group, string as_id)` | É clicado um botão, um botão grande, a parte principal de um botão dividido ou de um seletor de cor
`ue_toggled (string as_tab, string as_group, string as_id, boolean ab_checked)` | Um alternador ou uma caixa de verificação muda de estado; `ab_checked` transporta o novo estado
`ue_menu_selected (string as_tab, string as_group, string as_dropdown, string as_id, boolean ab_checked)` | É escolhida uma entrada de menu pendente. `as_dropdown` = o controlo portador, `as_id` = a entrada, `ab_checked` = o estado de uma entrada assinalável
`ue_combo_changed (string as_tab, string as_group, string as_id, string as_text)` | Uma caixa de lista muda de valor, por seleção ou por introdução de dados
`ue_value_changed (string as_tab, string as_group, string as_id, double ad_value)` | Um contador numérico muda de valor
`ue_color_changed (string as_tab, string as_group, string as_id, long al_color)` | É escolhida uma cor num seletor de cor
`ue_gallery_selection_changed (string as_tab, string as_group, string as_id, string as_from_item, string as_item)` | Um mosaico de galeria foi retido. Mesmos argumentos que `ue_gallery_selection_changing`: a pergunta e o seu resultado leem-se da mesma forma, e `as_from_item` é o mosaico abandonado
`ue_gallery_selection_changing (string as_tab, string as_group, string as_id, string as_from_item, string as_item)` → boolean | Cancelável, colocado antes de o mosaico ser retido. Lançado por predefinição; `ib_veto_gallery = false` elimina-o. `as_from_item` é o mosaico atual. Devolva `false` para o conservar (um estilo que o documento ainda não pode assumir)
`ue_launcher (string as_tab, string as_group)` | É clicada a seta de iniciador de um grupo — abra a sua window de opções
`ue_selection_changed (string as_id)` | Um separador torna-se ativo, por clique ou através de `of_select_tab`
`ue_app_button ( )` | É clicado o botão da aplicação
`ue_app_menu_selected (string as_id)` | É escolhida uma entrada do menu da aplicação
`ue_minimized (boolean ab_minimized)` | A faixa de opções é recolhida ou expandida pelo utilizador
`ue_size_changed (long al_height, boolean ab_minimized)` | A altura da faixa de opções mudou por si própria: recolhida, expandida, um separador contextual apresentado, uma janela mais estreita que perde uma linha. Ao contrário de `ue_auto_height` — que só fala quando o componente se dimensiona a si mesmo — este dispara quer a altura automática esteja ativa ou não: é informação pura, para recolocar o que está por baixo
`ue_keytips (boolean ab_on, integer ai_level)` | As keytips aparecem (`true`) ou desaparecem (`false`). `ai_level` indica em que ponto está a navegação: `1` = os separadores estão letrados, `2` = os comandos do separador atual estão letrados, `0` = já não existe qualquer keytip
`ue_auto_height (long al_height)` | A faixa de opções anuncia a sua altura ideal e acabou de se ajustar a ela — sempre ativo: a altura de uma faixa de opções é intrínseca
`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 #

### Uma faixa de opções completa, do menu da aplicação aos grupos #

    // event open: toda a construcao e agrupada numa unica representacao
    n_pbt_ribbon_tab   lnv_onglet
    n_pbt_ribbon_group lnv_groupe
    n_pbt_ribbon_item  lnv_item

    uo_ruban.of_set_redraw(false)
    uo_ruban.is_app_button = "Ficheiro"

    // Menu da aplicacao, com uma cascata sob "Guardar como"
    uo_ruban.of_add_app_menu_item(/*id*/ "nouveau", /*rotulo*/ "Novo", /*imagem*/ "mono:img\new.svg")
    uo_ruban.of_add_app_menu_item("ouvrir", "Abrir...", "mono:img\open.svg")
    uo_ruban.of_add_app_menu_item("enr_sous", "Guardar como", "mono:img\saveas.svg")
    uo_ruban.of_add_app_menu_item(/*pai*/ "enr_sous", /*id*/ "sous_pdf", "Documento PDF", "")
    uo_ruban.of_add_app_menu_item(/*pai*/ "enr_sous", /*id*/ "sous_csv", "Ficheiro CSV", "")
    uo_ruban.of_add_app_menu_separator("sep1")
    uo_ruban.of_add_app_menu_item("quitter", "Sair", "mono:img\exit.svg")

    // Barra de acesso rapido, por cima dos separadores
    uo_ruban.of_add_qat(/*id*/ "qat_enr", /*imagem*/ "mono:img\save.svg", /*tooltip*/ "Guardar")
    uo_ruban.of_add_qat("qat_annuler", "mono:img\undo.svg", "Anular")

    // Separador Inicio
    lnv_onglet = uo_ruban.of_add_tab("accueil", "Início")
    lnv_onglet.is_keytip = "A"

    lnv_groupe = lnv_onglet.of_add_group("presse_papier", "Área de transferência")
    lnv_item = lnv_groupe.of_add_big_split("coller", "Colar", "mono:img\paste.svg")
    lnv_item.of_add_menu_item("coller_texte", "Colar sem formatação", "")
    lnv_item.of_add_menu_item("coller_lien", "Colar como ligação", "")
    lnv_groupe.of_add_button("couper", "Cortar", "mono:img\cut.svg")
    lnv_groupe.of_add_button("copier", "Copiar", "mono:img\copy.svg")
    lnv_groupe.ib_launcher = true       // seta de opcoes no canto inferior direito

    uo_ruban.of_set_redraw(true)
    uo_ruban.of_select_tab("accueil")

### Um encaminhamento de cliques único #

    // event ue_clicked de uo_ruban: (string as_tab, string as_group, string as_id)
    // O caminho completo chega com o evento: basta um unico encaminhamento,
    // e dois grupos podem reutilizar o mesmo identificador sem se estorvarem.
    choose case as_group + "/" + as_id
        case "presse_papier/couper" ; of_couper()
        case "presse_papier/copier" ; of_copier()
        case "presse_papier/coller" ; of_coller()
        case "police/gras"          ; of_basculer_gras()
    end choose

### Comandar o estado dos controlos consoante os direitos #

    // Sempre pelo caminho: separador > grupo > controlo
    uo_ruban.of_tab("accueil").of_group("presse_papier").of_item("coller").ib_enabled = of_presse_papier_non_vide()
    uo_ruban.of_tab("accueil").of_group("outils").of_item("pinceau").ib_checked = true
    uo_ruban.of_tab("admin").ib_visible = gb_administrateur

    // Desativar a cinzento uma entrada DENTRO de um menu pendente (nivel 4)
    uo_ruban.of_tab("accueil").of_group("presse_papier").of_item("coller") &
            .of_menu_item("coller_lien").ib_enabled = false

### Separadores contextuais com faixa #

O princípio do Office: separadores que só aparecem quando a seleção o justifica, encimados por uma faixa intitulada e colorida.

    // event open: prepara-se o grupo contextual, oculto por predefinicao
    n_pbt_ribbon_ctx_group lnv_ctx
    n_pbt_ribbon_tab       lnv_onglet
    n_pbt_ribbon_group     lnv_groupe

    // Sem cor, a faixa segue o acento do tema; RGB(...) para a impor
    lnv_ctx = uo_ruban.of_add_contextual_group(/*id*/ "img", /*titulo*/ "Ferramentas de Imagem", &
                                               /*cor*/ RGB(224, 32, 96))
    lnv_onglet = lnv_ctx.of_add_tab("format", "Formatar")
    lnv_groupe = lnv_onglet.of_add_group("ajuster", "Ajustar")
    lnv_groupe.of_add_big_button("rogner", "Recortar", "mono:img\crop.svg")
    lnv_groupe.of_add_button("pivoter", "Rodar", "mono:img\rotate.svg")

    // Ao selecionar uma imagem: revela-se o separador e ativa-se
    uo_ruban.of_tab("format").ib_visible = true
    uo_ruban.of_select_tab("format")

    // Ao desselecionar: oculta-se, a faixa desaparece com ele
    uo_ruban.of_tab("format").ib_visible = false

### Caixa de lista, contador, seletor de cor e galeria #

    n_pbt_ribbon_group lnv_groupe
    n_pbt_ribbon_item  lnv_item

    lnv_groupe = uo_ruban.of_tab("accueil").of_add_group("police", "Tipo de letra")

    // Caixa de lista editavel: preenche-se pelo seu handle
    lnv_item = lnv_groupe.of_add_combo(/*id*/ "nom_police", /*largura_px*/ 140, /*modificavel*/ true)
    lnv_item.of_add_combo_item("Segoe UI")
    lnv_item.of_add_combo_item("Arial")
    lnv_item.of_add_combo_item("Calibri")
    lnv_item.is_text = "Segoe UI"

    // Contador numerico: minimo, maximo, incremento, valor inicial
    lnv_groupe.of_add_spinner(/*id*/ "taille", /*largura_px*/ 70, /*minimo*/ 6, /*maximo*/ 96, &
                              /*incremento*/ 1, /*valor*/ 11)

    // Seletor de cor no modo de paleta completa (com Validar / Cancelar)
    lnv_groupe.of_add_colorpicker(/*id*/ "couleur", /*rotulo*/ "Cor", &
                                  /*imagem*/ "mono:img\font-color.svg", &
                                  /*cor*/ RGB(0, 0, 0), &
                                  /*modo*/ lnv_groupe.COLORMODE_OPEN)

    // Galeria de estilos: mosaicos ilustrados deslizantes
    lnv_item = lnv_groupe.of_add_gallery(/*id*/ "styles", /*largura_px*/ 220, &
                                         /*largura_mosaico*/ 64, /*altura_mosaico*/ 48)
    lnv_item.of_add_gallery_item("st_normal", "img\style-normal.png", "Normal")
    lnv_item.of_add_gallery_item("st_titre",  "img\style-titre.png",  "Título")
    lnv_item.of_add_gallery_item("st_note",   "img\style-note.png",   "Nota")
    lnv_item.of_add_gallery_item("st_code",   "img\style-code.png",   "Código")

    // A faixa recolhida mostra 4 miniaturas de cada vez; as restantes continuam
    // acessiveis atraves das setas, ou na grelha expandida.
    lnv_item.ii_visible_items = 4

    lnv_item.of_select_item("st_normal")

    // event ue_value_changed de uo_ruban: (string as_tab, string as_group, string as_id, double ad_value)
    if as_id = "taille" then of_appliquer_taille(ad_value)

    // event ue_color_changed de uo_ruban: (string as_tab, string as_group, string as_id, long al_color)
    if as_id = "couleur" then of_appliquer_couleur(al_color)

### Recusar a escolha de uma miniatura de galeria #

    // A pergunta e colocada por PREDEFINICAO: nada a ativar. Esta linha faz o
    // contrario, elimina-a quando arbitrar nao serve.
    uo_ruban.ib_veto_gallery = false

    // event ue_gallery_selection_changing de uo_ruban:
    //   (string as_tab, string as_group, string as_id, string as_from_item, string as_item)
    // Devolver FALSE conserva a miniatura atual (as_from_item).
    if as_item = "st_code" and not of_document_supporte_code() then
        MessageBox("Estilo", "Este documento não pode assumir o estilo Código.")
        return false
    end if
    return true

### O iniciador de caixa de diálogo #

    // A pequena seta no canto inferior direito do grupo
    uo_ruban.of_tab("accueil").of_group("police").ib_launcher = true

    // event ue_launcher de uo_ruban: (string as_tab, string as_group)
    // O caminho identifica o grupo: abre-se a window de opcoes correspondente.
    choose case as_group
        case "police"        ; open(w_options_police)
        case "presse_papier" ; open(w_options_collage)
    end choose

### Keytips: conduzir a faixa de opções pelo teclado #

    // Alt apresenta as letras; Alt seguido de A e depois C aciona "copier"
    uo_ruban.of_tab("accueil").is_keytip = "A"
    uo_ruban.of_tab("accueil").of_group("presse_papier").of_item("copier").is_keytip = "C"
    uo_ruban.of_tab("accueil").of_group("presse_papier").of_item("couper").is_keytip = "X"

Premir Alt esteja o foco onde estiver na window entrega o comando à faixa de opções: esta recebe o foco de teclado e mostra as suas letras. Não tem nada a ligar — basta que esteja declarada pelo menos uma keytip. Esc, um segundo Alt ou a escolha de um comando devolvem o foco ao controlo que o utilizador tinha abandonado.

`ue_keytips` avisa-o de cada mudança de estado e indica-lhe o nível atual:

    // event ue_keytips de uo_ruban: (boolean ab_on, integer ai_level)
    // O teclado conduz a faixa de opcoes: apagar a ajuda da barra de estado, que
    // fala do rato, e repo-la quando as letras desaparecerem.
    if ab_on then
        uo_statut.of_item("main").is_text = "Escreva uma letra (nivel " + String(ai_level) + ")"
    else
        uo_statut.of_item("main").is_text = ""
    end if

### Tooltips enriquecidos num controlo #

    n_pbt_ribbon_item lnv_item

    lnv_item = uo_ruban.of_tab("accueil").of_group("presse_papier").of_item("coller")
    lnv_item.is_super_tooltip_title = "Colar (Ctrl+V)"
    lnv_item.is_super_tooltip_text  = "Insere o conteúdo da área de transferência." &
                                    + "[br][br][size-=15]Utilize a seta para colar sem formatação.[/size-=15]"
    lnv_item.is_super_tooltip_image = "img\paste.png"

Estas quatro propriedades são exatamente as mesmas de qualquer outro item da biblioteca. Para um tooltip de uma só linha basta `is_tooltip`.

### Altura automática #

A faixa de opções dimensiona-se sozinha: não há nada para ativar. Avisa-o sempre que a altura muda (recolhimento, separador contextual, mudança de tema) para que possa reposicionar o que está por baixo.

    // event ue_auto_height de uo_ruban: (long al_height)
    // A faixa de opcoes ja se redimensionou: reposiciona-se o que esta por baixo.
    uo_contenu.y      = uo_ruban.y + uo_ruban.height
    uo_contenu.height = this.height - uo_contenu.y

### Recolher a faixa de opções para ganhar espaço #

    uo_ruban.ib_minimized = true

    // event ue_minimized de uo_ruban: (boolean ab_minimized)
    // Memoriza-se a preferencia do utilizador para a proxima abertura.
    of_enregistrer_preference("ruban_replie", ab_minimized)

### Recomeçar com uma faixa de opções vazia #

    // of_reset esvazia separadores, grupos, controlos, barra de acesso rapido e menu
    uo_ruban.of_reset()
    uo_ruban.of_add_tab("accueil", "Início")

## A partir de um menu PowerBuilder existente #

Uma aplicação PowerBuilder já descreveu os seus comandos uma vez: no seu menu. Etiquetas, atalhos, imagens, separadores, submenus, dicas — está tudo lá. `n_pbt_menu2ribbon` relê esse menu por RTTI e escreve o PowerScript que constrói o friso correspondente.

    // Uma so vez, a mao : o gerador ESCREVE codigo, nao corre em producao.
    // Cole o resultado no open da sua janela.
    n_pbt_menu2ribbon lnv_gen
    string ls_code

    lnv_gen = create n_pbt_menu2ribbon
    ls_code = lnv_gen.of_generate(/*menu*/ m_principal, /*variavel*/ "uo_ruban")
    destroy lnv_gen

    ClipBoard(ls_code)

A conversão é determinista: sem IA, sem chamada de rede, nada que saia da máquina. E os identificadores gerados mantêm o caminho do menu (`m_principal.m_fichier.m_ouvrir`), pelo que o `choose case` das suas ações existentes funciona tal como está a partir de `ue_clicked`.

O código produzido é um ponto de partida para rever, não um entregável: um menu é uma lista, um friso é uma disposição. Agrupe, escolha os seus botões grandes, retire o que não merece estar sempre à vista. O exemplo 9 da página do friso na aplicação de demonstração mostra um resultado completo.

## Boas práticas #

- Enquadre toda a construção com `of_set_redraw(false)` / `of_set_redraw(true)`: uma faixa de opções completa é então desenhada de uma só vez, sem cintilação.
- Conserve os handles devolvidos (`n_pbt_ribbon_tab`, `n_pbt_ribbon_group`, `n_pbt_ribbon_item`) em variáveis locais durante a construção: o código mantém-se curto e legível. Para comandar um controlo mais tarde, basta voltar a passar pelo caminho.
- Invoque `of_preload_icons` no arranque: sem isso, a primeira apresentação de um separador nunca aberto revela um breve atraso antes dos seus ícones.
- Um identificador só precisa de ser único dentro do seu grupo. Aproveite para nomear os controlos de forma simples (`copier`, `coller`) em vez de recorrer a prefixos.
- Reserve os separadores contextuais para os comandos que não têm qualquer sentido fora de contexto: um separador permanente desativado a cinzento é mais tranquilizador do que um separador que aparece e desaparece.
- A pergunta é colocada por predefinição: um `ue_gallery_selection_changing` deixado vazio autoriza sempre a escolha, não tem nada a fazer. Desative-a com `ib_veto_gallery = false` se arbitrar não lhe serve, porque cada pergunta custa uma ida e volta ao PowerBuilder.
- Um único iniciador de caixa de diálogo por grupo, e apenas se o grupo tiver realmente opções avançadas a oferecer.
- Para reconstruir uma faixa de opções inteira, prefira `of_clear()` (ou `of_reset()`) a uma série de `of_remove_tab`: sem isso, a reutilização de um identificador de separador falha.
- Para uma barra de comandos mais leve, sem separadores nem grupos, consulte toolbar; para uma navegação lateral, listbar.

← Referência dos componentes · Índice do guia