Tabletop Simulator

Tabletop Simulator

47 ratings
The art of scripting: XML Interfaces Part I: Overview
By Floaty
A short introduction to XML User Interfaces. Basic knowledge about XML and Lua required.
2
   
Award
Favorite
Favorited
Unfavorite
Introduction
This guide will provide a short overview over the basics of the newly introduced XML UIs, the available elements, useful attributes, layouting, definition of default states of elements and communication with Lua script. It will not teach the basics for XML in general. If you unfamiliar with the principles of XML or its basic structure, please visit one of the countless online tutorials for this purpose (one example that seems to fit :click[www.w3schools.com]).
Attributes
Attributes can be used to either modify the appearance or behaviour of elements. Whilst several different attributes are available, this guide tries to list the most important ones for a quick start.

General
General attributes are of use to set basic things about the element or to group it for later identification.

Name
Description
active
Specifies whether or not this element is active. Can be used to hide elements via Lua script
class
Allows to group elements
id
Used as an identifier for a specific UI element.
visibility
Specifies what colours are able to see this element

Note: Visibility allows four different values:
  • Host: Only visible to the game host.
  • Admin: Only visible to the host and any promoted player.
  • Red: Only visible to the player in that seat color. Works with all color names. Different colors can be concatenated via adding a | between each color.
  • Clubs: Only visible to members of that player group. Works with all team names. Different teams can be concatenated via adding a | between each team.

Text attributes
Text attributes influence the (text) content and its appearance of an element.

Name
Description
text
Specifies the text.
alignment
Specifies the alignment of the text in the element.6 values are possible, which are a combination of one descriptor for the vertical orientation (Upper, Middle, Lower) and one for the horizontal orientation (Left, Center, Right)
color
Specifies the color of the text
fontStyle
Specifies the style of the font. Possible values: Normal, Bold, Italic, BoldItalic
fontSize
Specifies the size of the font.

Sizing & Poistioning
To give elements their appropriate size, at least width and height of the element has to be set. Otherwise the elements will be automatically sized, which is almost never preferable. Nethertheless, elements inside layout elements are always rezsized to fit their parent (exception: Panel).

Name
Description
Width/Height
Set's the width/height an object occupies.
minWidth/Height
Set's the minimal width/height an object occupies. The width/height cannot be reduced below the set value
prefferedWidth/Height
Set's the preferred width/height of an object (which is currently ignored by most layouts)
offsetXY
Changes the position of an object by the given offset. Important to place elements.
flexibleWidth/Height
Decides if the width/height of the element is flexible, meaning that it can be dynamically changed.
visibility
Specifies what colours are able to see this element

Action Listener
Action Listener, also called "Event Attributes" are useful to send information to a script about the happening of specific user interactions like a click.

Name
Description
onClick
Clicking on the element.
onMouseEnter
Pointer entering the boundary of the element.
onMouseExit
Pointer leaving the boundary of the element.
onDrag
Element drag event.
onBeginDrag
Element beginning to be dragged.
onEndDrag
Element being release from its drag.
onMouseDown
Mouse click action.
onMouseUp
Mouse click finishing action.
onSubmit
//
Elements
Text
Text elements are representations of strings. They serve as simple labels and can be used to preformat text for use in other elements.


Images
Images are what the name promises: Images. They have to be provided via the asset manager.

Useful Attributes
Name
Description
name
The name of the file in the asset manager
Type
Seems to concern how the image is cropped. Currently not tested. 4 values possible: Simple, Sliced, Filled, Tiled


Progress bars
Progress bars are useful to indicate the progression of something.


Useful Attributes
Name
Description
percentage
The percentage to indicate
showPercentageText
Should the percentage also be illustraded by a string?
textColor
The color of the percentage text
color
The background color of the bar
fillImageColor
The fill color of the actual bar
Inputs
Inputs are elements that can take information in. This information can be text or an event such as a mouse click or the pointer entering the element boundaries.

Buttons
Buttons can be used as simple triggers to activate certain functions.


It can be created via
<Button> Text </Button>

