Space Engineers

Space Engineers

Not enough ratings
XUI Documentation
By Significant Otter
XUI is an XML based UI framework (delivered as ingame script) that aims at solving most of the problems that you are presented with when making UIs for LCD/Text panels.
For example it allows you, to create interactive menus, working hyperlinks, progressbars, text input fields with nearly no programming (no. Writing xml code is not programming :P).
Even centering and aligning of text is possible with simple xml attributes.

This guide will help you getting started and utilizing all basic features of the framework.

The framework itself can be found here.
   
Award
Favorite
Favorited
Unfavorite
Introduction
With LCD panels being in the game for a very long time, the idea to utilize them for displaying relevant data or even interactive interfaces (in combination with button panels) comes very naturally. Unfortunately this task - as straight forward as it sounds - is a difficult and cumbersome one - especially when it comes to interactivity.
This is the reason why I've created the XUI framework. It's a simple to use and very powerful tool to create almost anything that you could wish for in terms of interfaces.

You can simply write xml code which it will transfer to a nicely formatted output on the lcd panel. The script can even include links to other pages or retrieving data from input fields - making it a very versatile tool.

Furthermore it is very easy to set up a button panel for interaction with the script. Most interface elements recognize and react to certain key codes which need simply be passed as arguments to the programmable block the script lives in.
Explanation
The Framework consists of a static wrapper class XML, which contains all important classes and methods, for example the xml parser and all xml element definitions.

The method for parsing an xml string can be called as follows:
XML.ParseXML("some<br/>xml");

But you won't necessarily need this method, because you will mostly use the UIController class, which offers a lot of utility and convenience methods.

The UIController class

To actually render xml onto a text panel, you need to create an instance of the UIController class. I recommend using the the following method for that purpose:
XML.UIController ctrl = XMl.UIController.FromXML(xmlString)
Otherwise you can call a constructor of UIController with an XMLTree object (more information below).

To render the ui onto a text panel, simply call
ctrl.RenderTo(textPanel);
from your UIController object (textPanel is a IMyTextPanel object).

To apply text panel properties defined in the xml string to the text panel, there is another simple method:
ctrl.ApplyScreenProperties(textPanel);

For transmitting key codes or other instructions to the UIController, use it's Call(List<string>) method, e.g.:
ctrl.Call(new List<string> ["key", "up"]);

There is a convenience method contained in the framework for splitting up the programmable blocks parameters into lists like that; feel free to use it:
List<string> parameters = Parser.ParameterString2List(argument);

The XMLTree class
Once parsed, any xml node is represented by an instance of the class XML.XMLTree (or deriving from it). Any of these objects can have multiple child elements as you would expect from an xml representation. the field
XML.XMLTree.Type
contains the xml element name (the same string you would define the element with in an xml string, e.g. <elementname/>). That makes it easy to find, filter or select xml elements by type (relevant methods are described in the API Documentation).
Furthermore, any xml element can have any xml attribute, consisting of an attribute name and an attribute value. XML.XMLTree provides methods to define those attributes:
XML.XMLTree element = new XML.Menu() as XML.XMLTree; element.SetAttribute("animal", "snake"); Echo(element.GetAttribute("animal")); // will output 'snake'.

