# 画面設計書 24-Layout

## 概要

本ドキュメントは、Dear ImGuiのデモセクション「Layout & Scrolling」の設計書です。Demo Window内の折りたたみセクションとして、ウィンドウレイアウトと配置に関するデモンストレーションを行います。

### 本画面の処理概要

**業務上の目的・背景**：本セクションは、Dear ImGuiでウィジェットやウィンドウをどのように配置・レイアウトするかを示すリファレンスです。子ウィンドウの作成、水平レイアウト（SameLine）、グループ化、テキストベースライン調整、スクロール制御、テキストクリッピング、オーバーラップモードなど、GUIアプリケーションの視覚的な構成に必要な技術を網羅しています。複雑なUIレイアウトを実現するための基盤となる知識を提供します。

**画面へのアクセス方法**：Demo Windowの「Layout & Scrolling」CollapsingHeaderをクリックすることでセクションが展開されます。DemoWindowLayout関数がShowDemoWindow()から呼び出されることで表示されます。

**主要な操作・処理内容**：
1. Child windows - 子ウィンドウの作成と活用
2. Widgets Width - ウィジェット幅の制御
3. Basic Horizontal Layout - SameLineによる水平配置
4. Groups - BeginGroup/EndGroupによるグループ化
5. Text Baseline Alignment - テキストとウィジェットのベースライン調整
6. Scrolling - 垂直・水平スクロールの制御
7. Text Clipping - テキストのクリッピング手法
8. Overlap Mode - オーバーラップ（重なり）の制御

**画面遷移**：Demo Windowの一部として表示されます。CollapsingHeaderで折りたたみ/展開可能です。各サブセクションはTreeNodeで階層化されています。

**権限による表示制御**：本セクションでは権限による表示制御は実装されていません。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 73 | SameLine | 主機能 | 水平レイアウトのデモ |
| 74 | NewLine | 主機能 | 改行のデモ |
| 75 | Spacing | 主機能 | スペースのデモ |
| 76 | Dummy | 主機能 | ダミーアイテムのデモ |
| 77 | Indent | 主機能 | インデントのデモ |
| 78 | Unindent | 主機能 | インデント解除のデモ |
| 79 | BeginGroup | 主機能 | グループの開始 |
| 80 | EndGroup | 主機能 | グループの終了 |
| 26 | BeginChild | 補助機能 | 子ウィンドウレイアウト |
| 61 | PushItemWidth | 補助機能 | アイテム幅の設定 |

## 画面種別

デモセクション（CollapsingHeader）

## URL/ルーティング

N/A（Dear ImGuiはImmediate Mode GUIライブラリのため、URL/ルーティングの概念は適用されません）

## 入出力項目

| 項目名 | 型 | 入力/出力 | 説明 |
|--------|-----|----------|------|
| なし | - | - | 本セクションは引数を受け取らない |

## 表示項目

### Child windows セクション
| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| ChildL | BeginChild | 水平スクロール対応の左側子ウィンドウ |
| ChildR | BeginChild | 角丸ボーダー付きの右側子ウィンドウ |
| ResizableChild | BeginChild | 手動リサイズ対応の子ウィンドウ |
| ConstrainedChild | BeginChild | 制約付き自動リサイズの子ウィンドウ |
| Red | BeginChild | 背景色カスタマイズのデモ用子ウィンドウ |

### Widgets Width セクション
| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| 固定幅スライダー | DragFloat | PushItemWidth(100) |
| 右揃えスライダー | DragFloat | PushItemWidth(-100) |
| 半分幅スライダー | DragFloat | PushItemWidth(GetContentRegionAvail().x * 0.5f) |
| 右端揃えスライダー | DragFloat | PushItemWidth(-FLT_MIN) |

### Scrolling セクション
| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| 垂直スクロール | BeginChild | Top/25%/Center/75%/Bottomの5パターン |
| 水平スクロール | BeginChild | Left/25%/Center/75%/Rightの5パターン |
| FizzBuzzボタン | Button | 水平スクロールデモ用のカラフルなボタン群 |

