# 画面設計書 101-DragDrop

## 概要

本ドキュメントは、IntegrationTestAppにおけるドラッグ＆ドロップ機能のテストページ（DragDropPage）の画面設計書です。

### 本画面の処理概要

本画面は、Avaloniaフレームワークのドラッグ＆ドロップ機能を統合テストするためのテストページです。ドラッグソースからドロップターゲットへの要素間データ転送機能をテストできます。

**業務上の目的・背景**：本画面は、Avaloniaフレームワークの品質保証のために存在します。ドラッグ＆ドロップ機能は、ファイル操作やUI要素の並べ替えなど多くのアプリケーションで使用される重要な機能です。この機能の正常動作を自動テストおよび手動テストで確認することで、フレームワーク全体の信頼性を向上させます。また、ドロップ位置の座標がウィンドウ原点からのオフセットを考慮して正しく計算されることを検証する目的があります。

**画面へのアクセス方法**：IntegrationTestAppのメインウィンドウから、ListBoxナビゲーションで「DragDrop」項目を選択することでアクセスします。

**主要な操作・処理内容**：
1. ドラッグソース（青い領域）をマウスでドラッグしてデータ転送を開始
2. ドロップターゲット（緑の領域）にドラッグしてドロップ位置を確認
3. ドロップ実行時に座標情報とドロップ結果がステータスに表示
4. Resetボタンで状態を初期化

**画面遷移**：
- 遷移元：IntegrationTestApp MainWindow（ListBoxナビゲーション）
- 遷移先：なし（テストページ単体）

**権限による表示制御**：本画面は統合テスト用のため、権限による表示制御は実装されていません。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 54 | DragDrop | 主機能 | ドラッグ＆ドロップのテスト。要素間のデータ転送機能の検証 |

## 画面種別

テスト画面

## URL/ルーティング

IntegrationTestApp内のUserControlとして読み込まれるため、URLルーティングはありません。
クラス名: `IntegrationTestApp.Pages.DragDropPage`

## 入出力項目

| 項目名 | 種別 | データ型 | 必須 | 説明 |
|--------|------|----------|------|------|
| ドラッグデータ | 入力 | Text | - | ドラッグ時に転送されるデータ（固定値: "TestDragData"） |
| ドロップ位置 | 出力 | Point | - | ドロップ時の座標情報 (X, Y) |
| ステータス | 出力 | string | - | ドラッグ＆ドロップ操作の結果状態 |

## 表示項目

| 項目名 | コントロール名 | 種別 | 説明 |
|--------|--------------|------|------|
| Drop Position | DropPosition | TextBlock | ドロップ位置の座標を表示 |
| Status | DragDropStatus | TextBlock | ドラッグ＆ドロップの状態（Dragging.../Copied/Moved/Cancelled等） |
| Spacer | - | Border | ウィンドウ原点からのオフセットを設定するスペーサー（高さ100px） |
| Drag Source | DragSource | Border | ドラッグ開始領域（青色、CornflowerBlue） |
| Drop Target | DropTarget | Border | ドロップ受付領域（緑色、LightGreen） |
| Drop Target Text | DropTargetText | TextBlock | ドロップ結果のテキスト表示 |
| Reset Button | ResetDragDrop | Button | 状態リセットボタン |

## イベント仕様

### 1-DragSource_PointerPressed

ドラッグソース領域でマウス左ボタンが押された際に発火します。

**処理フロー**:
1. 左ボタン押下を確認
2. DataTransferオブジェクトを生成し、テキストデータ "TestDragData" を追加
3. ステータスを "Dragging..." に更新
4. DragDrop.DoDragDropAsyncを呼び出してドラッグ操作を開始
5. ドロップ結果に応じてステータスを更新（Copied/Moved/Cancelled）

### 2-DropTarget_DragOver

ドロップターゲット上でドラッグ中の要素が移動した際に発火します。

**処理フロー**:
1. イベントソースがDropTargetまたはその子要素か確認
2. DragEffectsをCopyに設定
3. ドロップ位置の座標を "DragOver: (X, Y)" 形式で表示

### 3-DropTarget_Drop

ドロップターゲット上でドロップが実行された際に発火します。

**処理フロー**:
1. イベントソースがDropTargetまたはその子要素か確認
2. ドロップ位置の座標を取得
3. 座標がターゲット領域内かを検証
4. テキストデータを取得し、結果をDropTargetTextに表示
5. 領域外の場合はエラーメッセージを表示

### 4-ResetDragDrop_Click

Resetボタンがクリックされた際に発火します。

**処理フロー**:
1. DropPositionテキストをクリア
2. DragDropStatusテキストをクリア
3. DropTargetTextを初期値 "Drop items here" にリセット

## データベース更新仕様

