# 機能設計書 7-TextBox

## 概要

本ドキュメントは、Avaloniaフレームワークにおけるテキスト入力コントロールである`TextBox`の機能設計を記述する。`TemplatedControl`を継承し、テキスト編集、選択、クリップボード操作、Undo/Redo、入力検証などの機能を提供する。

### 本機能の処理概要

`TextBox`クラスは、ユーザーからのテキスト入力を受け付ける基本的なコントロールであり、以下の機能を提供する：
- **テキスト編集**：文字の入力、削除、置換
- **テキスト選択**：マウスドラッグ、Shift+矢印キーによる選択
- **クリップボード操作**：Cut/Copy/Paste
- **Undo/Redo**：操作履歴の管理
- **入力制御**：AcceptsReturn、AcceptsTab、MaxLength
- **表示制御**：TextWrapping、TextAlignment、Watermark
- **パスワードモード**：PasswordCharによる文字隠蔽
- **リビール機能**：パスワードの一時表示

**業務上の目的・背景**：フォーム入力、検索ボックス、ログイン画面など、ほぼすべてのアプリケーションで必要とされる基本的なテキスト入力機能を提供する。

**機能の利用シーン**：
- ログインフォームのユーザー名/パスワード入力
- 検索ボックス
- テキストエディタ
- フォームの各種入力フィールド

**主要な処理内容**：
1. `Text`プロパティによるテキスト管理
2. `SelectionStart`/`SelectionEnd`による選択範囲管理
3. `Cut`/`Copy`/`Paste`メソッドによるクリップボード操作
4. `Undo`/`Redo`メソッドによる履歴操作
5. `TextPresenter`への描画委譲
6. キーボード入力のハンドリング

**関連システム・外部連携**：
- `IClipboard`：クリップボード操作
- `UndoRedoHelper`：Undo/Redo管理
- `TextPresenter`：テキストレンダリング
- `ScrollViewer`：スクロール対応

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| S-01 | LoginWindow | 入力 | ユーザー名/パスワード入力 |

## 機能種別

UIコントロール / テキスト入力

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Text | string? | No | 入力テキスト | TwoWayバインディング |
| AcceptsReturn | bool | No | Enterキーで改行を許可 | デフォルト: false |
| AcceptsTab | bool | No | Tabキーでタブを許可 | デフォルト: false |
| MaxLength | int | No | 最大文字数 | 0で無制限 |
| MaxLines | int | No | 最大行数 | 0で無制限 |
| MinLines | int | No | 最小行数 | デフォルト: 1 |
| IsReadOnly | bool | No | 読み取り専用 | デフォルト: false |
| PasswordChar | char | No | パスワード文字 | 0で無効 |
| Watermark | string? | No | プレースホルダーテキスト | - |
| TextWrapping | TextWrapping | No | 折り返し設定 | デフォルト: NoWrap |
| TextAlignment | TextAlignment | No | テキスト配置 | デフォルト: Left |
| IsUndoEnabled | bool | No | Undo有効 | デフォルト: true |
| UndoLimit | int | No | Undo履歴上限 | デフォルト: 10 |
| RevealPassword | bool | No | パスワード表示 | デフォルト: false |
| InnerLeftContent | object? | No | 左側コンテンツ | - |
| InnerRightContent | object? | No | 右側コンテンツ | - |

### 入力データソース

- キーボード入力
- クリップボードからの貼り付け
- データバインディング
- マウスドラッグ（選択）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| TextChanged | event | テキスト変更時イベント |
| TextChanging | event | テキスト変更前イベント（キャンセル可能） |
| CopyingToClipboard | event | コピー時イベント |
| CuttingToClipboard | event | カット時イベント |
| PastingFromClipboard | event | ペースト時イベント |
| SelectedText | string? | 選択中のテキスト |

### 出力先

- Textプロパティ（バインディングソースへ）
- クリップボード（Copy/Cut時）

## 処理フロー

### 処理シーケンス

```
1. テキスト入力
   └─ OnTextInput
   └─ HandleTextInput
   └─ DeleteSelection（選択範囲がある場合）
   └─ InsertText
   └─ UndoRedoHelper.Snapshot
   └─ RaiseTextChangeEvents

2. キー操作
   └─ OnKeyDown
   └─ キー種別判定（矢印、Home/End、Delete等）
   └─ Shiftキー状態による選択更新
   └─ カーソル/選択範囲更新

3. クリップボード操作
   ├─ Copy: GetSelection → Clipboard.SetText
   ├─ Cut: Copy + DeleteSelection
   └─ Paste: Clipboard.GetText → InsertText

4. Undo/Redo
   └─ UndoRedoHelper.Undo/Redo
   └─ UndoRedoState適用
```

### フローチャート

