# ui

Build widgets and read their values. gamesense-compatible; Lynx adds tabs, popovers, icons, watermark rows, cards, custom draw regions and toasts. A tab or container that does not exist yet is created. Every builder returns a `ScriptHandle`, which goes stale when the menu is rebuilt.

A single-control group renders inline: a slider (or any control) placed alone in a container shows as an ordinary row, not a popover.

## Builders

#### ui.new_checkbox

`ui.new_checkbox(tab: string, container: string, name: string)`: ScriptHandle

Argument | Type | Description
-------- | ---- | -----------
  **tab** | string | Tab name.
  **container** | string | Container (group) name.
  **name** | string | Row label.

A checkbox.

#### ui.new_slider

`ui.new_slider(tab: string, container: string, name: string, min: number, max: number[, initial, show_tooltip, unit, scale, tooltips])`: ScriptHandle

Argument | Type | Description
-------- | ---- | -----------
  **min** | number | Low bound.
  **max** | number | High bound.
  **initial** | number | Starting value.
  **show_tooltip** | boolean | Show the value tooltip.
  **unit** | string | Suffix drawn after the value.
  **scale** | number | Display scale.
  **tooltips** | table | Maps whole values to labels.

A slider over `[min, max]`.

#### ui.new_combobox

`ui.new_combobox(tab: string, container: string, name: string, ...)`: ScriptHandle

A single-select combobox. Options are extra string arguments or one array.

#### ui.new_multiselect

`ui.new_multiselect(tab: string, container: string, name: string, ...)`: ScriptHandle

A multi-select list. Options are extra string arguments or one array; at most 32.

#### ui.new_listbox

`ui.new_listbox(tab: string, container: string, name: string, items: string[])`: ScriptHandle

A listbox of `items`.

#### ui.new_textbox

`ui.new_textbox(tab: string, container: string, name: string)`: ScriptHandle

A single-line text field.

#### ui.new_button

`ui.new_button(tab: string, container: string, name: string, callback: fun())`: ScriptHandle

A button that calls `callback` when pressed.

#### ui.new_label

`ui.new_label(tab: string, container: string, text: string)`: ScriptHandle

A static label showing `text`.

#### ui.new_card

`ui.new_card(tab: string, container: string, title: string[, body: string])`: ScriptHandle

A static card showing a title and optional `body` subtitle. Display only, not an input: `ui.get` raises, `ui.set` is a no-op, and duplicates are allowed.

#### ui.new_long_card

`ui.new_long_card(tab: string, container: string, title: string[, body: string])`: ScriptHandle

A tall card variant showing the title only (`body` is ignored). Same display-only semantics as `new_card`.

#### ui.new_custom

`ui.new_custom(tab: string, container: string, height: number, fn: fun(x: number, y: number, w: number, h: number))`: ScriptHandle

Reserves `height` pixels in the menu and calls `fn` each frame with the region's screen rect. Draw inside `fn` with the [`renderer`](/base/renderer/) API, clipped to the rect. The callback runs on the overlay thread, same as `paint`. Display only: `ui.get` raises, `ui.set` is a no-op, duplicates allowed.

#### ui.new_color_picker

`ui.new_color_picker(tab: string, container: string, name: string[, r, g, b, a])`: ScriptHandle

A colour picker. Attaches to the previous row when there is one, like gamesense.

#### ui.new_hotkey

`ui.new_hotkey(tab: string, container: string, name: string)`: ScriptHandle

A hotkey row.

#### ui.new_string

`ui.new_string(name: string[, default: string])`: ScriptHandle

A named string that persists in the config but draws no row.

#### ui.new_tab

`ui.new_tab(name: string[, icon: string])`: ScriptHandle

Create or find a menu tab.

#### ui.new_popover

`ui.new_popover(tab: string, container: string, name: string[, icon: string])`: ScriptHandle

A popover usable as the `container` argument of the builders.

#### ui.attach_popover

`ui.attach_popover(item: ScriptHandle)`: ScriptHandle

The dots-popover attached to a menu row.

#### ui.new_watermark_item

`ui.new_watermark_item(name: string[, icon: string])`: ScriptHandle

A watermark row whose text is set with `ui.set`.

## Icons

#### ui.load_icon

`ui.load_icon(name: string, bytes: string)`

Register an icon by name from SVG or PNG bytes, for `new_tab`, `new_popover` and `set_icon`.

#### ui.set_icon

`ui.set_icon(item: ScriptHandle, icon: string)`

Set a row's icon by a registered name.

## Row state

#### ui.set_enabled

`ui.set_enabled(item: ScriptHandle, enabled: boolean)`

Enable or disable a row.

#### ui.set_visible

`ui.set_visible(item: ScriptHandle, visible: boolean)`

Show or hide a row.

#### ui.set_callback

`ui.set_callback(item: ScriptHandle, fn: fun(item: ScriptHandle))`

Call `fn` whenever the item's value changes.

#### ui.reference

`ui.reference(tab: string, container: string, name: string)`: ScriptHandle

Find a built-in Lynx widget by tab, container and name (raw key or translated label, case-insensitive), including inside popovers.

## Values

#### ui.get

`ui.get(item: ScriptHandle)`: any ...

Reads an item's value: checkbox boolean; slider number; combobox string; multiselect string array; listbox zero-based index; colour `r, g, b, a`; textbox/label/watermark string; hotkey `pressed, key`.

#### ui.set

`ui.set(item: ScriptHandle, ...)`

Sets an item's value; the argument shape matches what `ui.get` returns. Fires the item's callback.

#### ui.update

`ui.update(item: ScriptHandle, ...)`

Replace the options of a combobox, multiselect or listbox the script created.

#### ui.name

`ui.name(item: ScriptHandle)`: string

The item's name.

## Menu geometry

#### ui.is_menu_open

`ui.is_menu_open()`: boolean

Whether the Lynx menu is open.

#### ui.menu_position

`ui.menu_position()`: number, number

The menu's top-left corner in overlay pixels.

#### ui.menu_size

`ui.menu_size()`: number, number

The menu's size in overlay pixels.

#### ui.mouse_position

`ui.mouse_position()`: number, number

The pointer position in overlay pixels.

#### ui.notify

`ui.notify(text: string[, seconds: number])`

Show a toast for `seconds` (default 3).

#### ui.toast

`ui.toast(text: string[, seconds: number, ok: boolean])`

Post a toast through the Lynx menu's toast queue for `seconds` (default 3). `ok` (default `true`) marks it as a success toast. Bursts are rate-limited and identical text is de-duplicated, so a per-frame call will not spam the queue.