# 帳票設計書 3-クリップボードログ出力

## 概要

本ドキュメントは、Dear ImGuiライブラリのクリップボードログ出力機能に関する帳票設計書である。GUIのテキスト出力をOSのクリップボードにキャプチャする機能について記述する。

### 本帳票の処理概要

クリップボードログ出力機能は、ImGuiウィジェットから生成されるテキスト出力をメモリ上のバッファに蓄積し、LogFinish呼び出し時にOSクリップボードにコピーする機能である。

**業務上の目的・背景**：GUI開発において、ウィジェットの状態やレイアウト情報を素早く他のアプリケーション（テキストエディタ、ドキュメント作成ツール、チャットアプリなど）と共有したい場合がある。クリップボードログ出力機能により、ファイル保存やコンソール確認を経由せずに、直接クリップボード経由でテキストデータを転送できる。これは、バグレポート作成時やペアプログラミング時の情報共有に特に有用である。

**帳票の利用シーン**：開発者がウィンドウ構造やウィジェット状態を素早くコピーしたい場合に、LogToClipboard関数を呼び出してログキャプチャを開始する。LogFinish後、クリップボードの内容を任意のアプリケーションにペーストできる。LogButtons関数によりGUI上のボタンからも簡便にクリップボード出力を開始できる。また、スタイルエディタではスタイル設定のエクスポートにも使用される。

**主要な出力内容**：
1. ウィジェットのテキストラベル（Button、Text、TreeNodeなど）
2. ツリー構造のインデント（TreeDepthに応じた4スペースのインデント）
3. LogText関数で直接出力されたカスタムテキスト
4. ウィジェットの装飾テキスト（prefix/suffix）

**帳票の出力タイミング**：LogToClipboard関数が呼び出された時点からログキャプチャが開始され、LogFinish関数が呼び出されると蓄積されたテキストがSetClipboardText関数を通じてOSクリップボードにコピーされる。

**帳票の利用者**：アプリケーション開発者、テクニカルライター、サポートエンジニア

## 帳票種別

ログ出力（クリップボード転送形式）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | 任意のImGuiウィンドウ | - | LogToClipboard()関数呼び出し |
| - | デモウィンドウ | - | LogButtonsからの「Log To Clipboard」ボタン |
| - | スタイルエディタ | - | Colorsタブの「Export」ボタン |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（クリップボード転送） |
| 用紙サイズ | N/A（クリップボード出力） |
| 向き | N/A |
| ファイル名 | N/A（クリップボードへ直接出力） |
| 出力方法 | SetClipboardText関数経由 |
| 文字コード | UTF-8（プラットフォーム依存） |

### クリップボード固有設定

| 項目 | 内容 |
|-----|------|
| バッファ | g.LogBuffer（ImGuiTextBuffer） |
| 転送タイミング | LogFinish()呼び出し時 |
| 転送関数 | SetClipboardText() |

## 帳票レイアウト

### レイアウト概要

テキストベースのログ出力であり、階層構造をインデントで表現する。

```
[ウィンドウ/ウィジェットテキスト]
    [子ウィジェットテキスト（4スペースインデント）]
        [孫ウィジェット（8スペースインデント）]
[改行による区切り]
```

### 出力項目

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | テキスト内容 | ウィジェットが表示するテキスト | ImGui::LogRenderedText | プレーンテキスト |
| 2 | インデント | ツリー深度に応じた空白 | TreeDepth * 4 | スペース文字 |
| 3 | 改行 | 行の区切り | IM_NEWLINE | LF または CRLF |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| LogEnabled | ログ機能が有効であること | Yes |
| バッファ非空 | LogFinish時にg.LogBufferが空でないこと | Yes（空の場合はクリップボード更新されない） |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | 描画順 | 昇順（ウィジェット描画順） |

### 改ページ条件

N/A（クリップボード転送のため改ページ概念なし）

## データベース参照仕様

### 参照テーブル一覧

N/A（データベースは使用しない）

### 内部データ構造参照

| データ構造 | 用途 | アクセス方法 |
|-----------|------|-------------|
| ImGuiContext.LogBuffer | テキスト蓄積バッファ | g.LogBuffer |
| ImGuiContext.LogEnabled | ログ有効フラグ | g.LogEnabled |
| ImGuiContext.LogFlags | ログ種別フラグ | g.LogFlags |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| インデント幅 | TreeDepth * 4 | なし | スペース文字数 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[LogToClipboard呼び出し] --> B{既にログ有効?}
    B -->|Yes| Z[終了]
    B -->|No| C[LogBegin実行]
    C --> D[ログキャプチャ開始]
    D --> E[ウィジェット描画]
    E --> F[LogRenderedText呼び出し]
    F --> G[テキストをLogBufferへ追加]
    G --> H{LogFinish呼び出し?}
    H -->|No| E
    H -->|Yes| I{LogBuffer空?}
    I -->|Yes| J[クリップボード更新なし]
    I -->|No| K[SetClipboardText実行]
    K --> L[ログ状態リセット]
    J --> L
    L --> Z
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 既にログ有効 | LogToClipboard呼び出し時に既にログが有効 | なし（早期リターン） | 既存ログセッションを終了後に再開 |
| バッファ空 | LogFinish時にLogBufferが空 | なし（クリップボード更新スキップ） | ログ対象ウィジェットが存在するか確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | メモリ制限内 |
| 目標出力時間 | 即時（メモリ操作） |
| 同時出力数上限 | 1（同時に1つのログセッションのみ） |

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

