Version: 2023.1
言語: 日本語
イベントによる動作の制御
イベントの処理

ディスパッチイベント

UI Toolkit は、オペレーティングシステムやスクリプトからのイベントをリッスンし、EventDispatcher でこれらのイベントをビジュアル要素にディスパッチします。イベントディスパッチャーは、送信する各イベントに適切なディスパッチ方法を決定します。方法がきまると、ディスパッチャーはそれを実行します。

ビジュアル要素は、いくつかのイベントに対してデフォルトの動作を実装します。追加のイベントを作成して実行する場合もあります。例えば、MouseMoveEvent は追加の MouseEnterEventMouseLeaveEvent を作成することがあります。これらの追加イベントはキューに置かれ、現在のイベントが完了した後に処理されます。例えば、MouseMoveEventMouseEnterEventMouseLeaveEvent イベントの前に完了します。

イベントタイプのディスパッチ動作

各イベントタイプには、それぞれのディスパッチ動作があります。各イベントタイプの動作は、3 つの段階に分かれます。

  • トリクルダウン: トリクルダウンの段階でエレメントに送られるイベント。
  • バブルアップ: バブルアップの段階で要素に送られるイベント。
  • キャンセル可能: このタイプのイベントは、デフォルトのアクションの実行をキャンセル、停止、回避することができます。

各イベントタイプのディスパッチ動作の一覧は、イベントのリファレンス ページ](UIE-Events-Reference.html) を参照してください。

イベント伝播

イベントターゲットを選択すると、イベントディスパッチャーはイベントの伝搬 (propagation) パスを計算します。伝搬経路は、イベントを受け取るビジュアル要素が順序通りに並べられたリストです。伝搬経路は次の順序で発生します。

  1. パスは、ビジュアル要素ツリーのルートから始まり、ターゲットに向かって下降します。これは トリクルダウンの段階 です。
  2. イベントターゲットがイベントを受け取ります。
  3. その後、イベントはツリーをルートに向かって上昇していきます。これが バブルアップの段階 です。
伝搬経路
伝搬経路

ほとんどのイベントタイプは、伝搬経路上のすべての要素に送られます。いくつかのイベントタイプはバブルアップの段階をスキップし、いくつかのイベントタイプはイベントターゲットのみに送信されます。

要素を隠したり無効にしたりするとその要素はイベントを受け取りません。隠したり無効にした要素の先祖や子孫にはイベントが伝わります。

あるイベントが伝搬経路をたどると、Event.currentTarget はそのイベントを処理する要素に更新されます。イベントのコールバック関数の中には、ディスパッチの動作を記録する 2 つのプロパティがあります。

  • Event.currentTarget は、コールバックが登録されたビジュアル要素です。
  • Event.target は、イベントが発生する要素で、例えばマウス直下の要素などです。

イベントターゲット

イベントのターゲットは、イベントの種類によって異なります。マウスイベントの場合、ターゲットは通常、直接マウスの下にある選択される可能性が最も高い要素です。キーボードイベントの場合、ターゲットは現在フォーカスされている要素です。

UI Toolkit のイベントには target プロパティがあり、これには、イベントが発生した要素への参照が含まれます。オペレーティングシステムから発生するほとんどのイベントでは、ディスパッチプロセスが自動的にイベントターゲットを見つけます。

ターゲット要素は EventBase.target に格納されており、ディスパッチプロセス中は変更されません。プロパティ Event.currentTarget は、現在イベントを処理しているビジュアル要素に更新されます。

選択モードとカスタムシェイプ

ほとんどのマウスイベントは、選択 (picking) モードを使用してターゲットを決定します。VisualElement クラスは以下の値をサポートする pickingMode プロパティを持っています。

  • PickingMode.Position(デフォルト): 位置の矩形に基づいて選択します。
  • PickingMode.Ignore: マウスイベントの結果によって選択することを防ぎます。

VisualElement.ContainsPoint() メソッドをオーバーライドすると、カスタムの交差ロジックを行えます。

マウスをキャプチャする

MouseDownEvent の後、一部の要素では、カーソルが要素の上に乗っていなくても、その後のすべてのマウスイベントを確実に受け取るために、ポインター位置を捉える必要があります。例えば、ボタンやスライダー、スクロールバーをクリックしたときなどです。

マウスをキャプチャするには、element.CaptureMouse()MouseCaptureController.CaptureMouse() を呼び出します。

マウスをリリースするには MouseCaptureController.ReleaseMouse() を呼び出します。CaptureMouse() の呼び出し時に他の要素がすでにマウスをキャプチャしている場合、その要素は MouseCaptureOutEvent を受け取り、キャプチャしなくなります。

どのような時でも、アプリケーションの 1 つの要素だけがキャプチャできます。要素はキャプチャできますが、マウスホイールイベントを除くすべての後続のマウスイベントのターゲットにもなります。これは、まだターゲットが設定されていないマウスイベントにのみ適用され、ターゲットの決定はディスパッチプロセスに依存します。

詳しくは、キャプチャーイベント を参照してください。

フォーカスリングとタブの順序

各 UI Toolkit パネルには、要素のフォーカス順序を定義するフォーカスリングがあります。デフォルトでは、要素のフォーカス順序は、ビジュアル要素ツリーで深さ優先探索 (DFS) によって決まります。例えば、下に描かれているツリーのフォーカス順序は、F、B、A、D、C、E、G、I、H です。

フォーカス順序
フォーカス順序

イベントによっては、どの要素にフォーカスがあるかを決定するためにフォーカス順序を使用するものがあります。例えば、キーボードイベントのターゲットは、フォーカスされている要素です。

  • ビジュアル要素がフォーカス可能かを制御するには、focusable プロパティを使用します。デフォルトで VisualElements はフォーカス可能ではありませんが、TextField などのサブクラスの中には、デフォルトでフォーカス可能なものがあります。

フォーカスの順序を制御するには、以下のように tabIndex プロパティを使用します (tabIndex のデフォルト値は 0)。

  • tabIndex が負の値の場合は、要素でタブを使うことはできません。
  • focus-index が 0 の場合、要素はフォーカスリングアルゴリズムによって決定されたデフォルトのフォーカス順序を維持します。
  • tabIndex が正の場合、その要素は tabIndexが 0 (tabIndex = 0) か、tabIndex 値がそれ自体より小さい他の要素の前に置かれます。

その他の参考資料

イベントによる動作の制御
イベントの処理