If you want to use the monospace font rather than SEs default font, you have to define it manually at the moment (since I unfortunately havent't found a way to read the current setting from the text panel):
TextUtils.SelectFont(TextUtils.FONT.MONOSPACE);
To select the default font again, use:
TextUtils.SelectFont(TextUtils.FONT.DEFAULT);

The full documentation of the XMLTree clas can be found in the chapter API Documentation.

To wrap this up, here a minimal example to print a xml ui on a text panel:
IMyTextPanel screen = GridTerminalSystem.GetBlockWithName("UIPanel") as IMyTextPanel; XML.UIController ui = UIController.FromXML("<uicontrols>Title</uicontrols>"); ui.ApplyScreenProperties(screen); ui.RenderTo(screen);
XML Documentation
XML nodes are usually defined as
<nodename attributename='attributevalue'>content</nodename>
You can also use double quotes for attributes - don't forget to escape them in the string definition. If you don't need the nodes content, you can also use the following syntax:
<nodename attributename='attributevalue'/>

There are some attributes which can either have the value "true" or "false" (boolean attributes). In this case you can just leave them out completely (equals value "false") or add them like this (equals value "true"):
<nodename booleanattribute></nodename>

If you define unkown xml elements they will result in generic nodes containing all their attributes and rendering content and child nodes without modification. You can also add your own xml node definitions; refer to the chapter 'Extending the Framework'.
These are the currently implemented XML elements and attributes:

All xml elements (even generic ones) will interprete the following attributes:
Universal Attributes
alignSelf
possible values: "left", "center", "right"[/b]
defines the xml nodes outer alignment.
width
possible values: "<integer>", "<integer>%"
sets the elements width (if only an integer is given, this will refer to the unit used by the SE font).
alignChildren
possible values: "left", "center", "right"
defines the xml nodes childrens alignment (even inner text).
selected
possible values: "true", "false" (boolean)
automatically selects this xml node (!currently broken!)
selectable
possible values: "true", "false" (boolean)
defines if this node should be selectable.
flow
possible values: "vertical", "horizontal"
defines the direction of the text flow inside the xml node.
value
possible values:"<anything>"
defines the value which will be retrieved by UIContoller.GetValues() (refer to chapter "API Basics").

<menu></menu>
Serves as a container for menuitem elements.
content rendering: yes

<menuitem></menuitem>
Defines a menuitem as part of a menu. Is selectable by default.
content rendering: yes
route
possible values: "xml:<XmlDefinition>", "fn:<RegisteredRouteFunctionId>" (for more information on routes refer to chapter "Hyperlinks and Routing")

<progressbar></progressbar>
Defines a progressbar. Can be set to selectable to allow interaction (set by default). The progressbar's value attribute defines to which extent it will be rendered filled (values from 0.1 to 1).
content rendering: no
filledString
possible values: "<any string>"
The string to create the filled portion of the progressbar from.
emptyString
possible values: "<any string>"
The string to create the empty portion of the progressbar from.
stepSize
possible values: "<float between 0.0 and 1.0>"
defines the amount to be added/subtracted to the fillLevel on interactively increasing/decreasing it (probably only relevant if selectable="true").

<container></container>
XML element used for grouping child elements
content rendering: yes

<hl></hl>
Renders a horizontal line.
content rendering: no

<uicontrols></uicontrols>
Renders an element with a navigation component to revert the ui if the ui stack is not empty (refer to UIContoller.RevertUI() in chapter "API Basics"; set to selectable by default).
content rendering: yes

<textinput></textinput>
Renders a textinput field, which can be operated interactively with key codes (for information how to setup a button panel refer to ...). Default value is "".
content rendering: no
maxlength
possible values: "<int greater than 0>"
defines the maximum length to be entered.

<submitbutton></submitbutton>
Defines a submitbutton which will open a route (if defined). Is selectable by default.
content rendering: yes
route
possible values: "xml:<XmlDefinition>", "fn:<RegisteredRouteFunctionId>" (for more information on routes refer to chapter "Hyperlinks and Routing")

<br></br>
Adds a line break.
content rendering: no

<space></space>
Adds a spacer using the width attribute. Currently redundant with an empty container, so might be removed in the future.
content rendering: no

<hidden></hidden>
A xml attribute which is not being rendered but can store values (using the value attribute).
content rendering: no

<hiddenData></hiddenData>
A xml attribute which is not being rendered but can store values (using any attribute, not only the value attribute).
content rendering: no

<generic></generic>
'generic' can be replaced by any string, and will be created as a generic XMLTree with the type set to the element name. The resulting generic xml element will not have any special behaviour, but can be used for example for data storage.

<meta></meta>
The screen properties can be defined inside the xml definition by the <meta/> element. I recommend putting this element first in the xml definition for the sake of readability. It will not be rendered on the screen.
content rendering: no
fontSize
possible values: "<float greater than 0 and less than 10>"
Defines the font size value of the text panel.
fontColor
possible values: "<RRGGBB with R,G,B=hexadecimal number between 0 and F>"
Defines the font color of the text panel.
backgroundColor
possible values: "<RRGGBB with R,G,B=hexadecimal number between 0 and F>"
Defines the background color of the text panel.
historyDisabled
possible values: "true", "false" (boolean)
If set to "true", the xml ui will not be saved to the history (i.e. ui stack).
refresh
possible values: any route definition string that will be accepted by the constructor:
new XML.Route(definitionString);
If defined, the uiController will try to follow this route (i.e. call uiController.FollowRoute(new Route(definitionString);) every time, uiController.Call(["refresh"]) is being executed.
revert
possible values: "true", "false" (boolean)
If set to "true", the uiController will not load this ui, but instead revert to the last ui on the ui stack (if possible).
Data Handling
Retrieving data
Any xml element can carry data, which can be retrieved. In most cases this is done by the name and value attributes. You can get the data of the whole ui by calling the method GetValues() of the UIController object. It will return a Dictionary<string, string> of values, the key corresponding to an xml elements name attribute and the value corresponding to its value attribute.
To only get an excerpt of the available data you can call the GetValues method with a filter function, which expects an XMLTree object as parameters and returns a boolean.
Accordingly, the following example would return all values of progressbar elements:
uiController.GetValues( node => node.Type == "progressbar" );

You might at one point or another want to serialize data (for example to save it). For this purpose the UIController has a method GetPackedValues() which will return a xml attribute string. This could for example look like the following:
"surname='Pete' lastname='Maggins' age='34'"

Note: There is one xml element, which will not only store the value attributes value, but any attribute-name-value-combination. THis is the hiddendata element (refer to the XML Documentation).

Setting data
Other than defining xml attributes directly in the xml definition before it is parsed or changing it interactively using buttons (refer to the chapter on interactivity), you can set and change values programmatically by calling an XMLTree objects method SetAttribute(string attributeName, string attributeValue). There exists a similar method (XMLTree.GetAttribute(string attributeName)) for retrieving data as well.
Hyperlinks and View handling
Hyperlinks in XUI are done by so-called routes. Routes are defined by a xml attribute in the form
route='<type>:<content>'
. This element is only interpreted by some xml elements; those are <menuitem/> and <submitbutton/>.

Per default there are 2 types of routes. The more simple one is 'xml'; routes of this type defined the page that's being linked to by simply providing an xml string, e.g.:
<menuitem route='xml:<uicontrols>Second Page</uicontrols>'>Link</menuitem>
This should be straight forward to understand.

The second route type is the function route. A function route is defined like this:
<menuitem route='fn:functionName'>Link</menuitem>
To be able to recognize a function name you have to register a function with this name. This is done by calling the static method
XML.RegisterRouteFunction(string id, Action<UIController> fn)
.This way you can register an Action, that is called, when the link (or menuitem or submitbutton...) is activated. It will receive a reference to the uicontroller as parameter. That way, you can do the following things in that Action:

1. Retrieve data from the ui (refer to the Data Handling chapter on information how to do this).
2. Load a new ui page (refer to the chapter 'API Documentation', in particular the method XML.UIController.LoadUI(XMLTree ui)).
3. Revert to a previous ui page (XML.UIController.RevertUI()).
4. Anything you can imagine. :P

If you want to have your route function executed multiple times, you can load a ui with a refresh attribute in the meta element. This attributes value can be set to the route definition (remember: 'fn:functionName'). In that case, any time you call
uiController.Call("refresh")
, the route function will be executed (until of course, you change the ui).
API Documentation Part 1
class XML.UIController
This is your basic interface to most of the frameworks features. You will always need an instance of this class for rendering, retrieving data, executing key commands on the ui, etc.

XML.UIController properties:
Stack<XMLTree> UIStack
Contains the history of ui pages.
string Type
Is set to "CTRL". Can be used to distinguish XML.UIController instances from XML.XMLTree instances.

XML.UIController methods:
Constructor(XMLTree rootNode);
Creates an instance of XML.UIController and loads 'rootNode' as ui.p
UIController FromXML(string xmlString);
returns a UIController object, containing the specified xml tree.
void RenderTo(IMyTextPanel screen);
renders the current xml tree onto the specified text panel.
string Render();
Returns the rendered UI as string. !!!This does not support centering and aligning, because no screen is referenced.!!!
void ApplyScreenProperties(IMyTextPanel screen);
applies the screen properties (bg color, text color, text size) contained in the current xml ui to the specified text panel
void LoadXML(string xmlString);
loads another xml definition as current ui. The former ui (if the 'history-disabled' flag is not set) will be saved on the ui stack
void LoadUI(XML.XMLTree xmlTree);
loads another xml tree as current ui. The former ui (if the 'history-disabled' flag is not set) will be saved on the ui stack
void RevertUI();
Drops the current ui and restores the last one on the ui stack. If the ui stack is empty, this method will not have any results.
void ClearUIStack()
Clears history.
string Render();
Returns a string containing the rendered xml ui (ready to print it onto a text panel). !This method does not support text aligning/centering, since this feature requires more information about the target text panel!
void Call(List<string> parameters);
This method can be called with one of the following parameter lists:
["refresh"] - rerenders the ui (in case it is rendered from a route).
["revert"] - reverts the ui (compare method RevertUI())
["key", keycode] - transmitts key stroke to the ui. For available key codes refer to ...
XML.XMLTree GetSelectedNode();
returns the currently selected xml node as XMLTree.
void FollowRoute(Route route);
Follows the given route. For more information about routes refer to the chapter "Hyperlinks and Routing"
Dictionary<string, string> GetValues();
Retrieves values of all (named) xml nodes. For example for evaluating formulars.
Dictionary<string, string>GetValues(Func<XMLTree, bool> filter);
Retrieves values of all (named) xml nodes for which filt(node) returns true.
string GetPackedValues();
Retrieves values of all (named) xml nodes as xml attribute string. Useful for saving data or transmitting data to another programmable block.
string GetPackedValues(Func<XMLTree, bool> filter);
Retrieves values of all (named) xml nodes, for which filter(node) returns true, as xml attribute string.
bool SelectNext();
Tries to select the next selectable xml element and returns true if successful, else false.
XMLTree GetNode(Func<XMLTree, bool> filter);
Returns the first node for which filter(node) returns true or null if none found.
List<XMLTree> GetAllNodes(Func<XMLTree, bool> filter);
Returns a list of all nodes for which filter(node) returns true.

class XML.Route
Instances of this class define what shall be done, when a user clicks on a link/menuitem/submitbutton...

XML.Route methods:
Constructor(string definition)
Creates a new route from the given definition.
void Follow(UIController controller)
Follow the route.
static void RegisterRouteFunction(string id, Action<UIController> fn)
Register a function with the given id
API Documentation Part 2
abstract class XML.XMLTree
This is the base class of any xml element object. It implements a tree structure with a variable number of children per parent.

XML.XMLTree properties:
string Type
Is set to the element name (for example "submitbutton" for a submitbutton element).

XML.XMLTree methods:
Constructor()
Returns an instance of the class XML.XMLTree (can only be called from derived classes, since XML.XMLTree is abstract).
bool IsSelectable()
Returns true if the xml element is selectable, else false.
bool IsSelected()
Returns true if the xml element is selected, else false.
XMLTree GetSelectedSibling()
Returns the selected sibling (child or sibling of child), if any.
void AddChild(XMLTree child)
Adds child to the XMLTree object.
XMLParentNode GetParent()
Returns the xml elements parent or null, if it has none.
XMLTree GetChild(int i)
Returns the child with index i, or null if no child with that index exists.
XMLTree GetNode(Func<XMLTree, bool> filter)
returns the first node of this node and its siblings for which filter(node) returns true or null if no such node is found.
List<XMLTree> GetAllNodes(Func<XMLTree, bool> filter)
Returns a list of all nodes of this node and its siblings for which filter(node) returns true.
bool SelectFirst()
Tries to select the first child. Returns true if this was successfull, else false.
bool SelectLast()
Tries to select the last child. Returns true if this was successfull, else false.
bool SelectNext()
Tries to select the next child. Returns true if this was successfull, else false.
bool SelectPrevious()
Tries to select the previous child. Returns true if this was successfull, else false.
string GetAttribute(string attributeName)
Returns the specified attributes value or null, if no attribute of this name was found.
void SetAttribute(string name, string value)
Sets the specified attribute to the specified value.
void OnKeyPressed(string keyCode)
Triggers key press event on node.
void PreventDefault(string keyCode)
Configures the xml element to prevent the corresponding key press event to be propagated to the parent node.
void AllowDefault(string keyCode)
Configures the xml element to allow the corresponding key press event to be propagated to the parent node.
void FollowRoute(Route route)
Tries to find a parent (usually the ui controller) which is able to follow the given route.
Dictionary<string, string> GetValues(Func<XMLTree, bool> filter)
Returns the values of any node in this node and all siblings for which filter(node) returns true.
int GetWidth(int maxWidth)[/i]Returns the resulting width, determined by the width attribute and the maximum available width.[/i]
string Render(int availableWidth)
Returns the element rendered into a string with respect to the available width.
Extending the Framework
Work in progress. Will be added soon.
3 Comments
zorgkirill Dec 20, 2017 @ 9:58am 
kakoi-to huiovuy freimwork
Significant Otter  [author] Jan 16, 2017 @ 5:43pm 
If I can help you somehow, just ask. ^^

Also, it might help to have a look into the comprehensive tutorial first: https://steamcommunity.com/sharedfiles/filedetails/?id=791130491
Cthulhu Jan 16, 2017 @ 1:48pm 
If i understood this one right... this is fucking awesome... but i think i have to read it again :X