- クリップボードは他のアプリケーションからアクセス可能なため、機密情報の漏洩に注意
- クリップボードマネージャーによる履歴記録にも留意
- 共有PC環境での使用時は特に注意が必要

## 備考

- LogBufferが空の場合、クリップボードは更新されない（既存のクリップボード内容が保持される）
- auto_open_depth引数により、ツリーノードの自動展開深度を制御可能（-1でデフォルト値使用）
- スタイルエディタでは、カラー設定のC++コードエクスポートにも使用される

---

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

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

### 推奨読解順序

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

まず、ログ機能で使用されるデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | 961行目: LogToClipboard関数の宣言を確認 |
| 1-2 | imgui_internal.h | `imgui_internal.h` | ImGuiLogFlags_OutputClipboard定義を確認 |
| 1-3 | imgui.h | `imgui.h` | 1119-1122行目: クリップボードユーティリティ（GetClipboardText/SetClipboardText）を確認 |

**読解のコツ**: imgui.hの関数宣言コメントで機能概要を把握し、関連するクリップボードAPIとの連携を理解する。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.cpp | `imgui.cpp` | 15213-15219行目: LogToClipboard関数の実装 |

**主要処理フロー**:
1. **15215-15217行目**: 既にログ有効なら早期リターン
2. **15218行目**: LogBegin関数でログセッション開始（ImGuiLogFlags_OutputClipboard）

#### Step 3: ログ終了とクリップボード転送を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui.cpp | `imgui.cpp` | 15229-15261行目: LogFinish関数 |
| 3-2 | imgui.cpp | `imgui.cpp` | 15248-15251行目: クリップボードへの転送処理 |

**主要処理フロー**:
- **15248行目**: ImGuiLogFlags_OutputClipboardケース
- **15249行目**: LogBufferが空でないか確認
- **15250行目**: SetClipboardText(g.LogBuffer.begin())でクリップボードに転送

#### Step 4: 実際の使用例を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | imgui_demo.cpp | `imgui_demo.cpp` | 8525-8541行目: スタイルエディタでのExport機能 |
| 4-2 | imgui.cpp | `imgui.cpp` | 8025行目: Ctrl+Cによるウィンドウ内容コピー |

**主要処理フロー**:
- **8528行目**: output_dest == 0の場合LogToClipboard()を使用
- **8540行目**: LogFinish()でクリップボードに転送

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

```
LogToClipboard(auto_open_depth)
    │
    └─ LogBegin(ImGuiLogFlags_OutputClipboard, auto_open_depth)
           ├─ g.LogEnabled = true
           ├─ g.LogFlags = flags
           └─ g.LogDepthRef = window->DC.TreeDepth
                  │
                  └─ [ウィジェット描画時]
                         │
                         └─ LogRenderedText(ref_pos, text, text_end)
                                │
                                └─ LogText(fmt, ...)
                                       │
                                       └─ LogTextV(g, fmt, args)
                                              │
                                              └─ g.LogBuffer.appendfv(...)

LogFinish()
    │
    ├─ LogText(IM_NEWLINE)
    ├─ [case ImGuiLogFlags_OutputClipboard]
    │      └─ if (!g.LogBuffer.empty())
    │             └─ SetClipboardText(g.LogBuffer.begin())
    ├─ g.LogEnabled = false
    └─ g.LogBuffer.clear()
```

### データフロー図

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

LogToClipboard() ───────▶ LogBegin()
                              │
                              ▼
ウィジェット描画 ─────────▶ LogRenderedText()
                              │
                              ▼
                        LogTextV()
                              │
                              ▼
                        g.LogBuffer ◀─────── [メモリ蓄積]
                              │
                              ▼
LogFinish() ──────────▶ SetClipboardText() ──▶ OSクリップボード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | 公開API宣言（LogToClipboard, SetClipboardText等） |
| imgui.cpp | `imgui.cpp` | ソース | ログ機能の実装 |
| imgui_internal.h | `imgui_internal.h` | ヘッダー | 内部データ構造定義 |
| imgui_demo.cpp | `imgui_demo.cpp` | ソース | スタイルエディタでの使用例 |
