--- title: Nwn 2 Gui Scripting description: A quick summary of Nwn 2 Gui Scripting published: 1 date: 2020-05-21T20:50:36.442Z tags: --- # Click here to edit this page: https://wiki.tcharles.fr/e/en/nwn-2-gui-scripting # Resources - [oeiprogrammer](https://oeiprogrammer.blogspot.fr) # Language The GUI are written in a superset of the standard XML. - The first line must be something like `` - 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 `` - The `UIScene` tag can be left unclosed # Rules ## File name The XML file name must not exceed 32 characters (TODO: with or without extension?) ## Stacking - Elements with the same parent will be stacked from top to bottom. For example with ``, A will appear over B ## Variables 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. Examples: `local:0`, `local:1337`, `global:42`, ... ### Listbox variables - `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 ## 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 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 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. # Tips & Tricks - When developing add the attribute `idleexpiretime="0.1"` to the UIScene. This allows the UI file to be reloaded every time you close it in-game. - You can trace UI events by: + 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 ``. This can be replaced by `` 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 --- # UIPane This is the most basic UI construction block: an invisible container (similar to HTML `
`. Every other elements inherits its properties in a certain fashion. 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 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 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. 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 | Attribute | Usage | Possible values | |-------------------|-------------------------------------------------------------------------------------------------|----------------------| | `name=""` | Name (more like an ID) of the UI Pane to retrieve it | String | | `hotbartype` | ?? | | | `MouseOverSFX=""` | Sound to play when the mouse goes over | Sound file name | | `MouseDownSFX=""` | Sound | Sound file name | | `MouseUpSFX=""` | Sound | Sound file name | | `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` callbacks | Float between [0, 1] | | | | | ### Event attributes - `OnLeftClick`: When the player clicks on the pane - `OnLeftDoubleClick`: When the player double clicks on the pane - `OnRightClick`: When the player right clicks on the pane - `OnRightDoubleClick`: When the player right double clicks on the pane - `OnMouseDrop`: Drag & drop related event - `OnMouseDropReceived`: Drag & drop related event - `OnMouseDropFailed`: Drag & drop related event - `OnMouseEnter`: Mouse go over the pane - `OnMouseLeave`: Mouse go out of the pane - `OnGainedFocus`: For example when starting to edit a UIText _need testing_ - `OnLostFocus`: For example when clicking outside of the UIText you were editing _need testing_ - `OnResize`: _need info on resizing panes_ - `OnToolTip`: When the user keep the mose over the pane for a few seconds + `UIObject_Tooltip_DisplayTooltipString('Your custom tooltip',OBJECT_X,OBJECT_Y,SCREEN_TOOLTIP_2,ALIGN_NONE,ALIGN_NONE,0,0,ALIGN_LEFT)` * Display a small tooltip - `OnRadialRequestDefaultTooltip`: _need info_ --- # UIScene Inherits from UIPane element. This element the first in the XML file and is always open and never closed. All elements below are treated as UIScene children. ```xml ``` ## priority attribute | Value | Usage | |-------------------------------------|-----------------------------------------------------------------------| | `SCENE_SCRIPT` | GUIs brought up by script | | `SCENE_TOOLTIP` | Appears on top of any other GUI | | `SCENE_GLOBAL` | Used for messageboxes generally. | | `SCENE_FE_FULLSCREEN` | Pre-game full screen GUIs | | `SCENE_INGAME_FULLSCREEN` | Full screen GUIs within the game. | | `SCENE_INGAME_SYSTEM` | Escape menu and options screens. | | `SCENE_NWN1_DIALOG` | NWN1 style dialog box _differences with `SCREEN_QUICKCHAT` ?_ | | `SCENE_INGAME_MENU` | The popup player menu | | `SCENE_INGAME` | Most of the windows in-game | | `SCENE_INGAME_TARGET` | The target box | | | | | `SCREEN_FADE` | The first UIIcon object will be used as the fade background | | `SCREEN_QUICKCHAT` | NWN1 style dialog box _differences with `SCENE_NWN1_DIALOG` ?_ | | `SCREEN_CUTSCENE` | NWN2 style cutscenes | | `SCREEN_CONTEXTMENU` | The rightclick menu system | | `SCREEN_MINIMAP` | The in-game minimap GUI | | `SCREEN_AREAMAP` | Full-sized area map | | `SCREEN_MESSAGEBOX_SPLITSTACK` | Used for splitting stacks of items in inventory | | `SCREEN_MESSAGEBOX_SPLITSTACKSTORE` | Used for splitting stacks of items for stores | | `SCREEN_MESSAGEBOX` | Generic message box popups spawned using nwscript `DisplayMessageBox` | | `SCREEN_STRINGINPUT_MESSAGEBOX` | Generic input box popups spawned using nwscript `DisplayInputBox` | | `SCREEN_MESSAGE` | Unusable | | `SCREEN_HOTBAR` | Hotbar system _need info_ | | `SCREEN_HOTBAR_2` | Hotbar system _need info_ | | `SCREEN_HOTBAR_V1` | Hotbar system _need info_ | | `SCREEN_HOTBAR_V2` | Hotbar system _need info_ | - `SCREEN_QUICKCHAT`: NWN2 will search the following elements names, and fill them. + `npclistbox` - Listbox of NPC spoken text + `npctext` - Text field for NPC spoken text (Contained by `npclistbox` generally) + `replieslistbox` - Listbox of Player Reply options + `skipdialogbutton` - Button for skipping through the NPC spoken nodes + `speakername` - Text field for containing the speaker's name + `portrait` - UIPortrait object + All but the speakername and portrait fields are necessary or the window will not be loaded. - `SCREEN_CUTSCENE`: NWN2 will search the following elements names, and fill them. + `topbar`: UIFrame for the top black bar + `bottombar`: UIFrame for the bottom black bar + `FULLSCREEN_IMAGE`: UIIcon used for full screen images. + `toplistbox`: Listbox to contain the text shown on top + `toplistboxtext`: Textfield contained by toplistbox + `bottomlistbox`: Listbox to contain the text shown on the bottom. Spoken by NPCs + `bottomlistboxtext`: Text field contained by bottomlistbox + `replieslistbox`: Listbox to contain the replies available to a player. + `skipdialogbutton`: Fullscreen button for clicking through the dialog + Failure to locate any of the above objects will result in the screen not loading. - `SCREEN_MESSAGEBOX`: NWN2 will search the following elements names, and fill them. - `messagetext`: Text field that contains the message. - `okbutton`: Button that will execute the OK callback - `cancelbutton`: Button that will execute the Cancel callback - `messageboxlb`: Listbox for containing the message text in case the text gets long. - `MSGBOX_BACKGROUND`: Frame used for the background, this one is optional. ## Attributes | Attribute | Usage | Possible values | |--------------------------|---------------------------------------------------------------------------------------------------------------------------|-----------------| | `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 | | ## 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 - `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` ## Attributes | Attribute | Usage | Possible values | |-----------------------|---------------------------------------------------------------------------------------------------|---------------------------------| | `fill=""` | Pattern to use to fill the element. The value is the resource name, with its extension. | Image file name with extension | | `fillstyle="stretch"` | Texture filling method | `stretch`, `center`, `tile` | | `border` | Thickness of the border in pixels | Integer | | `top` | Texture for the UIFrame border | Image file name with extension | | `topright` | Texture for the UIFrame border | Image file name with extension | | `left` | Texture for the UIFrame border | Image file name with extension | | `right` | Texture for the UIFrame border | Image file name with extension | | `bottomleft` | Texture for the UIFrame border | Image file name with extension | | `bottom` | Texture for the UIFrame border | Image file name with extension | | `bottomright` | Texture for the UIFrame border | Image file name with extension | | `color` | Color to blend with the UIFrame images (rgb multiplication? __need info__) | Hexadecimal color (ie `ff00ff`) | | `mhtop` | Do not seem to work (see [oeiprogrammer](https://oeiprogrammer.blogspot.fr/search/label/uiframe)) | | | `mhbottom` | Do not seem to work (see [oeiprogrammer](https://oeiprogrammer.blogspot.fr/search/label/uiframe)) | | | `mvleft` | Do not seem to work (see [oeiprogrammer](https://oeiprogrammer.blogspot.fr/search/label/uiframe)) | | | `mvright` | Do not seem to work (see [oeiprogrammer](https://oeiprogrammer.blogspot.fr/search/label/uiframe)) | | | `mhside` | Do not seem to work (see [oeiprogrammer](https://oeiprogrammer.blogspot.fr/search/label/uiframe)) | | | `mvside` | Do not seem to work (see [oeiprogrammer](https://oeiprogrammer.blogspot.fr/search/label/uiframe)) | | | `maside` | Do not seem to work (see [oeiprogrammer](https://oeiprogrammer.blogspot.fr/search/label/uiframe)) | | --- # UIIcon Very similar with the UIFrame element. Inherits from UIPane element. ## Attributes | Attribute | Usage | Possible values | |-----------|-----------------|--------------------------------| | `img=""` | 2D texture file | Image file name with extension | --- # UIButton ## Attributes | Attribute | Usage | Possible values | |-------------------------|---------------------------------------------------------------------------------------------------------------------|---------------------------------| | `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` | | `header=false` | This button is the UICollapsable's header button | Boolean | | | | | ## 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 (`UICollapsable` was opened and has just been closed) - `down`: when the button is being pressed or is selected (`UICollapsable` is collapsed and will be opened) - `focused`: When the player has the focus on the button (`UICollapsable` is collapsed) - `hilited`: when the button is being hovered (`UICollapsable` is collapsed) - `hifocus`: when the button has the focus **and** is being hovered (`UICollapsable` is collapsed) - `header`: Only usable when the `UIButton` is inside a `UICollapsable`: when the `UICollapsable` is open - `hiheader`: Only usable when the `UIButton` is inside a `UICollapsable`: when button is being hovered while the `UICollapsable` is open - `downheader`: Only usable when the `UIButton` is inside a `UICollapsable`: when button is being pressed while the `UICollapsable` is close 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. ## 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` --- # UIText # UIGrid --- # UIListBox UIListBoxes serve two purposes: - Provide a scrollable view, where elements are automatically placed vertically from top to bottom - Provide a container that can be filled with rows by some NWScript See [Listbox variables](#listbox-variables) for special variables related to listboxes. ## Children If no `y` position is defined _need confirmation_, children of a listbox are dynamically placed from top to bottom. If a child element has the attribute `prototype` set to `true`, the element will be used as a row template. Any row added to the listbox using `AddListBoxRow` will copy the prototype child and append it to the listbox. You must add a `UIScrollBar` child, otherwise no scrollbar will be visible. ## Attributes | Attribute | Usage | Possible values | |------------------------------------|---------------------------------------------------------------------------------------------------------------------|-----------------| | `showpartialchild=true` | `false` will hide children that don't have enough space to be fully displayed | Boolean | | `unequalcontrols` | Set to `false` if each listbox child has the same height, to improve scrolling performance. Set to `true` otherwise | Boolean | | `xPadding` | Horizontal space between two children of the listbox | Integer | | `yPadding` | Vertical space between two children of the listbox | Integer | | `snaptobottom=false` | `true` will keep the listbox scrolled all the way down when adding children | Boolean | | `scrollsegmentsize` | Number of pixels the listbox content is moved when scrolling it with the wheel or by clicking the scrollbar arrows | Integer | | `scrollbaronright=true` | Set to `false` to move the scrollbar to the left side of the listbox | Boolean | | `selectonleftclick=false` | If `true`, clicking a row will make it selected (probably for `listboxtext:LBName.UITxtName` _need testing_) | Boolean | | `hidescrollbarwhennotneeded=false` | If `true` the scrollbar will be hidden when scrolling is not necessary. | Boolean | | `hidescrollbar=false` | `true` to always hide the scrollbar | Boolean | | | | | ### Notes - `hidescrollbarwhennotneeded` `hidescrollbar`: It is better to keep those to `false`, as sometimes the scroll position is kept when removing/adding content, and you can end up having a UIListbox with some content but no visible scrollbar nor children. ## NWScript The following functions in NWScript can interact with listbox rows: ##### ClearListBox ```c void ClearListBox( object oPlayer, string sScreenName, string sListBox ); ``` Remove all rows from a `UIListBox` - `oPlayer`: player object - `sScreenName`: `UIScene` `name` attribute - `sListBox`: `UIListBox` `name` attribute ##### AddListBoxRow ```c void AddListBoxRow( object oPlayer, string sScreenName, string sListBox, string sRowName, string sTextFields, string sTextures, string sVariables, string sHideUnhide ); ``` Adds a new row into a `UIListBox` - `oPlayer`: player object - `sScreenName`: `UIScene` `name` attribute - `sListBox`: `UIListBox` `name` attribute - `sRowName`: a string identifier for the row (__needs testing__) - `sTextFields`: List of `UIText` elements to set the `text` attribute. + Examples: `TEXT_ELEMENT_NAME=Hello world`, `ITEM_NAME=Great sword;PRICE=42` (TODO: test if the element test lookup is restricted to the listbox content, i.e. if there are issues if there are multiple elements with the same name) - `sTextures`: List of `UIFrame` (TODO: or `UIIcon` ?) elements to set the image/icon. + Examples: `FRAME_ELEMENT_NAME=ia_attack.tga`, `ITEM_ICON=it_am_scalemail00.tga;ITEM_CAT_ICON=b_armor_normal.tga` - `sVariables`: GUI variables to set? (__needs testing__) - `sHideUnhide`: List of UI elements to show or hide. + Examples: `ELEMENT_NAME=hide`, `BUTTON_ATTACK=hide;BUTTON_BEFRIENDS=show` ##### ModifyListBoxRow ```c void ModifyListBoxRow( object oPlayer, string sScreenName, string sListBox, string sRowName, string sTextFields, string sTextures, string sVariables, string sHideUnhide ); ``` Modifies an existing row inside a `UIListBox`. The parameters are the same as `AddListBoxRow` --- # UIScrollBar 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. When collapsed (closed), the UICollapsable's height will be the height of the header UIButton element. When expanded (opened), UICollapsable's height will be the height defined as the `height` attribute. The UICollapsable works particularly well inside a UIListbox, since content will be automatically rearranged when the UICollapsable changes its height. 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. ## Attributes | Attribute | Usage | Possible values | |----------------|------------------------------------------------------|-----------------| | `isexpanded` | `true` will make the collapsable expanded by default | Boolean | | `collapselock` | | Boolean | | `indent=0` | Space on the left of the children elements | Integer | | `xPadding=0` | horizontal space between around elements | Integer | | `yPadding=0` | vertical space between around elements | Integer | --- # UIProgressBar A progress bar that can be controlled by NWScript. The progress bar basically clips the image given as the `img` attribute depending on the progress value. ## Attributes | Attribute | Usage | Possible values | |------------------|----------------------------------------------------------------------|-----------------| | `img` | Image to use as the progress bar foreground | Boolean | | `vertical=false` | `true` to make the progress bar vertical | Boolean | | `lerpincrease` | `true` make the progress indicator move more smoothly _need testing_ | Boolean | | `lerpdecrease` | `true` make the progress indicator move more smoothly _need testing_ | Boolean | ## NWScript ##### SetGUIProgressBarPosition ```c void SetGUIProgressBarPosition( object oPlayer, string sScreenName, string sUIObjectName, float fPosition ); ``` Sets the progress of a UIProgressBar - `oPlayer`: player object - `sScreenName`: `UIScene` `name` attribute - `sUIObjectName`: `UIProgressBar` `name` attribute - `fPosition`: Percent of completeness of the `UIProgressBar`, between 0 and 1 ##### SetScrollBarRanges ```c void SetScrollBarRanges( object oPlayer, string sScreenName, string sScrollBarName, int nMinSize, int nMaxSize, int nMinValue, int nMaxValue ); ``` TODO: does it work for progress bars? ##### SetScrollBarValue ```c void SetScrollBarValue( object oPlayer, string sScreenName, string sScrollBarName, int nValue ); ``` TODO: does it work for progress bars? # Special files ## contextmenu.xml Manage all in-game right click menus. ### 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` #### Event attributes - `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. ## stylesheet.xml Defines styles for buttons and scrollbars ## fontfamily.xml Defines font styles and variants. ```xml ``` # 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 - `UIHotbarButton` - `UIPortrait` - `UITextTree` --- # 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)) - `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 ``. # NWScript functions ## SetGUITexture - `void DisplayGuiScreen( object oPlayer, string sScreenName, int bModal, string sFileName = "", int bOverrideOptions = FALSE);` - `void CloseGUIScreen( object oPlayer, string sScreenName );` - - `void SetLocalGUIVariable( object oPlayer, string sScreenName, int nVarIndex, string sVarValue );` - `void SetGlobalGUIVariable( object oPlayer, int nVarIndex, string sVarValue );` - - `void SetGUITexture( object oPlayer, string sScreenName, string sUIObjectName, string sTexture );` - `void SetGUIObjectHidden( object oPlayer, string sScreenName, string sUIObjectName, int bHidden );` - `void SetGUIObjectDisabled( object oPlayer, string sScreenName, string sUIObjectName, int bDisabled );` - `void SetGUIObjectText( object oPlayer, string sScreenName, string sUIObjectName, int nStrRef, string sText );` - Set a ``'s text. The text will render tags like `` correctly - `void SetGUIProgressBarPosition( object oPlayer, string sScreenName, string sUIObjectName, float fPosition );` - `void SetGUITexture( object oPlayer, string sScreenName, string sUIObjectName, string sTexture );` - `void SetScrollBarRanges( object oPlayer, string sScreenName, string sScrollBarName, int nMinSize, int nMaxSize, int nMinValue, int nMaxValue );` - `void ClearListBox( object oPlayer, string sScreenName, string sListBox );` - `void AddListBoxRow( object oPlayer, string sScreenName, string sListBox, string sRowName, string sTextFields, string sTextures, string sVariables, string sHideUnhide );` - `void ModifyListBoxRow( object oPlayer, string sScreenName, string sListBox, string sRowName, string sTextFields, string sTextures, string sVariables, string sHideUnhide );` - `void SetScrollBarValue( object oPlayer, string sScreenName, string sScrollBarName, int nValue );` - `void DisplayMessageBox( object oPC, int nMessageStrRef, string sMessage, string sOkCB="", string sCancelCB="", int bShowCancel=FALSE, string sScreenName="", int nOkStrRef=0, string sOkString="", int nCancelStrRef=0, string sCancelString="" );` - `void DisplayInputBox( object oPC, int nMessageStrRef, string sMessage, string sOkCB="", string sCancelCB="", int bShowCancel=FALSE, string sScreenName="", int nOkStrRef=0, string sOkString="", int nCancelStrRef=0, string sCancelString="", string sDefaultString="", string sUnusedString="" );`