commandpalette — n_pbt_commandpalette #
← Referencia de componentes · Índice de la guía
Paleta de comandos: el usuario pulsa un atajo, escribe tres letras y alcanza cualquier acción de su aplicación — sin buscarla en los menús.
▶ Verlo en vivo — Aplicación de demostración, mosaico Command palette: la vista previa, el código que lo produce y esta página, uno al lado del otro.
En resumen #
| Objeto | n_pbt_commandpalette — no visual: nada que colocar en la ventana |
| Sirve para | Hacer que toda acción de la aplicación sea alcanzable desde el teclado, en tres letras |
| Retorno | No bloqueante: of_open() devuelve el control de inmediato; la elección vuelve como evento |
La paleta es una ventana desprendida, suya: flota sobre su aplicación, toma el foco mientras el usuario escribe y lo devuelve al cerrarse.
Inicio rápido #
// Una vez, al arrancar : las acciones de su aplicacion
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_nouveau()
case "open"; of_ouvrir()
case "save"; of_enregistrer()
end choose
La conexión: la ventana anfitriona #
La paleta es un objeto no visual, pero no tiene ningún receptor ni mensaje que cablear: fije ipo_owner en su ventana, y la paleta recoge ella misma sus eventos y los lanza en ese objeto.
Dos líneas, una sola vez, al abrir la ventana:
inv_palette.ipo_owner = this // la ventana a la que la paleta pertenece
inv_palette.of_register_shortcut() // la paleta debe responder a su tecla
Eso es todo lo que hay que conectar. La elección del usuario, la apertura y el cierre le vuelven después como simples eventos en
ipo_owner— sin receptor, sin mensaje que mapear, sin temporizador.
El atajo: es la DLL quien lo oye #
El atajo que abre la paleta no lo escucha la página: se registra en la DLL, la única que ve las teclas pulsadas mientras el foco está en otro control. Ahí está toda la diferencia entre una paleta que se encuentra y una que solo responde si ya se ha hecho clic en ella.
La DLL oye el atajo, pero no abre nada por sí misma: se lo avisa con ue_shortcut, y decide usted. Una paleta que se abre sobre un diálogo modal no ayudaría a nadie.
// event ue_shortcut : la tecla ha caido
if not ib_dialog_open then inv_palette.of_open()
is_shortcut elige el atajo; of_register_shortcut() lo entrega. Llámelo una vez al abrir la ventana — de lo contrario la paleta solo responde a su tecla después de haberse abierto una vez. of_open lo vuelve a entregar de paso, así que un atajo cambiado más tarde no necesita nada más.
// El atajo de siempre, el de los editores de codigo
inv_palette.is_shortcut = inv_palette.SHORTCUT_DEFAULT
// O el suyo
inv_palette.is_shortcut = "ctrl+shift+p"
// O ninguno : la paleta solo se abre con of_open()
inv_palette.is_shortcut = inv_palette.SHORTCUT_NONE
Dos componentes que piden el mismo atajo: gana el que tiene el foco, si no el primero registrado. El capítulo del teclado lo detalla.
Dónde aparece la paleta #
is_position dice dónde se posa la ventana. Siempre se la trae de vuelta a la pantalla: una paleta anclada bajo un campo al pie de la ventana no desaparece tras la barra de tareas.
| Constante | Dónde |
|---|---|
POSITION_WINDOW_CENTER | Centrada en ipo_owner — el valor predeterminado, y lo que el ojo espera |
POSITION_SCREEN_CENTER | Centrada en la pantalla, sea cual sea la ventana |
POSITION_ABSOLUTE | En il_x / il_y, en píxeles de pantalla |
PowerBuilder trabaja en PBU: convierta antes de rellenar il_x / il_y.
Su altura sigue al número de comandos mostrados y se reduce a medida que se filtra — sin que su esquina superior se mueva, o el cuadro de búsqueda se escaparía bajo los dedos. Está limitada a media pantalla: más allá, la lista se desplaza por dentro y el cuadro de búsqueda queda arriba.
Un clic en otro sitio de la aplicación cierra la paleta, y ese clic alcanza igualmente su objetivo — como al salir de un menú. No hay nada que hacer.
Propiedades #
| Propiedad | Tipo | Predeterminado | Función |
|---|---|---|---|
ipo_owner | powerobject | — | La ventana a la que la paleta pertenece: posee la ventana emergente y le sirve de ancla, y es en ella donde se lanzan los eventos de la paleta. Póngala antes de of_open — es la única conexión que hacer |
ipo_receiver | powerobject | — | Opcional, heredado: un objeto visual distinto en el que entregar los eventos, en lugar de ipo_owner. Déjelo vacío — la paleta ahora entrega sus eventos ella misma mediante ipo_owner |
is_shortcut | string | "ctrl+k" | Atajo que abre la paleta, desde cualquier sitio de la ventana. Constantes SHORTCUT_DEFAULT (ctrl+k) y SHORTCUT_NONE (ninguno). Surte efecto en of_register_shortcut |
is_position | string | window-center | Dónde se posa la ventana (constantes POSITION_*) |
il_x · il_y | long | 0 | Posición en píxeles de pantalla, leída solo por POSITION_ABSOLUTE |
is_placeholder | string | "" | Texto gris en el cuadro de búsqueda mientras no se escribe nada |
is_recent | string | "" | Memoria de uso: los id lanzados más recientemente, el más reciente primero, separados por comas. La paleta los sube arriba, y la recencia desempata al filtrar — nunca invierte la pertinencia. Reléala tras el uso y persístela, devuélvela al arrancar. Una paleta que empieza en blanco cada mañana no aprende nada |
il_max_recent | long | 8 | Cuántas guarda el bloque « Usados recientemente ». 8 por defecto. 0 lo apaga: una aplicación cuyos usuarios prefieren ver sus grupos intactos puede decirlo. Una entrada del bloque permanece en su grupo y lleva su nombre — un atajo no mueve aquello que abrevia |
Métodos #
| Método | Función |
|---|---|
of_add_command (string as_key, string as_label, string as_group) | Declara una acción: su identificador, su etiqueta y el grupo bajo el que aparece. Devuelve 0 una vez aplicado, -5 ante un argumento no válido (clave vacía, dirección errónea), -2 si el componente no está creado |
of_add_command (string as_key, string as_label, string as_group, string as_hint, string as_shortcut, string as_keywords) | Lo mismo, con la explicación a la derecha, el atajo a mostrar, que lanza su comando mientras la paleta está abierta — así es como se aprende ; fuera, su aplicación conserva sus propios aceleradores — y palabras clave que la búsqueda lee sin mostrarlas. Devuelve 0 una vez aplicado, -5 ante un argumento no válido (clave vacía, dirección errónea), -2 si el componente no está creado |
of_remove_command (string as_key) | Quita una acción; las demás quedan. Devuelve 0 una vez aplicado, -5 ante un argumento no válido (clave vacía, dirección errónea), -2 si el componente no está creado |
of_command (string as_key) → n_pbt_commandpalette_command | El handle de un comando, para renombrarlo, cambiar su atajo, atenuarlo u ocultarlo mediante sus propiedades. Atenuar en lugar de quitar: quitar lo que el usuario no puede hacer ahora le quita también toda posibilidad de descubrir que existe. El estado viaja con los comandos: un cambio hecho con la paleta abierta se ve en la siguiente apertura |
of_key ( ) → string | En el handle que devuelve of_command: la clave del comando que designa — lo que of_command recibió para obtenerlo, y lo que se guarda cuando el handle pasa de mano en mano |
of_clear_commands ( ) | Vacía la paleta. Devuelve 0 una vez aplicado, -2 si el componente no está creado |
of_count ( ) → integer | Cuántos comandos lleva la paleta |
of_keys_at ( integer ai_index ) → string | El identificador del comando en la posición ai_index (desde 1), o "" más allá de cualquiera de los extremos. Con of_count, esto permite recorrer una paleta que uno no ha llenado — un módulo compartido añade los suyos |
of_has ( string as_key ) → boolean | ¿Existe un comando bajo este identificador? Preguntar evita declarar un segundo bajo un identificador ya ocupado |
of_open ( ) | Abre la paleta: una ventana propia, poseída por ipo_owner, colocada por is_position. Toma el foco y lo devuelve al cerrarse. Devuelve 0 una vez abierta, -1 si falta el runtime WebView2, -4 si su ventana no pudo crearse |
of_is_open ( ) | VERDADERO mientras la paleta está en pantalla. Es lo que permite al atajo alternar: pulsado una segunda vez una paleta se cierra — volver a llamar a of_open destruiría la ventana para reconstruirla idéntica, lo que se ve como un parpadeo, no como un cierre. La DLL sigue sin decidir nada: informa |
of_close ( ) | La cierra. Perder el foco también la cierra, como un menú. Devuelve 0 |
of_register_shortcut ( ) | Entrega el atajo de is_shortcut a la DLL. Llámelo una vez al abrir la ventana. Un solo atajo por ventana: volver a llamarlo tras cambiar is_shortcut sustituye al anterior, que deja de responder de inmediato — nunca hay nada que quitar antes. Devuelve 0 si se puso, 1 si sustituyó a uno, 2 si un is_shortcut vacío lo quitó |
of_process_events ( ) | Recoge los eventos en espera y los lanza en ipo_owner. El componente la llama él mismo mientras la paleta vive: normalmente no tiene que hacerlo |
of_reset ( ) | Vacía los comandos y devuelve las propiedades a sus valores predeterminados. ipo_owner e ipo_receiver quedan intactos: son el cableado, no el contenido. Devuelve 0 una vez aplicado, -2 si el componente no está creado |
Propiedades de un comando — n_pbt_commandpalette_command #
Obtenida con of_command(clave). La paleta reconstruye su ventana desde su lista en cada of_open: una propiedad cambiada mientras está abierta se ve en la siguiente apertura.
| Propiedad | Tipo | Predeterminado | Función |
|---|---|---|---|
is_label | string | — | El texto de la fila |
is_shortcut | string | "" | El atajo mostrado a la derecha de la fila, y activo mientras la paleta está abierta (Ctrl+Shift+S) |
ib_enabled | boolean | true | Comando atenuado: visible, buscable e inerte — ni clic, ni Intro, ni su atajo |
ib_visible | boolean | true | Comando oculto: fuera de la lista y de los atajos, sin ser eliminado; vuelve tal cual |
Eventos #
| Evento | Se dispara cuando |
|---|---|
ue_command_selected (string as_key) | El usuario ha elegido una acción. La paleta ya se ha cerrado: hacer lo que anuncia le toca a usted |
ue_shortcut ( ) | Se ha pulsado el atajo. La DLL avisa, PB decide. Una paleta alterna con su propia tecla: if of_is_open() then of_close() else of_open(). También puede negarse |
ue_opened ( ) | La paleta está en pantalla — mediante of_open |
ue_closed ( ) | Acaba de cerrarse, se haya elegido algo o no |
La paleta no hace nada por sí misma. Informa del identificador elegido y se cierra. Es su aplicación la que actúa — la misma acción, lanzada desde un menú o desde la paleta, pasa por el mismo código.
Desde el teclado #
| Tecla | Efecto |
|---|---|
El atajo de is_shortcut | Avisa a su código con ue_shortcut; es él quien abre |
| Escritura | Filtra sobre la marcha: las letras no tienen por qué seguirse, nva encuentra « Nuevo archivo » |
| Flechas arriba / abajo | Mueven la selección por la lista |
| Intro | Elige la acción seleccionada (ue_command_selected) |
| El atajo mostrado en una fila | Lanza ese comando, sin tener que seleccionarlo |
| Escape | Cierra sin elegir nada |
Ejemplos #
Alimentar la paleta desde su menú #
// Las palabras clave no se ven, pero la busqueda las lee :
// escribir "pdf" encuentra la exportacion aunque la etiqueta no lo diga
inv_palette.of_add_command(/*key*/ "export", /*label*/ "E", /*group*/ "F", /*hint*/ "H", /*shortcut*/ "Ctrl+E", /*keywords*/ "pdf csv xlsx")
Elegir otro atajo #
// Ctrl+K ya lo usa su aplicacion ? Elija otro.
// of_register_shortcut lo entrega, y el anterior se va solo.
inv_palette.is_shortcut = "ctrl+shift+p"
inv_palette.of_register_shortcut()
Anclarla bajo un campo #
// Anclada bajo un campo : PB cuenta en PBU, la DLL en pixeles
// La paleta se trae de vuelta a la pantalla si se salia
inv_palette.is_position = inv_palette.POSITION_ABSOLUTE
inv_palette.il_x = UnitsToPixels(sle_1.x, XUnitsToPixels!)
inv_palette.il_y = UnitsToPixels(sle_1.y + sle_1.height, YUnitsToPixels!)
inv_palette.is_placeholder = "P"
inv_palette.of_open()
inv_palette.of_remove_command(/*key*/ "print")
inv_palette.of_clear_commands()
inv_palette.of_close()
Buenas prácticas #
- Dé a cada comando el mismo identificador que en su menú: una sola función trata ambos, y el usuario obtiene exactamente lo mismo.
- Llame a
of_register_shortcut()al abrir la ventana, no en el primerof_open: una paleta que solo responde a su tecla después de abrirse con el ratón no sirve de nada. - Rellene las palabras clave: es lo que separa una paleta que se usa de una en la que nunca se encuentra nada. Piense en las palabras del usuario, no en las suyas.
- Muestre el atajo de la acción en
as_shortcut: la paleta se convierte así en la manera de aprenderlos. - Ponga solo acciones inmediatas. Un comando que abre un diálogo de configuración, sí; uno que necesita tres parámetros, no.
- Quite los comandos que ya no tienen sentido en lugar de dejarlos fallar: una paleta que ofrece lo imposible pierde la confianza de una vez.