Friday, February 23, 2007

Couple new GUI script functions for 1.06

1.06 will have a number of new script functions that will give improved control over custom GUIs.

Two of the new script functions are:

SetGUIProgressBarPosition();

This script function will let you set the position of a progress bar (Between 0.0 for empty and 1.0 for full).

The other new function is:

SetGUITexture();

This script function will let you set the texture for a UIIcon, a UIFrame's fill texture, or a Button's Base Frame's fill texture.

Both script functions require the UIScene to be scriptloadable like all the other GUI related scripting functions.

Thursday, February 22, 2007

New UI Callback Parameters

In 1.06, callbacks can take 2 new 'variable' parameters in addition to global:# and local:#.

The first new parameter type is
listboxrow:listboxname

This will insert the row # that is currently selected in the listbox indicated by listboxname

For example, if I had a callback that looked like:

OnLeftClick=UIObject_Misc_ExecuteServerScript("myguiscript",listboxrow:mylb)

On the same UIScene I have a listbox called 'mylb' where I have selected the 3rd row.

When the OnLeftClick callback above gets executed, the 1 parameter that gets sent to that script will be an integer with the value of 2. (The first row in the LB would send a value of 0).


The second new parameter type also deals with ListBoxes:
listboxtext:listboxname[.textfieldname]

This will insert the text contained by that row. If the listbox rows are buttons or text fields, then the textfieldname parameter above is not necessary. If instead they are complex UI Panes, then the textfieldname will be used to specify which object within the pane contains the text we want.

For example, if I had a callback that looked like:
OnLeftClick=UIObject_Misc_ExecuteServerScript("myguiscript",listboxtext:mylb.mytext)

In the same UIScene, I have a Listbox named 'mylb'. The rows of that lb are complex UIPanes that contain a text field in them called 'mytext'.

When that callback executes, the engine will look at 'mylb', find the currently selected row, then look for the object named 'mytext' within that row and insert the text within that object as a parameter to the script on the server.

Now obviously the real power of these new variable parameters will be when coupled with the ability for scripts to populate a gui listbox. That functionality isn't in yet, but is something else I intend to have in for 1.06.


There are other new 'variable' parameter syntaxes that will be coming along with 1.06 that I'll post about once I have actually implemented them. :)

Monday, February 19, 2007

UIButton_OnUpdate_ControlSelected

This callback takes a single parameter. It's only purpose is to enable or disable a button based on whether or not the user has selected a row in a List Box.

The single parameter is:
sListBoxName = The name of the list box we want to check for selection.

If the user has a row selected in the listbox named in the parameter, then the UIButton will be set to Enabled.

If the user does not have a row selected in the listbox named in the parameter, then the UIButton will be disabled.

UIObject_Misc_StoreObjectData

The only valid parameter to this callback is a local or global GUI variable index.
localguivars are expressed as local:#, where # is the index for the variable.

globalguivars are expressed as global:#, where # is the index for the variable.

This callback takes the engine-level data in a UIObject and stores it in a global or local gui variable. The engine-level data will vary from UIObject to UIObject. It is also impossible to specify which data item you want to set the GUI variable to, if the UIObject has multiple items of data.

This is a really old callback and is of limited use to custom GUIs at this time. My intent is to write a new callback that accomplishes what this callback does, but that takes more parameters in order to more accurately specify what data you are interested in from the UIObject.

UIObject_Tooltip_DisplayTooltipString

UIObject_Tooltip_DisplayTooltipString takes up to 9 parameters, but only the first four parameters are required.

Parameter list:
Message = The literal string to display in the tooltip

XLoc = The X origin for where the tooltip should appear. This can be a pixel location, or you can use the following two strings to make it relative: MOUSE_X will place the X origin of the tooltip near where the mouse is. OBJECT_X will place the tooltip next to the UIObject that is being moused over, if any. At first, it will try to place the tooltip to the right side of the UIObject. But if there is not enough screen space to fit the tooltip there, it will place it on the left side of the UIObject.

YLoc = The Y origin for where the tooltip should appear. This can be a pixel location, or you can use the following two strings to make it relative: MOUSE_Y will place the Y origin of the tooltip near where the mouse is. OBJECT_Y will place the tooltip next to the UIObject that is being moused over, if any. At first, it will try to place the tooltip on top of the UIObject. But if there is not enough screen space to fit the tooltip there, it will place it on the bottom of the UIObject.

Screen Tag = The Screen Tag for the XML file to be used for the tooltip

XAlignment = This parameter can be used to quickly position a tooltip relative to the full-screen space. The valid arguments are: ALIGN_NONE(default), ALIGN_CENTER, ALIGN_LEFT, ALIGN_RIGHT

YAlignment = This parameter can be used to quickly position a tooltip relative to the full-screen space. The valid arguments are: ALIGN_NONE(default), ALIGN_CENTER, ALIGN_TOP, ALIGN_BOTTOM

XPadding = This is used along with XAlign to quickly position the tooltip. It controls how far in the tooltip should be pushed from the left or right border of the screen space. For example, setting XAlignment to ALIGN_RIGHT and XPadding to 10 will result in the tooltip appearing on the right side of the screen, with a space of 10 pixels between the right edge of the tooltip scene and the edge of the screen.

YPadding = This is used along with YAlign to quickly position the tooltip. It controls how far in the tootip should be pushed from the top or bottom border of the screen space. For example, setting YAlignment to ALIGN_BOTTOM and YPadding to 10 will result in the tooltip appearing on the bottom of the screen with a space of 10 pixels between the bottom edge of the tooltip scene and the edge of the screen.

TextAlignment = How the text should be aligned in the tooltip. The options are: ALIGN_NONE(default), ALIGN_CENTER, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_TOP, ALIGN_BOTTOM

Multiple Callbacks Per Event

In 1.06, it will be possible to set up multiple GUI callbacks on a single UI event in XML. The syntax will be to use the event name and append a number to it. The engine will read in the callbacks until it fails to find the next sequential number.

For example, I could set up a UI Button to with the following callbacks:

OnUpdate=UIObject_OnUpdate_DisableIfLocalVarEquals(local:3,"true")
OnLeftClick=UIObject_Input_ScreenOpen("SCREEN_OPTIONS","false")
OnLeftClick0=UIObject_Input_SetLocalVarString(local:3,"true")

When I click that button, it would open the Options screen, then set the local var to "true". On its next update, it would become disabled because of the OnUpdate check.

Note that the callback without a number will be handled before the 0'th callback.
So OnLeftClick will be handled before OnLeftClick0.

Also note that the callback without the number is not required but is mostly just supported for backwards compatibility.

For example, it would be valid to have the following callbacks:

OnLeftClick0=
OnLeftClick1=
OnLeftClick2=

That will work fine, executing 0, then 1, then 2.

It is also valid to have:
OnLeftClick=
OnLeftClick0=
OnLeftClick1=
OnLeftClick2=

This will execute them in order.

It is not valid to start with any other number besides 0 however.

OnLeftClick1=
OnLeftClick2=
OnLeftClick3=

will result in no callbacks being loaded for that event for that UIObject.

Sometimes the engine assigns callbacks to UIObjects internally. The engine will only ever override the first callback, so if you are having a problem with the engine overriding your callback for some UI Object, you might need to insert a dummy callback first, before the callbacks you actually want to execute. This doesn't happen too often though, so I doubt this will be an issue for very many.

Note at this time, the only event that doesn't support multiple callbacks is OnTooltip, due to how the engine has to handle this event internally. I may or may not be able to fix OnTooltip by the time 1.06 comes out.

Monday, February 12, 2007

Special Screens

Taking a break from writing about the UI Elements for a moment, though there are still some of those that I will cover in future posts.

Most XML files are loaded as default UI Scene, which implies no special behaviors. There are, however, several XML files that will get special handling in code and most conform to specific rules in order to even be loaded. All of these scenes are distinguished by their identifying name in the INI file (Or the screen tag given to them when being loaded via script). The actual XML file name doesn't matter.

