Repository navigation
split
Horizontal and vertical two-panel splits with draggable grab bars, double-click collapse, and programmatic control.
local wu = GetMod("WindowUtils")
local split = wu.Splitter
-- Horizontal split: left sidebar | right content
split.horizontal("sidebar", function()
for i, item in ipairs(menuItems) do
if ImGui.Selectable(item.label, selected == i) then
selected = i
end
end
end, function()
menuItems[selected].draw()
end, { defaultPct = 0.25, minPct = 0.15, maxPct = 0.4 })Create a horizontal split (left | right) with a draggable grab bar.
| Parameter | Type | Default | Description |
|---|---|---|---|
| id | string | - | Unique splitter ID |
| leftFn | function|nil | - | Renders left panel content |
| rightFn | function|nil | - | Renders right panel content |
| opts.defaultPct | number | 0.5 | Default split position (0-1) |
| opts.minPct | number | 0.1 | Minimum left panel fraction |
| opts.maxPct | number | 0.9 | Maximum left panel fraction |
| opts.grabWidth | number | ItemSpacing.x | Grab bar width in pixels |
Returns: number - current split fraction (0-1)
Alias: split.h(...)
Create a vertical split (top / bottom) with a draggable grab bar.
| Parameter | Type | Default | Description |
|---|---|---|---|
| id | string | - | Unique splitter ID |
| topFn | function|nil | - | Renders top panel content |
| bottomFn | function|nil | - | Renders bottom panel content |
| opts.defaultPct | number | 0.5 | Default split position (0-1) |
| opts.minPct | number | 0.1 | Minimum top panel fraction |
| opts.maxPct | number | 0.9 | Maximum top panel fraction |
| opts.grabWidth | number | ItemSpacing.x | Grab bar height in pixels |
Returns: number - current split fraction (0-1)
Alias: split.v(...)
Every opts field on horizontal and vertical is read only on the first call for a given id. defaultPct, minPct, maxPct, and grabWidth are copied into the splitter's state when that state is created; passing different values on later frames is silently ignored. There are no every-frame opts fields on these two functions.
To change the position after creation, call setSplitPct(id, pct). To change minPct, maxPct, or grabWidth, call splitter.destroy(id) and let the next frame re-create the state with the new opts.
Two other consequences of this:
-
opts.elementIdis not read by two-panel splits, so their grab bars cannot be targeted by the tutorial system. Only multi-splitter dividers supportelementId. - Two-panel splits are not persisted. Unlike
multi()andtoggle(), there is no layout-cache restore, so the position starts atdefaultPctevery session.
Get current split fraction for a two-panel splitter.
Returns: number|nil - fraction (0-1), or nil if not initialized
Set split fraction programmatically. Value is clamped to the splitter's min/max range.
Reset splitter to its default fraction. Cancels any collapse animation.
split.horizontal("sidebar", function()
for i, item in ipairs(menuItems) do
if ImGui.Selectable(item.label, selected == i) then
selected = i
end
end
end, function()
menuItems[selected].draw()
end, { defaultPct = 0.25, minPct = 0.15, maxPct = 0.4 })-- Vertical outer split with horizontal inner split
split.vertical("outer", function()
split.horizontal("inner", function()
ImGui.Text("Top-Left")
end, function()
ImGui.Text("Top-Right")
end)
end, function()
ImGui.Text("Bottom")
end, { defaultPct = 0.6 })