# 通知設計書 10-OpenPopupOnItemClick

## 概要

本ドキュメントは、Dear ImGuiライブラリにおけるOpenPopupOnItemClick API関数の設計・動作仕様を記載したものである。OpenPopupOnItemClickは直前のアイテムがクリックされた時にポップアップを開くヘルパー関数である。

### 本通知の処理概要

OpenPopupOnItemClickは、直前に描画されたUIアイテムがクリック（デフォルトは右クリック）された時にポップアップを開くための便利な関数である。内部的にはマウスボタンのリリースイベントを検出し、アイテムがホバーされている場合にOpenPopupExを呼び出す。

**業務上の目的・背景**：コンテキストメニューは、UIアイテムを右クリックした際に表示される標準的なUIパターンである。OpenPopupOnItemClickは、このパターンを簡潔に実装するためのヘルパー関数を提供する。BeginPopupContextItem()との違いは、OpenPopupOnItemClickはポップアップを開くだけで、BeginPopup()の呼び出しは別途必要な点である。

**通知の送信タイミング**：UIアイテムの描画直後に呼び出される。マウスボタンのリリースイベントが検出され、かつアイテムがホバーされている場合にのみポップアップが開かれる。

**通知の受信者**：Dear ImGuiの内部ポップアップスタック管理システム（OpenPopupStack）。条件を満たした場合にOpenPopupExが呼び出される。

**通知内容の概要**：アイテムクリック時のポップアップオープンリクエスト。str_idがNULLの場合は直前アイテムのIDが使用される。ImGuiPopupFlagsでマウスボタンやオプションを指定可能。

**期待されるアクション**：クリック条件を満たした場合、ポップアップがOpenPopupStackに登録され、次回のBeginPopup()呼び出しでtrueを返すようになる。

## 通知種別

UI内部通知（ImGuiポップアップスタック状態変更通知）

## 送信仕様

### 基本情報

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

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

OpenPopupOnItemClickの呼び出しは、直前のUIアイテムに対して行われる。ポップアップIDはstr_idが指定された場合はそのID、NULLの場合はLastItemData.IDが使用される。

## 通知テンプレート

### API関数シグネチャ

| 項目 | 内容 |
|-----|------|
| 関数名 | OpenPopupOnItemClick |
| 戻り値 | void |
| 引数 | const char* str_id = NULL, ImGuiPopupFlags popup_flags = 0 |
| 定義場所 | imgui.h:858 |

### 本文テンプレート

