# 機能設計書 57-メニュー

## 概要

本ドキュメントは、VS Codeのメニュー機能に関する設計書である。メインメニューバー、コンテキストメニュー、コマンドセンターなど、アプリケーション全体のメニュー構造を管理・表示する機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：
VS Codeの多数の機能へのアクセス手段として、階層的なメニュー構造が必要である。ネイティブメニューとカスタムメニューの両方をサポートし、プラットフォームに応じた最適なユーザー体験を提供する。キーボードショートカットの表示やメニューアイテムの有効/無効制御も行う。

**機能の利用シーン**：
- ファイル操作（開く、保存、閉じる等）
- 編集操作（コピー、ペースト、検索等）
- 表示設定（サイドバー、パネル、ズーム等）
- 実行・デバッグ操作
- 拡張機能からのメニュー項目追加

**主要な処理内容**：
1. メニューバーの構築・表示（File, Edit, View等）
2. サブメニューの管理
3. キーバインディングの表示
4. メニューアイテムの有効/無効/チェック状態管理
5. 最近使ったファイル/フォルダの表示
6. プラットフォーム別メニュースタイルの適用

**関連システム・外部連携**：
- Electron: ネイティブメニューAPI
- キーバインディングサービス: ショートカット表示
- コマンドサービス: メニューアクション実行

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | タイトルバー | 主機能 | メインメニュー、コマンドセンターの表示 |

## 機能種別

UI表示 / メニュー管理 / コマンド連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| windowId | number | Yes | 対象ウィンドウID | 正の整数 |
| menuData | IMenubarData | Yes | メニューデータ | menus、keybindings必須 |

### 入力データソース

- メニューレジストリ
- キーバインディングサービス
- 最近使ったファイル履歴

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| menu | IMenubarMenu | 構築されたメニュー構造 |
| keybinding | IMenubarKeybinding | キーバインディング情報 |

### 出力先

- ネイティブメニューバー（Electron）
- カスタムメニューバー（HTML/CSS）

## 処理フロー

### 処理シーケンス

```
1. メニューデータ収集
   └─ メニューレジストリからアイテムを取得
2. キーバインディング解決
   └─ 各メニューアイテムのショートカットを取得
3. 有効/無効状態の決定
   └─ コンテキストキーに基づいて判定
4. メニュー構造の構築
   └─ 階層的なメニューデータを作成
5. プラットフォーム別処理
   └─ ネイティブまたはカスタムメニューを更新
```

### フローチャート

```mermaid
flowchart TD
    A[メニュー更新要求] --> B[メニューレジストリ取得]
    B --> C[キーバインディング解決]
    C --> D[コンテキストキー評価]
    D --> E[有効/無効状態決定]
    E --> F{メニュースタイル}
    F -->|Native| G[Electronメニュー更新]
    F -->|Custom| H[HTMLメニュー更新]
    G --> I[完了]
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-57-01 | セパレーター識別 | id='vscode.menubar.separator'で識別 | 常時 |
| BR-57-02 | サブメニュー判定 | submenuプロパティの有無で判定 | 常時 |
| BR-57-03 | 最近使ったアイテム | uriプロパティでRecent判定 | 常時 |
| BR-57-04 | デフォルト有効 | enabled未指定時はtrue | 常時 |
| BR-57-05 | デフォルト未チェック | checked未指定時はfalse | 常時 |

### 計算ロジック

```typescript
// メニューアイテム種別判定
function isMenubarMenuItemSubmenu(menuItem: MenubarMenuItem): menuItem is IMenubarMenuItemSubmenu {
  return menuItem.submenu !== undefined;
}

function isMenubarMenuItemSeparator(menuItem: MenubarMenuItem): menuItem is IMenubarMenuItemSeparator {
  return menuItem.id === 'vscode.menubar.separator';
}

function isMenubarMenuItemRecentAction(menuItem: MenubarMenuItem): menuItem is IMenubarMenuRecentItemAction {
  return menuItem.uri !== undefined;
}

