# 機能設計書 37-RelativePanel

## 概要

本ドキュメントは、Avalonia UIフレームワークにおけるRelativePanel（相対レイアウトパネル）の機能設計を定義するものである。RelativePanelは子要素を他の要素または親パネルに対して相対的に配置するレイアウトパネルを提供する。

### 本機能の処理概要

RelativePanelは、添付プロパティを使用して子要素を他の兄弟要素またはパネル自体に対して相対的に配置する高度なレイアウトパネルを提供する。UWP/WinUIのRelativePanelと同様の機能を提供し、複雑な相対配置レイアウトを宣言的に実現できる。

**業務上の目的・背景**：アダプティブUIデザインにおいて、要素間の相対的な位置関係を維持しながらレイアウトを構築する必要がある。RelativePanelは、要素Aの右側に要素Bを配置する、要素Cを親の中央に配置するなどの関係性ベースのレイアウトを可能にする。

**機能の利用シーン**：
- アダプティブUIレイアウト
- 要素間の関係性に基づく配置
- パネルに対する相対配置（中央寄せ、端寄せ）
- 複雑なフォームレイアウト

**主要な処理内容**：
1. 要素間の相対配置（Above/Below/LeftOf/RightOf）
2. 要素との整列（AlignLeftWith/AlignRightWith/AlignTopWith/AlignBottomWith）
3. パネルとの整列（AlignLeftWithPanel/AlignRightWithPanel等）
4. 中央配置（AlignHorizontalCenterWith/AlignVerticalCenterWith/AlignHorizontalCenterWithPanel/AlignVerticalCenterWithPanel）
5. 依存グラフによる計測順序の解決

**関連システム・外部連携**：Panel基底クラスを継承。HandyControlからの移植。

**権限による制御**：特になし。UIコンポーネントとしてアプリケーション側で必要に応じて実装。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | RelativePanelはアダプティブレイアウトが必要な画面で使用される |

## 機能種別

レイアウト制御 / UIコンテナ

## 入力仕様

### 添付プロパティ - 相対位置指定

| プロパティ名 | 型 | 説明 | デフォルト値 |
|-------------|-----|------|-------------|
| Above | object | この要素の上に配置する対象要素 | null |
| Below | object | この要素の下に配置する対象要素 | null |
| LeftOf | object | この要素の左に配置する対象要素 | null |
| RightOf | object | この要素の右に配置する対象要素 | null |

### 添付プロパティ - 要素との整列

| プロパティ名 | 型 | 説明 | デフォルト値 |
|-------------|-----|------|-------------|
| AlignLeftWith | object | 左端を揃える対象要素 | null |
| AlignRightWith | object | 右端を揃える対象要素 | null |
| AlignTopWith | object | 上端を揃える対象要素 | null |
| AlignBottomWith | object | 下端を揃える対象要素 | null |
| AlignHorizontalCenterWith | object | 水平中央を揃える対象要素 | null |
| AlignVerticalCenterWith | object | 垂直中央を揃える対象要素 | null |

### 添付プロパティ - パネルとの整列

| プロパティ名 | 型 | 説明 | デフォルト値 |
|-------------|-----|------|-------------|
| AlignLeftWithPanel | bool | 左端をパネルに揃える | false |
| AlignRightWithPanel | bool | 右端をパネルに揃える | false |
| AlignTopWithPanel | bool | 上端をパネルに揃える | false |
| AlignBottomWithPanel | bool | 下端をパネルに揃える | false |
| AlignHorizontalCenterWithPanel | bool | パネルの水平中央に配置 | false |
| AlignVerticalCenterWithPanel | bool | パネルの垂直中央に配置 | false |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DesiredSize | Size | 計測フェーズで計算されたバウンディングサイズ |
| 子要素の最終位置 | Rect | 配置フェーズで決定された各子要素の位置とサイズ |

## 処理フロー

### 処理シーケンス

```
1. MeasureOverrideフェーズ
   ├─ 依存グラフ構築
   │   └─ 各子要素のAddNode/AddLink
   ├─ グラフ計測（依存順序で実行）
   │   ├─ 循環依存検出
   │   └─ 各ノードのMeasureChild
   ├─ バウンディングサイズ計算
   └─ 再計測（確定サイズで）
2. ArrangeOverrideフェーズ
   └─ 各ノードのArrange
```

### フローチャート

```mermaid
flowchart TD
    A[MeasureOverride開始] --> B[依存グラフクリア]
    B --> C[子要素ループ]
    C --> D[AddNode]
    D --> E[依存リンク追加]
    E --> F{次の子?}
    F -->|Yes| C
    F -->|No| G[Graph.Measure]
    G --> H{循環依存?}
    H -->|Yes| I[例外スロー]
    H -->|No| J[各ノードMeasureChild]
    J --> K[GetBoundingSize]
    K --> L[再計測]
    L --> M[DesiredSize返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-37-01 | 依存順序解決 | 依存先が先に計測される | 依存関係あり時 |
| BR-37-02 | 循環依存エラー | 循環依存を検出した場合は例外スロー | 循環依存検出時 |
| BR-37-03 | デフォルト位置 | 指定がない場合は左上(0,0)に配置 | 未指定時 |
| BR-37-04 | 参照要素検証 | 参照先が子要素に存在しない場合は例外 | 不正参照時 |

### 計算ロジック

**中央配置計算**:
```
AlignHorizontalCenterWithPanel時:
  Left = (AvailableWidth - childWidth) / 2
  Right = (AvailableWidth - childWidth) / 2
