# 機能設計書 28-コンテナレイアウト

## 概要

本ドキュメントは、Godot Engineのコンテナレイアウト機能について、その設計と実装の詳細を記述した機能設計書である。本機能は、HBoxContainer、VBoxContainer、GridContainer等のレイアウトコンテナを提供し、子コントロールの自動配置とサイズ調整を可能にする。

### 本機能の処理概要

**業務上の目的・背景**：ゲームやアプリケーションのUI設計において、コントロールの配置を手動で行うのは煩雑である。コンテナレイアウト機能により、開発者は子要素の水平・垂直・グリッド配置を自動化でき、画面サイズの変更やコンテンツの増減にも柔軟に対応できるレスポンシブなUIを構築できる。

**機能の利用シーン**：
- メニュー項目の垂直配置（VBoxContainer）
- ツールバーボタンの水平配置（HBoxContainer）
- 設定画面のグリッドレイアウト（GridContainer）
- ダイアログのボタン配置

**主要な処理内容**：
1. 子コントロールの最小サイズ計算
2. サイズフラグに基づく伸縮処理
3. アライメント（BEGIN/CENTER/END）の適用
4. 間隔（separation）の適用
5. RTL（右から左）レイアウト対応

**関連システム・外部連携**：Control（基底クラス）、Theme（間隔設定）

**権限による制御**：特に権限による制御はなし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 9 | インスペクタードック | 補助機能 | コンテナプロパティの編集 |

## 機能種別

レイアウト管理 / 自動配置 / サイズ計算

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| p_alignment | AlignmentMode | No | アライメント（BEGIN/CENTER/END） | enum範囲内 |
| p_vertical | bool | No | 垂直配置かどうか | BoxContainerのみ |
| p_columns | int | No | 列数（GridContainer） | 1以上 |

### 入力データソース

- シーンファイル（.tscn）からのプロパティ設定
- 子コントロールのサイズフラグ（SIZE_FILL、SIZE_EXPAND等）
- Themeからの間隔（separation）設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| get_minimum_size | Size2 | コンテナの最小サイズ |
| get_allowed_size_flags_horizontal | Vector<int> | 許可される水平サイズフラグ |
| get_allowed_size_flags_vertical | Vector<int> | 許可される垂直サイズフラグ |

### 出力先

- 子コントロールのRect（位置とサイズ）
- シグナル発行（pre_sort_children、sort_children）

## 処理フロー

### 処理シーケンス

```
1. 子コントロールの追加/変更/削除を検知
   └─ add_child_notify / remove_child_notify
2. queue_sortでソートをキューに追加
   └─ pending_sort = true, call_deferred
3. _sort_childrenの実行
   └─ NOTIFICATION_PRE_SORT_CHILDREN
   └─ NOTIFICATION_SORT_CHILDREN
4. 各コンテナ固有のレイアウト計算
   └─ BoxContainer::_resort / GridContainer
5. fit_child_in_rectで子を配置
   └─ サイズフラグに基づく調整
```

### フローチャート

