# 機能設計書 23-ToggleSwitch

## 概要

本ドキュメントは、AvaloniaフレームワークにおけるToggleSwitchコントロールの機能設計を記載する。ToggleSwitchは、オン/オフの2状態を切り替えるスイッチ型のUIコントロールである。

### 本機能の処理概要

ToggleSwitchは、トグルボタンの一種で、オン/オフの状態をスライダー形式で視覚的に表現するコントロールである。CheckBoxとは異なり、設定の有効/無効を切り替えるモバイルアプリケーション風のUIを提供する。ドラッグ操作によるスワイプ切り替えにも対応している。

**業務上の目的・背景**：
モダンなアプリケーションUIにおいて、設定のオン/オフを直感的に操作できるスイッチコントロールが必要である。特にモバイルアプリケーション風のインターフェースを構築する際に、CheckBoxよりも視覚的にわかりやすいToggleSwitchが好まれる。

**機能の利用シーン**：
- 設定画面でのオプション有効/無効切り替え
- 通知設定のオン/オフ
- ダークモード切り替え
- Wi-Fi/Bluetooth等の機能トグル
- 機能フラグの有効化/無効化

**主要な処理内容**：
1. クリックによるオン/オフ切り替え
2. ドラッグ操作によるスワイプ切り替え
3. オン/オフ状態に応じたコンテンツ表示（OnContent/OffContent）
4. 状態変更時のスライドアニメーション
5. IsCheckedChangedイベントの発行
6. 擬似クラスによるスタイル制御（:checked, :unchecked, :dragging）

**関連システム・外部連携**：
- ToggleButton基底クラスからの継承
- ICommandパターンによるコマンドバインディング

**権限による制御**：
本コントロールには権限による制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 66 | ToggleSwitch | 主画面 | ToggleSwitchコントロールのデモ |

## 機能種別

UI操作 / 入力コントロール / トグル操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| IsChecked | bool? | No | チェック状態（true=オン, false=オフ, null=不定） | - |
| OnContent | object | No | オン状態時に表示するコンテンツ | - |
| OffContent | object | No | オフ状態時に表示するコンテンツ | - |
| KnobTransitions | Transitions | No | ノブ（つまみ）のアニメーション | - |
| Command | ICommand | No | トグル時に実行するコマンド | - |
| CommandParameter | object | No | コマンドに渡すパラメータ | - |
| IsEnabled | bool | No | コントロールの有効/無効 | デフォルト: true |

### 入力データソース

- ユーザーによるクリック操作
- ユーザーによるドラッグ/スワイプ操作
- プログラムによるIsChecked設定
- データバインディングによるIsChecked制御
- キーボード操作（Space/Enter）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| IsChecked | bool? | 現在のチェック状態 |

### 出力先

- UI表示（ノブ位置、OnContent/OffContentの表示切り替え）
- IsCheckedChangedイベントの発行
- Commandの実行

## 処理フロー

### 処理シーケンス

```
1. 入力検出
   ├─ クリック操作: OnClick
   └─ ドラッグ操作: OnPointerPressed → OnPointerMoved → OnPointerReleased
2. 状態切り替え判定
   ├─ クリック: 現在の状態を反転
   └─ ドラッグ: 移動距離に基づいて状態決定
3. IsCheckedプロパティ更新
   └─ ToggleButton.OnClickでToggleメソッド呼び出し
4. KnobTransition実行
   └─ ノブ位置のアニメーション
5. コンテンツ切り替え
   └─ OnContent/OffContentの表示切り替え
6. 擬似クラス更新
   └─ :checked/:uncheckedの設定
7. イベント・コマンド実行
   └─ IsCheckedChangedイベント発行、Command実行
```

### フローチャート

