# 機能設計書 242-GetMouseDragDelta

## 概要

本ドキュメントは、Dear ImGuiライブラリにおけるGetMouseDragDelta関数の機能設計について記述する。この関数はマウスドラッグ操作における移動差分を取得するためのユーティリティ関数である。

### 本機能の処理概要

GetMouseDragDelta関数は、マウスボタンを押下してからの移動量（ドラッグ差分）を取得する機能を提供する。初期クリック位置からのマウス移動量を計算し、ドラッグ操作が一定のしきい値を超えた場合にのみ有効な値を返す。これにより、意図しない微小な移動をドラッグとして誤検出することを防止する。

**業務上の目的・背景**：GUIアプリケーションにおいて、ドラッグ&ドロップ操作、ウィンドウのリサイズ、スライダーの操作、カスタムウィジェットの操作など、マウスのドラッグ移動量に基づいた処理は非常に一般的である。この関数は、ドラッグ操作の移動量を取得するための標準的な手段を提供し、しきい値による誤検出防止機能も内蔵している。

**機能の利用シーン**：ドラッグ可能なウィジェットの移動量計算、カスタムスライダーの値調整、ドラッグ&ドロップ操作での移動距離の取得、リサイズハンドルの移動量計算、カスタム描画キャンバスでのパン操作などに使用される。

**主要な処理内容**：
1. 指定されたマウスボタンの状態を確認
2. しきい値（lock_threshold）を決定（負の場合はIO設定から取得）
3. ドラッグ最大距離がしきい値を超えているかチェック
4. マウス位置が有効かどうかを検証
5. 現在位置とクリック開始位置の差分を計算して返却

**関連システム・外部連携**：バックエンドがマウス入力を処理し、ImGuiIO構造体のMousePos、MouseDown、MouseClickedPos等の値を更新する。この関数はそれらの値を読み取って計算を行う。

**権限による制御**：本機能に権限による制御は存在しない。コンテキストが有効であれば常に呼び出し可能である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 27 | Inputs | 補助機能 | マウスドラッグ判定のデモ |

## 機能種別

読取処理 / 計算処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| button | ImGuiMouseButton | No (デフォルト: 0) | 対象のマウスボタン（0=左、1=右、2=中） | 0-2の範囲内 |
| lock_threshold | float | No (デフォルト: -1.0f) | ドラッグ開始のしきい値（負の場合はio.MouseDraggingThresholdを使用） | - |

### 入力データソース

- ImGuiIO::MouseDown[] - 各マウスボタンの押下状態
- ImGuiIO::MouseReleased[] - 各マウスボタンのリリース状態
- ImGuiIO::MouseClickedPos[] - 各マウスボタンのクリック開始位置
- ImGuiIO::MousePos - 現在のマウス位置
- ImGuiIO::MouseDragMaxDistanceSqr[] - ドラッグ中の最大移動距離（二乗）
- ImGuiIO::MouseDraggingThreshold - デフォルトのドラッグしきい値

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | ImVec2 | クリック開始位置からの移動量（ピクセル単位） |
| x | float | 水平方向の移動量 |
| y | float | 垂直方向の移動量 |

### 出力先

- 呼び出し元への戻り値として返却
- しきい値未満の場合は(0.0f, 0.0f)を返却

## 処理フロー

### 処理シーケンス

```
1. グローバルコンテキスト取得
   └─ GImGuiを逆参照
2. ボタン番号の検証
   └─ アサーションで範囲チェック
3. しきい値の決定
   └─ 負の場合はio.MouseDraggingThresholdを使用
4. ドラッグ状態の確認
   ├─ MouseDownまたはMouseReleasedがtrue
   └─ MouseDragMaxDistanceSqrがしきい値の二乗以上
5. マウス位置の有効性確認
   ├─ 現在位置が有効か
   └─ クリック開始位置が有効か
6. 差分計算と返却
   └─ 条件を満たせば差分を、満たさなければ(0,0)を返却
```

### フローチャート

```mermaid
flowchart TD
    A[GetMouseDragDelta呼び出し] --> B[コンテキスト取得]
    B --> C{lock_threshold < 0?}
    C -->|Yes| D[io.MouseDraggingThreshold使用]
    C -->|No| E[指定値を使用]
    D --> F{MouseDown or MouseReleased?}
    E --> F
    F -->|No| G[ImVec2{0,0}を返却]
    F -->|Yes| H{距離 >= しきい値?}
    H -->|No| G
    H -->|Yes| I{両位置が有効?}
    I -->|No| G
    I -->|Yes| J[差分を計算]
    J --> K[ImVec2を返却]
    G --> L[終了]
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-242-1 | しきい値ロック | しきい値を超えるまでは(0,0)を返す | ドラッグ開始時 |
| BR-242-2 | ボタンリリース後も有効 | ボタンを離した直後のフレームでも値を取得可能 | MouseReleased時 |
| BR-242-3 | 無効位置での無効化 | マウス位置が無効な場合は(0,0)を返す | マウス利用不可時 |

### 計算ロジック

```
差分 = 現在のマウス位置 - クリック開始位置
     = g.IO.MousePos - g.IO.MouseClickedPos[button]

