# 画面設計書: パス2Dエディタ

## 基本情報

| 項目 | 内容 |
|------|------|
| 画面ID | 50 |
| 画面名 | パス2Dエディタ |
| ファイルパス | `editor/scene/2d/path_2d_editor_plugin.h`, `editor/scene/2d/path_2d_editor_plugin.cpp` |
| 主要クラス | `Path2DEditor`, `Path2DEditorPlugin` |
| 基底クラス | `HBoxContainer`, `EditorPlugin` |

## 概要

パス2DエディタはPath2Dノードを編集するための専用エディタです。Curve2Dリソースのポイント作成・編集、コントロールポイント（In/Out）の操作、カーブの閉じ操作、セグメント分割などをサポートします。CanvasItemEditorのメニューパネルに統合され、ハンドルミラーリングオプションを提供します。

### 主な機能

1. **ポイント編集**: カーブポイントの選択、移動、削除
2. **コントロールポイント編集**: In/Outコントロールポイントの操作
3. **ポイント作成**: 新規ポイントの追加
4. **セグメント分割**: カーブ上のクリックでセグメントを分割
5. **カーブ閉じ**: カーブを閉じてループを作成
6. **ハンドルミラー**: 角度・長さのミラーリングオプション

## 画面構成

### レイアウト構造

```
+------------------------------------------------------------------+
| CanvasItemEditor Menu Panel                                       |
+------------------------------------------------------------------+
| Path2DEditor (HBoxContainer)                                      |
| +-----------------------------------------------------------+    |
| | toolbar                                                    |    |
| | +-------+-------+-------+-------+-------+-------+--------+ |    |
| | |Select |Curve  |Create |Delete |Close  |Clear  |Options | |    |
| | |[icon] |[icon] |[icon] |[icon] |[icon] |[icon] |[menu]  | |    |
| | +-------+-------+-------+-------+-------+-------+--------+ |    |
| +-----------------------------------------------------------+    |
| | create_curve_button                                        |    |
| | [Create Curve] (shown when no curve)                       |    |
| +-----------------------------------------------------------+    |
+------------------------------------------------------------------+
```

## 表示項目

### ツールバーボタン

| 項目 | 種類 | アイコン | 説明 | ソースコード参照 |
|------|------|----------|------|------------------|
| curve_edit | Button | CurveEdit | ポイント選択モード | L65, L46, L848-856 |
| curve_edit_curve | Button | CurveCurve | コントロールポイント編集モード | L66, L47, L858-865 |
| curve_create | Button | CurveCreate | ポイント作成モード | L63, L48, L867-874 |
| curve_del | Button | CurveDelete | ポイント削除モード | L64, L49, L876-882 |
| curve_close | Button | CurveClose | カーブを閉じる | L62, L50, L884-889 |
| curve_clear_points | Button | Clear | 全ポイントクリア | L61, L51, L891-896 |

### その他のUI要素

| 項目 | 種類 | 説明 | ソースコード参照 |
|------|------|------|------------------|
| handle_menu | MenuButton | ハンドルオプションメニュー | L67, L904-915 |
| create_curve_button | Button | Curve2D作成ボタン | L69, L919-923 |
| clear_points_dialog | ConfirmationDialog | ポイントクリア確認ダイアログ | L70, L898-902 |

## モード

| モード | 説明 | ソースコード参照 |
|--------|------|------------------|
| MODE_CREATE | ポイント作成モード | L51 |
| MODE_EDIT | ポイント編集モード（デフォルト） | L52 |
| MODE_EDIT_CURVE | コントロールポイント編集モード | L53 |
| MODE_DELETE | ポイント削除モード | L54 |
| MODE_CLOSE | カーブを閉じる（アクション） | L55 |
| MODE_CLEAR_POINTS | 全ポイントクリア（アクション） | L56 |

## アクション状態

| アクション | 説明 | ソースコード参照 |
|-----------|------|------------------|
| ACTION_NONE | アクションなし | L82 |
| ACTION_MOVING_POINT | ポイント移動中 | L83 |
| ACTION_MOVING_NEW_POINT | 新規ポイント移動中 | L84 |
| ACTION_MOVING_NEW_POINT_FROM_SPLIT | 分割ポイント移動中 | L85 |
| ACTION_MOVING_IN | Inコントロール移動中 | L86 |
| ACTION_MOVING_OUT | Outコントロール移動中 | L87 |

## ハンドルオプション

| オプション | デフォルト | 説明 | ソースコード参照 |
|-----------|-----------|------|------------------|
| HANDLE_OPTION_ANGLE | true | ハンドル角度のミラーリング | L77, L72, L911-912 |
| HANDLE_OPTION_LENGTH | true | ハンドル長さのミラーリング | L78, L73, L913-914 |

## イベント仕様

### マウス操作

