# 機能設計書 54-DragDrop

## 概要

本ドキュメントは、Avaloniaフレームワークにおけるドラッグ＆ドロップ（DragDrop）機能の設計仕様を定義する。DragDropは、UI要素間でのデータ転送操作を実現するための静的クラスであり、ルーテッドイベントとデータ転送インターフェースを提供する。

### 本機能の処理概要

DragDropは、Avaloniaアプリケーションにおけるドラッグ＆ドロップ操作を実現するためのAPIを提供する静的クラスである。ドラッグ操作の開始、ドラッグ中の視覚的フィードバック、ドロップターゲットへのデータ配信を統一的に管理する。

**業務上の目的・背景**：ドラッグ＆ドロップは、ファイルマネージャー、メールクライアント、デザインツールなど多くのアプリケーションで直感的なデータ操作を可能にする重要な機能である。DragDropは、クロスプラットフォームで一貫したドラッグ＆ドロップ体験を提供し、開発者がプラットフォーム固有の実装を意識することなくデータ転送機能を実装できるようにする。

**機能の利用シーン**：
- ファイルのフォルダ間移動・コピー
- リスト項目の並び替え
- 外部アプリケーションからのファイルドロップ
- テキストや画像のドラッグコピー
- カスタムデータ型の転送

**主要な処理内容**：
1. DragEnter/DragLeave/DragOver/Dropの4つのルーテッドイベント定義
2. AllowDrop添付プロパティによるドロップ受け入れ制御
3. DoDragDropAsyncによる非同期ドラッグ操作の開始
4. IDataTransferインターフェースによるデータ転送
5. DragDropEffects（Copy/Move/Link/None）による操作種別指定

**関連システム・外部連携**：IPlatformDragSource（プラットフォーム固有実装）、IDataTransfer、DragDropDeviceと連携。OS固有のドラッグ＆ドロップAPIを抽象化。

**権限による制御**：AllowDrop添付プロパティでドロップ受け入れを制御可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | Clipboard | 主機能 | クリップボード操作のデモ。コピー・ペースト機能 |
| 30 | Drag+Drop | 主機能 | ドラッグ＆ドロップのデモ。要素間のデータ転送 |
| 101 | DragDrop | 主機能 | ドラッグ＆ドロップのテスト |

## 機能種別

データ転送 / イベント処理 / ユーザーインタラクション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| triggerEvent | PointerEventArgs | Yes | ドラッグを開始するポインターイベント | nullチェック |
| dataTransfer | IDataTransfer | Yes | 転送するデータ | nullチェック |
| allowedEffects | DragDropEffects | Yes | 許可するドロップ効果 | 有効な列挙値 |

### 入力データソース

- ユーザーのドラッグ操作（PointerPressedイベントからの発生）
- 外部アプリケーションからのドラッグ操作
- IDataTransferによる転送データ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DragDropEffects | DragDropEffects | 実際に適用されたドロップ効果 |
| DragEventArgs | DragEventArgs | ドラッグイベント引数 |

### 出力先

- ドロップターゲット要素（DragEnter/DragLeave/DragOver/Dropイベント）
- DoDragDropAsync呼び出し元（Task<DragDropEffects>）

## 処理フロー

### 処理シーケンス

```
1. DoDragDropAsync呼び出し
   └─ ドラッグ操作を開始
2. プラットフォームDragSource取得
   └─ IPlatformDragSourceをAvaloniaLocatorから取得
3. ドラッグ開始
   └─ プラットフォーム固有のドラッグ操作を開始
4. ターゲット上でのイベント発火
   └─ DragEnter → DragOver（繰り返し） → DragLeave/Drop
5. ドロップ完了
   └─ 適用されたDragDropEffectsを返却
```

### フローチャート

