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 #
| Userobject | u_pbt_radialmenu |
| Classe de itens | n_pbt_radialmenu_item (of_item(keys)) |
| Serve para | Oferecer um punhado de comandos frequentes onde a mão já está |
| Princípio | Descreve 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 #
| Propriedade | Tipo | Predefinição | Papel |
|---|---|---|---|
ii_max_sectors | integer | 8 | Quantos 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_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 | "" | Dica simples. Mantida por compatibilidade: o lançador é invisível, não tem superfície para sobrevoar, e nada a mostra |
is_super_tooltip_title | string | "" | Título da dica enriquecida. Mantido por compatibilidade, nunca mostrado — ver is_tooltip |
is_super_tooltip_text | string | "" | Texto da dica enriquecida. Mantido por compatibilidade, nunca mostrado — ver is_tooltip |
is_super_tooltip_image | string | "" | Imagem da dica enriquecida. Mantida por compatibilidade, nunca mostrada — ver is_tooltip |
Métodos #
| Método | Papel | |
|---|---|---|
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 #
| Evento | Disparado 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 #
| Propriedade | Tipo | Predefinição | Papel |
|---|---|---|---|
is_text | string | "" | 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_enabled | boolean | true | A falso, o ramo fica desativado e o seu setor ignora todos os cliques |
ib_visible | boolean | true | A 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_checked | boolean | false | A verdadeiro, um arco fino sob a faixa marca o ramo como ativo |
il_accent | long | -1 | Acento deste ramo: a sua faixa quando apontado, e a sua marca (-1 = o do componente) |
il_back_color | long | -1 | Faixa deste ramo em repouso (-1 = a do tema) |
il_text_color | long | -1 | Cor do rótulo deste ramo (-1 = a do tema) |
il_back_color_hover | long | -1 | Fatia deste ramo enquanto é apontado (-1 = a do tema) |
il_text_color_hover | long | -1 | Cor 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 #
- Abra ao LARGAR o clique direito do controlo, nunca ao premir. É o que separa abrir de escolher, e o utilizador precisa de ambos.
- Rótulos curtos. Uma ou duas palavras. O setor está lá para a direção; o texto inteiro só se lê ao apontar o ramo.
- Quatro a seis ramos valem mais que oito. Uma roda recorda-se pela posição; quantas menos posições, mais depressa se aprendem.
- Ponha os comandos mais frequentes em cima e em baixo. São as duas direções que a mão alcança sem pensar.
- Mantenha a ordem estável de uma abertura para a outra: todo o interesse de uma roda é que o gesto acabe por preceder a leitura.
- Um menu radial não substitui um menu de lista. Vinte comandos raros leem-se melhor numa lista; guarde a roda para o punhado que se usa a toda a hora.
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.