# 機能設計書 141-Selectable

## 概要

本ドキュメントは、Dear ImGuiライブラリにおけるSelectable関数の機能設計を記述する。Selectableはクリックで選択可能なテキストアイテムを作成するウィジェット関数である。

### 本機能の処理概要

Selectable関数は、ユーザーが選択可能なテキストアイテムを作成する機能を提供する。このウィジェットはリストボックス、メニュー、ファイルブラウザなど、選択操作が必要なUIで広く利用される。

**業務上の目的・背景**：GUIアプリケーションにおいて、リスト形式のデータから項目を選択する操作は非常に一般的である。Selectableは、テーブルやリストビューのような複雑なウィジェットの構成要素として、またスタンドアロンの選択アイテムとして、柔軟に利用できる基本的なUI部品を提供する。

**機能の利用シーン**：
- ファイルブラウザでのファイル選択
- プロパティエディタでの項目選択
- メニューアイテムの実装基盤
- コンソールウィンドウでの履歴選択
- アセットブラウザでのアセット選択

**主要な処理内容**：
1. ラベルテキストのサイズ計算とレイアウト処理
2. 選択状態に応じたハイライト背景の描画
3. ホバー・クリック・ナビゲーション操作の検出
4. マルチセレクトモード時の選択状態管理との連携
5. 自動ポップアップクローズ機能

**関連システム・外部連携**：マルチセレクトシステム（BeginMultiSelect/EndMultiSelect）と連携し、複数選択機能を提供する。

**権限による制御**：ImGuiSelectableFlags_Disabledフラグにより選択不可状態を設定可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | Console | 補助機能 | 履歴選択可能アイテム |
| 12 | Simple Layout | 補助機能 | サイドバーの選択可能アイテム |
| 22 | Assets Browser | 主機能 | アセットの選択可能アイテム |
| 23 | Widgets | 主機能 | 選択可能アイテムのデモ |

## 機能種別

ウィジェット作成 / ユーザーインタラクション処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| label | const char* | Yes | 表示するラベル文字列。##でID専用ラベルを指定可能 | NULL不可 |
| selected | bool | No | 選択状態（読み取り専用オーバーロード） | - |
| p_selected | bool* | No | 選択状態へのポインタ（読み書きオーバーロード） | - |
| flags | ImGuiSelectableFlags | No | 動作フラグ | ImGuiSelectableFlags_列挙値 |
| size | ImVec2 | No | アイテムサイズ。0.0fで自動計算 | x>=0, y>=0 |

### 入力データソース

- 呼び出し元からの直接パラメータ指定
- グローバルコンテキスト（GImGui）からのスタイル設定
- マルチセレクトコンテキスト（g.CurrentMultiSelect）からの選択状態

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | bool | クリックされた場合true |
| p_selected | bool* | 選択状態が更新される（ポインタ版のみ） |
| LastItemData | ImGuiLastItemData | アイテム状態情報（ホバー、クリック等） |

### 出力先

- 画面描画（描画リストへの追加）
- 内部状態の更新（ナビゲーション、フォーカス状態）

## 処理フロー

### 処理シーケンス

