Scorciatoie da tastiera

Blockly gestisce un registro di scorciatoie da tastiera che mappano i tasti (o le combinazioni di tasti come ctrl-C) alle azioni. Il registro è precompilato con una serie di scorciatoie, come ctrl-C e meta-C per la copia. Puoi aggiungere e rimuovere scorciatoie dal registro.

Come funzionano le scorciatoie da tastiera

Il registro delle scorciatoie contiene oggetti che modellano le scorciatoie da tastiera. Quando l'utente preme un tasto (o una combinazione di tasti), Blockly:

  1. Controlla il registro per vedere se alla chiave si applicano scorciatoie. Se più di una scorciatoia utilizza il tasto, le scorciatoie vengono provate in ordine inverso di registrazione. ovvero viene provata per prima la scorciatoia registrata più di recente.

  2. Chiama la funzione preconditionFn della scorciatoia, che determina se la scorciatoia si applica alla situazione attuale. Ad esempio, la scorciatoia per copiare si applica ai blocchi, ma non allo spazio di lavoro. Se la scorciatoia non viene applicata, Blockly prova la scorciatoia successiva nell'elenco, se presente.

  3. Chiama la funzione callback della scorciatoia, che esegue l'azione della scorciatoia. Ad esempio, la scorciatoia per la copia crea una copia dell'oggetto attualmente selezionato, come un blocco. Se questa funzione restituisce true, l'elaborazione si interrompe. Se restituisce false, Blockly prova la scorciatoia successiva nell'elenco, se presente.

Ambito

Un oggetto Scope identifica il componente Blockly che ha lo stato attivo. Gli oggetti di ambito vengono passati a preconditionFn e callback, che li utilizzano per decidere se una scorciatoia si applica a un componente specifico e, in caso affermativo, come applicarla.

Per utilizzare un oggetto Scope, utilizza la relativa proprietà focusedNode. Si tratta di un oggetto che implementa IFocusableNode. Questa interfaccia viene implementata da tutti i componenti Blockly su cui l'utente può concentrarsi, inclusi workspace, blocchi, campi, commenti e i tuoi componenti personalizzati; per ulteriori informazioni, consulta Sistema di messa a fuoco.

Ad esempio, un preconditionFn potrebbe utilizzare focusedNode per garantire che una scorciatoia si applichi solo ai blocchi.

preconditionFn(workspace, scope) {
  return (scope.focusedNode instanceof Blockly.BlockSvg);
}

L'interfaccia KeyboardShortcut

Gli oggetti nel registro delle scorciatoie implementano l'interfaccia KeyboardShortcut. Contiene le seguenti proprietà.

name (obbligatorio)

Un nome univoco per la scorciatoia. Questo valore non viene mostrato agli utenti e non deve essere leggibile. Non deve essere tradotto.

const logFieldsShortcut = {
  name: 'logFields',
  // ...
};

preconditionFn (facoltativo)

Blockly chiama questa funzione per decidere se una scorciatoia si applica alla situazione attuale. Se restituisce true, Blockly chiama callback. Se restituisce false, Blockly ignora questa scorciatoia. Ad esempio:

const logFieldsShortcut = {
  // ...
  preconditionFn(workspace, scope) {
    // This shortcut only applies to blocks.
    return (scope.focusedNode instanceof Blockly.BlockSvg);
  },
  // ...
};

Una scorciatoia può omettere questa funzione se viene sempre applicata (non comune). Le scorciatoie non devono omettere questa funzione e poi agire in modo condizionale in callback. In questo modo, Blockly non può eseguire operazioni come la creazione di menu di aiuto contestuali che mostrano le scorciatoie applicabili.

callback (facoltativo)

Questa funzione esegue l'azione associata alla scorciatoia. Viene chiamato solo se preconditionFn restituisce true o non esiste. I suoi parametri sono:

  • workspace: il WorkspaceSvg attuale.
  • e: l'Event che ha avviato la scorciatoia.
  • shortcut: il KeyboardShortcut stesso.
  • scope: il Scope a cui si applica la scorciatoia.

Restituisce true se l'operazione ha esito positivo e false se non va a buon fine.

Ad esempio:

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;
  },
  // ...
};

Sebbene callback sia facoltativo, in genere non c'è motivo per non implementarlo.

