# 画面設計書 11-グループドック

## 概要

本ドキュメントは、Godot Engineエディタにおけるグループドック（Groups Dock）の画面設計書である。グループドックは、シーン内のノードをグループに追加・削除し、グループを管理するためのドックパネルである。

### 本画面の処理概要

グループドックは、選択されたノードに対してグループの追加・削除・編集を行う機能を提供する。シーングループとグローバルグループの2種類のグループを管理でき、複数ノードの一括操作にも対応している。

**業務上の目的・背景**：Godot Engineでは、ノードをグループに所属させることで、シグナルのブロードキャストやノードの一括取得など、効率的なノード管理が可能となる。本画面は、エディタ上で視覚的かつ直感的にグループ管理を行うために必要であり、ゲーム開発における複雑なノード間の関係性を整理する業務課題を解決する。

**画面へのアクセス方法**：エディタメニューから「View > Docks > Groups」を選択、または、ショートカットキー（ED_SHORTCUTで定義された「docks/open_groups」）を使用してアクセスする。デフォルトでは右上のドックスロット（DOCK_SLOT_RIGHT_UL）に配置される。

**主要な操作・処理内容**：
1. グループツリーの表示: シーングループとグローバルグループを階層的に表示
2. グループへのノード追加: チェックボックスをオンにして選択ノードをグループに追加
3. グループからのノード削除: チェックボックスをオフにして選択ノードをグループから削除
4. 新規グループの作成: 「+」ボタンからダイアログを開き、新規グループを作成
5. グループの名前変更: 右クリックメニューからグループ名を変更
6. グループの削除: 右クリックメニューからグループを削除
7. グループの種別変換: シーングループとグローバルグループ間の変換
8. グループ名のコピー: クリップボードへグループ名をコピー
9. フィルタ検索: テキストフィルタによるグループの絞り込み

**画面遷移**：シーンツリードック（SceneTreeDock）からノードを選択すると、グループドックの表示が更新される。また、プロジェクト設定ダイアログのグループ設定と連携している。

**権限による表示制御**：継承シーンやインスタンス化されたシーンから継承されたグループは編集不可（ロックアイコン表示）となる。編集可能なグループのみチェックボックスが操作可能である。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | シーンツリードック | 遷移元機能 | ノード選択時にグループ表示を更新 |
| - | プロジェクト設定 | API連携 | グローバルグループの定義・管理 |
| - | EditorUndoRedoManager | 補助機能 | グループ操作のUndo/Redo管理 |

## 画面種別

一覧 / 編集（ドックパネル）

## URL/ルーティング

エディタ内部ドック（URLなし）

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 必須 | 説明 |
|--------|----------|----------|------|------|
| フィルタテキスト | 入力 | String | - | グループ名のフィルタリング条件 |
| グループ名 | 入力 | String | 必須 | 新規作成・名前変更時のグループ名 |
| グループ説明 | 入力 | String | - | グローバルグループの説明文 |
| グローバルフラグ | 入力 | bool | - | グローバルグループとして作成するかのフラグ |
| 選択ノード | 入力 | Vector<Node*> | - | 操作対象のノード群 |

## 表示項目

| 項目名 | データ型 | 表示形式 | 説明 |
|--------|----------|----------|------|
| シーングループ一覧 | TreeItem | チェックボックス付きリスト | シーン固有のグループ一覧 |
| グローバルグループ一覧 | TreeItem | チェックボックス付きリスト | プロジェクト全体のグループ一覧 |
| グループ名 | String | テキスト | 各グループの名前 |
| 所属状態 | bool | チェックボックス | 選択ノードのグループ所属状態 |
| ロックアイコン | Texture2D | アイコン | 編集不可グループの表示 |
| コピーボタン | Button | アイコンボタン | グループ名のクリップボードコピー |

## イベント仕様

### 1-グループチェック状態変更（_item_edited）

ユーザーがグループのチェックボックスをオン/オフすると、選択されたノードをグループに追加または削除する。

- **処理フロー**:
  1. TreeItemからグループ名を取得
  2. チェック状態に応じてUndoRedo操作を作成
  3. `_add_to_group`または`_remove_from_group`を実行
  4. シーンツリーを再描画

### 2-新規グループ追加（_show_add_group_dialog / _confirm_add）

「+」ボタンをクリックすると、新規グループ作成ダイアログが表示される。

- **処理フロー**:
  1. ConfirmationDialogを表示
  2. グループ名の入力とバリデーション
  3. グローバル/シーンの選択
  4. 確定時に`_confirm_add`でグループを作成
  5. ノードをグループに追加

### 3-グループ名変更（_show_rename_group_dialog / _confirm_rename）

右クリックメニューから「Rename」を選択すると、名前変更ダイアログが表示される。

- **処理フロー**:
  1. ConfirmationDialogを表示
  2. 新しいグループ名の入力とバリデーション
  3. グローバルグループの場合、全シーンの参照更新オプション表示
  4. 確定時に`_confirm_rename`でグループ名を変更

