# 画面設計書 14-Long Text

## 概要

本ドキュメントは、Dear ImGuiのサンプルアプリケーション「Long Text」画面の設計仕様を定義する。本画面は、大量のテキストを効率的に表示するサンプル実装であり、異なる表示方法のパフォーマンス比較を提供する。

### 本画面の処理概要

本画面は、ImGuiにおける大量テキストの表示方法とそのパフォーマンス特性を実演する。数千行のテキストを効率的に表示するための異なるアプローチ（単一呼び出し、クリッピング有り/無し）を比較できる。

**業務上の目的・背景**：ログビューア、テキストエディタ、コンソールなどのアプリケーションでは、数万行にも及ぶテキストを表示する必要がある。本画面は、ImGuiのTextUnformatted()による高速なテキスト表示と、ImGuiListClipperによる仮想スクロールの効果を実証する。開発者は適切な方法を選択するための知見を得ることができる。

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

**主要な操作・処理内容**：
1. テスト種別の選択（3種類の表示方法）
2. テキストバッファへの1000行追加
3. バッファのクリア
4. 大量テキストのスクロール表示

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

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 24 | Begin | 主機能 | ウィンドウの開始処理 |
| 25 | End | 主機能 | ウィンドウの終了処理 |
| 84 | TextUnformatted | 主機能 | 大量テキストの効率的な表示 |
| 98 | RadioButton | 補助機能 | 表示モードの切り替え（Combo使用） |
| 92 | Button | 補助機能 | テキスト追加/クリアボタン |

## 画面種別

表示（テキストビューア/パフォーマンステスト）

## URL/ルーティング

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

## 入出力項目

| 項目名 | 型 | I/O | 必須 | 説明 |
|--------|-----|-----|------|------|
| p_open | bool* | I/O | No | ウィンドウの表示状態を制御するポインタ |
| test_type | int (static) | I/O | No | テスト種別（0-2） |
| log | ImGuiTextBuffer (static) | I/O | No | テキストバッファ |
| lines | int (static) | I/O | No | 現在の行数 |

## 表示項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 説明テキスト | Text | "Printing unusually long amount of text." |
| テスト種別コンボ | Combo | 3種類の表示方法を選択 |
| バッファ情報 | Text | 行数とバイト数の表示 |
| ログテキスト | TextUnformatted/Text | テストパターンのテキスト |

## イベント仕様

### 1-テスト種別の変更

Comboボックスから表示方法を選択する：
- 0: "Single call to TextUnformatted()" - バッファ全体を1回の呼び出しで表示
- 1: "Multiple calls to Text(), clipped" - ImGuiListClipperを使用して表示範囲のみ描画
- 2: "Multiple calls to Text(), not clipped (slow)" - クリッピングなしで全行を描画

### 2-Clearボタン押下

log.clear()を呼び出してテキストバッファをクリアし、lines変数を0にリセットする。

### 3-Add 1000 linesボタン押下

forループで1000行のテストテキスト（"N The quick brown fox jumps over the lazy dog"）をバッファに追加する。lines変数に1000を加算。

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

本画面はデータベースを使用しない。テキストデータはstatic変数のImGuiTextBufferに保持される。

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

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

### メモリバッファ操作詳細

| 操作 | 対象バッファ | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Add 1000 lines | log (ImGuiTextBuffer) | APPEND | 1000行のテストテキストを追加 |
| Clear | log (ImGuiTextBuffer) | CLEAR | バッファ全体をクリア |

## メッセージ仕様

| 表示テキスト | 表示場所 | 説明 |
|-------------|---------|------|
| "Printing unusually long amount of text." | ウィンドウ上部 | 画面の説明 |
| "Buffer contents: %d lines, %d bytes" | ボタン下 | 現在のバッファ状態 |
| "%i The quick brown fox jumps over the lazy dog" | ログエリア | テストテキスト（行番号付き） |

## 例外処理

| 状態 | 処理内容 |
|------|----------|
| ウィンドウ非表示時 | Begin()がfalseを返した場合、End()を呼び出して即座にリターン |
| バッファ空時 | 子ウィンドウは空で表示 |

