# TextInput

> टेक्स्ट प्रविष्टि का अमूर्त आधार — cursor, चयन, clipboard, फ़ोकस और कीबोर्ड, TextField और TextArea में समान।

Source: https://crossfly.dev/hi/docs/ui/widgets/textinput — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# TextInput

`TextInput` वह **अमूर्त वर्ग** है जो [`TextField`](/docs/ui/widgets/textfield) (एक पंक्ति) और [`TextArea`](/docs/ui/widgets/textarea) (बहुपंक्ति) के बीच साझा संपूर्ण संपादन तर्क को केंद्रित करता है: cursor, चयन, clipboard, फ़ोकस/blink, कीबोर्ड शॉर्टकट, तीरों द्वारा नेविगेशन, `ActionSheet` के साथ long-touch और वर्चुअल कीबोर्ड के साथ एकीकरण। उपवर्ग स्थानिक मैपिंग (1D बनाम 2D), रोलिंग, रेंडरिंग और मास्क लागू करते हैं।

आप `TextInput` को सीधे **instantiate नहीं करते** — आप `TextField` या `TextArea` को instantiate करते हैं। यह पृष्ठ उसका सिंहावलोकन है जो दोनों विरासत में लेते हैं। यह `UIConstants.TextInputComponent` (`setText`/`getText`/`isPassword`/`replaceText`/`keyboardHidden`/`getCursorPos`/`hasFocus`) लागू करता है।

> 🟡 · **पैकेज:** `dev.crossfly.ui` · **विस्तार करता है:** `Component` · **लागू करता है:** `UIConstants.TextInputComponent` · **अमूर्त**

## कब उपयोग करें
- किसी भी प्रविष्टि फ़ील्ड को संदर्भित करते समय **साझा प्रकार** के रूप में (`TextInput campo = new TextField(...)`)।
- ऐसा कोड लिखते समय जो cursor/चयन/clipboard पर काम करता है बिना यह परवाह किए कि वह 1 पंक्ति है या N।

## कब उपयोग न करें
- किसी ठोस फ़ील्ड को instantiate करने के लिए → [`TextField`](/docs/ui/widgets/textfield) (1 पंक्ति) या [`TextArea`](/docs/ui/widgets/textarea) (बहुपंक्ति) उपयोग करें।

## पदानुक्रम
`Component` → **`TextInput`** (अमूर्त) → [`TextField`](/docs/ui/widgets/textfield) / [`TextArea`](/docs/ui/widgets/textarea)। constructor buffer की प्रारंभिक क्षमता लेता है: `TextInput(int initialCapacity)`। यह `isPressable() → true` है।

## आंतरिक अवस्था (मुख्य फ़ील्ड)
| फ़ील्ड | प्रकार | अर्थ |
|---|---|---|
| `chars` | `StringBuffer` | टेक्स्ट का कच्चा buffer |
| `text` | `String` | प्रदर्शित टेक्स्ट (उपवर्ग द्वारा अद्यतन; `""` से शुरू) |
| `insertPos` | `int` | cursor की स्थिति (सम्मिलन) |
| `startSelectPos` | `int` | चयन का आरंभ, या चयन न होने पर `-1` |
| `cursorShowing` | `boolean` | cursor blink का दृश्य चरण |
| `keyboardCanOpen` | `boolean` | अगले touch-up पर कीबोर्ड खुल सकता है |
| `hasFocus` | `boolean` | कीबोर्ड फ़ोकस है |
| `caption` | `String` | placeholder / फ़्लोटिंग caption |

## विरासत में मिली विधियाँ (cursor, चयन, clipboard)
| विधि | रिटर्न | क्या करता है |
|---|---|---|
| `setText(String)` | `void`* | टेक्स्ट सेट करता है (उपवर्ग द्वारा लागू) |
| `getText()` | `String` | वर्तमान टेक्स्ट (`TextField` में मास्क सहित) |
| `setCursorPos(int start, int end)` | `void` | चयन सेट करता है; यदि `start==end`, तो केवल cursor चलाता है |
| `setCursorPos(int pos)` | `void` | चयन रहित cursor |
| `getCursorPos()` | `int[]` | `[startSelectPos, insertPos]` |
| `getInsertPos()` | `int` | cursor की स्थिति |
| `hasSelection()` | `boolean` | कोई चयनित अंतराल है? |
| `getSelectionStart()` / `getSelectionEnd()` | `int` | स्थितियों का min / max |
| `getTextBuffer()` / `getLength()` | `StringBuffer` / `int` | कच्चा buffer / आकार |
| `clipboardCopy()` / `clipboardCut()` | `void` | चयन कॉपी / कट करता है (`Device.clipboard*` के माध्यम से) |
| `clipboardPaste()` / `clearText()` | `void` | **अमूर्त** — उपवर्ग मास्क/`\n` संभालता है |
| `mapKeys(String from, String to)` | `void` | वर्ण-दर-वर्ण remapping (आकार भिन्न होने पर `IllegalArgumentException` फेंकता है; `null`/`null` साफ़ करता है) |
| `hasFocus()` | `boolean` | कीबोर्ड फ़ोकस है |
| `restoreFocusAtEnd()` | `void` | फ़ोकस पुनः असाइन करता है और cursor को अंत तक ले जाता है (picker/keypad बंद करने के बाद) |

