- 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.
-`listboxrow:LISTBOX_NAME`: The listbox's selected row number _need testing_
-`listboxtext:LISTBOX_NAME.TEXT_NAME`: The content of a UIText located inside the UIListbox's prototype child. Tip: `UIText` elements with `hidden=true` are useful for storing arbitrary data inside a listbox row
Events attributes 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 callbacks inside double quotes: `OnEvent="Callback('arg0','spaced arg',42)"`. This way it is compatible with XML standards and the callback argument 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 attribute by appending 0, 1, ... to the event attribute name: `OnEvent0="DoThis()" OnEvent1="ThenDoThat()"`. **If event attribute 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 your editor's syntax coloring.
- Any standard-compliant XML parser will fail at parsing NWN2 stock UI files, but NWN2 is able to load files that follows XML standards. 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.
- You can use tools meant to generate HTML/XML files for building NWN2 GUIs much faster: https://www.npmjs.com/package/pug
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.
- 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. :)_
| `ignoreevents="false"` | If true, all events on this pane and all its children will be ignored. Useful if you need to place elements in front of buttons | Boolean |
| `capturemouseclicks="true"` | If false, mouse clicks will go through the node and trigger the associated event on its parents. | Boolean |
| `capturemouseevents="true"` | Not working / do the same as `capturemouseclicks`_need testing_ | Boolean |
| `focusable="true"` | Allow/forbid clicking on the pane _need more info_ | Boolean |
| `handleactiontarget=???` | Allows to drag & drop items on it, or do "cursor actions" on it _need testing & more info_ | Boolean |
| `DefaultTooltip` | Display a strref as tooltip when hovering the pane | Integer (strref) |
| `disabled="false"` | Prevents the player to interact with the pane (apply mostly to buttons) _need to check effects on child elements_ | Boolean |
| `update="false"` | Execute the `OnUpdate` callback(s) when the GUI gets updated (at each client game frame, or set by `UpdateRate`) | Boolean |
| `UpdateRate` | Seconds between two executions of the `OnUpdate` event. | Float |
| `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 |
| `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`) |
| `style=""` | Name of an UIButton style defined in `stylesheet.xml`. The button will inherit all attributes values from its style | See `stylesheet.xml` |
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.
Note: Custom UIScrollbars can be build by placing UIButton children with the names `up`, `down`, `slider`, `back`, similar to how it's done in `stylesheet.xml`.
---
# UICollapsable
A UIPane that can be collapsed or expanded with a button action.
Like `UIListBox` children elements are automatically placed vertically from top to bottom, allowing to easily nest `UICollapsable` inside other `UICollapsable`s.
A tree view can be built using multiple nested `UICollapsable`s with `indent` set to a non-0 value.
## Children
The UICollapsable can have any number of children, but requires at least a `UIButton` element with the `header` attribute set to `true` to be interacted with.
Note: UICollapsable inside other UICollapsable will be be badly offset by the header height if they have `isexpanded=true`. The offset is corrected when collapsing/expanding it manually.
+ 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);`