# 機能設計書 77-Indent

## 概要

本ドキュメントは、Dear ImGuiライブラリのIndent関数の機能設計を記述する。この関数は、コンテンツ位置を右に移動させる（インデントを増やす）ためのAPI関数である。

### 本機能の処理概要

Indent関数は、現在のインデントレベルを増加させ、後続のウィジェットやテキストをウィンドウの左端から右にオフセットさせる。インデント幅を指定しない場合（0.0f以下）は、style.IndentSpacingの値が使用される。TreePush/TreePopと同様の視覚効果を持つが、IDスタックへの影響はない。

**業務上の目的・背景**：階層的なUIレイアウト（ツリービュー、ネストされたオプション、サブセクション）を構築する際に、視覚的な階層構造を表現することは重要である。Indent()は、TreeNode/TreePush等のツリーウィジェットを使わずに、単純なインデント効果を実現する。設定画面のサブカテゴリ、詳細オプションの表示、折りたたみセクション内のコンテンツ配置など、コンテンツの論理的な構造を視覚的に表現するために使用される。

**機能の利用シーン**：ツリービューのインデント表現、設定画面のサブオプション表示、ヘルプテキストの階層表示、折りたたみセクション内のコンテンツ配置、リストのネスト表現などで使用される。

**主要な処理内容**：
1. ウィンドウを取得する
2. DC.Indent.xを増加させる
3. DC.CursorPos.xを新しいインデント位置に更新する

**関連システム・外部連携**：この関数は純粋にImGui内部のレイアウト管理に関わるため、外部システムとの連携はない。

**権限による制御**：権限による制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 7 | User Guide | 補助機能 | テキストのインデント |
| 24 | Layout | 主機能 | インデントのデモ |

## 機能種別

レイアウト制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| indent_w | float | No | インデント幅（0.0f以下でstyle.IndentSpacingを使用） | デフォルト: 0.0f |

### 入力データソース

ユーザーコードから直接呼び出される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | void | 戻り値なし |

### 出力先

現在のウィンドウのDrawing Context（DC）のIndent.xとCursorPos.xを更新する。

## 処理フロー

### 処理シーケンス

```
1. グローバルコンテキストとウィンドウを取得
   └─ g = *GImGui, window = GetCurrentWindow()
2. インデント幅を決定
   └─ indent_w != 0 → indent_w を使用
   └─ indent_w == 0 → style.IndentSpacing を使用
3. DC.Indent.xを増加
   └─ DC.Indent.x += (決定したインデント幅)
4. DC.CursorPos.xを更新
   └─ DC.CursorPos.x = Pos.x + DC.Indent.x + DC.ColumnsOffset.x
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[ウィンドウ取得]
    B --> C{indent_w != 0?}
    C -->|Yes| D[indent_w を使用]
    C -->|No| E[IndentSpacing を使用]
    D --> F[DC.Indent.x += indent幅]
    E --> F
    F --> G[DC.CursorPos.x 更新]
    G --> H[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | デフォルトインデント | indent_w が 0 または負の場合、style.IndentSpacing が使用される | 常時 |
| BR-02 | 累積インデント | Indent()を複数回呼び出すとインデントが累積する | 常時 |
| BR-03 | カーソル位置更新 | CursorPos.xはIndent.xとColumnsOffset.xを考慮して計算される | 常時 |

### 計算ロジック

インデント計算：
```
effective_indent = (indent_w != 0.0f) ? indent_w : style.IndentSpacing
DC.Indent.x += effective_indent
DC.CursorPos.x = window->Pos.x + DC.Indent.x + DC.ColumnsOffset.x
```

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

該当なし（メモリ内操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 特にエラー条件なし | - |

### リトライ仕様

該当なし

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

該当なし（フレーム単位の即座反映）

## パフォーマンス要件

非常に軽量な操作（座標計算とメンバ変数への代入のみ）。

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

特になし（純粋なUI操作）

## 備考

- Unindent()と対で使用することが推奨される
- TreePush/TreePopと異なり、IDスタックに影響を与えない
- style.IndentSpacingでデフォルトのインデント幅を変更可能

---

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

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

### 推奨読解順序

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

インデントに関わるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_internal.h | `imgui_internal.h` | ImGuiWindowTempData構造体のIndent（ImVec1型）を確認（2601行目） |
| 1-2 | imgui.h | `imgui.h` | ImGuiStyle構造体のIndentSpacingフィールドを確認 |

**読解のコツ**: Indentは内部的にImVec1型（float 1つ）で保持され、現在のX方向のインデント量を表す。ColumnsOffsetと組み合わせて最終的なCursorPos.xが決定される。

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

Indent関数の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.cpp | `imgui.cpp` | Indent関数の実装（11444-11450行目） |

**主要処理フロー**:
1. **11446行目**: グローバルコンテキストを取得
2. **11447行目**: GetCurrentWindow()でウィンドウを取得
3. **11448行目**: DC.Indent.xを増加（indent_w != 0 ? indent_w : IndentSpacing）
4. **11449行目**: DC.CursorPos.xを新しいインデント位置に更新

#### Step 3: 関連関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui.cpp | `imgui.cpp` | Unindent関数（11452-11458行目）でインデント解除処理を確認 |

**主要処理フロー**:
- **11456行目**: DC.Indent.x -= (indent_w != 0 ? indent_w : IndentSpacing)
- **11457行目**: DC.CursorPos.xの更新

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

```
ImGui::Indent(indent_w)
    │
    ├─ GImGui取得
    │
    ├─ GetCurrentWindow()
    │
    ├─ インデント幅決定
    │      ├─ indent_w != 0: indent_wを使用
    │      └─ indent_w == 0: style.IndentSpacingを使用
    │
    ├─ DC.Indent.x += インデント幅
    │
    └─ DC.CursorPos.x = Pos.x + Indent.x + ColumnsOffset.x
```

### データフロー図

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

indent_w ────────▶ Indent() ──────────▶ DC.Indent.x
(float)                   │                  (増加)
                          │
                          └────────────▶ DC.CursorPos.x
                                           (新しいインデント位置)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | Indent関数の宣言（582行目） |
| imgui.cpp | `imgui.cpp` | ソース | Indent関数の実装（11444-11450行目） |
| imgui.cpp | `imgui.cpp` | ソース | Unindent関数の実装（11452-11458行目） |
| imgui_internal.h | `imgui_internal.h` | 内部ヘッダー | ImGuiWindowTempData構造体のIndent定義（2601行目） |
