Skip to content

Instantly share code, notes, and snippets.

@CromFr
Last active February 6, 2019 18:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CromFr/39250324d3af85a2a8f2d73fbdc8b272 to your computer and use it in GitHub Desktop.
Save CromFr/39250324d3af85a2a8f2d73fbdc8b272 to your computer and use it in GitHub Desktop.
NW2 GUI Scripting

GUI Scripting

Resources

Language

The GUI are written in a non standard form of XML.

  • The first line must be something like <?xml version="1.0" encoding="utf-8"?>
  • Attributes values can be delimited by ', " or can end with a space
    • 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, the GUI will not load
  • The UIScene element is never closed

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/><B/>, A will appear over B

Variables

The GUI file can store client-side variables that can be either local (only accessible through the current UI) or global (all UI share the same variables). They are identified by an integer index, and always store a string value.

Examples: local:0, local:1337, global:42, ...

Functions

Functions are special attribute values that 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.

TODO: callback parameter parsing & delimitation (ie what happens if UIObject_Misc_ExecuteServerScript("A,B","C",D,'E,F','G',H))

You can use multiple functions on a single event by appending 0, 1, ... to the event name, ie OnEvent0="DoThis()" OnEvent1="ThenDoThat()". Note: if you don't number events correctly, the GUI will not load.

The most useful callback is certainly UIObject_Misc_ExecuteServerScript that allows you to execute nwscript for any event from any UI element: OnEvent="UIObject_Misc_ExecuteServerScript('gui_yourscript','AnyArgumentList',local:25)"

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 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 safely be replaced by <?xml version="1.0" encoding="utf-8"?>.
  • Any standard-compliant XML parser will fail at parsing NWN2 UI files. You can find a custom XML parser implementation for nwn2 here. 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.

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
  • 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. :)

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

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 functions Float between [0, 1]

Events

  • 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 version="1.0" encoding="utf-8"?>
<UIScene name="MYSCENE" width="800" height="600">
<UIPane x=5 y=5 width=10 height=10>
    <!-- any elements -->
</UIPane>
<!-- Do not close UIScene -->

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

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

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)
mhbottom Do not seem to work (see oeiprogrammer)
mvleft Do not seem to work (see oeiprogrammer)
mvright Do not seem to work (see oeiprogrammer)
mhside Do not seem to work (see oeiprogrammer)
mvside Do not seem to work (see oeiprogrammer)
maside Do not seem to work (see oeiprogrammer)

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

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 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
  • UIHotbarButton
  • UIPortrait
  • UITextTree

Generic functions

  • UIObject_Misc_ExecuteServerScript(gui_script,arg0,arg1,...)

  • 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);

  • 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 <UIText>'s text. The text will render tags like <i><b><color=red> 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="" );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment