# 機能設計書 6-Button

## 概要

本ドキュメントは、Avaloniaフレームワークにおける標準的なボタンコントロールである`Button`の機能設計を記述する。`ContentControl`を継承し、クリック操作、コマンドバインディング、キーボードショートカット、フライアウトなどの機能を提供する。

### 本機能の処理概要

`Button`クラスは、ユーザーインタラクションを処理する最も基本的なコントロールであり、以下の機能を提供する：
- **クリック処理**：マウスクリック、キーボード（Enter/Space）、アクセスキーによる操作
- **コマンドバインディング**：MVVMパターンでのICommand連携
- **ホットキー**：KeyGestureによるショートカット
- **IsDefault/IsCancel**：ダイアログでのデフォルト/キャンセルボタン
- **フライアウト**：クリック時のポップアップ表示
- **ClickMode**：Press/Releaseでのクリックタイミング制御

**業務上の目的・背景**：フォーム送信、アクション実行、ダイアログ操作など、ほぼすべてのUIで使用される基本的な操作要素。MVVMパターンでのコマンドバインディングにより、UIとビジネスロジックの分離を実現する。

**機能の利用シーン**：
- フォームの送信ボタン
- ダイアログのOK/キャンセルボタン
- アクション実行ボタン
- ドロップダウンメニュー（Flyout連携）

**主要な処理内容**：
1. `Click`イベントの発火
2. `Command`プロパティによるICommand実行
3. `HotKey`によるキーボードショートカット
4. `IsDefault`/`IsCancel`によるダイアログ対応
5. `Flyout`によるポップアップ表示
6. `:pressed`/`:flyout-open`擬似クラスによる視覚状態管理

**関連システム・外部連携**：
- `ContentControl`：コンテンツ表示基盤
- `ICommand`：コマンドパターン
- `HotKeyManager`：ホットキー管理
- `FlyoutBase`：フライアウト
- `AccessKeyHandler`：アクセスキー

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| S-01 | MainWindow | 表示/入力 | 各種操作ボタンの実装基盤 |

## 機能種別

UIコントロール / ユーザー入力 / コマンド実行

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ClickMode | ClickMode | No | クリックのタイミング（Release/Press） | デフォルト: Release |
| Command | ICommand? | No | 実行するコマンド | - |
| CommandParameter | object? | No | コマンドパラメータ | - |
| HotKey | KeyGesture? | No | ショートカットキー | - |
| IsDefault | bool | No | デフォルトボタンか | デフォルト: false |
| IsCancel | bool | No | キャンセルボタンか | デフォルト: false |
| Flyout | FlyoutBase? | No | 表示するフライアウト | - |

### 入力データソース

- ポインター入力（マウスクリック）
- キーボード入力（Enter、Space）
- アクセスキー（Alt+文字）
- ホットキー
- ルートレベルのEnter/Escape（IsDefault/IsCancel時）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Click | event | クリック時のルーテッドイベント（Bubble） |
| IsPressed | bool | 押下状態 |

### 出力先

- Clickイベントリスナー
- Command.Execute()
- Flyout表示

## 処理フロー

### 処理シーケンス

```
1. ポインターによるクリック
   ├─ OnPointerPressed（ClickMode.Press時はここでOnClick）
   │    └─ IsPressed = true
   └─ OnPointerReleased（ClickMode.Release時はここでOnClick）
        └─ IsPressed = false
        └─ OnClick

2. キーボードによるクリック
   ├─ OnKeyDown
   │    ├─ Enter → OnClick（即時）
   │    └─ Space（IsFocused時）→ IsPressed = true
   │         └─ ClickMode.Pressの場合 → OnClick
   └─ OnKeyUp
        └─ Space（IsFocused時）→ IsPressed = false
             └─ ClickMode.Releaseの場合 → OnClick

3. OnClick処理
   └─ IsEffectivelyEnabled確認
   └─ フライアウト状態切り替え
   └─ ClickEvent発火
   └─ Command?.CanExecute確認
   └─ Command?.Execute実行
```

