UFO-Scripts/ui/LUA-utility-functions
Ufox extensions
Using the lua api to create a hierarchy of ui nodes leads to a lot of typing. So there is an alternative. Using the ufox utility library. This library contains a set of functions to create a ui tree from a set of nested lua tables specifying the structure of the ui nodes and the values of the properties. Currently ufox supports the following three functions for creating ui node structures:
ufox.build (data, parent) create a tree of ui nodes from data and assign them as child to prent ufox.build_window (data) create a window and associated child controls from data ufox.buidl_component (data) create a component and associated child controls from data
Using these functions leads to code like this:
local ui_data = {
class = "panel",
name = "pnlTest",
pos = { 10, 250 },
size = { 200, 200 },
layout = ufo.LAYOUT_TOP_DOWN_FLOW,
layoutmargin = 15,
backgroundcolor = { 0.50, 0.00, 0.00, 1.00 },
{
class = "MainMenuBtn",
name = "btnTest1",
text = "_Test 1",
on_click = function (sender)
ufo.print("Hello Ufo AI!\n")
end
},
{
class = "MainMenuBtn",
name = "btnTest2",
text = "_Test 2"
},
{
class = "MainMenuBtn",
name = "btnTest3",
text = "_Test 3"
}
}
local ui_node = ufox.build(ui_data, node_parent)
The above code creates a subtree of ui nodes based on the data foun in ui_data and assigns the subtree to the parent node specified in node_parent (usually the window).
Using the ufox build-functions requires you to adhere to the following guidelines:
- if a table declaration is to be converted to a ui control, at least the fields 'class' and 'name' must be specified
- a property can only be specified in the table declaration if there is a corresponding set function, so 'text' requires a set_text(..) function, 'background' a set_background(..) and so on
- the build_window function requires the top-level table declaration to have a 'class' field with value 'window'
Common mistakes
Although the use of the table hierarchy actually looks a lot like the old UFO-script, it is not the same. The most notable difference is the use of the 'comma' to separate field-value definitions. A common mistake is to omit a comma. If you do, you'll get an error like the following.
lua load error: [string "main.ufo"]:136: '}' expected (to close '{' at line 11) near 'version'
The above error simply states that somewhere in the file main.ufo (near line 136) in the list of field-value definitions a comma is missing.
Caveats
Note that while the ui engine relies on creation order for the layering order of ui nodes, lua does not guarantee the order of elements within a table, and so the build functions detailed above cannot guarantee the creation order of the nodes specified in the given table — using them in a ui tree with nodes that require a specific layering order will lead to the resulting window/component/ui nodes misbehaving. This can be worked around by making consecutive calls to the needed functions to ensure the correct layering.
local ui_tree = {
name = "inv_stats_hud",
class = "window",
pos = {236, 60},
size = {560, 418},
backgroundcolor = {0, 0.15, 0.1, 0.7},
bordercolor = {0.58, 0.81, 0.758, 0.7},
bordersize = 2,
-- Inventory area background image - needs to layer below the other inventory nodes.
{
name = "inv_bg",
class = "image",
pos = {10, 59},
size = {351, 349},
source = "/ui/inv_bg"
},
-- Other bottom layer or layer independent nodes here
}
local inv_stats_hud = ufox.build_window(ui_tree)
-- This node needs to layer on top of the background image above
-- hence we create it in a separate step to ensure proper creation (and thus layering) order.
do
local container = { name = "headgear", class = "container", pos = {88, 85} }
ufox.build(container, inv_stats_hud)
end
-- Other nodes to layer on top of the above here.