# 画面設計書 16-Constrained Resize

## 概要

本ドキュメントは、Dear ImGuiのサンプルアプリケーション「Constrained Resize」画面の設計仕様を定義する。本画面は、カスタムリサイズ制約を持つウィンドウのサンプル実装である。

### 本画面の処理概要

本画面は、SetNextWindowSizeConstraints()を使用してウィンドウのリサイズ動作をカスタマイズする方法を実演する。9種類の異なる制約パターン（最小/最大サイズ、アスペクト比維持、正方形、固定ステップ等）を試すことができる。

**業務上の目的・背景**：ゲームUI、ビューポート、グリッドレイアウトなどでは、ウィンドウサイズに特定の制約を課したい場合がある。例えば、アスペクト比を16:9に固定したビューポートや、グリッドに沿ったサイズ調整などが典型的なユースケースである。本画面は、これらの制約をImGuiで実現する方法を示す。

**画面へのアクセス方法**：Demo Windowのメニューバーから「Examples」メニューを選択し、「Constrained Resize」を選択することで表示される。または、アプリケーションコード内で`ShowExampleAppConstrainedResize(&show_app_constrained_resize)`を呼び出すことで直接表示可能。

**主要な操作・処理内容**：
1. 制約タイプの選択（9種類のプリセット）
2. ウィンドウのリサイズ操作で制約の効果を確認
3. プリセットサイズボタンでウィンドウサイズを変更
4. オートリサイズ/ウィンドウパディングオプションの切り替え
5. Shiftキー押下でダミービューポートを表示

**画面遷移**：本画面はDemo Windowの「Examples」メニューから呼び出される。独立したウィンドウとして表示され、他の画面への直接的な遷移機能は持たない。

**権限による表示制御**：本画面は権限による表示制御を持たない。すべてのユーザーが同一の機能にアクセス可能である。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 24 | Begin | 主機能 | ウィンドウの開始処理 |
| 25 | End | 主機能 | ウィンドウの終了処理 |
| 37 | SetNextWindowSizeConstraints | 主機能 | サイズ制約の設定 |
| 103 | BeginCombo | 補助機能 | 制約モード選択コンボボックス |
| 104 | EndCombo | 補助機能 | コンボボックスの終了 |

## 画面種別

デモ（ウィンドウ動作サンプル）

## URL/ルーティング

N/A（ImGuiはURLベースのルーティングを持たない。`ShowExampleAppConstrainedResize()`関数呼び出しによりウィンドウを表示）

## 入出力項目

| 項目名 | 型 | I/O | 必須 | 説明 |
|--------|-----|-----|------|------|
| p_open | bool* | I/O | No | ウィンドウの表示状態を制御するポインタ |
| auto_resize | bool (static) | I/O | No | オートリサイズの有効/無効 |
| window_padding | bool (static) | I/O | No | ウィンドウパディングの有効/無効 |
| type | int (static) | I/O | No | 制約タイプ（0-8、デフォルト6） |
| display_lines | int (static) | I/O | No | 表示行数（デフォルト10） |

## 表示項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ダミービューポート | ColorButton | Shift押下時に表示されるサイズ確認用領域 |
| サイズプリセットボタン | Button | 200x200, 500x500, 800x200のプリセット |
| 制約選択コンボ | Combo | 9種類の制約タイプを選択 |
| 行数スライダー | DragInt | 表示行数を調整 |
| オプションチェック | Checkbox | Auto-resize, Window padding |
| テキスト行 | Text | インデント付きのサンプルテキスト |

## イベント仕様

### 1-制約タイプ選択

Comboボックスから9種類の制約タイプを選択する：
- 0: Between 100x100 and 500x500 - 最小・最大サイズ制限
- 1: At least 100x100 - 最小サイズのみ
- 2: Resize vertical + lock current width - 幅固定、高さのみリサイズ
- 3: Resize horizontal + lock current height - 高さ固定、幅のみリサイズ
- 4: Width Between 400 and 500 - 幅のみ範囲制限
- 5: Height at least 400 - 高さの最小制限
- 6: Custom: Aspect Ratio 16:9 - アスペクト比維持（コールバック使用）
- 7: Custom: Always Square - 常に正方形（コールバック使用）
- 8: Custom: Fixed Steps (100) - 100ピクセル単位でリサイズ（コールバック使用）

### 2-プリセットサイズボタン

「Set 200x200」「Set 500x500」「Set 800x200」ボタンで、SetWindowSize()を呼び出してウィンドウサイズを即座に変更する。

### 3-Shiftキー押下

Shiftキーを押している間、ウィンドウ内容がダミービューポート（ColorButton）に置き換わり、現在のコンテンツ領域サイズが表示される。

### 4-オプション切り替え

- Auto-resize: ImGuiWindowFlags_AlwaysAutoResizeフラグを切り替え
- Window padding: WindowPaddingスタイル変数を0またはデフォルトに設定

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

本画面はデータベースを使用しない。

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

N/A（データベースアクセスなし）

## メッセージ仕様

