Skip to content

Widgets

These are the elements that belong inside windows. They all share the same pattern from the ui overview: each returns a result whose events are functions you call, and every result has addTooltip.

Anything that holds a value (checkbox, input, slider, dropdown, code editor) takes a state so its value survives between frames.


ui.text

type Color = { r: number, g: number, b: number, a: number? } -- each from 0 to 1
type TextOpts = { wrapped: boolean?, color: Color? }

ui.text(text: string, opts: TextOpts?) -> TextResult

Draws a line of text. Set wrapped to make long text wrap to the window width, and color to tint it. The result has a hovered event.

ui.text("Plain text")
ui.text("Colorful text", { color = { r = 1, g = 0.4, b = 0.4 } })
ui.text("An extremely long piece of text that should wrap across lines...", { wrapped = true })

ui.button

ui.button(label: string) -> ButtonResult

Draws a button, the result has clicked (true on the frame it's pressed) and hovered.

if ui.button("Play sound").clicked() then
    lua_sys.playMP3("sound.wav")
end

ui.checkbox

ui.checkbox(label: string, state: State<boolean>) -> CheckboxResult

A checkbox bound to a boolean state. When the player toggles it, the state updates automatically. The result has changed and hovered.

local enabled = ui.state(false)

ui.register(function()
    ui.window("Options", function()
        ui.checkbox("Enable this", enabled)
        if enabled.value then
            ui.text("enabled")
        end
    end)
end)

ui.input

type InputOpts = {
    hint: string?,
    numeric: boolean?,
    password: boolean?,
    multiline: boolean?,
    readOnly: boolean?,
    height: number?, -- only used when multiline
}

ui.input(label: string, state: State<string>, opts: InputOpts?) -> InputResult

A text box bound to a string state. The result has changed and hovered.

local name = ui.state("")

ui.register(function()
    ui.window("Profile", function()
        ui.input("Name", name, { hint = "Enter your name" })
        ui.text("Hello, " .. name.value)
    end)
end)

ui.slider

type SliderOpts = {
    min: number?, -- defaults to 0
    max: number?, -- defaults to 100
    step: number?,
    format: string?,
}

ui.slider(label: string, state: State<number>, opts: SliderOpts?) -> SliderResult

A drag slider bound to a number state. The result has changed and hovered.

local volume = ui.state(50) -- integer slider
local zoom = ui.state(1.0) -- decimal slider

ui.register(function()
    ui.window("Mixer", function()
        ui.slider("Volume", volume, { min = 0, max = 100 })
        ui.slider("Zoom", zoom, { min = 0.5, max = 4.0, step = 0.1 })
    end)
end)

ui.dropdown

type DropdownOpts = {
    options: { string },
}

ui.dropdown(label: string, state: State<string>, opts: DropdownOpts) -> DropdownResult

A dropdown menu bound to a string state. options is the list of choices, and the state is set to whichever one is selected. The result has changed and hovered.


ui.tree

type TreeOpts = {
    defaultOpen: boolean?,
    leaf: boolean?,
    bullet: boolean?,
    framed: boolean?,
    selected: boolean?,
    openOnArrow: boolean?,
    openOnDoubleClick: boolean?,
    spanFullWidth: boolean?,
}

ui.tree(label: string, body: () -> ()) -> TreeResult
ui.tree(label: string, opts: TreeOpts, body: () -> ()) -> TreeResult

A collapsible section. body draws its contents and only runs while the tree is open. The result has open, clicked, and hovered.

ui.window("Stats", function()
    ui.tree("Monsters", { defaultOpen = true }, function()
        ui.text("Mammott")
        ui.text("Toe Jammer")
        ui.tree("Rare", function()
            ui.text("Rare Mammott")
        end)
    end)
end)

ui.tabBar and ui.tabItem

ui.tabBar(id: string, body: () -> ()) -> ()
ui.tabItem(label: string, body: () -> ()) -> ()

tabBar draws a row of tabs, and each tabItem inside its body is one tab. A tab item's body only runs while that tab is selected. Neither returns a result. The id on the tab bar is not shown.

ui.window("Editor", function()
    ui.tabBar("editor-tabs", function()
        ui.tabItem("General", function() 
            -- widgets here
        end)
        ui.tabItem("Advanced", function() end)
    end)
end)

ui.codeEditor

type CodeEditorOpts = {
    language: string?, -- "Lua" (default), "C++", "C", "HLSL", "GLSL", "SQL", "AngelScript"
    palette: string?, -- "dark" (default), "light", "retroblue"
    width: number?,
    height: number?, -- defaults to 300
    readOnly: boolean?,
    showWhitespaces: boolean?, -- defaults to true
    tabSize: number?, -- defaults to 4
    border: boolean?, -- defaults to true
    handleKeyboard: boolean?, -- defaults to true
    handleMouse: boolean?, -- defaults to true
    colorizer: boolean?, -- defaults to true
}

ui.codeEditor(label: string, state: State<string>, opts: CodeEditorOpts?) -> CodeEditorResult

A full syntax highlighting code editor tied to a string state. The result has changed, hovered, and focused.

This is a binding of ImGuiColorTextEdit.

local source = ui.state("print('hello')")

ui.register(function()
    ui.window("Script", function()
        ui.codeEditor("##editor", source, { -- ## hides the title "editor"
            language = "Lua",
            palette = "retroblue",
            height = 400,
        })
    end)
end)