Useful Attributes
Name
Description
onClick
Name of the Lua function which will be called upon a click
icon
Path to a graphical icon the button can use
interactable
Indicates if the button can be used.

Switches
Switches can be used to let the user activate or deactivate certain functions/behaviours.
Two different kinds of Switches are available:

Toggles:


Toggle Buttons:


Both serve the same purpose and are just differently styled.

They can be created via
<ToggleButton> Text </ToggleButton> <Toggle> Text </Toggle>

Useful Attributes
Name
Description
onValueChanged
Lua function which will be called if the state of the toggle is changed
interactable
Indicates if the toggle can be used.
icon
Path to a graphical icon the button can use
isOn
indicates if the switch is currently toggled

Toggle groups
Toggle groups allow it to group toggles in a manner that they can be used as radio buttons to let the user choose between different available options if only option at a time is feasible.

They can be created via:
<ToggleGroup> <VerticalLayout> <Toggle>Toggle A</Toggle> <Toggle>Toggle B</Toggle> <Toggle>Toggle C</Toggle> </VerticalLayout> </ToggleGroup>

Useful Attributes
Name
Description
text
The content of the input field
onValueChanged
Name of the Lua function which will be called upon each edit of the input field
onEndEdit
Name of the Lua function which will be called when the input field gets deselected
interactable
Indicates if the input fieldcan be used.
readOnly
Indicates if the input field can be edited.

Input fields
Input fields can be used to show and edit text.


It can be created via
<InputField> Text </InputField>

Useful Attributes
Name
Description
text
The content of the input field
onValueChanged
Name of the Lua function which will be called upon each edit of the input field
onEndEdit
Name of the Lua function which will be called when the input field gets deselected
interactable
Indicates if the input fieldcan be used.
readOnly
Indicates if the input field can be edited.

Slider
Sliders can be used to conviently select a value between a given minimal and maximal value.


It can be created via
<Slider minValue = "?" maxValue = "?" value = "?" />

Useful Attributes
Name
Description
onValueChanged
Name of the Lua function which will be called upon each edit of the input field
interactable
Indicates if the input fieldcan be used.
minValue
The minimal possible value
maxValue
The maximal possible value
value
The current value
wholeNumbers
Indicates if the slider can only return whole numbers
direction
The direction of the slider. 4 different values are possible: LeftToRight RightToLeft TopToBottom BottomToTop

Dropdowns
A Dropdown menu can be used to build an expandle choice menu bar The dropdown has two states:

closed


opened


It can be created via
<Dropdown> <Option>Option 1</Option> </Dropdown>

Useful Attributes
Name
Description
onValueChanged
Name of the Lua function which will be called upon each edit of the input field
interactable
Indicates if the input fieldcan be used.
itemHeight
Indicates the height of the available options once the dropdown is opened
Layouts
General
Layout elements are used to group other elements in a specific manner. Besides their differences, they share a lot of attributes to define specific characteristics like padding, spacing, cell sizes and more. We will now dive deeper into the most useful attributes:

Padding
Padding defines the distance between the content of an element and its border. It is useful for aesthetic purposes. It can be specified via:
padding = "LEFT_VALUE RIGHT_VALUE TOP_VALUE BOTTOM_VALUE"

Padding can be used by all layout elements.

Alignment
Alignment is an attribute used to define how a child element with a smaller size than the parent element should be positioned inside the parent element. 6 values are possible, which are a combination of one descriptor for the vertical orientation (Upper, Middle, Lower) and one for the horizontal orientation (Left, Center, Right).
Example:
childAlignment = "UpperLeft"
Note: Text elements also use alignment to organize their text display. In this case, the alignment would be set the following way:
alignment = "UpperLeft"
All layout elements except the panel use alignment.


Spacing
Spacing tells the parent element how much space should be between individual child elements. It is useful for aesthetic purposes. It can be specified via:
spacing = "number"

All layout elements except the panel use spacing. Thereby the table layout uses the attribute cellSpacing to define the spacing between its cells.

