# 機能設計書 89-LabelText

## 概要

本ドキュメントは、Dear ImGuiライブラリにおけるLabelText関数の機能設計を定義する。LabelTextは、値+ラベル形式でテキストを表示する機能であり、他の入力ウィジェット（InputText、SliderFloat等）と同じレイアウトで「読み取り専用」の値を表示するために使用される。

### 本機能の処理概要

LabelText関数は、左側に値、右側にラベルという形式でテキストを表示する機能を提供する。InputTextやSliderFloatなどの入力ウィジェットと同じ配置ルールに従い、フォームやプロパティエディタにおいて一貫したレイアウトを実現する。

**業務上の目的・背景**：プロパティエディタやインスペクタのようなUIでは、編集可能な項目と読み取り専用の項目が混在することがある。LabelTextを使用することで、読み取り専用の値も編集可能な項目と同じレイアウトで表示でき、視覚的な一貫性を保つことができる。また、CalcItemWidthで設定された幅に従うため、他のウィジェットとの整列が容易である。

**機能の利用シーン**：
- プロパティエディタで読み取り専用の値を表示する場合
- 計算結果やステータスをラベル付きで表示する場合
- フォームで編集不可の項目を表示する場合
- 入力ウィジェットと同じレイアウトで情報を表示する場合

**主要な処理内容**：
1. 現在のウィンドウとスタイルを取得
2. CalcItemWidthで値の表示幅を計算
3. フォーマット文字列から値テキストを生成
4. テキストサイズを計算
5. ItemSize/ItemAddでアイテム領域を確保
6. 値とラベルをそれぞれ描画

**関連システム・外部連携**：ImGuiContext、ImGuiStyle、ImDrawList、CalcItemWidth

**権限による制御**：なし。すべてのImGuiユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 全画面 | 補助機能 | 値+ラベル形式のテキスト表示 |

## 機能種別

表示機能 / テキストウィジェット

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| label | const char* | Yes | 右側に表示するラベル | NULLチェックなし |
| fmt | const char* | Yes | printf形式のフォーマット文字列（値用） | NULLチェックなし |
| ... | 可変長引数 | No | フォーマット引数 | フォーマット文字列に対応 |

### 入力データソース

- 呼び出し元コードからの直接入力
- CalcItemWidth()の値（PushItemWidthで設定された幅）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | void | 戻り値なし。描画コマンドが生成される |

### 出力先

ImDrawList（ウィンドウの描画リスト）

## 処理フロー

### 処理シーケンス

```
1. 可変長引数の初期化
   └─ va_start(args, fmt)
2. LabelTextV関数の呼び出し
   └─ 実際の処理をLabelTextVに委譲
3. 可変長引数の終了
   └─ va_end(args)

LabelTextV内部処理:
4. ウィンドウとスタイルの取得
   └─ GetCurrentWindow()、g.Style
5. アイテム幅の計算
   └─ CalcItemWidth()
6. 値テキストのフォーマット
   └─ ImFormatStringToTempBufferV
7. テキストサイズの計算
   └─ CalcTextSize（値とラベルそれぞれ）
8. 境界ボックスの計算
   └─ value_bb, total_bb
9. ItemSize/ItemAdd
   └─ アイテム領域の確保と登録
10. 描画
    └─ RenderTextClipped（値）+ RenderText（ラベル）
```

### フローチャート

