# 機能設計書 4-Visual

## 概要

本ドキュメントは、Avaloniaフレームワークにおけるレンダリングとビジュアルツリーの基盤クラスである`Visual`の機能設計を記述する。`StyledElement`を継承し、画面表示に関連するすべての機能（レンダリング、変換、クリッピング、可視性など）を提供する。

### 本機能の処理概要

`Visual`クラスは、画面に表示されるすべての要素の基底クラスであり、以下の機能を提供する：
- **レンダリング**：`Render`メソッドによる描画とレンダラーへの無効化通知
- **ビジュアルツリー**：親子関係によるビジュアル階層の構築
- **変換**：RenderTransform、ミラー変換（RTL対応）
- **クリッピング**：ClipToBounds、Clipジオメトリ
- **可視性**：IsVisible、IsEffectivelyVisible
- **不透明度**：Opacity、OpacityMask

**業務上の目的・背景**：UIフレームワークにおいて、画面に表示される要素は共通のレンダリング基盤を必要とする。`Visual`クラスは、レンダラーとコントロール間のインターフェースを提供し、効率的な描画更新とツリー管理を実現する。

**機能の利用シーン**：
- カスタムコントロールの描画ロジック実装
- レイアウト計算後の位置・サイズ設定
- 変換やエフェクトの適用
- 可視性の制御

**主要な処理内容**：
1. `Render`メソッドによるDrawingContextへの描画
2. `InvalidateVisual`によるレンダリング無効化
3. `VisualChildren`コレクションによる子要素管理
4. `AttachedToVisualTree`/`DetachedFromVisualTree`ライフサイクル
5. `AffectsRender`ヘルパーによる自動無効化設定
6. `FlowDirection`とミラー変換の管理

**関連システム・外部連携**：
- `IRenderer`：実際の描画を行うレンダラー
- `IPresentationSource`：ビジュアルツリーのルート
- `CompositionVisual`：コンポジションレンダリング
- `DrawingContext`：描画API

**権限による制御**：特になし（フレームワーク基盤クラス）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能は全画面の基盤となるクラスであり、特定の画面に紐づかない |

## 機能種別

フレームワーク基盤 / レンダリング / ビジュアルツリー管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Bounds | Rect | No | 親要素相対の境界矩形 | protected set |
| ClipToBounds | bool | No | 境界でクリップするか | デフォルト: false |
| Clip | Geometry? | No | クリップジオメトリ | - |
| IsVisible | bool | No | 可視性 | デフォルト: true |
| Opacity | double | No | 不透明度 | デフォルト: 1 |
| OpacityMask | IBrush? | No | 不透明度マスク | - |
| RenderTransform | ITransform? | No | 描画変換 | - |
| RenderTransformOrigin | RelativePoint | No | 変換原点 | デフォルト: Center |
| FlowDirection | FlowDirection | No | テキスト方向（継承） | デフォルト: LeftToRight |
| ZIndex | int | No | Z順序 | デフォルト: 0 |
| Effect | IEffect? | No | 視覚効果 | - |

### 入力データソース

- レイアウトシステムからのBounds設定
- XAMLまたはコードからのプロパティ設定
- 親要素からの継承（FlowDirection）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| AttachedToVisualTree | event | ビジュアルツリーにアタッチされた時のイベント |
| DetachedFromVisualTree | event | ビジュアルツリーからデタッチされた時のイベント |
| IsEffectivelyVisible | bool | 親を含めた有効な可視性 |
| HasMirrorTransform | bool | ミラー変換適用フラグ |
| VisualRoot | Visual? | ビジュアルツリーのルート |

### 出力先

- レンダラーへの無効化通知
- ビジュアルツリーイベントリスナー

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ
   └─ DisableTransitions（ビジュアルツリー接続前）
   └─ VisualChildrenコレクション初期化
   └─ Validatorとイベントハンドラ設定

2. VisualChildrenへの追加
   └─ Validate（null/二重親チェック）
   └─ SetVisualParent
   └─ 親がアタッチ済みならOnAttachedToVisualTreeCore呼び出し

3. OnAttachedToVisualTreeCore
   └─ PresentationSource設定
   └─ RootedVisualChildrenCount++
   └─ RenderTransform変更イベント購読
   └─ EnableTransitions
   └─ CompositorにAttach
   └─ InvalidateMirrorTransform
   └─ UpdateIsEffectivelyVisible
   └─ OnAttachedToVisualTree（仮想メソッド）
   └─ AttachedToVisualTreeイベント発火
   └─ InvalidateVisual
   └─ 子要素への伝播

