# Keypad

> Numeric keypad/calculator window that anchors to a focused TextField.

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

# Keypad

`Keypad` is a **window** (`Window`) with a numeric keypad that anchors above or below the focused text field. When in calculator mode (`isCalculator`), it adds a 4th column with `+ − × ÷ =` and resolves the typed arithmetic, writing the result back into the field.

Usage is almost always **indirect**: you configure `Keyboard.KEYPAD`/`CALCULATOR` (or `EditMode.CURRENCY`) on the [`TextField`](/docs/ui/widgets/textfield) and the field itself instantiates and displays the `Keypad` when it gains focus. Instantiating it manually is rare.

> 🔴 · **Package:** `dev.crossfly.ui` · **Extends:** `Window` · **Style:** `KeypadStyle`

## When to use
- Embedded numeric input (without relying on the native keyboard), including on desktop.
- Calculator mode: let the user do math inside a monetary/numeric field.

## When NOT to use
- Free text input → leave it to the native keyboard (`Keyboard.DEFAULT`).
- You rarely instantiate `Keypad` directly — configure the keyboard on the [`TextField`](/docs/ui/widgets/textfield).

## Appearance
Grid of buttons (`GridLayout`): 3 columns (0–9, backspace, enter) or 4 columns in calculator mode (with operators). The buttons use `keyWidth`/`keyHeight` (× font height) and rounded corners on all four corners. The window positions itself below the field if it fits, otherwise above (aware of the floating caption).

``

## Complete example (copy, paste and run)
```java
package com.exemplo;

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

/** Runnable main screen. Point the launcher (classname) and run: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // Numeric field that will receive the Keypad keys
      TextField valor = new TextField().caption("Quantidade");
      add(LAY_AUTO, valor);

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

      // Button that opens the Keypad anchored to the field (direct use)
      Button abrir = new Button("Abrir keypad").onAction(c -> {
         Keypad kp = new Keypad(valor);   // target is the TextField above
         kp.show();
      });
      add(LAY_AUTO, abrir);

      // The Keypad writes to the field; read getText() on submit
      Button confirmar = new Button("Confirmar")
         .onAction(c -> saida.setText("Valor: " + valor.getText()));
      add(LAY_AUTO, confirmar);
   }
}
```

> The snippets below show **only the core** (what goes inside `onShow()`). To run them, place them in the `MainWindow` skeleton above.

## Basic usage (indirect, via TextField)
```java
// The TextField shows the Keypad by itself on focus:
TextField valor = new TextField().caption("Quantidade");
valor.setKeyboard(Keyboard.KEYPAD);      // embedded numeric keyboard
container.add(LAY_AUTO, valor);

// Calculator mode — CURRENCY already uses CALCULATOR by default:
TextField preco = new TextField().caption("Preço");
preco.setMode(EditMode.CURRENCY, true);
container.add(LAY_AUTO, preco);
```

## Direct usage (advanced)
```java
// Manually anchor a Keypad to a field:
Keypad kp = new Keypad(campo);   // field is a TextInput (TextField/TextArea)
kp.show();

// In calculator mode:
Keypad calc = new Keypad(campo);
calc.<KeypadStyle>getStyle().isCalculator(true);
calc.show();
```

## Constructors
| Constructor | Description |
|---|---|
| `Keypad(TextInput target)` | creates the keypad anchored to the `target` field that will receive the keys |

## Properties and customization (via `KeypadStyle`)
| Property | Type | What it does |
|---|---|---|
| `.isCalculator(boolean)` | `boolean` | 4th column with `+ − × ÷` and an `=` button |
| `.is1to9(boolean)` | `boolean` | key order (1-2-3 at the top vs 7-8-9) |
| `.keyWidth` / `.keyHeight` | `float` | key size (× font height) |
| `.digitColor` / `.specialColor` | ARGB | color of digits / special keys |
| `.keypadBackColor` | ARGB | key background |
| `.enterIcon` / `.backspaceIcon` | `Icon` | enter and backspace icons |
| `.radiusTL/TR/BL/BR` | `float` | corner radii |

## Callbacks and events
`Keypad` does not expose its own `onAction`. It sends the keys to the `target`:
- Digits → `target.onKeyTyped(c)`.
- Backspace / Enter → `target.onKeyDown(Input.Keys.BACKSPACE / ENTER)`.
- In calculator mode, `=` calculates and writes the result via `target.setText(...)`.
- On close (`onRemove`), focus returns to the field with `restoreFocusAtEnd()`.

To react, observe the **field** (`getText()`), not the `Keypad`.

## States
- **Enter ↔ Equals:** in calculator mode, the bottom button toggles between `Enter` (icon) and `=` (text) depending on whether there is a pending operation.
- The window closes when tapping outside or on confirming (`Enter`).

### Monetary field with embedded calculator
```java
TextField total = new TextField().caption("Total");
total.setMode(EditMode.CURRENCY, true);   // opens the Keypad in calculator mode
container.add(LAY_AUTO, total);
// The user types "10 + 5 =" and the field then shows 15.00.
```

### Force the Keypad on desktop
```java
// NUMERIC on desktop falls back to KEYPAD automatically in showInput();
// to ensure the Keypad on any platform, use KEYPAD explicitly:
TextField codigo = new TextField().caption("Código");
codigo.setKeyboard(Keyboard.KEYPAD);
container.add(LAY_AUTO, codigo);
```

## Best practices
- Prefer **configuring the keyboard on the `TextField`** (`setKeyboard`/`setMode`) over instantiating `Keypad` directly.
- For monetary input, `EditMode.CURRENCY` already brings the calculator — no further configuration is needed.

## Common mistakes
- **Registering `onAction` on the `Keypad`:** it does not fire its own action; observe the target field.
- **Instantiating `Keypad` without a focusable `target`:** it needs a `TextInput` to send the keys to.

## See also
- Area guide: [`ui/`](/docs/ui) · Recipes: [`cookbook/`](/docs/cookbook)
- Concept (virtual keyboard, focus): [`concepts/`](/docs/concepts)
- Related components: [`TextField`](/docs/ui/widgets/textfield) · [`TextInput`](/docs/ui/widgets/textinput) · [`TextArea`](/docs/ui/widgets/textarea)
