# 機能設計書 186-EndTabItem

## 概要

本ドキュメントは、ImGuiライブラリのEndTabItem関数の機能設計を記述する。この関数はBeginTabItemで開始されたタブアイテムを終了するためのAPIである。

### 本機能の処理概要

EndTabItem関数は、BeginTabItemで開始されたタブアイテムのコンテキストを終了し、IDスタックからのポップ処理を行う。この関数はBeginTabItemがtrueを返した場合にのみ呼び出す必要がある。

**業務上の目的・背景**：ImGuiのBegin/Endパターンに従い、タブアイテムのスコープを明確に管理する。EndTabItemは、BeginTabItemでプッシュされたIDをポップし、タブコンテンツ領域を正しく終了させる役割を担う。

**機能の利用シーン**：
- BeginTabItemがtrueを返した後のタブアイテム終了処理
- タブのコンテンツ追加完了後

**主要な処理内容**：
1. ウィンドウのスキップ状態チェック
2. タブバーコンテキストの検証
3. 現在のタブアイテムの取得
4. IDスタックからのポップ（NoPushIdでない場合）

**関連システム・外部連携**：
- BeginTabItemとのペア使用（必須）
- BeginTabBar/EndTabBarとの連携

**権限による制御**：本機能に権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 21 | Documents | 主機能 | タブアイテムの終了 |

## 機能種別

UI構造制御処理

## 入力仕様

### 入力パラメータ

なし（引数を取らない関数）

### 入力データソース

- 現在のタブバーコンテキスト（g.CurrentTabBar）
- 現在のタブアイテム（tab_bar->Tabs[tab_bar->LastTabItemIdx]）

## 出力仕様

### 出力データ

なし（void関数）

### 出力先

- IDスタックからのポップ

## 処理フロー

### 処理シーケンス

```
1. ウィンドウのスキップ状態チェック
   └─ SkipItemsの場合は即座にreturn
2. タブバーコンテキストの検証
   └─ g.CurrentTabBarがNULLの場合はアサーション
3. LastTabItemIdxの検証
   └─ 有効なインデックスか確認
4. 現在のタブアイテムの取得
5. NoPushIdフラグのチェック
   └─ フラグがない場合はPopID()を呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{window->SkipItems?}
    B -->|Yes| C[return]
    B -->|No| D{CurrentTabBar != NULL?}
    D -->|No| E[アサーション失敗]
    D -->|Yes| F{LastTabItemIdx >= 0?}
    F -->|No| E
    F -->|Yes| G[タブアイテム取得]
    G --> H{NoPushIdフラグ?}
    H -->|No| I[PopID]
    H -->|Yes| J[終了]
    I --> J
    C --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-186-01 | ペアリング | BeginTabItemがtrueを返した場合のみ呼び出す | 常時 |
| BR-186-02 | コンテキスト検証 | g.CurrentTabBarがNULLの場合はエラー | 常時 |
| BR-186-03 | NoPushId | BeginTabItemでNoPushIdが指定された場合はPopIDしない | NoPushId時 |

### 計算ロジック

特になし

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

該当なし（ImGuiはUIライブラリであり、データベース操作は行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | アサーション | g.CurrentTabBarがNULL | IM_ASSERT_USER_ERROR_RET |
| N/A | アサーション | LastTabItemIdxが無効 | IM_ASSERT |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- タブアイテム終了処理は軽量であること

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

該当なし

## 備考

- BeginTabItemがfalseを返した場合、EndTabItemを呼び出してはならない
- ImGuiTabItemFlags_NoPushIdを使用した場合、IDスタックへの操作は行われない
- EndTabItemは非常にシンプルな関数で、主にPopIDの呼び出しのみを行う

---

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

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

### 推奨読解順序

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

まず、タブアイテムの終了処理に関連するデータを理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_internal.h | `imgui_internal.h` | ImGuiTabBar構造体のLastTabItemIdxフィールド |
| 1-2 | imgui_internal.h | `imgui_internal.h` | ImGuiTabItem構造体のFlagsフィールド |

**読解のコツ**: LastTabItemIdxは最後に処理されたタブアイテムのインデックスを保持し、EndTabItemで使用される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui_widgets.cpp | `imgui_widgets.cpp` | EndTabItem関数（10369-10382行目） |

**主要処理フロー**:
1. **10371-10374行目**: SkipItemsチェック
2. **10376-10378行目**: CurrentTabBarとLastTabItemIdxのアサーション
3. **10379行目**: タブアイテムの取得
4. **10380-10381行目**: NoPushIdでない場合のPopID

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

```
ImGui::EndTabItem()
    │
    ├─ (検証: SkipItems)
    │
    ├─ (アサーション: CurrentTabBar, LastTabItemIdx)
    │
    ├─ タブアイテム取得 (tab_bar->Tabs[LastTabItemIdx])
    │
    └─ PopID() [条件付き: !(tab->Flags & NoPushId)]
```

### データフロー図

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

g.CurrentTabBar ───▶ EndTabItem() ──────▶ IDスタック (ポップ)
LastTabItemIdx             │
                           ├─ コンテキスト検証
                           └─ PopID (条件付き)
```

### 関連ファイル一覧

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