# Keypad

> Ventana de teclado numérico/calculadora que se ancla a un TextField enfocado.

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

# Keypad

`Keypad` es una **ventana** (`Window`) con un teclado numérico que se ancla arriba o abajo del campo de texto enfocado. Cuando está en modo calculadora (`isCalculator`), añade una 4.ª columna con `+ − × ÷ =` y resuelve la aritmética digitada, escribiendo el resultado de vuelta en el campo.

El uso es casi siempre **indirecto**: configuras `Keyboard.KEYPAD`/`CALCULATOR` (o `EditMode.CURRENCY`) en el [`TextField`](/docs/ui/widgets/textfield) y el propio campo instancia y muestra el `Keypad` cuando gana el foco. Instanciarlo manualmente es raro.

> 🔴 · **Paquete:** `dev.crossfly.ui` · **Extiende:** `Window` · **Estilo:** `KeypadStyle`

## Cuándo usar
- Entrada numérica integrada (sin depender del teclado nativo), incluso en escritorio.
- Modo calculadora: permitir que el usuario haga cuentas dentro de un campo monetario/numérico.

## Cuándo NO usar
- Entrada de texto libre → deja el teclado nativo (`Keyboard.DEFAULT`).
- Rara vez instancias `Keypad` directamente — configura el teclado en el [`TextField`](/docs/ui/widgets/textfield).

## Apariencia
Rejilla de botones (`GridLayout`): 3 columnas (0–9, backspace, enter) o 4 columnas en modo calculadora (con operadores). Los botones usan `keyWidth`/`keyHeight` (× altura de la fuente) y esquinas redondeadas en las cuatro puntas. La ventana se posiciona debajo del campo si cabe, si no arriba (consciente del caption flotante).

``

## Ejemplo completo (copiar, pegar y ejecutar)
```java
package com.exemplo;

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

/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // Campo numérico que recibirá las teclas del Keypad
      TextField valor = new TextField().caption("Quantidade");
      add(LAY_AUTO, valor);

      // Label de salida
      Label saida = new Label("Digite no keypad e toque em Confirmar");
      add(LAY_AUTO, saida);

      // Botón que abre el Keypad anclado al campo (uso directo)
      Button abrir = new Button("Abrir keypad").onAction(c -> {
         Keypad kp = new Keypad(valor);   // target es el TextField de arriba
         kp.show();
      });
      add(LAY_AUTO, abrir);

      // El Keypad escribe en el campo; lea getText() en el envío
      Button confirmar = new Button("Confirmar")
         .onAction(c -> saida.setText("Valor: " + valor.getText()));
      add(LAY_AUTO, confirmar);
   }
}
```

> Los fragmentos siguientes muestran **solo el núcleo** (lo que va dentro de `onShow()`). Para ejecutar, colócalos en el esqueleto `MainWindow` de arriba.

## Uso básico (indirecto, vía TextField)
```java
// El TextField muestra el Keypad solo al enfocar:
TextField valor = new TextField().caption("Quantidade");
valor.setKeyboard(Keyboard.KEYPAD);      // teclado numérico embebido
container.add(LAY_AUTO, valor);

// Modo calculadora — CURRENCY ya usa CALCULATOR por defecto:
TextField preco = new TextField().caption("Preço");
preco.setMode(EditMode.CURRENCY, true);
container.add(LAY_AUTO, preco);
```

## Uso directo (avanzado)
```java
// Anclar manualmente un Keypad a un campo:
Keypad kp = new Keypad(campo);   // el campo es un TextInput (TextField/TextArea)
kp.show();

// En modo calculadora:
Keypad calc = new Keypad(campo);
calc.<KeypadStyle>getStyle().isCalculator(true);
calc.show();
```

## Constructores
| Constructor | Descripción |
|---|---|
| `Keypad(TextInput target)` | crea el keypad anclado al campo `target` que recibirá las teclas |

## Propiedades y personalización (vía `KeypadStyle`)
| Propiedad | Tipo | Qué hace |
|---|---|---|
| `.isCalculator(boolean)` | `boolean` | 4.ª columna con `+ − × ÷` y botón `=` |
| `.is1to9(boolean)` | `boolean` | orden de las teclas (1-2-3 arriba vs 7-8-9) |
| `.keyWidth` / `.keyHeight` | `float` | tamaño de las teclas (× altura de la fuente) |
| `.digitColor` / `.specialColor` | ARGB | color de los dígitos / teclas especiales |
| `.keypadBackColor` | ARGB | fondo de las teclas |
| `.enterIcon` / `.backspaceIcon` | `Icon` | iconos de enter y backspace |
| `.radiusTL/TR/BL/BR` | `float` | radios de esquina |

## Callbacks y eventos
`Keypad` no expone `onAction` propio. Envía las teclas al `target`:
- Dígitos → `target.onKeyTyped(c)`.
- Backspace / Enter → `target.onKeyDown(Input.Keys.BACKSPACE / ENTER)`.
- En modo calculadora, `=` calcula y escribe el resultado vía `target.setText(...)`.
- Al cerrar (`onRemove`), el foco vuelve al campo con `restoreFocusAtEnd()`.

Para reaccionar, observa el **campo** (`getText()`), no el `Keypad`.

## Estados
- **Enter ↔ Equals:** en modo calculadora, el botón inferior alterna entre `Enter` (icono) y `=` (texto) según haya operación pendiente.
- La ventana se cierra al tocar fuera o al confirmar (`Enter`).

### Campo monetario con calculadora integrada
```java
TextField total = new TextField().caption("Total");
total.setMode(EditMode.CURRENCY, true);   // abre el Keypad en modo calculadora
container.add(LAY_AUTO, total);
// El usuario escribe "10 + 5 =" y el campo pasa a mostrar 15,00.
```

### Forzar el Keypad en escritorio
```java
// NUMERIC en desktop cae a KEYPAD automáticamente en showInput();
// para garantizar el Keypad en cualquier plataforma, use KEYPAD explícitamente:
TextField codigo = new TextField().caption("Código");
codigo.setKeyboard(Keyboard.KEYPAD);
container.add(LAY_AUTO, codigo);
```

## Buenas prácticas
- Prefiere **configurar el teclado en el `TextField`** (`setKeyboard`/`setMode`) a instanciar `Keypad` directamente.
- Para entrada monetaria, `EditMode.CURRENCY` ya trae la calculadora — no hace falta configurar nada más.

## Errores comunes
- **Registrar `onAction` en el `Keypad`:** no dispara acción propia; observa el campo objetivo.
- **Instanciar `Keypad` sin un `target` enfocable:** necesita un `TextInput` para enviar las teclas.

## Ver también
- Guía del área: [`ui/`](/docs/ui) · Recetas: [`cookbook/`](/docs/cookbook)
- Concepto (teclado virtual, foco): [`concepts/`](/docs/concepts)
- Componentes relacionados: [`TextField`](/docs/ui/widgets/textfield) · [`TextInput`](/docs/ui/widgets/textinput) · [`TextArea`](/docs/ui/widgets/textarea)
