# 画面設計書 12-ColorPickupFlyout（カラー選択）

## 概要

本ドキュメントは、Windows Terminal の ColorPickupFlyout（カラー選択）画面の設計仕様を記述する。ColorPickupFlyout は、タブの色をユーザーが選択・設定するためのフライアウトメニューである。

### 本画面の処理概要

ColorPickupFlyout は、タブに対して視覚的な色分けを行うためのカラーピッカーを提供するフライアウトコントロールである。プリセットカラーの一覧から色を選択する方法と、カスタムカラーピッカーを使用して任意の色を指定する方法の2通りの操作を提供する。

**業務上の目的・背景**：複数のタブを開いて作業する際、各タブを色で視覚的に区別できることは作業効率の向上に直結する。例えば、本番環境と開発環境のタブを異なる色で識別するなどの用途がある。ColorPickupFlyout はこのタブカラー設定を直感的な UI で実現する。

**画面へのアクセス方法**：TerminalPage 上でタブ色ピッカーを開くアクション（`_HandleOpenTabColorPicker`）が発動されることで表示される。具体的にはタブのコンテキストメニューから「色の設定」を選択するか、割り当てられたキーバインドを押下する。

**主要な操作・処理内容**：
1. プリセットカラーの選択：16色のプリセットカラーボタンから色を選択する（Crimson, SteelBlue, MediumSeaGreen, DarkOrange, MediumVioletRed, DodgerBlue, LimeGreen, Yellow, BlueViolet, SlateBlue, Lime, Tan, Magenta, Cyan, SkyBlue, DarkGray）
2. カスタムカラーの選択：「Custom」ボタンを押してカスタムカラーピッカーを展開し、任意の色を選択する
3. 色のクリア：「Clear」ボタンを押してタブの色設定をリセットする
4. カスタムカラーのリアルタイムプレビュー：カスタムカラーピッカーでの色変更がリアルタイムでタブに反映される

**画面遷移**：TerminalPage のタブコンテキストメニューまたはキーバインドからフライアウトが表示される。色の選択またはクリア後、フライアウトは自動的に閉じる。

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 13 | タブ色の設定 | 主機能 | カラーピッカーからタブの色を選択・設定 |
| 14 | タブ色ピッカーを開く | 主機能 | カラーピッカーフライアウトの表示 |

## 画面種別

ツール（フライアウトメニュー）

## URL/ルーティング

該当なし（XAML Flyout コントロールとしてタブアイテムに対して表示される）

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| ColorSelected | 出力 | Event (Windows.UI.Color) | - | 色が選択されたときに発火するイベント |
| ColorCleared | 出力 | Event | - | 色がクリアされたときに発火するイベント |

## 表示項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| プリセットカラーボタン（16個） | Button | 16色のプリセットカラーボタン（4x4グリッド配置） |
| ClearColorButton | Button | タブ色をクリアするボタン（ローカライズ済みテキスト） |
| CustomColorButton | ToggleButton | カスタムカラーピッカーの表示/非表示を切り替えるトグルボタン |
| customColorPicker | ColorPicker | Microsoft.UI.Xaml.Controls.ColorPicker。RGB スライダー、HEX 入力、カラースペクトラムを含む |
| OkButton | Button | カスタムカラーの確定ボタン（AccentButtonStyle 適用） |

## イベント仕様

### 1-プリセットカラー選択（ColorButton_Click）

16個のプリセットカラーボタンのいずれかがクリックされると、ボタンの Background（SolidColorBrush）から Color を取得し、`ColorSelected` イベントを発火する。その後、フライアウトを `Hide()` で閉じる。（ColorPickupFlyout.cpp 行30-36）

### 2-色のクリア（ClearColorButton_Click）

「Clear」ボタンがクリックされると、`ColorCleared` イベントを発火し、フライアウトを `Hide()` で閉じる。（ColorPickupFlyout.cpp 行45-49）

### 3-カスタムカラーパネルの表示/非表示（ShowColorPickerButton_Click）

