キーボード ショートカット

Blockly は、キー(または ctrl-C などのキーの組み合わせ)をアクションにマッピングするキーボード ショートカットのレジストリを保持します。レジストリには、コピー用の ctrl-Cmeta-C など、多くのショートカットが事前に入力されています。レジストリにショートカットを追加したり、レジストリからショートカットを削除したりできます。

キーボード ショートカットの仕組み

ショートカット レジストリには、キーボード ショートカットをモデル化するオブジェクトが含まれています。ユーザーがキー(またはキーの組み合わせ)を押すと、Blockly は次の処理を行います。

  1. レジストリをチェックして、キーに適用されるショートカットがあるかどうかを確認します。複数のショートカットでキーが使用されている場合は、登録の逆順でショートカットが試されます。つまり、最後に登録されたショートカットが最初に試行されます。

  2. ショートカットの preconditionFn 関数を呼び出します。この関数は、ショートカットが現在の状況に適用されるかどうかを判断します。たとえば、コピーのショートカットはブロックには適用されますが、ワークスペースには適用されません。ショートカットが適用されない場合、Blockly はリスト内の次のショートカットを試します(存在する場合)。

  3. ショートカットの callback 関数を呼び出し、ショートカットのアクションを実行します。たとえば、コピー ショートカットは、現在フォーカスされているオブジェクト(ブロックなど)のコピーを作成します。この関数が true を返すと、処理が停止します。false が返された場合、Blockly はリスト内の次のショートカットを試します(存在する場合)。

範囲

Scope オブジェクトは、現在フォーカスされている Blockly コンポーネントを識別します。スコープ オブジェクトは preconditionFncallback に渡され、それらはスコープ オブジェクトを使用して、ショートカットが特定のコンポーネントに適用されるかどうか、適用される場合はどのように適用されるかを決定します。

Scope オブジェクトを使用するには、その focusedNode プロパティを使用します。これは IFocusableNode を実装するオブジェクトです。このインターフェースは、ワークスペース、ブロック、フィールド、コメント、独自のカスタム コンポーネントなど、ユーザーがフォーカスできるすべての Blockly コンポーネントによって実装されます。詳細については、フォーカス システムをご覧ください。

たとえば、preconditionFnfocusedNode を使用して、ショートカットがブロックにのみ適用されるようにします。

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

KeyboardShortcut インターフェース

ショートカット レジストリ内のオブジェクトは、KeyboardShortcut インターフェースを実装します。これには次のプロパティが含まれます。

name(必須)

ショートカットの一意の名前。これはユーザーには表示されず、人が読める形式である必要はありません。翻訳しないでください。

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

preconditionFn(省略可)

Blockly はこの関数を呼び出して、ショートカットが現在の状況に適用されるかどうかを判断します。true を返すと、Blockly は callback を呼び出します。false を返すと、Blockly はこのショートカットを無視します。次に例を示します。

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

ショートカットが常に適用される場合(一般的ではありません)、ショートカットはこの関数を省略できます。ショートカットでこの関数を省略し、callback で条件付きでアクションを実行することはできません。そうすることで、Blockly が適用可能なショートカットを表示するコンテキスト ヘルプ メニューを作成するなどの処理を行うのを防ぐことができます。

callback(省略可)

この関数は、ショートカットに関連付けられたアクションを実行します。これは、preconditionFntrue を返すか、存在しない場合にのみ呼び出されます。パラメータは次のとおりです。

  • workspace: 現在の WorkspaceSvg
  • e: ショートカットを開始した Event
  • shortcut: KeyboardShortcut 自体。
  • scope: ショートカットが適用される Scope

成功した場合は true、失敗した場合は false を返します。

次に例を示します。

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

callback は省略可能ですが、通常は実装しない理由はありません。

keyCodes(省略可)

このショートカットを有効にするキー(またはキーの組み合わせ)の配列。キーを識別するには、Blockly.utils.KeyCodes のキーコードを使用します。次に例を示します。

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

追加のキーを既存のショートカットにマッピングする場合(たとえば、デフォルトのショートカットにキーを追加する場合)は、Blockly.ShortcutRegistry.registry.addKeyMapping を呼び出すことができます。これは一般的ではありません。

キーの組み合わせ

キーボード ショートカットが ControlC を同時に押すなどのキーの組み合わせで有効になる場合は、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 と Meta

Windows では、多くのショートカットが Control キーで有効になります。Mac では、これらのキーボード ショートカットは Command キーを使用します。これは META キーコードとして認識されます。両方のオペレーティング システムをサポートするには、CTRL キーコードと 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],
  // ...
};

実装に関する注意事項

Blockly のキーボード イベント ハンドラは、非推奨の KeyboardEventkeycode プロパティを使用します。

allowCollision(省略可)

デフォルトでは、特定のキーまたはキーの組み合わせに登録できるショートカットは 1 つのみです。このプロパティを true に設定すると、同じキー(またはキーの組み合わせ)のショートカットがすでに登録されている場合でも、キー(またはキーの組み合わせ)を登録できます。

このプロパティは、このショートカットを登録しようとした場合にのみ適用されます。他のショートカットが同じキー(またはキーの組み合わせ)を使用することを防ぐことはできません。登録できるかどうかは、allowCollision プロパティの値によって異なります。

特定のキーまたはキーの組み合わせに登録されているショートカットの数に関係なく、実行されるのは最大で 1 つです。ショートカットは登録の逆順(最後に登録されたものから最初に登録されたもの)で試行されます。いずれかのコールバックから true が返されると、他のショートカットは試行されません。

メタデータ(省略可)

追加情報を含む任意のオブジェクト。shortcut パラメータを介して callback で使用できます。

ショートカットの追加、削除、変更

新しいキーボード ショートカットを追加するには、Blockly.ShortcutRegistry.registry.register を呼び出します。

Blockly.ShortcutRegistry.registry.register(logFieldsShortcut);

この関数には、ショートカットと同じ名前の既存のショートカットを置き換えることができる 2 番目のパラメータ(allowOverrides)があります。これは KeyboardShortcut.allowCollision とは異なります。KeyboardShortcut.allowCollision では、別の名前のショートカットを追加できますが、既存のショートカットと同じキーまたはキーの組み合わせが使用されます。

キーボード ショートカットを削除するには、Blockly.ShortcutRegistry.registry.unregister を呼び出してショートカットの名前を渡します。

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

キーボード ショートカットをその場で変更することはできません。代わりに、既存のショートカットを削除して新しいショートカットを追加する必要があります。次に例を示します。

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

デフォルトのショートカット

ショートカット レジストリには、多数のショートカットが事前に入力されています。これらは https://github.com/google/blockly/blob/master/core/shortcut_items.ts で確認できます。ショートカットは registerXxxx 関数で定義されます。

キーボード ナビゲーションのショートカット

キーボード ナビゲーション プラグインには、矢印キーなどを使用してキーボードで Blockly を操作できるショートカットが含まれています。キーボード ナビゲーションは、運動機能や視覚に障がいがあるなど、マウスを使用できないユーザーにとって不可欠です。また、効率性を高めるためにキーボード ショートカットを使用したいパワーユーザーにも便利です。