# 画面設計書 105-Embedding

## 概要

本ドキュメントは、IntegrationTestAppにおける埋め込みコントロールのテストページ（EmbeddingPage）の画面設計書です。

### 本画面の処理概要

本画面は、Avaloniaフレームワークのネイティブコントロール埋め込み機能を統合テストするためのテストページです。ネイティブテキストボックスの埋め込み、ポップアップ内でのネイティブコントロール表示、ネイティブモーダルセッションの実行などをテストできます。

**業務上の目的・背景**：本画面は、Avaloniaフレームワークの品質保証のために存在します。ネイティブコントロール埋め込み機能は、プラットフォーム固有の機能（macOSのNSView、WindowsのHWND等）をAvalonia UIに統合するために重要です。この機能が正しく動作することで、既存のネイティブコンポーネントとの相互運用が可能になります。

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

**主要な操作・処理内容**：
1. ネイティブテキストボックス（NativeTextBox）へのテキスト入力
2. CheckBoxをクリックしてポップアップを開き、ポップアップ内のネイティブテキストボックスを操作
3. Resetボタンでテキストボックスを初期状態にリセット
4. Open Native Modalボタンでネイティブモーダルセッションを開始
5. モーダル内のボタンクリックで結果をModalResultTextBoxに表示

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

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 96 | NativePlatform | 主機能 | 埋め込みのテスト。ネイティブコントロールの統合 |

## 画面種別

テスト画面

## URL/ルーティング

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

## 入出力項目

| 項目名 | 種別 | データ型 | 必須 | 説明 |
|--------|------|----------|------|------|
| ネイティブテキスト | 入力/出力 | string | - | ネイティブテキストボックスのテキスト |
| ポップアップ内テキスト | 入力/出力 | string | - | ポップアップ内ネイティブテキストボックスのテキスト |
| モーダル結果 | 出力 | string | - | ネイティブモーダルセッションの結果 |

## 表示項目

| 項目名 | コントロール名 | 種別 | 説明 |
|--------|--------------|------|------|
| Native TextBox | NativeTextBox | NativeTextBox | ネイティブテキストボックス（高さ23px） |
| Popup Open CheckBox | EmbeddingPopupOpenCheckBox | CheckBox | ポップアップ開閉用チェックボックス |
| Native TextBox in Popup | NativeTextBoxInPopup | NativeTextBox | ポップアップ内のネイティブテキストボックス |
| Reset Button | Reset | Button | テキストリセットボタン |
| Open Native Modal | RunNativeModalSession | Button | ネイティブモーダル開始ボタン |
| Modal Result TextBox | ModalResultTextBox | TextBox | モーダル結果表示用テキストボックス |

## イベント仕様

### 1-Reset_Click

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

**処理フロー**:
1. ResetTextメソッドを呼び出し
2. NativeTextBoxとNativeTextBoxInPopupのTextを "Native text box" にリセット
3. ModalResultTextBoxのTextをクリア

### 2-RunNativeModalSession_OnClick

Open Native Modalボタンがクリックされた際に発火します（macOSのみ）。

**処理フロー**:
1. MacHelper.EnsureInitializedを呼び出してMonoMacを初期化
2. NSApplication.SharedApplicationを取得
3. CreateNativeWindowメソッドでネイティブウィンドウを作成
4. BeginModalSessionでモーダルセッションを開始
5. RunModalSessionでモーダルループを実行
6. モーダル終了時にEndModalSessionを呼び出し

### 3-ネイティブモーダル内ボタンクリック

モーダルウィンドウ内のButtonInModalがクリックされた際に発火します。

**処理フロー**:
1. ModalResultTextBox.Textを "Clicked" に設定
2. モーダルウィンドウをClose
3. NSApplication.StopModalが呼び出されモーダルセッション終了

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

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

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|------------|------|--------------|---------|
| MSG-001 | 情報 | Native text box | 初期状態またはリセット後 |
| MSG-002 | 情報 | Clicked | モーダル内ボタンクリック後 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| プラットフォームハンドル取得失敗 | InvalidOperationException("Could not get platform handle")をスロー |

## 備考

- 本画面はmacOS固有のMonoMac APIを使用しています（NSApplication、NSWindow、NSView等）
- NativeTextBoxはIntegrationTestApp.Embedding名前空間で定義されたカスタムコントロールです
- ポップアップはPlacement="Right"で配置され、CheckBoxの右側に表示されます
- ネイティブモーダルセッションはNSModalResponseContinue (-1002) を使用して継続判定を行います
- EmbeddableControlRootを使用してAvaloniaコントロールをネイティブビューに変換しています

