# 機能設計書 113-SliderFloat2/3/4

## 概要

本ドキュメントは、Dear ImGuiライブラリにおける複数要素の浮動小数点スライダー機能「SliderFloat2」「SliderFloat3」「SliderFloat4」の設計を詳細に記述したものである。

### 本機能の処理概要

SliderFloat2/3/4は、2〜4個の浮動小数点数（float型）を1行にまとめて表示・編集できるスライダーウィジェット群である。各コンポーネントは独立したスライダーとして動作し、ベクトル（2D/3D/4D）やカラー値の編集に適している。

**業務上の目的・背景**：ゲーム開発やグラフィックスプログラミングにおいて、位置（x,y,z）、回転（pitch,yaw,roll）、スケール（x,y,z）、色（r,g,b,a）など、複数の浮動小数点数をまとめて管理する場面は非常に多い。SliderFloat2/3/4はこれらの値を効率的に編集するための統合インターフェースを提供し、個別にSliderFloatを呼び出すよりもコードが簡潔になり、視覚的にもまとまりのある表示ができる。

**機能の利用シーン**：
- 2Dベクトル（位置、速度、サイズなど）の編集（SliderFloat2）
- 3Dベクトル（位置、回転、スケール、RGBカラーなど）の編集（SliderFloat3）
- 4Dベクトル（クォータニオン、RGBAカラー、矩形など）の編集（SliderFloat4）
- 複数の関連パラメータを一括で調整したいとき

**主要な処理内容**：
1. SliderScalarNを呼び出し（components数を2/3/4で指定）
2. SliderScalarN内部でグループ化開始
3. 各コンポーネントに対してSliderScalarを繰り返し呼び出し
4. コンポーネント間のレイアウト調整（SameLineで水平配置）
5. グループ化終了とラベル表示

**関連システム・外部連携**：本機能は単体で動作し、外部システムとの直接的な連携はない。内部的にSliderScalarNを呼び出し、SliderScalarNはさらにSliderScalarを複数回呼び出す。

**権限による制御**：ImGuiItemFlags_ReadOnlyフラグまたはImGuiSliderFlags_ReadOnlyフラグにより読み取り専用モードを設定可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 23 | Widgets | 主機能 | スライダーウィジェットのデモ表示 |

## 機能種別

インタラクティブウィジェット / ユーザー入力処理

## 入力仕様

### 入力パラメータ（SliderFloat2の場合）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| label | const char* | Yes | ウィジェットのラベル（ID生成にも使用） | NULL不可 |
| v | float[2] | Yes | 編集対象の2要素配列 | NULL不可 |
| v_min | float | Yes | スライダーの最小値 | 任意 |
| v_max | float | Yes | スライダーの最大値 | 任意 |
| format | const char* | No | 表示フォーマット文字列（デフォルト: "%.3f"） | printf形式 |
| flags | ImGuiSliderFlags | No | 動作制御フラグ（デフォルト: 0） | 有効なフラグの組み合わせ |

### 入力パラメータ（SliderFloat3の場合）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| label | const char* | Yes | ウィジェットのラベル | NULL不可 |
| v | float[3] | Yes | 編集対象の3要素配列 | NULL不可 |
| v_min | float | Yes | スライダーの最小値 | 任意 |
| v_max | float | Yes | スライダーの最大値 | 任意 |
| format | const char* | No | 表示フォーマット文字列 | printf形式 |
| flags | ImGuiSliderFlags | No | 動作制御フラグ | 有効なフラグの組み合わせ |

### 入力パラメータ（SliderFloat4の場合）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| label | const char* | Yes | ウィジェットのラベル | NULL不可 |
| v | float[4] | Yes | 編集対象の4要素配列 | NULL不可 |
| v_min | float | Yes | スライダーの最小値 | 任意 |
| v_max | float | Yes | スライダーの最大値 | 任意 |
| format | const char* | No | 表示フォーマット文字列 | printf形式 |
| flags | ImGuiSliderFlags | No | 動作制御フラグ | 有効なフラグの組み合わせ |

### 入力データソース

ユーザーからのマウス操作（クリック・ドラッグ）およびキーボード入力。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | bool | いずれかの値が変更された場合true |
| v[0..n] | float | 更新されたスライダー値（配列の各要素） |

### 出力先

呼び出し元への戻り値、およびvが指す配列への値の書き込み。

## 処理フロー

### 処理シーケンス

```
1. SliderScalarNを呼び出し
   └─ components = 2/3/4, data_type = ImGuiDataType_Float
2. SliderScalarN内部処理
   ├─ ウィンドウ取得とスキップ判定
   ├─ BeginGroup()でグループ化開始
   ├─ PushID(label)でIDスコープ作成
   ├─ PushMultiItemsWidths()で各コンポーネントの幅を計算
   ├─ for (i = 0; i < components; i++)
   │     ├─ PushID(i)
   │     ├─ SameLine()（2番目以降）
   │     ├─ ColorMarkersフラグ時: SetNextItemColorMarker()
   │     ├─ SliderScalar("", ...)
   │     ├─ PopID()
   │     └─ PopItemWidth()
   ├─ PopID()
   ├─ ラベル表示
   └─ EndGroup()
3. 結果を返却（いずれかの値が変更されたか）
```

### フローチャート

