# 機能設計書 150-BeginMenuBar

## 概要

本ドキュメントは、Dear ImGuiライブラリにおけるBeginMenuBar関数の機能設計を記述する。BeginMenuBarはウィンドウのメニューバー領域を開始する関数である。

### 本機能の処理概要

BeginMenuBar関数は、ImGuiWindowFlags_MenuBarフラグを持つウィンドウ内でメニューバー領域の描画と操作を開始する。メニューバーは水平レイアウトで、BeginMenu/MenuItemを使用してメニュー項目を追加できる。

**業務上の目的・背景**：デスクトップアプリケーションでは、ファイル、編集、ヘルプなどのメニューバーが標準的なUIパターンである。BeginMenuBarは、ウィンドウ上部のメニュー領域を管理し、メニュー項目のナビゲーションとキーボード操作を提供する。

**機能の利用シーン**：
- ウィンドウ固有のメニューバー作成
- ドキュメント編集ウィンドウのメニュー
- ツールウィンドウのオプションメニュー
- サブウィンドウのコンテキストメニュー

**主要な処理内容**：
1. メニューバーフラグの確認（ImGuiWindowFlags_MenuBar必須）
2. グループの開始（位置のバックアップ）
3. クリップ矩形の設定
4. カーソル位置の設定（メニューバー領域）
5. 水平レイアウトモードの設定
6. メニューナビゲーションレイヤーの設定

**関連システム・外部連携**：
- EndMenuBarとペアで使用
- BeginMenu、MenuItemと組み合わせて使用
- ウィンドウのImGuiWindowFlags_MenuBarフラグが必要

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Demo Window | 主機能 | メニューバーの開始 |
| 12 | Simple Layout | 主機能 | メニューバーの開始 |
| 21 | Documents | 補助機能 | メニューバーの開始 |

## 機能種別

スコープ開始 / メニューレイアウト / ナビゲーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| （なし） | - | - | パラメータなし | - |

### 入力データソース

- グローバルコンテキスト（GImGui）からの現在のウィンドウ
- ウィンドウのImGuiWindowFlags_MenuBarフラグ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | bool | メニューバーが有効な場合true、EndMenuBarを呼び出す必要がある |

### 出力先

- 内部状態の設定（レイアウト、ナビゲーション）
- クリップ矩形の設定

## 処理フロー

### 処理シーケンス

```
1. ウィンドウスキップ確認
   └─ window->SkipItemsがtrueならfalse返却

2. メニューバーフラグ確認
   └─ ImGuiWindowFlags_MenuBarがなければfalse返却

3. グループの開始
   └─ BeginGroupで位置をバックアップ

4. IDのプッシュ
   └─ PushID("##MenuBar")

5. クリップ矩形の計算と設定
   └─ メニューバー領域のクリップ矩形を計算
   └─ 丸み処理を考慮
   └─ PushClipRectでクリップ設定

6. カーソル位置の設定
   └─ MenuBarRectからカーソル位置を設定
   └─ MenuBarOffsetを適用

7. レイアウトモードの設定
   └─ LayoutType = Horizontal
   └─ IsSameLine = false

8. ナビゲーションレイヤーの設定
   └─ NavLayerCurrent = ImGuiNavLayer_Menu

9. メニューバーアペンドフラグの設定
   └─ MenuBarAppending = true

10. テキスト整列
    └─ AlignTextToFramePadding
```

### フローチャート