### 4-グループ削除（_show_remove_group_dialog / _confirm_delete）

右クリックメニューから「Delete」を選択すると、削除確認ダイアログが表示される。

- **処理フロー**:
  1. ConfirmationDialogを表示
  2. グローバルグループの場合、全シーンの参照削除オプション表示
  3. 確定時に`_confirm_delete`でグループを削除

### 5-グループ種別変換（_menu_id_pressed - CONVERT_GROUP）

右クリックメニューから「Convert to Global/Scene Group」を選択すると、グループの種別を変換する。

- **処理フロー**:
  1. シーングループの場合: ProjectSettingsにグローバルグループとして登録
  2. グローバルグループの場合: ProjectSettingsから削除し、シーングループに変換
  3. ツリー表示を更新

### 6-フィルタ入力（filter text_changed）

フィルタ入力欄にテキストを入力すると、グループ一覧がフィルタリングされる。

- **処理フロー**:
  1. `_update_tree`を呼び出し
  2. `filter->get_text().is_subsequence_ofn(E)`で部分一致判定
  3. 一致するグループのみ表示

### 7-グループ名コピー（_modify_group - COPY_GROUP）

グループ項目の「コピー」ボタンをクリックすると、グループ名がクリップボードにコピーされる。

- **処理フロー**:
  1. `DisplayServer::get_singleton()->clipboard_set(ti->get_text(p_column))`を実行

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

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

本画面はGodot EngineのNode/SceneTreeシステムとProjectSettingsを操作する。

| 操作（イベント） | 対象 | 操作種別 | 概要 |
|----------------|------|---------|------|
| グループ追加 | Node::groups | INSERT | ノードにグループを追加 |
| グループ削除 | Node::groups | DELETE | ノードからグループを削除 |
| グローバルグループ作成 | ProjectSettings | INSERT | project.godotにグローバルグループを追加 |
| グローバルグループ削除 | ProjectSettings | DELETE | project.godotからグローバルグループを削除 |
| グローバルグループ名変更 | ProjectSettings | UPDATE | project.godotのグローバルグループ名を変更 |

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

#### ProjectSettings (project.godot)

| 操作 | 項目（プロパティ名） | 更新値・取得条件 | 備考 |
|-----|---------------------|-----------------|------|
| INSERT | global_group/{グループ名} | 説明文（String） | グローバルグループの登録 |
| DELETE | global_group/{グループ名} | Variant() (null) | グローバルグループの削除 |
| UPDATE | global_group/{新グループ名} | 元の説明文 | 名前変更（旧削除＋新規追加） |

#### Node::groups（シーンファイル内）

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| INSERT | groups配列 | StringName（グループ名） | Node.add_to_group()で追加 |
| DELETE | groups配列 | StringName（グループ名） | Node.remove_from_group()で削除 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| - | 案内 | Select one or more nodes to edit their groups. | ノード未選択時 |
| - | バリデーション | Group can't be empty. | グループ名が空の場合 |
| - | バリデーション | Group already exists. | 同名グループが存在する場合 |
| - | バリデーション | Group name is valid. | バリデーション成功時 |
| - | ツールチップ | This group belongs to another scene and can't be edited. | 編集不可グループ |
| - | ツールチップ | Add a new group. | 追加ボタン |
| - | ツールチップ | Copy group name to clipboard. | コピーボタン |
| - | 確認 | Delete group "{グループ名}" and all its references? | グループ削除確認時 |

## 例外処理

| 例外状態 | 処理内容 |
|---------|---------|
| ノード未選択 | 「Select one or more nodes...」メッセージを表示し、グループツリーを非表示 |
| シーン未編集 | グループリストが空の状態で表示 |
| 継承グループの編集試行 | チェックボックスを無効化（編集不可） |
| バリデーションエラー | OKボタンを無効化し、エラーメッセージを表示 |

## 備考

- グループ操作はすべてEditorUndoRedoManagerを通じて行われ、Undo/Redoに対応している
- シーングループはシーンファイル内にのみ保存され、グローバルグループはproject.godotに保存される
- ショートカットキー: Delete（グループ削除）、F2/Enter（macOS）（グループ名変更）、Ctrl+F（検索フォーカス）

---

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

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

### 推奨読解順序

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

まず、グループ管理に関するデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | groups_editor.h | `editor/docks/groups_editor.h` | GroupsEditorクラスのメンバ変数（scene_groups, global_groups, selection等）の定義を確認 |
| 1-2 | node.h | `scene/main/node.h` | Node::GroupInfo構造体とグループ関連メソッドの宣言を確認 |

**読解のコツ**: `HashMap<StringName, bool> scene_groups`はシーングループとその編集可否を、`HashMap<StringName, String> global_groups`はグローバルグループと説明文を管理している。

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

