Skip to content

imgui

stable

Build immediate-mode UI layouts by declaring widgets into a UiContext and reading back the element list each frame.

use plugin imgui::{UiContext.new, button, label, …}
21 functions UI
/ filter jk navigate Esc clear
Functions (21)
  1. UiContext.new Create a new UI context
  2. button Add a button widget
  3. label Add a text label widget
  4. slider Add a numeric slider widget
  5. checkbox Add a checkbox widget
  6. text_input Add a text input widget
  7. combo Add a dropdown combo box widget
  8. radio_button Add a radio button widget
  9. progress_bar Add a progress bar widget
  10. color_edit Add an RGBA color editor widget
  11. begin_panel Begin a collapsible panel group
  12. end_panel End the current panel group
  13. begin_tree_node Begin a tree node group
  14. end_tree_node End the current tree node
  15. begin_menu Begin a menu group
  16. end_menu End the current menu
  17. menu_item Add a menu item widget
  18. separator Add a horizontal separator
  19. same_line Place the next widget on the same line
  20. elements Get all declared widgets as a table
  21. clear Clear all widgets and reset IDs

Overview

imgui is a retained data layer for immediate-mode UIs: instead of drawing pixels, it records the widgets you declare into a stateful UiContext handle and hands the list back to you each frame so your own renderer can draw it. Every widget call appends an element table (a map with a type tag, the widget's properties, and a unique id) to the context, and grouping calls like begin_panel/end_panel push marker elements so the renderer can reconstruct nesting. The context is stateful: IDs auto-increment and persist until you clear it, which is why the typical loop clears at the top of a frame, declares fresh widgets, then reads elements at the bottom.

Use it when you want to describe a UI declaratively in Zolo and feed the resulting element list to a host (a game engine, a canvas, an ImGui binding) without owning any drawing code yourself.

Common patterns

Build a frame from scratch: clear, declare widgets, then read them back.

use plugin imgui::{UiContext}

let ui = UiContext.new()
ui.clear()
ui.label("Settings")
ui.slider("Volume", 0.0, 1.0, 0.8)
ui.checkbox("Fullscreen", true)

for el in ui.elements() {
  print("{el["type"]}")
}

Group related widgets inside a panel so the renderer can nest them.

use plugin imgui::{UiContext}

let ui = UiContext.new()
ui.begin_panel("Audio")
ui.slider("Master", 0.0, 1.0, 0.7)
ui.slider("Music", 0.0, 1.0, 0.5)
ui.separator()
ui.checkbox("Mute", false)
ui.end_panel()

Lay out a button row using same_line between widgets.

use plugin imgui::{UiContext}

let ui = UiContext.new()
ui.button("Save")
ui.same_line()
ui.button("Cancel")
let els = ui.elements()
print("first: {els[1]["type"]}")

Create a new UI context

Creates a new immediate-mode UI context. Declare widgets on it each frame, read back the element list, then pass it to your renderer.

use plugin imgui::{UiContext}

let ui = UiContext.new()
ui.button("Click me")
let elems = ui.elements()
print(elems[1]["type"])

Add a button widget

Adds a button widget. Returns a table {type: "button", label, id}.

use plugin imgui::{UiContext}

let ui = UiContext.new()
let btn = ui.button("Submit")
print(btn["label"])

Add a text label widget

Adds a static text label. Returns {type: "label", text, id}.

use plugin imgui::{UiContext}

let ui = UiContext.new()
ui.label("Player Health:")
ui.label("100 / 100")

Add a numeric slider widget

Adds a numeric slider widget. Returns {type: "slider", label, min, max, value, id}.

use plugin imgui::{UiContext}

let ui = UiContext.new()
let s = ui.slider("Volume", 0.0, 1.0, 0.75)
print(s["value"])

Add a checkbox widget

Adds a checkbox widget. Returns {type: "checkbox", label, checked, id}.

use plugin imgui::{UiContext}

let ui = UiContext.new()
let cb = ui.checkbox("Enable shadows", true)
print(cb["checked"])

Add a text input widget

Adds a text input field. Returns {type: "text_input", label, value, id}.

use plugin imgui::{UiContext}

let ui = UiContext.new()
let inp = ui.text_input("Username", "player1")
print(inp["value"])

Add a dropdown combo box widget

Adds a dropdown combo box. items is a table of strings; selected is the 0-based index of the current selection. Returns {type: "combo", label, items, selected, id}.

use plugin imgui::{UiContext}

let ui = UiContext.new()
let c = ui.combo("Quality", ["Low", "Medium", "High"], 1)
print(c["selected"])

Add a radio button widget

Adds a radio button. active indicates whether this option is currently selected. Returns {type: "radio_button", label, active, id}.

use plugin imgui::{UiContext}

let ui = UiContext.new()
ui.radio_button("Option A", true)
ui.radio_button("Option B", false)

Add a progress bar widget

Adds a progress bar. fraction is 0.0–1.0. overlay is text shown inside the bar (pass an empty string for none). Returns {type: "progress_bar", fraction, overlay, id}.

use plugin imgui::{UiContext}

let ui = UiContext.new()
ui.progress_bar(0.65, "65%")

Add an RGBA color editor widget

Adds an RGBA color picker. Channel values are floats 0.0–1.0. Returns {type: "color_edit", label, r, g, b, a, id}.

use plugin imgui::{UiContext}

let ui = UiContext.new()
let col = ui.color_edit("Background", 0.1, 0.2, 0.3, 1.0)
print(col["r"])

Begin a collapsible panel group

Begins a named panel group. All widgets added after this call belong to the panel until end_panel is called.

use plugin imgui::{UiContext}

let ui = UiContext.new()
ui.begin_panel("Settings")
ui.slider("Volume", 0.0, 1.0, 0.5)
ui.end_panel()

End the current panel group

Closes the current panel group opened with begin_panel.

Begin a tree node group

Opens a collapsible tree node. Widgets declared between begin_tree_node and end_tree_node are nested children.

use plugin imgui::{UiContext}

let ui = UiContext.new()
ui.begin_tree_node("Advanced")
ui.checkbox("Debug mode", false)
ui.end_tree_node()

End the current tree node

Closes the current tree node opened with begin_tree_node.

Begin a menu group

Opens a menu with the given label. Add menu items with menu_item before calling end_menu.

use plugin imgui::{UiContext}

let ui = UiContext.new()
ui.begin_menu("File")
ui.menu_item("Open")
ui.menu_item("Save")
ui.end_menu()

End the current menu

Closes the current menu opened with begin_menu.

Add a horizontal separator

Adds a horizontal separator line between widgets.

use plugin imgui::{UiContext}

let ui = UiContext.new()
ui.label("Section A")
ui.separator()
ui.label("Section B")

Place the next widget on the same line

Instructs the renderer to place the next widget on the same horizontal line as the previous one.

use plugin imgui::{UiContext}

let ui = UiContext.new()
ui.button("OK")
ui.same_line()
ui.button("Cancel")

Get all declared widgets as a table

Returns the complete list of declared widgets as a 1-indexed table of element tables. Call this at the end of a frame to hand off to your renderer.

use plugin imgui::{UiContext}

let ui = UiContext.new()
ui.label("Hello")
ui.button("Go")
let elems = ui.elements()
print(elems[1]["type"])
print(elems[2]["type"])

Iterate the element list to drive your own renderer:

use plugin imgui::{UiContext}

let ui = UiContext.new()
ui.label("Status")
ui.progress_bar(0.5, "loading")
ui.button("Retry")

for el in ui.elements() {
  print("draw {el["type"]}")
}

Clear all widgets and reset IDs

Removes all widgets from the context and resets element IDs to 1. Call this at the start of each frame to rebuild the UI.

use plugin imgui::{UiContext}

let ui = UiContext.new()
ui.button("Old button")
ui.clear()
ui.button("Fresh button")
let elems = ui.elements()
print(elems[1]["label"])
enespt-br