```mermaid
flowchart TD
    A[DoDragDropAsync開始] --> B{IPlatformDragSource存在?}
    B -->|No| C[dataTransfer.Dispose]
    C --> D[Task.FromResult(None)返却]
    B -->|Yes| E[dragSource.DoDragDropAsync]
    E --> F{ドラッグ中}
    F --> G[ターゲット上でDragEnterEvent]
    G --> H[DragOverEvent繰り返し]
    H --> I{ドロップ?}
    I -->|Yes| J[DropEvent発火]
    I -->|No| K[DragLeaveEvent発火]
    J --> L[DragDropEffects返却]
    K --> F
    L --> M[処理完了]
    D --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-54-01 | AllowDrop必須 | ドロップを受け入れるにはAllowDrop=trueが必要 | ドロップターゲット要素 |
| BR-54-02 | イベントバブリング | ドラッグイベントはビジュアルツリーをバブルアップ | 全ドラッグイベント |
| BR-54-03 | 効果の制限 | allowedEffectsで許可された効果のみ適用可能 | ドラッグ操作全体 |
| BR-54-04 | データ所有権 | IPlatformDragSource不在時はdataTransferをDispose | プラットフォーム未対応時 |

### 計算ロジック

特になし

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

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

該当なし（UIフレームワークのためデータベース操作は行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentNullException | 必須パラメータがnull | 呼び出し元でのnullチェック |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- ドラッグ中のDragOverイベントはマウス移動に追従する頻度で発火
- ヒットテスト処理はパフォーマンスに影響

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

- 外部アプリケーションからのドラッグデータは信頼せずに検証が必要
- ファイルパスの検証を行いパストラバーサル攻撃を防止

## 備考

- DragDropEffects.Noneはドロップが無効であることを示す
- 非同期APIのためUIスレッドをブロックしない
- クリップボード操作と連携可能

---

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

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

### 推奨読解順序

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

ドラッグ＆ドロップで使用される型定義を先に把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DragDropEffects.cs | `src/Avalonia.Base/Input/DragDropEffects.cs` | Copy/Move/Link/None列挙型 |
| 1-2 | DragEventArgs.cs | `src/Avalonia.Base/Input/DragEventArgs.cs` | ドラッグイベント引数、IDataTransferアクセス |
| 1-3 | IDataTransfer.cs | `src/Avalonia.Base/Input/IDataTransfer.cs` | データ転送インターフェース |

**読解のコツ**: DragDropEffectsはFlags属性を持ち、複数効果の組み合わせを表現可能。DragEventArgsはKeyModifiersも保持し、修飾キーによる動作変更をサポート。

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

ドラッグ＆ドロップAPIの静的メソッドを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DragDrop.cs | `src/Avalonia.Base/Input/DragDrop.cs` | 静的クラス、ルーテッドイベント定義 |

**主要処理フロー**:
1. **13-25行目**: DragEnter/DragLeave/DragOver/Dropルーテッドイベント定義
2. **27行目**: AllowDrop添付プロパティ定義
3. **129-141行目**: DoDragDropAsyncメソッド

#### Step 3: イベントハンドラー登録を理解する

イベントハンドラーの追加・削除パターンを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DragDrop.cs | `src/Avalonia.Base/Input/DragDrop.cs` | Add/RemoveXxxHandlerメソッド群 |

**主要処理フロー**:
- **50-63行目**: AddDragEnterHandler/RemoveDragEnterHandler
- **65-83行目**: AddDragLeaveHandler/RemoveDragLeaveHandler
- **85-103行目**: AddDragOverHandler/RemoveDragOverHandler
- **105-123行目**: AddDropHandler/RemoveDropHandler

#### Step 4: プラットフォーム連携を理解する

プラットフォーム固有実装との連携を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | IPlatformDragSource.cs | `src/Avalonia.Base/Input/Platform/IPlatformDragSource.cs` | プラットフォーム固有インターフェース |
| 4-2 | DragDropDevice.cs | `src/Avalonia.Base/Input/DragDropDevice.cs` | ドラッグイベント処理デバイス |

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

```
DragDrop.DoDragDropAsync
    │
    └─ AvaloniaLocator.GetService<IPlatformDragSource>
           │
           └─ IPlatformDragSource.DoDragDropAsync
                  │
                  ├─ DragDropDevice.ProcessRawEvent
                  │      ├─ DragEnterEvent発火
                  │      ├─ DragOverEvent発火
                  │      ├─ DragLeaveEvent発火
                  │      └─ DropEvent発火
                  │
                  └─ Task<DragDropEffects>返却
```

### データフロー図

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

PointerEventArgs ───▶ DragDrop.DoDragDropAsync ───▶ Task<DragDropEffects>
  └─ トリガーイベント     │
                          ├─ IPlatformDragSource連携
IDataTransfer ───────────▶│
  └─ 転送データ           └─ プラットフォーム固有処理

                     ターゲット要素
                          │
                          ├─▶ DragEnterEvent
                          ├─▶ DragOverEvent
                          ├─▶ DragLeaveEvent
                          └─▶ DropEvent
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DragDrop.cs | `src/Avalonia.Base/Input/DragDrop.cs` | ソース | 静的クラス、ルーテッドイベント定義 |
| DragEventArgs.cs | `src/Avalonia.Base/Input/DragEventArgs.cs` | ソース | ドラッグイベント引数 |
| DragDropEffects.cs | `src/Avalonia.Base/Input/DragDropEffects.cs` | ソース | ドラッグ効果列挙型 |
| IDataTransfer.cs | `src/Avalonia.Base/Input/IDataTransfer.cs` | ソース | データ転送インターフェース |
| DataObject.cs | `src/Avalonia.Base/Input/DataObject.cs` | ソース | データオブジェクト実装 |
| DragDropDevice.cs | `src/Avalonia.Base/Input/DragDropDevice.cs` | ソース | ドラッグイベント処理 |
| IPlatformDragSource.cs | `src/Avalonia.Base/Input/Platform/IPlatformDragSource.cs` | ソース | プラットフォーム抽象化 |
| DataFormat.cs | `src/Avalonia.Base/Input/DataFormat.cs` | ソース | データフォーマット定義 |