処理の起点となるファイル・関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | groups_dock.cpp | `editor/docks/groups_dock.cpp` | GroupsDockの初期化とGroupsEditorの生成 |
| 2-2 | groups_dock.h | `editor/docks/groups_dock.h` | GroupsDockのクラス構造（EditorDockを継承） |

**主要処理フロー**:
1. **39-48行目（groups_dock.cpp）**: コンストラクタでGroupsEditorを生成し、ドック設定（名前、アイコン、ショートカット、デフォルトスロット）を行う
2. **35-37行目（groups_dock.cpp）**: `set_selection`メソッドでノード選択をGroupsEditorに委譲

#### Step 3: グループツリー表示処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | groups_editor.cpp | `editor/docks/groups_editor.cpp` | `_update_tree()`メソッド（209-305行目）のツリー構築ロジック |

**主要処理フロー**:
- **224-225行目**: tree->clear()でツリーをクリア
- **238-245行目**: シーングループのルート作成
- **253-270行目**: シーングループ項目の作成（チェックボックス、編集可否、ロックアイコン）
- **278-302行目**: グローバルグループ項目の作成

#### Step 4: グループ操作処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | groups_editor.cpp | `editor/docks/groups_editor.cpp` | `_item_edited()`（369-412行目）でチェック状態変更時の処理 |
| 4-2 | groups_editor.cpp | `editor/docks/groups_editor.cpp` | `_confirm_add()`（528-567行目）で新規グループ追加処理 |
| 4-3 | groups_editor.cpp | `editor/docks/groups_editor.cpp` | `_confirm_rename()`（569-618行目）でグループ名変更処理 |
| 4-4 | groups_editor.cpp | `editor/docks/groups_editor.cpp` | `_confirm_delete()`（620-658行目）でグループ削除処理 |

**主要処理フロー**:
- **377-411行目**: EditorUndoRedoManagerを使用したUndo/Redo対応のグループ追加/削除
- **96-112行目**: `_add_to_group` / `_remove_from_group`でノードのグループ操作を実行

#### Step 5: ダイアログ表示処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | groups_editor.cpp | `editor/docks/groups_editor.cpp` | `_show_add_group_dialog()`（660-726行目）で追加ダイアログのUI構築 |
| 5-2 | groups_editor.cpp | `editor/docks/groups_editor.cpp` | `_validate_name()`（833-839行目）でグループ名のバリデーション |

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

```
GroupsDock（エントリーポイント）
    │
    └─ GroupsEditor（主要処理）
           │
           ├─ set_selection()（ノード選択受付）
           │      └─ _update_tree()（ツリー表示更新）
           │
           ├─ _item_edited()（チェック状態変更）
           │      ├─ _get_group_mask()
           │      ├─ _add_to_group() / _remove_from_group()
           │      └─ EditorUndoRedoManager::commit_action()
           │
           ├─ _show_add_group_dialog()
           │      └─ _confirm_add()
           │             ├─ _add_scene_group() / ProjectSettings
           │             └─ _update_tree()
           │
           ├─ _show_rename_group_dialog()
           │      └─ _confirm_rename()
           │             ├─ _rename_scene_group() / ProjectSettings
           │             └─ _update_tree()
           │
           └─ _show_remove_group_dialog()
                  └─ _confirm_delete()
                         ├─ _remove_scene_group() / ProjectSettings
                         └─ _update_tree()
```

### データフロー図

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

ノード選択 ───────▶ set_selection() ───────▶ グループツリー表示
(SceneTreeDock)         │
                        ▼
                 _update_groups()
                        │
                        ▼
                 _update_tree()
                        │
                        ▼
              Tree（シーン/グローバル）

チェック操作 ──────▶ _item_edited() ───────▶ Node::groups更新
                        │                    SceneTree更新
                        ▼
              EditorUndoRedoManager

追加ダイアログ ───▶ _confirm_add() ────────▶ scene_groups更新
                        │                    ProjectSettings更新
                        ▼
              グローバルフラグ判定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| groups_dock.cpp | `editor/docks/groups_dock.cpp` | ソース | ドックパネルのエントリーポイント |
| groups_dock.h | `editor/docks/groups_dock.h` | ヘッダ | ドックパネルのクラス定義 |
| groups_editor.cpp | `editor/docks/groups_editor.cpp` | ソース | グループ編集機能の主要実装 |
| groups_editor.h | `editor/docks/groups_editor.h` | ヘッダ | グループ編集機能のクラス定義 |
| editor_dock.h | `editor/docks/editor_dock.h` | ヘッダ | ドック基底クラス |
| editor_undo_redo_manager.h | `editor/editor_undo_redo_manager.h` | ヘッダ | Undo/Redo管理 |
| project_settings_editor.cpp | `editor/settings/project_settings_editor.cpp` | ソース | グローバルグループ設定連携 |
| scene_tree_dock.cpp | `editor/docks/scene_tree_dock.cpp` | ソース | ノード選択連携 |
