# 機能設計書 120-InputText

## 概要

本ドキュメントは、Dear ImGuiライブラリにおけるテキスト入力ボックス機能「InputText」の設計を詳細に記述したものである。

### 本機能の処理概要

InputTextは、ユーザーが文字列を入力・編集できるテキスト入力フィールドウィジェットを作成する機能である。単一行のテキスト入力をサポートし、カーソル移動、テキスト選択、コピー&ペースト、Undo/Redoなどの一般的なテキスト編集機能を提供する。内部的にはstb_textedit.hライブラリを使用している。

**業務上の目的・背景**：テキスト入力は最も基本的なユーザー入力形式の一つである。名前、パス、検索クエリ、コマンドなど、文字列による入力が必要な場面は非常に多い。InputTextは、プラットフォームに依存しない高機能なテキスト入力インターフェースを提供し、コンソールウィンドウ、プロパティエディタ、検索フィールドなど多様なユースケースに対応する。

**機能の利用シーン**：
- ファイル名やパスの入力
- 検索フィールドやフィルター
- プロパティエディタでの文字列値の編集
- コンソールやコマンドラインインターフェース
- ユーザー名やパスワードの入力

**主要な処理内容**：
1. ウィンドウとスタイルの取得、ウィジェットIDの生成
2. フレーム領域とラベル領域の計算
3. マウスホバーとクリック検出によるアクティブ状態の制御
4. stb_texteditライブラリによるテキスト編集処理
5. キーボード入力の処理（文字入力、編集コマンド）
6. テキストの描画（選択範囲、カーソル含む）

**関連システム・外部連携**：本機能は単体で動作するが、コールバック機能を通じて外部処理と連携可能。また、クリップボード操作はプラットフォームバックエンドと連携する。

**権限による制御**：ImGuiInputTextFlags_ReadOnlyフラグにより読み取り専用モードを設定可能。ImGuiInputTextFlags_Passwordフラグによりパスワード入力モードを設定可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Demo Window | 補助機能 | テキスト入力ボックスの表示 |
| 10 | Console | 主機能 | コマンド入力テキストボックス |
| 13 | Property Editor | 補助機能 | テキストプロパティの編集 |
| 23 | Widgets | 主機能 | テキスト入力のデモ |

## 機能種別

インタラクティブウィジェット / テキスト入力処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| label | const char* | Yes | ウィジェットのラベル（ID生成にも使用） | NULL不可 |
| buf | char* | Yes | 編集対象の文字列バッファ | NULL不可、NULL終端必須 |
| buf_size | size_t | Yes | バッファのサイズ（NULL終端含む） | 1以上 |
| flags | ImGuiInputTextFlags | No | 動作制御フラグ（デフォルト: 0） | 有効なフラグの組み合わせ |
| callback | ImGuiInputTextCallback | No | コールバック関数（デフォルト: NULL） | 関数ポインタまたはNULL |
| user_data | void* | No | コールバックに渡すユーザーデータ（デフォルト: NULL） | 任意 |

### 入力データソース

ユーザーからのキーボード入力、マウス操作（クリック、ドラッグによる選択）、クリップボード。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | bool | 値が変更された場合true（デフォルト）、またはEnter押下時true（EnterReturnsTrue時） |
| buf | char* | 更新された文字列（bufが指す領域） |

### 出力先

呼び出し元への戻り値、およびbufが指すバッファへの文字列の書き込み。

## 処理フロー

### 処理シーケンス