```

**RightOf配置**:
```
Left = 参照要素のRight（パネル右端からの距離の逆算）
```

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

該当なし（UIコンポーネントのためDB操作は行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ArgumentException | パラメータエラー | 参照先要素がChildren内に存在しない | 例外スロー |
| Exception | 循環依存エラー | 依存グラフに循環が検出された | 例外スロー（"Circular dependency detected"） |

## パフォーマンス要件

- 依存グラフによる効率的な計測順序解決
- 2パスの計測（初期計測→バウンディング計算→再計測）

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

特になし

## 備考

- HandyControlからの移植実装
- UWP/WinUIのRelativePanelと互換

---

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

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

### 推奨読解順序

#### Step 1: 添付プロパティを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | RelativePanel.AttachedProperties.cs | `src/Avalonia.Controls/RelativePanel.AttachedProperties.cs` | 全添付プロパティ定義 |

**読解のコツ**: 添付プロパティは3カテゴリ（相対位置/要素整列/パネル整列）に分類。[ResolveByName]属性は名前による要素解決を可能にする。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RelativePanel.cs | `src/Avalonia.Controls/RelativePanel.cs` | メインクラス |

**主要処理フロー**:
- **12行目**: `RelativePanel`クラス定義（partialクラス）
- **14行目**: `_childGraph`フィールド - 依存グラフ
- **18-31行目**: `GetDependencyElement` - 依存要素の取得と検証

#### Step 3: MeasureOverride - 依存グラフ構築と計測

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | RelativePanel.cs | `src/Avalonia.Controls/RelativePanel.cs` | MeasureOverrideメソッド（33-65行目） |

**主要処理フロー**:
- **35行目**: グラフクリア
- **36-52行目**: 子要素ループ - ノード追加と依存リンク構築
- **54行目**: `_childGraph.Measure` - 依存順序での計測
- **57-58行目**: サイズ計算フラグ判定
- **60-64行目**: バウンディングサイズ計算と再計測

#### Step 4: GraphNodeクラス - ノード定義

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | RelativePanel.cs | `src/Avalonia.Controls/RelativePanel.cs` | GraphNodeクラス（73-204行目） |

**主要処理フロー**:
- **87-93行目**: Left/Top/Right/Bottomプロパティ（NaN初期値）
- **97-115行目**: 依存ノード参照
- **123行目**: Arrangeメソッド
- **138-156行目**: GetBoundingSize - バウンディングサイズ計算

#### Step 5: Graphクラス - 依存グラフ管理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | RelativePanel.cs | `src/Avalonia.Controls/RelativePanel.cs` | Graphクラス（206-526行目） |

**主要処理フロー**:
- **244-254行目**: AddNode - ノード追加
- **256-260行目**: Measure - 計測開始
- **262-290行目**: Measureメソッド - 再帰的依存解決、循環検出
- **292-506行目**: MeasureChild - 各ノードの詳細計測

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

```
RelativePanel (レイアウトパネル)
    │
    ├─ MeasureOverride()
    │      ├─ _childGraph.Clear()
    │      ├─ 子要素ループ
    │      │      ├─ _childGraph.AddNode()
    │      │      └─ _childGraph.AddLink() ×10
    │      ├─ _childGraph.Measure()
    │      │      └─ Measure() - 再帰
    │      │             ├─ 循環依存検出
    │      │             └─ MeasureChild()
    │      │                    ├─ Panel整列適用
    │      │                    ├─ 要素整列適用
    │      │                    ├─ 相対位置適用
    │      │                    └─ 中央配置適用
    │      └─ GetBoundingSize()
    │
    └─ ArrangeOverride()
           └─ GetNodes().Do(node => node.Arrange())
```

### データフロー図

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

添付プロパティ ───────────▶ GetDependencyElement()
                              │
                              ▼
子要素コレクション ────────▶ 依存グラフ構築
                              │
                    ┌─────────┴─────────┐
                    ▼                   ▼
         ノード追加           リンク追加
         (AddNode)            (AddLink)
                    │                   │
                    └─────────┬─────────┘
                              ▼
                     Graph.Measure()
                              │
                    ┌─────────┴─────────┐
                    ▼                   ▼
         依存順序解決        MeasureChild()
         (循環検出)          (位置計算)
                    │                   │
                    └─────────┬─────────┘
                              ▼
                     GetBoundingSize()
                              │
                              ▼
                     ArrangeOverride()
                              │
                              ▼
                     子要素配置完了
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RelativePanel.cs | `src/Avalonia.Controls/RelativePanel.cs` | ソース | メインクラス、Graph/GraphNode内部クラス |
| RelativePanel.AttachedProperties.cs | `src/Avalonia.Controls/RelativePanel.AttachedProperties.cs` | ソース | 添付プロパティ定義 |
| Panel.cs | `src/Avalonia.Controls/Panel.cs` | ソース | 基底クラス |
