APL キーボード



キーボード

キーボードのサポートについて

キーボードのキーが押下され、解放されるたびに、KeyDownおよびKeyUpのキーボードイベントが生成されます。通常、これら2つのイベントはセットになっており、KeyDownの後には(いずれは)対応するKeyUpが発生します。以下の点に注意してください。

  • すべてのキーでKeyUpおよびKeyDownのイベントが生成されます。これには、ShiftキーやControlキーなどの修飾キーも含まれます。
  • オートリピートをサポートしているキーボード(キー)では、キーが押下されている間、KeyDownイベントが連続して生成され、キーが解放されるとKeyUpイベントが1回生成されます。オートリピートがサポートされていないキーもあります。たとえば、Shiftキーではオートリピートは行われません。
  • オペレーティングシステムの実装によっては、KeyDownイベントの後にKeyUpイベントが必ずしも1対1で生成されない場合があります。

KeyUpとKeyDownのキーボードイベントは、現在フォーカスがあるコンポーネントに渡されます。コンポーネントに割り当てられているカスタムキーボードハンドラーでは、コマンドシークエンス実行のトリガーとなるキーが指定されます。また、カスタムキーボードハンドラーにより、キーボードイベントを他のコンポーネントに渡してさらに処理する必要があるかどうかが決まります。

カスタムキーボードハンドラーで処理されないキーボードイベントは、コンポーネント階層の次のコンポーネントに渡されます。コンポーネントハンドラーで処理されないイベントは、ドキュメントのカスタムキーボードハンドラーに渡されます。どのコンポーネントにもフォーカスが存在しない場合、ドキュメントキーボードハンドラーがすべてのキーボードイベントを受け取ります。

簡単な例でこの動作を説明します。1つのSequenceがあり、一連のTouchWrapperボタンが縦に並んでいるとします。そのうちの1つのボタンにフォーカスがあり、ここでユーザーが「w」キーを押すと、次のような処理が行われます。

  1. keyboard.key = "w"のKeyDownイベントが作成されます。
  2. TouchWrapperコンポーネントのカスタムキーボードハンドラーが存在する場合は、そのハンドラーにイベントが渡されます(この例では、存在しないものとします)。
  3. コンポーネントの階層で、このTouchWrapperのすぐ上にあるコンポーネントはSequenceです。
  4. Sequenceのカスタムキーボードハンドラーが存在する場合は、そのハンドラーにイベントが渡されます(この例では、存在しないものとします)。
  5. ドキュメントのカスタムキーボードハンドラーが存在する場合は、そのハンドラーにイベントが渡されます。

別のキー(MediaPlayPauseなど)では、Sequenceで処理されず、すぐにカスタムドキュメントキーハンドラーに渡される場合があります。

キーボードイベント

キーボードイベントは、フォーカスのあるコンポーネントまたはドキュメントに送信されるメッセージです。キーボードイベントでは、キーボードのどのキーが押下または解放されたかを明示してイベントが生成されます。

キーボードイベントには、keyDownとkeyUpの2種類があります。keyDownイベントは、キーボードのキーが押下された場合またはキーがオートリピートされた場合に必ず生成されます。keyDownイベントは、すべてのキーで生成されます。たとえば、Shiftキーを押した場合もkeyDownイベントが生成されます。keyUpイベントは、キーボードのキーが解放された場合に必ず生成されます。

キーボードイベントのデータには、どのキーが押下されたか、オートリピートによるものかどうか、そのキーと同時に押下された修飾キーが含まれます。例として、キーボードの「6」キーを押下し続けた場合は、次のようになります。

{
  "key": "6",
  "code": "Digit6",
  "repeat": true,
  "shiftKey": false,
  "altKey": false,
  "ctrlKey": false
  "metaKey": false,
}

キーボードイベントでは、以下のプロパティが報告されます。

名前 説明
altKey ブール値 イベント発生時にAltキーが押下されていた場合はtrueになります(OS XではOptionキー)。
code 文字列 キーボードの物理キーの文字列表現です。
ctrlKey ブール値 イベント発生時にControlキーが押下されていた場合はtrueになります。
key 文字列 キーボードで押下されたキーの文字列表現です。修飾キーも対象となります。
metaKey ブール値 イベント発生時にメタキーが押下されていた場合はtrueになります。Windows用キーボードの場合はWindowsキー、Mac用キーボードの場合はcommandキーです。
repeat ブール値 オートリピートになるようにキーが押し続けられている場合はtrueになります。
shiftKey ブール値 イベント発生時にShiftキーが押下されていた場合はtrueになります。

altKey