| 操作 | モード | 処理 | ソースコード参照 |
|------|--------|------|------------------|
| 左クリック（ポイント） | MODE_EDIT | ポイント選択/ドラッグ開始 | L105-112 |
| 左クリック（In/Outコントロール） | MODE_EDIT/EDIT_CURVE | コントロールポイント選択 | L113-135 |
| 左クリック（空白） | MODE_CREATE | 新規ポイント追加 | L176-189 |
| 左クリック（カーブ上） | MODE_EDIT | セグメント分割 | L192-222 |
| Ctrl/Cmd+左クリック | MODE_EDIT | ポイント追加 | L176 |
| 右クリック（ポイント） | MODE_EDIT/CREATE | ポイント削除 | L140-148 |
| 右クリック（In/Outコントロール） | MODE_EDIT/CREATE | コントロール削除 | L149-165 |
| 左クリック（ポイント） | MODE_DELETE | ポイント削除 | L140 |
| 右クリック（アクション中） | - | アクションキャンセル | L170-173 |
| 左ボタン解放 | - | アクション確定/Undo登録 | L225-301 |
| マウス移動（ドラッグ中） | - | ポイント/コントロール移動 | L375-416 |
| マウス移動（MODE_EDIT） | - | エッジ検出（分割用） | L328-372 |

### キーボード修飾子

| 修飾子 | 処理 | ソースコード参照 |
|--------|------|------------------|
| Shift+ドラッグ | コントロールポイント選択 | L853 |
| Ctrl/Cmd+クリック | ポイント追加（MODE_EDIT時） | L176 |

## Undo/Redo アクション

| アクション名 | 処理内容 | ソースコード参照 |
|-------------|----------|------------------|
| "Remove Point from Curve" | ポイント削除 | L142 |
| "Remove Out-Control from Curve" | Outコントロール削除 | L150 |
| "Remove In-Control from Curve" | Inコントロール削除 | L158 |
| "Move Point in Curve" | ポイント移動 | L237 |
| "Add Point to Curve" | ポイント追加 | L246 |
| "Split Curve" | セグメント分割 | L256 |
| "Move In-Control in Curve" | Inコントロール移動 | L267 |
| "Move Out-Control in Curve" | Outコントロール移動 | L283 |
| "Close the Curve" | カーブを閉じる | L701 |
| "Clear Curve Points" | 全ポイントクリア | L718 |
| "Create Curve in Path2D" | Curve2D作成 | L791 |

## メッセージ仕様

### ツールチップ

| ボタン | ツールチップ | ソースコード参照 |
|--------|-------------|------------------|
| curve_edit | Select Points + 操作説明 | L853 |
| curve_edit_curve | Select Control Points (Shift+Drag) | L862 |
| curve_create | Add Point (in empty space) + Delete | L871 |
| curve_del | Delete Point | L880 |
| curve_close | Close Curve | L887 |
| curve_clear_points | Clear Points | L894 |

### ダイアログ

| ダイアログ | タイトル | テキスト | ソースコード参照 |
|-----------|---------|----------|------------------|
| clear_points_dialog | "Please Confirm..." | "Remove all curve points?" | L899-900 |

## 描画処理

### ビューポート描画 (forward_canvas_draw_over_viewport)

```
1. 可視性チェック
2. Transform計算
3. アイコン取得
   - EditorPathSharpHandle（シャープポイント用）
   - EditorPathSmoothHandle（スムースポイント用）
   - EditorCurveHandle（コントロールハンドル用）
4. ポイントごとに:
   - Outコントロールの線と点描画
   - Inコントロールの線と点描画
   - シャープ/スムースの判定とポイント描画
5. エッジ上なら EditorHandleAdd アイコン描画
6. マルチメッシュによるバッチ描画
   - debug_handle_curve_multimesh_rid（カーブハンドル）
   - debug_handle_sharp_multimesh_rid（シャープポイント）
   - debug_handle_smooth_multimesh_rid（スムースポイント）
```

### ポイントタイプ判定

| タイプ | 条件 | ソースコード参照 |
|--------|------|------------------|
| Smooth | In/Outコントロールのいずれかがポイントと異なる位置 | L458-480 |
| Sharp | In/Outコントロールが両方ともポイントと同じ位置 | L458-487 |

## RenderingServerリソース

| RID | 用途 | ソースコード参照 |
|-----|------|------------------|
| debug_mesh_rid | コントロールハンドル接続線 | L115, L496-506 |
| debug_handle_mesh_rid | ハンドル描画用メッシュ | L116, L931-965 |
| debug_handle_curve_multimesh_rid | カーブハンドルマルチメッシュ | L119, L516-545 |
| debug_handle_sharp_multimesh_rid | シャープハンドルマルチメッシュ | L120, L549-578 |
| debug_handle_smooth_multimesh_rid | スムースハンドルマルチメッシュ | L121, L582-611 |

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

### 推奨読解順序

1. **クラス定義** (path_2d_editor_plugin.h L41-139)
   - Mode enum、Action enum、HandleOption enum
   - メンバ変数宣言

2. **プラグインクラス** (path_2d_editor_plugin.h L141-157)
   - Path2DEditorPlugin定義
   - forward_canvas_gui_input、forward_canvas_draw_over_viewport

3. **コンストラクタ** (path_2d_editor_plugin.cpp L845-975)
   - ツールバーボタン作成
   - ハンドルメニュー作成
   - RenderingServerリソース作成

