UI Routines¶
UI Routines (STL.UI_ROUTINES) are named update functions that synchronize the visible state of the UI with the current engine state. They answer a single question: given the current parameter values, what should be shown, hidden, or labelled differently?
They are not callbacks — they do not write to parameters. They are pure read-and-display logic, always callable, always safe to re-run.
Why UI Routines Exist¶
Without a centralized refresh mechanism, display logic is scattered across init code, callback handlers, and reload logic. When a preset loads, the display does not update. When a parameter changes programmatically, the widgets lag. UI Routines solve this by providing a single call uir.update() that runs all display logic from scratch, regardless of what triggered the need for a refresh.
Key Concepts¶
Registration and Auto-Linkage¶
Every routine is a plain KSP function registered into the STL.UI_ROUTINES group at compile time. Calling call uir.update() runs all registered routines in order.
define STL.UI_ROUTINES += plc_global_navigation
function uir.plc_global_navigation()
plc__ui -> hide := HIDE_WHOLE_CONTROL
select plc.ui.section_id
case plc.ui.section.POLYCORE
plc__ui -> hide := HIDE_PART_NOTHING
case plc.ui.section.CONSOLE
console.ui -> hide := HIDE_PART_NOTHING
end select
end functionThe naming convention is uir.<name>() where <name> matches the string in the STL.UI_ROUTINES registration. IVLS auto-links the two at compile time; a typo causes a build error.
Multiple routines are registered independently. Each is called once per uir.update(), in registration order.
Sub-Groups¶
A sub-group is a named subset that can be invoked in isolation with uir.RunGroup(GroupName), avoiding the full update chain for events that only affect a narrow part of the UI:
define UIR.Polycore.ARP_TABLE_DISPLAY += UIR.Polycore.ARP_TABLE_CONTENT
define STL.UI_ROUTINES += UIR.Polycore.ARP_DISPLAY
function uir.plc_arp_dynamic_display()
uir.RunGroup(Polycore.ARP_TABLE_DISPLAY)
end functionThe parent routine acts as a proxy — the full uir.update() run reaches the sub-group via this proxy, but the sub-group can also be called directly when only the ARP table needs refreshing.
Auto-Linkage via Box Parameters¶
An Engine Box parameter can carry a ui_routine property. When the parameter changes, that routine is called automatically via process_ui_routine(par):
tokyo.mono_poly.ui_routine := uir.tss.legato_latencyThis is implemented in the SDK's unnamed-pars.ksp — the par setter calls process_ui_routine(par) after writing the value, which invokes the assigned routine if one is set.
Use this when a parameter change has a narrow, well-defined UI consequence. Prefer the full call uir.update() when uncertain.
The Standard cb Reload Pattern¶
The canonical way to restore UI state after a DAW reload or preset change is to call uir.update() from cb Reload:
node Polycore.GUILogic:
cb Reload:
call uir.update()The instpers variables (section_id, page_id, etc.) survive the reload. Without uir.update(), the widgets would remain in their default visual state even though those variables are set correctly.
Connections to Other Parts of IVLS¶
UI Routines are typically called from:
par_cb.responsein engine-box nodes, for parameters whose change affects widget visibilitycb Reload(orcb PostReload) to restore display state after preset load- Manual
on ui_control()handlers in ui-callbacks that write navigation state and then need a display refresh
Patterns and Caveats¶
Do not write raw set_control_par() or widget -> hide := outside of UI Routine functions or on ui_control() handlers. If display logic is scattered across init code or callback code without a routine, it will fail to fire on DAW reload and cause visual state corruption.
Not every parameter change needs call uir.update(). A volume change never affects widget visibility. Only call it when the change might affect what is shown or hidden.
Routines are read-only. They observe state and update display. They never write to parameters. That direction goes through ui-callbacks.
The typical flow for a navigation button:
- User clicks button →
on ui_control()fires incb Functions - Handler writes new navigation state to an
instpersvariable - Handler calls
call uir.update() - Routines read the variable and update panel visibility
Related¶
- engine-box —
par_cb.responsecallsuir.update()after relevant parameter changes - ui-callbacks — widget binding and the
on ui_control()pattern