```mermaid
flowchart TD
    A[SliderFloat2/3/4呼び出し] --> B[SliderScalarN呼び出し]
    B --> C{window->SkipItems?}
    C -->|Yes| D[return false]
    C -->|No| E[BeginGroup]
    E --> F[PushID/PushMultiItemsWidths]
    F --> G[ループ開始 i=0]
    G --> H[PushID i]
    H --> I{i > 0?}
    I -->|Yes| J[SameLine]
    I -->|No| K[SliderScalar]
    J --> K
    K --> L[PopID/PopItemWidth]
    L --> M{i < components?}
    M -->|Yes| N[i++]
    N --> G
    M -->|No| O[PopID]
    O --> P[ラベル表示]
    P --> Q[EndGroup]
    Q --> R[return value_changed]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-113-1 | 統一範囲 | 全コンポーネントに同じv_min/v_maxが適用される | 常時 |
| BR-113-2 | 独立変更 | 各コンポーネントは独立して変更可能 | 常時 |
| BR-113-3 | 幅分割 | 利用可能幅は均等にコンポーネント数で分割される | 常時 |
| BR-113-4 | 戻り値統合 | いずれかのコンポーネントが変更されればtrueを返す | 常時 |
| BR-113-5 | カラーマーカー | ColorMarkersフラグ設定時、R/G/B/Aのカラーマーカーを表示 | ColorMarkersフラグ設定時 |

### 計算ロジック

コンポーネント幅の計算：

```
total_width = CalcItemWidth()
item_inner_spacing = style.ItemInnerSpacing.x
component_width = (total_width - item_inner_spacing * (components - 1)) / components
```

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | アサーション | 無効なImGuiSliderFlagsが渡された場合 | 正しいフラグ値を使用する |

### リトライ仕様

本機能はユーザー入力ウィジェットであり、リトライは適用されない。

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

本機能はトランザクション処理を行わない。

## パフォーマンス要件

フレームごとに呼び出されるため、軽量な処理が求められる。SliderScalarNはグループ化とループ処理のオーバーヘッドがあるが、実用上問題ない程度。

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

- format文字列の検証は呼び出し側の責任
- 配列の境界チェックは呼び出し側の責任

## 備考

- SliderFloat2/3/4は内部でSliderScalarNを呼び出すシンプルなラッパー
- 各コンポーネントに異なる範囲を設定したい場合は、個別にSliderFloatを呼び出す必要がある
- ColorMarkersフラグは1.92以降で利用可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | SliderFloat2/3/4関数宣言（697-699行目） |

**読解のコツ**: 配列パラメータv[2]/v[3]/v[4]の宣言に注目。これは単にfloat*へのエイリアスではなく、明示的に要素数を示している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui_widgets.cpp | `imgui_widgets.cpp` | SliderFloat2関数（3428-3431行目） |
| 2-2 | imgui_widgets.cpp | `imgui_widgets.cpp` | SliderFloat3関数（3433-3436行目） |
| 2-3 | imgui_widgets.cpp | `imgui_widgets.cpp` | SliderFloat4関数（3438-3441行目） |

**主要処理フロー**:
- 各関数は単にSliderScalarNを呼び出すワンライナー
- components引数が2/3/4と異なるのみ

#### Step 3: 実際の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_widgets.cpp | `imgui_widgets.cpp` | SliderScalarN関数（3385-3421行目） |

**主要処理フロー**:
- **3388-3390行目**: ウィンドウ取得とスキップ判定
- **3394行目**: BeginGroup()でグループ化開始
- **3395行目**: PushID(label)でIDスコープ作成
- **3396行目**: PushMultiItemsWidths()で幅計算
- **3398-3409行目**: コンポーネントループ
  - **3400行目**: PushID(i)
  - **3401-3402行目**: SameLine（2番目以降）
  - **3403-3404行目**: ColorMarkersフラグ時の処理
  - **3405行目**: SliderScalar呼び出し
- **3412-3417行目**: ラベル表示処理
- **3419行目**: EndGroup()

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

```
SliderFloat2/3/4 (imgui_widgets.cpp:3428-3441)
    │
    └─ SliderScalarN (imgui_widgets.cpp:3385)
           │
           ├─ BeginGroup()
           ├─ PushID(label)
           ├─ PushMultiItemsWidths(components, ...)
           │
           ├─ [ループ: i = 0 to components-1]
           │     ├─ PushID(i)
           │     ├─ SameLine() [i > 0の場合]
           │     ├─ SetNextItemColorMarker() [ColorMarkersフラグ時]
           │     └─ SliderScalar("", data_type, v, ...)
           │            └─ SliderBehavior(...)
           │
           ├─ PopID()
           ├─ TextEx(label)
           └─ EndGroup()
```

### データフロー図

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

v[0..n] (配列へのポインタ)
v_min, v_max
       │
       ▼
       ├─────────▶ SliderScalarN ─────────────────────────────▶ 各要素の更新
       │               │
       │               ├─▶ SliderScalar(v[0]) ──▶ v[0]更新
       │               ├─▶ SliderScalar(v[1]) ──▶ v[1]更新
       │               ├─▶ SliderScalar(v[2]) ──▶ v[2]更新 (Float3/4)
       │               └─▶ SliderScalar(v[3]) ──▶ v[3]更新 (Float4)
       │
       ▼
format ────────────────────▶ 各コンポーネントの値表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | SliderFloat2/3/4関数宣言 |
| imgui_internal.h | `imgui_internal.h` | ヘッダー | 内部関数宣言、GDefaultRgbaColorMarkers |
| imgui_widgets.cpp | `imgui_widgets.cpp` | ソース | SliderFloat2/3/4/SliderScalarNの実装 |