altKeyのブール値は、このイベントの発生時にAltキーが押下されていた場合はtrueになります。OS Xの場合は、AltキーではなくOptionキーになります。キーボードのAltキーを押下すると、それ自体のキーボードイベントが生成されます。たとえば、OS X用キーボードでOptionキーと4キーを同時に押下すると、次のようなキーボードイベントが生成されます。

KeyDown( code='AltLeft', key='Alt', repeat=false, altKey=true, ctrl/shift/metaKey=false )
KeyDown( code='Digit4', key='¢', repeat=false, altKey=true, ctrl/shift/metaKey=false )
KeyUp( code='Digit4', key='¢', repeat=false, altKey=true, ctrl/shift/metaKey=false )
KeyUp( code='AltLeft', key='Alt', repeat=false, altKey=false, ctrl/shift/metaKey=false )

code

codeプロパティは、押下されたキーボードの物理キーを表します。codeの値は文字列です。この値の定義は、W3C勧告候補のUI Events KeyboardEvent code valuesに記載されています。

codeの値の例を以下に示します。

Digit2               「2」キー
KeyF                 「F」キー
Backslash            「\」キー
Semicolon            「;」キー
AltLeft              スペースキーの左の「Alt」キー
ShiftRight           スペースキーの右の「Shift」キー
MediaPlayPause       メディア再生/一時停止キー(通常はリモコンにあるもの)
AudioVolumeDown      音量下キー

ctrlKey

ctrlKeyのブール値は、このイベントの発生時にControlキーが押下されていた場合はtrueになります。キーボードのControlキーを押下すると、それ自体のキーボードイベントが生成されます。たとえば、OS X用キーボードでControlキーとmキーを同時に押下すると、次のようなキーボードイベントが生成されます。

KeyDown( code='ControlLeft', key='Control', repeat=false, ctrlKey=true, alt/shift/metaKey=false )
KeyDown( code='KeyM', key='m', repeat=false, ctrlKey=true, alt/shift/metaKey=false )
KeyUp( code='KeyM', key='m', repeat=false, ctrlKey=true, alt/shift/metaKey=false )
KeyUp( code='ControlLeft', key='Control', repeat=false, ctrlKey=false, alt/shift/metaKey=false )

key

keyプロパティは、次のいずれかとなります。

  1. ユーザーが入力した文字に対応するキーの文字列。ロケール、修飾キー、有効になっているキーボードオーバーライドも考慮されます。この場合のkeyプロパティは、テキスト入力領域に入力されたテキストと考えることができます。
  2. W3C勧告候補で定義されている名前付きキーの属性値。この場合のkeyプロパティは、そのキーで何ができるかを示す便宜上のラベル(「Tab」など)と考えることができます。

keyの値は文字列であり、W3C勧告候補のUI Events KeyboardEvent key valuesで定義されています。

keyの値の例を以下に示します。

6                 数字の「6」
&                 Shiftを併用した「7」キー(USキーボードの場合)
¢                 Altを併用した「4」キー(OS Xの場合)
Delete            前方削除
Shift             Shiftキー(左右は問いません)
BrightnessDown    輝度調整キー
MediaPlayPause    メディア再生/一時停止キー(通常はリモコンにあるもの)

次のkey値は、今後のバージョンのAPL用に予約されています: 「GoBack」、「Enter」、「Tab」、「ArrowUp」、「ArrowDown」、「ArrowRight」、「ArrowLeft」、「Home」、「End」

metaKey

metaKeyのブール値は、このイベントの発生時にメタキーが押下されていた場合はtrueになります。キーボードのメタキーを押下すると、それ自体のキーボードイベントが生成されます。たとえば、OS X用キーボードでメタキーと「/」キーを同時に押下すると、次のようなキーボードイベントが生成されます。

KeyDown( code='MetaLeft', key='Meta', repeat=false, metaKey=true, alt/ctrl/shiftKey=false )
KeyDown( code='Slash', key='/', repeat=false, metaKey=true, alt/ctrl/shiftKey=false )
KeyUp( code='MetaLeft', key='Meta', repeat=false, metaKey=false, alt/ctrl/shiftKey=false )

このOS Xの例で、スラッシュ(/)キーについてはKeyUpイベントが発生していないことに注意してください。このイベントはオペレーティングシステムで吸収され、コンポーネントには提供されません。一般に、修飾キーが含まれている場合には特に、KeyUpイベントとKeyDownイベントがすべて渡されるという前提で考えるのは注意が必要です。

repeat

ブール値のrepeatは、KeyDownイベントがオートリピートの場合にtrueになります。1つのキーの最初のKeyDownイベントでは、repeatがfalseになります。同じキーのそれ以降のKeyDownイベントでは、repeatがtrueに設定されます。