*`setText` `TextComponent` अनुबंध में `void` लौटाता है; `TextField.text(...)`/`TextArea.text(...)` **fluent** संस्करण प्रदान करते हैं जो स्वयं फ़ील्ड लौटाते हैं।

## Callbacks और घटनाएँ
| Callback | कब ट्रिगर होता है |
|---|---|
| `onAction(Action)` (विरासत में) | `onTouchUp` में (कीबोर्ड खुलने के बाद) |
| `onFocus()` / `onBlur()` | फ़ोकस प्राप्ति / हानि (cursor और blink चालू/बंद करता है) |

कोई समर्पित `onChange` नहीं है: परिवर्तनों पर प्रतिक्रिया देने के लिए, क्रिया callback के माध्यम से देखें या `getText()` से पूछें।

## अवस्थाएँ
- **focused:** cursor चालू और झपकता (`cursorShowing`), स्पर्श पर कीबोर्ड/`Keypad` खुलता है; `onFocus()`/`onBlur()` संक्रमण नियंत्रित करते हैं।
- **selection:** अंतराल `[startSelectPos, insertPos]`; long-touch सब कुछ चुनता है और `ActionSheet` (Copy/Cut/Paste/Clear) खोलता है।
- **disabled / read-only:** शैली में `setEnabled(false)` या `editable=false` संपादन रोकते हैं।

## कुंजियाँ (`onKeyDown` से विरासत में)
- **Ctrl+C / V / X** → कॉपी / पेस्ट / कट; **Ctrl+A** → सब कुछ चुनें।
- **Backspace / Delete** → चयन या एक वर्ण मिटाता है।
- **Left / Right / Home / End** → cursor चलाता है; **Shift** के साथ चयन बढ़ाता है।

## पूरा उदाहरण (कॉपी करें, पेस्ट करें और चलाएँ)
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;

/** चलाने योग्य मुख्य स्क्रीन। launcher (classname) की ओर संकेत करें और चलाएँ: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // बहुरूपी संदर्भ: TextInput, TextField/TextArea का अमूर्त आधार है
      TextInput campo = new TextField("valor inicial");
      add(LAY_AUTO, (Component) campo);

      // आउटपुट Label
      Label saida = new Label("Leia o campo com o botão");
      add(LAY_AUTO, saida);

      // हर कुंजी पर इवेंट नहीं है: भेजते समय getText() पढ़ें
      Button enviar = new Button("Enviar")
         .onAction(c -> saida.setText("Você digitou: " + campo.getText()));
      add(LAY_AUTO, enviar);
   }
}
```

> नीचे के अंश **केवल मूल भाग** दिखाते हैं (जो `onShow()` के अंदर जाता है)। चलाने के लिए, उन्हें ऊपर दिए `MainWindow` कंकाल में रखें।

## उदाहरण (आधार प्रकार का उपयोग)
```java
// ठोस फ़ील्ड का बहुरूपी संदर्भ
TextInput campo = new TextField("valor inicial");
container.add(LAY_AUTO, (Component) campo);

// आधार वर्ग के जरिए सामान्य ऑपरेशन
if (campo.hasSelection())
   campo.clipboardCopy();
int[] sel = campo.getCursorPos();     // [start, insert]
campo.setCursorPos(campo.getLength()); // कर्सर अंत में
```

## अच्छे अभ्यास
- जब कोड स्वरूप (1 बनाम N पंक्तियाँ) पर निर्भर न हो, तो `TextInput`/`UIConstants.TextInputComponent` के विरुद्ध प्रोग्राम करें।
- किसी picker/`Keypad` को बंद करने के बाद, फ़ोकस सही ढंग से लौटाने के लिए `restoreFocusAtEnd()` कॉल करें।

## सामान्य गलतियाँ
- **`TextInput` को instantiate करने का प्रयास:** यह अमूर्त है — `TextField`/`TextArea` उपयोग करें।
- **आधार में `clipboardPaste()`/`clearText()` के काम करने की अपेक्षा:** ये अमूर्त हैं; व्यवहार उपवर्ग से आता है (`TextField` में मास्क, `TextArea` में `\n`)।

## यह भी देखें
- क्षेत्र गाइड: [`ui/`](/docs/ui) · रेसिपी: [`cookbook/`](/docs/cookbook)
- अवधारणा (फ़ोकस, प्रविष्टि घटनाएँ): [`concepts/`](/docs/concepts)
- संबंधित घटक: [`TextField`](/docs/ui/widgets/textfield) · [`TextArea`](/docs/ui/widgets/textarea) · [`Keypad`](/docs/ui/widgets/keypad)