```mermaid
flowchart TD
    A[BeginMenuBar開始] --> B{SkipItems?}
    B -->|Yes| C[return false]
    B -->|No| D{MenuBarフラグ?}
    D -->|No| C
    D -->|Yes| E[BeginGroup]
    E --> F[PushID ##MenuBar]
    F --> G[クリップ矩形計算]
    G --> H[PushClipRect]
    H --> I[カーソル位置設定]
    I --> J[LayoutType = Horizontal]
    J --> K[NavLayerCurrent = Menu]
    K --> L[MenuBarAppending = true]
    L --> M[AlignTextToFramePadding]
    M --> N[return true]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-150-01 | フラグ必須 | ImGuiWindowFlags_MenuBarがウィンドウに必要 | 常時 |
| BR-150-02 | ペア呼び出し | trueを返した場合のみEndMenuBarを呼び出す | 常時 |
| BR-150-03 | 水平レイアウト | メニューバー内は水平レイアウト | スコープ内 |
| BR-150-04 | メニューナビゲーション | キーボード/ゲームパッドでメニュー間移動可能 | スコープ内 |

### 計算ロジック

クリップ矩形計算:
```cpp
const float border_top = ImMax(window->WindowBorderSize * 0.5f - window->TitleBarHeight, 0.0f);
ImRect bar_rect = window->MenuBarRect();
ImRect clip_rect(
    IM_ROUND(bar_rect.Min.x + window->WindowBorderSize * 0.5f),
    IM_ROUND(bar_rect.Min.y + border_top),
    IM_ROUND(ImMax(bar_rect.Min.x, bar_rect.Max.x - ImMax(window->WindowRounding, window->WindowBorderSize * 0.5f))),
    IM_ROUND(bar_rect.Max.y)
);
clip_rect.ClipWith(window->OuterRectClipped);
```

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

該当なし（ImGuiはインメモリUIライブラリ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 警告（アサーション） | EndMenuBarをペアなしで呼び出し | BeginMenuBar/EndMenuBarのペアリングを確認 |
| - | アサーション | MenuBarAppendingがfalseでEndMenuBar呼び出し | BeginMenuBar成功後のみEndMenuBarを呼び出す |

### リトライ仕様

該当なし

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

BeginMenuBarとEndMenuBarで囲まれたスコープ内でメニュー項目を追加する。

## パフォーマンス要件

- 軽量な操作（主にレイアウト設定）
- クリップ矩形の計算と設定のみ

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

特になし。

## 備考

- フルスクリーンメニューバーはBeginMainMenuBarを使用
- メニューバー領域はウィンドウのMenuBarRect()で取得可能
- 子メニューのナビゲーションはEndMenuBarで処理される

---

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

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

### 推奨読解順序

#### Step 1: API宣言を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | BeginMenuBar関数宣言（809行目）とコメントを確認 |
| 1-2 | imgui.h | `imgui.h` | ImGuiWindowFlags_MenuBarフラグ定義を確認 |

**読解のコツ**: BeginMenuBarはImGuiWindowFlags_MenuBarを持つウィンドウでのみ有効。

#### Step 2: 実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui_widgets.cpp | `imgui_widgets.cpp` | BeginMenuBar実装（8998-9026行目） |

**主要処理フロー**:
1. **9001-9004行目**: ウィンドウスキップとMenuBarフラグ確認
2. **9006-9008行目**: BeginGroupとPushID
3. **9010-9016行目**: クリップ矩形の計算と設定
4. **9018-9019行目**: カーソル位置とCursorMaxPosの設定
5. **9020-9023行目**: レイアウトとナビゲーション設定
6. **9024行目**: AlignTextToFramePadding

#### Step 3: EndMenuBarを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_widgets.cpp | `imgui_widgets.cpp` | EndMenuBar実装（9028行目〜） |

**主要処理フロー**:
- **9036-9037行目**: アサーション（MenuBarフラグ、MenuBarAppending確認）
- **9039-9059行目**: ナビゲーション処理（子メニューからの戻り）
- クリップ矩形のポップ、ID/グループのポップ

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

```
BeginMenuBar()
    │
    ├─ GetCurrentWindow()
    │
    ├─ [check] window->SkipItems
    │
    ├─ [check] window->Flags & ImGuiWindowFlags_MenuBar
    │
    ├─ BeginGroup()
    │
    ├─ PushID("##MenuBar")
    │
    ├─ window->MenuBarRect() → bar_rect
    │
    ├─ clip_rect計算
    │
    ├─ PushClipRect(clip_rect.Min, clip_rect.Max, false)
    │
    ├─ window->DC.CursorPos/CursorMaxPos設定
    │
    ├─ window->DC.LayoutType = Horizontal
    │
    ├─ window->DC.NavLayerCurrent = ImGuiNavLayer_Menu
    │
    ├─ window->DC.MenuBarAppending = true
    │
    └─ AlignTextToFramePadding()
```

### データフロー図

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

（なし）                           │
                                  │
window->Flags ────────────────────┼──▶ BeginMenuBar() ──────────▶ bool (success)
                                  │           │
window->MenuBarRect() ────────────┤           ├──▶ クリップ矩形設定
                                  │           │
window->WindowBorderSize ─────────┤           ├──▶ カーソル位置設定
                                  │           │
window->WindowRounding ───────────┘           ├──▶ LayoutType = Horizontal
                                              │
                                              └──▶ NavLayerCurrent = Menu
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | 公開API宣言 |
| imgui_widgets.cpp | `imgui_widgets.cpp` | ソース | BeginMenuBar/EndMenuBar実装 |
| imgui_internal.h | `imgui_internal.h` | ヘッダー | ImGuiNavLayer_Menu等の内部定義 |