4. **入力処理** (path_2d_editor_plugin.cpp L65-420)
   - forward_gui_input()
   - マウスボタン処理
   - マウス移動処理

5. **描画処理** (path_2d_editor_plugin.cpp L422-612)
   - forward_canvas_draw_over_viewport()
   - マルチメッシュ設定

6. **モード選択** (path_2d_editor_plugin.cpp L665-727)
   - _mode_selected()
   - カーブ閉じ、ポイントクリア処理

7. **ハンドルオプション** (path_2d_editor_plugin.cpp L729-746)
   - _handle_option_pressed()

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

```
Path2DEditorPlugin::edit()
└── Path2DEditor::edit()
    ├── _cancel_current_action() [アクション中の場合]
    ├── node = cast_to<Path2D>()
    ├── _update_toolbar()
    └── node->connect(visibility_changed)

_mode_selected(MODE_EDIT)
├── curve_edit->set_pressed(true)
├── 他のボタンを非選択
└── mode = MODE_EDIT

_mode_selected(MODE_CLOSE)
├── 開始点と終了点が同じかチェック
├── undo_redo->create_action("Close the Curve")
├── curve->add_point(begin)
└── undo_redo->commit_action()

forward_gui_input() [左クリック]
├── [MODE_EDIT, ポイント上]
│   ├── action = ACTION_MOVING_POINT
│   └── moving_from = point_position
├── [MODE_EDIT/EDIT_CURVE, In/Out上]
│   ├── action = ACTION_MOVING_IN/OUT
│   └── moving_from = in/out
├── [MODE_CREATE または Ctrl+MODE_EDIT]
│   ├── curve->add_point()
│   └── action = ACTION_MOVING_NEW_POINT
├── [MODE_EDIT, カーブ上]
│   ├── curve->add_point() [挿入位置計算]
│   └── action = ACTION_MOVING_NEW_POINT_FROM_SPLIT
└── [右クリック, ポイント/コントロール上]
    └── undo_redo->create_action("Remove Point/Control")

forward_gui_input() [左ボタン解放]
├── [ACTION_MOVING_POINT]
│   └── undo_redo->create_action("Move Point in Curve")
├── [ACTION_MOVING_NEW_POINT]
│   └── undo_redo->create_action("Add Point to Curve")
├── [ACTION_MOVING_NEW_POINT_FROM_SPLIT]
│   └── undo_redo->create_action("Split Curve")
├── [ACTION_MOVING_IN]
│   ├── undo_redo->create_action("Move In-Control")
│   └── [mirror_handle_angle] -> Out側も更新
└── [ACTION_MOVING_OUT]
    ├── undo_redo->create_action("Move Out-Control")
    └── [mirror_handle_angle] -> In側も更新

forward_canvas_draw_over_viewport()
├── xform = canvas_transform * screen_transform
├── ポイントループ
│   ├── Outコントロール処理
│   │   ├── debug_handle_lines.push_back(line)
│   │   └── debug_handle_curve_transforms.push_back(transform)
│   ├── Inコントロール処理
│   │   ├── debug_handle_lines.push_back(line)
│   │   └── debug_handle_curve_transforms.push_back(transform)
│   └── smooth ? debug_handle_smooth_transforms : debug_handle_sharp_transforms
├── [on_edge] draw_texture(EditorHandleAdd)
├── rs->mesh_add_surface_from_arrays(debug_mesh_rid, lines)
└── rs->canvas_item_add_multimesh() × 3
```

### データフロー図

```
[Path2Dノード]
    |
    | (edit)
    v
[Path2DEditor]
    |
    +----> [node->get_curve()] ----> [Curve2D]
    |                                    |
    |                                    +---> point_position
    |                                    +---> point_in
    |                                    +---> point_out
    |
    +----> [action / action_point / moving_from]
    |           |
    |           | (forward_gui_input)
    |           v
    |      [ドラッグ処理]
    |           |
    |           v
    |      [curve->set_point_position/in/out]
    |
    +----> [Undo/Redo]
             |
             v
         [EditorUndoRedoManager]

[描画]
    |
    | (forward_canvas_draw_over_viewport)
    v
[debug_handle_*_transforms]
    |
    | (multimesh_set_buffer)
    v
[RenderingServer]
    |
    v
[ビューポート描画]
```

### 関連ファイル一覧

| ファイル | 役割 |
|----------|------|
| `editor/scene/2d/path_2d_editor_plugin.h` | エディタクラス定義 |
| `editor/scene/2d/path_2d_editor_plugin.cpp` | エディタ実装 |
| `scene/2d/path_2d.h` | Path2Dノード定義 |
| `scene/2d/path_2d.cpp` | Path2Dノード実装 |
| `scene/resources/curve.h` | Curve2Dリソース定義 |
| `scene/resources/curve.cpp` | Curve2Dリソース実装 |
| `editor/scene/canvas_item_editor_plugin.h` | CanvasItemEditor |
| `editor/editor_undo_redo_manager.h` | Undo/Redo管理 |
| `servers/rendering_server.h` | RenderingServer API |