Note that when I list them below, if a name ends with a * mark, that means that only the text up to the * mark is required and that the name may be unique after that mark.

The following are special GUI screens that are loaded differently than most XML files:

SCREEN_FADE = The full screen 'fade' effect. It gets loaded like a normal XML file at first. After loaded, the first UIIcon object found (The one highest up in the file) becomes the engine's 'Fading' icon. The rest of the contents of the file will behave normally. In our default SCREEN_FADE, we include just the full screen icon. But there may be other things one would want to include on the fade, such as custom images, etc.

SCREEN_QUICKCHAT = The NWN1 style dialog box. First it is loaded like a normal XML file, then the following ui objects are searched for in order for the engine to use 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 = The fill screen cutscene view with the black bars on the top and bottom. This window is loaded like any other, then the following objects are searched for by the engine:
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_CONTEXTMENU = The rightclick menu system. Technically, this gets loaded like any other XML file. I'll make another post later about the syntax and format of the contextmenu.xml file.

SCREEN_MINIMAP = The in-game minimap GUI. I don't know a lot about how the Minimap works. If further documentation is requested for it, I can research it further later.

SCREEN_AREAMAP = The in-game area map that can be brought up. I don't know a lot about how the Area Map works. If further documentation is requested for it, I can research it further later.

SCREEN_MESSAGEBOX_SPLITSTACK* = Scene used for splitting stacks of items in inventory. The only gui element required is 'inputbox'.

SCREEN_MESSAGEBOX_SPLITSTACKSTORE* = Scene used for splitting stacks of items for stores. It's actually loaded identically to the SCREEN_MESSAGEBOX_SPLITSTACK and only requires the 'inputbox' object to exist. I'm not sure why it got made into a seperate entry.

SCREEN_MESSAGEBOX* = This is used for the generic message box popups. I'll probably have to write up more on them another time as they can be used effectively by scripts as well. The required elements for these are:
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.

SCREEN_STRINGINPUT_MESSAGEBOX* = Message boxes that prompt for user string input. They are identical to normal Message boxes, except that they also require a 'inputbox' text field.

SCREEN_MESSAGE* = Chat boxes, pretty much. Note that currently the engine only supports loading the hard coded ones in ingamegui.ini. I hope to change this to be a lot more flexible down the line. The required elements are:
messagelistbox - Listbox containing the scrollback text. If it is not found, the engine searches for messagelistbox2 instead. If neither is found, the screen is not loaded.
inputbox - Text field used for user input.
IMEREadingWindow - Used for IME support.
IMEReadingWindowBG - Used for IME support.
IMEComposeWindow - Used for IME support.
IMEComposeWindow - Used for IME support.
IMECandidateWindow - Used for IME support.
IMECandidateWindowBG - Used for IME support.
INPUT_CONTAINER - Used by the engine for easily hiding/unhiding the input related objects.

SCREEN_HOTBAR, SCREEN_HOTBAR_2, SCREEN_HOTBAR_V1, SCREEN_HOTBAR_V2 = All the hotbars built into the game. There are no required or special UI elements needed to load these.

If a Screen Tag doesn't match to any of the above screens, then a normal UI Scene gets created with all the default behaviors associated with it.

Friday, February 9, 2007

UIObject - hideoverride

In 1.05 there is a new attribute that all UI Objects handle called hideoverride. If true, this attribute sets a UI Object hidden and keeps it that way until a script says otherwise via the SetGuiObjectHidden() script function.

This can be used to keep an item hidden that the GUI may try to make visible regardless what a script tries to do, such as a row in a list box.

As a result, objects that are set hidden via SetGuiObjectHidden() will STAY hidden no matter what, unless SetGuiObjectHidden() is later used to make it visible.

For example, if I add a new icon to a screen and set it hideoverride=true in the XML, it will remain hidden on that screen no matter what the GUI might try to do with it until I call SetGuiObjectHidden() with a false parameter to make it visible again, at which point the GUI once again has control over making that object hidden or unhidden.

Wednesday, February 7, 2007

UIText

