# 画面設計書 14-Menubar - View

## 概要

本ドキュメントは、three.js エディタにおける表示メニュー（Menubar - View）の画面設計書である。このメニューは、Viewport上に表示される各種ヘルパー（グリッド、カメラ、ライト、スケルトン）の表示/非表示を切り替える機能、およびフルスクリーン表示やXR（VR/AR）モードへの切り替え機能を提供する。

### 本画面の処理概要

**業務上の目的・背景**：3Dシーン編集において、ヘルパーオブジェクト（グリッド、カメラの視錐台、ライトの方向など）は作業中の視覚的なガイドとして重要だが、最終的なレンダリング結果を確認する際には非表示にしたい場合がある。このメニューは、ヘルパーの表示状態をトグル形式で素早く切り替えることを可能にし、作業効率と成果物プレビューの両立を実現する。

**画面へのアクセス方法**：エディタメイン画面（editor/index.html）のメニューバー領域に常時表示される。「View」メニュータイトルをクリックすると、ドロップダウン形式でオプションが展開される。

**主要な操作・処理内容**：
1. **Grid Helper**：グリッドの表示/非表示を切り替え（デフォルト: 表示）
2. **Camera Helpers**：カメラヘルパーの表示/非表示を切り替え（デフォルト: 表示）
3. **Light Helpers**：ライトヘルパーの表示/非表示を切り替え（デフォルト: 表示）
4. **Skeleton Helpers**：スケルトンヘルパーの表示/非表示を切り替え（デフォルト: 表示）
5. **Fullscreen**：ブラウザをフルスクリーンモードに切り替え
6. **AR/VR**：対応デバイスでWebXRセッションを開始（対応時のみ表示）

**画面遷移**：メニュー操作によりViewportの表示状態が変更される。Fullscreen/XRモードでは画面全体の表示状態が変化する。

**権限による表示制御**：AR/VR機能は `'xr' in navigator` のチェックおよび `isSessionSupported()` の結果により、対応ブラウザ・デバイスでのみ表示される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 154 | GridHelper | 主機能 | グリッド表示のオン/オフ切替 |
| 157 | CameraHelper | 補助機能 | カメラヘルパー表示切替 |
| 158 | DirectionalLightHelper | 補助機能 | ライトヘルパー表示切替 |

## 画面種別

メニュー（ドロップダウン）

## URL/ルーティング

エディタメイン画面の一部として `editor/index.html` に含まれる。独立したルーティングは持たない。

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 説明 |
|--------|----------|---------|------|
| states | 入出力 | Object | ヘルパー表示状態（gridHelper, cameraHelpers, lightHelpers, skeletonHelpers） |

## 表示項目

| 項目 | 表示内容 | 初期状態 | 条件 |
|------|---------|---------|------|
| Grid Helper | グリッド表示トグル | ON (toggle-on) | 常時表示 |
| Camera Helpers | カメラヘルパー表示トグル | ON (toggle-on) | 常時表示 |
| Light Helpers | ライトヘルパー表示トグル | ON (toggle-on) | 常時表示 |
| Skeleton Helpers | スケルトンヘルパー表示トグル | ON (toggle-on) | 常時表示 |
| 区切り線 | UIHorizontalRule | - | 常時表示 |
| Fullscreen | フルスクリーン切替 | - | 常時表示 |
| AR | AR モード開始 | - | immersive-ar対応時のみ |
| VR | VR モード開始 | - | immersive-vr対応時（AR非対応時） |

## イベント仕様

### 1-Grid Helper（グリッド表示切替）

- **トリガー**：Grid Helperメニュー項目クリック
- **処理内容**：
  1. `states.gridHelper` を反転
  2. メニュー項目の `toggle-on` クラスをトグル
  3. `signals.showHelpersChanged.dispatch(states)` でViewportに通知
- **画面更新**：Viewportのグリッドが表示/非表示になる

### 2-Camera Helpers（カメラヘルパー表示切替）

- **トリガー**：Camera Helpersメニュー項目クリック
- **処理内容**：
  1. `states.cameraHelpers` を反転
  2. メニュー項目の `toggle-on` クラスをトグル
  3. `signals.showHelpersChanged.dispatch(states)` でViewportに通知
- **画面更新**：Viewport上のカメラヘルパー（視錐台表示）が表示/非表示になる

### 3-Light Helpers（ライトヘルパー表示切替）

- **トリガー**：Light Helpersメニュー項目クリック
- **処理内容**：
  1. `states.lightHelpers` を反転
  2. メニュー項目の `toggle-on` クラスをトグル
  3. `signals.showHelpersChanged.dispatch(states)` でViewportに通知
- **画面更新**：Viewport上のライトヘルパー（方向表示など）が表示/非表示になる

### 4-Skeleton Helpers（スケルトンヘルパー表示切替）

- **トリガー**：Skeleton Helpersメニュー項目クリック
- **処理内容**：
  1. `states.skeletonHelpers` を反転
  2. メニュー項目の `toggle-on` クラスをトグル
  3. `signals.showHelpersChanged.dispatch(states)` でViewportに通知
- **画面更新**：Viewport上のスケルトンヘルパー（ボーン表示）が表示/非表示になる

### 5-Fullscreen（フルスクリーン切替）

