# 画面設計書 19-Window Titles

## 概要

本ドキュメントは、Dear ImGuiのサンプルアプリケーション「Window Titles」画面の設計仕様を定義する。本画面は、ウィンドウタイトルとID生成の操作方法を実演するサンプル実装である。

### 本画面の処理概要

本画面は、ImGuiにおけるウィンドウIDの生成と、タイトル表示の制御方法を実演する。「##」と「###」マーカーを使用して、表示タイトルとID生成を分離する方法を学ぶことができる。3つのウィンドウが同時に表示され、それぞれ異なるパターンを示す。

**業務上の目的・背景**：ImGuiでは、ウィンドウは標準でタイトル文字列をIDとして使用する。しかし、同じ表示名で異なるウィンドウを作成したい場合や、表示名を動的に変更しつつ同一のウィンドウとして扱いたい場合がある。本画面は、これらのユースケースに対応するための「##」「###」マーカーの使用方法を示す。

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

**主要な操作・処理内容**：
1. 同一タイトル+異なるIDの2つのウィンドウを表示（##マーカー使用）
2. 動的に変化するタイトル+固定IDのウィンドウを表示（###マーカー使用）
3. 各ウィンドウの独立した位置・サイズ管理

**画面遷移**：本画面はDemo Windowの「Examples」メニューから呼び出される。3つのウィンドウが同時に表示され、それぞれ独立して閉じることはできない。

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 24 | Begin | 主機能 | 複数ウィンドウの開始処理 |
| 25 | End | 主機能 | ウィンドウの終了処理 |
| 85 | Text | 補助機能 | ウィンドウ内テキストの表示 |

## 画面種別

デモ（ID生成サンプル）

## URL/ルーティング

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

## 入出力項目

| 項目名 | 型 | I/O | 必須 | 説明 |
|--------|-----|-----|------|------|
| p_open | bool* | I | No | 未使用（互換性のため存在） |

## 表示項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ウィンドウ1 | Window | タイトル "Same title as another window##1" |
| ウィンドウ2 | Window | タイトル "Same title as another window##2" |
| ウィンドウ3 | Window | タイトル "Animated title [動的文字列]###AnimatedTitle" |
| 説明テキスト | Text | 各ウィンドウ内の説明 |

## イベント仕様

### 1-##マーカーによるID分離（ウィンドウ1, 2）

「Same title as another window##1」と「Same title as another window##2」の2つのウィンドウは、表示上は同じタイトル「Same title as another window」を持つが、「##」以降の「1」「2」によって異なるIDが生成される。これにより、同一表示名でも別々のウィンドウとして管理される。

### 2-###マーカーによる動的タイトル（ウィンドウ3）

「Animated title [動的文字列]###AnimatedTitle」は、表示タイトルが毎フレーム変化する。しかし「###」以降の「AnimatedTitle」がIDとして使用されるため、タイトルが変わっても同一ウィンドウとして位置・サイズが保持される。

アニメーション要素：
- 回転する文字（| / - \）が0.25秒ごとに変化
- フレームカウンターが表示される

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

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

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

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

## メッセージ仕様

| 表示テキスト | 表示場所 | 説明 |
|-------------|---------|------|
| "This is window 1.\nMy title is the same as window 2, but my identifier is unique." | ウィンドウ1 | ##マーカーの説明 |
| "This is window 2.\nMy title is the same as window 1, but my identifier is unique." | ウィンドウ2 | ##マーカーの説明 |
| "This window has a changing title." | ウィンドウ3 | ###マーカーの説明 |

## 例外処理

| 状態 | 処理内容 |
|------|----------|
| p_openがNULL | 問題なく動作（引数を使用しない） |

## 備考

- p_open引数は互換性のために存在するが、実際には使用されていない
- 各ウィンドウは初回表示時にSetNextWindowPosで位置を設定（ImGuiCond_FirstUseEver）
- base_posはビューポート位置を取得し、相対位置で各ウィンドウを配置
- GetTime()とGetFrameCount()でアニメーションを実現
- sprintf()でタイトル文字列を動的に生成

---

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

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

### 推奨読解順序

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

本画面はstatic変数を使用しない。すべての状態はImGuiの内部で管理される。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_demo.cpp | `imgui_demo.cpp` | 9870-9872行のコメントでマーカーの使い方を確認 |

**読解のコツ**: ImGuiのIDシステムでは、「##」以降の文字列はIDに使用されるが表示されない。「###」以降の文字列はIDに使用され、それ以前の文字列は表示のみに使用される。

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

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

**主要処理フロー**:
1. **9875-9876行**: GetMainViewport()でbase_posを取得
2. **9882-9886行**: ウィンドウ1（##1）の表示
3. **9888-9891行**: ウィンドウ2（##2）の表示
4. **9894-9899行**: ウィンドウ3（###AnimatedTitle）の表示

#### Step 3: アニメーションタイトルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_demo.cpp | `imgui_demo.cpp` | 9894-9895行のタイトル生成 |

**主要処理フロー**:
- **9895行**: sprintf()でタイトル文字列を動的に生成
  - `"|/-\\"[(int)(GetTime() / 0.25f) & 3]`: 回転文字（0.25秒周期）
  - `GetFrameCount()`: 現在のフレーム番号
  - `###AnimatedTitle`: 固定ID

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

```
ShowExampleAppWindowTitles(bool*)
    |
    +-- ImGui::GetMainViewport()
    |       +-> base_pos = viewport->Pos
    |
    +-- [Window 1: ##マーカー]
    |   +-- SetNextWindowPos(base_pos + (100, 100))
    |   +-- Begin("Same title as another window##1")
    |   +-- Text("This is window 1...")
    |   +-- End()
    |
    +-- [Window 2: ##マーカー]
    |   +-- SetNextWindowPos(base_pos + (100, 200))
    |   +-- Begin("Same title as another window##2")
    |   +-- Text("This is window 2...")
    |   +-- End()
    |
    +-- [Window 3: ###マーカー]
        +-- sprintf(buf, "Animated title %c %d###AnimatedTitle", ...)
        +-- SetNextWindowPos(base_pos + (100, 300))
        +-- Begin(buf)
        +-- Text("This window has a changing title.")
        +-- End()
```

### データフロー図

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

タイトル文字列 ---------> Begin()
                          |
                          +-> "##"検出 -----------------> 表示: ##より前
                          |                              ID: ##より後
                          |
                          +-> "###"検出 ----------------> 表示: ###より前
                                                          ID: ###より後

GetTime() --------------> アニメーション計算
                          |
                          +-> 回転文字選択 -------------> タイトルに埋め込み

GetFrameCount() --------> sprintf()
                          |
                          +-> フレーム番号 -------------> タイトルに埋め込み
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui_demo.cpp | `imgui_demo.cpp` | ソース | ShowExampleAppWindowTitles()関数のデモ実装 |
| imgui.h | `imgui.h` | ヘッダー | Begin, GetTime, GetFrameCount, GetMainViewportの宣言 |
| imgui.cpp | `imgui.cpp` | ソース | Begin/End、ID生成ロジックの実装 |