UIText is the GUI object used for containing and rendering text. It is one of the more complicated UI Objects to work with.

UIText takes the following attributes:

fontfamily
This defines which font should be used via a string argument. The fonts are defined in fontfamily.xml. The 'name' attribute for the different UIFontFamily elements in fontfamily.xml is how they are identified here. If this attribute is not set, then the text field will use the 'Default' font family defined in fontfamily.xml.

nextcontrol
Which control should have focus if the user hits tab while editing this UIText field. It only really makes sense to put UIText field names as the arguments to this attribute, as focus doesn't have any significant meaning for any other type of UIObject. Note that the nextcontrol must be in the same UIScene as this text field.

prevcontrol
Which control should have focus if the user hits shift+tab while editing this UIText field. It only really makes sense to put UIText field names as the arguments to this attribute, as focus doesn't have any significant meaning for any other type of UIObject. Note that the prevcontrol must be in the same UIScene as this text field.

filter
This attribute can be used to limit what text the user can enter into this text field when editing it. By default, any input character is valid. It takes strings as its arguments. The following strings are handled:
alpha - Only letters can be entered in this field.
numeric - Only numbers can be entered in this field.
alphanumeric - Only letters and numbers can be entered in this field.
signed_numeric - Only numbers in this field, except the '-' character, which may only be entered at the front of the string.

maxnumber
This number limits the max number that a user can enter when editing this text field. It only means anything if the text field's filter is set to numeric or signed_numeric.

allowspace
If this attribute is false, then any space characters will not be allowed in this field, including tabs or newlines. It defaults to false.

allowpunc
This attribute only means anything if the filter type is set to alpha or alphanumeric. It allows graphical punctuation characters to be entered in the text field. If no filter type is specified, then this attribute doesn't do anything. It defaults to false, so must be set to true if the intent is to allow users to enter punctuation style characters into this text field.

password
Defaults to false. If set to true, then the characters in this string will be replaced with * marks when this text field gets rendered.

sanitized
Defaults to false. If this attribute is set to true, then any string entered in this text field will be run through the built in swear-filter.

style
This is a modifier to the font that is being used. It takes a string or number as its argument. The following arguments are supported:
normal - Or style 1. This is defined by the UIFontNormal element in fontfamily.xml
bold - Or style 2. This is defined by the UIFontBold element in fontfamily.xml
italic - Or style 3. This is defined by the UIFontItalic element in fontfamily.xml
bolditalic - Or style 4. This is defined by the UIFontBoldItalic element in fontfamily.xml

indent
This is the number of pixels to indent the first line of any text. It defaults to 0.

hangingindent
This is the number of pixels to indent all lines besides the first line in a multi-line text field. It defaults to 0.

align
This is how the text should be aligned in the text field. The following string arguments are handled: left, right, center. Defaults to left.

hilite
Defaults to false. If set true, then the text in this text field will hilight when moused over.

valign
This is how the text should be aligned vertically within the text field. The following string arguments are handled: top, bottom, middle. Defaults to top.

poscenter
This attribute is defunct and no longer does anything.

sizetofit
Defaults to false. If set to true, then the text field will extend its height downward as far as possible in order to contain the length of text within it. This is an old attribute and should be replaced by just setting the height of the text field to DYNAMIC.

buttonoverlay
This only means anything if the text field is a child element of a UIButton element. If left to the default of false, then this text field will become the normal text field that shows up in buttons. If set to true, it becomes Overlay Text. At this time, Overlay Text can only be manipulated by the engine.

editable
Defaults to false. If set to true, then the user can edit the text within this text field by clicking it to place their cursor and typing like normal.

selectable
This attribute does nothing at this time.

maxlines
The max number of lines this text field can contain. Setting this attribute to '1' will keep the engine from trying to break the text into multiple lines. Text that will not fit into the text field after the maximum number of lines has been reached will not get rendered. If not defined, the engine will try to wrap a string and fit it into the space available no matter what, which can sometimes result in no text at all appearing due to spacing errors.