「Custom」トグルボタンがクリックされると、`customColorPanel` の Visibility を切り替える。Collapsed の場合は Visible に、Visible の場合は Collapsed に設定する。（ColorPickupFlyout.cpp 行59-70）

### 4-カスタムカラーのリアルタイム変更（ColorPicker_ColorChanged）

カスタムカラーピッカーの色が変更されるたびに、新しい色で `ColorSelected` イベントが発火される。これによりタブの色がリアルタイムでプレビューされる。（ColorPickupFlyout.cpp 行86-89）

### 5-カスタムカラーの確定（CustomColorButton_Click）

「OK」ボタンがクリックされると、カスタムカラーピッカーの現在の色で `ColorSelected` イベントを発火し、フライアウトを `Hide()` で閉じる。（ColorPickupFlyout.cpp 行79-84）

### 6-Tab 側のイベントハンドリング

Tab クラスの `AttachColorPicker` メソッド（Tab.cpp 行785）で ColorPickupFlyout が Tab に接続される。ColorSelected イベントで `SetRuntimeTabColor` が、ColorCleared イベントで `ResetRuntimeTabColor` が呼び出される。フライアウトが閉じられると（Closed イベント）、イベントハンドラが解除される。

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

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

該当なし。タブの色設定はランタイム状態としてメモリ上に保持される。永続化は行われない。

## メッセージ仕様

| メッセージID | 種別 | 表示条件 | メッセージ内容 |
|-------------|------|----------|---------------|
| TabColorClearButton/Content | ボタンラベル | 常時 | 色クリアボタンのテキスト |
| TabColorCustomButton/Content | ボタンラベル | 常時 | カスタムカラーボタンのテキスト |
| Ok | ボタンラベル | カスタムカラーパネル表示時 | OK ボタンのテキスト |

## 例外処理

- 特別な例外処理は実装されていない。ColorPickupFlyout は単純なUI操作のみを行い、外部リソースへのアクセスは行わない。

## 備考

- プリセットカラーは 4x4 グリッド（VariableSizedWrapGrid, MaximumRowsOrColumns=4）で配置される
- カスタムカラーピッカーはアルファチャンネル（透明度）を無効化している（IsAlphaEnabled=False）
- ColorPicker は HEX 入力、RGB スライダー、カラースペクトラムを含む
- フライアウトの配置は Bottom（下部）に設定されている（Placement="Bottom"）
- フライアウトはルートバウンズに制約されない（ShouldConstrainToRootBounds="False"）
- タブ色はランタイム設定であり、アプリケーション再起動時には保持されない

---

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

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

### 推奨読解順序

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

ColorPickupFlyout で扱われるイベントデリゲートを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ColorPickupFlyout.idl | `src/cascadia/TerminalApp/ColorPickupFlyout.idl` | ColorSelectedArgs（Windows.UI.Color を引数に取るデリゲート）と ColorClearedArgs（引数なしデリゲート）の定義を確認（行3-4）。Flyout を基底クラスとするランタイムクラスの構造を理解（行6-11） |

**読解のコツ**: IDL のデリゲート定義はイベント駆動型のコントロール設計を理解する鍵となる。

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

TerminalPage からフライアウトがどのように呼び出されるかを追跡する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | `_HandleOpenTabColorPicker` メソッド（行706-718）がエントリーポイント。_tabColorPicker がなければ新規作成し、activeTab.AttachColorPicker で Tab に接続する |
| 2-2 | Tab.cpp | `src/cascadia/TerminalApp/Tab.cpp` | `AttachColorPicker` メソッド（行785-818）で ColorSelected / ColorCleared / Closed の3つのイベントをサブスクライブし、`ShowAt(TabViewItem())` でフライアウトを表示する |

**主要処理フロー**:
1. **行706**: `_HandleOpenTabColorPicker` がアクションから呼び出される
2. **行711-713**: `_tabColorPicker` が未作成なら `winrt::make<ColorPickupFlyout>()` で生成
3. **行716**: `activeTab->AttachColorPicker(_tabColorPicker)` でタブに接続
4. **行817**: `_tabColorPickup.ShowAt(TabViewItem())` でフライアウトを表示