本画面はUIテスト用であり、データベースとの連携はありません。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|------------|------|--------------|---------|
| MSG-001 | 情報 | Dragging... | ドラッグ開始時 |
| MSG-002 | 成功 | Copied | コピー操作でドロップ完了時 |
| MSG-003 | 成功 | Moved | 移動操作でドロップ完了時 |
| MSG-004 | 情報 | Cancelled | ドラッグ操作がキャンセルされた時 |
| MSG-005 | 成功 | Drop OK | 正常な位置にドロップされた時 |
| MSG-006 | エラー | Drop position ERROR | 領域外にドロップされた時 |
| MSG-007 | エラー | ERROR: Position out of bounds! (X, Y) | ドロップ位置が境界外の場合 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| ドラッグソースがnullの場合 | IsChildOfメソッドでfalseを返し、イベント処理をスキップ |
| ドロップターゲットが子要素でない場合 | イベント処理をスキップし、他のハンドラに処理を委譲 |
| DataTransferからテキスト取得失敗 | DropTargetTextの更新をスキップ |

## 備考

- 本画面は100pxのスペーサー行を設置し、ドラッグ＆ドロップのコントロールがウィンドウ原点(0,0)にないことを保証しています。これは座標計算の正確性をテストするためです。
- ドラッグデータは固定値 "TestDragData" が使用されます。
- AutomationProperties.AccessibilityViewが設定されており、UIオートメーションテストに対応しています。

---

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

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

### 推奨読解順序

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

まず、ドラッグ＆ドロップで使用されるデータ構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DataTransfer.cs | `src/Avalonia.Base/Input/DataTransfer.cs` | ドラッグ＆ドロップで転送されるデータを格納するクラス |
| 1-2 | DragDropEffects.cs | `src/Avalonia.Base/Input/DragDropEffects.cs` | ドラッグ操作の種類（Copy, Move, Link, None）を定義するenum |

**読解のコツ**: Avaloniaのドラッグ＆ドロップは、DataTransferクラスを通じてデータを転送します。DragDropEffectsはビットフラグとして組み合わせ可能です。

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

処理の起点となるXAMLファイルとコードビハインドを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DragDropPage.axaml | `samples/IntegrationTestApp/Pages/DragDropPage.axaml` | 画面レイアウトとイベントバインディングの定義 |
| 2-2 | DragDropPage.axaml.cs | `samples/IntegrationTestApp/Pages/DragDropPage.axaml.cs` | イベントハンドラの実装 |

**主要処理フロー**:
1. **行12-19**: コンストラクタでDragOverとDropイベントハンドラを登録
2. **行21-40**: DragSource_PointerPressedでドラッグ操作を開始
3. **行42-53**: DropTarget_DragOverでドラッグ中の位置を表示
4. **行55-80**: DropTarget_Dropでドロップ処理を実行
5. **行97-102**: ResetDragDrop_Clickで状態をリセット

#### Step 3: DragDropサービスを理解する

ドラッグ＆ドロップの中核となるサービスクラスを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DragDrop.cs | `src/Avalonia.Base/Input/DragDrop.cs` | DoDragDropAsyncメソッドとイベント定義 |
| 3-2 | DragEventArgs.cs | `src/Avalonia.Base/Input/DragEventArgs.cs` | ドラッグイベントの引数クラス |

**主要処理フロー**:
- **DragDrop.DoDragDropAsync**: 非同期でドラッグ＆ドロップ操作を実行
- **DragEventArgs.GetPosition**: ドロップ位置を相対座標で取得

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

```
DragDropPage
    │
    ├─ DragSource_PointerPressed (マウス押下)
    │      ├─ new DataTransfer()
    │      ├─ DataTransfer.Add(DataTransferItem.CreateText())
    │      └─ DragDrop.DoDragDropAsync()
    │              └─ プラットフォーム固有実装へ
    │
    ├─ DropTarget_DragOver (ドラッグ中)
    │      ├─ IsChildOf() - 子要素判定
    │      └─ DragEventArgs.GetPosition() - 位置取得
    │
    ├─ DropTarget_Drop (ドロップ時)
    │      ├─ DragEventArgs.GetPosition()
    │      ├─ DataTransfer.TryGetText()
    │      └─ 境界チェック処理
    │
    └─ ResetDragDrop_Click (リセット)
           └─ テキストクリア処理
```

### データフロー図

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

PointerPressed ───▶ DragDrop.DoDragDropAsync() ───▶ DragDropEffects
                           │
                           ▼
DragOver Event ───▶ GetPosition(DropTarget) ───▶ DropPosition.Text
                           │
                           ▼
Drop Event ───▶ TryGetText() + 境界チェック ───▶ DropTargetText.Text
                                                    DragDropStatus.Text
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DragDropPage.axaml | `samples/IntegrationTestApp/Pages/DragDropPage.axaml` | ソース | 画面レイアウト定義（XAML） |
| DragDropPage.axaml.cs | `samples/IntegrationTestApp/Pages/DragDropPage.axaml.cs` | ソース | イベントハンドラ実装（コードビハインド） |
| MainWindow.axaml | `samples/IntegrationTestApp/MainWindow.axaml` | ソース | 親ウィンドウ（ナビゲーション） |
| DragDrop.cs | `src/Avalonia.Base/Input/DragDrop.cs` | ソース | ドラッグ＆ドロップAPIの定義 |
| DataTransfer.cs | `src/Avalonia.Base/Input/DataTransfer.cs` | ソース | データ転送クラス |
| DragEventArgs.cs | `src/Avalonia.Base/Input/DragEventArgs.cs` | ソース | ドラッグイベント引数 |
