tab — u_pbt_tab #
← Referência dos componentes · Índice do guia
Separadores modernos que alojam controlos reais do PowerBuilder: faixa reposicionável, ícones por separador, separadores que se podem fechar, reordenação com o rato.
▶ Ver ao vivo — Aplicação de demonstração, mosaico Tab: a pré-visualização, o código que o produz e esta página, lado a lado.
Em resumo #
| Userobject | u_pbt_tab |
| Classe de items | n_pbt_tab_page (uma página = um separador) |
| Serve para | Substituir um tab do PowerBuilder por uma faixa com tema, mantendo os ecrãs existentes como páginas |
| Opções opt-in | ib_reorderable |
O argumento decisivo: uma página não é uma maqueta HTML, é um dragobject do PowerBuilder — um userobject, uma DataWindow, um conjunto de controlos ou até outro componente PBToolboxAI. O componente encarrega-se do posicionamento, do redimensionamento e da apresentação/ocultação na mudança de separador. Ver Alojar controlos reais do PowerBuilder.
Início rápido #
// event open da janela : cada pagina e um controlo PB ja colocado na janela
uo_tabs.of_add_page(/*key*/ "customers", /*title*/ "Clientes", /*page*/ uo_page_customers)
uo_tabs.of_add_page(/*key*/ "invoices", /*title*/ "Faturas", /*page*/ uo_page_invoices, /*closable*/ true)
// Um icone por separador, colocado no handle da pagina
uo_tabs.of_page(/*key*/ "customers").is_icon = "mono:img\customers.svg"
uo_tabs.of_page(/*key*/ "invoices").is_icon = "mono:img\invoice.svg"
// Mostra o primeiro separador
uo_tabs.of_select_page(/*key*/ "customers")
// event ue_selection_changed de uo_tabs : (string as_from_key, string as_key)
of_load_page(as_key)
Propriedades #
| Propriedade | Tipo | Predefinição | Função |
|---|---|---|---|
is_position | string | "top" | Colocação da faixa: top, bottom (banda horizontal), start, end (banda vertical). Constantes POSITION_TOP, POSITION_BOTTOM, POSITION_START, POSITION_END. START/END são lógicas e acompanham o sentido de escrita |
is_overflow_mode | string | "menu" | O que faz uma banda demasiado pequena para os seus separadores. menu (predefinição) mantém cada separador legível: os que já não cabem saem da banda e o botão ··· lista-os todos, ficando o separador ativo sempre visível. compact mantém-nos todos na banda e deixa-os reduzir-se, até ao espaço que um texto truncado exige. Constantes OVERFLOW_MENU, OVERFLOW_COMPACT |
ib_reorderable | boolean | false | Opt-in: o utilizador pode reordenar os separadores arrastando o respetivo cabeçalho com o rato (aciona ue_tab_reordered) |
ib_veto_selection | boolean | false | Perguntar antes de o separador ativo mudar — um gesto do utilizador (clique, teclado, atalho, lista de separadores) e of_select_page: aciona ue_selection_changing, que pode recusar; um of_select_page recusado devolve -4. Desativado por predefinição, como qualquer evento cancelável: coloque-o a true para poder recusar (trabalho não guardado). Cada pergunta de um gesto custa uma ida e volta ao PowerBuilder (~35 ms) |
ib_veto_close | boolean | false | Perguntar antes de o utilizador fechar um separador (cruz, clique do meio, menu de contexto, Delete): aciona ue_tab_closing, que pode recusar. Desativado por predefinição: coloque-o a true para manter uma página com trabalho não guardado |
ib_context_menu | boolean | true | Menu contextual integrado no cabeçalho de um separador: Fechar, Fechar os outros, Fechar à direita, Fechar todos, esbatidos quando não têm alvo. Ativo por predefinição. O clique direito seleciona primeiro o separador: se a aplicação recusar a mudança, não abre nenhum menu. Com ib_veto_close, cada fecho passa por ue_tab_closing, uma pergunta por página: a que detém trabalho não guardado recusa sozinha e permanece aberta enquanto as vizinhas partem. A false, o clique direito num separador seleciona-o e depois lança ue_tab_rclicked: abra aí o seu próprio menu |
is_theme_style | string | "" | Estilo visual do componente (constantes THEME_STYLE_*); vazio = o da aplicação, seguido a cada mudança |
is_theme_mode | string | "" | Variante clara ou escura (constantes THEME_MODE_*); vazio = a da aplicação, seguida a cada mudança |
il_theme_accent | long | -1 | Cor de destaque deste componente (-1 = destaque da aplicação, ou o 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 |
Propriedades de uma página — n_pbt_tab_page #
Obtidas através de of_page(id), podem ser alteradas a quente, sem reconstruir a faixa.
| Propriedade | Tipo | Predefinição | Função |
|---|---|---|---|
is_title | string | "" | Etiqueta do separador. Aceita a formatação com etiquetas |
is_icon | string | "" | Ícone do separador (formas aceites: caminho, mono:, tint:, recurso de DLL). Vazio = nenhum ícone |
ib_enabled | boolean | true | false desativa o separador: nenhum clique, tecla, atalho nem of_select_page o ativa, e não tem cruz de fecho. Desativar o separador ativo deixa-o ativo e a sua página utilizável: desative a própria página se for preciso (o seu código sabe se deve continuar editável) |
ib_visible | boolean | true | false oculta o separador sem eliminar a página; ocultar o separador ativo ativa o seu vizinho (o da direita, senão o da esquerda); ocultar o último separador visível oculta a página e lança ue_selection_changed com uma chave vazia |
ib_closable | boolean | false | Cruz de fecho neste separador. Raramente conhecido no momento em que a página é adicionada: passa a true assim que o documento que contém é guardado, e a false enquanto lá corre um processamento. Um clique do meio num separador que se pode fechar também o fecha, tal como a sua cruz |
is_shortcut | string | "" | Atalho de teclado que ativa este separador: "Ctrl+2", "Alt+F", "F6"… Responde onde quer que o utilizador esteja na janela, incluindo a página alojada — o atalho é detido pela DLL, não pela barra de separadores. Selecionar assim é um clique: ue_selection_changing é perguntado se ib_veto_selection estiver ativo, ue_selection_changed segue; um separador desativado ou oculto ignora-o. "" remove-o |
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 |
Métodos #
| Método | Função | |
|---|---|---|
of_add_page (string as_key, string as_title, dragobject ado_page) | Acrescenta um separador que não se pode fechar, sem ícone, e aloja o controlo. Devolve 0 depois de aplicado, -5 se a chave estiver vazia, contiver uma / ou uma ` | , já estiver ocupada, ou se a página faltar ou já estiver alojada (por este separador com outra chave, ou por outro componente): nada é acrescentado então, -2` se o componente não estiver criado |
of_add_page (string as_key, string as_title, dragobject ado_page, boolean ab_closable) | Idem, com cruz de fecho se ab_closable. Devolve 0 depois de aplicado, -5 se a chave estiver vazia, contiver uma / ou uma ` | , já estiver ocupada, ou se a página faltar ou já estiver alojada (por este separador com outra chave, ou por outro componente): nada é acrescentado então, -2` se o componente não estiver criado |
of_add_page (string as_key, string as_title, dragobject ado_page, boolean ab_closable, string as_icon) | Idem, com o ícone colocado de imediato (o separador surge logo completo). Devolve 0 depois de aplicado, -5 se a chave estiver vazia, contiver uma / ou uma ` | , já estiver ocupada, ou se a página faltar ou já estiver alojada (por este separador com outra chave, ou por outro componente): nada é acrescentado então, -2` se o componente não estiver criado |
of_insert_page (string as_key, string as_title, dragobject ado_page, integer ai_index) | Acrescenta a página e desloca-a depois para a posição ai_index (1 = a primeira). Devolve 0 depois de aplicado, -5 pelas mesmas recusas que of_add_page, -2 se o componente não estiver criado | |
of_insert_page (string as_key, string as_title, dragobject ado_page, boolean ab_closable, string as_icon, integer ai_index) | Idem, dizendo o que of_add_page diz : se o separador fecha, e o seu ícone. Devolve 0 depois de aplicado, -5 pelas mesmas recusas que of_add_page, -2 se o componente não estiver criado | |
of_move_page (string as_key, integer ai_index) | Desloca um separador existente para a posição ai_index (1 = a primeira); a página alojada e a seleção são preservadas. Devolve 0 depois de aplicado, -5 se a chave não designar nenhuma página, -2 se o componente não estiver criado | |
of_select_page (string as_key) | Ativa um separador, como um clique nele: com ib_veto_selection ativo, ue_selection_changing é perguntado primeiro; depois segue ue_selection_changed, como num clique (logo após o seu script, a partir da fila de eventos), e of_selected_key() relido logo a seguir já devolve a nova chave. Separador já ativo: nada é perguntado nem lançado. Devolve 0 depois de aplicado (ou se já ativo), -4 se o seu ue_selection_changing recusou (nada se move), -5 se a chave não designar nenhuma página ou se a página não puder ser mostrada (oculta, desativada, além do limite da demonstração) — incluindo quando depois nenhuma página fica ativa, -2 se o componente não estiver criado | |
of_remove_page (string as_key) | Retira o separador e devolve o controlo à sua janela de origem, oculto. O controlo continua utilizável e pode ser alojado noutro local. Não lança ue_tab_closed: foi o seu código que o fez. Se era a página ativa, a sua vizinha passa a ativa. Devolve 0 depois de aplicado, -5 se a chave não designar nenhuma página, -2 se o componente não estiver criado | |
of_selected_key ( ) | Identificador do separador ativo, "" se não existir nenhum | |
of_get_layout ( ) | Relê a disposição atual em JSON: a ordem dos separadores e a visibilidade de cada um. Guarde-a (ficheiro, base de dados, registo) e devolva-a com of_set_layout no arranque seguinte. O mesmo par tem os mesmos nomes em todos os componentes reorganizáveis | |
of_set_layout (string as_layout_json) | Repõe uma disposição lida com of_get_layout ou recebida com ue_layout_changed. O que a disposição não nomeia mantém o seu lugar no fim: uma disposição de ontem não deve fazer desaparecer o que foi acrescentado desde então. Aplicá-la não gera qualquer event de disposição — foi você que a forneceu; se ocultar o separador ativo, o seu vizinho passa a ativo e ue_selection_changed di-lo. Devolve 0 depois de aplicado, -5 se o texto estiver vazio ou não for JSON válido, -2 se o componente não estiver criado | |
of_page (string as_key) | Handle n_pbt_tab_page da página (criado no primeiro acesso) | |
of_refresh_page (string as_key) | Atualiza a representação de uma página construída fora do ecrã, sem cintilação. Devolve 0, -5 se a chave não designar nenhuma página, -2 se o componente não estiver criado | |
of_relayout ( ) | Volta a publicar a zona de página para que o controlo alojado seja reposicionado (útil após uma apresentação diferida). Devolve 0 depois de aplicado, -2 se o componente não estiver criado | |
of_preload_icons (string as_icons[]) | Pré-aquece um lote de ícones no arranque: um separador aberto mais tarde apresenta o seu ícone de imediato. Devolve 0 depois de aplicado, -2 se o componente não estiver criado | |
of_reset ( ) | Esvazia a faixa: cada página alojada é devolvida à sua janela de origem e o componente regressa ao estado inicial. Devolve 0 depois de aplicado, -2 se o componente não estiver criado | |
of_set_redraw (boolean) | Agrupa uma rajada de alterações numa única representação. Devolve 0 depois de aplicado, -2 se o componente não estiver criado | |
of_save_as_png (string) · of_save_as_jpg (string) | Exporta a representação como imagem. Devolve 0 depois de a imagem ser escrita, -4 se a escrita falhar, -2 se o componente não estiver criado |
of_add_pagedevolve um código negativo se o identificador estiver vazio, já estiver a ser utilizado ou se o controlo indicado não for válido ou já estiver alojado.
Quando há demasiados separadores — reduzem-se para caber na banda, mas nunca abaixo de uma largura legível: o ícone e a cruz de fecho ocupam o seu espaço para além do título, nunca no lugar dele. Os que já não cabem saem da banda, e na sua extremidade aparece um botão ···: abre a lista de todos os separadores visíveis, com o ativo assinalado, e a escolha passa para ele. O separador ativo permanece sempre visível. A banda não desliza — esse botão é o caminho para os separadores fora do enquadramento. Nada a programar, o comportamento é automático.
Teclado e rato — Ctrl+Tab e Ctrl+Page Down passam ao separador seguinte, Ctrl+Shift+Tab e Ctrl+Page Up ao anterior: só contam os separadores que podem ficar ativos (os ocultos e os desativados são saltados), e o percurso recomeça do início. Estas teclas respondem quando o teclado está na banda de separadores ou numa página que ela aloja — um controlo PowerBuilder da página tal como outro componente colocado nela; a partir de um controlo fora do tab, ficam para a janela. É um gesto do utilizador: ue_selection_changing é colocado se ib_veto_selection estiver ativo, e depois segue-se ue_selection_changed. Um clique do meio num separador que se pode fechar fecha-o, exatamente como a sua cruz: a mesma pergunta ue_tab_closing se ib_veto_close estiver ativo, e depois ue_tab_closed; num separador desativado ou que não se pode fechar, não faz nada. Nada a programar.
Eventos #
| Evento | Acionado quando |
|---|---|
ue_selection_changed (string as_from_key, string as_key) | O separador ativo mudou, por um gesto (um clique, o teclado, incluindo Ctrl+Tab, um atalho, a lista de separadores), por of_select_page (uma ordem do seu código também o lança, como SelectTab lança SelectionChanged) ou porque um separador sai (fechado, retirado, oculto). Mesmos argumentos que ue_selection_changing: a pergunta e o seu resultado leem-se da mesma forma, e as_from_key é a página abandonada — mesmo quando já não existe. Um as_key vazio significa que nenhum separador pode ser mostrado: todas as páginas estão ocultas |
ue_tab_closed (string as_key) | O utilizador fechou um separador: a sua cruz, um clique do meio sobre ele, o menu de contexto ou a tecla Delete. O separador já foi retirado e a página devolvida à sua janela. of_remove_page nunca o lança: foi o seu código que o fez |
ue_tab_reordered (string as_key, integer ai_index) | O utilizador terminou de arrastar um cabeçalho. ai_index é a nova posição, a partir de 1, como of_move_page |
ue_layout_changed (string as_layout_json) | A disposição a guardar mudou: o utilizador arrastou um cabeçalho, ou o seu código deslocou um separador (of_move_page, of_insert_page) ou ocultou / voltou a mostrar um (ib_visible). of_set_layout não o lança (essa disposição foi você que a forneceu), nem acrescentar, fechar ou retirar um separador — a ordem dos outros não muda. Transporta a disposição inteira, não apenas o que se moveu: guardá-la é uma única atribuição |
ue_selection_changing (string as_from_key, string as_key) → boolean | Cancelável, colocado antes de o separador ativo mudar — um gesto do utilizador ou of_select_page —, quando ib_veto_selection está a true (desativado por predefinição). Devolva false para ficar na página: nada se move, e of_select_page devolve -4 |
ue_tab_closing (string as_key) → boolean | Cancelável, colocado antes de o utilizador fechar um separador, quando ib_veto_close está a true (desativado por predefinição). Nomeado para fazer par com ue_tab_closed: closing / closed. Devolva false para manter o separador (e a página que aloja) aberto |
ue_tab_rclicked (string as_key) | Clique direito no cabeçalho de um separador quando ib_context_menu está a false: o separador é primeiro selecionado (através de ue_selection_changing se estiver armado — uma seleção recusada não lança nada), e depois este event dá a sua chave. Abra aqui o seu próprio menu: PopMenu(PointerX(), PointerY()) da sua janela. Um separador desativado não lança nada; um único event por clique direito |
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 #
Um dossiê de páginas de negócio #
// event open : os userobjects de pagina ja estao colocados na janela
uo_tabs.of_set_redraw(/*on*/ false)
// Um separador por userobject de pagina
uo_tabs.of_add_page(/*key*/ "identity", /*title*/ "Identidade", /*page*/ uo_identity)
uo_tabs.of_add_page(/*key*/ "addresses", /*title*/ "Moradas", /*page*/ uo_addresses)
uo_tabs.of_add_page(/*key*/ "accounting", /*title*/ "Contabilidade", /*page*/ uo_accounting)
// Um icone por separador, colocado no handle da pagina
uo_tabs.of_page(/*key*/ "identity").is_icon = "mono:img\user.svg"
uo_tabs.of_page(/*key*/ "addresses").is_icon = "mono:img\map.svg"
uo_tabs.of_page(/*key*/ "accounting").is_icon = "mono:img\euro.svg"
// Uma so renderizacao para tudo e depois mostra-se o primeiro separador
uo_tabs.of_set_redraw(/*on*/ true)
uo_tabs.of_select_page(/*key*/ "identity")
Documentos que se podem fechar, abertos a pedido #
// Abrir um documento num novo separador que se pode fechar
uo_tabs.of_add_page(/*key*/ ls_key, /*title*/ ls_label, /*page*/ uo_editor, /*closable*/ true, /*icon*/ "mono:img\doc.svg")
uo_tabs.of_select_page(/*key*/ ls_key)
// event ue_tab_closed de uo_tabs : (string as_key)
// O separador ja foi retirado ; falta libertar os dados de negocio.
of_free_document(as_key)
Reordenação com o rato #
// The user may drag a tab to a new place
uo_tabs.ib_reorderable = true
// event ue_tab_reordered de uo_tabs : (string as_key, integer ai_index)
// ai_index = nova posicao, a partir de 1 (como of_move_page) : memoriza-se a ordem escolhida.
of_save_order(as_key, ai_index)
Faixa vertical #
// Banda de separadores do lado esquerdo, util quando as etiquetas sao longas
uo_tabs.is_position = uo_tabs.POSITION_START
Inativar ou ocultar um separador consoante os direitos #
// O caminho passa sempre pelo handle da pagina
uo_tabs.of_page(/*key*/ "accounting").ib_enabled = of_is_allowed("accounting")
uo_tabs.of_page(/*key*/ "audit").ib_visible = gb_expert_mode
Reagir à seleção #
// event ue_selection_changed de uo_tabs : (string as_from_key, string as_key)
choose case as_key
case "identity" ; uo_identity.of_refresh()
case "addresses" ; uo_addresses.of_refresh()
case "accounting" ; uo_accounting.of_refresh()
end choose
Recusar uma mudança de separador ou um fecho #
// As duas perguntas tem de ser ATIVADAS: sem estas linhas o componente nao
// pergunta nada e muda de pagina ou fecha de imediato.
uo_tabs.ib_veto_selection = true
uo_tabs.ib_veto_close = true
// event ue_selection_changing de uo_tabs : (string as_from_key, string as_key)
// Devolver FALSE mantem o utilizador na pagina que abandona.
if of_page_modified(as_from_key) then
if MessageBox("Modificações", "Sair sem guardar?", Question!, YesNo!) = 2 then
return false
end if
end if
return true
// event ue_tab_closing de uo_tabs : (string as_key)
// Devolver FALSE mantem o separador e a pagina que aloja abertos.
return not of_page_modified(as_key)
Recomeçar com uma faixa vazia #
// of_reset devolve CADA pagina alojada a sua janela de origem antes de esvaziar
uo_tabs.of_reset()
uo_tabs.of_add_page(/*key*/ "home", /*title*/ "Início", /*page*/ uo_home)
Boas práticas #
- Os controlos alojados têm de existir antes da chamada: devem ser colocados na janela em tempo de desenho, cabendo ao componente ocultá-los e reposicioná-los.
- Recomenda-se carregar as páginas uma única vez no
opene comandar em seguida apenas a seleção: é mais rápido do que acrescentar e retirar páginas continuamente. - Deve chamar-se
of_preload_iconsno arranque se os separadores tiverem ícones: sem isso, a primeira abertura de um separador oculto apresenta um breve atraso antes do ícone. - As duas perguntas são colocadas por predefinição: um evento deixado vazio autoriza sempre a ação, não tem nada a fazer. Desative-as com
ib_veto_selection/ib_veto_closeafalsese arbitrar não lhe serve, porque cada pergunta custa uma ida e volta ao PowerBuilder. - Um controlo alojado é uma janela nativa: desenha-se por cima da camada web. Nenhum efeito visual do componente pode passar à frente dele.
- Não esquecer
of_reset()antes de reconstruir uma faixa: sem essa chamada, a reutilização de um identificador de página falha e os controlos anteriores permanecem visíveis. - Para zonas redimensionáveis e destacáveis em vez de páginas exclusivas, é preferível utilizar dockcontainer.
- No teclado, a barra de separadores segue o seu eixo: Esquerda/Direita (invertidas na escrita da direita para a esquerda), Cima/Baixo nas posições
start/end, Início/Fim, Enter ou Espaço para ativar, Delete para fechar um separador que se pode fechar. Os separadores desativados e os que saíram da barra são saltados.
Herdado da base comum #
Estes membros existem em todos os componentes visuais — não são próprios deste. São detalhados uma só vez, nos capítulos transversais; esta tabela apenas diz onde os ler.
| Membros | Função | Detalhado em |
|---|---|---|
of_count · of_keys_at · of_has | Percorrer o que o componente contém | 3.2 Os items |
of_reset | Repor o componente a zero | 3.6 Repor um componente a zero: of_reset() |
of_register_shortcut · of_clear_shortcuts | Atalhos de teclado do componente | 3.5 Os atalhos de teclado |
of_is_created · of_is_ready · of_get_last_error | Se nasceu, se está pronto, o que falhou | 3.7 Diagnóstico |
of_save_as_png · of_save_as_jpg | Exportar a renderização como imagem | 3.8 Exportar a representação como imagem |
of_set_redraw | Agrupar as alterações num único repinte | 3.10 Boas práticas |
of_preload_icons | Ícones mostrados sem atraso | Apresentação instantânea: of_icon |
of_set_translation | Traduzir uma legenda do componente | 5.2 Adaptar uma etiqueta: of_set_translation |
of_focus_webview | Dar o foco ao componente | 6.4 Teclado e focus |
of_print · of_print_to_pdf | Imprimir, ou escrever um PDF | 6.9 Imprimir |
of_set_property · of_get_property · of_component_name | Controlar uma propriedade pelo nome | 3.1 O motor de propriedades |
Duas ajudas não são herdadas: of_icon e of_escape_markup vivem em n_pbt_utils. Declare um — n_pbt_utils lnv_utils, nada a criar — e chame-as nele.