# 機能設計書 173-EndTable

## 概要

本ドキュメントは、ImGuiライブラリにおける`EndTable`関数の機能設計を記載する。この関数は、`BeginTable`で開始されたテーブルを終了し、描画の確定と後処理を行う。

### 本機能の処理概要

**業務上の目的・背景**：テーブルの描画処理を完了し、リソースの解放と状態の復元を行う必要がある。`EndTable`は、テーブル内のすべてのコンテンツが追加された後に呼び出され、ボーダーの描画、描画チャンネルのマージ、スクロール処理、設定の保存など、テーブルのライフサイクルを正しく終了するための重要な機能である。

**機能の利用シーン**：
- テーブルへのコンテンツ追加が完了した後
- ループ処理でテーブル行を出力した後の終了処理
- 条件付きテーブル表示で、BeginTableがtrueを返した場合のクリーンアップ

**主要な処理内容**：
1. 最終行の終了処理（TableEndRow）
2. コンテキストメニューの処理（ContextMenuInBodyフラグ使用時）
3. テーブル高さの確定
4. クリップ矩形のポップ
5. ボーダーの描画（TableDrawBorders）
6. 描画チャンネルのマージ（TableMergeDrawChannels）
7. 列の自動フィット幅の更新
8. リサイズ処理の適用
9. IDスタックのポップ
10. 親ウィンドウの状態復元
11. 設定の保存（SettingsDirtyの場合）

**関連システム・外部連携**：
- 描画リストシステム（DrawSplitter）
- 子ウィンドウシステム（EndChild）
- 設定保存システム（TableSaveSettings）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 26 | Tables | 主画面 | テーブルの終了処理 |

## 機能種別

UI制御機能（スコープ終了）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | パラメータなし | - |

### 入力データソース

- ImGuiコンテキストのカレントテーブル（g.CurrentTable）
- テーブルの一時データ（table->TempData）

## 出力仕様

### 出力データ

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

### 出力先

- 描画リスト（ボーダー描画）
- INI設定ファイル（設定変更時）
- 親ウィンドウの状態復元

## 処理フロー

### 処理シーケンス