```mermaid
flowchart TD
    A[LabelText開始] --> B[va_start]
    B --> C[LabelTextV呼び出し]
    C --> D[GetCurrentWindow]
    D --> E{SkipItems?}
    E -->|Yes| F[リターン]
    E -->|No| G[CalcItemWidth]
    G --> H[フォーマット処理]
    H --> I[CalcTextSize 値/ラベル]
    I --> J[境界ボックス計算]
    J --> K[ItemSize/ItemAdd]
    K --> L{ItemAdd成功?}
    L -->|No| M[リターン]
    L -->|Yes| N[RenderTextClipped 値]
    N --> O[RenderText ラベル]
    O --> P[va_end]
    P --> Q[終了]
    F --> Q
    M --> Q
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | レイアウト一貫性 | InputText等と同じレイアウトルールに従う | 常時 |
| BR-02 | 幅設定 | CalcItemWidthで設定された幅を値表示に使用 | 常時 |
| BR-03 | ラベル配置 | ラベルは値の右側に配置される | 常時 |
| BR-04 | パディング | FramePaddingが適用される | 常時 |

### 計算ロジック

- **値の表示領域**: pos から pos + ImVec2(w, value_size.y + style.FramePadding.y * 2)
- **全体の高さ**: ImMax(value_size.y, label_size.y) + style.FramePadding.y * 2
- **ラベル位置**: value_bb.Max.x + style.ItemInnerSpacing.x

## データベース操作仕様

該当なし（メモリ内操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 通常エラーは発生しない | - |

### リトライ仕様

該当なし

## トランザクション仕様

該当なし

## パフォーマンス要件

- フォーマット処理のオーバーヘッドあり
- テキストサイズ計算のオーバーヘッドあり
- 1フレーム内で多数回呼び出し可能

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

- Text関数と同様、ユーザー入力をフォーマット文字列として直接使用しないこと

## 備考

- 他の入力ウィジェットと同じアイテム幅を使用するため、PushItemWidth/PopItemWidthの影響を受ける
- LabelTextVはva_list版
- IM_FMTARGS(2)マクロによりコンパイラのフォーマット文字列チェックが有効
- ラベルがない場合（空文字列の場合）はラベル部分が描画されない

---

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

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

### 推奨読解順序

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

レイアウト関連の構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | ImGuiStyle構造体（FramePadding、ItemInnerSpacing） |
| 1-2 | imgui_internal.h | `imgui_internal.h` | ImRect構造体 |

**読解のコツ**: FramePaddingはウィジェット内部のパディング、ItemInnerSpacingは同一行内の要素間のスペースである。

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

LabelText関数の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.h | `imgui.h` | LabelText/LabelTextV関数宣言（623-624行目） |
| 2-2 | imgui_widgets.cpp | `imgui_widgets.cpp` | LabelText/LabelTextV関数実装（382-417行目） |

**主要処理フロー**:
1. **382-388行目**: LabelText関数 - va_startで可変長引数を初期化し、LabelTextVを呼び出し、va_endで終了
2. **391-417行目**: LabelTextV関数
   - **393-395行目**: GetCurrentWindowとSkipItems確認
   - **397-399行目**: スタイル取得とCalcItemWidth
   - **401-402行目**: ImFormatStringToTempBufferVでフォーマット処理
   - **403-404行目**: 値とラベルのテキストサイズ計算
   - **406-408行目**: 境界ボックスの計算
   - **409-410行目**: ItemSize/ItemAdd
   - **414行目**: RenderTextClippedで値を描画
   - **415-416行目**: ラベルがある場合はRenderTextでラベルを描画

#### Step 3: レイアウト計算を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui.cpp | `imgui.cpp` | CalcItemWidth関数 |

**主要処理フロー**:
- CalcItemWidth: PushItemWidthで設定された幅、またはデフォルト幅を返す

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

```
ImGui::LabelText(label, fmt, ...)
    │
    ├─ va_start(args, fmt)
    │
    └─ ImGui::LabelTextV(label, fmt, args)
           │
           ├─ GetCurrentWindow()
           │
           ├─ CalcItemWidth()
           │
           ├─ ImFormatStringToTempBufferV()
           │
           ├─ CalcTextSize()（値用、ラベル用）
           │
           ├─ ItemSize() / ItemAdd()
           │
           ├─ RenderTextClipped()（値）
           │
           └─ RenderText()（ラベル）
```

### データフロー図

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

label + fmt + ... ───▶ フォーマット ───▶ レイアウト計算 ───▶ 描画
                          │                     │
                          │                     ├── value_bb（値の領域）
                          │                     │
                          └── 値テキスト        └── total_bb（全体の領域）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | LabelText/LabelTextV関数の宣言（623-624行目） |
| imgui_widgets.cpp | `imgui_widgets.cpp` | ソース | LabelText/LabelTextV関数の実装（382-417行目） |
| imgui.cpp | `imgui.cpp` | ソース | CalcItemWidth関数、レイアウト関連関数 |
| imgui_internal.h | `imgui_internal.h` | 内部ヘッダー | ImRect構造体、内部関数 |
