# 機能設計書 99-ProgressBar

## 概要

本ドキュメントはImGuiのProgressBar機能について、その処理内容、入出力仕様、実装詳細を記述した機能設計書である。

### 本機能の処理概要

ProgressBarは、進捗状況を視覚的に表示するためのプログレスバーウィジェットを作成するUI機能である。0.0〜1.0の値を受け取り、その割合に応じてバーを塗りつぶす。また、負の値を指定すると「不確定状態」のアニメーションを表示できる。オプションでオーバーレイテキストを表示可能。

**業務上の目的・背景**：GUIアプリケーションにおいて、時間のかかる処理の進捗状況をユーザーに伝えることは非常に重要である。ファイルのダウンロード、データの読み込み、長時間処理の実行など、進捗を可視化することでユーザーの不安を軽減し、処理が正常に動作していることを示す。ProgressBarはこれらのニーズに対応し、シンプルかつ効果的な進捗表示を提供する。

**機能の利用シーン**：ファイル転送の進捗表示、データ読み込み中の表示、長時間処理の進捗、バッチ処理の完了率、タスクの達成度表示などで使用される。

**主要な処理内容**：
1. プログレスバーのサイズを計算する
2. バウンディングボックスを確定し、領域を確保する
3. フレームを描画する（背景）
4. 進捗に応じた幅でバーを塗りつぶす
5. 不確定状態の場合はアニメーション用のバー位置を計算する
6. オーバーレイテキストを描画する（指定時またはデフォルトのパーセント表示）

**関連システム・外部連携**：ImGuiのDrawList描画システムと連携。RenderFrame、RenderRectFilledInRangeHを使用。

**権限による制御**：特になし（読み取り専用表示ウィジェット）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 23 | Widgets | 補助機能 | プログレスバーのデモ |

## 機能種別

UIウィジェット / 状態表示

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| fraction | float | Yes | 進捗率（0.0〜1.0）。負の値は不確定状態 | 負の値でアニメーション、NaN対応 |
| size_arg | const ImVec2& | No | バーのサイズ。0で自動、負で右端揃え | デフォルト: ImVec2(-FLT_MIN, 0) |
| overlay | const char* | No | オーバーレイテキスト | NULL終端文字列またはNULL |

### 入力データソース

- 呼び出し元からの直接指定
- ImGuiStyleからのスタイル設定値

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | void | 戻り値なし |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. ウィンドウの取得とスキップチェック
   └─ GetCurrentWindow()で現在のウィンドウを取得
   └─ SkipItemsがtrueの場合はreturn

2. サイズ計算
   └─ CalcItemSize()で最終サイズを決定
   └─ 幅のデフォルト: CalcItemWidth()
   └─ 高さのデフォルト: FontSize + FramePadding.y * 2

3. アイテム登録
   └─ ItemSize()でレイアウト領域を確保
   └─ ItemAdd()で描画リストに追加

4. 進捗値の処理
   └─ fraction < 0: 不確定状態
   └─ fraction >= 0: ImSaturate()で0.0〜1.0にクランプ
   └─ NaN対応（fraction != fractionで判定）

5. 不確定状態の計算
   └─ fill_n0, fill_n1を計算（アニメーション用）

6. 描画
   └─ RenderFrame()で背景フレームを描画
   └─ RenderRectFilledInRangeH()で進捗バーを描画

7. オーバーレイテキスト
   └─ overlay指定時: そのテキストを描画
   └─ overlay未指定かつ確定状態: "XX%"形式で自動生成
   └─ 不確定状態かつoverlay未指定: テキストなし
```

### フローチャート

```mermaid
flowchart TD
    A[開始: ProgressBar] --> B{SkipItems?}
    B -->|Yes| C[return]
    B -->|No| D[サイズ計算]
    D --> E[ItemSize/ItemAdd]
    E --> F{ItemAdd成功?}
    F -->|No| C
    F -->|Yes| G{fraction < 0?}
    G -->|Yes| H[不確定状態<br/>アニメーション計算]
    G -->|No| I[fraction を 0-1 にクランプ]
    H --> J[RenderFrame<br/>背景描画]
    I --> J
    J --> K[RenderRectFilledInRangeH<br/>進捗バー描画]
    K --> L{overlay指定?}
    L -->|Yes| M[指定テキストを描画]
    L -->|No| N{不確定状態?}
    N -->|Yes| C
    N -->|No| O[パーセント表示を生成・描画]
    M --> C
    O --> C
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-99-01 | 値のクランプ | fractionは0.0〜1.0にクランプ | fraction >= 0 |
| BR-99-02 | 不確定状態 | fraction < 0で不確定状態のアニメーション | fraction < 0 |
| BR-99-03 | NaN対応 | NaN値は0.0として扱う | fraction != fraction |
| BR-99-04 | 自動パーセント表示 | overlay未指定かつ確定状態で自動的にパーセント表示 | overlay == NULL && !is_indeterminate |

