PBToolboxAI v4 ← Site

radialmenu — u_pbt_radialmenu #

← Referência dos componentes · Índice do guia

Menu de contexto radial: os comandos em coroa à volta do cursor, escolhidos pela direção em vez de lidos numa lista.

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


Em resumo #

Userobjectu_pbt_radialmenu
Classe de itensn_pbt_radialmenu_item (of_item(keys))
Serve paraOferecer um punhado de comandos frequentes onde a mão já está
PrincípioDescreve os ramos; a roda, a forma e a navegação são connosco

Arranque rápido #

// Uma roda montada para o que esta sob o cursor
uo_wheel.of_add_item(/*keys*/ "cut",    /*text*/ "Cut")
uo_wheel.of_add_item(/*keys*/ "copy",   /*text*/ "Copy")
uo_wheel.of_add_item(/*keys*/ "paste",  /*text*/ "Paste")
uo_wheel.of_add_item(/*keys*/ "delete", /*text*/ "Delete")

// Abre-se ao soltar o botao direito: ver ue_rclicked

Abrir e depois escolher #

A roda abre-se ao largar o botão direito, e é preciso um segundo clique para escolher. Não é um detalhe de implementação: se abrisse ao premir, o largar desse mesmo clique selecionaria de imediato o setor caído sob o cursor, e o utilizador lançaria um comando sem o ter visto.

É por isso que of_show() é chamado a partir do evento de clique direito do controlo sobre o qual o utilizador faz o gesto (um statictext, um button, uma grelha…): nesse instante o botão já está em cima, e o clique seguinte é mesmo o que escolhe. O menu radial, esse, não tem superfície nenhuma — logo, nenhum evento de rato próprio.

O componente em si é invisível: não ocupa lugar na janela. Coloque-o onde quiser, com largura e altura nulas — só existe enquanto a roda está aberta.

O ramo apontado — com o rato ou o teclado — mostra o rótulo inteiro, por cima dos vizinhos: um setor guarda no máximo duas linhas (uma só a partir de nove ramos), e é isso que lhe permite levar um rótulo curto sem mentir sobre o que faz. O cubo central é a saída: clicar nele fecha a roda; dentro de uma sub-roda, sobe um nível. Enquanto a roda está aberta a aplicação continua a correr: um ramo retirado, desativado ou ocultado entretanto já não se escolhe (em vez disso, ue_dismissed), e of_clear, of_remove_item ou of_reset fecham a roda aberta.

// Abre-se ao soltar o botao direito: ver ue_rclicked
uo_wheel.of_show()

Pelo teclado, as setas percorrem os ramos saltando os desativados, Enter ou Espaço escolhe, ← e Retrocesso sobem um nível, e Escape sobe um nível numa sub-roda — só fecha a roda na raiz. Nenhuma destas teclas chega à aplicação enquanto a roda está aberta. Em leitura da direita para a esquerda, a coroa gira no outro sentido e ← e → trocam de papel: → sobe um nível.


As sub-rodas #

Um endereço pendura ramos sob outro: export/pdf. Escolher o ramo pai não escolhe nada: a roda é substituída pela dos seus filhos, e o cubo passa a ser o caminho de volta.

Porquê substituir em vez de acrescentar uma segunda coroa? Porque um anel exterior dividiria os setores por dois em cada nível. Oito ramos já é o máximo legível; não há espaço para mostrar dois níveis ao mesmo tempo.

O evento ue_item_selected comunica o endereço completo (export/pdf), não a chave da folha sozinha. Duas sub-rodas podem portanto nomear os seus ramos da mesma forma.

// A branch, then two entries at its address
uo_wheel.of_add_item(/*keys*/ "export", /*text*/ "Export")
uo_wheel.of_add_item(/*keys*/ "export/pdf", /*text*/ "PDF")
uo_wheel.of_add_item(/*keys*/ "export/csv", /*text*/ "CSV")

Para retirar um ramo — com a sua sub-roda — sem reconstruir toda a roda: of_remove_item("export/csv"). Os outros ramos ficam no lugar.


Quando há ramos a mais #

Uma roda lê-se pela direção, e para além de oito setores as fatias deixam de se distinguir. ii_max_sectors fixa esse teto (de 3 a 12, 8 por predefinição).

