# 画面設計書 12-ヒストリードック

## 概要

本ドキュメントは、Godot Engineエディタにおけるヒストリードック（History Dock）の画面設計書である。ヒストリードックは、エディタ操作のUndo/Redo履歴を一覧表示し、任意の時点にジャンプできる機能を提供するドックパネルである。

### 本画面の処理概要

ヒストリードックは、EditorUndoRedoManagerが管理するUndo/Redoスタックの履歴を時系列順に表示し、任意の履歴項目をクリックすることでその時点の状態に戻る（または進む）機能を提供する。シーン固有の履歴とグローバル履歴を個別にフィルタリング表示できる。

**業務上の目的・背景**：ゲーム開発では、試行錯誤を繰り返しながらシーンやスクリプトを編集することが多い。Ctrl+Z/Ctrl+Yによる単純なUndo/Redoでは、複数手順前の状態に戻るのに何度も操作が必要となる。本画面は、履歴を視覚化し、任意の時点に直接ジャンプできることで、効率的な編集作業を支援する。

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

**主要な操作・処理内容**：
1. 履歴一覧の表示: Undo/Redo操作の履歴をタイムスタンプ順に表示
2. シーン履歴のフィルタ: 「Scene」チェックボックスで現在のシーン固有の履歴を表示/非表示
3. グローバル履歴のフィルタ: 「Global」チェックボックスでグローバル履歴を表示/非表示
4. 履歴へのジャンプ: 履歴項目をクリックしてその時点の状態に遷移
5. 現在位置の表示: 現在のバージョン位置をハイライト表示
6. レイアウト保存: フィルタ設定の永続化

**画面遷移**：本画面は独立したドックパネルとして動作し、他の画面との遷移はない。EditorUndoRedoManagerのシグナル（history_changed, version_changed）を監視して表示を更新する。

**権限による表示制御**：特になし。すべてのユーザーが全機能を利用可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | EditorUndoRedoManager | 主機能 | Undo/Redo履歴の管理・取得 |
| - | EditorNode | 連携機能 | シーン変更通知の受信 |
| - | ConfigFile | 補助機能 | レイアウト設定の保存・読み込み |

## 画面種別

一覧（ドックパネル）

## URL/ルーティング

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

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 必須 | 説明 |
|--------|----------|----------|------|------|
| シーン履歴フラグ | 入力 | bool | - | シーン履歴を表示するかどうか |
| グローバル履歴フラグ | 入力 | bool | - | グローバル履歴を表示するかどうか |
| 選択インデックス | 入力 | int | - | ジャンプ先の履歴インデックス |

## 表示項目

| 項目名 | データ型 | 表示形式 | 説明 |
|--------|----------|----------|------|
| アクション名 | String | リストアイテム | 各Undo/Redoアクションの名前 |
| 現在位置インジケータ | int | 選択状態 | 現在のバージョン位置 |
| グローバル履歴マーカー | Color | 前景色 | グローバル履歴はアクセントカラーで表示 |
| 開始点 | String | リストアイテム | 「The Beginning」（履歴の開始点） |

## イベント仕様

### 1-履歴変更イベント（on_history_changed）

EditorUndoRedoManagerでUndo/Redo操作が行われると、履歴一覧が更新される。

- **処理フロー**:
  1. `history_changed`シグナルを受信
  2. 表示中であれば`refresh_history()`を呼び出し
  3. 非表示であれば`need_refresh`フラグを設定

### 2-バージョン変更イベント（on_version_changed）

現在のバージョンが変更されると、選択位置が更新される。

- **処理フロー**:
  1. `version_changed`シグナルを受信
  2. 表示中であれば`refresh_version()`を呼び出し
  3. 非表示であれば`need_refresh`フラグを設定

### 3-履歴ジャンプ（seek_history）

履歴項目をクリックすると、その時点の状態にジャンプする。

- **処理フロー**:
  1. `item_selected`シグナルを受信
  2. 選択されたインデックスと現在位置を比較
  3. 現在位置 < 選択位置の場合: `undo()`を繰り返し実行
  4. 現在位置 > 選択位置の場合: `redo()`を繰り返し実行
  5. フィルタ設定に応じて、シーン履歴のみ/グローバル履歴のみ/両方を対象