### 計算ロジック

- 確定状態の塗りつぶし範囲: `fill_n0 = 0.0f, fill_n1 = fraction`
- 不確定状態の塗りつぶし範囲:
  - `fill_width_n = 0.2f`（バー幅の20%）
  - `fill_n0 = ImFmod(-fraction, 1.0f) * (1.0f + fill_width_n) - fill_width_n`
  - `fill_n1 = fill_n0 + fill_width_n`
- パーセント表示: `"%.0f%%", fraction * 100 + 0.01f`

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

データベース操作なし（UI描画のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 早期リターン | window->SkipItems == true | 何もせずreturn |
| - | 早期リターン | ItemAdd失敗 | 何もせずreturn |
| - | NaN対応 | fraction == NaN | 0.0fとして扱う |

### リトライ仕様

リトライ不要（フレームごとに再評価）

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

トランザクション管理なし（即時処理）

## パフォーマンス要件

- 単一フレーム内で多数のProgressBarを描画可能
- 描画処理は軽量

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

- 特になし（読み取り専用表示ウィジェット）

## 備考

- 不確定状態のアニメーションは、fractionに`-ImGui::GetTime()`などの時間ベースの値を渡すことで実現
- オーバーレイテキストはバーの右端またはバー内に描画される
- 色はImGuiCol_PlotHistogramを使用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | 641行目: ProgressBar関数のAPI宣言を確認 |

**読解のコツ**: ProgressBarは戻り値がvoidであることに注意。表示専用のウィジェット。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui_widgets.cpp | `imgui_widgets.cpp` | 1401-1461行目: ProgressBar関数の実装 |

**主要処理フロー**:
1. **1403-1405行目**: ウィンドウ取得とスキップチェック
2. **1410-1411行目**: サイズ計算
3. **1413-1415行目**: ItemSize/ItemAdd
4. **1419-1421行目**: 不確定状態の判定とクランプ
5. **1424-1425行目**: NaN対応
6. **1427-1433行目**: 不確定状態のアニメーション計算
7. **1436行目**: RenderFrameで背景描画
8. **1438-1441行目**: 進捗バー描画
9. **1445-1459行目**: オーバーレイテキスト処理

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

```
ImGui::ProgressBar(fraction, size_arg, overlay)
    │
    ├─ GetCurrentWindow()
    │
    ├─ CalcItemSize()
    │      └─ サイズを計算
    │
    ├─ CalcItemWidth()
    │      └─ デフォルト幅を取得
    │
    ├─ ItemSize() / ItemAdd()
    │
    ├─ ImSaturate()
    │      └─ 値を0.0〜1.0にクランプ
    │
    ├─ ImFmod() [不確定状態時]
    │      └─ アニメーション用の位置計算
    │
    ├─ RenderFrame()
    │      └─ 背景フレームを描画
    │
    ├─ RenderRectFilledInRangeH()
    │      └─ 進捗バーを描画
    │
    ├─ ImFormatString() [オーバーレイ自動生成時]
    │      └─ パーセント文字列を生成
    │
    ├─ CalcTextSize()
    │      └─ オーバーレイテキストサイズ計算
    │
    └─ RenderTextClipped()
           └─ オーバーレイテキストを描画
```

### データフロー図

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

fraction (float) ───────────> 状態判定 ──────────────────────> 確定/不確定
                                │
                            [確定] ImSaturate
                            [不確定] アニメーション計算
                                │
size_arg ───────────────────> CalcItemSize ─────────────────> 最終サイズ
                                │
                            ItemSize/ItemAdd
                                │
                            RenderFrame ────────────────────> DrawList (背景)
                                │
                            RenderRectFilledInRangeH ───────> DrawList (バー)
                                │
overlay (文字列) ───────────> [指定時] そのまま使用
                            [未指定] パーセント生成
                                │
                            RenderTextClipped ──────────────> DrawList (テキスト)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | ProgressBar APIの宣言 |
| imgui_widgets.cpp | `imgui_widgets.cpp` | ソース | ProgressBarの実装 |
| imgui.cpp | `imgui.cpp` | ソース | RenderFrame、RenderRectFilledInRangeH等 |