function isMenubarMenuItemAction(menuItem: MenubarMenuItem): menuItem is IMenubarMenuItemAction {
  return !isMenubarMenuItemSubmenu(menuItem)
      && !isMenubarMenuItemSeparator(menuItem)
      && !isMenubarMenuItemRecentAction(menuItem);
}
```

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

### 操作別データベース影響一覧

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | メニュー更新失敗 | IPC通信エラー | ログ出力、再試行 |

### リトライ仕様

メニュー更新は次回の更新トリガーで自動的に再試行される。

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

該当なし

## パフォーマンス要件

- メニュー表示は即座に行う
- メニュー構築はバックグラウンドで実行

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

- 拡張機能からのメニュー登録は検証される

## 備考

- macOSではアプリケーションメニューが常にネイティブ
- カスタムメニューはHTMLベースで高いカスタマイズ性

---

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

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

### 推奨読解順序

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

メニュー関連の型定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | menubar.ts | `src/vs/platform/menubar/common/menubar.ts` | IMenubarData、IMenubarMenu、MenubarMenuItem |

**読解のコツ**:
- MenubarMenuItemは4種類のUnion型（Action, Submenu, Separator, RecentAction）
- isMenubarMenuItemXxx関数で型ガードを行う

**主要処理フロー**:
1. **8-9行目**: ICommonMenubarService - サービスインターフェース
2. **12-15行目**: IMenubarData - メニュー全体のデータ構造
3. **17-19行目**: IMenubarMenu - 単一メニューの構造
4. **21-25行目**: IMenubarKeybinding - キーバインディング情報
5. **27-32行目**: IMenubarMenuItemAction - 通常アクション
6. **34-40行目**: IMenubarMenuRecentItemAction - 最近使った項目
7. **42-46行目**: IMenubarMenuItemSubmenu - サブメニュー
8. **48-50行目**: IMenubarMenuItemSeparator - セパレーター
9. **52行目**: MenubarMenuItem - Union型
10. **54-68行目**: 型ガード関数群

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

```
ICommonMenubarService
    │
    └─ updateMenubar(windowId, menuData)
           │
           ├─ IMenubarData
           │      ├─ menus: { [id: string]: IMenubarMenu }
           │      └─ keybindings: { [id: string]: IMenubarKeybinding }
           │
           └─ IMenubarMenu
                  │
                  └─ items: MenubarMenuItem[]
                         │
                         ├─ IMenubarMenuItemAction
                         │      ├─ id
                         │      ├─ label
                         │      ├─ checked
                         │      └─ enabled
                         │
                         ├─ IMenubarMenuItemSubmenu
                         │      ├─ id
                         │      ├─ label
                         │      └─ submenu: IMenubarMenu
                         │
                         ├─ IMenubarMenuItemSeparator
                         │      └─ id: 'vscode.menubar.separator'
                         │
                         └─ IMenubarMenuRecentItemAction
                                ├─ id
                                ├─ label
                                ├─ uri
                                └─ remoteAuthority
```

### データフロー図

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

メニューレジストリ
    │
    ↓
┌───────────────┐
│アイテム収集   │
└───────────────┘
    │
    ↓
┌───────────────┐
│キーバインディング│
│    解決       │
└───────────────┘
    │
    ↓
┌───────────────┐
│有効/無効判定  │
│(コンテキスト) │
└───────────────┘
    │
    ↓
┌───────────────┐
│IMenubarData   │
│  構築        │
└───────────────┘
    │
    ├──────────────────┐
    ↓                  ↓
┌──────────┐    ┌──────────┐
│Native    │    │Custom    │
│Menu (Mac)│    │Menu(HTML)│
└──────────┘    └──────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| menubar.ts | `src/vs/platform/menubar/common/menubar.ts` | ソース | 共通型定義 |
| menubar.ts | `src/vs/platform/menubar/electron-browser/menubar.ts` | ソース | ブラウザ側実装 |
| menubar.ts | `src/vs/platform/menubar/electron-main/menubar.ts` | ソース | メインプロセス実装 |
| menubarMainService.ts | `src/vs/platform/menubar/electron-main/menubarMainService.ts` | ソース | サービス実装 |
