Skip to content
CyanideX edited this page Aug 5, 2026 · 2 revisions

Core

Window state management, grid snapping, smooth animations, and constraint sizing.

Quick Start

The easiest path is wu.Begin/wu.End — grid snapping, animations, and collapse tracking happen automatically:

local wu = GetMod("WindowUtils") or ImGui

wu.SetConstraints(200, 150, 600, 800, "MyWindow")
ImGui.SetNextWindowPos(100, 100, ImGuiCond.FirstUseEver)
if wu.Begin("MyWindow") then
    ImGui.Text("Hello from a managed window!")
end
wu.End()

If you need manual control (explicit Update() options, or retrofitting an existing mod), see the Developer Guide. The rules: call Update() after your content, before End(), and always call it — even when the window is collapsed.

wu.SetConstraints(200, 150, 600, 800, "MyWindow")
ImGui.SetNextWindowPos(100, 100, ImGuiCond.FirstUseEver)
if ImGui.Begin("MyWindow") then
    ImGui.Text("Content here")
end
wu.Update("MyWindow")
ImGui.End()

Window Management

Update(windowName, opts?)

Process window state for one frame. Handles drag detection, grid snapping, animation, and expanded-size tracking.

Parameter Type Default Description
windowName string - Window title (must match ImGui.Begin())
opts.gridEnabled boolean config Override grid snapping
opts.animationEnabled boolean config Override snap animation
opts.animationDuration number config Override animation duration (seconds)
opts.treatAllDragsAsWindowDrag boolean false Treat all drags as window drags (for settings windows with live preview)

opts.animationDuration also falls back to config when passed as false or nil. Easing function and snapCollapsed are always read from config and cannot be overridden per call.

Returns: nothing. Do not branch on the result.

Must be called inside Begin()/End(), outside any child windows.

SnapToGrid(position, windowName?)

Snap a value to the nearest grid point.

Parameter Type Default Description
position number - Value to snap
windowName string|nil nil Window name for grid config lookup (nil uses master)

Returns: number - snapped value

GridAlignMin(value, windowName?)

Align a minimum constraint so SnapToGrid always rounds into the valid range. Use when building constraints manually.

Parameter Type Default Description
value number - Raw minimum in pixels
windowName string|nil nil Window name for grid config lookup

Returns: number - aligned minimum

GridAlignMax(value, windowName?)

Align a maximum constraint so SnapToGrid always rounds into the valid range.

Parameter Type Default Description
value number - Raw maximum in pixels
windowName string|nil nil Window name for grid config lookup

Returns: number - aligned maximum

Constraints

SetConstraints(minW, minH, maxW, maxH, windowName?)

Grid-align all four constraint values and apply them via ImGui.SetNextWindowSizeConstraints. Call before ImGui.Begin().

Parameter Type Default Description
minW number - Minimum width in pixels
minH number - Minimum height in pixels
maxW number - Maximum width in pixels
maxH number - Maximum height in pixels
windowName string|nil nil Window name for grid config lookup

Grid alignment is bypassed automatically during constraint animations for smooth interpolation.

wu.SetConstraints(200, 150, 600, 800, "MyWindow")
if ImGui.Begin("MyWindow") then
    ImGui.Text("Content here")
end
wu.Update("MyWindow")
ImGui.End()

When a window name is passed, the first call of the session also restores the cached window size, so a window with no auto-restoring expand panels comes back at the size it had when you last used it instead of the size ImGui saved in its .ini.

SetConstraintsPct(minWPct, minHPct, maxWPct, maxHPct, windowName?)

Convenience wrapper that converts display-percentage values to pixels, then calls SetConstraints.

Widths and heights use different references. Heights are a percentage of display height. Maximum width is a percentage of display width, while minimum width is a percentage of a 16:9-normalized width (display width capped at height * 16/9) so minimums stay sane on ultrawide displays. If the resulting minimum width exceeds the maximum, it is clamped down to the maximum.

Parameter Type Default Description
minWPct number - Minimum width as display % (0-100)
minHPct number - Minimum height as display % (0-100)
maxWPct number - Maximum width as display % (0-100)
maxHPct number - Maximum height as display % (0-100)
windowName string|nil nil Window name for grid config lookup
-- Window between 10% and 40% of screen width, 10% and 80% of screen height
wu.SetConstraintsPct(10, 10, 40, 80, "MyWindow")

State Queries

IsAnimating(windowName)

Check if a window is currently playing a snap animation.

Returns: boolean

GetExpandedSize(windowName)

Get the last known expanded (non-collapsed) size of a window.

Returns: number|nil, number|nil - width, height (nil if never tracked)

CompleteAnimation(windowName)

Immediately finish a window's snap animation, jumping to the target position/size. No-op if the window is not animating. The collapsed check reads the current ImGui window, so call this inside that window's Begin()/End() scope.

ResetWindow(windowName)

Clear all tracking state for a window. Also cleans up any constraint animations associated with it.

InvalidateGridCache(windowName?)

Clear cached grid size calculations. Called automatically when per-window config changes. Pass nil to clear all caches (e.g., after changing master grid settings).

Parameter Type Default Description
windowName string|nil nil Specific window, or nil for all

Constraint Animations

Smooth transitions for window max-size constraints. Used by the expand system and available to mod authors for custom constraint-driven animations.

AnimateConstraint(windowName, property, target, opts?)

Start a smooth constraint animation. Automatically calls CompleteAnimation for the window to prevent conflicts with snap animations.

