# 画面設計書 35-シェーダー作成ダイアログ

## 概要

本ドキュメントは、Godot Engineエディタにおけるシェーダー作成ダイアログ（ShaderCreateDialog）の画面設計を記述する。このダイアログは新規シェーダーファイルの作成または既存シェーダーの読み込みに使用され、シェーダータイプ、モード、テンプレートの選択が可能である。

### 本画面の処理概要

このダイアログ画面では、シェーダーリソースの新規作成または既存ファイルの読み込みを行う。Godotがサポートする様々なシェーダー言語（ビジュアルシェーダー、標準シェーダーなど）に対応し、各言語に適したテンプレートを提供する。

**業務上の目的・背景**：ゲーム開発において、シェーダーは視覚表現の核となる重要な要素である。マテリアルの外観、ポストプロセスエフェクト、パーティクル表現など、多くの視覚効果にシェーダーが使用される。このダイアログは、適切なシェーダータイプとモード（Spatial/CanvasItem/Particles/Sky/Fog）の選択を支援し、テンプレートによる初期コードの提供でシェーダー開発の開始を容易にする。

**画面へのアクセス方法**：ファイルシステムドックで右クリック→「新規」→「シェーダー」を選択、またはマテリアルインスペクターからシェーダーを新規作成する際にアクセスする。

**主要な操作・処理内容**：
1. シェーダータイプの選択（Shader/VisualShader/ShaderInclude等）
2. シェーダーモードの選択（Spatial/Canvas Item/Particles/Sky/Fog）
3. テンプレートの選択（Default/Empty）
4. 組み込みシェーダーオプションの設定
5. 保存パスの指定またはファイル選択
6. シェーダーの作成または既存ファイルの読み込み

**画面遷移**：
- 遷移元：ファイルシステムドック、マテリアルインスペクター
- 遷移先（作成成功時）：シェーダーエディタで新規シェーダーが開く
- 遷移先（読み込み成功時）：シェーダーエディタで既存シェーダーが開く
- 遷移先（キャンセル時）：元の画面に戻る

**権限による表示制御**：built_in_enabledフラグにより組み込みシェーダーオプションの有効/無効が制御される。load_enabledフラグにより既存ファイル読み込み機能の有効/無効が制御される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| F-040 | シェーダー管理 | 主機能 | シェーダーの作成・読み込み |
| F-041 | シェーダーエディタ | 遷移先機能 | シェーダーコード編集 |
| F-042 | リソース保存 | 補助機能 | シェーダーファイルの保存 |
| F-043 | シェーダー言語プラグイン | 補助機能 | 言語バリエーションの提供 |

## 画面種別

登録（新規作成/読み込みダイアログ）

## URL/ルーティング

該当なし（デスクトップアプリケーションのモーダルダイアログ）

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 必須 | 説明 |
|--------|----------|---------|------|------|
| シェーダータイプ | 入力 | int | 必須 | type_menuの選択インデックス |
| シェーダーモード | 入力 | int | 必須 | Shader::Mode enum値 |
| テンプレート | 入力 | int | オプション | 0=Default, 1=Empty |
| 組み込みシェーダー | 入力 | bool | オプション | trueの場合シーンに埋め込み |
| ファイルパス | 入力 | String | 条件付き必須 | 組み込み以外で必須 |
| 基本パス | 入力（config） | String | オプション | 初期パス設定 |
| 優先タイプ | 入力（config） | String | オプション | デフォルト選択タイプ |
| 優先モード | 入力（config） | int | オプション | デフォルト選択モード |
| 作成シェーダー | 出力 | Shader | - | shader_createdシグナルで出力 |
| 作成ShaderInclude | 出力 | ShaderInclude | - | shader_include_createdシグナルで出力 |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| Type | ドロップダウン | シェーダータイプ選択（Shader/VisualShader/ShaderInclude等） |
| Mode | ドロップダウン | シェーダーモード選択（Spatial/Canvas Item/Particles/Sky/Fog） |
| Template | ドロップダウン | テンプレート選択（Default/Empty/N/A） |
| Built-in Shader | チェックボックス | シーンへの組み込みオプション |
| Path | テキスト入力 + ボタン | ファイルパス入力と参照ボタン |
| 検証パネル | ラベル群 | パス検証結果、シェーダー状態メッセージ |

## イベント仕様

### 1-シェーダータイプ選択

type_menuで項目を選択すると、_type_changed()が呼び出される。選択に応じて：
- ファイルパスの拡張子が自動更新される
- ShaderInclude選択時はmodeメニューが無効化される
- テンプレートメニューの内容が更新される（use_templatesフラグに基づく）
- 最後に選択した言語がEditorSettingsに保存される

### 2-モード選択

mode_menuで項目を選択すると、_mode_changed()が呼び出され、current_modeが更新される。設定はEditorSettingsのプロジェクトメタデータに保存される。

### 3-テンプレート選択

template_menuで項目を選択すると、_template_changed()が呼び出され、current_templateが更新される。設定はEditorSettingsに保存される。

### 4-組み込みシェーダートグル

