# Hint

> 非模态的短暂通知，用来替代 Toast 与 ToolTip，显示后会自行消失。

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

# Hint

`Hint` 是 CrossFly 的**非模态**短暂通知：通常出现在屏幕底部附近，显示一条简短消息，并在一段时间后自行消失（带淡出）。它不会阻止与 UI 其余部分的交互。它是旧 `Toast` 的现代化替代品 —— **相同的 API** —— 同时也覆盖了旧 `ToolTip` 的场景（两者均已从框架中移除）。

`Hint` **不继承 `Window`**：它是一个带**静态** API 的工具类，内部会创建一个 `ToastWindow`。

> 🟢 · **包：** `dev.crossfly.ui` · **继承：** —（静态工具类） · **配置：** 静态字段

## 何时使用
- 被动且简短的反馈："已保存！"、"连接失败"、"已复制"。
- 不需要用户操作的临时状态。

## 何时不要使用
- 需要决策/确认的场景 → 使用 [`Alert`](/docs/ui/widgets/alert) 或 [`ActionSheet`](/docs/ui/widgets/actionsheet)。

## 外观
深色圆角胶囊（默认 `0xFF303030`，白色文本），水平居中，定位在屏幕约 85% 高度处。以柔和的淡入淡出出现和消失。

## 完整示例（复制、粘贴并运行）
```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());

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

      // Hint 是静态的：由一个 Button 在 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);
   }
}
```

> 下面的片段只展示**核心部分**（放入 `onShow()` 内的内容）。要运行它们，请将其放入上面的 `MainWindow` 骨架中。

## 基本用法
```java
// 消息显示 2 秒，然后自动消失
Hint.show("Salvo com sucesso!", 2000);
```

## 显示 API（静态）
| 重载 | 描述 |
|---|---|
| `Hint.show(String message, int delay)` | 默认位置/padding。 |
| `Hint.show(String message, int delay, Window parentWindow)` | 定义父窗口。 |
| `Hint.show(String message, int delay, Window parentWindow, Relative at, Gap innerGap)` | 完整形式：垂直位置（`at`）和内部 padding（`innerGap`）。 |

前两个重载会委托给第三个，缺失的字段传 `null`。

| 参数 | 类型 | 含义 |
|---|---|---|
| `message` | `String` | 文本。**`null` 会隐藏**当前 hint。 |
| `delay` | `int` | 可见毫秒数。`INFINITE`/`INFINITE_NOANIM` 使其保持在屏幕上。 |
| `parentWindow` | `Window` | 可选父窗口；默认 = 顶层窗口。 |
| `at` | `Relative` | `START`（顶部）/ `CENTER` / `END`（底部）或相对值。`null` 使用 `position`。 |
| `innerGap` | `Gap` | 内部 padding。`null` 使用静态 `ingap`。 |

## 全局配置（静态字段）
所有外观都由共享的静态字段控制 —— **修改它们会影响后续所有 hint**。

| 字段 | 类型 | 默认值 | 作用 |
|---|---|---|---|
| `Hint.backColor` | `int` | `0xFF303030` | 背景色。 |
| `Hint.foreColor` | `int` | `WHITE` | 文本颜色。 |
| `Hint.position` | `Relative` | `Relative.ofScreen(0.85f)` | 默认垂直位置。 |
| `Hint.ingap` | `Gap` | `Gap.ofFont(0.7f, 0.35f, 0.7f, 0.35f)` | 默认内部 padding。 |
| `Hint.font` | `Font` | `Font.get().bold()` | 文本字体。 |
| `Hint.fade` | `int` | `200` | 动画模式下的目标 alpha 值。 |
| `Hint.INFINITE` | `int` | `Integer.MAX_VALUE` | 无限时长**带**动画。 |
| `Hint.INFINITE_NOANIM` | `int` | `Integer.MIN_VALUE` | 无限时长**无**动画。 |

## 状态
- 当 `delay` 有限时按时间自动消失。
- 使用 `INFINITE`/`INFINITE_NOANIM` 时持久显示 —— 需通过 `Hint.show(null, 0)` 手动关闭。
- Hint **不会堆叠**：新的会替代当前的。

### 顶部红色错误提示，并恢复静态字段
```java
Hint.backColor = 0xFFB00020;
Hint.show("Falha ao salvar", 2500, null, Relative.START, null);
Hint.backColor = 0xFF303030; // 为后续提示恢复默认值
```

### 持久 Hint 与手动移除
```java
Hint.show("Conectando...", Hint.INFINITE);
// ... 结束时：
Hint.show(null, 0); // message == null 隐藏当前提示
```

### 通过 Gap 自定义 padding
```java
Hint.show("Detalhes copiados", 1800, null, Relative.CENTER, Gap.ofFont(1f, 0.5f, 1f, 0.5f));
```

## 最佳实践
- 用于被动且简短的反馈；绝不用于决策。
- 对于临时性的调整，优先在调用中传递 `at`/`innerGap`，而不是修改静态字段。
- 当全局修改某个静态字段（如 `backColor`）时，请在之后**恢复**它，以免泄漏状态。

## 常见错误
- **`INFINITE` 未关闭** —— 会永远停留在屏幕上；请用 `Hint.show(null, ...)` 关闭。
- **没有顶层窗口**（栈为空）—— hint 根本不会出现。
- **期望 hint 累积** —— 不会；新的会替代旧的。

## 迁移（Toast/ToolTip 已移除）
`Toast.show(...)` 1:1 迁移到 `Hint.show(...)`（相同的签名和静态字段）。`ToolTip` 没有直接替代品（不再有长按）—— 如需短暂提示，请使用通过 `at`/`position` 定位的 `Hint`。

## 另请参阅
- 领域指南：[`ui/`](/docs/ui) · 食谱：[`cookbook/`](/docs/cookbook)
- 相关组件：[`Alert`](/docs/ui/widgets/alert) · [`ActionSheet`](/docs/ui/widgets/actionsheet)