```
1. InputTextExを呼び出し
   └─ hint = NULL, size = (0,0), 単一行モード
2. InputTextEx内部処理
   ├─ ウィンドウ取得とスキップ判定
   ├─ ID生成と領域計算
   ├─ ItemSizeとItemAddの呼び出し
   ├─ アクティブ状態の管理
   │     ├─ 初期化時: テキストバッファのコピー、カーソル位置設定
   │     └─ アクティブ時: stb_textedit状態の管理
   ├─ マウス入力処理
   │     ├─ クリック: カーソル位置設定
   │     ├─ ダブルクリック: 単語選択
   │     ├─ トリプルクリック: 行選択
   │     └─ ドラッグ: テキスト選択
   ├─ キーボード入力処理
   │     ├─ 文字入力: 文字挿入
   │     ├─ 矢印キー: カーソル移動
   │     ├─ Ctrl+A: 全選択
   │     ├─ Ctrl+C/X/V: コピー/カット/ペースト
   │     ├─ Ctrl+Z/Y: Undo/Redo
   │     └─ Enter: 確定（単一行時）
   ├─ テキスト描画
   │     ├─ 選択範囲の描画
   │     ├─ テキストの描画
   │     └─ カーソルの描画（点滅）
   └─ コールバック処理（必要時）
3. 結果を返却
```

### フローチャート

```mermaid
flowchart TD
    A[InputText呼び出し] --> B[InputTextEx呼び出し]
    B --> C{window->SkipItems?}
    C -->|Yes| D[return false]
    C -->|No| E[ID生成と領域計算]
    E --> F[ItemSize/ItemAdd]
    F --> G{クリックまたはNav?}
    G -->|Yes| H[アクティブ化]
    H --> I[テキストバッファ初期化]
    G -->|No| J{既にアクティブ?}
    J -->|No| K[非アクティブ描画]
    J -->|Yes| L[マウス入力処理]
    I --> L
    L --> M[キーボード入力処理]
    M --> N[テキスト描画]
    N --> O[カーソル描画]
    O --> P{コールバック必要?}
    P -->|Yes| Q[コールバック呼び出し]
    P -->|No| R[バッファ更新]
    Q --> R
    K --> R
    R --> S[return value_changed]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-120-1 | バッファサイズ | 入力テキストはbuf_size-1文字まで（NULL終端分を確保） | 常時 |
| BR-120-2 | UTF-8 | 入力テキストはUTF-8エンコーディング | 常時 |
| BR-120-3 | 単一行 | InputTextは単一行のみ（複数行はInputTextMultiline） | 常時 |
| BR-120-4 | パスワードモード | Passwordフラグ設定時、全文字を'*'で表示 | Passwordフラグ設定時 |
| BR-120-5 | 読み取り専用 | ReadOnlyフラグ設定時、編集不可 | ReadOnlyフラグ設定時 |
| BR-120-6 | 文字フィルター | CharsDecimal/CharsHexadecimal等のフラグで入力文字を制限 | フィルターフラグ設定時 |

### 計算ロジック

テキストサイズの計算：
```
text_size = CalcTextSize(text, text_end)
```

カーソル位置の計算（stb_textedit使用）：
```
cursor_pos = stb_textedit_click(state, x, y)
```

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | アサーション | bufがNULLの場合 | 有効なバッファを渡す |
| - | アサーション | CallbackResizeフラグ時にcallbackがNULL | コールバック関数を設定する |
| - | アサーション | Multilineフラグが設定された場合 | InputTextMultilineを使用する |

### リトライ仕様

本機能はユーザー入力ウィジェットであり、リトライは適用されない。

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

本機能はトランザクション処理を行わない。

## パフォーマンス要件

フレームごとに呼び出されるため、軽量な処理が求められる。長いテキストの場合もstb_texteditによる効率的な処理が行われる。

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

- パスワード入力にはPasswordフラグを使用し、表示を隠蔽する
- バッファオーバーフロー対策としてbuf_sizeで制限
- クリップボード操作はプラットフォームバックエンドを通じて行われる

## 備考

- std::string用のラッパーはmisc/cpp/imgui_stdlib.hで提供される
- InputTextMultilineは複数行入力に対応
- InputTextWithHintはプレースホルダーテキストを表示可能
- コールバック機能を使用してオートコンプリートやバリデーションを実装可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | ImGuiInputTextFlags列挙型（1247-1282行目） |
| 1-2 | imgui.h | `imgui.h` | ImGuiInputTextCallbackData構造体（2633-2659行目） |
| 1-3 | imgui_internal.h | `imgui_internal.h` | ImGuiInputTextState構造体 |
| 1-4 | imstb_textedit.h | `imstb_textedit.h` | stb_texteditの状態管理構造体 |

**読解のコツ**: ImGuiInputTextFlagsの各フラグがどのような動作を制御するかを把握することが重要。特にCallbackXXXフラグとCharsXXXフラグは頻繁に使用される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui_widgets.cpp | `imgui_widgets.cpp` | InputText関数（3952-3956行目） |

**主要処理フロー**:
1. **3954行目**: MultilineフラグがないことをAssert
2. **3955行目**: InputTextExへの委譲

#### Step 3: 実際の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_widgets.cpp | `imgui_widgets.cpp` | InputTextEx関数（4657行目以降） |
| 3-2 | imgui_widgets.cpp | `imgui_widgets.cpp` | stb_texteditコールバック関数群（3982-4249行目） |

**主要処理フロー**:
- **4657-4668行目**: 入力パラメータの検証（アサーション）
- **4674-4738行目**: 領域計算とItemAdd
- **4740-4896行目**: アクティブ状態の管理と初期化
- **4929-5006行目**: マウス入力処理（クリック、ダブルクリック、ドラッグ）
- **5007行目以降**: キーボード入力処理、描画、コールバック

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

```
InputText (imgui_widgets.cpp:3952)
    │
    └─ InputTextEx (imgui_widgets.cpp:4657)
           │
           ├─ GetCurrentWindow()
           ├─ CalcItemSize()
           ├─ ItemSize() / ItemAdd()
           ├─ GetInputTextState()
           │
           ├─ [アクティブ時の処理]
           │     ├─ マウス処理
           │     │     ├─ stb_textedit_click()
           │     │     └─ stb_textedit_drag()
           │     │
           │     └─ キーボード処理
           │           ├─ state->OnKeyPressed()
           │           │     └─ stb_textedit_key()
           │           └─ state->OnCharPressed()
           │                 └─ stb_textedit_text()
           │
           ├─ [描画処理]
           │     ├─ RenderFrame()
           │     ├─ RenderTextClipped() [選択範囲]
           │     ├─ RenderText() [テキスト]
           │     └─ DrawList->AddLine() [カーソル]
           │
           └─ [コールバック処理]
                 └─ callback(ImGuiInputTextCallbackData)