4. InvalidateVisual
   └─ PresentationSource?.Renderer.AddDirty(this)

5. Render
   └─ DrawingContextへの描画（派生クラスで実装）
```

### フローチャート

```mermaid
flowchart TD
    A[Visual作成] --> B[コンストラクタ]
    B --> C[VisualChildrenに追加される]
    C --> D{親がアタッチ済み?}
    D -->|Yes| E[OnAttachedToVisualTreeCore]
    D -->|No| F[待機]
    E --> G[PresentationSource設定]
    G --> H[EnableTransitions]
    H --> I[InvalidateMirrorTransform]
    I --> J[UpdateIsEffectivelyVisible]
    J --> K[OnAttachedToVisualTree]
    K --> L[子要素への伝播]
    L --> M[InvalidateVisual]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | VisualChildrenにnull禁止 | nullを子要素として追加できない | Validate時 |
| BR-02 | 二重親禁止 | 既に親を持つVisualを別の親に追加できない | Validate時 |
| BR-03 | IsEffectivelyVisible計算 | 自身と全親がIsVisible=trueの時のみtrue | IsVisible変更時 |
| BR-04 | ミラー変換計算 | FlowDirection.RTLでBypassFlowDirectionPolicies=falseの時に適用 | FlowDirection変更時 |
| BR-05 | ZIndex変更時の再計算 | ZIndex変更時に親の子再計算を要求 | ZIndexChanged |
| BR-06 | Transitions無効化 | ビジュアルツリー接続前はトランジション無効 | コンストラクタ |

### 計算ロジック

**IsEffectivelyVisible計算**：
```
IsEffectivelyVisible = parentState && IsVisible
// parentState = 親のIsEffectivelyVisible（ルートの場合はtrue）
```

**HasMirrorTransform計算**：
```
thisShouldBeMirrored = (FlowDirection == RTL) && !BypassFlowDirectionPolicies
parentShouldBeMirrored = (parent.FlowDirection == RTL) && !parent.BypassFlowDirectionPolicies
HasMirrorTransform = thisShouldBeMirrored != parentShouldBeMirrored
```

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

該当なし（メモリ内データ構造のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentNullException | VisualChildrenにnull追加 | nullチェックを追加 |
| - | InvalidOperationException | 二重親設定 | 先に親から削除 |
| - | ArgumentNullException | Render(null) | DrawingContextを指定 |
| - | InvalidOperationException | 複数のPresentationSourceにアタッチ | 1つのみアタッチ可能 |

### リトライ仕様

該当なし

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

該当なし（メモリ内操作のみ）

## パフォーマンス要件

- `AffectsRender`で指定されたプロパティ変更時のみ自動無効化
- `UpdateIsEffectivelyVisible`はforeachを避けてインデックスアクセス（PERF-SENSITIVE）
- ZIndex変更時の`HasNonUniformZIndexChildren`フラグで不要な再計算を回避

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

- 特別なセキュリティ考慮事項なし（フレームワーク内部クラス）

## 備考

- WPFの`Visual`に相当
- `Layoutable`クラスでレイアウト機能が追加される

---

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

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

### 推奨読解順序

#### Step 1: クラス定義とプロパティを理解する

レンダリング関連の主要プロパティを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Visual.cs | `src/Avalonia.Base/Visual.cs` | 23-33行目：クラス定義とXMLコメント |
| 1-2 | Visual.cs | `src/Avalonia.Base/Visual.cs` | 37-121行目：プロパティ定義（Bounds, Clip, IsVisible等） |

**読解のコツ**:
- `AffectsRender<Visual>`で指定されたプロパティ群が描画に影響することを確認
- `FlowDirectionProperty`は`inherits: true`で継承プロパティ

#### Step 2: コンストラクタと初期化を理解する

初期化処理とVisualChildrenの設定を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Visual.cs | `src/Avalonia.Base/Visual.cs` | 139-152行目：静的コンストラクタ（AffectsRender設定） |
| 2-2 | Visual.cs | `src/Avalonia.Base/Visual.cs` | 154-167行目：インスタンスコンストラクタ |