keyCodes (facoltativo)

Un array di tasti (o combinazioni di tasti) che attivano questa scorciatoia. Per identificare i tasti, utilizza i codici tasto in Blockly.utils.KeyCodes. Ad esempio:

const logFieldsShortcut = {
  // ...
  keyCodes: [Blockly.utils.KeyCodes.L],
  // ...
};

Se vuoi mappare tasti aggiuntivi a una scorciatoia esistente, ad esempio se vuoi aggiungere tasti a una scorciatoia predefinita, puoi chiamare Blockly.ShortcutRegistry.registry.addKeyMapping. Questa situazione non è comune.

Combinazioni di tasti

Se la scorciatoia da tastiera viene attivata da una combinazione di tasti, ad esempio tenendo premuti Control e C contemporaneamente, crea un keycode serializzato chiamando 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
  // ...
};

Controllo e Meta

Su Windows, molte scorciatoie vengono attivate con il tasto Control. Su Mac, queste scorciatoie da tastiera utilizzano invece il tasto Command, che viene riconosciuto come keycode META. Per supportare entrambi i sistemi operativi, registra le scorciatoie con il codice tasto CTRL e il codice tasto 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 di implementazione

I gestori di eventi della tastiera di Blockly utilizzano la proprietà keycode di KeyboardEvent anche se è ritirata.

allowCollision (facoltativo)

Per impostazione predefinita, puoi registrare una sola scorciatoia per un determinato tasto o combinazione di tasti. Se imposti questa proprietà su true, puoi registrare un tasto (o una combinazione di tasti) anche se è già stata registrata una scorciatoia con lo stesso tasto (o combinazione di tasti).

Tieni presente che questa proprietà si applica solo quando si tenta di registrare questa scorciatoia. Non impedisce ad altre scorciatoie di utilizzare lo stesso tasto (o combinazione di tasti). La possibilità di registrarli dipende dal valore della proprietà allowCollision.

Indipendentemente dal numero di scorciatoie registrate per un determinato tasto o combinazione di tasti, ne verrà eseguita al massimo una. Le scorciatoie vengono provate nell'ordine inverso di registrazione (dall'ultima registrata alla prima registrata). Dopo che uno di questi restituisce true dal callback, non vengono provate altre scorciatoie.

metadati (facoltativo)

Si tratta di un oggetto arbitrario contenente informazioni aggiuntive. È disponibile per callback tramite il parametro shortcut.

Aggiungere, eliminare e modificare scorciatoie

Per aggiungere una nuova scorciatoia da tastiera, chiama Blockly.ShortcutRegistry.registry.register:

Blockly.ShortcutRegistry.registry.register(logFieldsShortcut);

Questa funzione ha un secondo parametro (allowOverrides) che ti consente di sostituire una scorciatoia esistente con lo stesso nome della tua scorciatoia. Tieni presente che questa operazione è diversa da KeyboardShortcut.allowCollision, che ti consente di aggiungere una scorciatoia con un nome diverso, ma utilizza lo stesso tasto o combinazione di tasti di una scorciatoia esistente.

Per eliminare una scorciatoia da tastiera, chiama Blockly.ShortcutRegistry.registry.unregister e passa il nome della scorciatoia:

Blockly.ShortcutRegistry.registry.unregister('logFields');

Non puoi modificare una scorciatoia da tastiera sul posto. Devi invece eliminare la scorciatoia esistente e aggiungerne una nuova. Ad esempio:

// 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);

Scorciatoie predefinite

Il registro delle scorciatoie è precompilato con una serie di scorciatoie. Puoi trovarli all'indirizzo https://github.com/google/blockly/blob/master/core/shortcut_items.ts. Le scorciatoie sono definite nelle funzioni registerXxxx.

Scorciatoie di navigazione da tastiera

Il plug-in di navigazione da tastiera contiene scorciatoie che consentono agli utenti di navigare in Blockly con la tastiera, ad esempio utilizzando i tasti freccia. La navigazione da tastiera è essenziale per gli utenti che non possono utilizzare un mouse, ad esempio quelli con disabilità motorie o visive. È utile anche per gli utenti esperti che potrebbero voler utilizzare le scorciatoie da tastiera per una maggiore efficienza.