```mermaid
flowchart TD
    A[子コントロール変更] --> B[queue_sort]
    B --> C{pending_sort?}
    C -->|No| D[call_deferred設定]
    C -->|Yes| E[スキップ]
    D --> F[_sort_children]
    F --> G[NOTIFICATION_PRE_SORT_CHILDREN]
    G --> H[NOTIFICATION_SORT_CHILDREN]
    H --> I[BoxContainer::_resort]
    I --> J[最小サイズ計算]
    J --> K{SIZE_EXPAND?}
    K -->|Yes| L[伸縮計算]
    K -->|No| M[最小サイズ使用]
    L --> N[アライメント適用]
    M --> N
    N --> O[fit_child_in_rect]
    O --> P[子コントロール配置完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-28-01 | アライメント | ALIGNMENT_BEGIN(0)、CENTER(1)、END(2)で配置位置を制御 | 伸縮なし時 |
| BR-28-02 | 間隔適用 | theme_cache.separationを子要素間に適用 | 2つ以上の子要素 |
| BR-28-03 | サイズフラグ | SIZE_EXPAND時にstretch_ratioに基づき余白を分配 | SIZE_EXPAND設定時 |
| BR-28-04 | 遅延ソート | queue_sortで次フレームにバッチ処理 | 複数変更時 |

### 計算ロジック

**BoxContainer最小サイズ計算**：
- 垂直：height = Σ(子のheight) + (子の数-1) * separation
- 水平：width = Σ(子のwidth) + (子の数-1) * separation
- 交差方向は最大値を採用

**伸縮計算**：
- stretch_avail = 利用可能なスペース - 非伸縮要素のサイズ
- final_size = stretch_avail * (child.stretch_ratio / stretch_ratio_total)
- エラー蓄積による端数補正あり（134-137行目）

**GridContainer配置**：
- row = valid_controls_index / columns
- col = valid_controls_index % columns
- 列幅・行高は各列/行の最大最小サイズから計算

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

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

データベース操作はなし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 無効な列数 | GridContainer.columns < 1 | ERR_FAIL_COND |
| - | 方向変更不可 | 固定コンテナで方向変更 | ERR_FAIL_COND_MSG |

### リトライ仕様

リトライ機構はなし。

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

トランザクション管理は不要。

## パフォーマンス要件

- queue_sortによる遅延実行でバッチ処理
- pending_sortフラグで重複ソートを防止

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

- 特になし

## 備考

- Containerクラス単体では配置ロジックなし（警告表示）
- SortableVisibilityModeで非表示要素のスキップ制御
- アクセシビリティロール：ROLE_CONTAINER

---

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

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

### 推奨読解順序

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

Container基底クラスの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | container.h | `scene/gui/container.h` | Container クラス、NOTIFICATION_SORT_CHILDREN(51)、SortableVisibilityMode enum |

**読解のコツ**: NOTIFICATION_PRE_SORT_CHILDREN(50)とNOTIFICATION_SORT_CHILDREN(51)の通知定数、queue_sort、fit_child_in_rectのAPIを把握する。

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

Container基底クラスの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | container.cpp | `scene/gui/container.cpp` | queue_sort(130-141行目)、_sort_children(81-93行目)、fit_child_in_rect(95-128行目) |

**主要処理フロー**:
1. **130-141行目**: queue_sort - call_deferredでバッチ処理
2. **81-93行目**: _sort_children - 通知とシグナル発行
3. **95-128行目**: fit_child_in_rect - サイズフラグに基づく子の配置

#### Step 3: 具体的なコンテナ実装を理解する

BoxContainerとGridContainerの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | box_container.h | `scene/gui/box_container.h` | AlignmentMode enum（39-43行目）、vertical、theme_cache |
| 3-2 | box_container.cpp | `scene/gui/box_container.cpp` | _resort(43-236行目)、get_minimum_size(238-274行目) |
| 3-3 | grid_container.h | `scene/gui/grid_container.h` | columns、h_separation、v_separation |
| 3-4 | grid_container.cpp | `scene/gui/grid_container.cpp` | NOTIFICATION_SORT_CHILDREN内のレイアウト計算 |

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

```
Container（基底クラス）
    │
    ├─ queue_sort
    │      └─ callable_mp(this, &Container::_sort_children).call_deferred()
    │
    ├─ _sort_children
    │      ├─ NOTIFICATION_PRE_SORT_CHILDREN
    │      └─ NOTIFICATION_SORT_CHILDREN
    │             │
    │             ├─ BoxContainer::_resort
    │             │      ├─ 最小サイズ収集
    │             │      ├─ 伸縮計算（stretch_avail / stretch_ratio_total）
    │             │      ├─ アライメント適用
    │             │      └─ fit_child_in_rect
    │             │
    │             └─ GridContainer
    │                    ├─ col_minw / row_minh計算
    │                    ├─ col_expanded / row_expanded判定
    │                    └─ fit_child_in_rect
    │
    └─ fit_child_in_rect
           ├─ SIZE_FILL判定
           ├─ SHRINK_BEGIN / CENTER / END適用
           └─ set_rect
```

### データフロー図

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

子コントロール追加 ────────┐
                          │
サイズフラグ変更 ─────────┼──▶ queue_sort ──▶ _sort_children
                          │                      │
可視性変更 ───────────────┘                      ▼
                                        ┌───────┴───────┐
                                        │               │
                                        ▼               ▼
                                 BoxContainer     GridContainer
                                  ::_resort          処理
                                        │               │
                                        ├───────────────┤
                                        │               │
                                        ▼               ▼
                                   fit_child_in_rect
                                        │
                                        ▼
                                 子コントロール
                                 Rect更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| container.h | `scene/gui/container.h` | ソース | Container基底クラス定義 |
| container.cpp | `scene/gui/container.cpp` | ソース | Container実装 |
| box_container.h | `scene/gui/box_container.h` | ソース | BoxContainer、HBoxContainer、VBoxContainer定義 |
| box_container.cpp | `scene/gui/box_container.cpp` | ソース | BoxContainer実装 |
| grid_container.h | `scene/gui/grid_container.h` | ソース | GridContainer定義 |
| grid_container.cpp | `scene/gui/grid_container.cpp` | ソース | GridContainer実装 |
| margin_container.h | `scene/gui/margin_container.h` | ソース | MarginContainer定義 |
| flow_container.h | `scene/gui/flow_container.h` | ソース | FlowContainer定義 |