### フローチャート

```mermaid
flowchart TD
    A[クリック入力] --> B{入力種別?}
    B -->|Pointer| C[OnPointerPressed/Released]
    B -->|Keyboard| D[OnKeyDown/Up]
    B -->|AccessKey| E[OnAccessKey]
    B -->|HotKey| F[HotKeyManager]

    C --> G{ClickMode?}
    D --> G
    E --> H[OnClick]
    F --> H

    G -->|Press| I[Press時にOnClick]
    G -->|Release| J[Release時にOnClick]

    I --> H
    J --> H

    H --> K{IsEffectivelyEnabled?}
    K -->|No| L[終了]
    K -->|Yes| M[Flyout切り替え]
    M --> N[ClickEvent発火]
    N --> O{Command?}
    O -->|Yes| P{CanExecute?}
    O -->|No| L
    P -->|Yes| Q[Command.Execute]
    P -->|No| L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ClickMode.Release | デフォルトではリリース時にClickイベント発火 | ClickMode == Release |
| BR-02 | ClickMode.Press | Press時にClickイベント発火 | ClickMode == Press |
| BR-03 | IsDefault動作 | VisualRoot全体でEnterキーを監視 | IsDefault == true |
| BR-04 | IsCancel動作 | VisualRoot全体でEscapeキーを監視 | IsCancel == true |
| BR-05 | Spaceキー制限 | IsFocused時のみSpaceでクリック（子TextBoxとの競合回避） | Space入力時 |
| BR-06 | IsEnabledCore | コマンドのCanExecuteがfalseの場合も無効化 | Command設定時 |
| BR-07 | フライアウト共有対応 | Flyout.Targetが自身の場合のみ状態更新 | Flyout設定時 |

### 計算ロジック

**IsEnabledCore計算**：
```csharp
IsEnabledCore => base.IsEnabledCore && _commandCanExecute
```

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | BindingError | CommandバインディングでBindingError | _commandCanExecute = false で無効化 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- CanExecuteChangedは効率的に処理
- HotKeyはロジカルツリーのアタッチ/デタッチで適切に登録解除
- AccessKeyは静的クラスハンドラで一括処理

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

- コマンド実行前にCanExecuteを確認
- 無効状態ではクリック処理を実行しない

## 備考

- WPFのButtonと同等の機能を提供
- ContentControlを継承しており、任意のコンテンツを表示可能

---

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

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

### 推奨読解順序

#### Step 1: クラス定義とプロパティを理解する

ボタンの基本構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Button.cs | `src/Avalonia.Controls/Button.cs` | 16-36行目：ClickMode列挙型とクラス定義 |
| 1-2 | Button.cs | `src/Avalonia.Controls/Button.cs` | 43-95行目：プロパティ定義 |

**読解のコツ**:
- `ContentControl`を継承し、`ICommandSource`を実装
- `pcPressed`/`pcFlyoutOpen`の擬似クラスが視覚状態を制御

#### Step 2: クリック処理を理解する

クリックの処理フローを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Button.cs | `src/Avalonia.Controls/Button.cs` | 345-368行目：OnClick |
| 2-2 | Button.cs | `src/Avalonia.Controls/Button.cs` | 403-427行目：OnPointerPressed |
| 2-3 | Button.cs | `src/Avalonia.Controls/Button.cs` | 430-445行目：OnPointerReleased |

**主要処理フロー**:
- **345-368行目**: `OnClick`でフライアウト切り替え、Clickイベント発火、Command実行
- **403-427行目**: `OnPointerPressed`でIsPressed設定、ClickMode.Pressの場合OnClick
- **430-445行目**: `OnPointerReleased`でClickMode.Releaseの場合OnClick

#### Step 3: キーボード処理を理解する

キーボードによるクリックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Button.cs | `src/Avalonia.Controls/Button.cs` | 296-323行目：OnKeyDown |
| 3-2 | Button.cs | `src/Avalonia.Controls/Button.cs` | 326-340行目：OnKeyUp |

**主要処理フロー**:
- **296-323行目**: Enter即時OnClick、SpaceはIsFocused時のみ処理
- **326-340行目**: Space KeyUpでClickMode.Release時OnClick

#### Step 4: コマンドバインディングを理解する

ICommandとの連携を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Button.cs | `src/Avalonia.Controls/Button.cs` | 247-262行目：OnAttachedToLogicalTree |
| 4-2 | Button.cs | `src/Avalonia.Controls/Button.cs` | 265-280行目：OnDetachedFromLogicalTree |
| 4-3 | Button.cs | `src/Avalonia.Controls/Button.cs` | 591-611行目：CanExecuteChanged |

**主要処理フロー**:
- **247-262行目**: ロジカルツリーアタッチ時にCanExecuteChanged購読
- **265-280行目**: デタッチ時に購読解除
- **591-611行目**: CanExecute結果をIsEnabledCoreに反映

#### Step 5: IsDefault/IsCancelを理解する

ダイアログ対応機能を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Button.cs | `src/Avalonia.Controls/Button.cs` | 205-244行目：OnAttachedToVisualTree/OnDetachedFromVisualTree |
| 5-2 | Button.cs | `src/Avalonia.Controls/Button.cs` | 643-673行目：ListenForDefault/Cancel系メソッド |
| 5-3 | Button.cs | `src/Avalonia.Controls/Button.cs` | 680-701行目：RootDefaultKeyDown/RootCancelKeyDown |

**主要処理フロー**:
- **205-244行目**: ビジュアルツリーアタッチ時にルートのKeyDownイベント購読
- **680-701行目**: Enter/Escapeキーでクリック処理

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

```
Button
    │
    ├─ ContentControl（コンテンツ表示）
    │      └─ TemplatedControl → Control → InputElement
    │
    ├─ ICommandSource
    │      ├─ Command
    │      └─ CommandParameter
    │
    ├─ クリック処理
    │      ├─ OnPointerPressed/Released
    │      ├─ OnKeyDown/Up
    │      ├─ OnAccessKey
    │      └─ HotKeyManager
    │
    ├─ IsDefault/IsCancel
    │      └─ VisualRoot.KeyDown
    │
    └─ Flyout
           ├─ OpenFlyout
           └─ CloseFlyout