Parameter Type Default Description
windowName string - Window name (for grid bypass coordination)
property string - Constraint property key (e.g., "maxW", "maxH")
target number - Target value to animate to
opts.duration number 0.3 Animation duration in seconds
opts.easing string "easeOut" Easing function name
opts.initialValue number|nil nil Override starting value. When nil, the current value is used, or the target value if the property has never animated (so the first call snaps instead of animating)

While a constraint animation is active for a window, grid snapping and snap animations are bypassed for that window. After the animation completes, a grid snap is triggered automatically.

-- Animate max width from current to 500px over 0.4s
wu.AnimateConstraint("MyWindow", "maxW", 500, { duration = 0.4, easing = "easeInOut" })

UpdateConstraint(property, normal, expanded, isExpanded)

Drive a constraint animation each frame. Returns the current interpolated value.

Parameter Type Default Description
property string - Constraint property key
normal number - Value when not expanded
expanded number - Value when expanded
isExpanded boolean - Current expanded state (used for initial value if no animation started)

Returns: number - current interpolated value

local maxW = wu.UpdateConstraint("maxW", 300, 600, isExpanded)
wu.SetConstraints(200, 150, maxW, 800, "MyWindow")

IsConstraintAnimating(property)

Check if a specific constraint property is currently animating.

Parameter Type Description
property string Constraint property key

Returns: boolean

IsAnyConstraintAnimating()

Check if any constraint animation is active across all windows.

Returns: boolean

IsWindowConstraintAnimating(windowName)

Check if any constraint animation is active for a specific window. O(1) lookup.

Parameter Type Description
windowName string Window name to check

Returns: boolean

Configuration

SetDefaults(config)

Override global default values for all windows. Values not present in config are left unchanged.

Parameter Type Description
config table Key-value pairs to merge into defaults
wu.SetDefaults({
    gridUnits = 3,
    animationDuration = 0.3,
    easeFunction = "easeInOut",
})

SetWindowConfig(windowName, config)

Set per-window configuration overrides. Merged into existing config (does not replace).

Parameter Type Description
windowName string Window title
config table Key-value pairs to merge
wu.SetWindowConfig("MyWindow", {
    gridUnits = 1,
    animationEnabled = false,
})

ClearWindowConfig(windowName)

Remove all per-window configuration overrides, reverting to defaults.

Parameter Type Description
windowName string Window title

GetConfig(windowName, key)

Get the effective configuration value for a window, respecting the priority chain.

Parameter Type Description
windowName string Window title
key string Configuration key

Returns: any - resolved value

Priority chain: Master Override (when enabled) > Per-Window Config > Defaults

Utilities

Lerp(a, b, t)

Linear interpolation between two values.

Parameter Type Description
a number Start value
b number End value
t number Factor (0-1)

Returns: number - interpolated value

ApplyEasing(t, windowName?)

Apply the configured easing function to an interpolation factor.

Parameter Type Default Description
t number - Factor (0-1)
windowName string|nil nil Window name for easing config lookup

Returns: number - eased value

Available easing functions: linear, easeIn, easeOut, easeInOut, bounce.

How It Works

Grid snapping: Windows snap on drag release. Grid size = gridUnits * 20px (default 2 → 40px grid). Both position and size snap. Shift+drag locks to one axis.

Priority chain: Master Override (settings GUI) > Per-Window Config (SetWindowConfig) > Defaults (SetDefaults).

Constraint animations: While active, grid snapping and snap animations are bypassed to prevent jitter. After completion, a grid snap fires automatically to re-align.

Configuration Keys

Key Type Default Description
gridUnits number 2 Grid size multiplier (grid = gridUnits * 20px)
gridEnabled boolean true Enable grid snapping
snapCollapsed boolean true Snap collapsed windows
animationEnabled boolean true Enable snap animations
animationDuration number 0.2 Snap animation duration (seconds)
easeFunction string "easeOut" Easing function name

Examples

Basic Managed Window

local wu = GetMod("WindowUtils") or ImGui

wu.SetConstraints(200, 150, 600, 800, "MyMod")
ImGui.SetNextWindowPos(100, 100, ImGuiCond.FirstUseEver)
if wu.Begin("MyMod") then
    ImGui.Text("Content here")
end
wu.End()

Per-Window Grid Override

wu.SetWindowConfig("DetailPanel", { gridUnits = 1 })
wu.SetConstraints(100, 100, 400, 600, "DetailPanel")
if wu.Begin("DetailPanel") then
    -- content
end
wu.End()

Percentage-Based Constraints

wu.SetConstraintsPct(10, 10, 40, 80, "MyMod")
if wu.Begin("MyMod") then
    -- content
end
wu.End()

Constraint Animation (Manual)

-- Toggle between normal and expanded max width
if shouldExpand and not wu.IsConstraintAnimating("myMaxW") then
    wu.AnimateConstraint("MyWindow", "myMaxW", 800, { duration = 0.3 })
elseif not shouldExpand and not wu.IsConstraintAnimating("myMaxW") then
    wu.AnimateConstraint("MyWindow", "myMaxW", 400, { duration = 0.3 })
end

local maxW = wu.UpdateConstraint("myMaxW", 400, 800, shouldExpand)
wu.SetConstraints(200, 150, maxW, 600, "MyWindow")

if ImGui.Begin("MyWindow") then
    ImGui.Text("Content here")
end
wu.Update("MyWindow")
ImGui.End()

Clone this wiki locally