# 機能設計書 135-TreeNode

## 概要

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

### 本機能の処理概要

TreeNodeは、階層的なデータ構造を表示するためのツリーノードを作成する機能である。ノードが開いている場合にtrueを返し、その場合は必ずTreePop()を呼び出す必要がある。

**業務上の目的・背景**：階層的なデータ（ファイルシステム、オブジェクト階層、設定カテゴリなど）をGUI上で表示・操作する需要は非常に多い。TreeNodeは、折りたたみ可能な階層構造を簡単に実装するための基本ウィジェットを提供する。ユーザーはクリックでノードを展開/折りたたみでき、直感的な階層ナビゲーションが可能となる。

**機能の利用シーン**：プロパティエディタでのオブジェクト階層表示、ファイルブラウザでのディレクトリ構造表示、デモウィンドウでのセクション分け、デバッガでのオブジェクトインスペクション、シーングラフエディタでのノード階層表示など。

**主要な処理内容**：
1. ラベルからウィジェットIDを生成
2. 開閉状態の取得（ストレージまたはデフォルト設定から）
3. ノード領域の描画（矢印アイコン、背景、テキスト）
4. マウス/キーボード操作による開閉状態の切り替え
5. 開いている場合はツリー階層をプッシュ（インデント+ID）
6. 開いているかどうかをboolで返却

**関連システム・外部連携**：TreePop()と必ずペアで使用。SetNextItemOpen()で開閉状態を事前設定可能。マルチセレクトシステムとも連携可能（BETA）。

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

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

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | bool | ノードが開いている場合true（TreePop必須）、閉じている場合false |

### 出力先

- 画面上へのウィジェット描画
- IDスタック（開いている場合プッシュ）
- インデント変更

## 処理フロー

### 処理シーケンス

```
1. ウィンドウスキップチェック
   └─ SkipItemsがtrueならfalse返却
2. ラベルからIDを生成
   └─ window->GetID(label)
3. TreeNodeBehaviorを呼び出し
   └─ フラグは ImGuiTreeNodeFlags_None
4. 開閉状態を返却
   └─ trueの場合はTreePop()が必要
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{SkipItems?}
    B -->|Yes| C[return false]
    B -->|No| D[ID生成]
    D --> E[TreeNodeBehavior呼び出し]
    E --> F{ノードが開いている?}
    F -->|Yes| G[return true]
    F -->|No| H[return false]
    G --> I[※TreePop必須]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-135-01 | ペア必須 | 戻り値がtrueの場合、必ずTreePop()を呼び出す | 常時 |
| BR-135-02 | ID一意性 | 同じIDを持つTreeNodeは状態を共有する | 常時 |
| BR-135-03 | デフォルト閉 | 明示的に指定しない限り初期状態は閉じている | 常時 |
| BR-135-04 | ストレージ永続化 | 開閉状態はウィンドウのストレージに保存される | 常時 |

### 計算ロジック

- ID生成：`window->GetID(label)`
- 開閉状態取得：`TreeNodeUpdateNextOpen(storage_id, flags)`

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

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

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

## エラー処理

### エラーケース一覧

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

### リトライ仕様

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

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

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

## パフォーマンス要件

- 毎フレーム呼び出されることを想定
- 大量のノード（数千件）でもパフォーマンス維持のため、クリッピング対応が重要

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

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

## 備考

- TreeNodeExを使用するとより細かいフラグ制御が可能
- CollapsingHeaderとは異なり、IDスタックにプッシュしインデントを追加する
- Bullet()やGetTreeNodeToLabelSpacing()で同じインデント幅のテキストを配置可能

---

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

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

### 推奨読解順序

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

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

**読解のコツ**: Framed、Leaf、DefaultOpen、SpanAvailWidthなど、よく使うフラグを理解する。

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

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

**主要処理フロー**:
1. **741行目**: 基本形（label）
2. **742-743行目**: ID分離形（str_id/ptr_id + fmt）
3. **744-745行目**: va_list版

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_widgets.cpp | `imgui_widgets.cpp` | TreeNode(label)の実装（6659-6666行目） |
| 3-2 | imgui_widgets.cpp | `imgui_widgets.cpp` | TreeNode(str_id, fmt, ...)の実装（6641-6648行目） |

**主要処理フロー**:
- **6661-6663行目**: ウィンドウ取得とスキップチェック
- **6664行目**: ID生成
- **6665行目**: TreeNodeBehavior呼び出し（フラグなし）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | imgui_widgets.cpp | `imgui_widgets.cpp` | TreeNodeBehaviorの実装（6816-7149行目） |

**主要処理フロー**:
- **6818-6820行目**: ウィンドウ取得とスキップチェック
- **6826-6832行目**: パディングとラベルサイズ計算
- **6862-6863行目**: 開閉状態の取得
- **6900-6990行目**: マウス操作とクリック処理
- **7020-7080行目**: 描画処理（背景、矢印、テキスト）
- **7100-7130行目**: 開いている場合のTreePush

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

```
TreeNode (imgui_widgets.cpp:6659)
    │
    └─ TreeNodeBehavior (imgui_widgets.cpp:6816)
           │
           ├─ GetCurrentWindow
           ├─ CalcTextSize
           ├─ ItemSize
           ├─ ItemAdd
           │
           ├─ TreeNodeUpdateNextOpen
           │      └─ ImGuiStorage::GetInt
           │
           ├─ ButtonBehavior
           │
           ├─ RenderFrame
           ├─ RenderArrow
           ├─ RenderText
           │
           └─ TreePush (is_open時)
                  ├─ Indent
                  └─ PushID
```

### データフロー図

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

const char* label ───▶ ID生成
                           │
                           ▼
                   開閉状態取得
                   (Storage)
                           │
マウス/キー入力 ──────▶ 操作処理 ──────▶ 状態更新
                           │                 (Storage)
                           ▼
                   ノード描画
                   (矢印/背景/テキスト)
                           │
                           ▼
                   開いていれば
                   TreePush ────────▶ IDスタック
                           │            インデント
                           ▼
                   return is_open ───▶ bool
```

### 関連ファイル一覧

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