Os ramos a mais não se perdem: o último lugar da coroa passa a ser um ramo que os contém a todos e que abre como sub-roda. Um menu que deixasse cair a cauda seria um menu que mente sobre o que oferece.

Apertar a coroa é muitas vezes um ganho: quatro ramos largos apontam-se mais depressa do que oito estreitos.


Propriedades #

PropriedadeTipoPredefiniçãoPapel
ii_max_sectorsinteger8Quantos ramos uma coroa pode levar (3 a 12). O que exceder passa sob um último ramo que abre como sub-roda. Acima de oito, a roda compacta-se (ícone mais pequeno, rótulo numa linha) para que os rótulos não se sobreponham
is_theme_stylestring""Estilo visual do componente (constantes THEME_STYLE_*); vazio = o da aplicação, seguido a cada mudança
is_theme_modestring""Variante clara ou escura (constantes THEME_MODE_*); vazio = a da aplicação, seguida a cada mudança
il_theme_accentlong-1Cor de destaque deste componente (-1 = destaque da aplicação, ou o do tema)
is_tooltipstring""Dica simples. Mantida por compatibilidade: o lançador é invisível, não tem superfície para sobrevoar, e nada a mostra
is_super_tooltip_titlestring""Título da dica enriquecida. Mantido por compatibilidade, nunca mostrado — ver is_tooltip
is_super_tooltip_textstring""Texto da dica enriquecida. Mantido por compatibilidade, nunca mostrado — ver is_tooltip
is_super_tooltip_imagestring""Imagem da dica enriquecida. Mantida por compatibilidade, nunca mostrada — ver is_tooltip

Métodos #