```
1. ウィンドウのスキップ確認
   └─ window->SkipItemsがtrueなら早期リターン

2. ラベルサイズの計算
   └─ CalcTextSizeでテキストサイズを取得

3. レイアウト計算
   └─ サイズ引数と利用可能スペースからバウンディングボックスを計算

4. ItemAdd呼び出し
   └─ アイテムの登録とクリッピング判定

5. マルチセレクトヘッダー処理
   └─ マルチセレクトモード時、選択状態とボタンフラグを調整

6. ボタン動作処理（ButtonBehavior）
   └─ ホバー、プレス、ホールド状態の検出

7. マルチセレクトフッター処理
   └─ マルチセレクトモード時、選択状態の更新

8. レンダリング
   └─ 背景ハイライトとテキストの描画

9. ポップアップ自動クローズ
   └─ 条件に応じて親ポップアップを閉じる
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{SkipItems?}
    B -->|Yes| C[return false]
    B -->|No| D[ラベルサイズ計算]
    D --> E[バウンディングボックス計算]
    E --> F[ItemAdd]
    F --> G{表示領域内?}
    G -->|No| C
    G -->|Yes| H{マルチセレクト?}
    H -->|Yes| I[MultiSelectItemHeader]
    H -->|No| J[ButtonBehavior]
    I --> J
    J --> K{マルチセレクト?}
    K -->|Yes| L[MultiSelectItemFooter]
    K -->|No| M{SelectOnNav?}
    L --> N[レンダリング処理]
    M -->|Yes| O[Auto-select処理]
    M -->|No| N
    O --> N
    N --> P{ポップアップ内?}
    P -->|Yes| Q[CloseCurrentPopup]
    P -->|No| R[return pressed]
    Q --> R
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-141-01 | 隣接アイテム連続表示 | 隣接するSelectableは隙間なく連続したハイライトを表示 | 複数Selectableが連続する場合 |
| BR-141-02 | SpanAllColumns | テーブル/カラム全体にハイライトを拡張 | ImGuiSelectableFlags_SpanAllColumns指定時 |
| BR-141-03 | ダブルクリック対応 | ダブルクリックイベントを検出可能 | ImGuiSelectableFlags_AllowDoubleClick指定時 |
| BR-141-04 | 無効化表示 | グレーアウト表示で選択不可 | ImGuiSelectableFlags_Disabled指定時 |

### 計算ロジック

サイズ計算:
- size.x == 0.0f: 利用可能な残り幅を使用
- size.x > 0.0f: 指定幅を使用
- size.y == 0.0f: ラベルの高さを使用
- size.y > 0.0f: 指定高さを使用

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

該当なし（ImGuiはインメモリUIライブラリ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | アサーション | マルチセレクト時にSetNextItemSelectionUserDataが未呼び出し | SetNextItemSelectionUserDataを先に呼び出す |

### リトライ仕様

該当なし

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

即時モードGUIのため、トランザクション管理は不要。各フレームで状態が再評価される。

## パフォーマンス要件

- 大量のSelectableアイテムを効率的に処理するため、クリッピング最適化を実装
- SpanAllColumns時は追加のクリップ矩形操作が必要
- マルチセレクトのボックス選択時、通常クリップされるアイテムも処理対象となる場合あり

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

ユーザー入力されたラベル文字列は内部でそのまま使用される。メモリ安全性はImGui全体の設計に依存。

## 備考

- 高機能版はImPlotやカスタム実装を推奨
- ##を使用した非表示ラベルでカスタム描画領域を作成可能
- version 1.91.0でImGuiSelectableFlags_DontClosePopupsがImGuiSelectableFlags_NoAutoClosePopupsにリネーム

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | ImGuiSelectableFlags_列挙型の定義（1355-1371行目）を確認し、利用可能なフラグオプションを理解する |

**読解のコツ**: フラグはビットマスクで定義されており、複数のフラグを論理和で組み合わせることができる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.h | `imgui.h` | Selectable関数の宣言（763-764行目）で2つのオーバーロードを確認 |
| 2-2 | imgui_widgets.cpp | `imgui_widgets.cpp` | Selectable実装のメイン関数（7300-7480行目） |

**主要処理フロー**:
1. **7302-7304行目**: ウィンドウのスキップ判定
2. **7310-7315行目**: ラベルサイズ計算とItemSize呼び出し
3. **7317-7338行目**: 水平スペース充填とバウンディングボックス計算
4. **7341-7358行目**: ItemAdd呼び出しと表示判定
5. **7391-7406行目**: マルチセレクト処理（ヘッダー/フッター）
6. **7437-7466行目**: レンダリング処理（背景・テキスト）
7. **7468-7470行目**: ポップアップ自動クローズ

#### Step 3: マルチセレクト連携を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_widgets.cpp | `imgui_widgets.cpp` | MultiSelectItemHeader関数（8117行目〜）で選択状態の前処理を確認 |
| 3-2 | imgui_widgets.cpp | `imgui_widgets.cpp` | MultiSelectItemFooter関数で選択状態の後処理を確認 |

**主要処理フロー**:
- **7360行目**: is_multi_select判定（ItemFlagsのImGuiItemFlags_IsMultiSelectをチェック）
- **7392-7396行目**: マルチセレクト時のヘッダー処理呼び出し
- **7403-7406行目**: マルチセレクト時のフッター処理呼び出し

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

```
Selectable(label, selected, flags, size)
    │
    ├─ GetCurrentWindow()
    │
    ├─ CalcTextSize(label)
    │
    ├─ ItemSize(size)
    │
    ├─ ItemAdd(bb, id)
    │
    ├─ [if multi-select] MultiSelectItemHeader(id, &selected, &button_flags)
    │
    ├─ ButtonBehavior(bb, id, &hovered, &held, button_flags)
    │
    ├─ [if multi-select] MultiSelectItemFooter(id, &selected, &pressed)
    │
    ├─ RenderFrame(bb.Min, bb.Max, col)
    │
    ├─ RenderNavCursor(bb, id, flags)
    │
    ├─ RenderTextClipped(pos, ...)
    │
    └─ [if popup] CloseCurrentPopup()
```

### データフロー図

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

label ─────────────────┐
                       │
selected ──────────────┼──▶ Selectable() ──────────────▶ pressed (bool)
                       │         │
flags ─────────────────┤         │
                       │         ├──▶ 描画リストへの追加
size ──────────────────┘         │    (背景・テキスト)
                                 │
GImGui (スタイル) ──────────────▶│
                                 │
g.CurrentMultiSelect ───────────▶├──▶ LastItemData更新
                                 │    (StatusFlags)
                                 │
                                 └──▶ ナビゲーション状態更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | 公開API宣言、フラグ定義 |
| imgui_widgets.cpp | `imgui_widgets.cpp` | ソース | Selectable関数の実装 |
| imgui_internal.h | `imgui_internal.h` | ヘッダー | 内部フラグ定義（ImGuiSelectableFlags_内部フラグ） |
