# 機能設計書 136-TreeNodeEx

## 概要

本ドキュメントは、ImGuiライブラリにおける拡張ツリーノードウィジェット `TreeNodeEx` の機能仕様を定義するものである。

### 本機能の処理概要

TreeNodeExは、ImGuiTreeNodeFlagsを指定できる拡張版のツリーノードを作成する機能である。TreeNodeよりも細かい動作制御が可能。

**業務上の目的・背景**：標準のTreeNodeでは対応できない、より複雑なユースケースに対応するために設計されている。例えば、選択状態の表示、デフォルトで開いた状態、葉ノードの表現、クリック動作のカスタマイズなど、様々な表示・動作オプションをフラグで制御できる。プロパティエディタ、シーングラフビューア、アセットブラウザなど、専門的なUIを構築する際に必須となる機能である。

**機能の利用シーン**：選択状態を表示するツリービュー、常に開いた状態で表示するヘルプツリー、子ノードを持たない葉ノードの表示、ダブルクリックでのみ開閉するツリー、全幅にわたってクリック可能なツリーノードなど。

**主要な処理内容**：
1. ラベル/IDからウィジェットIDを生成
2. フラグに基づく開閉状態の初期値決定
3. フラグに応じたノード領域の計算（幅の拡張等）
4. 選択状態、フレーム表示等のフラグベース描画
5. クリック動作のカスタマイズ（矢印のみ、ダブルクリック等）
6. TreePushの自動呼び出し（NoTreePushOnOpen未設定時）

**関連システム・外部連携**：TreePop()と必ずペアで使用（NoTreePushOnOpenフラグ未設定時）。SetNextItemOpen()で開閉状態を事前設定可能。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Demo Window | 主画面 | 各セクションの階層表示 |
| 2 | Metrics/Debugger Window | 主画面 | 内部状態のツリー表示 |
| 13 | Property Editor | 主画面 | プロパティのツリー表示 |
| 23 | Widgets | 参照画面 | ツリーノードのデモ |

## 機能種別

ユーザー入力処理 / ウィジェット描画 / 階層管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| label | const char* | Yes | ノードのラベル（ID生成にも使用） | NULL不可 |
| flags | ImGuiTreeNodeFlags | No | ノードの動作・表示オプション | デフォルトは0 |
| str_id | const char* | No | IDとラベルを分離する場合のID | オーバーロード版 |
| ptr_id | const void* | No | ポインタベースのID | オーバーロード版 |
| fmt | const char* | No | フォーマット文字列 | オーバーロード版 |
| ... | va_list | No | フォーマット引数 | オーバーロード版 |

### 主要なフラグ

| フラグ名 | 値 | 説明 |
|---------|-----|------|
| Selected | 1 << 0 | 選択状態として描画 |
| Framed | 1 << 1 | 背景フレーム付きで描画（CollapsingHeader用） |
| NoTreePushOnOpen | 1 << 3 | 開いてもTreePushしない |
| DefaultOpen | 1 << 5 | デフォルトで開いた状態 |
| OpenOnDoubleClick | 1 << 6 | ダブルクリックでのみ開閉 |
| OpenOnArrow | 1 << 7 | 矢印クリックでのみ開閉 |
| Leaf | 1 << 8 | 葉ノード（折りたたみ不可、矢印なし） |
| SpanAvailWidth | 1 << 11 | 右端までヒット領域を拡張 |

### 入力データソース

- ユーザーが指定するラベル/ID/フラグ
- マウス/キーボード入力による操作
- ImGuiStorage（開閉状態の永続化）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | bool | ノードが開いている場合true |

### 出力先

- 画面上へのウィジェット描画
- IDスタック（開いている場合かつNoTreePushOnOpen未設定時）
- インデント変更

## 処理フロー

### 処理シーケンス