| 表示テキスト | 表示場所 | 説明 |
|-------------|---------|------|
| "(Hold Shift to display a dummy viewport)" | ウィンドウ上部 | 操作ガイド |
| "%.2f x %.2f" | ダミービューポート内 | コンテンツ領域サイズ |
| "Hello, sailor! Making this line long enough for the example." | ウィンドウ下部 | サンプルテキスト |

## 例外処理

| 状態 | 処理内容 |
|------|----------|
| window_openがfalse | ウィンドウ内容は描画されないがEnd()は呼び出される |
| ドッキング使用時 | サイズ制約は機能しない（dockin'ブランチでの制限事項） |

## 備考

- カスタム制約（type 6-8）はコールバック関数で実装
- CustomConstraints構造体にAspectRatio(), Square(), Step()の3つのコールバックを定義
- サイズ制約はウィンドウデコレーション（タイトルバー等）を考慮しない点に注意
- ボーダーからのリサイズは3つのカスタムデモで正常に動作しない場合がある

---

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

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

### 推奨読解順序

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

カスタム制約のコールバック構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_demo.cpp | `imgui_demo.cpp` | 9683-9702行のCustomConstraints構造体 |
| 1-2 | imgui_demo.cpp | `imgui_demo.cpp` | 9704-9715行のtest_desc配列（制約説明文） |
| 1-3 | imgui_demo.cpp | `imgui_demo.cpp` | 9717-9721行のstatic変数 |

**読解のコツ**: ImGuiSizeCallbackDataにはDesiredSizeが含まれ、コールバックでこの値を変更することで制約を実現する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui_demo.cpp | `imgui_demo.cpp` | ShowExampleAppConstrainedResize()関数（9681-9772行）全体を確認 |

**主要処理フロー**:
1. **9723-9734行**: type変数に基づいてSetNextWindowSizeConstraints()を呼び出し
2. **9737-9742行**: window_paddingオプションによるスタイル変更
3. **9740行**: Begin()でウィンドウを開始
4. **9746-9769行**: Shift押下でビューポート表示、通常時はUI表示

#### Step 3: 制約設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_demo.cpp | `imgui_demo.cpp` | 9726-9734行の9種類の制約設定 |

**主要処理フロー**:
- **9726行**: type=0: 最小100x100、最大500x500
- **9727行**: type=1: 最小100x100、最大無制限
- **9728行**: type=2: 幅固定（-1）、高さ可変
- **9729行**: type=3: 高さ固定（-1）、幅可変
- **9732-9734行**: カスタムコールバックを使用

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

```
ShowExampleAppConstrainedResize(bool* p_open)
    |
    +-- [制約タイプに応じた設定]
    |   +-- type=0-5: SetNextWindowSizeConstraints(min, max)
    |   +-- type=6: SetNextWindowSizeConstraints(..., AspectRatio, &aspect_ratio)
    |   +-- type=7: SetNextWindowSizeConstraints(..., Square)
    |   +-- type=8: SetNextWindowSizeConstraints(..., Step, &fixed_step)
    |
    +-- [パディング設定]
    |   +-- PushStyleVar(WindowPadding, 0) / PopStyleVar()
    |
    +-- ImGui::Begin("Example: Constrained Resize", p_open, window_flags)
            |
            +-- [Shift押下時]
            |   +-- ImGui::GetContentRegionAvail()
            |   +-- ImGui::ColorButton("viewport", ...)
            |   +-- ImGui::Text("%.2f x %.2f")
            |
            +-- [通常時]
                +-- ImGui::Text("(Hold Shift to display...)")
                +-- ImGui::Button("Set 200x200") -> SetWindowSize()
                +-- ImGui::Button("Set 500x500") -> SetWindowSize()
                +-- ImGui::Button("Set 800x200") -> SetWindowSize()
                +-- ImGui::Combo("Constraint", &type, test_desc)
                +-- ImGui::DragInt("Lines", &display_lines)
                +-- ImGui::Checkbox("Auto-resize", &auto_resize)
                +-- ImGui::Checkbox("Window padding", &window_padding)
                +-- for (display_lines)
                        +-- ImGui::Text("Hello, sailor!...")
```

### データフロー図

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

制約タイプ選択 ---------> SetNextWindowSizeConstraints()
                          |
                          +-> ImGuiSizeCallbackData -----> リサイズ時の制約適用

リサイズ操作 -----------> コールバック呼び出し
                          |
                          +-> DesiredSize変更 -----------> 制約に沿ったサイズ

プリセットボタン -------> SetWindowSize()
                          |
                          +-> ウィンドウサイズ変更 ------> 制約適用後の表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui_demo.cpp | `imgui_demo.cpp` | ソース | ShowExampleAppConstrainedResize()関数とCustomConstraints構造体 |
| imgui.h | `imgui.h` | ヘッダー | SetNextWindowSizeConstraints、ImGuiSizeCallbackDataの宣言 |
| imgui.cpp | `imgui.cpp` | ソース | Begin/End、サイズ制約処理の実装 |
| imgui_widgets.cpp | `imgui_widgets.cpp` | ソース | Button, Combo, Checkbox, DragIntの実装 |