```

### データフロー図

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

PointerPressed/Released
        │
        ▼
   ClickMode判定 ──────────▶ OnClick
                                │
KeyDown(Enter/Space)            │
        │                       │
        ▼                       ▼
   IsFocused確認 ──────────▶ IsEffectivelyEnabled確認
        │                       │
        ▼                       ▼
   OnClick ──────────────────▶ Flyout切り替え
                                │
                                ▼
                           ClickEvent発火
                                │
                                ▼
                           Command?.CanExecute
                                │
                                ▼
                           Command?.Execute ──▶ ビジネスロジック
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Button.cs | `src/Avalonia.Controls/Button.cs` | ソース | ボタンコントロール |
| ContentControl.cs | `src/Avalonia.Controls/ContentControl.cs` | ソース | コンテンツ表示基盤（親クラス） |
| ICommandSource.cs | `src/Avalonia.Controls/ICommandSource.cs` | ソース | コマンドソースインターフェース |
| IClickableControl.cs | `src/Avalonia.Controls/IClickableControl.cs` | ソース | クリック可能インターフェース |
| HotKeyManager.cs | `src/Avalonia.Controls/HotKeyManager.cs` | ソース | ホットキー管理 |
| AccessKeyHandler.cs | `src/Avalonia.Input/AccessKeyHandler.cs` | ソース | アクセスキー処理 |
| FlyoutBase.cs | `src/Avalonia.Controls/Flyouts/FlyoutBase.cs` | ソース | フライアウト基底 |
| ButtonAutomationPeer.cs | `src/Avalonia.Controls/Automation/Peers/ButtonAutomationPeer.cs` | ソース | オートメーション対応 |
