# 機能設計書 239-IsMouseHoveringRect

## 概要

本ドキュメントは、ImGuiライブラリにおけるマウスホバー矩形判定機能「IsMouseHoveringRect」の設計仕様を定義する。

### 本機能の処理概要

IsMouseHoveringRect関数は、マウスカーソルが指定された矩形領域（バウンディングレクト）の上にあるかどうかを判定する機能である。オプションでクリッピング領域を考慮した判定も可能である。フォーカス、ウィンドウの順序、ポップアップによるブロックなどは考慮されない、純粋な幾何学的判定を行う。

**業務上の目的・背景**：カスタムウィジェットやカスタム描画領域において、マウスが特定の領域上にあるかを判定する必要がある。標準のImGuiウィジェットはIsItemHoveredで判定できるが、カスタム領域ではIsMouseHoveringRectを使用する。この機能により、カスタムボタンやホットスポットの実装が可能となる。

**機能の利用シーン**：
- カスタムウィジェットでのホバー検出
- カスタム描画領域でのマウスインタラクション
- ツールチップ表示のトリガー（特定領域のホバー）
- ドラッグ&ドロップのドロップターゲット判定
- ゲームにおけるUI領域の判定
- ヒートマップやチャートでのマウス位置検出

**主要な処理内容**：
1. 矩形領域の指定（r_min、r_max）
2. クリッピング設定の適用（オプション）
3. タッチ入力用の拡張パディングを考慮したヒットテスト
4. マウス位置が矩形内にあるかの判定
5. 結果の返却

**関連システム・外部連携**：ImGuiIO構造体からマウス位置情報を取得。現在のウィンドウのClipRectと連携してクリッピングを行う。スタイル設定のTouchExtraPaddingを使用してタッチ入力に対応。

**権限による制御**：この関数はフォーカスやウィンドウの順序を考慮しない純粋な幾何学的判定のため、権限制御は行われない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 20 | Custom Rendering | 参照画面 | カスタム描画でのマウス判定使用 |

## 機能種別

入力判定処理 / ヒットテスト

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| r_min | const ImVec2& | Yes | 矩形の左上座標（スクリーン座標） | なし |
| r_max | const ImVec2& | Yes | 矩形の右下座標（スクリーン座標） | なし |
| clip | bool | No | クリッピング領域を考慮するか（デフォルトはtrue） | なし |

### 入力データソース

- ImGuiIO.MousePos：現在のマウス位置
- ImGuiWindow.ClipRect：現在のウィンドウのクリッピング矩形
- ImGuiStyle.TouchExtraPadding：タッチ入力用の拡張パディング

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | bool | マウスが矩形上にある場合true、それ以外はfalse |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 関数呼び出し（IsMouseHoveringRect(r_min, r_max, clip)）
   └─ グローバルコンテキストを取得

2. 矩形のクリッピング（clipがtrueの場合）
   └─ rect_clipped.ClipWith(g.CurrentWindow->ClipRect)で
      現在のウィンドウのクリップ領域と交差を計算

3. ヒットテスト
   └─ rect_clipped.ContainsWithPad(g.IO.MousePos, g.Style.TouchExtraPadding)
   └─ タッチ入力用の拡張パディングを考慮してマウス位置を判定

4. 結果の返却
   └─ ヒットテスト結果をそのまま返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: IsMouseHoveringRect] --> B[rect_clipped = ImRect r_min, r_max]
    B --> C{clip == true?}
    C -->|Yes| D[rect_clipped.ClipWith CurrentWindow->ClipRect]
    C -->|No| E[rect_clipped をそのまま使用]
    D --> F{rect_clipped.ContainsWithPad MousePos, TouchExtraPadding}
    E --> F
    F -->|No| G[return false]
    F -->|Yes| H[return true]
    G --> I[終了]
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-239-01 | スクリーン座標使用 | 矩形はスクリーン絶対座標で指定する必要がある | 常時 |
| BR-239-02 | クリッピング適用 | clip=trueの場合、現在のウィンドウのClipRectで矩形がクリップされる | clip=true時 |
| BR-239-03 | タッチパディング | TouchExtraPaddingを考慮した拡張ヒットテストを行う | 常時 |
| BR-239-04 | フォーカス非考慮 | この関数はフォーカス、ウィンドウ順序、ポップアップブロックを考慮しない | 常時 |