## イベント仕様

### 1-子ウィンドウのスクロール

BeginChild()で作成された子ウィンドウ内でマウスホイールを回すと、スクロールが発生します。ImGuiWindowFlags_NoScrollWithMouseでマウスホイールスクロールを無効化できます。

### 2-SameLineによる水平配置

SameLine()を呼び出すと、次のウィジェットが前のウィジェットの右側に配置されます。SameLine(x)でX座標を指定した配置も可能です。

### 3-グループの使用

BeginGroup()/EndGroup()で囲んだウィジェット群は1つのアイテムとして扱われ、IsItemHovered()やSameLine()を適用できます。

### 4-スクロール位置の制御

SetScrollHereY()/SetScrollHereX()で現在のカーソル位置にスクロールします。SetScrollFromPosY()/SetScrollFromPosX()で指定位置にスクロールします。

### 5-ウィジェット幅の制御

PushItemWidth()/PopItemWidth()またはSetNextItemWidth()で次のウィジェットの幅を設定します。負の値は右端からのオフセットを意味します。

### 6-手動リサイズ

ImGuiChildFlags_ResizeYを指定すると、子ウィンドウの下端をドラッグしてリサイズできます。ダブルクリックで自動フィットします。

### 7-オーバーラップモード

SetNextItemAllowOverlap()を呼び出すと、後に描画されるウィジェットとの重なりが許可されます。

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

N/A（本デモセクションはデータベースを使用しません。すべてのデータはローカル変数またはstatic変数で管理されます）

## メッセージ仕様

| メッセージID | 種別 | 表示条件 | メッセージ内容 |
|--------------|------|----------|----------------|
| なし | - | - | 本セクションではメッセージ表示なし |

## 例外処理

| 例外状況 | 処理内容 |
|----------|----------|
| CollapsingHeaderが折りたたまれている場合 | 早期リターンで処理をスキップ |
| 子ウィンドウが非表示の場合 | child_is_visibleフラグでスキップ |

## 備考

- BeginChild()にはImGuiChildFlagsとImGuiWindowFlagsの両方を指定可能
- 子ウィンドウ内でもBeginMenuBar()が使用可能
- スクロール位置はフレームごとに保持される
- ImGuiChildFlags_FrameStyleでフレームスタイルの子ウィンドウを作成可能
- 水平スクロールにはImGuiWindowFlags_HorizontalScrollbarが必要

---

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

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

### 推奨読解順序

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

処理の起点となる関数を特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_demo.cpp | `imgui_demo.cpp` | DemoWindowLayout関数（行4340-5219）がエントリーポイント |

**主要処理フロー**:
1. **行4342**: CollapsingHeader("Layout & Scrolling")で折りたたみセクションを開始
2. **行4345-4477**: Child windowsセクション
3. **行4479-4565**: Widgets Widthセクション
4. **行4567-4658**: Basic Horizontal Layoutセクション
5. **行4660-4705**: Groupsセクション
6. **行4707-4833**: Text Baseline Alignmentセクション
7. **行4835-5122**: Scrollingセクション
8. **行5124-5187**: Text Clippingセクション
9. **行5189-5218**: Overlap Modeセクション

#### Step 2: Child windowsを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui_demo.cpp | `imgui_demo.cpp` | Child windowsセクション（行4345-4477）を理解する |

**主要処理フロー**:
- **行4357-4365**: 水平スクロール対応の子ウィンドウ（ChildL）
- **行4370-4400**: 角丸ボーダーと内部テーブルを持つ子ウィンドウ（ChildR）
- **行4403-4415**: 手動リサイズ対応の子ウィンドウ（ResizableChild）
- **行4418-4432**: 制約付き自動リサイズの子ウィンドウ（ConstrainedChild）
- **行4443-4474**: カスタマイズオプションのデモ（Red）