### 4-シーンフィルタ切り替え（current_scene_checkbox toggled）

「Scene」チェックボックスをトグルすると、シーン履歴の表示を切り替える。

- **処理フロー**:
  1. `toggled`シグナルを受信
  2. `refresh_history()`を呼び出して履歴一覧を再構築

### 5-グローバルフィルタ切り替え（global_history_checkbox toggled）

「Global」チェックボックスをトグルすると、グローバル履歴の表示を切り替える。

- **処理フロー**:
  1. `toggled`シグナルを受信
  2. `refresh_history()`を呼び出して履歴一覧を再構築

### 6-シーン変更イベント（scene_changed）

編集中のシーンが変更されると、履歴一覧が更新される。

- **処理フロー**:
  1. EditorNodeの`scene_changed`シグナルを受信
  2. `on_history_changed()`を呼び出し

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

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

本画面はEditorUndoRedoManagerを介してUndo/Redo操作を行うが、直接的なデータ更新は行わない。

| 操作（イベント） | 対象 | 操作種別 | 概要 |
|----------------|------|---------|------|
| 履歴ジャンプ | シーン/プロジェクト | UNDO/REDO | 選択された履歴位置までUndo/Redoを連続実行 |

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

#### ConfigFile（エディタレイアウト）

| 操作 | 項目（セクション/キー） | 更新値・取得条件 | 備考 |
|-----|------------------------|-----------------|------|
| UPDATE | {section}/include_scene | bool値 | シーン履歴フィルタの状態 |
| UPDATE | {section}/include_global | bool値 | グローバル履歴フィルタの状態 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| - | 案内 | The Beginning | 履歴の開始点（最古の状態） |
| - | ラベル | Scene | シーン履歴フィルタのチェックボックス |
| - | ラベル | Global | グローバル履歴フィルタのチェックボックス |

## 例外処理

| 例外状態 | 処理内容 |
|---------|---------|
| 両フィルタOFF | 「The Beginning」のみ表示し、履歴ジャンプを無効化 |
| 履歴が空 | 「The Beginning」のみ表示 |
| 非表示時の更新 | `need_refresh`フラグを設定し、表示時に遅延更新 |

## 備考

- グローバル履歴はアクセントカラー（`accent_color`）で表示され、シーン履歴と視覚的に区別できる
- 履歴はタイムスタンプの降順（新しい順）でソートされる
- フィルタ設定はConfigFileに保存され、エディタ再起動後も維持される
- シーンを切り替えると履歴一覧が自動更新される

---

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

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

### 推奨読解順序

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

まず、Undo/Redo履歴のデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | history_dock.h | `editor/docks/history_dock.h` | HistoryDockクラスのメンバ変数（ur_manager, action_list, current_version等）を確認 |
| 1-2 | editor_undo_redo_manager.h | `editor/editor_undo_redo_manager.h` | EditorUndoRedoManager::Action構造体とHistoryクラスを確認 |

**読解のコツ**: `EditorUndoRedoManager::History`には`undo_stack`と`redo_stack`があり、`Action`構造体には`action_name`と`timestamp`が含まれる。`GLOBAL_HISTORY`定数はグローバル履歴を識別するために使用される。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | history_dock.cpp | `editor/docks/history_dock.cpp` | コンストラクタ（238-283行目）でUIの初期化とシグナル接続を確認 |

**主要処理フロー**:
1. **238-242行目**: ドック設定（名前、アイコン、ショートカット、デフォルトスロット）
2. **244-246行目**: EditorUndoRedoManagerのシグナル接続
3. **254-261行目**: シーン履歴チェックボックスの作成と設定
4. **263-270行目**: グローバル履歴チェックボックスの作成と設定
5. **277-282行目**: ItemListの作成とitem_selectedシグナル接続

#### Step 3: 履歴表示処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | history_dock.cpp | `editor/docks/history_dock.cpp` | `refresh_history()`（56-115行目）の履歴構築ロジック |