ドラッグ判定 = g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold
```

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

### 操作別データベース影響一覧

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | アサーション違反 | button < 0 または button >= IM_COUNTOF(g.IO.MouseDown) | 有効なボタン番号（0-2）を指定 |
| - | コンテキスト未初期化 | GImGuiがNULL | CreateContext()を先に呼び出す |

### リトライ仕様

リトライ処理は不要。

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

本機能はトランザクション処理を行わない。

## パフォーマンス要件

- 処理時間: O(1) - 単純な条件判定と減算のみ
- メモリ使用: 追加のメモリ割り当てなし
- 呼び出し頻度: 毎フレーム複数回呼び出し可能

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

- マウスドラッグ情報は機密性の低いデータ
- 入力値の範囲検証はアサーションで実施
- 外部への情報漏洩リスクなし

## 備考

- ResetMouseDragDelta()関数で差分をリセット可能
- IsMouseDragging()関数でドラッグ中かどうかの判定が可能
- バックエンドはウィンドウ外でもマウス位置を有効に保つ必要がある

---

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

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

### 推奨読解順序

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

マウスドラッグに関連するデータがImGuiIO内でどのように管理されているかを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | ImGuiIO構造体のMouseDown、MouseClickedPos、MouseDragMaxDistanceSqr定義 |
| 1-2 | imgui.h | `imgui.h` | ImGuiIO::MouseDraggingThreshold - デフォルトしきい値設定 |

**読解のコツ**: ImGuiIOには複数のマウス関連配列があり、それぞれボタンごと（最大5ボタン）の状態を保持している。

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

関数の実装を確認する。

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

**主要処理フロー**:
1. **9993行目**: ボタン番号の範囲チェック（アサーション）
2. **9994-9995行目**: しきい値の決定
3. **9996行目**: MouseDownまたはMouseReleasedの確認
4. **9997行目**: 最大移動距離がしきい値を超えているか確認
5. **9998行目**: 両方のマウス位置が有効かをIsMousePosValidで確認
6. **9999行目**: 現在位置 - クリック開始位置の差分を計算
7. **10000行目**: 条件を満たさない場合は(0,0)を返却

#### Step 3: 関連する補助関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui.cpp | `imgui.cpp` | IsMousePosValid関数（9967-9973行目）- 位置の有効性判定 |
| 3-2 | imgui.cpp | `imgui.cpp` | ResetMouseDragDelta関数（10003行目付近）- 差分のリセット |
| 3-3 | imgui.cpp | `imgui.cpp` | IsMouseDragging関数 - ドラッグ中判定 |

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

```
GetMouseDragDelta(button, lock_threshold)
    │
    ├─ g.IO.MouseDraggingThreshold (しきい値取得)
    │
    ├─ g.IO.MouseDown[button] (押下状態確認)
    │
    ├─ g.IO.MouseReleased[button] (リリース状態確認)
    │
    ├─ g.IO.MouseDragMaxDistanceSqr[button] (最大距離確認)
    │
    ├─ IsMousePosValid(&g.IO.MousePos)
    │      └─ マウス位置有効性チェック
    │
    ├─ IsMousePosValid(&g.IO.MouseClickedPos[button])
    │      └─ クリック開始位置有効性チェック
    │
    └─ g.IO.MousePos - g.IO.MouseClickedPos[button] (差分計算)
```

### データフロー図

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

バックエンド                     GetMouseDragDelta()         呼び出し元
    │                                │                          │
    ├── MouseDown更新 ─────────────▶ │                          │
    ├── MouseClickedPos更新 ────────▶ │ 条件判定                  │
    ├── MousePos更新 ──────────────▶ │    │                      │
    └── MouseDragMaxDistanceSqr ───▶ │    ▼                      │
                                     │ 差分計算                   │
                                     │    │                      │
                                     └────┴─────────────────────▶ ImVec2
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | 関数宣言、ImGuiIO構造体定義 |
| imgui.cpp | `imgui.cpp` | ソース | GetMouseDragDelta関数の実装 |
| imgui_impl_*.cpp | `backends/` | バックエンド | マウス状態を更新するプラットフォーム実装 |
