# 機能設計書 14-タブ色ピッカーを開く

## 概要

本ドキュメントは、Windows Terminalにおけるタブの色を選択するためのカラーピッカーフライアウトを表示する機能（OpenTabColorPicker アクション）の設計を記述する。

### 本機能の処理概要

タブヘッダー上にカラーピッカーフライアウト（ColorPickupFlyout）を表示し、ユーザーがGUIで色を選択してタブに適用できるようにする機能である。プリセット色の選択、カスタムカラーピッカーでの色選択、色のクリアが可能。

**業務上の目的・背景**：No.13「タブ色の設定」機能ではコマンドやキーバインドで特定の色を直接指定するが、本機能ではGUIベースのカラーピッカーを提供し、ユーザーが視覚的に色を選択できるようにする。色のコード値を知らなくても直感的に色を選択できる。

**機能の利用シーン**：ユーザーがタブを右クリックしてコンテキストメニューから「色の設定」を選択する場面や、キーバインドでカラーピッカーを開く場面で使用される。

**主要な処理内容**：
1. OpenTabColorPickerアクションの受信
2. 対象タブの特定
3. ColorPickupFlyoutインスタンスの生成（未生成の場合）
4. タブへのカラーピッカーのアタッチ（イベントハンドラ登録）
5. カラーピッカーフライアウトの表示
6. ユーザーの色選択に応じてSetRuntimeTabColor / ResetRuntimeTabColorを呼び出し
7. カラーピッカー閉じ時にイベントハンドラのクリーンアップ

**関連システム・外部連携**：外部連携なし。

**権限による制御**：権限による制御なし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleOpenTabColorPickerによりColorPickupFlyoutを表示 |
| 12 | ColorPickupFlyout（カラー選択） | 主画面 | カラーピッカーフライアウトの表示 |

## 機能種別

UI操作 / UI表示制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | OpenTabColorPickerアクションにパラメータなし | - |

### 入力データソース

キーバインド、コマンドパレット、またはコンテキストメニューからのアクション実行。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| カラーピッカーUI | ColorPickupFlyout | タブヘッダー上に表示されるカラー選択フライアウト |

### 出力先

TabViewItemに対するFlyoutとして表示

## 処理フロー

### 処理シーケンス

```
1. _HandleOpenTabColorPicker が呼び出される
   └─ sender から対象タブを特定
2. _tabColorPicker が未生成の場合
   └─ winrt::make<ColorPickupFlyout>() で新規生成
3. activeTab->AttachColorPicker(_tabColorPicker) を呼び出し
   ├─ ColorSelected イベントハンドラを登録
   │   └─ 色選択時: Tab::SetRuntimeTabColor(newTabColor)
   ├─ ColorCleared イベントハンドラを登録
   │   └─ 色クリア時: Tab::ResetRuntimeTabColor()
   └─ Closed イベントハンドラを登録
       └─ フライアウト閉じ時: 3つのイベントハンドラを解除、_tabColorPickup = nullptr
4. _tabColorPickup.ShowAt(TabViewItem()) でフライアウト表示
5. args.Handled(true) を設定
```

### フローチャート