## 備考

- ImGuiTextBufferは動的にメモリを確保し、大量のテキストを効率的に保持
- TextUnformatted()は内部でクリッピング最適化を行い、表示範囲外のテキストをスキップ
- ImGuiListClipperを使用する方法（test_type=1）は、同一高さのアイテムが前提
- test_type=2は意図的に非効率な方法で、パフォーマンスの差を実感するためのもの
- ItemSpacingを0に設定してテキスト行間を詰めている

---

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

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

### 推奨読解順序

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

本画面は単純な構造で、static変数でテストデータを保持する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_demo.cpp | `imgui_demo.cpp` | 9602-9604行のstatic変数（test_type, log, lines） |

**読解のコツ**: ImGuiTextBufferはstd::stringに似た動的バッファで、appendf()で書式付き追加、begin()/end()でイテレータアクセスが可能。

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

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

**主要処理フロー**:
1. **9594行**: SetNextWindowSizeで初期サイズ520x600を設定
2. **9595-9599行**: Begin()でウィンドウを開始、失敗時は早期リターン
3. **9605行**: Text()で説明文を表示
4. **9606-9609行**: Combo()でテスト種別を選択
5. **9610行**: バッファの状態（行数・バイト数）を表示
6. **9611-9618行**: Clear/Addボタンの処理
7. **9619-9646行**: BeginChild()内でテスト種別に応じた描画

#### Step 3: 各表示方法を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_demo.cpp | `imgui_demo.cpp` | 9620-9645行のswitch文による表示方法の分岐 |

**主要処理フロー**:
- **9622-9625行**: case 0 - TextUnformatted()で全バッファを1回で出力
- **9626-9637行**: case 1 - ImGuiListClipperで表示範囲のみText()呼び出し
- **9638-9644行**: case 2 - 全行をText()で出力（非効率）

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

```
ShowExampleAppLongText(bool* p_open)
    |
    +-- ImGui::SetNextWindowSize(520, 600)
    |
    +-- ImGui::Begin("Example: Long text display", p_open)
    |
    +-- ImGui::Text("Printing unusually long amount of text.")
    |
    +-- ImGui::Combo("Test type", &test_type, ...)
    |
    +-- ImGui::Text("Buffer contents: %d lines, %d bytes")
    |
    +-- ImGui::Button("Clear")
    |       +-- log.clear()
    |       +-- lines = 0
    |
    +-- ImGui::Button("Add 1000 lines")
    |       +-- for (i = 0..999)
    |               +-- log.appendf(...)
    |       +-- lines += 1000
    |
    +-- ImGui::BeginChild("Log")
            |
            +-- switch (test_type)
                    |
                    +-- case 0: ImGui::TextUnformatted(log.begin(), log.end())
                    |
                    +-- case 1: [ImGuiListClipper使用]
                    |           +-- clipper.Begin(lines)
                    |           +-- while (clipper.Step())
                    |                   +-- for (DisplayStart..DisplayEnd)
                    |                           +-- ImGui::Text("%i ...")
                    |
                    +-- case 2: [クリッピングなし]
                                +-- for (i = 0..lines)
                                        +-- ImGui::Text("%i ...")
```

### データフロー図

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

"Add 1000 lines" -------> log.appendf()
                          |
                          +-> 1000行分のテキスト追加 --> テキストバッファ拡張

"Clear" ----------------> log.clear()
                          |
                          +-> バッファクリア -----------> 空のバッファ

テスト種別選択 ---------> switch (test_type)
                          |
                          +-> 表示方法の切り替え -------> 描画パフォーマンス変化
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui_demo.cpp | `imgui_demo.cpp` | ソース | ShowExampleAppLongText()関数のデモ実装 |
| imgui.h | `imgui.h` | ヘッダー | ImGuiTextBuffer, ImGuiListClipper, TextUnformattedの宣言 |
| imgui.cpp | `imgui.cpp` | ソース | Begin/End, BeginChild/EndChild, TextUnformattedの実装 |
| imgui_widgets.cpp | `imgui_widgets.cpp` | ソース | Text, Button, Comboの実装 |
