# 機能設計書 232-IsKeyChordPressed

## 概要

本ドキュメントは、ImGuiライブラリにおける複合キー入力判定機能「IsKeyChordPressed」の設計仕様を定義する。

### 本機能の処理概要

IsKeyChordPressed関数は、修飾キー（Ctrl/Shift/Alt/Super）と通常キーの組み合わせ（キーコード）が押されたかを判定する機能である。例えば「Ctrl+S」のようなキーボードショートカットの検出に使用される。ただし、この関数はルーティングやフォーカスチェックを行わないため、より高度なショートカット処理にはShortcut()関数の使用が推奨される。

**業務上の目的・背景**：アプリケーションでは、単一のキーだけでなく、複数のキーを同時に押す「キーコード」によるショートカット操作が一般的である。Ctrl+Cでコピー、Ctrl+Vでペーストなど、ユーザーが期待する標準的なキーボード操作を実現するために、複合キー入力の検出機能が不可欠である。

**機能の利用シーン**：
- 標準的なキーボードショートカット（Ctrl+C、Ctrl+V、Ctrl+Z等）の検出
- アプリケーション固有のショートカット実装
- ゲームにおける複合キー操作の検出
- エディタでのモディファイア付きコマンド処理
- シンプルなホットキー機能の実装

**主要な処理内容**：
1. キーコードの正規化（FixupKeyChord関数による修飾キーの補正）
2. 現在の修飾キー状態との比較（IO.KeyModsとの照合）
3. 通常キー部分の押下判定（IsKeyPressed関数による確認）
4. キーオーナーシップの検証（オプション）
5. 結果の返却

**関連システム・外部連携**：ImGuiIO構造体からキー入力情報と修飾キー状態を取得。内部的にIsKeyPressed関数と連携してキー押下判定を行う。

**権限による制御**：内部API版ではキーオーナーシップ機能により、特定のウィジェットがキー入力を専有できる。owner_idを指定することで、他のコンポーネントからのキーコード検出をブロックできる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 27 | Inputs | 参照画面 | キーボード入力判定のデモ表示 |

## 機能種別

入力判定処理 / キーコード検出

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| key_chord | ImGuiKeyChord | Yes | 検出するキーコード（修飾キー + キーのビット論理和）例: ImGuiMod_Ctrl \| ImGuiKey_S | なし |
| flags | ImGuiInputFlags | No | 入力フラグ（内部API版、デフォルトはImGuiInputFlags_None） | ImGuiInputFlags_RepeatMask_のみサポート |
| owner_id | ImGuiID | No | キーオーナーID（内部API版、デフォルトはImGuiKeyOwner_Any） | なし |

### 入力データソース

- ImGuiIO.KeyMods：現在のモディファイアキー状態
- ImGuiIO.KeysData配列：各キーの状態情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | bool | キーコードが押された場合true、それ以外はfalse |

### 出力先

呼び出し元への戻り値として返却

## 処理フロー

### 処理シーケンス

