PBToolboxAI v5 ← Site

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 #

Objecton_pbt_commandpalette — não visual: nada para colocar na janela
Serve paraTornar todas as acções da aplicação alcançáveis pelo teclado, em três letras
RetornoNã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 #

Coloque n_pbt_commandpalette na sua janela como objeto não visual (aqui chamado inv_palette): os seus eventos programam-se nele, como os de um controlo.

// Uma vez, no arranque : as accoes da sua aplicacao
inv_palette.ipo_owner = this
inv_palette.of_add_command(/*key*/ "new",  /*label*/ "New project", /*group*/ "File")
inv_palette.of_add_command(/*key*/ "open", /*label*/ "Open file...", /*group*/ "File")
inv_palette.of_add_command(/*key*/ "save", /*label*/ "Save", /*group*/ "File")
inv_palette.of_register_shortcut()
// event ue_command_selected of inv_palette : (string as_key)
// parent is the window : the palette runs nothing by itself
choose case as_key
	case "new";  parent.wf_new()
	case "open"; parent.wf_open()
	case "save"; parent.wf_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: recolhe sozinha os seus eventos e dispara-os em si mesma — ue_command_selected, ue_shortcut, ue_opened e ue_closed programam-se no objeto paleta colocado na janela (ou num descendente). ipo_owner indica a que janela pertence.

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 do objeto paleta (não de ipo_owner) — sem recetor, sem mensagem a mapear, sem temporizador. Um evento pode abrir uma MessageBox ou fechar a janela («Sair»): os seguintes esperam que termine, e uma paleta destruída com a sua janela pára de forma limpa.

Onde escrever os eventos #

O PowerBuilder só oferece os eventos de um objeto não visual em dois lugares: a paleta colocada na janela (no pintor, Insert > Object, depois n_pbt_commandpalette, chamada inv_palette: os seus eventos programam-se como os de um controlo — é o que supõem os exemplos desta página), ou um descendente de n_pbt_commandpalette (n_my_palette), cujos eventos levam os seus scripts e que a janela cria com create n_my_palette. Uma variável n_pbt_commandpalette criada por create não tem script: a paleta abre-se, mas a escolha do utilizador não chega a ninguém.


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.

ConstanteOnde
POSITION_WINDOW_CENTERCentrada em ipo_owner — a predefinição, e o que o olho espera
POSITION_SCREEN_CENTERCentrada no ecrã, seja qual for a janela
POSITION_ABSOLUTEEm 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 #

PropriedadeTipoPredefiniçãoPapel
ipo_ownerpowerobject—A janela a que a paleta pertence: possui a janela de pop-up e serve-lhe de âncora, e o seu atalho responde nessa janela. Defina-a antes de of_open. Deixada vazia, o atalho responde em todas as janelas da aplicação. Os eventos não são disparados nela mas no próprio objeto paleta. Dois objetos paleta na mesma janela guardam cada um o seu atalho e os seus eventos: nenhum recebe os do outro
ipo_receiverpowerobject—Opcional, herdado: uma janela cujo pbm_custom02 é tocado a cada evento, para o código antigo que aí chamava of_process_events. Deixe-o vazio — a paleta entrega os seus eventos sozinha, em si mesma
is_shortcutstring"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_positionstringwindow-centerOnde a janela assenta (constantes POSITION_*)
il_x · il_ylong0Posição em píxeis de ecrã, lida apenas por POSITION_ABSOLUTE
is_placeholderstring""Texto cinzento na caixa de pesquisa enquanto nada foi escrito
is_recentstring""Memória de uso: os ids lançados mais recentemente, o mais recente primeiro, separados por vírgulas. A paleta fá-los subir ao topo; ao filtrar, a recência só desempata resultados que correspondem mais ou menos igualmente bem — nunca põe uma correspondência mais fraca à frente de uma melhor, seja qual for il_max_recent. Os espaços à volta dos ids e os duplicados são limpos, e a lista limpa volta aqui. Releia-a após o uso e persista-a; volte a defini-la no arranque. Uma paleta que recomeça do zero todas as manhãs não aprende nada
il_max_recentlong8Quantos o bloco « Usados recentemente » guarda. 8 por omissão. Um limite mais baixo corta is_recent na abertura seguinte. 0 desliga-o: uma aplicação cujos utilizadores preferem os grupos intactos pode dizê-lo — is_recent fica então tal como está, sem uso. Uma entrada do bloco fica no seu grupo e leva o nome desse grupo — um atalho não move aquilo que abrevia

Métodos #