internalチェックボックスをトグルすると、_built_in_toggled()が呼び出される。有効時：
- ファイルパス入力が無効化される
- パス参照ボタンが無効化される
- is_new_shader_createdがtrueに設定される

### 5-パス変更

file_pathにテキストを入力すると、_path_changed()が呼び出され、パス検証が行われる。検証項目：
- パスが空でないこと
- ファイル名が空でないこと
- パスがres://で始まること
- 基本パスが有効であること
- 同名のディレクトリが存在しないこと
- 拡張子が選択タイプに適合すること

### 6-パス参照ボタン押下

path_buttonをクリックすると、_browse_path()が呼び出され、EditorFileDialogがポップアップ表示される。

### 7-OKボタン押下（作成）

is_new_shader_createdがtrueの場合、_create_new()が呼び出される：
- EditorShaderLanguagePluginから新規シェーダーを作成
- ShaderIncludeの場合はshader_include_createdシグナルを発行
- 通常シェーダーの場合はshader_createdシグナルを発行
- 組み込みでない場合はResourceSaverでファイル保存

### 8-OKボタン押下（読み込み）

is_new_shader_createdがfalseの場合、_load_exist()が呼び出される：
- ResourceLoaderで既存シェーダーを読み込み
- shader_createdシグナルを発行

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| シェーダー作成 | ファイルシステム | CREATE | 新規シェーダーファイル作成 |
| 組み込みシェーダー作成 | シーンファイル | UPDATE | シーンに埋め込みリソースとして追加 |
| 既存シェーダー読み込み | なし | SELECT | 既存ファイルの読み取りのみ |

### テーブル別更新項目詳細

#### ファイルシステム（シェーダーファイル）

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| CREATE | ファイルパス | file_path->get_text() | ローカライズされたパス |
| CREATE | シェーダーコード | テンプレートに基づく初期コード | EditorShaderLanguagePluginから生成 |
| CREATE | シェーダーモード | current_mode | Spatial/CanvasItem等 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| MSG_ID_SHADER | 成功 | Shader path/name is valid. | パスと名前が有効な場合 |
| MSG_ID_SHADER | 情報 | File exists, it will be reused. | 既存ファイルを読み込む場合 |
| MSG_ID_SHADER | エラー | Invalid path. | パスが無効な場合 |
| MSG_ID_PATH | 成功 | Will create a new shader file. | 新規作成の場合 |
| MSG_ID_PATH | 成功 | Built-in shader (into scene file). | 組み込みシェーダーの場合 |
| MSG_ID_PATH | 成功 | Will load an existing shader file. | 既存ファイル読み込みの場合 |
| MSG_ID_PATH | エラー | Path is empty. | パスが空の場合 |
| MSG_ID_PATH | エラー | Filename is empty. | ファイル名が空の場合 |
| MSG_ID_PATH | エラー | Path is not local. | res://で始まらない場合 |
| MSG_ID_PATH | エラー | Invalid base path. | ディレクトリが存在しない場合 |
| MSG_ID_PATH | エラー | A directory with the same name exists. | 同名ディレクトリ存在時 |
| MSG_ID_PATH | エラー | Invalid extension for selected shader type. | 拡張子不一致の場合 |
| MSG_ID_PATH | エラー | Shader file already exists. | 既存ファイルかつload_enabled=falseの場合 |
| MSG_ID_BUILT_IN | 情報 | Note: Built-in shaders can't be edited using an external editor. | 組み込みシェーダー選択時 |
| - | エラー | Error - Could not create shader in filesystem. | ファイル保存失敗時（アラート） |
| - | エラー | Error - Could not create shader include in filesystem. | ShaderInclude保存失敗時（アラート） |
| - | エラー | Error loading shader from {path} | 読み込み失敗時（アラート） |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| シェーダー言語が読み込めない | ERR_FAIL_COND_MSGでエラーメッセージ |
| パス検証でcurrent_typeが範囲外 | ERR_FAIL_COND_Vでエラーメッセージ返却 |
| ResourceSaver::saveでエラー | アラートダイアログでエラーメッセージ表示 |
| ResourceLoader::loadでnull返却 | アラートダイアログでエラーメッセージ表示 |

## 備考

- ダイアログのタイトルは「Create Shader」
- OKボタンのテキストは状態に応じて「Create」または「Load」に変化
- タイプメニューの最小サイズは250 * EDSCALEピクセル
- 最後に選択した言語、モード、テンプレート、組み込み設定がEditorSettingsに保存され、次回起動時に復元される
- ShaderInclude選択時はModeメニューが無効化される（モード指定不要のため）
- 組み込みシェーダーの場合、パスはシーンファイルパス + ユニークID形式で自動生成される
- 対応拡張子：.gdshader, .tres, .res（シェーダータイプにより異なる）

---

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

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

### 推奨読解順序

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

ダイアログの構成要素とシェーダータイプデータを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | shader_create_dialog.h | `editor/shader/shader_create_dialog.h` | ShaderTypeData構造体（53-57行目）、クラスメンバ変数（61-82行目） |

**読解のコツ**: ShaderTypeDataは各シェーダー言語の拡張子とテンプレート使用可否を保持。MSG_ID_*は検証パネルのメッセージ識別子。

