# 機能設計書 33-StackPanel

## 概要

本ドキュメントは、Avalonia UIフレームワークにおけるStackPanel（スタックレイアウトパネル）の機能設計を定義するものである。StackPanelは子要素を水平または垂直方向に一列に並べるシンプルなレイアウトパネルを提供する。

### 本機能の処理概要

StackPanelは、Orientation（方向）プロパティで指定された方向に子要素を順次配置するレイアウトパネルを提供する。スタック方向には無制限に拡張し、直交方向には最大の子要素サイズに合わせる「Size To Content」動作を実装する。

**業務上の目的・背景**：UIレイアウトにおいて、要素を単純に縦または横に並べるニーズは非常に多い。StackPanelは、メニュー項目、リスト、ツールバーなどの一列配置を簡単に実現できるレイアウトコンテナを提供する。

**機能の利用シーン**：
- メニューやツールバーの項目配置
- フォームのラベルと入力フィールドの縦並び
- ボタングループの横並び配置
- リスト表示（VirtualizingStackPanelと連携）

**主要な処理内容**：
1. Orientationによる配置方向の決定（Horizontal/Vertical）
2. Spacingによる子要素間の間隔設定
3. スタック方向への無制限拡張計測
4. 直交方向の最大サイズ計算
5. キーボードナビゲーションのサポート

**関連システム・外部連携**：Panel基底クラスを継承し、INavigableContainer、IScrollSnapPointsInfoインターフェースを実装。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | StackPanelは基本レイアウトパネルとして多くの画面で使用される |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Orientation | Orientation | No | 子要素の配置方向（デフォルト: Vertical） | Horizontal/Vertical |
| Spacing | double | No | 子要素間のスペース（デフォルト: 0） | 0以上 |
| AreHorizontalSnapPointsRegular | bool | No | 水平スナップポイントが等間隔か | - |
| AreVerticalSnapPointsRegular | bool | No | 垂直スナップポイントが等間隔か | - |

### 入力データソース

- 子要素コレクション（Children）
- 配置方向と間隔設定

## 出力仕様

### 出力データ

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

### 出力イベント

| イベント名 | 発生条件 |
|-----------|---------|
| HorizontalSnapPointsChanged | 水平方向のスナップポイント計測が変更された時 |
| VerticalSnapPointsChanged | 垂直方向のスナップポイント計測が変更された時 |

## 処理フロー

### 処理シーケンス

```
1. MeasureOverrideフェーズ
   ├─ 配置方向の決定
   ├─ スタック方向に無制限サイズ設定
   ├─ 各子要素の計測
   ├─ スタック方向: サイズ累積（+ Spacing）
   └─ 直交方向: 最大サイズ取得
2. ArrangeOverrideフェーズ
   ├─ 各子要素を順次配置
   ├─ スタック方向: 前の要素末尾から配置
   └─ 直交方向: 親サイズまたは子サイズの最大
```

### フローチャート

```mermaid
flowchart TD
    A[MeasureOverride開始] --> B{Orientation?}
    B -->|Horizontal| C[Width = ∞]
    B -->|Vertical| D[Height = ∞]
    C --> E[子要素ループ]
    D --> E
    E --> F{可視?}
    F -->|No| G[次の子へ]
    F -->|Yes| H[child.Measure]
    H --> I[サイズ累積]
    I --> G
    G --> J{全子要素完了?}
    J -->|No| E
    J -->|Yes| K[Spacing調整]
    K --> L[DesiredSize返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-33-01 | 無制限拡張 | スタック方向には無制限（PositiveInfinity）に拡張可能 | 常時 |
| BR-33-02 | 非可視要素スキップ | IsVisible=falseの子要素は配置・計測対象外 | 子要素が非可視時 |
| BR-33-03 | Spacing適用 | 可視要素間にのみSpacingを適用（最後の要素後ろには不要） | 複数可視要素時 |
| BR-33-04 | ナビゲーションラップ | wrap=trueの場合、端に達したら反対端に移動 | ナビゲーション時 |

### 計算ロジック

**DesiredSize計算（Vertical時）**:
```
Width = Max(child1.Width, child2.Width, ...)
Height = child1.Height + spacing + child2.Height + spacing + ... （最後のspacingは除く）
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidOperationException | 状態エラー | Regular=trueなのにGetIrregularSnapPoints呼出 | 例外スロー |
| InvalidOperationException | 状態エラー | Regular=falseなのにGetRegularSnapPoints呼出 | 例外スロー |