次の点に注意してください。(a)リピートの間隔はデバイスで制御されます。(b)repeatイベントはどのデバイスでも送信されるわけではありません。(c)修飾キーなどの一部のキーではrepeatイベントが送信されません。

shiftKey

shiftKeyのブール値は、このイベントの発生時にShiftキーが押下されていた場合にtrueになります。キーボードのShiftキーを押下すると、それ自体のキーボードイベントが生成されます。たとえば、OS X用キーボードでShiftキーとmキーを同時に押下すると、次のようなキーボードイベントが生成されます。

KeyDown( code='ShiftLeft', key='Shift', repeat=false, shiftKey=true, alt/ctrl/metaKey=false )
KeyDown( code='KeyM', key='M', repeat=false, shiftKey=true, alt/ctrl/metaKey=false )
KeyUp( code='KeyM', key='M', repeat=false, shiftKey=true, alt/ctrl/metaKey=false )
KeyUp( code='ShiftLeft', key='Shift', repeat=false, shiftKey=false, alt/ctrl/metaKey=false )

キーボードイベントハンドラー

APLドキュメントでは、2つの方法でキーストロークが処理されます。1つ目は、アクション可能なコンポーネントに関連付けられているデフォルトの動作によるものです。これには、TouchWrapperScrollViewSequencePager、フォーカスの選択(アクション可能なコンポーネント)などがあります。2つ目は、アクション可能なコンポーネントおよびベースドキュメントに割り当てられたキーボードイベントハンドラーによるものです。

アクション可能なコンポーネントおよびルートAPLドキュメントにはそれぞれ、標準のプロパティに加えて、以下のプロパティがあります。

プロパティ デフォルト スタイル設定 動的 説明
handleKeyDown キーハンドラーの配列 [] キー押下のイベントを確認するためのハンドラーです。
handleKeyUp キーハンドラーの配列 [] キー解放のイベントを確認するためのハンドラーです。

単一のキーハンドラーは、以下のプロパティを持つオブジェクトです。

プロパティ デフォルト 説明
commands コマンド配列 [] このハンドラーが呼び出された場合に実行されるコマンドです。
propagate ブール値 false trueの場合、処理されたイベントがバブリングされます。
when ブール値 true trueの場合、このハンドラーが呼び出されます。

キーハンドラーの配列は順番にチェックされます。when句がtrueになっている最初のキーハンドラーが呼び出され、そのハンドラーのコマンドが実行されます。propagateプロパティがtrueの場合、そのイベントは次のコンポーネントに伝わります(配列の次のハンドラーではありません)。このバブリングは即座に発生することに注意してください。通常はコマンドが実行される前になります。

たとえば、2Dのゲーム用コントローラーに対応するには(画面上で画像を動かすなど)、次のようにTouchWrapperを拡張できます。

{
  "type": "TouchWrapper",
  "bind": [
    { "name": "x", "value": 0 },
    { "name": "y", "value": 0 }
  ],
  "handleKeyDown": [
    {
      "when": "${event.keyboard.code == 'KeyW'}",
      "commands": [
        {
          "type": "SetValue",
          "property": "y",
          "value": "${y - 10}"
        },
        {
          "type": "SetValue",
          "property": "transform",
          "value": [ { "translateX": "${x}", "translateY": "${y}" } ]
        }
      ]
    },
    {
      "when": "${event.keyboard.code == 'KeyS'}",
      "commands": [
        {
          "type": "SetValue",
          "property": "y",
          "value": "${y + 10}"
        },
        {
          "type": "SetValue",
          "property": "transform",
          "value": [ { "translateX": "${x}", "translateY": "${y}" } ]
        }
      ]
    },
    {
      "when": "${event.keyboard.code == 'KeyA'}",
      "commands": [
        {
          "type": "SetValue",
          "property": "x",
          "value": "${x - 10}"
        },
        {
          "type": "SetValue",
          "property": "transform",
          "value": [ { "translateX": "${x}", "translateY": "${y}" } ]
        }
      ]
    },
    {
      "when": "${event.keyboard.code == 'KeyD'}",
      "commands": [
        {
          "type": "SetValue",
          "property": "x",
          "value": "${x + 10}"
        },
        {
          "type": "SetValue",
          "property": "transform",
          "value": [ { "translateX": "${x}", "translateY": "${y}" } ]
        }
      ]
    },
    {
      "when": "${event.keyboard.code == 'Enter'}",
      "description": "通常の'Enter'動作をブロック"
    }
  ],
  "items": {
    "type": "Image",
    "source": "...."
  }
}