- **トリガー**：Fullscreenメニュー項目クリック
- **処理内容**：
  1. `document.fullscreenElement === null` をチェック
  2. nullなら `document.documentElement.requestFullscreen()` でフルスクリーン開始
  3. nullでなければ `document.exitFullscreen()` でフルスクリーン解除
  4. Safari向けに `webkitFullscreenElement` / `webkitRequestFullscreen` / `webkitExitFullscreen` も対応
- **画面更新**：ブラウザがフルスクリーンモードになる/解除される

### 6-AR/VR（XRモード開始）

- **トリガー**：AR または VR メニュー項目クリック
- **処理内容**：
  1. `signals.enterXR.dispatch('immersive-ar')` または `signals.enterXR.dispatch('immersive-vr')` を発行
  2. ViewportでWebXRセッションが開始される
- **画面更新**：XRデバイスでの表示が開始される

### 7-helperAdded（ヘルパー追加時）

- **トリガー**：`signals.helperAdded` が発行された時
- **処理内容**：
  1. `signals.showHelpersChanged.dispatch(states)` で現在のヘルパー表示状態をViewportに通知
- **目的**：新しく追加されたヘルパーに対して、現在の表示設定を適用する

## データベース更新仕様

本画面はブラウザ上で動作する3Dエディタであり、データベースへの直接的な更新は行わない。ヘルパー表示状態はセッション中のみ保持される。

## メッセージ仕様

| メッセージ種別 | メッセージ内容 | 表示条件 |
|---------------|---------------|---------|
| なし | - | 本メニューでは特別なメッセージ表示はない |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| XR非対応ブラウザ | AR/VRメニュー項目が表示されない |
| Fullscreen API非対応 | 標準API/WebKit両方を試行 |

## 備考

- ヘルパー表示状態はコンポーネント内のローカル変数 `states` で管理される
- 初期状態ではすべてのヘルパーが表示（true）に設定されている
- `signals.helperAdded` イベントにより、新規追加されたヘルパーにも自動的に表示設定が適用される
- WebXRのofferSession APIにも対応している（`navigator.xr.offerSession`）

---

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

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

### 推奨読解順序

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

ヘルパー表示状態を管理するstatesオブジェクトの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Menubar.View.js | `editor/js/Menubar.View.js` | statesオブジェクトの初期化（22-29行目） |

**読解のコツ**: statesオブジェクトは4つのbooleanプロパティを持ち、それぞれがヘルパーカテゴリの表示状態を管理する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Menubar.View.js | `editor/js/Menubar.View.js` | メニュー構築とイベントハンドラ |

**主要処理フロー**:
1. **3-18行目**: UIPanel/UIRowを使用したメニュー構造の構築
2. **22-29行目**: states オブジェクトの初期化（すべてtrue）
3. **33-43行目**: Grid Helperトグルの実装
4. **47-57行目**: Camera Helpersトグルの実装
5. **61-71行目**: Light Helpersトグルの実装
6. **75-85行目**: Skeleton Helpersトグルの実装
7. **91-95行目**: helperAddedシグナルのハンドラ
8. **103-131行目**: Fullscreenの実装
9. **135-185行目**: WebXR (AR/VR)の実装

#### Step 3: Viewportとの連携を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Viewport.js | `editor/js/Viewport.js` | showHelpersChangedシグナルのハンドラ |

**主要処理フロー**:
- Viewportでは `signals.showHelpersChanged` を購読し、statesに基づいて各ヘルパーのvisibleプロパティを更新

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

```
MenubarView (Menubar.View.js)
    │
    ├─ gridHelper.onClick()
    │      ├─ states.gridHelper = !states.gridHelper
    │      ├─ this.toggleClass('toggle-on', states.gridHelper)
    │      └─ signals.showHelpersChanged.dispatch(states)
    │             └─ Viewport.js: ヘルパーのvisible更新
    │
    ├─ cameraHelpers.onClick() ... (同様)
    ├─ lightHelpers.onClick() ... (同様)
    ├─ skeletonHelpers.onClick() ... (同様)
    │
    ├─ fullscreen.onClick()
    │      ├─ document.fullscreenElement === null ?
    │      │      ├─ Yes: document.documentElement.requestFullscreen()
    │      │      └─ No: document.exitFullscreen()
    │      └─ (Safari: webkit prefix版も対応)
    │
    └─ ar/vr.onClick()
           └─ signals.enterXR.dispatch('immersive-ar' or 'immersive-vr')
                  └─ Viewport.js: WebXRセッション開始
```

### データフロー図

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

メニュークリック ───────▶ Menubar.View.js ──────────▶ signals.showHelpersChanged
                              │                              │
states (ローカル) ◀───────────┘                              ▼
                                                      Viewport.js
                                                      (ヘルパーvisible更新)
                                                              │
                                                              ▼
                                                      画面再描画
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Menubar.View.js | `editor/js/Menubar.View.js` | ソース | Viewメニューの主要実装 |
| Viewport.js | `editor/js/Viewport.js` | ソース | showHelpersChangedシグナル処理 |
| ui.js | `editor/js/libs/ui.js` | ソース | UIコンポーネント（UIPanel, UIRow, UIHorizontalRule等） |
| Editor.js | `editor/js/Editor.js` | ソース | signalsオブジェクトの管理 |