### 計算ロジック

ヒットテスト判定ロジック：
```
clipped_rect = (clip) ? Intersect(rect, CurrentWindow->ClipRect) : rect
IsMouseHoveringRect = clipped_rect.Contains(MousePos, TouchExtraPadding)
```

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

該当なし（メモリ上の状態データのみ参照）

## エラー処理

### エラーケース一覧

該当なし（幾何学的判定のため特にエラーは発生しない）

### リトライ仕様

該当なし（同期的な状態チェック関数のため）

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

該当なし

## パフォーマンス要件

- 処理時間：O(1)の定数時間で完了
- 1フレームあたり複数回呼び出し可能
- メモリアロケーションなし

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

該当なし（UIライブラリ内部のヒットテスト処理のみ）

## 備考

- フォーカスやウィンドウの順序を考慮した判定が必要な場合はIsWindowHoveredやIsItemHoveredを使用すること
- カスタムウィジェットでは、InvisibleButton + IsItemHoveredの組み合わせも推奨される
- 座標はスクリーン座標（GetCursorScreenPosで取得可能）で指定する必要がある

---

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

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

### 推奨読解順序

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

ヒットテストに関連するデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | ImVec2構造体で座標の表現を確認 |
| 1-2 | imgui_internal.h | `imgui_internal.h` | ImRect構造体でClipWith、ContainsWithPadメソッドを確認 |
| 1-3 | imgui.h | `imgui.h` | ImGuiStyle.TouchExtraPaddingでタッチパディングを確認 |

**読解のコツ**: ImRectはMin（左上）とMax（右下）を持つ矩形構造体。ContainsWithPadはパディングを考慮した包含判定を行う。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.h | `imgui.h` | IsMouseHoveringRect関数の宣言（1107行目） |
| 2-2 | imgui.cpp | `imgui.cpp` | 実装（9905-9918行目） |

**主要処理フロー**:
1. **9907行目**: グローバルコンテキストを取得
2. **9910行目**: ImRectを作成（r_min、r_max）
3. **9911-9912行目**: clip=trueの場合、ClipWithでクリッピング
4. **9915-9916行目**: ContainsWithPadでマウス位置を判定
5. **9917行目**: trueを返却

#### Step 3: 関連機能を理解する

クリッピングとヒットテストの詳細を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_internal.h | `imgui_internal.h` | ImRect::ClipWithメソッドで矩形の交差計算を確認 |
| 3-2 | imgui_internal.h | `imgui_internal.h` | ImRect::ContainsWithPadメソッドでパディング付き包含判定を確認 |

**主要処理フロー**:
- **ClipWith**: 2つの矩形の交差部分を計算
- **ContainsWithPad**: 指定された点がパディングを考慮して矩形内にあるかを判定

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

```
ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip)  [imgui.cpp:9905]
    │
    ├─ ImRect rect_clipped(r_min, r_max)
    │
    ├─ rect_clipped.ClipWith(g.CurrentWindow->ClipRect)  [clip=true時]
    │
    └─ rect_clipped.ContainsWithPad(g.IO.MousePos, g.Style.TouchExtraPadding)
```

### データフロー図

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

ImVec2 r_min, r_max      ───▶ ImRect rect_clipped を作成
bool clip                         │
                                  ▼
                         clip=true の場合
                         ClipWith(ClipRect)で
                         クリッピング適用
                                  │
                                  ▼
                         ContainsWithPad で
                         マウス位置判定
                         (TouchExtraPadding考慮)
                                  │
                                  ▼
                               bool結果を返却      ───▶ 呼び出し元
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | パブリックAPIの宣言、ImVec2定義 |
| imgui.cpp | `imgui.cpp` | ソース | IsMouseHoveringRectの実装 |
| imgui_internal.h | `imgui_internal.h` | ヘッダー | ImRect構造体の定義 |
| imgui_demo.cpp | `imgui_demo.cpp` | ソース | 使用例のデモコード |
