# 機能設計書 57-HotkeyManager

## 概要

本ドキュメントは、Avaloniaフレームワークにおけるホットキー管理（HotkeyManager）機能の設計仕様を定義する。HotkeyManagerは、コントロールにグローバルショートカットキーを割り当て、キーボードショートカットによるコマンド実行を実現する機能を提供する。

### 本機能の処理概要

HotkeyManagerは、HotKey添付プロパティを通じてコントロールにキーボードショートカットを割り当てる機能を提供する。設定されたホットキーはTopLevelのKeyBindingsに登録され、ウィンドウ全体でショートカットキーが有効になる。

**業務上の目的・背景**：キーボードショートカットは、ユーザーの作業効率を大幅に向上させる重要な機能である。特に頻繁に使用するアクションに対してショートカットキーを提供することで、マウス操作を減らし、作業の高速化を実現できる。HotkeyManagerは、XAMLで宣言的にショートカットキーを定義できるようにし、開発者の実装負担を軽減する。

**機能の利用シーン**：
- メニュー項目へのCtrl+S（保存）、Ctrl+O（開く）などのショートカット割り当て
- ボタンへのF5（リフレッシュ）などのファンクションキー割り当て
- ツールバーボタンへのショートカット割り当て

**主要な処理内容**：
1. HotKey添付プロパティによるKeyGestureの設定
2. TopLevelへのKeyBinding自動登録
3. ICommandSourceまたはIClickableControlのコマンド/クリック実行
4. コントロールの有効/無効状態に応じた実行制御

**関連システム・外部連携**：TopLevel、KeyBinding、KeyGesture、ICommandSource、IClickableControlと連携してショートカット機能を実現。

**権限による制御**：コントロールのIsEffectivelyEnabledプロパティでコマンド実行可否を制御。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | Accelerator | 主機能 | キーボードアクセラレータのデモ。ショートカットキーの登録と処理 |

## 機能種別

ショートカットキー管理 / 添付プロパティ / コマンド実行

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| HotKey | KeyGesture? | No | ショートカットキー定義 | null許容 |

### 入力データソース

- XAML属性でのHotKey添付プロパティ設定
- コードビハインドでのプロパティ設定

## 出力仕様

### 出力データ

該当なし（コマンド実行の副作用のみ）

### 出力先

- ICommand.Execute（ICommandSource実装時）
- IClickableControl.RaiseClick（IClickableControl実装時）

## 処理フロー

### 処理シーケンス

```
1. HotKey添付プロパティ設定
   └─ HotKeyProperty.Changedで検出
2. Manager初期化
   └─ 対象コントロールのManagerインスタンス作成
3. TopLevel監視開始
   └─ AncestorFinderで親TopLevelを監視
4. KeyBinding登録
   └─ TopLevel.KeyBindingsにKeyBinding追加
5. キー押下検出
   └─ KeyGestureがマッチするとコマンド実行
```

### フローチャート