```mermaid
flowchart TD
    A[OpenTabColorPicker アクション受信] --> B[対象タブ特定]
    B --> C{_tabColorPicker 存在?}
    C -->|No| D[ColorPickupFlyout 生成]
    C -->|Yes| E[AttachColorPicker]
    D --> E
    E --> F[イベントハンドラ登録]
    F --> G[ShowAt でフライアウト表示]
    G --> H{ユーザー操作}
    H -->|色選択| I[SetRuntimeTabColor]
    H -->|色クリア| J[ResetRuntimeTabColor]
    H -->|閉じる| K[イベントハンドラ解除]
    I --> L[Handled = true]
    J --> L
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-14-01 | 遅延生成 | ColorPickupFlyout は初回使用時に生成され、以降再利用される | _tabColorPicker が null の場合 |
| BR-14-02 | 色選択イベント | ユーザーが色を選択すると SetRuntimeTabColor が呼ばれタブ色が即座に変更される | ColorSelected イベント発火時 |
| BR-14-03 | 色クリアイベント | ユーザーが色をクリアすると ResetRuntimeTabColor が呼ばれデフォルト色に戻る | ColorCleared イベント発火時 |
| BR-14-04 | クリーンアップ | フライアウト閉じ時に全イベントハンドラが解除され、_tabColorPickup が null に設定される | Closed イベント発火時 |

### 計算ロジック

特になし。

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

データベース操作なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし | タブ未取得 | _senderOrFocusedTabがnullptrを返した場合 | 処理をスキップ |

### リトライ仕様

リトライ不要。

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

トランザクション管理なし。

## パフォーマンス要件

カラーピッカーフライアウトの表示は即座に行われること。

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

特になし。

## 備考

- ColorPickupFlyoutはプリセット色ボタン、カスタムカラーピッカー、色クリアボタンで構成される
- weakThisパターンを使用してタブの寿命管理を行い、タブが閉じられた後のイベント処理を安全にしている
- イベントハンドラはトークンベースで管理され、Closedイベント時に確実に解除される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ColorPickupFlyout.h | `src/cascadia/TerminalApp/ColorPickupFlyout.h` | **6-18行目**: ColorPickupFlyout クラスの構造。ColorCleared / ColorSelected イベントの宣言 |
| 1-2 | ColorPickupFlyout.idl | `src/cascadia/TerminalApp/ColorPickupFlyout.idl` | カラーピッカーの WinRT インターフェース定義 |

**読解のコツ**: `til::event<T>` はスレッドセーフなイベントディスパッチャー。ColorClearedArgs / ColorSelectedArgs はデリゲート型として定義されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | **706-719行目**: _HandleOpenTabColorPicker の実装。ColorPickupFlyout の遅延生成と AttachColorPicker の呼び出し |

**主要処理フロー**:
1. **709行目**: _senderOrFocusedTab で対象タブを特定
2. **711-714行目**: _tabColorPicker が未生成の場合、winrt::make で新規生成
3. **716行目**: activeTab->AttachColorPicker(_tabColorPicker) を呼び出し
4. **718行目**: args.Handled(true) を設定

#### Step 3: Tab クラスのアタッチ処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Tab.cpp | `src/cascadia/TerminalApp/Tab.cpp` | **785-818行目**: AttachColorPicker の実装。3つのイベントハンドラ登録とShowAt呼び出し |

**主要処理フロー**:
- **793-798行目**: ColorSelected イベントハンドラ - SetRuntimeTabColor を呼び出し
- **800-805行目**: ColorCleared イベントハンドラ - ResetRuntimeTabColor を呼び出し
- **807-815行目**: Closed イベントハンドラ - 3つのイベントを解除し _tabColorPickup を null に設定
- **817行目**: _tabColorPickup.ShowAt(TabViewItem()) でフライアウトを表示

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

```
TerminalPage::_HandleOpenTabColorPicker (AppActionHandlers.cpp:706)
    |
    +-- ColorPickupFlyout 生成（必要時）
    |
    +-- Tab::AttachColorPicker(colorPicker) (Tab.cpp:785)
            |
            +-- ColorSelected イベントハンドラ登録
            |       +-- Tab::SetRuntimeTabColor(newTabColor)
            |
            +-- ColorCleared イベントハンドラ登録
            |       +-- Tab::ResetRuntimeTabColor()
            |
            +-- Closed イベントハンドラ登録
            |       +-- イベントハンドラ3件解除
            |       +-- _tabColorPickup = nullptr
            |
            +-- _tabColorPickup.ShowAt(TabViewItem())
```

### データフロー図

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

アクション           TerminalPage                         ColorPickupFlyout
(OpenTabColorPicker) --> ::_HandleOpenTabColorPicker() --> ShowAt(TabViewItem)
                                                              |
                                                        [ユーザー色選択]
                                                              |
                                                        ColorSelected イベント
                                                              |
                                                        Tab::SetRuntimeTabColor()
                                                              |
                                                        タブ背景色更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleOpenTabColorPicker の実装 |
| Tab.cpp | `src/cascadia/TerminalApp/Tab.cpp` | ソース | AttachColorPicker の実装 |
| Tab.h | `src/cascadia/TerminalApp/Tab.h` | ヘッダー | Tab クラスの宣言 |
| ColorPickupFlyout.cpp | `src/cascadia/TerminalApp/ColorPickupFlyout.cpp` | ソース | カラーピッカーの実装 |
| ColorPickupFlyout.h | `src/cascadia/TerminalApp/ColorPickupFlyout.h` | ヘッダー | ColorPickupFlyout クラスの宣言 |
| ColorPickupFlyout.xaml | `src/cascadia/TerminalApp/ColorPickupFlyout.xaml` | XAML | カラーピッカーのレイアウト定義 |
| ColorPickupFlyout.idl | `src/cascadia/TerminalApp/ColorPickupFlyout.idl` | IDL | ColorPickupFlyout の WinRT 型定義 |
| TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | ヘッダー | _tabColorPicker メンバーと _HandleOpenTabColorPicker の宣言 |
