commandpalette — n_pbt_commandpalette #
← Referência dos componentes · Índice do guia
Paleta de comandos: o utilizador prime um atalho, escreve três letras e alcança qualquer acção da sua aplicação — sem a procurar nos menus.
▶ Ver ao vivo — Aplicação de demonstração, mosaico Command palette: a pré-visualização, o código que o produz e esta página, lado a lado.
Em resumo #
| Objecto | n_pbt_commandpalette — não visual: nada para colocar na janela |
| Serve para | Tornar todas as acções da aplicação alcançáveis pelo teclado, em três letras |
| Retorno | Não bloqueante: of_open() devolve o controlo de imediato; a escolha volta como evento |
A paleta é uma janela destacada, sua: paira sobre a aplicação, toma o foco enquanto o utilizador escreve e devolve-o ao fechar-se.
Início rápido #
// Uma vez, no arranque : as accoes da sua aplicacao
inv_palette.ipo_owner = this
inv_palette.of_add_command(/*key*/ "new", /*label*/ "N", /*group*/ "F")
inv_palette.of_add_command(/*key*/ "open", /*label*/ "O", /*group*/ "F")
inv_palette.of_add_command(/*key*/ "save", /*label*/ "S", /*group*/ "F")
inv_palette.of_register_shortcut()
// event ue_command_selected : (string as_key)
choose case as_key
case "new"; of_new()
case "open"; of_open()
case "save"; of_save()
end choose
A ligação: a janela anfitriã #
A paleta é um objeto não visual, mas não tem qualquer recetor nem mensagem a ligar: defina ipo_owner na sua janela, e a paleta recolhe sozinha os seus eventos e dispara-os nesse objeto.
Duas linhas, uma só vez, ao abrir a janela:
// A janela a que a paleta pertence
inv_palette.ipo_owner = this
// A paleta tem de responder a sua tecla
inv_palette.of_register_shortcut()
É tudo o que há para ligar. A escolha do utilizador, a abertura e o fecho voltam depois como simples eventos em
ipo_owner— sem recetor, sem mensagem a mapear, sem temporizador.
O atalho: é a DLL que o ouve #
O atalho que abre a paleta não é escutado pela página: é registado junto da DLL, a única que vê as teclas premidas enquanto o foco está noutro controlo. É toda a diferença entre uma paleta que se encontra e uma que só responde depois de se ter clicado nela.
A DLL ouve o atalho, mas não abre nada por si: avisa-o através de ue_shortcut, e é o senhor que decide. Uma paleta a abrir por cima de um diálogo modal não ajudaria ninguém.
// event ue_shortcut : a tecla caiu
if not ib_dialog_open then inv_palette.of_open()
is_shortcut escolhe o atalho; of_register_shortcut() entrega-o. Chame-o uma vez ao abrir a janela — caso contrário a paleta só responde à sua tecla depois de já ter sido aberta uma vez. of_open volta a entregá-lo de passagem, portanto um atalho alterado mais tarde não precisa de mais nada.
// O atalho do costume, o dos editores de codigo
inv_palette.is_shortcut = inv_palette.SHORTCUT_DEFAULT
// Ou o seu
inv_palette.is_shortcut = "ctrl+shift+p"
// Ou nenhum : a paleta so abre por of_open()
inv_palette.is_shortcut = inv_palette.SHORTCUT_NONE
O atalho da paleta só é consultado depois dos atalhos dos outros componentes da janela, com ou sem foco: um botão de barra de ferramentas com o mesmo atalho ganha. O atalho desta janela passa antes de um atalho registado sem
ipo_owner(toda a aplicação). Só são aceites as teclas que o gancho sabe nomear — letras, algarismos, F1 a F24, Enter, Esc, Del, Ins, Home, End, PgUp, PgDn e, com Ctrl ou Alt, as setas, Espaço, Tab, Retrocesso,+ - , .; qualquer outra devolve-5. O capítulo do teclado detalha-o.
Onde a paleta aparece #
is_position diz onde a janela assenta. É sempre trazida de volta para dentro do ecrã: uma paleta ancorada sob um campo no fundo da janela não desaparece atrás da barra de tarefas.
| Constante | Onde |
|---|---|
POSITION_WINDOW_CENTER | Centrada em ipo_owner — a predefinição, e o que o olho espera |
POSITION_SCREEN_CENTER | Centrada no ecrã, seja qual for a janela |
POSITION_ABSOLUTE | Em il_x / il_y, em píxeis de ecrã |
O PowerBuilder trabalha em PBU, e a posição de um controlo é relativa à sua janela: para ancorar a paleta sob um controlo, of_anchor_under(controlo) faz a conversão e define as três propriedades. Com dois ecrãs, abre no ecrã do ponto pedido.
A sua altura acompanha o número de comandos mostrados e diminui à medida que se filtra — sem que o canto superior se mexa, senão a caixa de pesquisa fugia debaixo dos dedos. Está limitada a meio ecrã: acima disso a lista desliza por dentro e a caixa de pesquisa fica em cima.
Um clique noutro sítio da aplicação fecha a paleta, e esse clique atinge na mesma o seu alvo — como ao sair de um menu. Nada a fazer para isso.
Propriedades #
| Propriedade | Tipo | Predefinição | Papel |
|---|---|---|---|
ipo_owner | powerobject | — | A janela a que a paleta pertence: possui a janela de pop-up e serve-lhe de âncora, o seu atalho responde nessa janela, e é nela que os eventos da paleta são disparados. Defina-a antes de of_open — é a única ligação a fazer. Deixada vazia, o atalho responde em todas as janelas da aplicação. Dois objetos paleta na mesma janela guardam cada um o seu atalho e os seus eventos: nenhum recebe os do outro |
ipo_receiver | powerobject | — | Opcional, legado: um objeto visual distinto onde entregar os eventos, em vez de ipo_owner — é também a única janela cujo pbm_custom02 é tocado a cada evento. Deixe-o vazio — a paleta entrega agora os seus eventos sozinha através de ipo_owner |
is_shortcut | string | "ctrl+k" | Atalho que abre a paleta, de qualquer sítio da janela. Constantes SHORTCUT_DEFAULT (ctrl+k) e SHORTCUT_NONE (nenhum). Produz efeito em of_register_shortcut |
is_position | string | window-center | Onde a janela assenta (constantes POSITION_*) |
il_x · il_y | long | 0 | Posição em píxeis de ecrã, lida apenas por POSITION_ABSOLUTE |
is_placeholder | string | "" | Texto cinzento na caixa de pesquisa enquanto nada foi escrito |
is_recent | string | "" | Memória de uso: os ids lançados mais recentemente, do mais recente, separados por vírgulas. A paleta sobe-os ao topo, e a recência desempata ao filtrar — nunca inverte a pertinência. Releia-a após o uso e persista-a, reponha-a no arranque. Uma paleta que começa em branco todas as manhãs não aprende nada |
il_max_recent | long | 8 | Quantas o bloco « Usados recentemente » guarda. 8 por omissão. 0 desliga-o: uma aplicação cujos utilizadores preferem ver os seus grupos intactos pode dizê-lo. Uma entrada do bloco permanece no seu grupo e leva o nome dele — um atalho não desloca aquilo que abrevia |
Métodos #
| Método | Papel | |
|---|---|---|
of_add_command (string as_key, string as_label, string as_group) | Declara uma acção: o seu identificador, a sua etiqueta e o grupo sob o qual aparece. Devolve 0 depois de acrescentada, -5 se a chave estiver vazia, contiver /, ` | ou uma vírgula (is_recent` é uma lista separada por vírgulas), ou já estiver ocupada. Dezenas de milhares de comandos continuam fluidos: a paleta só desenha as linhas visíveis |
of_add_command (string as_key, string as_label, string as_group, string as_hint, string as_shortcut, string as_keywords) | O mesmo, com a explicação à direita, o atalho a mostrar, que lança o seu comando enquanto a paleta está aberta — é assim que se aprende ; fora, a sua aplicação conserva os seus próprios aceleradores, e durante a escrita Ctrl+C, Ctrl+V, Ctrl+Z e Ctrl+A ficam com a caixa de pesquisa — e palavras-chave que a pesquisa lê sem as mostrar. Devolve 0 depois de acrescentada, -5 se a chave estiver vazia, contiver /, ` | ou uma vírgula (is_recent` é uma lista separada por vírgulas), ou já estiver ocupada |
of_insert_command (string as_key, string as_label, string as_group, integer ai_index) | Declara uma acção numa posição escolhida (1 = a primeira) em vez de no fim: um módulo partilhado arruma os seus comandos onde devem ficar. 0 ou menos, ou para além do fim, acrescenta no fim. Explicação, atalho, palavras-chave e ícone definem-se depois com of_command. Devolve 0 depois de acrescentada, -5 para as mesmas chaves que of_add_command | |
of_remove_command (string as_key) | Retira uma acção; as outras ficam. Devolve 0 depois de retirada, -5 se nenhum comando tiver essa chave | |
of_command (string as_key) → n_pbt_commandpalette_command | O handle de um comando, para o renomear, mudar o seu atalho, esbatê-lo ou escondê-lo pelas suas propriedades. Esbater em vez de retirar: retirar o que o utilizador não pode fazer agora retira-lhe também toda a hipótese de descobrir que existe. O estado viaja com os comandos: uma alteração feita com a paleta aberta vê-se na abertura seguinte | |
of_key ( ) → string | No handle que of_command devolve: a chave do comando que designa — o que of_command recebeu para o obter, e o que se guarda quando o handle passa de mão em mão | |
of_clear_commands ( ) | Esvazia a paleta. Devolve 0 | |
of_count ( ) → long | Devolve o número de comandos que a paleta carrega | |
of_keys_at ( long al_index ) → string | O identificador do comando na posição al_index (a partir de 1), ou "" para além de qualquer das extremidades. Com of_count, é o que permite percorrer uma paleta que não se preencheu — um módulo partilhado acrescenta os seus | |
of_has ( string as_key ) → boolean | Existe um comando sob este identificador? Perguntar é melhor do que adivinhar: of_add_command recusa (-5) um identificador já ocupado | |
of_anchor_under ( dragobject ado_control ) | Ancora a paleta sob um controlo — um campo, um botão: define is_position como POSITION_ABSOLUTE e il_x / il_y no canto inferior esquerdo do controlo, em píxeis de ecrã. Chame-o antes de of_open; a paleta continua a ser trazida de volta para dentro do ecrã. Devolve 0, ou -5 se o controlo não for válido | |
of_open ( ) | Abre a paleta: uma janela sua, possuída por ipo_owner, colocada por is_position. Toma o foco e devolve-o ao fechar-se. Devolve 0 depois de pedida — segue-se sempre ue_opened (no ecrã) ou ue_closed (com a razão por que não apareceu) —, -6 se faltar o runtime WebView2, -4 se a sua janela não pôde ser criada | |
of_is_open ( ) | VERDADEIRO enquanto a paleta está no ecrã. É isso que permite ao atalho alternar: premido uma segunda vez uma paleta fecha-se — voltar a chamar of_open destruiria a janela para a reconstruir idêntica, o que se vê como um tremeluzir, não como um fecho. A DLL continua a não decidir nada: informa. Uma vez aberta, a paleta tem o foco na sua própria janela: o atalho premido aí fecha-a sozinho. Responde pela paleta deste objeto: quando outro objeto paleta abre a sua, esta é substituída e of_is_open responde FALSO aqui | |
of_close ( ) | Fecha a paleta que este objeto abriu — nunca a que outro objeto paleta abriu entretanto. Perder o foco também a fecha, como um menu. Devolve 0 | |
of_register_shortcut ( ) | Entrega o atalho de is_shortcut à DLL. A chamar uma vez ao abrir a janela. Um só atalho por objeto paleta: voltar a chamá-lo depois de mudar is_shortcut substitui o anterior, que deixa logo de responder — nunca há nada a retirar antes. Devolve 0 se foi posto, 1 se substituiu um, 2 se um is_shortcut vazio não deixa nenhum atalho (retirado, ou não havia), -5 se a tecla for das que o gancho não vê (ver acima) — o atalho anterior mantém-se então. Sem ipo_owner, o atalho responde em todas as janelas da aplicação. Dois objetos paleta de uma mesma janela guardam cada um o seu; o mesmo atalho registado por um segundo objeto passa para este (1). Destruir o objeto retira o seu atalho — nunca o que outro objeto paleta detém | |
of_process_events ( ) | Recolhe os eventos em espera e levanta-os em ipo_owner. O componente chama-a sozinho enquanto a paleta vive: normalmente não tem de o fazer | |
of_reset ( ) | Esvazia os comandos e a memória de uso (is_recent), repõe as propriedades nas predefinições, fecha uma paleta aberta e repõe um atalho registado em SHORTCUT_DEFAULT. ipo_owner e ipo_receiver ficam intactos: são a ligação, não o conteúdo |
Propriedades de um comando — n_pbt_commandpalette_command #
Obtida com of_command(chave). A paleta reconstrói a sua janela a partir da sua lista a cada of_open: uma propriedade alterada enquanto está aberta vê-se na abertura seguinte.
| Propriedade | Tipo | Predefinição | Função |
|---|---|---|---|
is_label | string | — | O texto da linha |
is_shortcut | string | "" | O atalho mostrado à direita da linha, e honrado enquanto a paleta está aberta (Ctrl+Shift+S) |
is_group | string | — | O grupo sob o qual o comando figura; mudá-lo desloca-o sem o retirar (mantém a sua posição entre os comandos) |
is_hint | string | "" | A pequena linha sob a etiqueta |
is_keywords | string | "" | As palavras que a pesquisa lê sem as mostrar — as palavras do utilizador |
is_icon | string | "" | Um ícone à esquerda da linha: um ficheiro, uma imagem de biblioteca, ou mono: / tint: para um que segue o tema |
ib_enabled | boolean | true | Comando esbatido: visível, pesquisável e inerte — nem clique, nem Enter, nem o seu atalho |
ib_visible | boolean | true | Comando escondido: fora da lista e dos atalhos, sem ser eliminado; volta tal como estava |
Eventos #
| Evento | Accionado quando |
|---|---|
ue_command_selected (string as_key) | O utilizador escolheu uma acção. A paleta já se fechou: fazer o que ela anuncia cabe-lhe a si |
ue_shortcut ( ) | O atalho foi premido. A DLL transmite, o PB decide. Uma paleta alterna na sua própria tecla: if of_is_open() then of_close() else of_open() — premido dentro da paleta aberta, o atalho fecha-a sozinho. Também pode recusar |
ue_opened ( ) | A paleta está no ecrã — através de of_open |
ue_closed (string as_reason) | Acabou de se fechar, tenha sido escolhido algo ou não. Segue cada of_open que devolveu 0: as_reason está vazio para uma paleta que estava no ecrã, cancelled se foi fechada — ou substituída por outra paleta — antes de aparecer, failed se a sua janela não pôde nascer, blocked sob depuração remota sem licença |
A paleta não faz nada por si. Comunica o identificador escolhido e fecha-se. É a sua aplicação que age — a mesma acção, accionada a partir de um menu ou da paleta, passa pelo mesmo código.
Pelo teclado #
| Tecla | Efeito |
|---|---|
O atalho de is_shortcut | Avisa o seu código através de ue_shortcut; é ele que abre |
| Escrita | Filtra à medida que se escreve: as letras não têm de se seguir, nfi encontra « Novo ficheiro », e os acentos não contam (preferences encontra « Préférences ») |
| Setas cima / baixo | Deslocam a selecção na lista |
| Enter | Escolhe a acção seleccionada (ue_command_selected) |
| O atalho mostrado numa linha | Lança esse comando, sem ter de o seleccionar |
| Escape | Fecha sem escolher nada |
Exemplos #
Alimentar a paleta a partir do seu menu #
// As palavras-chave nao se veem, mas a pesquisa le-as :
// escrever "pdf" encontra a exportacao mesmo que a etiqueta nao o diga
inv_palette.of_add_command(/*key*/ "export", /*label*/ "E", /*group*/ "F", /*hint*/ "H", /*shortcut*/ "Ctrl+E", /*keywords*/ "pdf csv xlsx")
Escolher outro atalho #
// Ctrl+K ja usado pela sua aplicacao ? Escolha outro.
// of_register_shortcut entrega-o, e o anterior sai sozinho.
inv_palette.is_shortcut = "ctrl+shift+p"
inv_palette.of_register_shortcut()
Ancorá-la sob um campo #
// Ancorada sob um campo, em pixeis de ecra
// A paleta e trazida de volta para dentro do ecra se transbordasse
inv_palette.of_anchor_under(/*control*/ sle_1)
inv_palette.is_placeholder = "P"
inv_palette.of_open()
// Remove one command, empty the list, close the palette
inv_palette.of_remove_command(/*key*/ "print")
inv_palette.of_clear_commands()
inv_palette.of_close()
Boas práticas #
- Dê a cada comando o mesmo identificador que no seu menu: uma só função trata ambos, e o utilizador obtém exactamente a mesma coisa.
- Chame
of_register_shortcut()ao abrir a janela, não no primeiroof_open: uma paleta que só responde à sua tecla depois de aberta com o rato não serve de nada. - Preencha as palavras-chave: é o que separa uma paleta que se usa de uma onde nunca se encontra nada. Pense nas palavras do utilizador, não nas suas.
- Mostre o atalho da acção em
as_shortcut: a paleta torna-se assim a maneira de os aprender. - Ponha lá apenas acções imediatas. Um comando que abre um diálogo de configuração, sim; um que precisa de três parâmetros, não.
- Retire os comandos que já não fazem sentido em vez de os deixar falhar: uma paleta que oferece o impossível perde a confiança de uma vez.