```mermaid
flowchart TD
    A[HotKey設定] --> B{IClickableControl or ICommandSource?}
    B -->|No| C[警告ログ出力]
    B -->|Yes| D[Manager作成・Init]
    D --> E[HotKeyProperty監視開始]
    D --> F[親TopLevel監視開始]
    F --> G{TopLevel変更?}
    G -->|Yes| H[旧TopLevelからKeyBinding削除]
    H --> I[新TopLevelにKeyBinding追加]
    G -->|No| J[待機]
    E --> K{HotKey変更?}
    K -->|Yes| L{nullに変更?}
    L -->|Yes| M[Manager停止]
    L -->|No| N[KeyBinding再登録]

    O[ショートカットキー押下] --> P{KeyGestureマッチ?}
    P -->|Yes| Q{IsEffectivelyEnabled?}
    Q -->|Yes| R{ICommandSource?}
    R -->|Yes| S[Command.Execute]
    R -->|No| T[RaiseClick]
    Q -->|No| U[無視]
    P -->|No| U
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-57-01 | 対象コントロール制限 | IClickableControlまたはICommandSource実装が必要 | HotKey設定時 |
| BR-57-02 | TopLevelスコープ | KeyBindingはTopLevelに登録される | KeyBinding登録時 |
| BR-57-03 | 有効状態チェック | IsEffectivelyEnabled=trueの場合のみ実行 | コマンド実行時 |
| BR-57-04 | ICommandSource優先 | ICommandSourceのCommandがあれば優先実行 | コマンド実行時 |

### 計算ロジック

特になし

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

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

該当なし（UIフレームワークのためデータベース操作は行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 警告ログ | IClickableControl/ICommandSource未実装 | 警告ログ出力、処理継続 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- ショートカットキー判定は即座に行われる必要がある

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

特になし

## 備考

- WeakReferenceでコントロールを保持しメモリリークを防止
- 親TopLevel変更時に自動的にKeyBindingを再登録

---

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

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

### 推奨読解順序

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

ホットキー管理で使用される型定義を先に把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | KeyGesture.cs | `src/Avalonia.Base/Input/KeyGesture.cs` | Key + KeyModifiersの組み合わせ |
| 1-2 | KeyBinding.cs | `src/Avalonia.Base/Input/KeyBinding.cs` | KeyGestureとICommandの関連付け |

**読解のコツ**: KeyGestureはCtrl+Sのようなショートカットキーの組み合わせを表現。KeyBindingはKeyGestureとコマンドを紐付ける。

#### Step 2: HotkeyManagerクラスを理解する

添付プロパティとManagerクラスの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | HotkeyManager.cs | `src/Avalonia.Controls/HotkeyManager.cs` | HotKey添付プロパティ、Managerネストクラス |

**主要処理フロー**:
1. **11-12行目**: HotKeyProperty添付プロパティ定義
2. **14-75行目**: HotkeyCommandWrapperネストクラス（ICommand実装）
3. **78-142行目**: Managerネストクラス（登録・解除ロジック）
4. **144-160行目**: 静的コンストラクタ（プロパティ変更監視）

#### Step 3: コマンドラッパーを理解する

HotkeyCommandWrapperの動作を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | HotkeyManager.cs | `src/Avalonia.Controls/HotkeyManager.cs` | HotkeyCommandWrapper内部クラス |

**主要処理フロー**:
- **23-37行目**: GetCommand - ICommandSourceのコマンドまたはself取得
- **39-54行目**: CanExecute - 有効状態チェック
- **56-68行目**: Execute - コマンド実行またはRaiseClick

#### Step 4: Managerライフサイクルを理解する

ManagerクラスのInit/Register/Unregisterフローを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | HotkeyManager.cs | `src/Avalonia.Controls/HotkeyManager.cs` | Manager.Init/OnParentChanged/Register/Unregister |

**主要処理フロー**:
- **94-98行目**: Init - HotKeyとTopLevel監視開始
- **100-105行目**: OnParentChanged - TopLevel変更時の再登録
- **120-125行目**: Unregister - KeyBinding削除
- **127-133行目**: Register - KeyBinding追加

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

```
HotKeyProperty.Changed (静的コンストラクタで登録)
    │
    └─ new Manager(control).Init()
           │
           ├─ HotKeyProperty監視
           │      └─ OnHotkeyChanged
           │             ├─ null: Stop()
           │             └─ 非null: Unregister → Register
           │
           └─ TopLevel監視 (AncestorFinder)
                  └─ OnParentChanged
                         ├─ Unregister (旧TopLevel)
                         └─ Register (新TopLevel)
                                │
                                └─ _root.KeyBindings.Add(_binding)

キー押下時:
TopLevel.KeyBindings
    │
    └─ KeyBinding.TryHandle
           │
           └─ HotkeyCommandWrapper.Execute
                  │
                  ├─ ICommandSource.Command.Execute
                  └─ IClickableControl.RaiseClick
```

### データフロー図

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

HotKey="Ctrl+S" ───▶ HotkeyManager ───▶ KeyBinding登録
  (XAML属性)           │                   (TopLevel.KeyBindings)
                       ├─ Manager作成
                       └─ TopLevel監視

ショートカット押下 ───▶ KeyBinding.TryHandle ───▶ コマンド実行
                           │                      または
                           └─ HotkeyCommandWrapper    RaiseClick
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| HotkeyManager.cs | `src/Avalonia.Controls/HotkeyManager.cs` | ソース | メインクラス、添付プロパティ |
| KeyGesture.cs | `src/Avalonia.Base/Input/KeyGesture.cs` | ソース | ショートカットキー定義 |
| KeyBinding.cs | `src/Avalonia.Base/Input/KeyBinding.cs` | ソース | キーバインディング |
| ICommandSource.cs | `src/Avalonia.Base/Input/ICommandSource.cs` | ソース | コマンドソースインターフェース |
| IClickableControl.cs | `src/Avalonia.Base/Input/IClickableControl.cs` | ソース | クリック可能コントロール |
| TopLevel.cs | `src/Avalonia.Controls/TopLevel.cs` | ソース | キーバインディング保持 |
| AncestorFinder.cs | `src/Avalonia.Controls/Utils/AncestorFinder.cs` | ソース | 祖先要素監視ユーティリティ |
