# 通知設計書 40-NOTIFICATION_SCROLL_BEGIN

## 概要

本ドキュメントは、GodotエンジンのControlクラスにおけるNOTIFICATION_SCROLL_BEGIN通知の設計仕様を記載する。この通知はスクロール操作が開始された際に発火され、スクロール関連のアニメーション開始やUIフィードバックを可能にするイベントである。

### 本通知の処理概要

NOTIFICATION_SCROLL_BEGINは、スクロール操作（タッチスクロール、マウスホイール、スクロールバー操作など）が開始された際にScrollContainerなどのスクロール可能なコンテナから発行される通知である。

**業務上の目的・背景**：モバイルアプリやタッチインターフェースでは、スクロールの開始・終了を検出してスクロールバーの表示/非表示、慣性スクロールの管理、コンテンツのプリロードなどを行う必要がある。この通知により、スクロール開始時のUIフィードバックやアニメーション処理を実装できる。

**通知の送信タイミング**：ユーザーがスクロール操作を開始した際（タッチドラッグ、マウスホイール回転、スクロールバーのドラッグなど）に発火される。スクロール可能なコンテナが子コントロールに対して通知を発行する。

**通知の受信者**：ScrollContainerの子として配置されたControlノード。ItemList、Tree、TextEdit、RichTextLabelなどのスクロール可能なコンテンツを持つコントロールが主な受信者。

**通知内容の概要**：通知値は47（NOTIFICATION_SCROLL_BEGIN = 47）として定義され、スクロール操作が開始されたことを示す。

**期待されるアクション**：受信ノードはスクロール開始に応じた処理を行う。例えば、スクロールバーの表示、アニメーションの一時停止、コンテンツのロード準備などが典型的な処理となる。

## 通知種別

ゲームエンジン内部通知（Object._notificationで受信）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（スクロール開始時に発行） |
| 優先度 | 中（UIフィードバックに使用） |
| リトライ | なし（一度のみ発行） |

### 送信先決定ロジック

1. スクロール可能なコンテナ（ScrollContainerなど）がスクロール操作を検出
2. スクロール操作が実際に開始されること（スクロール位置が変化する）
3. コンテナ内の子コントロールに対して通知を発行
4. 上記条件を満たすControlノードに対してnotification()が呼び出される

## 通知テンプレート

### 内部通知の場合

| 項目 | 内容 |
|-----|------|
| 通知定数名 | NOTIFICATION_SCROLL_BEGIN |
| 通知値 | 47 |
| 逆順送信 | false（通常順） |
| 形式 | 整数値（int p_what） |

### 本文テンプレート

```cpp
// _notification()での受信例
void MyScrollableContent::_notification(int p_what) {
    switch (p_what) {
        case NOTIFICATION_SCROLL_BEGIN: {
            // スクロールが開始された
            is_scrolling = true;
            // スクロールバーを表示
            show_scrollbar_animation();
            // アニメーションを一時停止
            pause_animations();
        } break;
    }
}

// GDScriptでの例
func _notification(what):
    if what == NOTIFICATION_SCROLL_BEGIN:
        # スクロール開始時の処理
        is_scrolling = true
        $ScrollIndicator.visible = true
```

### 添付ファイル

該当なし（内部通知のため）

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| p_what | 通知種別 | notification()引数 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| タッチドラッグ | タッチスクリーンでのドラッグ操作 | スクロール位置が変化 | モバイル/タッチUI |
| マウスホイール | マウスホイール回転 | スクロール可能な状態 | デスクトップUI |
| スクロールバー | スクロールバーのドラッグ | スクロール位置が変化 | スクロールバー操作 |
| キーボード | Page Up/Down、矢印キー | フォーカス中でスクロール可能 | キーボード操作 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| スクロール不可 | コンテンツがスクロール不要なサイズの場合 |
| 既にスクロール中 | 継続中のスクロール操作（重複通知なし） |
| 非スクロールコンテナ | ScrollContainer以外の通常コンテナ |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[スクロール操作開始] --> B{スクロール可能?}
    B -->|No| C[処理終了]
    B -->|Yes| D{既にスクロール中?}
    D -->|Yes| C
    D -->|No| E[スクロール状態を開始に設定]
    E --> F[子コントロールにSCROLL_BEGIN通知]
    F --> G[派生クラス_notification処理]
    G --> H[スクロール処理継続]
    H --> I[スクロール終了時]
    I --> J[SCROLL_END通知発行]
    J --> C
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（ゲームエンジン内部処理のためデータベースは使用しない）