```

### データフロー図

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

buf (文字列バッファ)
       │
       ▼
クリック ──────────────▶ stb_textedit_click ────▶ カーソル位置
       │
キー入力 ──────────────▶ stb_textedit_key ─────▶ テキスト編集
       │                       │
文字入力 ──────────────▶ stb_textedit_text ────▶ 文字挿入
       │                       │
       │                       ▼
       │              InputTextState.TextA
       │                       │
       │                       ▼
       │              [コールバック処理]
       │                       │
       └───────────────────────▶ buf (更新)
                                    │
                                    ▼
                              画面描画
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | InputText関数宣言、ImGuiInputTextFlags/CallbackData定義 |
| imgui_internal.h | `imgui_internal.h` | ヘッダー | ImGuiInputTextState定義 |
| imgui_widgets.cpp | `imgui_widgets.cpp` | ソース | InputText/InputTextEx実装 |
| imstb_textedit.h | `imstb_textedit.h` | ヘッダー | stb_texteditライブラリ |
| misc/cpp/imgui_stdlib.h | `misc/cpp/imgui_stdlib.h` | ヘッダー | std::string用ラッパー宣言 |
| misc/cpp/imgui_stdlib.cpp | `misc/cpp/imgui_stdlib.cpp` | ソース | std::string用ラッパー実装 |
