# 通知設計書 36-NOTIFICATION_MOUSE_EXIT

## 概要

本ドキュメントは、GodotエンジンのControlクラスにおけるNOTIFICATION_MOUSE_EXIT通知の設計仕様を記載する。この通知はマウスカーソルがUIコントロールの領域から出た際に発火され、ホバー状態の解除や通常状態への復帰を可能にする重要なイベントである。

### 本通知の処理概要

NOTIFICATION_MOUSE_EXITは、マウスカーソルがControlノードの境界から出た際にViewportから発行される通知である。NOTIFICATION_MOUSE_ENTER（値41）とペアで使用され、ホバー状態の終了を検出するために使用される。

**業務上の目的・背景**：ユーザーインターフェースにおいて、マウスホバー終了時のフィードバックは開始時と同様に重要である。ボタンの通常色への復帰、ツールチップの非表示、カーソル形状のリセットなど、ホバー解除時の視覚的フィードバックを実装するためにこの通知が使用される。

**通知の送信タイミング**：Viewportがマウス位置を追跡し、カーソルが現在のControlの領域（has_point()がfalseを返す領域）に出た際に発火される。新しいコントロールに移動した場合は、古いコントロールへのMOUSE_EXITが先に発行され、その後新しいコントロールへのMOUSE_ENTERが発行される。

**通知の受信者**：現在ホバー状態にあるControlノード。BaseButton派生クラス、Slider、ScrollBar、Treeなど、NOTIFICATION_MOUSE_ENTERを処理するすべてのUI要素が対応する受信者となる。

**通知内容の概要**：通知値は42（NOTIFICATION_MOUSE_EXIT = 42）として定義され、マウスカーソルがコントロール領域から出たことを示す。

**期待されるアクション**：受信ノードはホバー状態を解除し、通常状態の外観に戻す。典型的な処理として、ホバーフラグのリセット、通常スタイルへの復帰、queue_redraw()による再描画がある。通知後には「mouse_exited」シグナルも発行される。

## 通知種別

ゲームエンジン内部通知（Object._notificationで受信）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（マウス移動イベント処理中に発行） |
| 優先度 | 中（視覚的フィードバックに使用） |
| リトライ | なし（一度のみ発行） |

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

1. マウスカーソルが現在ホバー中のControl領域から出る
2. 新しいコントロールへの移動時は、先にMOUSE_EXITが発行される
3. ウィンドウ外への移動時も発行される
4. 上記条件を満たすControlノードに対してnotification()が呼び出される

## 通知テンプレート

### 内部通知の場合

| 項目 | 内容 |
|-----|------|
| 通知定数名 | NOTIFICATION_MOUSE_EXIT |
| 通知値 | 42 |
| 逆順送信 | false（通常順） |
| 形式 | 整数値（int p_what） |

### 本文テンプレート

```cpp
// _notification()での受信例
void MyButton::_notification(int p_what) {
    switch (p_what) {
        case NOTIFICATION_MOUSE_EXIT: {
            // マウスが出た
            is_hovered = false;
            // 通常状態の描画に切り替え
            queue_redraw();
        } break;
    }
}

// GDScriptでの例
func _notification(what):
    if what == NOTIFICATION_MOUSE_EXIT:
        # ホバー終了処理
        modulate = Color(1.0, 1.0, 1.0)  # 通常色に戻す
```

### 添付ファイル

該当なし（内部通知のため）

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| p_what | 通知種別 | notification()引数 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| マウス移動 | InputEventMouseMotion | カーソルがControl領域から出る | 通常のホバー終了 |
| 別コントロールへ | 他のコントロールに入る | 現在のコントロールから出る | コントロール間移動 |
| ウィンドウ外 | ウィンドウ外へカーソル移動 | 現在のコントロールから出る | アプリ外への移動 |
| コントロール非表示 | hide()または削除 | ホバー中のコントロールが非表示に | 強制的なホバー終了 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 未ホバー | そもそもホバー状態でない場合 |
| 同一コントロール | 領域内での移動（EXITは発生しない） |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[マウス移動イベント] --> B[Viewportがマウス位置を処理]
    B --> C{現在ホバー中のコントロールあり?}
    C -->|No| D[処理終了]
    C -->|Yes| E{まだそのコントロール領域内?}
    E -->|Yes| D
    E -->|No| F[NOTIFICATION_MOUSE_EXIT発行]
    F --> G[派生クラス_notification処理]
    G --> H[mouse_exitedシグナル発行]
    H --> I{新しいコントロールあり?}
    I -->|Yes| J[新コントロールにMOUSE_ENTER通知]
    I -->|No| D
    J --> D