**主要処理フロー**:
- **139-152行目**: `AffectsRender<Visual>`で描画影響プロパティを登録
- **154-167行目**: トランジション無効化、VisualChildren初期化

#### Step 3: ビジュアルツリー管理を理解する

親子関係の設定とライフサイクルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Visual.cs | `src/Avalonia.Base/Visual.cs` | 527-568行目：OnAttachedToVisualTreeCore |
| 3-2 | Visual.cs | `src/Avalonia.Base/Visual.cs` | 575-606行目：OnDetachedFromVisualTreeCore |
| 3-3 | Visual.cs | `src/Avalonia.Base/Visual.cs` | 709-732行目：SetVisualParent |
| 3-4 | Visual.cs | `src/Avalonia.Base/Visual.cs` | 739-756行目：VisualChildrenChanged |

**主要処理フロー**:
- **527-568行目**: アタッチ時にPresentationSource設定、トランジション有効化、子要素伝播
- **575-606行目**: デタッチ時にトランジション無効化、PresentationSource解除
- **709-732行目**: 親設定時にデタッチ→アタッチの流れ

#### Step 4: レンダリングを理解する

描画関連の処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Visual.cs | `src/Avalonia.Base/Visual.cs` | 412-427行目：InvalidateVisual/Render |
| 4-2 | Visual.cs | `src/Avalonia.Base/Visual.cs` | 440-494行目：AffectsRenderヘルパー |

**主要処理フロー**:
- **412-415行目**: `InvalidateVisual`でレンダラーにdirty通知
- **421-427行目**: `Render`は仮想メソッド、派生クラスでオーバーライド
- **440-494行目**: `AffectsRender`でプロパティ変更→InvalidateVisualの自動連携

#### Step 5: FlowDirectionとミラー変換を理解する

RTLサポートの仕組みを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Visual.cs | `src/Avalonia.Base/Visual.cs` | 787-812行目：InvalidateMirrorTransform |

**主要処理フロー**:
- **787-812行目**: 自身と親のFlowDirectionを比較してHasMirrorTransformを決定

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

```
Visual
    │
    ├─ StyledElement（スタイリング基盤）
    │      └─ AvaloniaObject（プロパティシステム）
    │
    ├─ VisualChildren（子要素コレクション）
    │      └─ Visual[]（子ビジュアル）
    │
    ├─ IPresentationSource
    │      ├─ IRenderer（描画）
    │      └─ RootVisual（ルート）
    │
    └─ CompositionVisual（コンポジションレイヤー）
```

### データフロー図

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

VisualChildren.Add(child)
        │
        ▼
   Validate(child) ────▶ ArgumentNullException/InvalidOperationException
        │
        ▼
   SetVisualParent(child, this)
        │
        ▼
   OnAttachedToVisualTreeCore
        │
        ├──▶ PresentationSource設定
        │
        ├──▶ EnableTransitions
        │
        ├──▶ AttachToCompositor
        │
        ├──▶ InvalidateMirrorTransform
        │
        ├──▶ UpdateIsEffectivelyVisible
        │
        ├──▶ OnAttachedToVisualTree
        │
        ├──▶ AttachedToVisualTreeイベント
        │
        ├──▶ InvalidateVisual ────────▶ Renderer.AddDirty
        │
        └──▶ 子要素への伝播
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Visual.cs | `src/Avalonia.Base/Visual.cs` | ソース | ビジュアル基盤クラス（メイン） |
| Visual.Composition.cs | `src/Avalonia.Base/Visual.Composition.cs` | ソース | コンポジション統合（partial） |
| StyledElement.cs | `src/Avalonia.Base/StyledElement.cs` | ソース | スタイリング基盤（親クラス） |
| Layoutable.cs | `src/Avalonia.Base/Layout/Layoutable.cs` | ソース | レイアウト対応（派生クラス） |
| IRenderer.cs | `src/Avalonia.Base/Rendering/IRenderer.cs` | ソース | レンダラーインターフェース |
| DrawingContext.cs | `src/Avalonia.Base/Media/DrawingContext.cs` | ソース | 描画コンテキスト |
| VisualExtensions.cs | `src/Avalonia.Base/VisualTree/VisualExtensions.cs` | ソース | ビジュアルツリー拡張メソッド |
| IPresentationSource.cs | `src/Avalonia.Base/Rendering/IPresentationSource.cs` | ソース | プレゼンテーションソース |
