# 機能設計書 121-スクラッチパッドペイン

## 概要

本ドキュメントは、Windows Terminalにおけるスクラッチパッドペイン機能の設計を記述する。スクラッチパッドペインは、ターミナルペインとは独立した自由入力可能なテキストエリアをペインとして提供する機能である。

### 本機能の処理概要

スクラッチパッドペインは、ターミナルセッションとは無関係に自由にテキストを書き込めるペインを作成する機能である。通常のターミナルペインがシェルプロセスと接続されるのに対し、スクラッチパッドペインは純粋なテキスト入力エリアとして動作する。

**業務上の目的・背景**：開発者がターミナル作業中にメモやコマンドの下書き、一時的なテキスト記録を行う需要に応えるための機能である。また、Windows Terminalの「非ターミナルペイン」アーキテクチャの検証・実証を目的としており、IPaneContentインターフェースを実装するターミナル以外のコンテンツの実現可能性を示す役割も持つ。

**機能の利用シーン**：DevビルドおよびCanaryビルドにおいて、開発者が作業中にメモを取りたい場合や、コマンドを事前に組み立ててから実行したい場合に利用される。Feature_ScratchpadPaneフラグにより制御されるため、一般リリース版では無効化されている。

**主要な処理内容**：
1. ScratchpadContentインスタンスの生成（Grid + TextBoxの構築）
2. テーマに応じた背景色の適用（UnfocusedBorderBrush）
3. ペイン分割による既存タブへの組み込み
4. TextBoxへのフォーカス制御
5. コンテキストメニュー（TextMenuFlyout）の提供

**関連システム・外部連携**：外部システムとの連携はない。Windows Terminal内部のIPaneContentインターフェースを通じてペイン管理システムと統合される。

**権限による制御**：Feature_ScratchpadPaneフィーチャーフラグにより、DevビルドおよびCanaryビルドでのみ有効化される。一般リリース版（Release/Preview）では常に無効化されている。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleOpenScratchpadアクションハンドラからペイン分割で表示 |

## 機能種別

UI表示 / テキスト入力

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | アクション呼び出し時にパラメータは不要 | - |

### 入力データソース

ユーザーによるアクション実行（OpenScratchpadアクション）。テキスト入力はユーザーのキーボード入力から直接取得される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ペインUI | FrameworkElement | Grid内にTextBoxを配置したUIツリー |
| Title | hstring | 固定値 "Scratchpad" |
| Icon | hstring | QuickNoteアイコン（\ue70b） |
| GetNewTerminalArgs | INewContentArgs | BaseContentArgs("scratchpad") |

### 出力先

TerminalPageのペインツリーに新しいペインとして追加される。

## 処理フロー

### 処理シーケンス

```
1. ユーザーがOpenScratchpadアクションを実行
   └─ TerminalPage::_HandleOpenScratchpadが呼び出される
2. Feature_ScratchpadPane::IsEnabled()でフィーチャーフラグを確認
   └─ 無効の場合は何もしない
3. ScratchpadContentインスタンスを生成
   └─ コンストラクタでGrid + TextBoxを構築
4. KeyDownイベントハンドラを登録
   └─ コンテンツが処理しなかったキー入力をTerminalPageで処理
5. Paneオブジェクトを作成
   └─ ScratchpadContentをIPaneContentとしてラップ
6. _SplitPaneで現在のタブにペインを分割追加
   └─ SplitDirection::Automatic, 比率0.5で分割
```

### フローチャート

