Blockly mantiene un registro de combinaciones de teclas que asignan teclas (o combinaciones de teclas, como ctrl-C
) a acciones. El registro está precargado con varios accesos directos, como ctrl-C
y meta-C
para copiar. Puedes agregar y borrar accesos directos del registro.
Cómo funcionan las combinaciones de teclas
El registro de combinaciones de teclas contiene objetos que modelan combinaciones de teclas. Cuando el usuario presiona una tecla (o una combinación de teclas), Blockly hace lo siguiente:
Verifica el registro para ver si se aplica algún acceso directo a la clave. Si más de un acceso directo usa la tecla, se prueban en el orden inverso de registro. Es decir, primero se prueba el acceso directo registrado más recientemente.
Llama a la función
preconditionFn
del acceso directo, que determina si el acceso directo se aplica a la situación actual. Por ejemplo, el acceso directo para copiar se aplica a los bloques, pero no al espacio de trabajo. Si el atajo no se aplica, Blockly intenta con el siguiente atajo de la lista, si hay alguno.Llama a la función
callback
del acceso directo, que ejecuta la acción del acceso directo. Por ejemplo, el acceso directo de copiar crea una copia del objeto enfocado actualmente, como un bloque. Si esta función devuelvetrue
, se detiene el procesamiento. Si devuelvefalse
, Blockly prueba el siguiente atajo de la lista, si existe.
Alcance
Un objeto Scope
identifica el componente de Blockly que tiene el enfoque actualmente. Los objetos de alcance se pasan a preconditionFn
y callback
, que los usan para decidir si un acceso directo se aplica a un componente en particular y, si es así, cómo aplicarlo.
Para usar un objeto Scope
, usa su propiedad focusedNode
. Es un objeto que implementa IFocusableNode
. Todos los componentes de Blockly en los que el usuario puede enfocarse implementan esta interfaz, incluidos los espacios de trabajo, los bloques, los campos, los comentarios y tus propios componentes personalizados. Para obtener más información, consulta Sistema de enfoque.
Por ejemplo, un preconditionFn
podría usar focusedNode
para garantizar que un acceso directo solo se aplique a los bloques.
preconditionFn(workspace, scope) {
return (scope.focusedNode instanceof Blockly.BlockSvg);
}
La interfaz de KeyboardShortcut
Los objetos del registro de accesos directos implementan la interfaz KeyboardShortcut
. Contiene las siguientes propiedades.
El nombre es obligatorio
Es un nombre único para el acceso directo. Los usuarios no ven este valor, y no es necesario que sea legible para las personas. No se debe traducir.
const logFieldsShortcut = {
name: 'logFields',
// ...
};
preconditionFn (opcional)
Blockly llama a esta función para decidir si un atajo se aplica a la situación actual. Si devuelve true
, Blockly llama a callback
. Si devuelve false
, Blockly ignora este atajo. Por ejemplo:
const logFieldsShortcut = {
// ...
preconditionFn(workspace, scope) {
// This shortcut only applies to blocks.
return (scope.focusedNode instanceof Blockly.BlockSvg);
},
// ...
};
Un acceso directo puede omitir esta función si siempre se aplica (poco común).
Los accesos directos no deben omitir esta función y, luego, tomar medidas de forma condicional en callback
. Si lo haces, evitarás que Blockly realice acciones como crear menús de ayuda contextual que muestren los atajos aplicables.
callback (opcional)
Esta función ejecuta la acción asociada con el acceso directo. Se llama solo si preconditionFn
devuelve true
o no existe. Sus parámetros son los siguientes:
workspace
: Es elWorkspaceSvg
actual.e
: Es elEvent
que inició el acceso directo.shortcut
: Es elKeyboardShortcut
en sí.scope
: Es elScope
al que se aplica el acceso directo.
Devuelve true
si se ejecuta correctamente y false
si falla.
Por ejemplo:
const logFieldsShortcut = {
// ...
callback(workspace, event, shortcut, scope) {
// preconditionFn required focusedNode to be a BlockSvg.
for (input of scope.focusedNode.inputList) {
// Log the values of all named fields. (Label fields usually don't have names.)
for (field of input.fieldRow) {
if (field.name) {
console.log(field.name + ': ' + field.getText());
}
}
}
return true;
},
// ...
};
Aunque callback
es opcional, por lo general, no hay motivos para no implementarlo.
keyCodes (opcional)
Es un array de teclas (o combinaciones de teclas) que activan este acceso directo. Para identificar las teclas, usa los códigos de tecla en Blockly.utils.KeyCodes
.
Por ejemplo:
const logFieldsShortcut = {
// ...
keyCodes: [Blockly.utils.KeyCodes.L],
// ...
};
Si deseas asignar teclas adicionales a un acceso directo existente (por ejemplo, si quieres agregar teclas a un acceso directo predeterminado), puedes llamar a Blockly.ShortcutRegistry.registry.addKeyMapping
.
Esto no es común.
Combinaciones de teclas
Si la combinación de teclas activa tu atajo de teclado, como mantener presionadas Control
y C
de forma simultánea, crea un código de tecla serializado llamando a Blockly.ShortcutRegistry.registry.createSerializedKey
:
const ctrlC = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.C, // Keycode of main key
[Blockly.utils.KeyCodes.CTRL], // Array of modifier keys
);
const copyShortcut = {
// ...
keyCodes: [ctrlC], // Use the serialized keycode
// ...
};
Control y Meta
En Windows, muchas combinaciones de teclas se activan con la tecla Control
. En Mac, estas combinaciones de teclas usan la tecla Command
, que se reconoce como el código de tecla META
. Para admitir ambos sistemas operativos, registra tus combinaciones con el código de tecla CTRL
y el código de tecla META
.
const ctrlC = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.C,
[Blockly.utils.KeyCodes.CTRL],
);
const metaC = Blockly.ShortcutRegistry.registry.createSerializedKey(
Blockly.utils.KeyCodes.C,
[Blockly.utils.KeyCodes.META],
);
const copyShortcut = {
// ...
keyCodes: [ctrlC, metaC],
// ...
};
Nota de implementación
Los controladores de eventos de teclado de Blockly usan la propiedad keycode
de KeyboardEvent
, aunque esté obsoleta.
allowCollision (opcional)
De forma predeterminada, solo puedes registrar un atajo para una tecla o combinación de teclas determinada. Si configuras esta propiedad en true
, puedes registrar una tecla (o una combinación de teclas) incluso si ya se registró un acceso directo con la misma tecla (o combinación de teclas).
Ten en cuenta que esta propiedad solo se aplica cuando se intenta registrar este acceso directo.
No impide que otros atajos usen la misma tecla (o combinación de teclas). Si se pueden registrar, depende del valor de su propiedad allowCollision
.
Independientemente de la cantidad de combinaciones de teclas registradas para una tecla o combinación de teclas determinada, como máximo se ejecutará una correctamente. Los atajos se prueban en el orden inverso de registro (del último registrado al primero).
Después de que uno de ellos devuelva true
desde su devolución de llamada, no se intentará ningún otro acceso directo.
metadata (opcional)
Es un objeto arbitrario que contiene información adicional. Está disponible para callback
a través del parámetro shortcut
.
Cómo agregar, borrar y modificar accesos directos
Para agregar una nueva combinación de teclas, llama a Blockly.ShortcutRegistry.registry.register
:
Blockly.ShortcutRegistry.registry.register(logFieldsShortcut);
Esta función tiene un segundo parámetro (allowOverrides
) que te permite reemplazar un acceso directo existente con el mismo nombre que el tuyo. Ten en cuenta que esto es diferente de KeyboardShortcut.allowCollision
, que te permite agregar un atajo con un nombre diferente, pero que usa la misma tecla o combinación de teclas que un atajo existente.
Para borrar una combinación de teclas, llama a Blockly.ShortcutRegistry.registry.unregister
y pasa el nombre de la combinación:
Blockly.ShortcutRegistry.registry.unregister('logFields');
No puedes modificar un atajo de teclado en el lugar. En su lugar, debes borrar el acceso directo existente y agregar uno nuevo. Por ejemplo:
// Get the existing shortcut. getRegistry returns an object keyed by shortcut name.
const allShortcuts = Blockly.ShortcutRegistry.registry.getRegistry();
const modLogFieldsShortcut = allShortcuts[logFieldsShortcut.name];
// Apply the shortcut only to math blocks,
modLogFieldsShortcut.preconditionFn = function (workspace, scope) {
return (scope.focusedNode instanceof Blockly.BlockSvg &&
scope.focusedNode.type.startsWith('math_'));
}
// Delete the existing shortcut and add the modified shortcut.
Blockly.ShortcutRegistry.registry.unregister(logFieldsShortcut.name);
Blockly.ShortcutRegistry.registry.register(modLogFieldsShortcut);
Accesos directos predeterminados
El registro de accesos directos se completa previamente con varios accesos directos. Puedes encontrarlos en https://github.com/google/blockly/blob/master/core/shortcut_items.ts.
Los accesos directos se definen en las funciones registerXxxx
.
Combinaciones de teclas para la navegación
El complemento de navegación con el teclado contiene combinaciones de teclas que permiten a los usuarios navegar por Blockly con el teclado, por ejemplo, con las teclas de flecha. La navegación con el teclado es fundamental para los usuarios que no pueden usar un mouse, como las personas con discapacidades visuales o motoras. También es útil para los usuarios avanzados que desean usar combinaciones de teclas para aumentar la eficiencia.