MétodoPapel
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. Um comando com grupo vazio vem **primeiro**, sem cabeçalho; of_get_last_error` diz porque uma chave foi recusada
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. Um comando com grupo vazio vem **primeiro**, sem cabeçalho; of_get_last_error` diz porque uma chave foi recusada
of_insert_command (string as_key, string as_label, string as_group, long al_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_insert_command (string as_key, string as_label, string as_group, string as_hint, string as_shortcut, string as_keywords, long al_index)A forma completa, como of_add_command a recebe: a explicação, o atalho a mostrar e as palavras-chave chegam com o comando, na sua posição. Os mesmos valores devolvidos
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_commandO 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. Uma chave que nenhum comando tem dá um handle que não designa nada: os seus booleanos leem-se FALSE, os seus textos "", e uma escrita perde-se — of_get_last_error di-lo
of_key ( ) → stringNo 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, incluindo os comandos lidos de um menu (of_load_menu). Devolve 0
of_count ( ) → longDevolve o número de comandos que a paleta carrega
of_keys_at ( long al_index ) → stringO 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 ) → booleanExiste 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. Um controlo (ou uma janela) que se lê da direita para a esquerda dá o seu canto inferior direito: a paleta alinha-se nessa margem e abre-se para a esquerda
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. Os comandos lidos de um menu (of_load_menu) assumem o estado do seu item nesse momento
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. O atalho retomado por um segundo objeto volta ao primeiro quando o segundo é destruído. Enquanto uma janela está ativa, o atalho da paleta passa antes dos aceleradores do seu menu PowerBuilder: um item de menu na mesma tecla já não o ouve
of_process_events ( )Recolhe os eventos em espera e dispara-os no próprio objeto paleta. O componente chama-o sozinho enquanto a paleta vive: não tem de o fazer. Um evento que abre uma MessageBox não vê os seguintes disparados a meio, e um evento que fecha a janela da paleta pára a recolha de forma limpa
of_reset ( ) → longEsvazia 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. Os comandos lidos de um menu também saem Devolve 0 uma vez feito.
of_load_menu ( menu am_menu )Preenche a paleta a partir de um menu PowerBuilder: cada item sem subitens torna-se um comando, sem declarar as suas acções duas vezes — passe this.MenuID ou um dos seus itens. Chave = o ClassName do item, rótulo = o seu texto sem & nem o atalho escrito após uma tabulação, grupo = os textos dos itens acima, atalho = o que mostra, palavras-chave = o seu MicroHelp. O menu continua a ser o mestre: relido a cada of_open, um item desativado, oculto ou renomeado mostra-se tal como está (um pai leva os seus itens). Escolher um comando dispara ue_command_selected e não executa nada. Uma segunda chamada substitui os comandos da primeira; os de of_add_command ficam. Devolve 0, -5 quando o menu não é válido
of_loaded_item ( string as_key ) → menuO item de menu PowerBuilder de onde vem um comando (of_load_menu): em ue_command_selected, of_loaded_item(as_key).TriggerEvent(Clicked!) executa o que o menu executa. Uma chave que não vem de um menu dá uma referência inválida: teste-a com IsValid
of_get_last_error ( ) → stringPorque é que a última chamada devolveu -5 (uma chave recusada, um menu inválido, um atalho que o teclado não sabe comunicar), ou a última escrita de um handle de comando que não chegou a nenhum comando. "" quando nada falhou: cada chamada que age esvazia-o primeiro

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.

PropriedadeTipoPredefiniçãoFunção
is_labelstring—O texto da linha
is_shortcutstring""O atalho mostrado à direita da linha, e honrado enquanto a paleta está aberta (Ctrl+Shift+S)
is_groupstring—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_hintstring""A pequena linha sob a etiqueta
is_keywordsstring""As palavras que a pesquisa lê sem as mostrar — as palavras do utilizador
is_iconstring""Um ícone à esquerda da linha: um ficheiro, uma imagem de biblioteca, ou mono: / tint: para um que segue o tema
ib_enabledbooleantrueComando esbatido: visível, pesquisável e inerte — nem clique, nem Enter, nem o seu atalho
ib_visiblebooleantrueComando escondido: fora da lista e dos atalhos, sem ser eliminado; volta tal como estava

Eventos #

EventoAccionado 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. O botão esquerdo, Enter ou o atalho mostrado numa linha escolhem; um clique direito ou do meio não faz nada. O evento pode abrir uma MessageBox ou fechar a janela
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 #

TeclaEfeito
O atalho de is_shortcutAvisa o seu código através de ue_shortcut; é ele que abre
EscritaFiltra à 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 / baixoDeslocam a selecção na lista
EnterEscolhe a acção seleccionada (ue_command_selected)
O atalho mostrado numa linhaLança esse comando, sem ter de o seleccionar
EscapeFecha sem escolher nada
Page Up / Page DownMovem a seleção um ecrã
Home / EndCom texto escrito: ao início / ao fim da pesquisa. Campo vazio: ao primeiro / último comando. Ctrl+Home / Ctrl+End: sempre o primeiro / último comando; Shift+… seleciona no campo
TabFica no campo de pesquisa (a paleta é um diálogo modal)
Um clique direito ou do meio numa linhaNão faz nada: só o botão esquerdo escolhe

Enquanto um método de entrada (japonês, chinês, coreano) compõe, Enter e as setas pertencem-lhe: confirmar uma conversão nunca lança um comando.


Exemplos #

Alimentar a paleta a partir do seu menu #

// Every action of your menu becomes a command : nothing declared twice
inv_palette.of_load_menu(/*menu*/ this.MenuID)

// The palette answers its key from the window's opening
inv_palette.of_register_shortcut()
// Local variables
menu lm_item

// event ue_command_selected of inv_palette : run what the menu item runs
lm_item = inv_palette.of_loaded_item(/*key*/ as_key)
if IsValid(lm_item) then lm_item.TriggerEvent(Clicked!)

As palavras que a pesquisa lê #

// 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*/ "Export", /*group*/ "File", /*hint*/ "PDF, CSV or xlsx", /*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 = "Type a command..."
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 #


← Referência dos componentes · Índice do guia