```
1. ウィンドウスキップチェック
   └─ SkipItemsがtrueならfalse返却
2. ラベル/IDからウィジェットIDを生成
   └─ window->GetID(label) または window->GetID(str_id/ptr_id)
3. フォーマット処理（fmt版の場合）
   └─ ImFormatStringToTempBufferV
4. TreeNodeBehaviorを呼び出し
   └─ IDとフラグを渡す
5. 開閉状態を返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{SkipItems?}
    B -->|Yes| C[return false]
    B -->|No| D[ID生成]
    D --> E{fmt引数あり?}
    E -->|Yes| F[フォーマット処理]
    E -->|No| G[TreeNodeBehavior呼び出し]
    F --> G
    G --> H{is_open?}
    H -->|Yes| I[return true]
    H -->|No| J[return false]
    I --> K{NoTreePushOnOpen?}
    K -->|No| L[※TreePop必須]
    K -->|Yes| M[TreePop不要]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-136-01 | ペア条件付き | NoTreePushOnOpen未設定でtrue時、TreePop()必須 | 戻り値true時 |
| BR-136-02 | フラグ排他 | OpenOnDoubleClickとOpenOnArrowは排他ではなく併用可 | - |
| BR-136-03 | Leafフラグ | Leafフラグ時は常にtrue返却、NoTreePushOnOpen推奨 | Leafフラグ設定時 |
| BR-136-04 | 選択表示 | Selectedフラグでハイライト表示 | Selectedフラグ設定時 |

### 計算ロジック

- ID生成：`window->GetID(label)` または `window->GetID(str_id/ptr_id)`
- 領域拡張：`SpanAvailWidth`フラグ時は`WorkRect.Max.x`まで

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

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ウィンドウスキップ | window->SkipItemsがtrue | falseを返却して処理終了 |

### リトライ仕様

リトライ処理は不要（即時応答型）

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

トランザクション管理は不要

## パフォーマンス要件

- 毎フレーム呼び出されることを想定
- フラグ処理による追加オーバーヘッドは軽微

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

特になし（ローカルUI操作のみ）

## 備考

- CollapsingHeaderは内部でTreeNodeExを使用（CollapsingHeaderフラグ付き）
- AllowOverlapフラグで他のウィジェットとの重なりを許可可能
- DrawLinesフラグで階層接続線を描画可能（実験的機能）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | ImGuiTreeNodeFlags列挙型の定義（1297-1331行目） |

**読解のコツ**: 各フラグの意味と相互作用を理解することが重要。CollapsingHeaderフラグは複合フラグ。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.h | `imgui.h` | TreeNodeExの関数宣言（746-750行目） |

**主要処理フロー**:
1. **746行目**: 基本形（label + flags）
2. **747-748行目**: ID分離形（str_id/ptr_id + flags + fmt）
3. **749-750行目**: va_list版

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_widgets.cpp | `imgui_widgets.cpp` | TreeNodeEx(label, flags)の実装（6678-6685行目） |
| 3-2 | imgui_widgets.cpp | `imgui_widgets.cpp` | TreeNodeExV実装（6705-6727行目） |

**主要処理フロー**:
- **6680-6682行目**: ウィンドウ取得とスキップチェック
- **6683行目**: ID生成
- **6684行目**: TreeNodeBehavior呼び出し（フラグ指定）
- **6712-6713行目**: フォーマット処理（ExV版）

#### Step 4: コア処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | imgui_widgets.cpp | `imgui_widgets.cpp` | TreeNodeBehaviorでのフラグ処理（6826-6860行目） |

**主要処理フロー**:
- **6826-6827行目**: Framed/FramePaddingフラグ処理
- **6839-6844行目**: SpanAvailWidth/SpanFullWidthフラグ処理
- **6900-6990行目**: OpenOnDoubleClick/OpenOnArrowフラグ処理

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

```
TreeNodeEx (imgui_widgets.cpp:6678)
    │
    └─ TreeNodeBehavior (imgui_widgets.cpp:6816)
           │
           ├─ GetCurrentWindow
           ├─ CalcTextSize
           │
           ├─ [フラグに応じた領域計算]
           │      ├─ SpanAvailWidth時：右端まで拡張
           │      ├─ SpanFullWidth時：左端から拡張
           │      └─ Framed時：外側に拡張
           │
           ├─ ItemSize / ItemAdd
           │
           ├─ TreeNodeUpdateNextOpen
           │
           ├─ ButtonBehavior
           │      └─ [OpenOnArrow/DoubleClickの処理]
           │
           ├─ [描画処理]
           │      ├─ RenderFrame (Framed時)
           │      ├─ RenderArrow
           │      └─ RenderText
           │
           └─ TreePush (is_open && !NoTreePushOnOpen時)
```

### データフロー図

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

const char* label ───┬─▶ ID生成
                     │
ImGuiTreeNodeFlags   │
flags ───────────────┴─▶ フラグ解析
                              │
                              ▼
                         領域計算
                         (フラグ依存)
                              │
                              ▼
マウス/キー入力 ──────▶ 操作処理
                         (フラグ依存)
                              │
                              ▼
                         ノード描画
                         (フラグ依存)
                              │
                              ▼
                         条件付き
                         TreePush ────────▶ IDスタック
                              │
                              ▼
                         return is_open ───▶ bool
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダ | API宣言とフラグ定義 |
| imgui_widgets.cpp | `imgui_widgets.cpp` | ソース | TreeNodeEx/TreeNodeBehaviorの実装 |
| imgui_internal.h | `imgui_internal.h` | ヘッダ | 内部構造体定義 |
