[][src]Crate fungui

FunGUI is a UI layout system that seperates the description of the interface and the styling/layout.

In FunGUI there are two main systems that come into play that the rest is built around: Nodes and Styles.


Nodes are used to describe the user interface without any information about how it should look, only the structure. There are two types of nodes: Elements and Text.

Elements are simply a name which could be anything, there are no special names as everything is controled by the style rules. Elements may contain child nodes.

Text as the name implies is just text. Unlike elements, text may not have any child nodes.

Any node may have properties on it. Properties are used to provide configuration to a node which is useful if you use the same node type multiple times. For example an url property may be used on a text node to allow the style rules to color it differently or make it clickable.


An example of the node format:

alert(level="warning") {
    title {
        "This is an alert"
    content {
        "If you would like more info click "
    buttons {
        button(focused=true) {
        button {


Styles are used to define the behaviour of a node. This can be something like how the node will render or how the node will react to events.

Styles apply using matching rules to find what nodes they will apply too. Rules can specific a hierarchy of nodes and what properties the node should have and their values. This allows for a title inside an alert to act differently to a title inside an window for example.

Once a match is found the style rules are applied to the node. Rules can be a simple constant value or an expression. Expressions perform basic math (+-/*%) and boolean operations (|| && <= etc), reference properties that were matched and execute functions. Functions can be used for complex properties instead of spliting them across multiple rules.

Variables and types

Variables are typed and floats/integers are treated as seperate and not casted automatically, this includes constants in style rules as well. For constants defining a number as 5 will be an integer whilst 5.0 will be a float. For variables you can cast using int(val) or float(val).

Special variables

There are two special variables that can be used without using them in a matching rule: parent_width and parent_height. These allow you to size things relative to the parent's size without needing a custom layout to handle it. Whilst these are useful in some cases they do come with a larger cost. In order to handle this the interface may have to re-run the layout system multiple to resolve the variables causing a slowdown however this will generally only happen the first time the node has its layout computed.


An example of the style format:

alert {
    center = true,
    layout = "rows",
    width = 500,
    height = 400,
alert(level="warning") {
    background_color = rgb(255, 255, 0),

alert > title {
    layout = "lined",
    width = parent_width,
alert > title > @text {
    font_color = rgb(0, 0, 0),
    font_size = 24,

alert > content {
    layout = "lined",
    width = parent_width,
alert > content > @text {
    font_color = rgb(0, 0, 0),
    font_size = 16,
alert > content > @text(url=url) {
    font_color = rgb(0, 120, 0),
    on_mouse_up = action("visit", url),


Layouts take some of the style rules and use that to position and size a node. These can be added via add_layout_engine and selected using the layout style property.


The Extension trait paired with the RenderVisitor trait is the main way that is used to actually make the user interface do something. By itself FunGUI only does layout, the extension trait can be used to add events and rendering by adding its own properties to use in style rules. In UniverCity these are things like image and background_color for rendering and on_mouse_down for events where events are lua code defined inline with the styles:

This example is not tested
button {
    border_width = border_width(15.0),
    border = border_image("ui/button", 15, 15, true),
    shadow = shadow(2.0, 2.0, rgba(0, 0, 0, 0.3), 3.0, 0.0, "outset"),
    layout = "center",
    can_hover = true,

button(theme="blueprint") {
    border_width = border_width(15.0),
    border = border_image("ui/button", 15, 15, true),
    tint = rgba(0, 255, 255, 0.4),
button(on_click=click) {
    on_mouse_up = list(click, "init#
        return true



Tries to find and evalulate a given style property in a rule.


Used to create nodes inline without parsing a document at runtime.


Allows for the creation of queries in a similar format as style rules.



Provides access to a child node and its stored layout data


Flags used to mark certain properties as dirty/changed


An element node


Stores loaded nodes and manages the layout.


A node representing an element or text.


Helper struct to split a RefMut on a NodeInner whilst RefMut::split is unstable.


A chain of nodes and their parents


The inner data of a single node.


A query on a node that can be used to look up nodes in the same way that styles do.


The position and size of an node


A rule which contains a set of matchers to compare against the properties of a node and parents and a set of styles to apply if matched.


An unchanging key


Stores rules, functions and layouts needed for computing styles


A weak reference to a node.



The error type used in FunGUI


The value of a node.


A value that can be used as a style property



The "height" static key used by the absolute layout


The "width" static key used by the absolute layout


The "x" static key used by the absolute layout


The "y" static key used by the absolute layout



Types that can be converted to and from a value


Extensions extend stylish to allow custom style properties to be added


Used to position an element within another element.


Called for every node in a manager to allow them to be rendered.



Formats the error in a user friendly format


Formats a parsing error using format_error.

Type Definitions


An alias for a common return type used in FunGUI


A HashSet using a default FNV hasher.