multiline
This attribute toggles whether or not a user can hit enter to start a new line of text within a editable text field. It requires that allowspaces be also set to true or else it will seem to do nothing. It defaults to false. When false, the OnReturn callback will get called when the user hits enter, instead of a new line being inserted.

returnrestricted
This attribute can be a bit confusing. It defaults to false and only means anything when used with multiline=true. What happens is that if this attribute is set to 'true', the text field will accept multiple lines of input and wrap them automatically, but if the user hits their return key, the OnReturn callback gets called instead of inserting a newline. An example of this behavior can be found in the chat input box.

uppercase
Defaults to false. If true, all text rendered in this text field will be rendered in uppercase.

maxlength
This limits the number of characters that can be typed into a text field by the user. Once the user has entered the max limit of characters, no additional characters can be input. If no maxlength is set, the user can keep typing indefinitely.

color
A color to blend with all of the characters within the text field. This can sometimes conflict with the use of the color tags in text fields.

highlightcolor
This attribute defines the color that should be blended with the text when doing a mouse-over style highlight.

selectioncolor
This attribute does nothing at this time.

highlightonmouseover
This is just a clone of the hilite attribute mentioned above.

text
This is for hard coding the text that should show up in this text field. Overrides strref.

strref
This is for coding which string ref should show up in the text field. It is overridden by text.

OnReturn
This callback gets executed when the user hits Enter while the cursor is in this text field. Note that if the text field is set with multiline=true and restrictedreturn=false, then this callback will not get executed.

OnLostFocus
This callback is executed when the cursor is taken out of the text field due to the user clicking elsewhere.

UIFrame

UI Frame is used for borders and backgrounds for other UI Objects. UIFrames are imbedded in buttons and a few of the container style UI Objects that will be discussed later.

The following attributes are handled by UIFrame:

The following is a list of the texture pieces that make up a frame. They take a texture name as an argument. The texture pieces are:
topleft, topright, top, left, right, bottom, bottomleft, bottomright, fill.

The next set of attributes are methods of mirroring one piece to other pieces. This mirroring happens at render time.

mhtop
Stands for MirrorHorizontalTop. Defaults to false. If true, the Top Left Corner will be mirrored to the Top Right Corner. If combined with mvright, then the Top Left Corner will be mirrored to the Right Bottom Corner.

mhbottom
Stands for MirrorHorizontalBottom. Defaults to false. If true AND mvright is true, then the Top Left Corner will get mirrored to the Bottom Right Corner. If true AND mvright is false, then the Bottom Left Corner will get mirrored to the Bottom Right Corner.

mvleft
Stands for MirrorVerticalLeft. Defaults to false. If true, the Top Left Corner will get mirrored to the Bottom Left Corner. If true AND mhbottom is true, the Top Left Corner will get mirrored to the Bottom Right Corner.


mvright
Stands for MirrorVerticalRight. Defaults to false. If true AND mhtop is true, the Top Left Corner will get mirrored to the Bottom Right Corner. If true AND mhbottom is false, the Top Right Corner will get mirrored to the Bottom Right Corner.

mhside
Stands for MirrorHorizontalSide. Defaults to false. If true, the Left Side will get mirrored to the Right Side.

mvside
Stands for MirrorVeritcalSide. Defaults to false. If true, the Top Side will very mirrored to the Bottom Side.

maside
Stands for MirrorAllSides. Defaults to false. If true, the Left Side will get mirrored to the Top Side, Right Side, and Bottom Side.

The remaining attributes supported by UIFrame follow:
fillstyle
This tells the engine to fill in the center space of the frame with the fill texture using different algorithms. This attribute takes the following string arguments:
center - Center the 'fill' texture.
stretch - Stretch the 'fill' texture to take up the full center.
tile - Repeat the 'fill' texture to fill up the center.

border
This is the thickness of the border pieces in pixels. Note that it defaults to 0. If no border thickness is set, then all the textures besides 'fill' won't show up when the UIFrame gets rendered.

color
This takes color strings to define the color that should be blended with the frame textures.

Note that if a UIFrame doesn't have a height or width defined by its attributes, it automatically inherits the height and width of whatever object contains it.