# 画面設計書 36-入力イベント設定ダイアログ

## 概要

本ドキュメントは、Godot Engineエディタにおける入力イベント設定ダイアログ（InputEventConfigurationDialog）の画面設計を記述する。このダイアログはプロジェクト設定のインプットマップでアクションに入力イベントをバインドする際に使用され、キーボード、マウス、ジョイパッドの入力設定を構成できる。

### 本画面の処理概要

このダイアログ画面では、ゲームアクションにバインドする入力イベントを対話的に設定する。リアルタイムの入力リスニング機能と、手動での入力選択機能の両方を提供し、修飾キー、デバイス選択、キーモードなどの詳細設定も可能である。

**業務上の目的・背景**：ゲーム開発において、プレイヤーの入力をゲーム内アクションにマッピングすることは基本的な要件である。WASDキーによる移動、スペースキーによるジャンプ、マウスクリックによる攻撃など、多様な入力デバイスからのイベントを柔軟に設定できる必要がある。このダイアログは、キーコード（論理キー）、物理キーコード（キー位置）、Unicodeキーラベルの3つのキーモードをサポートし、国際化対応や特定のキーボードレイアウトへの対応を可能にする。

**画面へのアクセス方法**：プロジェクト設定→インプットマップタブで、アクションに対して「+」ボタンをクリックするか、既存の入力イベントをダブルクリックしてアクセスする。

**主要な操作・処理内容**：
1. 入力イベントのリアルタイムリスニング（EventListenerLineEdit）
2. 入力リストからの手動選択（キーボード/マウス/ジョイパッド）
3. 修飾キーの設定（Alt/Shift/Ctrl/Meta）
4. Command/Controlの自動リマップ設定
5. キーモードの選択（Keycode/Physical Keycode/Unicode）
6. キー位置の選択（Unspecified/Left/Right）
7. デバイスの選択（All Devices または特定デバイス）
8. 設定の確定

**画面遷移**：
- 遷移元：インプットマップエディタ（ActionMapEditor）
- 遷移先（確定時）：インプットマップエディタに戻り、設定した入力イベントが追加/更新される
- 遷移先（キャンセル時）：インプットマップエディタに戻る

**権限による表示制御**：allowed_input_typesにより、表示される入力タイプ（キー/マウス/ジョイパッドボタン/ジョイパッド軸）が制御される。イベントタイプに応じて追加オプション（修飾キー、デバイス選択、キーモード、位置）の表示/非表示が切り替わる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| F-050 | インプットマップ | 主機能 | アクションへの入力イベントバインド |
| F-051 | イベントリスニング | 補助機能 | リアルタイム入力検出 |
| F-052 | 入力設定 | 補助機能 | 修飾キー/デバイス/キーモード設定 |

## 画面種別

登録・編集（モーダルダイアログ）

## URL/ルーティング

該当なし（デスクトップアプリケーションのモーダルダイアログ）

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 必須 | 説明 |
|--------|----------|---------|------|------|
| 初期イベント | 入力 | Ref<InputEvent> | オプション | 編集対象の既存イベント |
| アクション名 | 入力 | String | オプション | 表示用のアクション名 |
| 許可入力タイプ | 入力 | int | 必須 | INPUT_KEY等のビットマスク |
| リスニング入力 | 入力 | InputEvent | オプション | リアルタイム検出された入力 |
| 入力リスト選択 | 入力 | int | オプション | ツリーアイテム選択 |
| 修飾キー | 入力 | bool[4] | オプション | Alt/Shift/Ctrl/Meta |
| 自動リマップ | 入力 | bool | オプション | Command/Control自動リマップ |
| キーモード | 入力 | KeyMode | オプション | Keycode/Physical/Unicode |
| キー位置 | 入力 | KeyLocation | オプション | Unspecified/Left/Right |
| デバイスID | 入力 | int | オプション | -1=All, 0-7=特定デバイス |
| 設定済みイベント | 出力 | Ref<InputEvent> | - | get_event()で取得 |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| イベントテキスト | ラベル | 現在設定されているイベントのテキスト表示 |
| イベントリスナー | テキスト入力 | リアルタイム入力検出用 |
| 検索フィルター | テキスト入力 | 入力リストのフィルタリング |
| 入力リストツリー | ツリービュー | Keyboard Keys/Mouse Buttons/Joypad Buttons/Joypad Axes |
| Additional Options | コンテナ | 追加設定エリア |
| Device | ドロップダウン | All Devices / Device 0-7 |
| 修飾キーチェックボックス | チェックボックス群 | Alt/Shift/Ctrl/Meta |
| Command/Control(auto) | チェックボックス | プラットフォーム自動リマップ |
| Key Mode | ドロップダウン | Keycode/Physical Keycode/Key Label |
| Physical Location | ドロップダウン | Unspecified/Left/Right |

## イベント仕様

### 1-入力リスニング

EventListenerLineEditに入力すると、_on_listen_input_changed()が呼び出される。受信したイベントは許可タイプとの照合が行われ、有効な場合は_set_event()で設定される。キーイベントの場合、現在のキーモードに応じてkeycode/physical_keycode/key_labelのいずれかのみが保持される。

### 2-入力リスト検索

input_list_searchにテキストを入力すると、_search_term_updated()→_update_input_list()が呼び出され、入力リストがフィルタリングされる。検索は大文字小文字を区別しない。

### 3-入力リスト選択

input_list_treeでアイテムを選択すると、_input_list_item_selected()が呼び出される。選択されたアイテムのタイプに応じて（INPUT_KEY/MOUSE_BUTTON/JOY_BUTTON/JOY_MOTION）、対応するInputEventが生成され、_set_event()で設定される。修飾キーの状態は保持される。

### 4-修飾キートグル

mod_checkboxesのいずれかをトグルすると、_mod_toggled()が呼び出され、イベントの修飾キー状態が更新される。autoremap_command_or_controlがオンの場合、Ctrl/Metaチェックボックスは無効化される。

### 5-Command/Control自動リマップトグル

autoremap_command_or_control_checkboxをトグルすると、_autoremap_command_or_control_toggled()が呼び出される。オンの場合、プラットフォームに応じてCommand/Controlが自動的にリマップされ、Ctrl/Metaチェックボックスは非表示になる。

### 6-キーモード選択

key_modeで選択を変更すると、_key_mode_selected()が呼び出される。original_eventからkeycodeまたはphysical_keycodeまたはkey_labelを取得し、他の値をKey::NONEにリセットする。

### 7-キー位置選択

key_locationで選択を変更すると、_key_location_selected()が呼び出される。修飾キー（Shift/Ctrl/Alt/Meta）の物理キーコード使用時のみ有効。

### 8-デバイス選択変更

device_id_optionで選択を変更すると、_device_selection_changed()が呼び出され、イベントのデバイスIDが更新される。選択インデックス0=All Devices(-1)、1-8=Device 0-7。

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| OKボタン押下 | project.godot | UPDATE | インプットマップの入力イベント追加/更新 |

### テーブル別更新項目詳細

#### project.godot（インプットマップセクション）

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| UPDATE | input/{action}/events | get_event()の戻り値 | InputEvent配列に追加 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| - | 情報 | No Event Configured | イベント未設定時 |
| - | 情報 | Event Configuration for "{action}" | アクション名指定時のタイトル |
| - | 情報 | Event Configuration | アクション名未指定時のタイトル |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 無効なキーイベント（keycode=NONE, physical=NONE, label=NONE） | イベントをクリアし、追加オプションを非表示にする |
| 許可されていない入力タイプ | _on_listen_input_changed()が早期リターン |
| ツリー構造の不整合（input_type=0） | _set_event()が早期リターン |

## 備考

- ダイアログの最小サイズは800 * EDSCALEピクセル（幅）に設定
- ポップアップサイズは(0, 400) * EDSCALE
- 新規イベント設定時、Physical Keycode（KEYMODE_PHY_KEYCODE）がデフォルトで選択される（QWERTY以外のキーボードレイアウトでの動作を考慮）
- デバイスは-1（All Devices）がデフォルト
- キー位置は0（Unspecified）がデフォルト
- 修飾キー名はプラットフォームにより異なる：macOS=Option/Command、Windows=Alt/Windows、その他=Alt/Meta
- 入力リストツリーのカテゴリにはアイコンが設定される（Keyboard/Mouse/JoyButton/JoyAxis）

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

ダイアログの構成要素と列挙型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | input_event_configuration_dialog.h | `editor/settings/input_event_configuration_dialog.h` | IconCache構造体（45-50行目）、ModCheckbox/KeyMode enum（74-102行目）、クラスメンバ変数（52-108行目） |

**読解のコツ**: INPUT_KEY等の入力タイプはビットマスクとして使用される。mod_checkboxes配列で修飾キーを管理。

