# 画面設計書 95-Pointer

## 概要

本ドキュメントは、IntegrationTestAppアプリケーションにおけるPointerPageの画面設計書です。ポインター（マウス）入力とキャプチャ機能をテストするためのページとして設計されています。

### 本画面の処理概要

**業務上の目的・背景**：本画面は、Avaloniaフレームワークにおけるポインター入力とポインターキャプチャ機能の統合テストを目的としています。モーダルダイアログ表示時のポインターキャプチャの動作、PointerPressedイベントの処理、PointerCaptureLostイベントの検出など、ポインター関連機能が正しく動作することを検証するためのテストUIを提供します。特にモーダルダイアログとポインターキャプチャの相互作用のテストに重点を置いています。

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

**主要な操作・処理内容**：
1. 「Show Dialog」ボタンをクリックしてモーダルダイアログを表示
2. PointerCaptureStatusでキャプチャ状態を確認
3. モーダルダイアログの「Close」ボタンでダイアログを閉じる

**画面遷移**：この画面はIntegrationTestAppのメインウィンドウ内のページとして表示されます。「Show Dialog」クリック時にモーダルダイアログが表示されます。

**権限による表示制御**：特になし。すべてのユーザーが全機能を利用可能です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 52 | MouseDevice | 主機能 | ポインターのテスト。ポインターキャプチャ、PointerPressedイベント処理 |

## 画面種別

テスト・検証画面

## URL/ルーティング

デスクトップアプリケーションのため、URLルーティングはなし。MainWindowのListBoxナビゲーションから「Pointer」を選択。

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| PointerPageShowDialog | 入力 | Border (クリック可能) | - | ダイアログ表示トリガー。PointerPressedイベントでダイアログ表示 |

## 表示項目

| 項目名 | コントロール名 | 説明 |
|--------|--------------|------|
| PointerPageShowDialog | Border | 「Show Dialog」テキストを持つクリック可能なボーダー |
| PointerCaptureStatus | TextBlock | ポインターキャプチャの状態を表示（コントロール名 or "None"） |

## イベント仕様

### 1-PointerPageShowDialog_PointerPressed

**トリガー**: 「Show Dialog」ボーダーへのPointerPressedイベント

**処理内容**:
1. 現在のポインターキャプチャ対象を取得（e.Pointer.Captured）
2. キャプチャ対象がある場合、PointerCaptureLostイベントハンドラを登録
3. PointerCaptureStatusにキャプチャ対象のコントロール名を表示
4. 新規Windowインスタンスを作成（200x200サイズ）
5. 「Close」ボタンをContentに設定
6. ShowDialog()でモーダルダイアログとして表示

### 2-CaptureLost (ローカル関数)

**トリガー**: ポインターキャプチャの喪失

**処理内容**:
1. PointerCaptureStatusを"None"に設定
2. イベントハンドラを解除

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

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

本画面はUIコントロールのテスト用であり、データベース操作は行いません。

## メッセージ仕様

本画面ではシステムメッセージの表示はありません。

## 例外処理

| 例外 | 発生条件 | 処理 |
|------|----------|------|
| AvaloniaInternalException | TopLevel.GetTopLevelがnullを返した場合 | 例外をスロー |

## 備考

- ボタンではなくBorderを使用している理由は、PointerPressedイベントでポインター情報にアクセスするため
- AutomationProperties.AccessibilityView="Control"により、アクセシビリティツリーでコントロールとして認識される
- DelegateCommandを使用してダイアログの閉じるボタンを実装
- ポインターキャプチャはマウスボタンを押下している間に要素外でもイベントを受け取る機能

---

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

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

### 推奨読解順序

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

まず、ポインター関連のイベント引数とキャプチャの仕組みを理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | PointerPressedEventArgs.cs | `src/Avalonia.Input/PointerPressedEventArgs.cs` | Pointerプロパティ、Capturedプロパティの構造 |

**読解のコツ**: Pointer.Capturedで現在キャプチャを保持しているコントロールを取得できます。

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

処理の起点となるページファイルを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | PointerPage.axaml | `samples/IntegrationTestApp/Pages/PointerPage.axaml` | UI構造、BorderへのPointerPressedイベント設定 |
| 2-2 | PointerPage.axaml.cs | `samples/IntegrationTestApp/Pages/PointerPage.axaml.cs` | イベントハンドラの実装 |

**主要処理フロー**:
1. **行9-16 (axaml)**: BorderにPointerPressedイベントを設定
2. **行14-46 (axaml.cs)**: PointerPageShowDialog_PointerPressedイベントハンドラ
3. **行22-29 (axaml.cs)**: TopLevel取得とウィンドウ作成

#### Step 3: イベント処理を理解する

ポインターキャプチャとダイアログ表示の処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | PointerPage.axaml.cs | `samples/IntegrationTestApp/Pages/PointerPage.axaml.cs` | CaptureLostローカル関数、ShowDialog呼び出し |

**主要処理フロー**:
- **行16-20**: CaptureLostローカル関数の定義
- **行24**: e.Pointer.Capturedでキャプチャ対象取得
- **行26-29**: PointerCaptureLostイベントハンドラ登録
- **行31**: PointerCaptureStatusの更新
- **行33-43**: ダイアログの作成と表示
- **行45**: ShowDialog()でモーダル表示

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

```
PointerPage
    │
    └─ PointerPageShowDialog_PointerPressed
           │
           ├─ e.Pointer.Captured 取得
           │
           ├─ CaptureLost イベントハンドラ登録
           │      └─ PointerCaptureStatus = "None"
           │
           ├─ PointerCaptureStatus 更新
           │
           ├─ new Window() 作成
           │      └─ Content = new Button("Close")
           │             └─ Command = DelegateCommand(dialog.Close)
           │
           └─ dialog.ShowDialog(window)
```

### データフロー図

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

Border             ───▶  PointerPressedEventArgs  ───▶  Pointer.Captured取得
PointerPressed          │
                        ├─ キャプチャ対象確認        ───▶  PointerCaptureStatus更新
                        │
                        └─ Window作成・ShowDialog   ───▶  モーダルダイアログ表示

ダイアログClose    ───▶  dialog.Close()           ───▶  ダイアログ閉じる
ボタン押下

PointerCapture    ───▶  CaptureLost               ───▶  PointerCaptureStatus
Lost                    イベント処理                    = "None"
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| PointerPage.axaml | `samples/IntegrationTestApp/Pages/PointerPage.axaml` | ソース | ページのUI定義 |
| PointerPage.axaml.cs | `samples/IntegrationTestApp/Pages/PointerPage.axaml.cs` | ソース | ページのコードビハインド |
| MainWindow.axaml | `samples/IntegrationTestApp/MainWindow.axaml` | ソース | メインウィンドウとナビゲーション |
| MainWindow.axaml.cs | `samples/IntegrationTestApp/MainWindow.axaml.cs` | ソース | ページ生成ファクトリ（行90） |
| DelegateCommand.cs | `samples/IntegrationTestApp/DelegateCommand.cs` | ソース | Closeボタンのコマンド実装 |