---

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

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

### 推奨読解順序

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

ネイティブコントロール埋め込みの基本構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | EmbeddableControlRoot.cs | `src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs` | Avalonia コントロールをネイティブビューに変換するクラス |
| 1-2 | NativeTextBox.cs | `samples/IntegrationTestApp/Embedding/NativeTextBox.cs` | カスタムネイティブテキストボックスの実装 |

**読解のコツ**: EmbeddableControlRootはAvaloniaのコントロールをネイティブプラットフォームのビューとして公開するためのルートコンテナです。TryGetPlatformHandleメソッドでネイティブハンドルを取得できます。

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

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

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

**主要処理フロー**:
1. **行9**: NativeTextBoxの配置（高さ23px）
2. **行10-16**: CheckBoxとPopupのバインディング設定
3. **行17-20**: Reset/RunNativeModalSessionボタンの配置
4. **行23-26**: ResetTextメソッドでテキスト初期化
5. **行34-49**: RunNativeModalSession_OnClickでモーダルセッション実行
6. **行51-91**: CreateNativeWindowでネイティブウィンドウ作成

#### Step 3: ネイティブモーダル処理を理解する

macOS固有のモーダルセッション処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | EmbeddingPage.axaml.cs | `samples/IntegrationTestApp/Pages/EmbeddingPage.axaml.cs` | CreateNativeWindowメソッド |

**主要処理フロー**:
- **行53-57**: Avaloniaボタンを作成
- **行59-67**: EmbeddableControlRootでラップ
- **行69-73**: NSWindowを作成
- **行78-82**: ボタンクリック時のコールバック設定
- **行84-90**: プラットフォームハンドル取得とContentView設定

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

```
EmbeddingPage
    │
    ├─ コンストラクタ
    │      └─ ResetText() ─── NativeTextBox/NativeTextBoxInPopup初期化
    │
    ├─ Reset_Click()
    │      ├─ ResetText()
    │      └─ ModalResultTextBox.Text = ""
    │
    └─ RunNativeModalSession_OnClick()
           │
           ├─ MacHelper.EnsureInitialized()
           │
           ├─ CreateNativeWindow()
           │      │
           │      ├─ new Button { Name = "ButtonInModal" }
           │      │
           │      ├─ new EmbeddableControlRoot { Content = button }
           │      │      └─ Prepare()
           │      │
           │      ├─ new NSWindow(...)
           │      │      └─ WillClose += StopModal
           │      │
           │      ├─ button.Click +=
           │      │      ├─ ModalResultTextBox.Text = "Clicked"
           │      │      └─ window.Close()
           │      │
           │      ├─ TryGetPlatformHandle()
           │      │
           │      ├─ window.ContentView = NSView
           │      │
           │      └─ root.StartRendering()
           │
           ├─ app.BeginModalSession(window)
           │
           ├─ while (app.RunModalSession(session) == Continue)
           │
           └─ app.EndModalSession(session)
```

### データフロー図

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

Reset Click ───▶ ResetText() ───▶ NativeTextBox.Text = "Native text box"
                                        NativeTextBoxInPopup.Text = "Native text box"
                                        ModalResultTextBox.Text = ""

CheckBox.IsChecked ───▶ Popup.IsOpen ───▶ ポップアップ表示/非表示

Open Native Modal ───▶ CreateNativeWindow() ───▶ NSWindow表示
                              │
                              ▼
                       BeginModalSession()
                              │
                              ▼
ButtonInModal Click ───▶ ModalResultTextBox.Text = "Clicked"
                              │
                              ▼
                       NSWindow.Close()
                              │
                              ▼
                       EndModalSession()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| EmbeddingPage.axaml | `samples/IntegrationTestApp/Pages/EmbeddingPage.axaml` | ソース | 画面レイアウト定義（XAML） |
| EmbeddingPage.axaml.cs | `samples/IntegrationTestApp/Pages/EmbeddingPage.axaml.cs` | ソース | イベントハンドラ実装（コードビハインド） |
| NativeTextBox.cs | `samples/IntegrationTestApp/Embedding/NativeTextBox.cs` | ソース | ネイティブテキストボックスの実装 |
| MacHelper.cs | `samples/IntegrationTestApp/Embedding/MacHelper.cs` | ソース | macOS初期化ヘルパー |
| MainWindow.axaml | `samples/IntegrationTestApp/MainWindow.axaml` | ソース | 親ウィンドウ（ナビゲーション） |
| EmbeddableControlRoot.cs | `src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs` | ソース | 埋め込み用ルートコントロール |
