- Attributes values can be delimited by `'`, `"` or if not delemited ends with a space
+ Example: this does not work: `OnLeftClick=UIObject_Misc_ExecuteServerScript("gui_myscript","Hello World")` because OnLeftClick value has no delimiter and will end after `Hello`
The GUI file can store client-side variables that can be either local (limited to the current UI) or global (shared across all UIs of a player). They are identified by an integer index, and always store a string value.
Events are special attributes that can trigger [callbacks](#callbacks) when specific actions are executed by the player (ex: clicking a button) or the client's engine (ex: when a frame is rendered).
Callbacks are special attribute values for event attributes, that can execute specific actions either on the client-side (setting local gui variables, changing gui appearance) or on the server-side (executing scripts).
It is better to put functions inside double quotes: `OnEvent="Callback('arg0','spaced arg',42)"`. This way it is compatible with XML standards and the function arguments values can contain spaces. Otherwise the UI won't load because the space will be treated as the end delimiter for the attribute value.
You can execute multiple callbacks on a single event by appending 0, 1, ... to the event name: `OnEvent0="DoThis()" OnEvent1="ThenDoThat()"`. **If event numbers are not ordered correctly, the GUI will not load**.
The most useful callback is certainly `UIObject_Misc_ExecuteServerScript` that allows you to execute a server-side nwscript for any event from any UI element: `OnEvent="UIObject_Misc_ExecuteServerScript('gui_yourscript','AnyArgumentList',local:25)"`. Note: If a player is able to customize any GUI, he can execute arbitrary code on the server, and can be problematic for online servers.
- Often NWN2 GUI files start with `<?xml version="1.0" encoding="utf-8">`. This can be replaced by `<?xml version="1.0" encoding="utf-8"?>` which generally fix syntaxic coloring.
- Any standard-compliant XML parser will fail at parsing NWN2 UI files. You can find a custom XML parser implementation for nwn2 [here](https://github.com/CromFr/NWN2GuiViewer/blob/master/source/nwnxml.d). Warning: written in the D language.
---
# UIPane
This is the most basic UI construction block: an invisible container (similar to HTML `<div>`. Every other elements inherits its properties in a certain fashion.
Any content placed outside of the UIPane bounds will be clipped.
| `draggable="false"` | Allows the user to drag and drop the pane _need more info_ | Boolean |
| `hidden="false"` | Pane visibility. Note: can be changed using gui functions or nwscript | Boolean |
| `hideoverride="false"` | Makes the pane visibility only controllable using nwscript | Boolean |
| `scalewithscene="false"` | Useful when making a fullscreen UI. _need more info_ | Boolean |
| `usescaler="false"` | See notes | Boolean |
- Any children elements that are out of the UIPane bounds will be clipped.
-`height=DYNAMIC` is often used for UIText elements inside a UIListbox, and does not work very well with other use cases.
- Warning: the default value for width or height is 0 and will make the UIPane and its content invisible
- Sometimes pane visibility goes wrong when using both nwscript and UI functions to change the hidden value.
- Notes on `usescaler`: _This tells the code to try and use some logic when this object gets resized in determining where its new X,Y origin should be. For example, if there is a lot of space to the right of the object, it will assume this object was left-anchored and keep the object to the left side with its new position. It's kind of a confusing attribute, all I can say is try it out and see if it does what you want, and don't use it if it doesn't. :)_
| `fullscreen="false"` | Controls if the UI should to be resized to fit the game fullscreen resolution | Boolean |
| `dragregion_x` | Define the dragging handle region _need testing with UIPane_ | Integer |
| `dragregion_y` | Define the dragging handle region _need testing with UIPane_ | Integer |
| `dragregion_width` | Define the dragging handle region _need testing with UIPane_ | Integer |
| `dragregion_height` | Define the dragging handle region _need testing with UIPane_ | Integer |
| `dragresizable="false"` | Allows to resize the UIScene by dragging its edges | Boolean |
| `dragresizeborder` | Width of the edges used to resize the UIScene | Integer |
| `expiretime=0.0` | Delay in seconds before the UI is automatically closed. `0` means never _need testing_ | Float |
| `idleexpiretime=0.0` | Delay in seconds before the UI is unloaded from memory when it is closed. Unloaded UIs re re-loaded from disk when needed | Float |
| `fadein=0.0` | Fade time in seconds when the UI appears on screen | Float |
| `fadeout=0.0` | Fade time in seconds when the UI disappears on screen | Float |
| `modal="false"` | If true, will block player from interacting with other UI elements | Boolean |
| `scriptloadable="false"` | If false, prevent nwscript functions from interacting with the UI _need testing with `UIObject_Misc_ExecuteServerScript`_ | Boolean |
| `backoutkey="true"` | True allows the Esc key to close the UI | Boolean |
| `autolayout="false"` | Automatically place elements in the UIScene. Mostly unusable | Boolean |
| `minwidth` | Defunct | |
| `minheight` | Defunct | |
## Events
-`OnCreate`: The XML file is read & loaded
-`OnDestroy`: The scene is unloaded from memory, ie: the gui is closed and the `idleexpiretime` timer expired
-`OnAdd`: The GUI is made visible
-`OnRemove`: The GUI is closed
-`OnBackout`: The GUI is closed using the escape key (if `backoutkey="true"`)
-`OnUnhandledMouseClick`: when a mouse click has not been handled by any object GUI
-`OnInit`
---
# UIFrame
Inherits from UIPane element.
## Inheritance quirks
- By default `width=PARENT_WIDTH` and `height=PARENT_HEIGHT`
| `strref="-1"` | STRREF to display inside the button | STRREF integer |
| `text=""` | Text to display inside the button | String |
| `repeatcallback="false` | If true, the OnLeftClick event will be triggered on every game frame | Boolean |
| `buttontype=""` | Type of a button if you want radio (only one can be activated at a time) or checkboxes (any can be activated) | `radio`, `check` or undefined |
| `groupid` | Button group ID in case of radio / check buttons | Integer |
| `groupmemberid` | ID of a button inside a group | Integer |
| `color` | Color to blend with the button | Hexadecimal color (ie `ff00ff`) |
| `disabledcolor` | Color to blend when the button is disabled | Hexadecimal color (ie `ff00ff`) |
| `disabledtextcolor` | Color to blend with the button text when the it is disabled | Hexadecimal color (ie `ff00ff`) |
| `style=""` | Name of an UIButton style defined in `stylesheet.xml`. The button will inherit all attributes values from its style | See `stylesheet.xml` |
## Children
UIButtons can contain multiple UIFrame children with the special `state` attribute, that controls when to display the UIFrame:
-`base`: Always displayed (ie: a background image)
-`disabled`: when the button is disabled (`disabled="true"`)
-`up`: When the button is not pressed/selected
-`down`: when the button is pressed/selected
-`focused`: When the player has the focus on the button
-`hilited`: _need info_
-`hifocus`: _need info_
-`header`: _need info_ related to `UICollapsable`
-`hiheader`: _need info_ related to `UICollapsable`
-`downheader`: _need info_ related to `UICollapsable`
You can find examples of this inside `stylesheet.xml`.
### Notes
The UIButton seems to be a kind of template element that automatically adds several children elements that are defined by its style attribute (or a default if none):
These children are:
- One `UIText`, which `text` and `strref` attributes can be set using the UIButton attribute
- Several `UIFrames`, that are shown/hidden depending on the button state, and which `color` attribute can be set using the UIButton attribute.
Define one of these children inside the UIButton element will override the style-defined one.
[Oeiprogrammer](https://oeiprogrammer.blogspot.fr/search/label/uibutton) also mention UIIcon children:
> An unlimited number of UIIcons that will be added to the 'overlay' list for that button. Overlays are extra icons that can be made visible by the engine that stay with the button. At this time, there is no way to manipulate these overlays via script.
## Events
-`OnSelected`: When the user activates the button only if `buttontype` is either `radio` or `check`
-`OnUnselected`: When the user deactivates the button only if `buttontype` is either `radio` or `check`
---
# UIText
# UICollapsable
# UIGrid
# UIListBox
Notes:
- Hiding the listbox scrollbar can cause issues because when you empty/re-fill it, the scrollbar position may be kept.
# UIScrollBar
# UIProgressBar
# Special files
## contextmenu.xml
### UIScene
Using the `OnAdd` event to trigger `UIObject_Misc_ExecuteServerScript` will prevent the GUI from loading.
### UIRadialNode
A collection of buttons in a context menu.
Each UIRadialNode can contains either a list of `UISubNode` or an `UIFrame` (can probably contain other types of elements)
Each `UIRadialNode` has a `name` property that is referred to in `UISubNode`
#### Events
-`OnLeftClickExpanded`
-`OnLeftClickCollapsed`
-`OnInit`: Triggering `UIObject_Misc_ExecuteServerScript` will prevent the GUI from loading (need more info).
### UISubNode
The `node` property refers to an existing `UIRadialNode`'s `name` property.
# Other XML elements
-`UIFontFamily`: Used only in `fontfamily.xml`. Adding new font families can cause weird bugs
-`UI3DScene`: Used for inventory, character portraits, character creation preview, ...
-`UIPointLight`: Used inside `UI3DScene` ti light up the 3d model.
-`UIFontBold`: Used only inside a `UIFontFamily` element
-`UIFontBoldItalic`: Used only inside a `UIFontFamily` element
-`UIFontItalic`: Used only inside a `UIFontFamily` element
-`UIFontNormal`: Used only inside a `UIFontFamily` element
+ Execute a server side script. The script must start with the `gui_` prefix (unless you are using [Skywing's AuroraServerNWScript nwnx4 plugin](http://www.nwnx.org/phpBB2/viewtopic.php?t=1803))
-`UIObject_Input_SetFadeAlpha(1.0)`
+ Need testing
-`UIObject_OnUpdate_FadeAlpha(0.25)`
+ Need testing
-`UIText_OnUpdate_DisplayLocalVar(local:1)`
+ Displays local var value in the text field. Does not render tags like `<i><b><color>`.
# NWScript functions
## SetGUITexture
-`void DisplayGuiScreen( object oPlayer, string sScreenName, int bModal, string sFileName = "", int bOverrideOptions = FALSE);`