```mermaid
flowchart TD
    A[テキスト入力] --> B{IsReadOnly?}
    B -->|Yes| C[入力破棄]
    B -->|No| D{選択範囲あり?}
    D -->|Yes| E[DeleteSelection]
    D -->|No| F[InsertText]
    E --> F
    F --> G{MaxLength超過?}
    G -->|Yes| H[切り詰め]
    G -->|No| I[テキスト更新]
    H --> I
    I --> J[UndoSnapshot]
    J --> K[TextChangedイベント]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | MaxLength制約 | 入力/貼り付け時に最大文字数を超えない | MaxLength > 0 |
| BR-02 | MaxLines制約 | 改行数が最大行数を超えない | MaxLines > 0 |
| BR-03 | AcceptsReturn | Enterキーで改行を挿入（falseなら無視） | AcceptsReturn設定 |
| BR-04 | AcceptsTab | Tabキーでタブを挿入（falseならフォーカス移動） | AcceptsTab設定 |
| BR-05 | IsReadOnly | 読み取り専用時はテキスト変更不可（選択・コピーは可能） | IsReadOnly == true |
| BR-06 | PasswordChar | 指定文字でテキストを隠蔽 | PasswordChar != 0 |
| BR-07 | RevealPassword | パスワード文字を一時的に表示 | RevealPassword == true |
| BR-08 | :empty擬似クラス | テキストが空の場合に適用 | Text.Length == 0 |

### 計算ロジック

**SelectedText取得**：
```csharp
get => Text?.Substring(SelectionStart, SelectionEnd - SelectionStart);
set => ReplaceSelection(value);
```

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | クリップボードアクセス失敗 | 例外は捕捉され無視 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 大量テキストの効率的なレンダリング（TextPresenterによる仮想化）
- Undo履歴のメモリ効率（UndoLimit設定）
- キーボード入力のリアルタイム応答

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

- PasswordCharによるパスワード隠蔽
- クリップボードからの貼り付け時のサニタイズなし（アプリ側で対応）

## 備考

- WPFのTextBoxと高い互換性
- テンプレートパーツとしてPART_TextPresenter、PART_ScrollViewerを使用

---

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

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

### 推奨読解順序

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

テキストボックスの基本構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TextBox.cs | `src/Avalonia.Controls/TextBox.cs` | 23-31行目：クラス定義とTemplatePartとPseudoClasses |
| 1-2 | TextBox.cs | `src/Avalonia.Controls/TextBox.cs` | 各種プロパティ定義 |

**読解のコツ**:
- `TemplatedControl`を継承
- `PART_TextPresenter`が必須テンプレートパーツ

#### Step 2: テキスト入力処理を理解する

入力処理フローを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TextBox.cs | `src/Avalonia.Controls/TextBox.cs` | OnTextInputメソッド |
| 2-2 | TextBox.cs | `src/Avalonia.Controls/TextBox.cs` | HandleTextInputメソッド |
| 2-3 | TextBox.cs | `src/Avalonia.Controls/TextBox.cs` | InsertTextメソッド |

**主要処理フロー**:
- テキスト入力時にMaxLength/MaxLinesチェック
- 選択範囲がある場合は置換
- Undo履歴にスナップショット

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

キー操作を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TextBox.cs | `src/Avalonia.Controls/TextBox.cs` | OnKeyDownメソッド |

**主要処理フロー**:
- 矢印キー、Home/End、Delete/Backspace等の処理
- Shift+矢印で選択範囲拡張
- Ctrl+A/C/X/V等のショートカット

#### Step 4: クリップボード操作を理解する

Cut/Copy/Pasteを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TextBox.cs | `src/Avalonia.Controls/TextBox.cs` | Cut/Copy/Pasteメソッド |

**主要処理フロー**:
- Copyでクリップボードにテキスト設定
- Cutでコピー後に選択範囲削除
- Pasteでクリップボードからテキスト挿入

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

```
TextBox
    │
    ├─ TemplatedControl（テンプレート基盤）
    │      └─ Control → InputElement → Layoutable
    │
    ├─ PART_TextPresenter（テキスト描画）
    │      └─ TextLayout
    │
    ├─ PART_ScrollViewer（スクロール）
    │
    ├─ UndoRedoHelper<UndoRedoState>
    │      ├─ Undo
    │      └─ Redo
    │
    └─ IClipboard
           ├─ GetTextAsync
           └─ SetTextAsync
```

### データフロー図

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

キーボード入力
        │
        ▼
   OnTextInput ──────────▶ IsReadOnlyチェック
        │                       │
        ▼                       ▼
   HandleTextInput              MaxLength/MaxLinesチェック
        │                       │
        ▼                       ▼
   InsertText ───────────────▶ Text更新
        │                       │
        ▼                       ▼
   UndoSnapshot ────────────▶ TextChangedイベント
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TextBox.cs | `src/Avalonia.Controls/TextBox.cs` | ソース | テキストボックスコントロール |
| TextPresenter.cs | `src/Avalonia.Controls/Presenters/TextPresenter.cs` | ソース | テキスト描画 |
| UndoRedoHelper.cs | `src/Avalonia.Controls/Utils/UndoRedoHelper.cs` | ソース | Undo/Redo管理 |
| ScrollViewer.cs | `src/Avalonia.Controls/ScrollViewer.cs` | ソース | スクロール対応 |
| IClipboard.cs | `src/Avalonia.Input/Platform/IClipboard.cs` | ソース | クリップボードIF |