```cpp
// 基本的な使用パターン（デフォルトは右クリック）
ImGui::Button("右クリックで開く");
ImGui::OpenPopupOnItemClick("context_menu");

if (ImGui::BeginPopup("context_menu"))
{
    ImGui::MenuItem("アイテム1");
    ImGui::MenuItem("アイテム2");
    ImGui::EndPopup();
}

// str_id=NULLで直前アイテムのIDを使用
ImGui::Button("ボタン##unique");
ImGui::OpenPopupOnItemClick();  // "ボタン##unique"のIDを使用

if (ImGui::BeginPopup("ボタン##unique"))
{
    ImGui::MenuItem("アイテム");
    ImGui::EndPopup();
}

// 左クリックで開く場合
ImGui::Button("左クリックで開く");
ImGui::OpenPopupOnItemClick("popup", ImGuiPopupFlags_MouseButtonLeft);
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| str_id | ポップアップ識別子（NULLで直前アイテムID） | 呼び出し元から渡される | No |
| popup_flags | ポップアップフラグ | 呼び出し元から渡される | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API呼び出し | OpenPopupOnItemClick()呼び出し | マウスリリース + アイテムホバー | デフォルトは右クリック |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| IsMouseReleased()がfalse | 指定されたマウスボタンがリリースされていない |
| IsItemHovered()がfalse | アイテムがホバーされていない |
| str_id=NULL && LastItemData.ID == 0 | 直前アイテムにIDがない場合はアサーション失敗 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[OpenPopupOnItemClick呼び出し] --> B[マウスボタン取得]
    B --> C{IsMouseReleased?}
    C -->|No| D[処理終了（何もしない）]
    C -->|Yes| E{IsItemHovered<br/>AllowWhenBlockedByPopup?}
    E -->|No| D
    E -->|Yes| F{str_id != NULL?}
    F -->|Yes| G[GetID(str_id)]
    F -->|No| H[LastItemData.ID使用]
    G --> I{ID != 0?}
    H --> I
    I -->|No| J[IM_ASSERT失敗]
    I -->|Yes| K[OpenPopupEx呼び出し]
    K --> L[終了]
    D --> L
    J --> L
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| ImGuiContext (GImGui) | グローバルコンテキスト | アイテム状態・マウス状態 |

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

#### ImGuiContext

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| CurrentWindow | 現在のウィンドウ | ID計算用 |
| LastItemData | 直前アイテム情報 | str_id=NULL時 |
| IO.MouseReleased | マウスリリース状態 | IsMouseReleased() |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| OpenPopupStack | PUSH/UPDATE | 条件を満たした場合のみ |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| アサーション失敗 | str_id=NULL && LastItemData.ID == 0 | 明示的なstr_idを指定する |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0 |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（即座に実行される同期処理）

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

特になし。ローカルUIレンダリング処理のため、外部通信やデータ永続化は行わない。

## 備考

- デフォルトは右クリック（ImGuiPopupFlags_MouseButtonRight）
- バージョン1.92.6でデフォルト値が変更された（popup_flags = 1 から = 0 へ）
- str_id=NULLの場合、直前アイテムのIDが使用される（Text()など識別子のないアイテムでは使用不可）
- BeginPopupContextItem()との違い: この関数はOpenPopupのみ行い、BeginPopupは呼び出さない
- マウスボタンのリリースイベントで発火する（クリックではなくリリース）
- ImGuiHoveredFlags_AllowWhenBlockedByPopupを使用してホバー判定を行う

---

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

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

### 推奨読解順序

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

マウスボタンフラグとポップアップフラグを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | ImGuiPopupFlags定義（1337-1352行目） |
| 1-2 | imgui.h | `imgui.h` | ImGuiPopupFlags_MouseButtonXXX（1340-1342行目） |

**読解のコツ**: マウスボタンフラグがビットシフトで定義されていることを理解する。

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

OpenPopupOnItemClickの宣言と実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.h | `imgui.h` | OpenPopupOnItemClick API宣言（858行目） |
| 2-2 | imgui.cpp | `imgui.cpp` | OpenPopupOnItemClick実装（12468-12479行目） |

**主要処理フロー**:
1. **12472行目**: GetMouseButtonFromPopupFlagsでマウスボタン取得
2. **12473行目**: IsMouseReleased + IsItemHoveredチェック
3. **12475行目**: ID計算（str_id or LastItemData.ID）
4. **12476行目**: IM_ASSERTでID検証
5. **12477行目**: OpenPopupEx呼び出し

#### Step 3: GetMouseButtonFromPopupFlagsを理解する

マウスボタンの取得ロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui.cpp | `imgui.cpp` | GetMouseButtonFromPopupFlags実装（12456-12464行目） |

**主要処理フロー**:
- フラグからマウスボタンを抽出
- デフォルトは右クリック（ImGuiMouseButton_Right）

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

```
OpenPopupOnItemClick(str_id, popup_flags) [imgui.cpp:12468]
    │
    ├─ GetMouseButtonFromPopupFlags(popup_flags) [マウスボタン取得]
    │       └─ デフォルト: ImGuiMouseButton_Right
    │
    ├─ IsMouseReleased(mouse_button) [マウスリリース確認]
    │
    ├─ IsItemHovered(AllowWhenBlockedByPopup) [ホバー確認]
    │
    ├─ ID計算
    │       │
    │       ├─ [str_id指定] CurrentWindow->GetID(str_id)
    │       │
    │       └─ [str_id=NULL] g.LastItemData.ID
    │
    └─ OpenPopupEx(id, popup_flags) [imgui.cpp:12172]
           └─ OpenPopupStack更新
```

### データフロー図

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

str_id (NULL可)    ───▶ OpenPopupOnItemClick()   ───▶ void
popup_flags               │
                          ▼
popup_flags        ───▶ GetMouseButtonFromPopupFlags()
                          │
                          ▼
IO.MouseReleased   ───▶ IsMouseReleased()
                          │
                          ▼ (trueの場合)
LastItemData       ───▶ IsItemHovered()
                          │
                          ▼ (trueの場合)
                       ID計算
                          │
                          ▼
                     OpenPopupEx()               ───▶ ポップアップ登録
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ソース | API宣言・フラグ定義 |
| imgui.cpp | `imgui.cpp` | ソース | 実装本体 |
