# 通知設計書 11-CloseCurrentPopup

## 概要

本ドキュメントは、Dear ImGuiライブラリにおける`CloseCurrentPopup()`関数の設計仕様を記載する。この関数は、現在開いているポップアップウィンドウを手動で閉じるための通知メカニズムを提供する。

### 本通知の処理概要

`CloseCurrentPopup()`は、`BeginPopup()`/`EndPopup()`スコープ内で呼び出すことで、現在のポップアップウィンドウを閉じる処理を行う。ポップアップスタックを管理し、メニュー階層がある場合は親ポップアップまで閉じる機能も備える。

**業務上の目的・背景**：GUIアプリケーションにおいて、ユーザーがメニューアイテムを選択したり、ダイアログで操作を完了した後、ポップアップを明示的に閉じる必要がある。この関数は、プログラム的にポップアップを閉じるための標準的な手段を提供し、ユーザーエクスペリエンスの向上と一貫したUI動作を実現する。

**通知の送信タイミング**：ユーザーがSelectable()やMenuItem()をアクティベートした時にデフォルトで呼び出される。また、OKボタンやCancelボタンがクリックされた時など、開発者が明示的に呼び出すことも可能。

**通知の受信者**：ImGuiの内部ポップアップスタック管理システムが受信者となる。具体的には、`g.OpenPopupStack`と`g.BeginPopupStack`のスタック状態が更新される。

**通知内容の概要**：現在のBeginPopupスタックの最上位ポップアップを閉じる指示。メニュー階層の場合は、親のモーダルでないポップアップまで遡って閉じる。

**期待されるアクション**：ポップアップウィンドウが非表示になり、フォーカスが適切なウィンドウに戻る。ナビゲーションハイライトが一時的に非表示になる。

## 通知種別

内部API呼び出し / ポップアップ状態変更通知

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 高 |
| リトライ | 無し |

### 送信先決定ロジック

現在のBeginPopupStackから対象ポップアップを特定し、OpenPopupStackの対応するエントリを閉じる。メニュー階層の場合は、ImGuiWindowFlags_ChildMenuフラグを持つポップアップの親チェーンを辿り、モーダルでない最初の親まで閉じる。

## 通知テンプレート

### API呼び出し形式

| 項目 | 内容 |
|-----|------|
| 関数名 | CloseCurrentPopup() |
| 戻り値 | void |
| 引数 | なし |

### 使用例