#### Step 2: 入力リスニング処理を理解する

リアルタイム入力検出の処理フローを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | input_event_configuration_dialog.cpp | `editor/settings/input_event_configuration_dialog.cpp` | _on_listen_input_changed()（205-266行目） |

**主要処理フロー**:
1. **207-209行目**: 無効/エコー/非押下イベントの除外
2. **212-234行目**: イベントタイプの判定と許可チェック
3. **240-255行目**: キーイベントのキーモードに応じた値のクリア
4. **263行目**: デバイス選択の維持
5. **265行目**: _set_event()でイベント設定

#### Step 3: イベント設定処理を理解する

_set_event()の詳細な処理フローを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | input_event_configuration_dialog.cpp | `editor/settings/input_event_configuration_dialog.cpp` | _set_event()（44-203行目） |

**主要処理フロー**:
- **45-105行目**: イベントタイプ判定とUI表示制御
- **111-115行目**: 追加オプションの表示/非表示制御
- **118-150行目**: 元のキーイベントからのキーモード無効化判定
- **153-191行目**: 入力リストツリーでの選択同期

#### Step 4: 入力リスト更新処理を理解する

_update_input_list()の実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | input_event_configuration_dialog.cpp | `editor/settings/input_event_configuration_dialog.cpp` | _update_input_list()（272-373行目） |

**主要処理フロー**:
- **280-298行目**: キーボードキーの追加（keycode_get_count使用）
- **300-322行目**: マウスボタンの追加（9種類）
- **324-345行目**: ジョイパッドボタンの追加（JoyButton::MAX）
- **347-372行目**: ジョイパッド軸の追加（JoyAxis::MAX * 2方向）

### プログラム呼び出し階層図

```
InputEventConfigurationDialog (ConfirmationDialog)
    │
    ├─ popup_and_configure(p_event, p_action_name)  [表示]
    │      ├─ _set_event()
    │      └─ popup_centered()
    │
    ├─ _on_listen_input_changed(p_event)            [リスニング]
    │      ├─ 入力タイプ判定
    │      ├─ キーモード処理
    │      └─ _set_event()
    │
    ├─ _set_event(p_event, p_original, p_update)    [イベント設定]
    │      ├─ event_as_text更新
    │      ├─ 修飾キーチェックボックス更新
    │      ├─ key_mode更新
    │      ├─ 追加オプション表示制御
    │      └─ 入力リストツリー選択同期
    │
    ├─ _input_list_item_selected()                  [リスト選択]
    │      ├─ InputEvent生成
    │      ├─ 修飾キー維持
    │      └─ _set_event()
    │
    └─ get_event()                                  [取得]
           └─ return event
```

### データフロー図

```
[入力]                    [処理]                         [出力]

リスナー入力 ───────────▶ _on_listen_input_changed() ──▶ _set_event()
EventListenerLineEdit          │
                              ├─ タイプ判定 (KEY/MOUSE/JOY)
                              ├─ キーモード処理
                              └─ デバイス維持

入力リスト選択 ─────────▶ _input_list_item_selected() ─▶ _set_event()
Tree                          │
                              ├─ InputEvent生成
                              └─ 修飾キー維持

修飾キートグル ─────────▶ _mod_toggled() ──────────────▶ _set_event()
CheckBox                      │
                              └─ Alt/Shift/Ctrl/Meta設定

キーモード選択 ─────────▶ _key_mode_selected() ────────▶ _set_event()
OptionButton                  │
                              └─ keycode/physical/label切替

                              │
                              ▼
                        event_as_text更新
                              │
                              ▼
OKボタン ───────────────▶ get_event() ─────────────────▶ InputEvent返却
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| input_event_configuration_dialog.cpp | `editor/settings/input_event_configuration_dialog.cpp` | ソース | ダイアログの実装 |
| input_event_configuration_dialog.h | `editor/settings/input_event_configuration_dialog.h` | ヘッダ | クラス定義 |
| event_listener_line_edit.h | `editor/settings/event_listener_line_edit.h` | ヘッダ | 入力リスニングUI |
| input_map.h | `core/input/input_map.h` | ヘッダ | インプットマップAPI |
| input_event.h | `core/input/input_event.h` | ヘッダ | InputEvent各クラス |
| action_map_editor.h | `editor/settings/action_map_editor.h` | ヘッダ | 呼び出し元エディタ |
