Blockly は、キー(または ctrl-C
などのキーの組み合わせ)をアクションにマッピングするキーボード ショートカットのレジストリを保持します。レジストリには、コピー用の ctrl-C
や meta-C
など、多くのショートカットが事前に入力されています。レジストリにショートカットを追加したり、レジストリからショートカットを削除したりできます。
キーボード ショートカットの仕組み
ショートカット レジストリには、キーボード ショートカットをモデル化するオブジェクトが含まれています。ユーザーがキー(またはキーの組み合わせ)を押すと、Blockly は次の処理を行います。
レジストリをチェックして、キーに適用されるショートカットがあるかどうかを確認します。複数のショートカットでキーが使用されている場合は、登録の逆順でショートカットが試されます。つまり、最後に登録されたショートカットが最初に試行されます。
ショートカットの
preconditionFn
関数を呼び出します。この関数は、ショートカットが現在の状況に適用されるかどうかを判断します。たとえば、コピーのショートカットはブロックには適用されますが、ワークスペースには適用されません。ショートカットが適用されない場合、Blockly はリスト内の次のショートカットを試します(存在する場合)。ショートカットの
callback
関数を呼び出し、ショートカットのアクションを実行します。たとえば、コピー ショートカットは、現在フォーカスされているオブジェクト(ブロックなど)のコピーを作成します。この関数がtrue
を返すと、処理が停止します。false
が返された場合、Blockly はリスト内の次のショートカットを試します(存在する場合)。
範囲
Scope
オブジェクトは、現在フォーカスされている Blockly コンポーネントを識別します。スコープ オブジェクトは preconditionFn
と callback
に渡され、それらはスコープ オブジェクトを使用して、ショートカットが特定のコンポーネントに適用されるかどうか、適用される場合はどのように適用されるかを決定します。
Scope
オブジェクトを使用するには、その focusedNode
プロパティを使用します。これは IFocusableNode
を実装するオブジェクトです。このインターフェースは、ワークスペース、ブロック、フィールド、コメント、独自のカスタム コンポーネントなど、ユーザーがフォーカスできるすべての Blockly コンポーネントによって実装されます。詳細については、フォーカス システムをご覧ください。
たとえば、preconditionFn
は focusedNode
を使用して、ショートカットがブロックにのみ適用されるようにします。
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(省略可)
この関数は、ショートカットに関連付けられたアクションを実行します。これは、preconditionFn
が true
を返すか、存在しない場合にのみ呼び出されます。パラメータは次のとおりです。
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
を呼び出すことができます。これは一般的ではありません。
キーの組み合わせ
キーボード ショートカットが Control
と C
を同時に押すなどのキーの組み合わせで有効になる場合は、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 のキーボード イベント ハンドラは、非推奨の KeyboardEvent
の keycode
プロパティを使用します。
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 を操作できるショートカットが含まれています。キーボード ナビゲーションは、運動機能や視覚に障がいがあるなど、マウスを使用できないユーザーにとって不可欠です。また、効率性を高めるためにキーボード ショートカットを使用したいパワーユーザーにも便利です。