Cell dimensions
Cell dimensions are used by the table layout and the grid layout to organize their space into a grid of even subspaces (cells).
Both layout types are know attributes to size their cells.
The grid layout uses the attribute cellSize with can be specified via:
cellSize = "WIDTH HEIGHT"
The table layout uses the attribute columnWidths to define the width of the cells. The height of a row is dependent on the highest child inside said row. It can be defined the following:
columnWidths = "WIDTH_COL_1 WIDTH_COL_2 WIDTH_COL_3 WIDTH_COL_4 etc."
This attribute can also use "auto-size" to automatically determine the needed width for the respective column.


Panel
The panel is an empty window which can be used to contain child elements. It's the most basic layouting element and does not order its child elements. All child elements are stacked in the middle of the panel. If the attribute padding was set, the panel behaves like a "layout-group", which seems to be very similar to a horizontal layout.
It can be defined via:
<Panel> <Element> Element content </Element> </Panel>
Layout
Ingame

Horizontal Layout
The horizontal layout orders its child elements horizontally.
It can be defined via:
<HorizontalLayout> <Element> Element content </Element> </HorizontalLayout>
Layout
Ingame

Vertical Layout
The vertical layout orders its child elements vertically.
It can be defined via:
<VerticalLayout> <Element> Element content </Element> </VerticalLayout>
Layout
Ingame

Grid Layout
The grid layout orders its child elements in a chess board - like grid. Thereby, the space each child element can occupy can be limited via the cellSize attribute. The grid layout will start to fill up its cells horizontally, then, when no space for further cells is left horizontally, if will start a new row below the first one.
It can be definedvia:
<VerticalLayout> <Element> Element content </Element> </VerticalLayout>
Layout
Ingame

Table Layout
The table layout is most sophisticated layout currently available. It uses row and cell elements to order its child elements. Each row and each cell can thereby be altered by defaults and attributes, making the table layout the most versatile layout to order elements.
It can be defined via:
<TableLayout> <Row> <Cell><Element> Element content </Element></Cell> <Cell><Element> Element content </Element></Cell> </Row> </TableLayout>
Layout
Ingame

Scroll Views
Scroll view are useful to fit content into other layout elements which has either a larger height, width or both as the parent element without cropping or wrapping of the elements content.
They can be defined via:
<VerticalScrollView> <Element> Element content </Element> </VerticalScrollView> <HorizontalScrollView> <Element> Element content </Element> </HorizontalScrollView>
Vertical
Horizontal

Despite their main use as layout elements, they can also serve as input elements, meaning they can trigger lua functions upon change.

Things to keep in mind
The layout elements will currently resize their child elements to fit their boundaries. That, unfortunately, renders them unfit for nesting. That is especially obvious when using horizontal or vertical layouts. They completely ignore the set dimensions of their child elements. That means that they have set to exactely fitting dimensions to get what you want. Example: Imagine you want a list of 10 buttons, which each button beeing 30x30. If you want to group them with a vertical layout, its size has to be 30 x 10 + left_padding + right_padding X 30 x 10 + top_padding + bottom_padding + spacing. Because it can be a chore to keep track of this in complex layouts, i recommand to avoid at layout groups to build up complex UIs if they are not build up and maintained by Lua script if you are trying to build more complex interfaces. Instead use Panels to set up the window, because they do not show this strange behaviour.
Advanced: Defaults
Defaults are used to set standard values for elements. This can be applied to either set a default appearence to elements such as buttons or sliders or to elements assigned to specified classes. Defaults are very similar to CSS descriptions.

How to define defaults
The following example will define the standard color of all Text elements to be white as well as their font size to be 18. All Text elements with the class "red" will be colored red.
<Defaults> <Text color="#FFFFFF" fontSize="18" /> <Text class="red" color="#FF0000" /> </Defaults>
Advanced: Communication with Lua scripts
Communication with Lua script is mainly performed via event triggers such as a button press, a value change of a slider or the text change of the input field (for a list of possible events, see the section "Attributes" under paragraph "Action Listener"). Communication between the UI and the script is a necessity to make the UI actual functional.

To start communication with the script, at first the UI has to know which function it should call if a specific event occurs. Let's assume we would want to perform an action upon a button click. At first we have to set the onClick attribute of the button to specify our onClickListener:

<Button onClick="clickFunction"> Click me for Action! </Button>

Now, if we click the button, a Lua function called "clickFunction" will be called. Each element automatically passes parameters to the function to make identification of of the calling element and the player who has triggered the event possible.

Following parameters will be passed to the function:

Parameter
Description
player
Indicates which player has triggered the event
value
A value send by the input. May be a string or number. Not used by buttons.
id
Only send if the elements has a specified ID. Useful to identify the triggering element and thus overload functions.

In Lua, this would look like:
function clickFunction(player,value,id) -- Some functional code end

UI manipulation via Lua script
Lua script can not only get information from the ui, it can also manipulate the UI.
Following functions are most useful to fulfill that task:

Function
Description
getAttributes(id)
Returns the attributes set by the user for the element with this id
getAttributes(id, attribute)
Returns the specific attribute set by the user for the element with this id
setAttributes(id, attribute, value)
Sets the specific attribute for the element with this id
setAttributes(id, data)
Sets the attributes (table data) for the element with this id
hide(id)
Hides the element with this id
show(id)
Shows the element with this id
12 Comments
Sirz Benjie Jul 12, 2023 @ 12:51pm 
Does anyone know how to get rid of the white borders around cells in tables? I want them to be invisible
Finaryman Oct 8, 2022 @ 1:24am 
<Panel position="0 0 -100"></Panel> panel is one unit above origin of the object
Finaryman Sep 28, 2022 @ 1:50pm 
u might wanna include how to position panel in 3d space
Urhixidur Oct 22, 2020 @ 7:06am 
Suppose I create a button with addButton({ parameters }). How do I get its ID in order to set additional attributes beside those accepted by addButton, such as alignment? If I try to pass the button's name (as a string) to self.UI.getAttributes(), I get the error "Object reference not set to an instance of an object".
DaceZA Jun 28, 2020 @ 12:42am 
Note: the original documentation for XmlLayout, the system used by TableTop Simulator, can be found here: http://digital-legacy.co.za/XmlLayout/Documentation
amaxslade Jun 22, 2020 @ 6:28am 
How do I populate a UI XML with items from a table & make them selectable?

To be more verbose:
If I have a table:
Opts[1] ={choice='pick one'}
Opts[2] ={choice='pick two'}
Opts[3] ={choice='pick three'}
how can I dynamically show these 3 options in the UI XML making them button choices for the user? Also it needs to accommodate for different amounts of choices. Today it might have only 3, but I might want to add more at a later date so I don't want to hardcode the amount of choices. So an option that include a For In statement is what I need.

Cheers
bhfred May 22, 2020 @ 12:33pm 
Any chance of training videos for basic knowledge about XML and Lua?
tim.engler75 Nov 23, 2019 @ 6:33pm 
Great guide! One thing is that on InputField, "fontSize" can be used, just like on Text. I didn't see this mentioned in the official api or in this guide, so just an FYI.
Bob April Jul 14, 2019 @ 11:39am 
My current workaround I'm playing with is to skip the icon attribute, place an image, then place a blank button on top of it. Example code -
<Panel
position="500 0 -75"
rotation="180 180 0"
height="700"
width="504"
padding="125,125,0,0"
>
<Image image="Named File"></Image>
</Panel>

<Panel
position="500 0 -75"
rotation="180 180 0"
height="700"
width="504"
padding="100,100,0,0"
>
<Button colors="clear" onClick="function_Name"></Button>
</Panel>
Bob April Jul 14, 2019 @ 11:38am 
Smithy64 - you get to define the icon by using a named file that you've uploaded to the asset manager. In TTS, open the Scripting window, look for the little crossed tools button on top right. Upload your files there. Then refer to them in your UI as so -

<Button icon="Named File" colors="clear" onClick="function_Name"></Button>

You don't have to use the "clear" option for the "colors" attribute, but I'm putting my UI on a sideboard table, and that lets the image transparency work best for me. Any named color or RGB code should work there.

I've also found that this tends to stretch your image oddly. Workaround in next comment.