#### Step 2: 初期化とUI構築を理解する

コンストラクタでのUI構築とconfig()での初期設定を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | shader_create_dialog.cpp | `editor/shader/shader_create_dialog.cpp` | コンストラクタ（476-581行目）、config()（320-381行目） |

**主要処理フロー**:
1. **476-502行目（コンストラクタ）**: GridContainerと検証パネルの初期化
2. **506-514行目**: タイプメニュー構築
3. **518-526行目**: モードメニュー構築
4. **530-534行目**: テンプレートメニュー構築
5. **538-543行目**: 組み込みシェーダーチェックボックス
6. **547-561行目**: パス入力UI構築
7. **320-381行目（config）**: 言語情報更新、優先設定適用、前回設定復元

#### Step 3: タイプ選択処理を理解する

シェーダータイプ選択時の処理フローを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | shader_create_dialog.cpp | `editor/shader/shader_create_dialog.cpp` | _type_changed()（196-248行目）、_update_language_info()（72-89行目） |

**主要処理フロー**:
- **196-217行目**: ファイルパス拡張子の自動更新
- **219-231行目**: ShaderInclude選択時のMode/Type無効化制御
- **231-244行目**: テンプレートメニュー内容更新
- **72-89行目**: 言語バリエーションごとのShaderTypeData構築

#### Step 4: シェーダー作成処理を理解する

_create_new()と_load_exist()の処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | shader_create_dialog.cpp | `editor/shader/shader_create_dialog.cpp` | _create_new()（132-181行目）、_load_exist()（183-194行目） |

**主要処理フロー**:
- **132-144行目（_create_new）**: EditorShaderLanguagePluginからシェーダー/ShaderInclude作成
- **146-157行目**: ShaderInclude保存とシグナル発行
- **158-177行目**: 通常シェーダー保存（組み込み/ファイル）とシグナル発行
- **183-194行目（_load_exist）**: ResourceLoaderで既存シェーダー読み込み

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

```
ShaderCreateDialog (ConfirmationDialog)
    │
    ├─ config()                          [初期化]
    │      ├─ _update_language_info()
    │      ├─ type_menu->add_item()
    │      ├─ _refresh_type_icons()
    │      ├─ _type_changed()
    │      └─ _path_changed()
    │
    ├─ _type_changed()                   [タイプ選択]
    │      ├─ _path_changed()
    │      ├─ template_menu更新
    │      └─ validation_panel->update()
    │
    ├─ _path_changed()                   [パス検証]
    │      ├─ _validate_path()
    │      ├─ DirAccess::file_exists()
    │      └─ validation_panel->update()
    │
    ├─ ok_pressed()                      [確定]
    │      ├─ _create_new()              [新規作成]
    │      │      ├─ EditorShaderLanguagePlugin::create_new_shader()
    │      │      ├─ ResourceSaver::save()
    │      │      └─ emit_signal("shader_created")
    │      │
    │      └─ _load_exist()              [読み込み]
    │             ├─ ResourceLoader::load()
    │             └─ emit_signal("shader_created")
    │
    └─ _browse_path()                    [パス参照]
           └─ file_browse->popup_file_dialog()
```

### データフロー図

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

タイプ選択 ─────────────▶ _type_changed() ─────────────▶ 拡張子更新
                              │                          テンプレート更新
                              └─ EditorShaderLanguagePlugin

モード選択 ─────────────▶ _mode_changed() ─────────────▶ current_mode設定
                              │
                              └─ EditorSettings保存

パス入力 ───────────────▶ _path_changed() ─────────────▶ 検証結果表示
                              │
                              └─ _validate_path()
                                     │
                                     ├─ 空チェック
                                     ├─ res://チェック
                                     ├─ ディレクトリ存在チェック
                                     └─ 拡張子チェック

OKボタン ───────────────▶ ok_pressed() ─────────────────▶ シグナル発行
                              │
                    ┌─────────┴─────────┐
                    ▼                   ▼
            _create_new()        _load_exist()
                    │                   │
                    ▼                   ▼
          "shader_created"     "shader_created"
         シグナル発行          シグナル発行
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| shader_create_dialog.cpp | `editor/shader/shader_create_dialog.cpp` | ソース | ダイアログの実装 |
| shader_create_dialog.h | `editor/shader/shader_create_dialog.h` | ヘッダ | クラス定義とShaderTypeData構造体 |
| editor_shader_language_plugin.h | `editor/shader/editor_shader_language_plugin.h` | ヘッダ | シェーダー言語プラグインAPI |
| editor_validation_panel.h | `editor/gui/editor_validation_panel.h` | ヘッダ | 入力検証パネル |
| editor_file_dialog.h | `editor/gui/editor_file_dialog.h` | ヘッダ | ファイル選択ダイアログ |
| shader_types.h | `servers/rendering/shader_types.h` | ヘッダ | シェーダーモード定義 |
| shader_include.h | `scene/resources/shader_include.h` | ヘッダ | ShaderIncludeリソース |
| editor_settings.h | `editor/settings/editor_settings.h` | ヘッダ | 設定保存/復元 |