### テーブル別参照項目詳細

該当なし

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 不整合 | SCROLL_BEGINなしでSCROLL_END | 状態フラグの防御的チェック |
| 競合 | 複数入力ソースからの同時スクロール | 単一スクロール状態として管理 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（ユーザー操作に依存） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

エンジン実行中、スクロール操作開始時に発火。

## セキュリティ考慮事項

エンジン内部通知のため、外部からの直接的なセキュリティリスクはない。

## 備考

- NOTIFICATION_SCROLL_END（値48）とペアで使用される
- ScrollContainerが主な発行元
- 慣性スクロール（キネティックスクロール）の開始時にも発行される
- スクロール方向（水平/垂直）の情報は通知自体には含まれない

---

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

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

### 推奨読解順序

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

まず、Controlクラスの構造と通知定数の定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | control.h | `scene/gui/control.h` | NOTIFICATION_SCROLL_BEGIN = 47定義（433行目） |

**読解のコツ**: 値47はControl固有の通知定数。NOTIFICATION_SCROLL_END（48）とペア。

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

ScrollContainerからの通知発行メカニズムを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | scroll_container.cpp | `scene/gui/scroll_container.cpp` | スクロール開始時の通知発行 |
| 2-2 | scroll_container.cpp | `scene/gui/scroll_container.cpp` | _gui_input()でのスクロール検出 |

#### Step 3: 派生クラスでの処理例を理解する

具体的なUI要素でのスクロール処理パターンを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | item_list.cpp | `scene/gui/item_list.cpp` | NOTIFICATION_SCROLL_BEGIN処理 |
| 3-2 | tree.cpp | `scene/gui/tree.cpp` | NOTIFICATION_SCROLL_BEGIN処理 |
| 3-3 | text_edit.cpp | `scene/gui/text_edit.cpp` | NOTIFICATION_SCROLL_BEGIN処理 |

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

```
ScrollContainer::_gui_input() / タッチ/マウスイベント
    │
    └─ スクロール操作検出
           │
           ├─ スクロール状態を開始に設定
           │
           └─ 子Control::notification(SCROLL_BEGIN)
                  │
                  └─ 派生クラス::_notification()
                         │
                         └─ スクロール開始処理
                               (アニメーション等)
```

### データフロー図

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

タッチ/マウス ───▶ ScrollContainer ───▶ notification(47)
ホイール             │                      │
                     ├─ スクロール検出      └─▶ 子コントロール処理
                     │                           (スクロールバー表示等)
                     └─ 状態管理
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| control.h | `scene/gui/control.h` | ヘッダ | Controlクラス定義、NOTIFICATION定数 |
| control.cpp | `scene/gui/control.cpp` | ソース | _notification()基本実装 |
| scroll_container.h | `scene/gui/scroll_container.h` | ヘッダ | ScrollContainerクラス定義 |
| scroll_container.cpp | `scene/gui/scroll_container.cpp` | ソース | スクロール通知発行 |
| item_list.cpp | `scene/gui/item_list.cpp` | ソース | アイテムリストでの通知処理例 |
| tree.cpp | `scene/gui/tree.cpp` | ソース | ツリーでの通知処理例 |
| text_edit.cpp | `scene/gui/text_edit.cpp` | ソース | テキストエディタでの通知処理例 |
| rich_text_label.cpp | `scene/gui/rich_text_label.cpp` | ソース | リッチテキストでの通知処理例 |
| Control.xml | `doc/classes/Control.xml` | ドキュメント | 公式APIドキュメント |
