# 機能設計書 216-IsItemDeactivatedAfterEdit

## 概要

本ドキュメントは、ImGuiのIsItemDeactivatedAfterEdit関数の機能設計書である。直前に追加されたアイテムが「編集を行った後に非アクティブになった瞬間」かを判定する機能について記載する。

### 本機能の処理概要

IsItemDeactivatedAfterEdit関数は、直前に追加されたウィジェット（アイテム）が、アクティブ状態で値を変更（編集）した後に非アクティブ状態になった瞬間かを判定するAPIである。単なる非アクティブ化ではなく、「編集を伴う非アクティブ化」のみを検出できる。

**業務上の目的・背景**：Undo/Redoシステムにおいて、ユーザーが実際に値を変更した編集操作のみを履歴に記録したい場合に重要となる。例えば、スライダーをドラッグして値を変更した場合は履歴に追加すべきだが、スライダーをクリックして何も変更せずにリリースした場合は履歴に追加すべきではない。本機能はこの区別を可能にする。

**機能の利用シーン**：
- Undo/Redoシステムで編集を伴う操作のみを履歴に記録する場合
- 編集完了時にデータを保存するが、変更がない場合は保存をスキップしたい場合
- 連続編集ウィジェット（スライダー/ドラッグ）の編集完了検出

**主要な処理内容**：
1. IsItemDeactivated()で非アクティブ化を確認
2. DeactivatedItemData.HasBeenEditedBeforeで編集があったかを確認
3. 両方の条件が満たされた場合にtrueを返却

**関連システム・外部連携**：ImGuiの内部状態管理システム（ImGuiContext）のDeactivatedItemData.HasBeenEditedBeforeを参照する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Demo Window | 参照画面 | Querying StatusセクションでIsItemDeactivatedAfterEditの動作確認 |
| 23 | Widgets | 参照画面 | 各ウィジェットの編集完了検出 |

## 機能種別

状態判定 / クエリ機能

## 入力仕様

### 入力パラメータ

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

### 入力データソース

- IsItemDeactivated()の結果 - 非アクティブ化判定
- ImGuiContext::DeactivatedItemData.HasBeenEditedBefore - 編集が行われたかのフラグ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | bool | 編集後に非アクティブになった場合true、それ以外はfalse |

### 出力先

呼び出し元への戻り値として返却

## 処理フロー

### 処理シーケンス

```
1. 非アクティブ化判定
   └─ IsItemDeactivated()を呼び出し
2. 編集有無確認
   └─ g.DeactivatedItemData.HasBeenEditedBeforeを確認
3. 結果返却
   └─ 両方がtrueの場合にtrueを返却
```

### フローチャート

```mermaid
flowchart TD
    A[IsItemDeactivatedAfterEdit呼び出し] --> B{IsItemDeactivated()?}
    B -->|No| F[false を返却]
    B -->|Yes| C{HasBeenEditedBefore?}
    C -->|Yes| E[true を返却]
    C -->|No| F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-216-01 | 編集必須 | 単にアクティブ→非アクティブの遷移だけでなく、アクティブ中に編集が行われた場合のみtrueを返す | 常時 |
| BR-216-02 | 偽陽性の可能性 | Combo()/ListBox()/Selectable()などは既に選択されている項目をクリックした場合でもtrueを返す可能性がある | 特定ウィジェット使用時 |
| BR-216-03 | Undo/Redoパターン | 連続編集を行うウィジェットでのUndo/Redo実装に最適 | Slider/Drag系ウィジェット |

### 計算ロジック

```cpp
bool ImGui::IsItemDeactivatedAfterEdit()
{
    ImGuiContext& g = *GImGui;
    return IsItemDeactivated() && g.DeactivatedItemData.HasBeenEditedBefore;
}
```

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

該当なし（GUIフレームワーク内部の状態参照のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 偽陽性 | Combo/ListBox/Selectableで既選択項目をクリック | アプリケーション側で追加判定が必要 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- IsItemDeactivated()の呼び出しと単純なフラグ確認のみの軽量な処理
- フレームごとに複数回呼び出しても問題なし

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

該当なし

## 備考

- **重要**: 一部のウィジェット（Combo(), ListBox(), Selectable()など）では、既に選択されている項目をクリックした場合でもtrueを返すことがある。これは「偽陽性」であり、厳密な編集検出が必要な場合はアプリケーション側で追加の判定ロジックが必要
- 旧名称は`IsItemDeactivatedAfterChange`（v1.63以前）であった
- SliderやDragなどの連続編集ウィジェットでUndo/Redoを実装する際の推奨パターン:
  1. IsItemActivated()で開始値を保存
  2. IsItemDeactivatedAfterEdit()で終了値を確定し、履歴に追加

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_internal.h | `imgui_internal.h` | ImGuiDeactivatedItemData構造体、特にHasBeenEditedBeforeフィールド（1451-1457行目） |

**読解のコツ**: HasBeenEditedBeforeフラグは、アイテムがアクティブ状態の間に少なくとも1回編集が行われたことを記録する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.h | `imgui.h` | 関数宣言（1014行目）と重要なコメント（偽陽性について） |
| 2-2 | imgui.cpp | `imgui.cpp` | 関数実装（6219-6223行目） |

**主要処理フロー**:
1. **6219行目**: 関数定義
2. **6221行目**: ImGuiContext参照の取得
3. **6222行目**: IsItemDeactivated() && HasBeenEditedBeforeの判定

#### Step 3: 依存関数を理解する

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

#### Step 4: 歴史的経緯を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | imgui.h | `imgui.h` | 旧名称IsItemDeactivatedAfterChangeのコメント（4104行目付近） |

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

```
ImGui::IsItemDeactivatedAfterEdit()
    │
    ├─ ImGui::IsItemDeactivated()
    │      └─ 非アクティブ化の判定
    │
    └─ g.DeactivatedItemData.HasBeenEditedBefore
           └─ 編集が行われたかの判定
```

### データフロー図

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

IsItemDeactivated() ──────────┐
                              │
                              ├──▶ AND判定 ────────▶ bool (true/false)
                              │
g.DeactivatedItemData         │
    └─ HasBeenEditedBefore ───┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | 公開API宣言、偽陽性についてのコメント |
| imgui.cpp | `imgui.cpp` | ソース | 関数実装 |
| imgui_internal.h | `imgui_internal.h` | ヘッダー | ImGuiDeactivatedItemData構造体定義 |
| imgui_demo.cpp | `imgui_demo.cpp` | デモ | 使用例（2157行目） |