MétodoPapel
of_add_item (string as_keys, string as_text)Acrescenta um ramo no seu endereço: format/strike pendura-se sob Format, que já tem de existir. É esse mesmo endereço que volta em ue_item_selected quando é escolhido. Devolve 0 depois de acrescentado, -5 se o endereço for recusado (pai não encontrado, endereço já ocupado, nível vazio como export/ ou /pdf, chave que contém ` ou começa por __), -2` se o componente não estiver criado
of_add_item (string as_keys, string as_text, string as_image, boolean ab_checked)O mesmo, com o ícone e a marca — o ícone como terceiro argumento, como em todo o resto da biblioteca. Um ramo desativa-se através do seu manípulo: of_item(keys).ib_enabled = false. Devolve 0 depois de acrescentado, -5 se o endereço for recusado (pai não encontrado, endereço já ocupado, nível vazio como export/ ou /pdf, chave que contém ` ou começa por __), -2` se o componente não estiver criado
of_clear ( )Esvazia a roda e liberta os manípulos obtidos por of_item (cada um designava um ramo que já não existe). Devolve 0 depois de aplicado, -2 se o componente não estiver criado
long of_show ( )Abre a roda centrada no cursor. Chame-o a partir do clique direito do controlo que recebe o gesto. Uma roda sem nenhum ramo visível não se abre: é disparado ue_dismissed. Devolve 0 depois de pedido, -2 se o componente não estiver criado
long of_show (long al_x, long al_y)O mesmo, centrada numa posição de ecrã em píxeis. Coordenadas negativas são um ponto real, (-1, -1) incluído: um ecrã colocado à esquerda ou acima do principal. Devolve 0 depois de pedido, -2 se o componente não estiver criado
of_item (string as_keys)Devolve o manípulo de um ramo, pelo seu endereço, para o alterar depois (rótulo, estado, cores). Uma chave simples é resolvida no endereço completo do único ramo que a leva: of_item("csv") e of_item("import/csv") devolvem então o mesmo manípulo. Ambígua, ou levada por nenhum ramo, devolve um manípulo que não muda nada em vez do ramo errado. of_key() do manípulo devolve a chave do último nível
of_remove_item (string as_keys)Retira um ramo e a sua sub-roda; os outros ficam. Devolve 0 depois de retirado, -5 se nenhum ramo vive nesse endereço, -2 se o componente não estiver criado
of_reset ( )Esvazia a roda e repõe todas as propriedades no valor de origem. Devolve 0 depois de aplicado, -2 se o componente não estiver criado

Eventos #

EventoDisparado quando
ue_item_selected (string as_keys)O utilizador escolheu um ramo. as_keys é o seu endereço completo (export/pdf), não a chave da folha sozinha. Um só evento por gesto: um duplo clique escolhe uma única vez
ue_dismissed ( )A roda fechou sem que nenhum ramo fosse escolhido: clique no cubo, clique fora da roda, Escape na raiz — e também quando of_show não tinha nada para mostrar

Um clique num canto da janela, fora do disco, conta como um clique fora: a roda fecha-se (ue_dismissed) e o clique passa para a aplicação que está atrás, em vez de ser engolido por um quadrado invisível.


Propriedades de item #

PropriedadeTipoPredefiniçãoPapel
is_textstring""Rótulo do ramo. Mantenha-o curto: um setor é uma fatia, não uma linha, e mostra no máximo duas linhas — o ramo apontado mostra o rótulo inteiro. Vazio, mostra-se a chave
ib_enabledbooleantrueA falso, o ramo fica desativado e o seu setor ignora todos os cliques
ib_visiblebooleantrueA falso, o ramo sai da roda — sub-roda incluída — sem ser eliminado; os setores fecham-se, e volta tal como estava. Um ramo cujas subentradas estão todas ocultas fica na roda, desativado: já não tem nada para abrir e não se escolhe como uma folha
ib_checkedbooleanfalseA verdadeiro, um arco fino sob a faixa marca o ramo como ativo
il_accentlong-1Acento deste ramo: a sua faixa quando apontado, e a sua marca (-1 = o do componente)
il_back_colorlong-1Faixa deste ramo em repouso (-1 = a do tema)
il_text_colorlong-1Cor do rótulo deste ramo (-1 = a do tema)
il_back_color_hoverlong-1Fatia deste ramo enquanto é apontado (-1 = a do tema)
il_text_color_hoverlong-1Cor do rótulo deste ramo enquanto é apontado (-1 = a do tema)

Um ramo não mostra nenhuma dica: a janela redonda não tem espaço fora do disco. O is_tooltip herdado pelo manípulo é guardado e relê-se, mas nunca é mostrado — é o ramo apontado que mostra o rótulo inteiro.


Exemplos #

Uma roda por contexto #

// Uma roda montada para o que esta sob o cursor
uo_wheel.of_clear()
uo_wheel.of_add_item(/*keys*/ "bold", /*text*/ "Bold", /*image*/ "mono:img\packimages.dll:svg/samples/bold", /*checked*/ true)
uo_wheel.of_add_item(/*keys*/ "find", /*text*/ "Find", /*image*/ "mono:img\packimages.dll:svg/samples/find", /*checked*/ false)

Reagir ao caminho escolhido #

// Evento ue_item_selected do menu radial
// as_keys traz o caminho completo, p. ex. "export/pdf"
choose case as_keys
	case "export/pdf"
		of_export_pdf()
	case "delete"
		of_delete_selection()
end choose

Marcar, desativar, apertar #

// Mark a branch as being on
uo_wheel.of_item(/*keys*/ "bold").ib_checked = true

// Grey out the one that makes no sense here
uo_wheel.of_item(/*keys*/ "paste").ib_enabled = false

// No maximo quatro ramos numa coroa
uo_wheel.ii_max_sectors = 4

Boas práticas #

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.

MembrosFunçãoDetalhado em
of_count · of_keys_at · of_hasPercorrer o que o componente contém3.2 Os items
of_resetRepor o componente a zero3.6 Repor um componente a zero: of_reset()
of_register_shortcut · of_clear_shortcutsAtalhos de teclado do componente3.5 Os atalhos de teclado
of_is_created · of_is_ready · of_get_last_errorSe nasceu, se está pronto, o que falhou3.7 Diagnóstico
of_save_as_png · of_save_as_jpgExportar a renderização como imagem3.8 Exportar a representação como imagem
of_set_redrawAgrupar as alterações num único repinte3.10 Boas práticas
of_preload_iconsÍcones mostrados sem atrasoApresentação instantânea: of_icon
of_set_translationTraduzir uma legenda do componente5.2 Adaptar uma etiqueta: of_set_translation
of_focus_webviewDar o foco ao componente6.4 Teclado e focus
of_print · of_print_to_pdfImprimir, ou escrever um PDF6.9 Imprimir
of_set_property · of_get_property · of_component_nameControlar uma propriedade pelo nome3.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.


← Referência dos componentes · Índice do guia