```
1. テーブル参照の取得と検証
   └─ g.CurrentTableがNULLでないことを確認
2. レイアウト未完了時の対応
   └─ IsLayoutLockedがfalseならTableUpdateLayoutを呼び出し
3. 現在の行の終了
   └─ IsInsideRowがtrueならTableEndRowを呼び出し
4. コンテキストメニュー処理
   └─ ContextMenuInBodyフラグ時、右クリックでメニューを開く
5. テーブル高さの確定
   └─ RowPosY2から最終高さを計算
6. スクロール範囲の設定
   └─ ScrollXフラグ使用時
7. クリップ矩形のポップ
   └─ NoClipフラグ未使用時
8. ボーダーの描画
   └─ Bordersフラグ使用時
9. 描画チャンネルのマージ
   └─ DrawSplitter.Merge()を呼び出し
10. 列の自動フィット幅更新
11. スクロール同期処理
12. リサイズ処理の適用
13. IDスタックのポップ
14. ウィンドウデータの復元
15. 設定の保存
    └─ IsSettingsDirtyがtrueの場合
16. カレントテーブルのクリア/復元
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{レイアウト<br/>完了?}
    B -->|No| C[TableUpdateLayout]
    B -->|Yes| D{行が<br/>開いている?}
    C --> D
    D -->|Yes| E[TableEndRow]
    D -->|No| F{ContextMenu<br/>InBody?}
    E --> F
    F -->|Yes| G{右クリック<br/>された?}
    F -->|No| H[テーブル高さ確定]
    G -->|Yes| I[TableOpenContextMenu]
    G -->|No| H
    I --> H
    H --> J{Borders<br/>フラグ?}
    J -->|Yes| K[TableDrawBorders]
    J -->|No| L[描画チャンネルマージ]
    K --> L
    L --> M[列幅更新]
    M --> N{リサイズ<br/>中?}
    N -->|Yes| O[新しい幅を適用]
    N -->|No| P[IDスタックポップ]
    O --> P
    P --> Q[ウィンドウ状態復元]
    Q --> R{設定<br/>変更?}
    R -->|Yes| S[TableSaveSettings]
    R -->|No| T[カレントテーブルクリア]
    S --> T
    T --> U[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-173-01 | BeginTableとのペア | EndTableはBeginTableがtrueを返した場合のみ呼び出す | 常に |
| BR-173-02 | レイアウト自動完了 | TableNextRow/TableNextColumnが呼ばれずにEndTableが呼ばれた場合、自動的にTableUpdateLayoutを実行 | IsLayoutLocked == false |
| BR-173-03 | 設定自動保存 | テーブル設定が変更された場合、自動的にINIファイルに保存される | IsSettingsDirty == true |

### 計算ロジック

列の自動フィット幅計算:
- 固定幅列: `column->WidthRequest`または`TableGetColumnWidthAuto()`
- ストレッチ列: 残りスペースを重みに応じて分配

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

該当なし（INIファイルへの設定保存はテーブル設定のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | アサーション失敗 | BeginTable外でEndTableを呼び出し | デバッグビルドで停止、ユーザーエラーメッセージ表示 |
| N/A | アサーション失敗 | IDスタックの不整合 | PushID/PopIDの対応を確認 |
| N/A | アサーション失敗 | ItemWidthスタックの不整合 | PushItemWidth/PopItemWidthの対応を確認 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 描画チャンネルのマージはO(c)（cはアクティブチャンネル数）
- ボーダー描画はO(n)（nは列数）

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

特になし

## 備考

- EndTableはBeginTableがtrueを返した場合のみ呼び出すこと
- 空のテーブル（行を1つも追加しない）でも正しく動作する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_internal.h | `imgui_internal.h` | ImGuiTable構造体のIsLayoutLocked, IsInsideRow等のフラグ |
| 1-2 | imgui_internal.h | `imgui_internal.h` | ImGuiTableTempData構造体のバックアップフィールド |

**読解のコツ**: EndTableは多くの状態を復元する必要があるため、TempDataに保存されたバックアップ値を理解することが重要。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.h | `imgui.h` | 902行目: 公開APIの宣言 |
| 2-2 | imgui_tables.cpp | `imgui_tables.cpp` | 1361-1581行目: EndTable実装 |

**主要処理フロー**:
1. **1363-1365行目**: カレントテーブルの取得とバリデーション
2. **1373-1374行目**: レイアウト未完了時のTableUpdateLayout呼び出し
3. **1383-1384行目**: 最終行の終了
4. **1387-1389行目**: コンテキストメニュー処理
5. **1419-1421行目**: クリップ矩形のポップ
6. **1425-1426行目**: ボーダー描画
7. **1441-1446行目**: 描画チャンネルのマージ
8. **1484-1490行目**: リサイズ処理
9. **1494-1499行目**: IDスタックのポップ
10. **1501-1509行目**: ウィンドウデータの復元
11. **1565-1566行目**: 設定の保存

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_tables.cpp | `imgui_tables.cpp` | TableEndRow関数 |
| 3-2 | imgui_tables.cpp | `imgui_tables.cpp` | TableDrawBorders関数 |
| 3-3 | imgui_tables.cpp | `imgui_tables.cpp` | TableMergeDrawChannels関数 |

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

```
EndTable()
    │
    ├─ TableUpdateLayout(table) [レイアウト未完了時]
    │
    ├─ TableEndRow(table) [行が開いている場合]
    │
    ├─ TableOpenContextMenu() [右クリック時]
    │
    ├─ DrawList->PopClipRect() [NoClip未使用時]
    │
    ├─ TableDrawBorders(table) [Bordersフラグ時]
    │
    ├─ TableMergeDrawChannels(table) [NoClip未使用時]
    │
    ├─ DrawSplitter->Merge()
    │
    ├─ PopID() × 1〜2回
    │
    ├─ EndChild() [子ウィンドウ使用時]
    │      └─ スクロール用子ウィンドウの終了
    │
    └─ TableSaveSettings(table) [設定変更時]
```

### データフロー図

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

g.CurrentTable ──────────▶ ┌───────────────────┐
                          │ EndTable()         │
table->TempData ─────────▶│   - 行終了         │ ────▶ [描画リスト更新]
                          │   - ボーダー描画   │
table->IsLayoutLocked ───▶│   - チャンネルマージ│ ────▶ [ウィンドウ状態復元]
                          │   - 状態復元       │
table->IsSettingsDirty ──▶│   - 設定保存       │ ────▶ [INI設定更新]
                          └───────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | 公開API宣言 |
| imgui_internal.h | `imgui_internal.h` | ヘッダー | 内部データ構造定義 |
| imgui_tables.cpp | `imgui_tables.cpp` | ソース | 実装本体 |