#### Step 3: XAML レイアウトを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ColorPickupFlyout.xaml | `src/cascadia/TerminalApp/ColorPickupFlyout.xaml` | Flyout の内部構造。水平方向 StackPanel でプリセットカラー領域とカスタムカラー領域を配置。VariableSizedWrapGrid で4列グリッドを実現。customColorPanel は初期 Visibility="Collapsed" |

#### Step 4: コントロールの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ColorPickupFlyout.h | `src/cascadia/TerminalApp/ColorPickupFlyout.h` | イベントハンドラメソッドの宣言と、ColorCleared / ColorSelected イベントの til::event 宣言（行16-17） |
| 4-2 | ColorPickupFlyout.cpp | `src/cascadia/TerminalApp/ColorPickupFlyout.cpp` | コンストラクタでのローカライズ処理（行17-19）、各ボタンクリックハンドラの実装 |

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

```
TerminalPage::_HandleOpenTabColorPicker (AppActionHandlers.cpp:706)
    |
    +-- winrt::make<ColorPickupFlyout>() (生成、必要時のみ)
    |
    +-- Tab::AttachColorPicker (Tab.cpp:785)
            |
            +-- ColorSelected イベントサブスクライブ
            |       +-- Tab::SetRuntimeTabColor
            |
            +-- ColorCleared イベントサブスクライブ
            |       +-- Tab::ResetRuntimeTabColor
            |
            +-- Closed イベントサブスクライブ
            |       +-- イベントハンドラ解除
            |
            +-- _tabColorPickup.ShowAt(TabViewItem())
                    |
                    +-- ColorButton_Click --> ColorSelected.raise --> Hide()
                    +-- ClearColorButton_Click --> ColorCleared.raise --> Hide()
                    +-- ShowColorPickerButton_Click --> customColorPanel 表示切替
                    +-- ColorPicker_ColorChanged --> ColorSelected.raise
                    +-- CustomColorButton_Click --> ColorSelected.raise --> Hide()
```

### データフロー図

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

ユーザー操作           ColorPickupFlyout                Tab
  |                        |                              |
プリセット色クリック -> ColorButton_Click         -> ColorSelected イベント
                        -> Background.Color取得       -> Tab::SetRuntimeTabColor
                        -> Hide()                       (タブ色変更)
  |                        |                              |
カスタム色変更    -> ColorPicker_ColorChanged     -> ColorSelected イベント
                        -> args.NewColor()             -> Tab::SetRuntimeTabColor
                                                        (リアルタイム反映)
  |                        |                              |
クリアボタン      -> ClearColorButton_Click       -> ColorCleared イベント
                        -> Hide()                      -> Tab::ResetRuntimeTabColor
                                                        (タブ色リセット)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ColorPickupFlyout.xaml | `src/cascadia/TerminalApp/ColorPickupFlyout.xaml` | ソース（XAML） | UI レイアウト定義 |
| ColorPickupFlyout.h | `src/cascadia/TerminalApp/ColorPickupFlyout.h` | ソース（ヘッダー） | クラス宣言・イベント定義 |
| ColorPickupFlyout.cpp | `src/cascadia/TerminalApp/ColorPickupFlyout.cpp` | ソース（実装） | コントロールの動作ロジック |
| ColorPickupFlyout.idl | `src/cascadia/TerminalApp/ColorPickupFlyout.idl` | ソース（IDL） | WinRT インターフェース定義 |
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース（実装） | `_HandleOpenTabColorPicker` / `_HandleSetTabColor` |
| Tab.cpp | `src/cascadia/TerminalApp/Tab.cpp` | ソース（実装） | `AttachColorPicker` によるイベント接続とフライアウト表示 |
| Resources.resw | `src/cascadia/TerminalApp/Resources/en-US/Resources.resw` | リソース | ボタンテキスト等の文字列リソース |