```cpp
if (ImGui::BeginPopupModal("Save?", NULL, ImGuiWindowFlags_AlwaysAutoResize))
{
    ImGui::Text("Do you want to save changes?");
    if (ImGui::Button("OK", ImVec2(120, 0)))
    {
        // 保存処理を実行
        ImGui::CloseCurrentPopup();
    }
    ImGui::SameLine();
    if (ImGui::Button("Cancel", ImVec2(120, 0)))
    {
        ImGui::CloseCurrentPopup();
    }
    ImGui::EndPopup();
}
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| N/A | N/A | N/A | この通知には添付ファイルは存在しない |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| popup_idx | 閉じるポップアップのインデックス | g.BeginPopupStack.Size - 1 | Yes |
| PopupId | ポップアップの識別子 | g.OpenPopupStack[popup_idx].PopupId | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ユーザー操作 | Selectable/MenuItemのアクティベート | デフォルト動作 | ImGuiSelectableFlags_NoAutoClosePopupsが設定されていない場合 |
| 開発者呼び出し | Button等のクリック後 | BeginPopup/EndPopupスコープ内 | 明示的なポップアップクローズ |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| スタック不整合 | popup_idx < 0 または popup_idx >= g.OpenPopupStack.Size の場合 |
| ID不一致 | BeginPopupStackとOpenPopupStackのPopupIdが一致しない場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[CloseCurrentPopup呼び出し] --> B{popup_idx有効?}
    B -->|No| C[早期リターン]
    B -->|Yes| D{PopupId一致?}
    D -->|No| C
    D -->|Yes| E[メニュー階層チェック]
    E --> F{ChildMenuフラグ?}
    F -->|Yes| G{親がMenuBarでない?}
    G -->|Yes| H[popup_idxデクリメント]
    H --> E
    G -->|No| I[ClosePopupToLevel実行]
    F -->|No| I
    I --> J[NavHideHighlightOneFrame設定]
    J --> K[終了]
    C --> K
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| g.BeginPopupStack | 現在のポップアップ階層 | ImGuiPopupData配列 |
| g.OpenPopupStack | 開いているポップアップ | ImGuiPopupData配列 |

### テーブル別参照項目詳細

#### g.OpenPopupStack

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| PopupId | ポップアップ識別 | g.OpenPopupStack[popup_idx] |
| Window | ポップアップウィンドウ参照 | Flags確認用 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| g.OpenPopupStack | 削除 | ClosePopupToLevelで指定レベルまで削除 |

#### 送信ログテーブル

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| DEBUG_LOG | CloseCurrentPopup | %d -> %d | デバッグログ出力のみ |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| スタック不整合 | BeginPopup/EndPopupの対応不正 | 早期リターン（無視） |
| ID不一致 | 異なるコンテキストでの呼び出し | 早期リターン（無視） |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

即座に実行される同期処理のため、配信時間帯の制限なし。

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

この関数は内部状態の更新のみを行い、外部リソースへのアクセスや機密情報の処理は行わない。スタック操作は安全性チェックを経て実行される。

## 備考

- Selectable()およびMenuItem()では、アクティベート時にデフォルトでCloseCurrentPopup()が呼び出される
- この動作を抑止するにはImGuiSelectableFlags_NoAutoClosePopupsフラグを使用する
- メニュー階層ではモーダルウィンドウまで遡って閉じることに注意

---

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

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

### 推奨読解順序

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

ポップアップスタック管理に使用されるデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_internal.h | `imgui_internal.h` | ImGuiPopupData構造体の定義を確認 |
| 1-2 | imgui_internal.h | `imgui_internal.h` | ImGuiContext内のOpenPopupStack, BeginPopupStackを確認 |

**読解のコツ**: ImGuiPopupDataにはPopupId, Window, RestoreNavWindow等の重要なフィールドがある。

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

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

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

**主要処理フロー**:
1. **12317行**: popup_idxの算出（BeginPopupStack.Size - 1）
2. **12318行**: 有効性チェック（範囲とPopupId一致）
3. **12322-12332行**: メニュー階層のトラバース（ChildMenuフラグ確認）
4. **12335行**: ClosePopupToLevel呼び出し
5. **12340-12341行**: NavHideHighlightOneFrame設定

#### Step 3: 下位関数を理解する

ClosePopupToLevel関数の動作を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui.cpp | `imgui.cpp` | ClosePopupToLevel関数の実装 |

**主要処理フロー**:
- スタックのトリミング
- フォーカスの復元処理

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

```
CloseCurrentPopup()  [imgui.cpp:12314]
    |
    +-- popup_idx計算とバリデーション
    |
    +-- while: メニュー階層トラバース
    |       +-- ImGuiWindowFlags_ChildMenu確認
    |       +-- ImGuiWindowFlags_MenuBar確認
    |
    +-- ClosePopupToLevel()  [imgui.cpp:12275]
    |       +-- OpenPopupStack.resize()
    |       +-- FocusWindow() / FocusTopMostWindowUnderOne()
    |
    +-- NavHideHighlightOneFrame設定
```

### データフロー図

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

g.BeginPopupStack ───▶ popup_idx算出 ───▶ ClosePopupToLevel
        |                    |                     |
g.OpenPopupStack  ───▶ ID検証/階層探索 ───▶ OpenPopupStack更新
        |                    |                     |
Window.Flags     ───▶ ChildMenu判定  ───▶ フォーカス復元
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | CloseCurrentPopup関数宣言（859行目） |
| imgui.cpp | `imgui.cpp` | ソース | CloseCurrentPopup実装（12314行目） |
| imgui_internal.h | `imgui_internal.h` | 内部ヘッダー | ImGuiPopupData, ImGuiContext定義 |
| imgui_widgets.cpp | `imgui_widgets.cpp` | ソース | Selectable等からの呼び出し元 |
| imgui_demo.cpp | `imgui_demo.cpp` | デモ | 使用例（5453, 5456行目等） |
