Update 'nwn-2-gui-scripting.md'

This commit is contained in:
tcharles 2020-01-10 14:50:27 +00:00
parent d59ff6dfab
commit 896a43ae80

View File

@ -8,14 +8,14 @@
# Language
The GUI are written in a non standard form of XML.
The GUI are written in a superset of the standard XML.
- The first line must be something like `<?xml version="1.0" encoding="utf-8"?>`
- 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`
- Auto-closing tags are accepted `<UIText />`
- If you repeat an attribute twice inside the same XML tag, the GUI will not load
- The `UIScene` tag must never be closed
- The `UIScene` tag can be left unclosed
# Rules
@ -34,18 +34,18 @@ The GUI file can store client-side variables that can be either local (limited t
Examples: `local:0`, `local:1337`, `global:42`, ...
## Events
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).
## Event attributes
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
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.
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.
> _TODO_: callback parameter parsing & delimitation (ie what happens if `UIObject_Misc_ExecuteServerScript("A,B","C",D,'E,F','G',H)`)
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**.
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.
@ -58,9 +58,9 @@ The most useful callback is certainly `UIObject_Misc_ExecuteServerScript` that a
+ Executing console commands `DebugMode 1` and `Guidebug`
+ Running [Skywing's client extension](https://neverwintervault.org/project/nwn2/other/nwn2-client-extension) and executing the in-chat command `/guidebug`.
- When an attribute appears twice on the same element, the UI fails to load.
- 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.
- 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
---
@ -73,40 +73,40 @@ Any content placed outside of the UIPane bounds will be clipped.
## Attributes
### Attributes - Positioning & Sizing
| Attribute | Usage | Possible values |
|--------------------------|-----------------------------------------------------------------------|---------------------------------------------------------------|
| `x="0"` | Horizontal offset | Positive integer, `ALIGN_LEFT`, `ALIGN_CENTER`, `ALIGN_RIGHT` |
| `y="0"` | Vertical offset | Positive integer, `ALIGN_TOP`, `ALIGN_CENTER`, `ALIGN_BOTTOM` |
| `width="0"` | Horizontal size | Positive integer, `PARENT_WIDTH`, `SCREEN_WIDTH` |
| `height="0"` | Vertical size | Positive integer, `PARENT_HEIGHT`, `SCREEN_HEIGHT` `DYNAMIC` |
| `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 |
| Attribute | Usage | Possible values |
|--------------------------|---------------------------------------------------------------------------------|---------------------------------------------------------------|
| `x="0"` | Horizontal offset | Positive integer, `ALIGN_LEFT`, `ALIGN_CENTER`, `ALIGN_RIGHT` |
| `y="0"` | Vertical offset | Positive integer, `ALIGN_TOP`, `ALIGN_CENTER`, `ALIGN_BOTTOM` |
| `width="0"` | Horizontal size | Positive integer, `PARENT_WIDTH`, `SCREEN_WIDTH` |
| `height="0"` | Vertical size | Positive integer, `PARENT_HEIGHT`, `SCREEN_HEIGHT` `DYNAMIC` |
| `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 callbacks or nwscript functions | 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.
- Sometimes pane visibility goes wrong when using both nwscript functions and UI callbacks 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. :)_
### Attributes - Event handling
| Attribute | Usage | Possible values |
|-----------------------------|--------------------------------------------------------------------------------------------------------------------------|------------------|
| `ignoreevents="false"` | If true, all events on this pane and all its children will be ignored. _need testing_ | 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` function(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 |
| `dontrendermousegrab` | _need testing_ | Boolean |
| `tupple` | Makes the pane behave like a button, ie can be clicked on, gain focus, lose focus, become enabled, become disabled, etc. | Boolean |
| | | |
| Attribute | Usage | Possible values |
|-----------------------------|---------------------------------------------------------------------------------------------------------------------------------|------------------|
| `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 |
| `dontrendermousegrab` | _need testing_ | Boolean |
| `tupple` | Makes the pane behave like a button, ie can be clicked on, gain focus, lose focus, become enabled, become disabled, etc. | Boolean |
| | | |
### Attributes - Misc
@ -120,11 +120,11 @@ Any content placed outside of the UIPane bounds will be clipped.
| `MouseDragSFX=""` | Sound | Sound file name |
| `MouseDropSFX=""` | Sound | Sound file name |
| `alpha="1.0"` | Opacity. 0: transparent, 1: opaque | Float between [0, 1] |
| `fadealpha=???` | _need info_ Used with `UIObject_Input_SetFadeAlpha` and `UIObject_OnUpdate_FadeAlpha` functions | Float between [0, 1] |
| `fadealpha=???` | _need info_ Used with `UIObject_Input_SetFadeAlpha` and `UIObject_OnUpdate_FadeAlpha` callbacks | Float between [0, 1] |
| | | |
### Events
### Event attributes
- `OnLeftClick`: When the player clicks on the pane
- `OnLeftDoubleClick`: When the player double clicks on the pane
@ -244,7 +244,7 @@ This element the first in the XML file and is always open and never closed. All
| `minwidth` | Defunct | |
| `minheight` | Defunct | |
## Events
## Event attributes
- `OnCreate`: The XML file is read & loaded
- `OnDestroy`: The scene is unloaded from memory, ie: the gui is closed and the `idleexpiretime` timer expired
@ -347,7 +347,7 @@ Define one of these children inside the UIButton element will override the style
[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
## Event attributes
- `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`
@ -381,7 +381,7 @@ Each UIRadialNode can contains either a list of `UISubNode` or an `UIFrame` (can
Each `UIRadialNode` has a `name` property that is referred to in `UISubNode`
#### Events
#### Event attributes
- `OnLeftClickExpanded`
- `OnLeftClickCollapsed`
- `OnInit`: Triggering `UIObject_Misc_ExecuteServerScript` will prevent the GUI from loading (need more info).
@ -403,7 +403,7 @@ The `node` property refers to an existing `UIRadialNode`'s `name` property.
---
# Generic functions
# Generic callbacks
- `UIObject_Misc_ExecuteServerScript(gui_script,arg0,arg1,...)`
+ 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))