```mermaid
flowchart TD
    A[OpenScratchpadアクション実行] --> B{Feature_ScratchpadPane::IsEnabled?}
    B -->|No| C[何もしない]
    B -->|Yes| D[ScratchpadContent生成]
    D --> E[Gridの背景色をUnfocusedBorderBrushに設定]
    E --> F[TextBoxを生成しGridに追加]
    F --> G[KeyDownハンドラを登録]
    G --> H[Paneオブジェクト作成]
    H --> I[_SplitPaneで分割追加]
    I --> J[args.Handled true]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-121-01 | フィーチャーフラグ制御 | Feature_ScratchpadPaneが有効な場合のみペインを作成する | アクション実行時 |
| BR-121-02 | タイトル固定 | ペインのタイトルは常に "Scratchpad" とする | 常時 |
| BR-121-03 | 読み取り専用無効 | ReadOnlyプロパティは常にfalseを返す | 常時 |
| BR-121-04 | テキスト折り返し | TextBoxはTextWrapping::Wrapで折り返し表示する | 常時 |
| BR-121-05 | 改行許可 | TextBoxはAcceptsReturn(true)で複数行入力を許可する | 常時 |

### 計算ロジック

計算ロジックは存在しない。

## データベース操作仕様

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

データベース操作は存在しない。スクラッチパッドの内容は永続化されず、ペインを閉じると消失する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし | フィーチャー無効 | Feature_ScratchpadPaneが無効な場合 | アクションを無視する（エラーとはしない） |

### リトライ仕様

リトライが必要な処理は存在しない。

## トランザクション仕様

トランザクション処理は存在しない。

## パフォーマンス要件

軽量なUIコンポーネント（Grid + TextBox）のみで構成されるため、特段のパフォーマンス要件は設けていない。

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

スクラッチパッドの内容は永続化されないため、機密情報の漏洩リスクは低い。ただし、ペイン表示中は画面上にテキストが表示されるため、ショルダーハッキングには注意が必要である。

## 備考

- 本機能はDevビルドおよびCanaryビルド限定の機能であり、安定版リリースには含まれない
- features.xmlにおけるFeature IDは997である
- スクラッチパッドの内容はセッション間で保存されない（揮発性）
- 最小サイズは{1, 1}に設定されている
- タブの色（TabColor）は常にnullptrを返す

---

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

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

### 推奨読解順序

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

IPaneContentインターフェースとBasicPaneEventsの構造を理解することが出発点となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | BasicPaneEvents.h | `src/cascadia/TerminalApp/BasicPaneEvents.h` | ペインコンテンツが発火する標準イベント一覧（ConnectionStateChanged, CloseRequested, TitleChanged等） |

**読解のコツ**: `til::typed_event` はWindows Terminalプロジェクト独自のイベントヘルパーで、WinRTの `TypedEventHandler` のラッパーである。

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

アクションハンドラがスクラッチパッドペインの生成起点となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | _HandleOpenScratchpad関数がエントリーポイント |

**主要処理フロー**:
1. **1602-1617行目**: _HandleOpenScratchpad関数全体。Feature_ScratchpadPane::IsEnabled()でフラグ確認後、ScratchpadContentを生成し、_SplitPaneで分割追加
2. **1605行目**: Feature_ScratchpadPane::IsEnabled()でフィーチャーフラグを確認
3. **1607行目**: winrt::make_self<ScratchpadContent>()でインスタンス生成
4. **1612行目**: KeyDownイベントハンドラの登録
5. **1614行目**: Paneオブジェクトの作成
6. **1615行目**: _SplitPaneで自動方向・0.5比率で分割追加

#### Step 3: コンテンツ実装を理解する

ScratchpadContentクラスがペインの実体を構成する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ScratchpadContent.h | `src/cascadia/TerminalApp/ScratchpadContent.h` | クラス定義。IPaneContentとBasicPaneEventsの両方を実装 |
| 3-2 | ScratchpadContent.cpp | `src/cascadia/TerminalApp/ScratchpadContent.cpp` | コンストラクタでのUI構築、各メソッドの実装 |

**主要処理フロー**:
- **13-28行目（.cpp）**: コンストラクタ。Gridを生成し、UnfocusedBorderBrushを背景に設定。TextBoxを生成し、TextMenuFlyoutをコンテキストメニューに、マージン10px、AcceptsReturn(true)、TextWrapping::Wrapを設定してGridに追加
- **35-38行目（.cpp）**: GetRoot()。_rootのGridを返す
- **43-46行目（.cpp）**: Focus()。_box（TextBox）にフォーカスを移す
- **51-54行目（.cpp）**: GetNewTerminalArgs()。BaseContentArgs("scratchpad")を返す
- **56-60行目（.cpp）**: Icon()。QuickNoteアイコン（\xe70b）を返す

#### Step 4: フィーチャーフラグを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | features.xml | `src/features.xml` | Feature_ScratchpadPaneの定義。ID=997、AlwaysDisabledだがDevとCanaryでは有効 |

**主要処理フロー**:
- **136-144行目**: Feature_ScratchpadPaneの定義ブロック。stage=AlwaysDisabledで、DevとCanaryビルドトークンでのみ有効

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

```
TerminalPage::_HandleOpenScratchpad (AppActionHandlers.cpp:1602)
    |
    +-- Feature_ScratchpadPane::IsEnabled()  (features.xml生成コード)
    |
    +-- winrt::make_self<ScratchpadContent>()
    |       |
    |       +-- ScratchpadContent::ScratchpadContent()  (ScratchpadContent.cpp:13)
    |               |
    |               +-- Grid構築
    |               +-- TextBox構築（TextMenuFlyout, AcceptsReturn, TextWrapping設定）
    |
    +-- ScratchpadContent::GetRoot().KeyDown()  (KeyDownハンドラ登録)
    |
    +-- std::make_shared<Pane>(*scratchPane)
    |
    +-- TerminalPage::_SplitPane()  (SplitDirection::Automatic, 0.5f)
```

### データフロー図

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

OpenScratchpad      ───>  _HandleOpenScratchpad   ───>  新規ペイン（Grid+TextBox）
アクション                   |                              |
                             +-- ScratchpadContent      TerminalPageのペインツリーに追加
                             |   コンストラクタ
                             +-- _SplitPane

ユーザーキー入力    ───>  TextBox                   ───>  テキスト表示（揮発性）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ScratchpadContent.h | `src/cascadia/TerminalApp/ScratchpadContent.h` | ソース | スクラッチパッドコンテンツクラスのヘッダー定義 |
| ScratchpadContent.cpp | `src/cascadia/TerminalApp/ScratchpadContent.cpp` | ソース | スクラッチパッドコンテンツクラスの実装 |
| BasicPaneEvents.h | `src/cascadia/TerminalApp/BasicPaneEvents.h` | ソース | ペインの標準イベント定義 |
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleOpenScratchpadアクションハンドラ |
| features.xml | `src/features.xml` | 設定 | Feature_ScratchpadPaneフィーチャーフラグ定義 |
