# 機能設計書 95-ArrowButton

## 概要

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

### 本機能の処理概要

ArrowButtonは、矢印アイコンを含む正方形のボタンを作成するためのUI機能である。4方向（上、下、左、右）の矢印を表示でき、スクロール操作、ナビゲーション、ドロップダウンの開閉などのインタラクションに使用される。

**業務上の目的・背景**：GUIアプリケーションにおいて、方向性を示すボタンは頻繁に必要とされる。例えば、数値の増減ボタン、リストの並べ替えボタン、スクロール操作ボタン、メニューの展開/折りたたみボタンなどである。ArrowButtonは、これらの用途に対応する標準化されたコンポーネントを提供し、一貫したUIデザインを実現する。

**機能の利用シーン**：数値入力欄の上下ボタン、ツリービューの展開/折りたたみ、カルーセルの左右ナビゲーション、ソート順序の切り替え、メニューのサブメニュー表示などで使用される。

**主要な処理内容**：
1. ボタンのサイズを計算する（正方形、GetFrameHeight()ベース）
2. バウンディングボックスを確定し、領域を確保する
3. ButtonBehaviorでクリック・ホバー・ホールド状態を判定する
4. 状態に応じた色でフレームを描画する
5. 指定された方向の矢印アイコンを描画する
6. 押下状態（pressed）を戻り値として返す

**関連システム・外部連携**：ImGuiのDrawList描画システム、RenderArrow関数と連携。CollapseButtonなど内部ウィジェットでも類似のパターンが使用される。

**権限による制御**：BeginDisabled/EndDisabledで無効化可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | ArrowButtonは画面機能マッピングに直接関連付けられていないが、ウィジェットデモや内部ウィジェットで使用される |

## 機能種別

UIウィジェット / ユーザー入力処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| str_id | const char* | Yes | ボタンの識別子文字列 | NULL終端文字列 |
| dir | ImGuiDir | Yes | 矢印の方向（Left, Right, Up, Down） | ImGuiDir_Left/Right/Up/Down |

### 入力データソース

- 呼び出し元からの直接指定
- ImGuiStyleからのスタイル設定値（FrameRounding、色設定等）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| pressed | bool | ボタンが押されたかどうか |

### 出力先

- 戻り値として呼び出し元に返却
- ImDrawList（現在のウィンドウの描画リスト）

## 処理フロー

### 処理シーケンス

```
1. ArrowButtonExの呼び出し
   └─ ArrowButton関数はArrowButtonExを呼び出す

2. サイズ計算
   └─ sz = GetFrameHeight()で正方形サイズを取得
   └─ size = ImVec2(sz, sz)

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

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

5. インタラクション判定
   └─ ButtonBehavior()でhovered/held/pressed状態を取得

6. 描画
   └─ 状態に応じた背景色を取得
   └─ RenderNavCursor()でナビゲーションカーソルを描画
   └─ RenderFrame()でボタン背景を描画
   └─ RenderArrow()で矢印アイコンを描画

7. 結果返却
   └─ pressed状態を返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始: ArrowButton] --> B[ArrowButtonEx呼び出し]
    B --> C[サイズ計算<br/>GetFrameHeight]
    C --> D{SkipItems?}
    D -->|Yes| E[return false]
    D -->|No| F[ItemSize/ItemAdd]
    F --> G{ItemAdd成功?}
    G -->|No| E
    G -->|Yes| H[ButtonBehavior]
    H --> I[背景色決定]
    I --> J[RenderNavCursor]
    J --> K[RenderFrame]
    K --> L[RenderArrow]
    L --> M[return pressed]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-95-01 | 正方形サイズ | サイズはGetFrameHeight()を使用した正方形 | 常時 |
| BR-95-02 | 矢印中央配置 | 矢印はボタンの中央に配置される | 常時 |
| BR-95-03 | 方向指定 | 4方向（Left, Right, Up, Down）のいずれかを指定 | 常時 |

### 計算ロジック

- ボタンサイズ: `sz = GetFrameHeight(); ImVec2(sz, sz)`
- 矢印位置: `bb.Min + ImVec2(ImMax(0.0f, (size.x - g.FontSize) * 0.5f), ImMax(0.0f, (size.y - g.FontSize) * 0.5f))`

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 早期リターン | window->SkipItems == true | falseを返す |
| - | 早期リターン | ItemAdd失敗 | falseを返す |

### リトライ仕様

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

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

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

## パフォーマンス要件

- 単一フレーム内で多数のArrowButtonを描画可能
- 矢印の描画はRenderArrow関数で効率的に行われる

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

- str_idは表示されないがID生成に使用される

## 備考

- ArrowButtonは内部でArrowButtonExを呼び出す
- ArrowButtonExはサイズとフラグを直接指定可能（内部API）
- CollapsingHeaderやInputIntなどの内部でも矢印描画が使用される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | 635行目: ArrowButton関数のAPI宣言を確認 |
| 1-2 | imgui.h | `imgui.h` | ImGuiDir列挙型（Left, Right, Up, Down）の定義 |

**読解のコツ**: ArrowButtonは方向を指定する必要があるため、ImGuiDir列挙型の値を理解することが重要。

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

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

**主要処理フロー**:
1. **887行目**: GetFrameHeight()で正方形サイズを取得
2. **888行目**: ArrowButtonExを呼び出し

#### Step 3: 内部実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_widgets.cpp | `imgui_widgets.cpp` | 857-883行目: ArrowButtonEx関数の実装 |

**主要処理フロー**:
- **860-862行目**: ウィンドウ取得とスキップチェック
- **864-868行目**: ID生成とItemSize/ItemAdd
- **871-872行目**: ButtonBehavior呼び出し
- **875-878行目**: 色取得とRenderNavCursor
- **878行目**: RenderFrame呼び出し
- **879行目**: RenderArrow呼び出し（中央に矢印を描画）

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

```
ImGui::ArrowButton(str_id, dir)
    │
    └─ ArrowButtonEx(str_id, dir, ImVec2(sz, sz), ImGuiButtonFlags_None)
           │
           ├─ GetCurrentWindow()
           │
           ├─ window->GetID(str_id)
           │
           ├─ ItemSize() / ItemAdd()
           │
           ├─ ButtonBehavior()
           │
           ├─ GetColorU32()
           │      └─ ButtonActive / ButtonHovered / Button
           │
           ├─ RenderNavCursor()
           │
           ├─ RenderFrame()
           │      └─ ボタン背景を描画
           │
           └─ RenderArrow()
                  └─ 矢印アイコンを描画
```

### データフロー図

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

str_id (文字列) ────────────> GetID ─────────────────────────> ImGuiID
                                │
dir (方向) ─────────────────────────────────────────────────> 矢印描画パラメータ
                                │
GetFrameHeight() ───────────> サイズ計算 ───────────────────> 正方形サイズ
                                │
                            ItemSize/ItemAdd
                                │
マウス/キーボード状態 ─────> ButtonBehavior ─────────────────> hovered, held, pressed
                                │
                            RenderFrame ────────────────────> DrawList (背景)
                            RenderArrow ────────────────────> DrawList (矢印)
                                │
                            return pressed ─────────────────> bool (戻り値)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | ArrowButton APIの宣言、ImGuiDir定義 |
| imgui_internal.h | `imgui_internal.h` | ヘッダー | ArrowButtonEx内部API宣言 |
| imgui_widgets.cpp | `imgui_widgets.cpp` | ソース | ArrowButton/ArrowButtonExの実装 |
| imgui_draw.cpp | `imgui_draw.cpp` | ソース | RenderArrow関数の実装 |