#### Step 3: Widgets Widthを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_demo.cpp | `imgui_demo.cpp` | Widgets Widthセクション（行4479-4565）を理解する |

**主要処理フロー**:
- **行4493-4501**: PushItemWidth(100)による固定幅
- **行4503-4513**: PushItemWidth(-100)による右端からのオフセット
- **行4515-4525**: GetContentRegionAvail().x * 0.5fによる半分幅
- **行4552-4562**: PushItemWidth(-FLT_MIN)による右端揃え

#### Step 4: Scrollingを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | imgui_demo.cpp | `imgui_demo.cpp` | Scrollingセクション（行4835-5122）を理解する |

**主要処理フロー**:
- **行4871-4911**: 垂直スクロール（SetScrollHereY）
- **行4922-4957**: 水平スクロール（SetScrollHereX）
- **行4966-4996**: FizzBuzzボタンによる水平スクロールデモ

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

```
ShowDemoWindow()
    |
    +-- DemoWindowLayout()
            |
            +-- ImGui::CollapsingHeader("Layout & Scrolling")
            |
            +-- TreeNode("Child windows")
            |       |
            |       +-- BeginChild("ChildL") / EndChild()
            |       +-- BeginChild("ChildR") / EndChild()
            |       |       +-- BeginMenuBar() / EndMenuBar()
            |       |       +-- BeginTable() / EndTable()
            |       +-- BeginChild("ResizableChild") / EndChild()
            |       +-- BeginChild("ConstrainedChild") / EndChild()
            |       +-- BeginChild("Red") / EndChild()
            |
            +-- TreeNode("Widgets Width")
            |       |
            |       +-- PushItemWidth() / PopItemWidth()
            |       +-- DragFloat() [各種幅設定]
            |
            +-- TreeNode("Basic Horizontal Layout")
            |       |
            |       +-- Text() + SameLine() + Text()
            |       +-- Button() + SameLine() + Button()
            |       +-- Combo() + SameLine() + SliderFloat()
            |       +-- Dummy() [スペーサー]
            |
            +-- TreeNode("Groups")
            |       |
            |       +-- BeginGroup() / EndGroup()
            |       +-- GetItemRectSize() [サイズ取得]
            |       +-- PlotHistogram() [グループと同サイズ]
            |
            +-- TreeNode("Text Baseline Alignment")
            |       |
            |       +-- AlignTextToFramePadding()
            |       +-- Text() + SameLine() + Button()
            |
            +-- TreeNode("Scrolling")
            |       |
            |       +-- BeginChild() [5つの垂直スクロール]
            |       |       +-- SetScrollHereY()
            |       +-- BeginChild() [5つの水平スクロール]
            |               +-- SetScrollHereX()
            |
            +-- TreeNode("Text Clipping")
            |       |
            |       +-- InvisibleButton() [ドラッグ領域]
            |       +-- PushClipRect() / PopClipRect()
            |       +-- AddText() [クリップ付き]
            |
            +-- TreeNode("Overlap Mode")
                    |
                    +-- SetNextItemAllowOverlap()
                    +-- Button() [重なるボタン]
```

### データフロー図

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

なし -----------------> CollapsingHeader判定 ------------> セクション展開/折りたたみ
                              |
スクロール/リサイズ ----> BeginChild処理 ----------------> 子ウィンドウ状態
操作                          |                                |
                              |                                v
                              |                           スクロール位置
                              |                           ウィンドウサイズ
                              v
ウィジェット幅設定 ----> PushItemWidth() ---------------> ウィジェット幅
(100/-100/0.5f等)             |
                              v
水平配置操作 ----------> SameLine() --------------------> レイアウト更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui_demo.cpp | `imgui_demo.cpp` | ソース | DemoWindowLayout関数の実装（行4337-5219） |
| imgui.h | `imgui.h` | ヘッダー | レイアウト関連API定義（SameLine, BeginChild, PushItemWidth等） |
| imgui.cpp | `imgui.cpp` | ソース | レイアウト関連関数の実装 |
