User Interface

User Interface introduction.

See also the detailed User Interface reference.


Widget constructors are only available during the main script chunk execution and explicitely disabled afterward during realtime execution.

Table constructor syntax

All widgets constructors accept named arguments to be specified using the table constructor syntax cf

so instead of writing

local button = Button("button name")
button.changed = function(self, mods) print( .. "button clicked") end

One can avoid repeating button and use the table constructor convenient syntax:

local button = Button{"foo",
x=5, y=20, width=120, height=45,
changed = function(self) print( .. " button clicked") end

Note the use of use of curly brackets instead of parenthesis to denote table constructor.


The available user interface size is 720x480px.

Auto layout

By default widgets are automatically laid out in creation order from left to right and from top to bottom on a grid using the first cell that is not already partially or totally filled by another widget. This let you combine manual layout and autolayout. The grid is made of 6 colums of 120px each with 5px on both size. Column height are 20px separated by 5px margins. wich allows up to 19 rows. Some widgets like Knobs, Slider, Menu and Table spans 2 rows (i.e. 45px) while Buttons, Spinners only need one row.

For convenience, a moveControl function is also available to manually position widgets on the invisible grid.

Manual Layout

Further control is possible using the x, y, width, height, size, position and bounds attributes to position and resize widgets at the pixel level.

changed callback

Instead of having a single callback to be notified of user interface changes, each widget has a changed callback property. One can assign any user defined function to this property. The widget that has changed is available to the callback function as the first argument:

local button = Button("button")
button.changed = function(self)

lua flexible function declaration syntax allows the following equivalent statements:

function button.changed(self)
button.changed = function(self)
function button:changed()
print( -- self is implicit when using the : syntax

One can also use a single callback function and dispatch changes based on the widget argument:

function callback(widget)
if == "button1" then
elseif == "button2" then
local button1 = Button{"button1", changed=callback}
local button2 = Button{"button1", changed=callback}
button1:push(true) -- print "foo"
button2:push(true) -- print "bar"

for Tables, the changed callback function takes an additional argument specifying the indes of the Table value that has changed.

function tableCallback(self, index)
print("table value changed: ", index, self:getValue(index))