# Hint

> Ephemeral non-modal notification (replaces Toast/ToolTip).

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

# Hint

`Hint` is CrossFly's **non-modal** ephemeral notification: it typically appears near the bottom of the screen, shows a short message and disappears on its own after a while (with a fade). It does not block interaction with the rest of the UI. It is the modernized replacement for the old `Toast` — **same API** — and also covers the case of the old `ToolTip` (both removed from the framework).

`Hint` **does not extend `Window`**: it is a utility class with a **static** API that internally creates a `ToastWindow`.

> 🟢 · **Package:** `dev.crossfly.ui` · **Extends:** — (static utility) · **Config:** static fields

## When to use
- Passive, brief feedback: "Saved!", "Failed to connect", "Copied".
- Transient status that requires no action from the user.

## When NOT to use
- Something that requires a decision/confirmation → use [`Alert`](/docs/ui/widgets/alert) or [`ActionSheet`](/docs/ui/widgets/actionsheet).

## Appearance
Dark rounded capsule (default `0xFF303030`, white text) horizontally centered, positioned at ~85% of the screen height. Appears and disappears with a smooth fade.

## 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());

      Label titulo = new Label("Toque para ver um Hint");
      add(LAY_AUTO, titulo);

      // Hint is static: a Button triggers the ephemeral notification in onAction
      Button salvar = new Button("Salvar")
         .onAction(c -> Hint.show("Salvo com sucesso!", 2000));
      add(LAY_AUTO, salvar);

      Button falhar = new Button("Simular erro")
         .onAction(c -> Hint.show("Falha ao conectar", 2500));
      add(LAY_AUTO, falhar);
   }
}
```

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

## Basic usage
```java
// Message visible for 2 seconds, then disappears on its own
Hint.show("Salvo com sucesso!", 2000);
```

## Display API (static)
| Overload | Description |
|---|---|
| `Hint.show(String message, int delay)` | Default position/padding. |
| `Hint.show(String message, int delay, Window parentWindow)` | Sets the parent window. |
| `Hint.show(String message, int delay, Window parentWindow, Relative at, Gap innerGap)` | Full form: vertical position (`at`) and internal padding (`innerGap`). |

The first two delegate to the third with `null` in the missing fields.

| Parameter | Type | Meaning |
|---|---|---|
| `message` | `String` | Text. **`null` hides** the current hint. |
| `delay` | `int` | Milliseconds visible. `INFINITE`/`INFINITE_NOANIM` keep it on screen. |
| `parentWindow` | `Window` | Optional parent; default = topmost window. |
| `at` | `Relative` | `START`(top) / `CENTER` / `END`(bottom) or a relative value. `null` uses `position`. |
| `innerGap` | `Gap` | Internal padding. `null` uses the static `ingap`. |

## Global configuration (static fields)
The entire appearance is controlled by shared statics — **changing them affects all subsequent hints**.

| Field | Type | Default | What it does |
|---|---|---|---|
| `Hint.backColor` | `int` | `0xFF303030` | Background color. |
| `Hint.foreColor` | `int` | `WHITE` | Text color. |
| `Hint.position` | `Relative` | `Relative.ofScreen(0.85f)` | Default vertical position. |
| `Hint.ingap` | `Gap` | `Gap.ofFont(0.7f, 0.35f, 0.7f, 0.35f)` | Default internal padding. |
| `Hint.font` | `Font` | `Font.get().bold()` | Text font. |
| `Hint.fade` | `int` | `200` | Alpha target in animated mode. |
| `Hint.INFINITE` | `int` | `Integer.MAX_VALUE` | Infinite duration **with** animation. |
| `Hint.INFINITE_NOANIM` | `int` | `Integer.MIN_VALUE` | Infinite duration **without** animation. |

## States
- Auto-dismiss by time when `delay` is finite.
- Persistent with `INFINITE`/`INFINITE_NOANIM` — must be closed manually with `Hint.show(null, 0)`.
- Hints **do not stack**: a new one replaces the current one.

### Error at the top, in red, restoring the static
```java
Hint.backColor = 0xFFB00020;
Hint.show("Falha ao salvar", 2500, null, Relative.START, null);
Hint.backColor = 0xFF303030; // restores the default for the next hints
```

### Persistent hint and manual removal
```java
Hint.show("Conectando...", Hint.INFINITE);
// ... when finished:
Hint.show(null, 0); // message == null hides the current hint
```

### Custom padding via Gap
```java
Hint.show("Detalhes copiados", 1800, null, Relative.CENTER, Gap.ofFont(1f, 0.5f, 1f, 0.5f));
```

## Best practices
- Use it for passive, brief feedback; never for decisions.
- Prefer passing `at`/`innerGap` in the call over mutating the statics, for one-off adjustments.
- When mutating a static globally (e.g. `backColor`), **restore** it afterward to avoid leaking state.

## Common mistakes
- **`INFINITE` without closing** — it stays on screen forever; close it with `Hint.show(null, ...)`.
- **No window on top** (empty stack) — the hint simply does not appear.
- **Expecting hints to accumulate** — they don't; the new one replaces the previous.

## Migration (Toast/ToolTip removed)
`Toast.show(...)` migrates 1:1 to `Hint.show(...)` (same signatures and statics). `ToolTip` has no direct replacement (there is no more press-and-hold) — use a `Hint` positioned with `at`/`position` if you need an ephemeral tip.

## See also
- Area guide: [`ui/`](/docs/ui) · Recipes: [`cookbook/`](/docs/cookbook)
- Related components: [`Alert`](/docs/ui/widgets/alert) · [`ActionSheet`](/docs/ui/widgets/actionsheet)