**主要処理フロー**:
- **57行目**: `action_list->clear()`でリストをクリア
- **61-65行目**: 両フィルタOFFの場合は「The Beginning」のみ表示
- **67-68行目**: シーン履歴とグローバル履歴を取得
- **70-102行目**: フィルタに応じてundo/redoスタックからアクションを収集
- **104行目**: タイムスタンプでソート（`sort_custom<SortActionsByTimestamp>()`）
- **105-110行目**: アクションをItemListに追加、グローバル履歴はアクセントカラーで表示
- **112-113行目**: 「The Beginning」を末尾に追加

#### Step 4: 履歴ジャンプ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | history_dock.cpp | `editor/docks/history_dock.cpp` | `seek_history()`（190-222行目）のジャンプロジック |

**主要処理フロー**:
- **199-209行目**: 現在位置 < 選択位置の場合、`undo()`を繰り返し
- **211-221行目**: 現在位置 > 選択位置の場合、`redo()`を繰り返し
- **200-208行目**: フィルタ設定に応じて`undo()`, `undo_history(scene_id)`, `undo_history(GLOBAL_HISTORY)`を選択

#### Step 5: バージョン管理処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | history_dock.cpp | `editor/docks/history_dock.cpp` | `refresh_version()`（125-177行目）の現在位置計算ロジック |

**主要処理フロー**:
- **138-149行目**: 最新のundoタイムスタンプを計算
- **151-173行目**: 各履歴スタックをスキャンして現在位置を特定
- **175-176行目**: `current_version`を更新し、リストの選択を設定

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

```
HistoryDock（エントリーポイント）
    │
    ├─ コンストラクタ
    │      ├─ UI初期化（CheckBox, ItemList）
    │      └─ シグナル接続
    │             ├─ history_changed → on_history_changed()
    │             ├─ version_changed → on_version_changed()
    │             ├─ scene_changed → on_history_changed()
    │             └─ item_selected → seek_history()
    │
    ├─ on_history_changed()
    │      └─ refresh_history()
    │             ├─ ur_manager->get_or_create_history()
    │             ├─ sort_custom<SortActionsByTimestamp>()
    │             └─ action_list->add_item()
    │
    ├─ on_version_changed()
    │      └─ refresh_version()
    │             └─ action_list->set_current()
    │
    └─ seek_history()
           ├─ ur_manager->undo() / undo_history()
           └─ ur_manager->redo() / redo_history()
```

### データフロー図

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

EditorUndoRedoManager
├─ history_changed ────▶ on_history_changed()
│                              │
│                              ▼
│                        refresh_history() ──────▶ ItemList表示
│                              │
│                              ▼
│                        undo_stack + redo_stack
│                              │
│                              ▼
│                        sort_custom<Timestamp>()
│
└─ version_changed ────▶ on_version_changed()
                               │
                               ▼
                         refresh_version() ──────▶ 選択位置更新

ユーザー操作
└─ item_selected ──────▶ seek_history() ─────────▶ undo()/redo()実行
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| history_dock.cpp | `editor/docks/history_dock.cpp` | ソース | ドックパネルの実装 |
| history_dock.h | `editor/docks/history_dock.h` | ヘッダ | ドックパネルのクラス定義 |
| editor_dock.h | `editor/docks/editor_dock.h` | ヘッダ | ドック基底クラス |
| editor_undo_redo_manager.h | `editor/editor_undo_redo_manager.h` | ヘッダ | Undo/Redo管理クラス |
| editor_undo_redo_manager.cpp | `editor/editor_undo_redo_manager.cpp` | ソース | Undo/Redo管理の実装 |
| editor_node.cpp | `editor/editor_node.cpp` | ソース | エディタメインクラス（scene_changedシグナル） |
| item_list.h | `scene/gui/item_list.h` | ヘッダ | リスト表示コントロール |
| check_box.h | `scene/gui/check_box.h` | ヘッダ | チェックボックスコントロール |
| config_file.h | `core/io/config_file.h` | ヘッダ | レイアウト設定保存 |