```

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

### 参照テーブル一覧

該当なし（ゲームエンジン内部処理のためデータベースは使用しない）

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

該当なし

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ノード削除 | ホバー中にノードが削除される | 削除前に自動的にEXIT通知 |
| 非表示化 | ホバー中にノードが非表示になる | 非表示時に自動的にEXIT通知 |
| 状態不整合 | ENTER無しでEXITが発生 | 状態フラグの防御的チェック |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（マウス移動に依存） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

エンジン実行中、マウス入力処理時に発火。

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

エンジン内部通知のため、外部からの直接的なセキュリティリスクはない。

## 備考

- NOTIFICATION_MOUSE_ENTER（値41）とペアで必ず使用
- NOTIFICATION_MOUSE_EXIT_SELF（値61）との違い：MOUSE_EXITは子への伝播による退出を含む、MOUSE_EXIT_SELFは自身の領域からの直接退出のみ
- コントロールが削除または非表示になった場合も発行される（状態整合性維持）

---

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

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

### 推奨読解順序

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

まず、Controlクラスの構造と通知定数の定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | control.h | `scene/gui/control.h` | NOTIFICATION_MOUSE_EXIT = 42定義（426行目） |

**読解のコツ**: 値42はNOTIFICATION_MOUSE_ENTER（41）の直後に定義されている。

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

Viewportからの通知発行メカニズムを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | viewport.cpp | `scene/main/viewport.cpp` | マウス位置追跡とMOUSE_EXIT通知発行 |

#### Step 3: 派生クラスでの処理例を理解する

BaseButtonなどの派生クラスでの具体的な処理パターンを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | base_button.cpp | `scene/gui/base_button.cpp` | NOTIFICATION_MOUSE_EXIT処理（ホバー解除） |
| 3-2 | slider.cpp | `scene/gui/slider.cpp` | NOTIFICATION_MOUSE_EXIT処理 |
| 3-3 | scroll_bar.cpp | `scene/gui/scroll_bar.cpp` | NOTIFICATION_MOUSE_EXIT処理 |

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

```
Viewport::_gui_input_event(InputEventMouseMotion)
    │
    └─ マウス位置判定
           │
           └─ 現在のコントロールから出た
                  │
                  └─ 旧コントロール::notification(MOUSE_EXIT)
                         │
                         └─ 派生クラス::_notification()
                                │
                                └─ ホバー解除・再描画
```

### データフロー図

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

マウス移動 ───▶ Viewport処理 ───▶ notification(42)
イベント            │                     │
                    ├─ 領域外判定         ├─▶ 派生クラス処理
                    │                     │    (ホバー解除)
                    └─ ホバー状態管理     └─▶ "mouse_exited"シグナル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| control.h | `scene/gui/control.h` | ヘッダ | Controlクラス定義、NOTIFICATION定数 |
| control.cpp | `scene/gui/control.cpp` | ソース | _notification()実装 |
| viewport.cpp | `scene/main/viewport.cpp` | ソース | マウスイベント処理、通知発行 |
| base_button.cpp | `scene/gui/base_button.cpp` | ソース | ボタンでの通知処理例 |
| slider.cpp | `scene/gui/slider.cpp` | ソース | スライダーでの通知処理例 |
| scroll_bar.cpp | `scene/gui/scroll_bar.cpp` | ソース | スクロールバーでの通知処理例 |
| split_container.cpp | `scene/gui/split_container.cpp` | ソース | 分割コンテナでの通知処理例 |
| tree.cpp | `scene/gui/tree.cpp` | ソース | ツリーでの通知処理例 |
| Control.xml | `doc/classes/Control.xml` | ドキュメント | 公式APIドキュメント |