## パフォーマンス要件

- 軽量なレイアウト計算（O(n)）
- 可視性チェックによる不要計算のスキップ

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

特になし

## 備考

- WPFのStackPanelからの移植実装
- 仮想化が必要な場合はVirtualizingStackPanelを使用

---

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

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

### 推奨読解順序

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

Orientationの定義とスナップポイント関連のインターフェースを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Orientation.cs | `src/Avalonia.Layout/Orientation.cs` | Horizontal/Vertical列挙型 |
| 1-2 | IScrollSnapPointsInfo.cs | `src/Avalonia.Controls/IScrollSnapPointsInfo.cs` | スナップポイントインターフェース |
| 1-3 | SnapPointsAlignment.cs | `src/Avalonia.Controls/SnapPointsAlignment.cs` | Near/Center/Far定義 |

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

StackPanelクラスの基本構造とプロパティを把握する。

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

**主要処理フロー**:
- **19行目**: `StackPanel`クラス定義。`Panel`, `INavigableContainer`, `IScrollSnapPointsInfo`を実装
- **24-31行目**: Spacing/Orientationプロパティ定義
- **64-68行目**: 静的コンストラクタ - AffectsMeasure登録

#### Step 3: MeasureOverride - 計測処理

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

**主要処理フロー**:
- **238行目**: 方向判定（fHorizontal）
- **246-253行目**: スタック方向にPositiveInfinity設定
- **259-286行目**: 子要素ループ - 計測とサイズ累積
- **288-295行目**: 最後のSpacing削除調整

**読解のコツ**: 226-232行目のコメントで「Size To Content」動作の説明あり。

#### Step 4: ArrangeOverride - 配置処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | StackPanel.cs | `src/Avalonia.Controls/StackPanel.cs` | ArrangeOverrideメソッド（304-347行目） |

**主要処理フロー**:
- **315-342行目**: 子要素ループ - 順次配置
- **319-322行目**: 非可視要素スキップ
- **324-339行目**: 方向別の位置・サイズ設定
- **344行目**: スナップポイント変更イベント発火

#### Step 5: ナビゲーション処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | StackPanel.cs | `src/Avalonia.Controls/StackPanel.cs` | GetControl/GetControlInDirectionメソッド（131-224行目） |

**主要処理フロー**:
- **131-172行目**: INavigableContainer実装 - ラップ対応
- **180-224行目**: 方向別のインデックス計算

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

```
StackPanel (レイアウトパネル)
    │
    ├─ MeasureOverride()
    │      ├─ Orientation判定
    │      ├─ 子要素.Measure() ループ
    │      └─ DesiredSize計算
    │
    ├─ ArrangeOverride()
    │      ├─ 子要素.Arrange() ループ
    │      │      └─ ArrangeChild()
    │      └─ SnapPointsChangedイベント発火
    │
    ├─ INavigableContainer.GetControl()
    │      └─ GetControlInDirection()
    │
    └─ IScrollSnapPointsInfo
           ├─ GetIrregularSnapPoints()
           └─ GetRegularSnapPoints()
```

### データフロー図

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

Orientation ─────────────▶ MeasureOverride()
                              │
Spacing ──────────────────▶ │
                              │
子要素コレクション ────────▶ 子要素ループ計測
                              │
                    ┌─────────┴─────────┐
                    ▼                   ▼
         スタック方向累積      直交方向最大値
                    │                   │
                    └─────────┬─────────┘
                              ▼
                     DesiredSize
                              │
                              ▼
                     ArrangeOverride()
                              │
                    ┌─────────┴─────────┐
                    ▼                   ▼
         子要素順次配置      SnapPointsChangedイベント
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| StackPanel.cs | `src/Avalonia.Controls/StackPanel.cs` | ソース | メインクラス |
| Panel.cs | `src/Avalonia.Controls/Panel.cs` | ソース | 基底クラス |
| Orientation.cs | `src/Avalonia.Layout/Orientation.cs` | ソース | 方向列挙型 |
| INavigableContainer.cs | `src/Avalonia.Input/INavigableContainer.cs` | ソース | ナビゲーションインターフェース |
| IScrollSnapPointsInfo.cs | `src/Avalonia.Controls/IScrollSnapPointsInfo.cs` | ソース | スナップポイントインターフェース |
| VirtualizingStackPanel.cs | `src/Avalonia.Controls/VirtualizingStackPanel.cs` | ソース | 仮想化版 |