```
1. パブリックAPI呼び出し（IsKeyChordPressed(key_chord)）
   └─ flags=ImGuiInputFlags_None, owner_id=ImGuiKeyOwner_Anyで内部版を呼び出し

2. キーコードの正規化
   └─ FixupKeyChord(key_chord)で修飾キーを補正（例：ImGuiKey_LeftCtrl → ImGuiMod_Ctrl追加）

3. 修飾キー状態の確認
   └─ (key_chord & ImGuiMod_Mask_) と g.IO.KeyMods を比較、一致しなければfalse

4. 通常キーの抽出と判定
   └─ (key_chord & ~ImGuiMod_Mask_) で通常キーを取得
   └─ キーがImGuiKey_Noneの場合、修飾キー自体をキーとして扱う

5. IsKeyPressedによる押下判定
   └─ IsKeyPressed(key, flags, owner_id)で最終判定

6. 結果の返却
   └─ IsKeyPressedの結果を返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: IsKeyChordPressed] --> B[FixupKeyChord でキーコード正規化]
    B --> C[修飾キー抽出: mods = key_chord & ImGuiMod_Mask_]
    C --> D{IO.KeyMods == mods?}
    D -->|No| E[return false<br/>修飾キー不一致]
    D -->|Yes| F[通常キー抽出: key = key_chord & ~ImGuiMod_Mask_]
    F --> G{key == ImGuiKey_None?}
    G -->|Yes| H[key = ConvertSingleModFlagToKey mods]
    G -->|No| I[keyをそのまま使用]
    H --> J[IsKeyPressed key, flags, owner_id]
    I --> J
    J --> K{IsKeyPressed の結果}
    K -->|false| L[return false]
    K -->|true| M[return true]
    E --> N[終了]
    L --> N
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-232-01 | 修飾キー完全一致 | 指定された修飾キーが現在押されている修飾キーと完全に一致する必要がある | 常時 |
| BR-232-02 | 左右キー自動補正 | ImGuiKey_LeftCtrl/RightCtrl等を指定した場合、対応するImGuiMod_Ctrlが自動的に追加される | FixupKeyChord適用時 |
| BR-232-03 | 修飾キー単体判定 | 通常キーが指定されていない場合、修飾キー自体の押下を判定する | key_chord & ~ImGuiMod_Mask_ == 0の場合 |
| BR-232-04 | ルーティング非対応 | この関数はショートカットルーティングを行わないため、複数のコンポーネントで同じキーコードを検出する可能性がある | 常時 |

### 計算ロジック

キーコード押下判定ロジック：
```
IsKeyChordPressed = (IO.KeyMods == (key_chord & ImGuiMod_Mask_)) && IsKeyPressed(通常キー)
```

## データベース操作仕様

該当なし（メモリ上のキー状態データのみ参照）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 警告コメント | ルーティングが必要なケースで使用された場合 | Shortcut()関数の使用を推奨（APIコメントで案内） |

### リトライ仕様

該当なし（同期的な状態チェック関数のため）

## トランザクション仕様

該当なし

## パフォーマンス要件

- 処理時間：O(1)の定数時間で完了
- 1フレームあたり複数回呼び出し可能
- メモリアロケーションなし

## セキュリティ考慮事項

該当なし（UIライブラリ内部の入力状態チェックのみ）

## 備考

- ショートカットルーティングやフォーカスチェックが必要な場合はShortcut()関数を使用すること
- macOS環境では、io.AddKeyEvent()によりCmdキーとCtrlキーが自動的にスワップされる
- ImGuiMod_Shortcutは廃止されており、クロスプラットフォームではImGuiMod_Ctrlを使用する

---

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

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

### 推奨読解順序

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

キーコードの構造と修飾キーフラグを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | ImGuiKeyChord型の定義（typedef int ImGuiKeyChord） |
| 1-2 | imgui.h | `imgui.h` | ImGuiMod_列挙型で修飾キーフラグを確認（ImGuiMod_Ctrl、ImGuiMod_Shift等） |
| 1-3 | imgui.h | `imgui.h` | ImGuiKey列挙型で通常キーコードを確認 |

**読解のコツ**: ImGuiKeyChordは修飾キーフラグ（上位ビット）と通常キー（下位ビット）のビット論理和で構成される。ImGuiMod_Mask_でマスクすることで修飾キー部分を抽出できる。

#### Step 2: エントリーポイントを理解する

パブリックAPI関数の宣言と実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.h | `imgui.h` | IsKeyChordPressed関数の宣言（1061行目） |
| 2-2 | imgui.cpp | `imgui.cpp` | パブリックAPI版の実装（10630-10633行目） |

**主要処理フロー**:
1. **10630-10633行目**: パブリックAPI - 内部版をデフォルトパラメータで呼び出し

#### Step 3: 内部実装を理解する

キーコード判定の詳細ロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui.cpp | `imgui.cpp` | 内部API版IsKeyChordPressedの実装（10636-10651行目） |
| 3-2 | imgui.cpp | `imgui.cpp` | FixupKeyChord関数でキーコード正規化の処理を確認 |
| 3-3 | imgui.cpp | `imgui.cpp` | ConvertSingleModFlagToKey関数で修飾キーから対応するキーへの変換を確認 |

**主要処理フロー**:
- **10639行目**: FixupKeyChord(key_chord)でキーコードを正規化
- **10640行目**: 修飾キーマスクを適用して修飾キー部分を抽出
- **10641-10642行目**: IO.KeyModsと修飾キーを比較、不一致ならfalse
- **10645行目**: 通常キー部分を抽出
- **10646-10647行目**: キーがNoneの場合、修飾キー自体をキーとして扱う
- **10648-10649行目**: IsKeyPressedでキー押下を判定

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

```
ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord)  [Public API - imgui.cpp:10630]
    │
    └─ ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id)  [Internal - imgui.cpp:10636]
           │
           ├─ FixupKeyChord(key_chord)
           │
           ├─ ConvertSingleModFlagToKey(mods)  [条件付き呼び出し]
           │
           └─ IsKeyPressed(key, flags, owner_id)
                  │
                  ├─ GetKeyData(key)
                  │
                  └─ TestKeyOwner(key, owner_id)
```

### データフロー図

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

ImGuiKeyChord key_chord  ───▶ FixupKeyChord()で正規化
                               │
                               ▼
                         修飾キー抽出と比較
                         (key_chord & ImGuiMod_Mask_)
                         vs IO.KeyMods
                               │
                               ▼
                         通常キー抽出
                         (key_chord & ~ImGuiMod_Mask_)
                               │
                               ▼
                         IsKeyPressed()で
                         キー押下判定
                               │
                               ▼
                         bool結果を返却      ───▶ 呼び出し元
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | パブリックAPIの宣言、ImGuiKeyChord/ImGuiMod定義 |
| imgui.cpp | `imgui.cpp` | ソース | IsKeyChordPressedの実装 |
| imgui_internal.h | `imgui_internal.h` | ヘッダー | 内部API版の宣言、FixupKeyChord等 |
| imgui_demo.cpp | `imgui_demo.cpp` | ソース | 使用例のデモコード |