```mermaid
flowchart TD
    A[入力開始] --> B{入力タイプ}
    B -->|クリック| C[状態反転]
    B -->|ドラッグ開始| D[:dragging設定]
    D --> E[ノブ位置更新]
    E --> F{ドラッグ終了?}
    F -->|No| E
    F -->|Yes| G[移動距離判定]
    G --> H{閾値超過?}
    H -->|Yes| C
    H -->|No| I[元の状態を維持]
    C --> J[IsChecked更新]
    I --> K[:dragging解除]
    J --> K
    K --> L[KnobTransition実行]
    L --> M[コンテンツ切り替え]
    M --> N[IsCheckedChangedイベント]
    N --> O[Command実行]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 3状態サポート | IsCheckedはtrue/false/nullの3状態をサポート（nullは不定状態） | IsThreeState=true時 |
| BR-002 | ドラッグ閾値 | ドラッグ移動量がノブ幅の50%を超えた場合に状態切り替え | ドラッグ操作時 |
| BR-003 | コマンド連動 | IsChecked変更時にCommandが設定されていればCanExecuteを確認後Execute | Command設定時 |
| BR-004 | 双方向バインディング | IsCheckedはデフォルトでTwoWayバインディング | 常時適用 |

### 計算ロジック

ドラッグによる状態切り替え判定：
```
switchArea = KnobBounds内でのドラッグ開始位置
delta = PointerPosition - dragStartPoint
新状態 = delta.X > (KnobWidth / 2) ? true : false
```

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

本コントロールはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | コマンド実行不可 | Command.CanExecute()がfalse | 状態は更新されるがコマンドは実行されない |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- ドラッグ操作中のノブ追従は滑らかに行われる必要がある
- アニメーションは滑らかなトランジションで実行される

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

本コントロールにはセキュリティ上の特別な考慮事項はない。

## 備考

- ToggleButtonを継承しているため、IsChecked、Click、Commandなどの機能はToggleButtonから継承される
- モバイルアプリケーション風のUIを実現するために設計されている

---

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

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

### 推奨読解順序

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

基底クラスToggleButtonの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ToggleButton.cs | `src/Avalonia.Controls/Primitives/ToggleButton.cs` | IsCheckedプロパティ、Toggleメソッド |
| 1-2 | Button.cs | `src/Avalonia.Controls/Button.cs` | OnClickメソッド、Commandパターン |

**読解のコツ**: ToggleSwitchはToggleButtonを継承しているため、IsCheckedの基本動作はToggleButtonで定義されている。

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

ToggleSwitchクラスの主要プロパティを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ToggleSwitch.cs | `src/Avalonia.Controls/ToggleSwitch.cs` | プロパティ定義、テンプレートパーツ |

**主要処理フロー**:
1. **19-20行目**: :dragging擬似クラスと:checked/:unchecked擬似クラスの定義
2. **22-28行目**: TemplatePart属性でKnobGrid、KnobCanvas、MovingKnobなどを指定
3. **31-55行目**: OnContent/OffContent/KnobTransitionsプロパティ定義

#### Step 3: テンプレート適用処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ToggleSwitch.cs | `src/Avalonia.Controls/ToggleSwitch.cs` | OnApplyTemplate、UpdateKnob |

**主要処理フロー**:
- **115-163行目**: OnApplyTemplateでテンプレートパーツを取得、サイズ変更監視を設定
- **165-197行目**: UpdateKnobでノブ位置を計算、アニメーション実行

#### Step 4: ドラッグ操作処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ToggleSwitch.cs | `src/Avalonia.Controls/ToggleSwitch.cs` | ポインターイベント処理 |

**主要処理フロー**:
- **199-241行目**: OnPointerPressedでドラッグ開始判定
- **248-272行目**: OnPointerMovedでノブ位置を更新
- **279-312行目**: OnPointerReleasedで状態確定、アニメーション実行

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

```
ToggleSwitch
    │
    ├─ OnApplyTemplate
    │      └─ UpdateKnob（初期ノブ位置設定）
    │
    ├─ OnClick（クリック操作）
    │      └─ Toggle (ToggleButton)
    │             └─ IsChecked更新
    │
    ├─ OnPointerPressed（ドラッグ開始）
    │      └─ _isDragging = true
    │             └─ :dragging擬似クラス設定
    │
    ├─ OnPointerMoved（ドラッグ中）
    │      └─ UpdateKnob（トランジションなし）
    │
    └─ OnPointerReleased（ドラッグ終了）
           ├─ 状態決定（移動距離判定）
           ├─ IsChecked更新
           └─ UpdateKnob（トランジションあり）
```

### データフロー図

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

クリック ────────────▶ OnClick
                          │
                          ▼
                       Toggle ─────────────────────────▶ IsChecked変更
                          │
ドラッグ開始 ────────▶ OnPointerPressed                      │
                          │                                  │
                     _isDragging                             │
                          │                                  │
ドラッグ中 ──────────▶ OnPointerMoved                        │
                          │                                  │
                     UpdateKnob（位置追従）                   │
                          │                                  │
ドラッグ終了 ────────▶ OnPointerReleased                     │
                          │                                  │
                    状態決定 ────────────────────────────────┤
                          │                                  │
                          ▼                                  ▼
                    UpdateKnob（アニメーション）      IsCheckedChangedイベント
                          │
                          ▼
                    UI更新（ノブ位置）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ToggleSwitch.cs | `src/Avalonia.Controls/ToggleSwitch.cs` | ソース | メインコントロールクラス |
| ToggleButton.cs | `src/Avalonia.Controls/Primitives/ToggleButton.cs` | ソース | 基底クラス（トグル機能） |
| Button.cs | `src/Avalonia.Controls/Button.cs` | ソース | 基底クラス（クリック、コマンド） |
| ToggleSwitch.xaml | `src/Avalonia.Themes.Fluent/Controls/ToggleSwitch.xaml` | テンプレート | Fluentテーマのテンプレート |
