http://code.wildfiregames.com/resources/divisions/GUI/TDD/GUI_Engine_TDD_1.41.doc http://code.wildfiregames.com/resources/divisions/GUI/TDD/GUI_Engine_TDD_1.41.xls

Technical Design Document for:

GUI Engine

This document belongs to the 0ad Technical Design Document

All work reserved by WildFire Games

Written by Gustav Larsson (aka Gee) gee@…

GUI Engine TDD Version 1.41

Documentation Files: GUI_Engine_TDD_1.41.doc GUI_Engine_TDD_1.41.xls

GUI Homepage / Online Documentation: http://gee.pyro.nu/GUI/

Or e-mail me and I�ll reply the files you need.

2 December 2003

Table of Contents

TABLE OF CONTENTS 3 INTRODUCTION 4 VERSION HISTORY 4 VERSION 1.0 (RELEASED 26 MARCH 2003) 4 VERSION 1.1 (RELEASED 9 APRIL 2003) 4 VERSION 1.11 (RELEASED 15 APRIL 2003) 4 VERSION 1.2 (RELEASED 1 MAY 2003) 4 VERSION 1.3 (RELEASED 12 SEPTEMBER 2003) 5 VERSION 1.4 (RELEASED 2 DECEMBER 2003) 5 CURRENT VERSION COMMENT 5

  1. BASIC LAYOUT 6

1.1 XML 6 1.2 JAVA-SCRIPTS 6 1.3 GUI 6 1.3.1 Parent Objects 6 1.3.2 Dependencies and Media used 6 1.3.3 Custom 7 1.3.3.1 Styles 7 1.3.3.2 Sprites 7 1.4 OBJECT 7 1.4.1 Settings 7

  1. XML FILES 8

2.1 <OBJECTS> 8 2.1.1 An Object�s anatomy 8 2.1.1.1 Object String 8 2.1.1.2 Type-dependent Elements 8 2.1.1.3 Actions 9 2.1.1.4 Children 9 2.1.2 Settings 9 2.1.2.1 Base settings 9 2.1.2.2 Excel Types and Settings file 10 2.1.2.3 Value types 11 2.1.3 Types 12 2.1.4 Drawing order 13 2.2 <STYLES> 13 2.2.1 Creating styles 13 2.3 <SPRITES> 14 2.3.1 Skip a step 15 2.4 <SETUP> 15 2.4.1 <tooltip> 15 2.4.1.1 Appearing text-box 16 2.4.1.2 Existing text-box 16 2.4.2 <scrollbar> 16 2.4.3 <icon> 17 2.5 INLINE JAVA-SCRIPT 17 2.5.1 The &lt;-solution 17 2.5.2 The CDATA-solution 18

  1. C++ API 19

3.1 SETTINGS 19 3.2 THE CLASS GUI 20 3.3 MESSAGES 20 3.4 XML READING 20 3.4.1 Flexibility 20

  1. JAVASCRIPT API 22
  2. MISCELLANEOUS 23

5.1 NAMING RULES 23

  1. ISSUES 24

Introduction The GUI in this documentation does not include the whole GUI of the game. Let�s say the map, it is part of the actual Graphical User Interface, but it will hardly be a part of the GUI Engine. The GUI Engine includes all buttons, text-boxes, progress-bars, and all such (and probably a lot more than the obvious too). The GUI Engine�s goal is to enable creation of GUIs completely without having to recompile (let alone, bloat your game code). This will be done with the help of XML files for the layout of the GUI, and JavaScripts for the functionality.

Version History Version history since first release. Version 1.0 (released 26 March 2003) � Skeleton for the document is made. 7 pages in length. Version 1.1 (released 9 April 2003) � Front page added to fit a 0 A.D. TDD. � Second page added with credits, contact and current version. � Version history added. � Chapter�s divided into root element types (<objects>, <styles> etc). � Examples added. � A lot of additions to the objects� chapter, such as standard actions. � Whole new chapter 4. <sprites> added. � Whole new chapter 5. <animations> added. � Issue 6.1 updated with 6.1.1 and 6.1.2, two different solutions. � Issue 6.2 added. � Issue 6.3 added. � Decision about name ambiguity made, sibling objects can�t share name, that�s all. Version 1.11 (released 15 April 2003) � Changed all Word�s quotations marks from fancy �these� to "these" in code examples because �these� are incorrect XML syntax if one would copy paste them. � The whole concept of animations is removed; I�ve been informed this feature will be supported beyond the GUI Engine as an integral part of texture database. � Issues are moved from 6 to 5. � A lot of adjustments made from Raj�s helpful comments. � Issue 5.1.2 is updated. Version 1.2 (released 1 May 2003) � I�ve compiled an excel file that keeps track of types and all their settings. This has changed �2.2.2 Type-dependent options�; it now explains how to read the excel file instead of listing all options. � A new chapter 5 called �<setup>� has been added. It includes how to setup tooltips, scrollbars and icons. � The ideas of horizontal scroll-bars and movable dialog-windows have been removed from planning. Lack of need. � The issue about drawing order has been settled and chapter �2.4 Drawing order� has been added. � Object names should now be completely unique, and the idea of making the name option perhaps not essential is rebuked. � Description added on the different types of values (int, bool, string etc). � Issue 6.2 about simple sprites has been removed and replaced by �4.1 Skip a step�. � The issue chapter has been moved again, it is now number 9. � �6. C++ API� and �7. JavaScript API� have has been added just to reserve space. � �8. Miscellaneous� has been added, it is a chapter that doesn�t really chronologically fit into the rest of the design document, and it should be used as a reference. � Current version comment added.

Version 1.3 (released 12 September 2003) � The chapters CGUI and CGUIObject has been renamed to GUI and Object since language specific information solely should be found in the C++ API chapter. � The chapters <objects>, <styles>, <sprites> and <setup> has all been given a parent called �XML Files�, this makes it clearer because we now have three major chapters: XML, C++ and JavaScript. All chapters that are placed after this new one have reduced its chapter number�s value by 3, thus making it �6. Issues� again. � Text in �Document Layout� has been moved to introduction to the �XML Files� chapter. � Previously I�ve used both the name �options� and �settings� for all object settings, they have hopefully all been changed to �settings� since that�s the name I use for them, and it can otherwise be confusing. � Settings added in Excel file: frozen, ghost, absolute. � The setting disabled was changed to a base setting. � Previously I had size1024 and sizerel024 like in AoM. I�ve removed sizerel1024 and added the boolean setting absolute that let�s you know if it�s absolute or relative. � The low-leveled C++ documentation has been moved to a separate file. � From empty filled the C++ API chapter with 2 pages. � Solution .1 and .2 to issue 6.1 are tested and works with the XML parser used. So they are now no longer in the issues section. � Before name, type and size1024 were essential settings, now they are ALL optional. I decided to make the defaults: type = �empty�, size1024 = �0 0 0 0� and name will just not be required. This means you can just specify <object> </object> and you get a typical transparent group. � The JavaScript/XML syntax collision issue is not an issue anymore, can be found in the XML chapter. � I�ve added an index of files which accompanies this file. I�ve seen many links which only provides this file, so it can be good to know you need all files to have the full documentation.

Version 1.4 (released 2 December 2003) � File GUI_ClassRelations_*.png has been removed, replaced by the online documentation. � Some class names has been changed, like CGUIObject is now IGUIObject since it�s interfaces. � The new settings type client area has been added. � Sizing has been updated from ratio-sizing to tileable. size1024 is now just size and of type client area instead of rect. � When making sprites, pixel and percent has been combined to size using the new type client area. Also the t_pixel and t_percent has been replaced by texture_size accordingly. � Done a lot of small updates of things that was outdated or deprecated.

Version 1.41 (released 18 December 2004) � Added reference to new attributes created by Philip Taylor aka Ykkrosh: sprite effects (2.3.3) and cellular sprites (2.3.2). Also added cell-id to the base attributes in 2.1.2.1. � Removed mention of LUA, since we�re currently using JavaScript.

Current version comment This version lacks the important object types listbox, combobox and slider because I need more feedback from the GUI graphics designers before I can set that up properly.

  1. Basic Layout

This is the basic approach and layout of the GUI Engine, comments and suggestions are always helpful.

1.1 XML The whole GUI will be read in from XML files. Why? Most importantly because XML is a mark-up language, which enables us to create the tree structures we require. In the main GUI class there will be a function that lets us input an XML file, so what we do when we setup a GUI is just having all the XML files being passed through this function and inputted into the engine. I�m sure it�s easier to understand the concept of the XML files with an example:

<!-- A list box --> <object type="listbox" name="list1" size="50 50 150 170"> <!-- Additional options --> <listitem>Select 1</listitem> <listitem>Select 2</listitem>

<!-- Actions --> <action on="CursorOver"> DoThis() </action> <action on="Load"> DoThat() </action>

<!-- Children --> <object name="child1" �></object> <object name="child2" �></object> </object>

1.2 JavaScripts JavaScript scripts will be used to carry out actions. If there is something in the game that should be controlled by�for instance�a button, it is essential for the script-engine to be able to carry out the button�s assignment. So if there�s anything the script-engine can�t control, you can�t make a button of it; but hopefully the script-engine will be able to control everything we need buttons and objects for. A script interface for controlling the GUI will be an important part as well, because it enables us to change the GUI not only from the GUI itself, but from wherever we can use the script-engine.

1.3 GUI 1.3.1 Parent Objects A primary list of parent objects will be stored in a list, they will all be objects that have no natural parent, such as the intro-menu or a dialog window. All buttons in the intro-menu though, will be stored as children within the intro-menu object. Each XML file (with the root element <objects>) will be one or more of these base trees.

1.3.2 Dependencies and Media used The GUI Engine will need access to the game�s keyboard and mouse inputting structure for interaction. Also the GUI will want access to all the fonts, which�s residing place I don�t know yet, but perhaps in some graphics structure outside the GUI. Sound I�m not sure about if the GUI needs access to yet, because it can be enough to just make a sound-playing interface for the script-system. It would mean you could go:

<action on="LeftButtonPress"> Inline script part PlaySound("click") Inline script part </action>

� and that might be enough.

1.3.3 Custom This section refers to things you declare in other XML files than <objects>, but they are of course used within the <objects>; for instance styles and sprites.

1.3.3.1 Styles Let�s say we want to create a button style for all the tray buttons, and one that�s slightly (or completely) different for the main menu buttons. Now, we don�t want to code how they will look each and every time we need one. We�ll just store the information as a style/template and then reference to that style when creating our buttons. Read more about styles here.

1.3.3.2 Sprites Sprites are declared separated, describing size, texturing etc. Read more about sprites here.

1.4 Object As mentioned in the GUI part, everything you see, everything you press, is an object belonging to one of the base trees of objects. Objects can have a dynamic amount of children, also regardless of object type, i.e. buttons can also have children, although you might only notice it in theory.

1.4.1 Settings Object settings are defined within the object tag, all settings cannot be used by all objects; type decides what more settings you can put within the tag than the base options (name, type, size etc). For instance, if you want an empty area, then textcolor=�0 0 255� will make very little sense, as oppose to if it were a text box. A list of which settings are available for which types can be found here.

  1. XML Files

Different XML files with different root elements will be loaded into the GUI. So basically you have a long list of XML files, and voil� that gives you your entire GUI. As said, there are different kinds of XML documents for the GUI, for instance one that declares objects, and one that declares styles. These two mentioned would have the root elements <objects> and <styles>. Each different root element will have its own chapter ahead.

2.1 <objects> In CGUI I�ve mentioned that there is a list of main objects; they are the only parentless objects. To input one of these objects you just need to create an XML file with the main tag <objects> and input it into the GUI Engine. Within the root element you can enter as many objects as you like, they will all be root parents. Here�s an example of a perfectly valid XML file:

GUI Objects XML file example <?xml version="1.0" encoding="ISO-8859-1"? standalone="no"><!DOCTYPE objects SYSTEM "objects.dtd"><objects><object name="root_parent1" type="empty" size="0 0 100% 50%"></object><object name="root_parent2" type="empty" size="0 50% 100% 100%"></object></objects>

2.1.1 An Object�s anatomy Within an object the order of all sub-elements is syntactically indifferent, but it is wise to keep the recommended standard:

GUI Parent XML file example <object Settings>Object StringType-dependent ElementsActionsChildren</object>

2.1.1.1 Object String This is a plain string within the object that could mean a variety of things depending on object type; a text box for instance uses this string as caption. This is the same string as in <name>Gee</name>, only we�ll have this string next to sub-elements too.

2.1.1.2 Type-dependent Elements Type-dependent elements are rare and can look completely different from type to type. It�s used for information that is too dynamic for a regular option such as name or type. As in an earlier example we used type-dependent elements to declare a list box�s items. There will be information about the type-dependent elements in the types� section.

2.1.1.3 Actions When certain events occur you want to be able to run a script to give for instance a button functionality, this is made with <action>. The action tag takes one option and that is �on�, like this:

<action on="MouseOver">JavaScript goes here</action>

Here is the list of actions that all types can use because they depend on essential information:

MouseEnter Called when the cursor enters the object�s parameters. � MouseLeave Same as above only when the cursor leaves. � MouseOver Called continuously when the cursor is hovering the object. � MouseLeftPress Called when left mouse button is pressed (and of course the mouse hovering the object too). � MouseLeftDown Called continusously when left mouse button is down. � MouseLeftRelease Called when left mouse button is released. � MouseRight* Same as above only with right mouse button. � Load When the GUI is first loaded.

Actually there is one more option for the action tag, it is optional and used when wanting to run a script from a separate file.

<action on="MouseOver" file="scriptfile1.txt" />

It will be used as if you had opened the file, selected everything and copied it to within the tags, except within the file you don�t have to worry about syntax collisions between JavaScript and XML.

2.1.1.4 Children All objects can have children, i.e. objects within the object. The children must not all be drawn within the parent, but do notice that if you add a scroll-bar, they will be cut-off at the edges. If you hide an object all its children are hid too, same with moving if the children�s setting absolute has been set to false, which means you specify the position and size relative to the parent�s coordinate-system (and not to the screens). This means you can create a whole group of buttons and hide them or move them all with a single call. An example of a parent/child-relationship is if you have a lot of text and perhaps images which is too much for the screen to show at once, you need a scroll-bar of course. This is done by creating an empty parent with scroll-bars and then specifying relative size and position of all children. The scroll-bars will then be adapted so they can scroll and display all children.

2.1.2 Settings Settings go within the object tag like this:

<object name="button1" type="button" size="10 20 100 200">

name, type and size are all settings, actually they are base settings�i.e. they are available for all different types. Then there�s the type-dependent settings such as textcolor or borderwidth, they can only be used by specific types.

Note! Always by good standards encapsulate the setting value with quotation marks!

2.1.2.1 Base settings Why only the base settings get this thorough introduction is because for some reason almost every type-dependent setting needs only a few lines of explanation, often even no more than the setting�s name.

For further information about these types, take a look at the XLS file that should accompany this file.

Setting: nameValue: string Something to identify the object with, all names should be unique, and no object should share the name with another object. The name is case-sensitive and regular characters should only be used. Avoid semicolon by all means because it�s a standard delimiter in the GUI.The name will actually be optional. If not entered it will be given an internal name since it a name is essential in the technical layout. This means directly the object will be static, but indirectly you can still hide a parent to it and it will be hid too.Ref. 5.1 Naming rules Setting: typeValue: string Hence the name it tells us what type of object, there will be a ton of different kinds, such as button, text, input box, progress bar etc. You can read more about the different types here. Setting: sizeValue: size Check the online documentation for the type �size� about more information on how to specify the size.Actions such as CursorOver, which can be used on all objects, will use these values when deciding state.Setting absolute to false means size and z will be relative to its parent. Setting: styleValue: string What style to use, read more about styles here. Setting: hiddenValue: bool True of false whether the object should be hidden or not. Note that hiding an object hides all its children too. Of course this argument as every other only specifies the initial value of the object, you can always change it to be shown later. Setting: zValue: int Read this to understand what z is. Setting absolute to false means size and z will be relative to its parent. Setting: absoluteValue: bool If this is false, size and the z will be added as a delta value to its parents, i.e. its position will be relative to its parent. If it�s true it will be absolute. Using scrollbars and such, all children are required to have absolute set to false, otherwise they will just be excluded from the scroll-bar effect.NOTICE if absolute is false and you use the term 100% in size, then that will regard the PARENTS size and not 100% of the screen! Setting: ghostValue: bool An object that is ghost doesn't acknowledge the fact that a cursor might be hovering it; i.e. it becomes a purely cosmetic overlay. So if you hover it, and the ghost object is visually closest, the object really being hovered will be the object behind it.On the right, there�s a button, let�s say you want to be able to press the whole thing, but if you add a regular progress bar on top of the button, it will steal the mouse if you hover and press it. Therefore you make it ghost, so hovering and pressing the progress bar will be like hovering and pressing the button.Just to clarify, making an interactive object such as a button ghost, is quite meaningless. Setting: cell-idValue: string Used in conjunction with a sprite of cells (see 2.3.2 Multi-Cell Sprites) to specify which element (in the range 0..n) of the sprite= to display at this time.

2.1.2.2 Excel Types and Settings file The rest of the setttings can be found in the Excel file:

GUI_Engine_TDD_1.4.xls Open the file otherwise the following will make very little sense.

In the rows we�ve got all the settings, as said all types share the same �settings-pool� (not technically, but in gist), to the right of the double line all types can be found in a column each. To see which settings can be used by a type you look at that column only. The different colors mean:

The setting is available, it uses the default shown in the the default column.

�new value� The setting is available, but a new default has been set, ignore the default column because the new value will be default for this type.

 sprite

The setting is available, but the default is actually pointing to another value. It can be like this: If no sprite-over is entered, it uses the same value as sprite. So if you set sprite and ignore sprite-over, it too will be given the same value as sprite, meaning nothing will seemingly change when hovering the object with the cursor. Check the default column to see what other setting it uses as default.

Setting is essential, no default is available. Notice I�ve removed a lot of the essentials, I�m not even sure this will still exist in the end.

The top row is not a setting, it describes the Object String. The following rows describe the Additional Actions available, these are actions that can require a more complex turn of events, such as a mouse press. They are accompanied by comments so take a look in the file. Check the column for the button type, you�ll see �Press�. Now if you want to add an action to when the button is pressed you can just add an action tag like this:

<action on="Press">

2.1.2.3 Value types I want to separate this from an object type, I�m talking about the different types of settings� values. You can see a column in the Excel file (type), it is next to the setting column and it can say things like �string� or �color�.

string Just a free string with the inclusion of any characters if nothing else is specified. name name is almost like string, only it follows these conventions. int Just a plain integer such as �-10� or �1024�. If you enter in the form of a float value it will work too, but it will be casted to an integer with regular C++ truncation. float Float value, like �2.32� or �.0001�. If you enter it in the form of an integer that�s fine too. bool A boolean value can be either 1 or 0, on and off. These values can be set to �true� or �false� (case sensitive!). enum This can be a number of strings, and those are always shown in a comment. Check textalign for instance where you have an enum that can be �left�, �center� and �right� (case sensitive!). color A color value can be entered in many different ways, usually with 3 or 4 (alpha) 1-byte integers with a blank space delimiter: like �255 255 255� or �0 0 0 100�.Also a standard setup of colors can also be used, such as: �black�, �white�, �blue�, �red� (case sensitive!). �black� for instance would be the equivalent of �0 0 0�. rect Rectangle with 4 integer values: left, top, right and bottom (in that order). The delimiter of the values are a blank space so it could look like �0 0 100 200�. client area Client area tells us the exact position and size of a rectangle relative to a parent rectangle. For instance an object relative the screen rectangle, or a texture tiling within the image rectangle. It includes both pixel modifier and percentage modifier. Examples: �0 0 100% 100%�, �50%-10 50%+10 50%-10 %+10�. As you see like rect but you can use [percentage][+-][pixel] for each value.Here is an example of a client rectangle. The client rectangle below is placed with its left edge concurrent with its parent, as is the top edges. The right edge is placed exactly in the middle and the bottom is like 10 pixels from the parent�s bottom (100%-10). To elaborate the example, I�ll show you how the client area will look if the parent size is changed.

2.1.3 Types Here is the introduction of all different object types, the rest can be found within the Excel file.

button The action Press is called when the user puts the cursor over the button, presses it, holds down, and releases it still being within the button�s perimeters. Between the press and the release the cursor can leave the button if it wishes.Default of textalign and textvalign are both center, but note that you don�t have to have text on top of the button if you don�t want to. text A box with text, the box itself is by default transparent. If you just want a rectangle you can always skip the caption. input An input box, or edit box one might call it, press it with the mouse and it will receive focus, now you will be able to enter text in it (for each character entered or removed Type will be called). InFocus is called continuously when the input box is in focus. empty Empty space for children to reside. If you have a group of buttons and you want them to be able to be moved or hid with just one call, this is the object�s type that you want.This is always completely transparent. You can add a scrollbar to this too.Note also that this is the default type. Which enables one to do a group with an empty <object> element. Thus no arguments needed at all! progressbar The value of the progressbar is from 0 to 100. If it�s set to 30, sprite and sprite2 will try to show that 30% of whatever is done. This is how it�s done: As the value increment, sprite will become bigger, and sprite2 smaller.This might be changed to sprite2 being static, and only sprite because bigger but on top of sprite2. We�ll see what works out the best. checkbox Everybody has seen a checkbox, it�s something that you want the user to specify either 1 or 0 to, true or false. If you�ve seen checkboxes in Windows, as you probably have, you can have the text actually being a part of the checkbox�being able to click it instead of the button. You can have such text with these checkboxes too. radiobutton A radiobutton is almost like a checkbox, only they come in a group of several, and only one in the group can have the value 1, the others will have 0. When pressing a radiobutton with 0 in a group, the 1 will jump to that radiobutton. Also text can be a part of the object too just like checkbox�s text.To create a group of radiobuttons you just put them all in the same object (the type empty is excellent for this), so they become siblings. When pressing a radiobutton all sibling-radiobuttons will be set to 0.

2.1.4 Drawing order In regular 2D drawing the object drawn last would appear on top of everything, but in 2D made by a 3D-engine all objects are drawn at the same time, and their order is decided by their Z-value. Each object will be given a Z-value automatically, but you can manually specify it with the setting z too. All root (parentless) objects will by default be given the Z-value 0. Children will�if not manually set�have the value of its parent�s Z, plus 10; if the parent�s Z-value has been customly set it will add 10 to that value. If you make siblings that overlap eachother, and with no manually specified Z-value, no guarantees of the outcome can be made.

2.2 <styles> What we do with styles is basically just change the default settings of all or some settings. When creating a style we enter settings and values for them, this will be the new defaults when using this style. Note that if you choose a style, and then define all the settings manually, the style will have no affect on the object; remember it�s only the default values we change with the help of styles.

2.2.1 Creating styles Creating styles are almost like creating objects, below is an example of a style XML file, adding this file to the GUI will make the styles available for the entire GUI. You can have more than one style file, and more than one style per file. Notice that we use the same settings as when creating objects; the only unique setting is name which of course represents the name of the style and nothing else. Settings that we can�t change default for is name, style and type. Notice that styles are completely type-independent, you can create a styles that you use for several different object types.

GUI Styles XML file example <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?><!DOCTYPE styles SYSTEM "styles.dtd"><styles><!-- Style that will hide the object as new default --><style name="style_name1" hidden="true" /><!-- Style that helps us create a nice edit box --><style name="editbox_nice" sprite="sprite1" font="font1" /></styles>

2.3 <sprites> Sprites are a bit more complex than the obvious in the GUI Engine. A sprite can be built up by a number of *real* sprites and put together as a collage, and the instructions on how the different real sprites should be placed and tiled is quite dynamic. This lets you for instance make a dialog box that has fixed edges, but a freely resizable tiled inside. Compare to an HTML page with frames, where you can resize the explorer.

Take a look at this image, this could be a resizable button for instance. We would want all the corners to have a static size, the actual size of the border texture. The borders would have a static width, but a tiling length. And of course the center would be tiled. So let us get down to how you create this sprite, all we need is a file with the root element <sprites>. Within that file we can define as many sprites as we want. Having multiple sprite files and not all in one is just a matter of design.

GUI Sprites XML file example <?xml version="1.0" encoding="ISO-8859-1"?><sprites><sprite name="sprite_name"><image texture="texture_name" size="0 0 100% 100%" texture_size="0 0 100% 100%" /></sprite></sprites>

We just created a sprite with its texture stretched to its every corner with the image stretched to the object�s corners. Within the <sprite> and </sprite> you can have as many <image /> as you like, they are each real sprites; they all together form the entire collage. Now to the image�s settings:

texture Name of texture from database. Not inputted means no texture will be used. size Indicates size and position of the image relative to the object size. Of type client area; view documentation of the type for more information. texture_size Where the texture should be placed within the image, outside the size it will just tile. Of type client area; view documentation of the type for more information. backcolor Regular color stamp, only used if texture is left null. bordercolor Color of border. Will be placed at the edge of the image and extend internally as bordersize increase. Useless if border isn�t set to true. border The only available bordersize is now 1. So this is only a true or false. delta-z This is ?z, in other words if you want a slight change in z value for one of your images. Default is of course 0.

When are these collage sprites used? First of all, all sprites you use in the GUI will be declared like this so of course always. Secondly its strengths will be shown in such as buttons, scroll-bars, dialog windowses, message boxes and much more. I know this complexity will come in handy, but then again it can be a lot of code when declaring 300 ordinary bitmaps, the next chapter will tell you how to avoid this.

Here�s an example of the picture above, if the width of the border is 20:

GUI Sprites XML file example <sprites> <sprite name="button"> <!-- Starting with top left corner continuing in a clockwise manner --> <image texture="t1" size="0 0 20 20" texture_size="0 0 20 20" /> <image texture="t2" size="20 0 100%-20 20" texture_size="0 0 20 20" /> <image texture="t3" size="100%-20 0 100% 20" texture_size="0 0 20 20" /> <image texture="t4" size="100%-20 20 100% 100%-20" texture_size="0 0 20 20" /> <image texture="t5" size="100%-20 100%-20 100% 100%" texture_size="0 0 20 20" /> <image texture="t6" size="20 100%-20 100%-20 100%" texture_size="0 0 20 20" /> <image texture="t7" size="0 100%-20 20 100%" texture_size="0 0 20 20" /> <image texture="t8" size="0 20 20 100%-20" texture_size="0 0 20 20" /> <!-- middle --> <image texture="t9" size="20 20 100%-20 100%-20" texture_size="0 0 100 100" /> </sprite></sprites>

2.3.1 Skip a step When using sprites it�s very important to know the difference between the sprite name, and the texture name. You can�t just go sprite=�texture-from-texture-database� and think that will work. You have to setup a sprite with that texture first. Now this can be quite annoying with all textures that are just 100% stretched throughout the object, there is a simpler way of doing this. Because for instance 100% stretched is such a regular setup you don�t actually have to declare a sprite for that texture, you can just use a sort of a template; it looks like this:

sprite="stretched:texture-from-texture-database"

The above is perfectly valid code, creating the following sprite using it instead of the template would be the equivalent:

<sprite name="new_name"> <image texture="texture-from-texture-database" size="0 0 100% 100%" texture_size="0 0 100% 100%" /> </sprite>

If there�s any more usual setups that would be nice to have as a template like this, please contact me and I�ll put it in. 2.3.2 Multi-Cell Sprites

It�s often more efficient to put multiple sprites of the same size in a grid, rather than storing each as a separate texture. Although we can reference different areas of a texture and store it in a sprite, each element in a sheet of icons would have to be assigned its own sprite, which would be highly repetitive.

With this method, we can keep all 64x64 Celtic entity portraits in one sprite, for example, and reference the individual cells.

To activate this feature, just add cell-size=�cell_width cell_height� to the <image> attributes to tell the sprite parser the size of the individual cells:

<sprite name="new_name"> <image texture="texture-from-texture-database" size="0 0 100% 100%" texture_size="0 0 100% 100%" cell-size="64 64"/> </sprite>

The GUI control <object>s have a corresponding cell-id attribute to specify which cell of the sprite to display; �0� is the 1st element in the sprite.

<object name="new_object" sprite=�new_name� cell-id=�1�/>

Or to change the cell-id from script:

GUIObject = getGUIObjectByName("new_object"); GUIObject["cell-id"] = "1"; Will use the second element in the sprite.

The cell-id attribute can also be added to an <icon> in a similar way to assign a particular cell of a sprite to the icon. 2.3.3 Sprite Effects

Effects are special features that can be added to a sprite when it is first created. For example, the brightness of all images in a sprite can be altered from their base image so they appear lit (to create an illuminated hover version of a button, for example), without having to create a duplicate texture and alter its brightness in PhotoShop.

Effects are specified in the <effect/> tag, which must always appear before any <image>s in a <sprite> declraration.

Available effects at this time are:

� add-color: The specified RGB value is added to the colour value of the sprite. For example, add-color=�42 42 42� increases its overall brightness when displayed. � multiply-color: Similar to add-color, except it multiples each component (where they�re in the range 0-1 rather 0-255); in other words, multiply-color will always leave black parts black. Due to an OpenGL clamping restriction, components can never be > 255, so multiply-color cannot make an image brighter (though add-color can).

Note: add-color and multiply-color cannot be used together in the same sprite.

<sprite name="new_name"> <effect add-color=�42 42 42�/> <image texture="texture-from-texture-database" size="0 0 100% 100%" texture_size="0 0 100% 100%" /> </sprite> 2.4 <setup> Within these XML files you set up various GUI-related things, such as tool-tip and scrollbars. Within the root element (<setup>) you can place a list with an indefinite amount of the following elements:

2.4.1 <tooltip> This XML element sets up the look and feel of a tooltip. What sprite to use, what font to use, the distance from the mouse and the time it takes to appear. This example shows how to set it up:

GUI Setup tooltip example <setup><!-- Appearing text-box --><tooltip name="tooltip1" maxwidth="300" pos="10 10" time="500" sprite="backsprite" font="font" textcolor="0 0 0" /><!-- Existing text-box --><tooltip name="tooltip2" useobject="text-box-object-name" hide-object="true" /></setup>

name Reference name of tooltip; follows these naming rules. Used as value in the object setting tooltip. Setting this to �default� makes it the default tooltip, the tooltip that will be used when not specifying tooltip-style. If the default doesn�t exist and you try to use the default tooltip, the result will be no tooltip at all.

There are two ways of making the tooltip, either with an existing text-box, or you can request that a completely new text-box should appear in relative position to the cursor position. This is a black or white choice, so decide what method and stick with those settings because the other ones will be completely ignored.

2.4.1.1 Appearing text-box maxwidth When string takes more than this amount of pixels in width to draw, it will word-wrap. Of course this shouldn�t be more than 1024! pos Two integers, x and y from the mouse pointer to the upper-left corner of the tool-tip (unless the tool-tip has reached and edge) when tool-tip appears. time Elapsed time from entering the object with the cursor and standing still, until the tool-tip appears. sprite Sprite that will fit like a glove around the text drawn. Can be set to null if no background sprite is wanted. font Font used from font database. textcolor Color of font.

2.4.1.2 Existing text-box useobject Reference name of the object you like to use as the tooltip aid. hide-object Boolean setting with default �false�. If this is �true� the object will be unhid when above the object with the cursor, and hid when exiting the object.

2.4.2 <scrollbar> A scrollbar can be quite complex and built up of a number of sprites. In order to make a good scroll-bar it�s essential to know the meaning of the sprites� client area features.

GUI Setup Tool-tip example <setup><scrollbar name="scrollbar1" width="20" scrollwheel="null"alwaysshown="true"scrollspeed="30"button-top="button1" button-top-over="null" button-top-pressed="button1b"button-top-disabled="null"button-bottom="button2"button-bottom-over="null" button-bottom-pressed="button2b"button-bottom-disabled="null"scrollback="scrollback"scroll="scroll"minimum-bar-size="10"/></setup>

name Reference name of scrollbar style; follows these naming rules. Used in the object setting scrollbar-style. The name �default� as tooltip sets the scrollbar you have when you don�t specify scrollbar-style. width The width of the scrollbar, look at the image. The object�s (who owns the scrollbar) width will be decreased by the value of width. scrollwheel null = you can�t scroll this scrollbar with the mouse wheel. hard = you can use the mouse wheel to scroll, when scrolling it will instantly snap. smooth = you can use the mouse wheel to scroll, and it will scroll smoothly. This is under reconsideration though, due to technical difficulties vis-�-vis necessity. alwaysshown If this is �true� the scrollbar will be drawn even when no scrolling is needed, although scroll won�t be drawn and the buttons will use their *-disabled variant. scrollspeed When�either pressing a scroll-button, or moving one step with the mouse wheel�this is how many pixels it will scroll. button-top Sprite name. �null� on �over, �pressed and �disabled means it will use the main one without suffix. button-bottom Same as above, only with the button that scrolls you down. scrollback Sprite name. scroll Sprite name. minimum-bar-size This is the minimum size of the actual bar you click and drag with your mouse (scroll). Naturally even though you have a lot to scroll through, it should never be only a couple of pixels.

2.4.3 <icon> This lets you specify the size and texture of an icon that can be used within any caption that uses text (or perhaps only text-boxes). The only information you need to specify here is sprite name and size.

GUI Setup Tool-tip example <setup><icon name="smiley" sprite="smiley-happy02" size="10 10"/></setup>

To use the happy smiley in text like this J. You use commands within the text-box�s caption:

<object type="text">Here�s the [icon:smiley] I told you about</object>

Notice that the GUI will search for a �[icon:� and not a �[�, so �[� and �]� can still freely be used within the caption.

2.5 Inline JavaScript A problem with inline JavaScripts is the fact that we want to be able to use �<� and �>� within the code (which creates a syntax collision between JavaScript and XML). I have come up with two solutions: 2.5.1 The &lt;-solution This solution is tested and it works.

<action on="ButtonOver"> Inline script part if (hello < 45)hello = 45 INVALID CODE Inline script part </action>

This problem can be fixed by using &lt; instead of < and &gt; instead of >.

<action on="ButtonOver"> Inline script part if (hello &lt; 45)hello = 45 VALID CODE Inline script part </action> 2.5.2 The CDATA-solution This solution is tested and it works.

Another solution would make it a CDATA section wherein the rules of syntax is very liberal. This looks like this in XML and is used for sections known to use many <, >, & and so on:

<action on="ButtonOver"> <![CDATA[ Inline script part if (hello < 45)hello = 45 VALID CODE Inline script part ]]> </action>

The only invalid syntaxes inside the CDATA section is �]]>� and �<![CDATA[� which of course gives us an incredible minimum of syntax collisions.

I think this seems to be the best solution because surely �<� and �>� is not the only syntax collision we might meet with, but the downside is of course �<![CDATA[� and �]]>� isn�t that nice and user-friendly. Raj came up with the idea of pre-processing all the XML files which would make us change these to something easier, like:

<action on="ButtonOver"> #Begin Inline script part if (hello < 45)hello = 45 VALID CODE Inline script part #End </action>

And of course #Begin would be changed to �<![CDATA[� much like #End to �]]>�. A pre-processing state would enable us to do more useful things, like removing the �<?xml �� tag from the files, and add it solely in the pre-processing state.

More info about this at http://www.w3schools.com/xml/xml_cdata.asp.

  1. C++ API

Note! Most of the C++ API documentation can be found online at http://gee.pyro.nu/GUI/.

When including a GUI into a project, essentially all we have to work with is the main class, the CGUI. The CGUI has got one main CGUIObject object, it isn�t a real object, so its children we�ll be called �parentless�, since we don�t count this first object. Anyway as known each object can have a dynamic amount of children, so this base object will have children, that in its turn will have children, and so forth. This is what I call the object tree.

3.1 Settings Each CGUIObject inescapably has got a basic set of base settings. These reside within the CGUIObject in a struct at m_BaseSettings. But when creating say the derived object CButton, we want to extend the base settings with more, and we want them two to be able to work transparent with the base settings. This is what I�m talking about:

GUI<bool>::SetSetting(pObject, "hidden", true); GUI<CStr>::SetSetting(pObject, "sprite", SpriteName);

The setting hidden being a base setting within the CGUIObject, and sprite being an extended setting in the CButton. Alright first of all CButton is not directly derived from CGUIObject, it is derived from a wrapper class of the extended settings, CGUISettingsObject. This class is templated wherein you input a struct with the extended settings:

Struct SMoreSettings {

	bool m_ExSetting;

};

class CObjectWithMoreSettings : public CGUISettingsObject<SMoreSettings> {

};

This will get CGUISettingsObject<SMoreSettings> instantiated which will include a static map that tells us where we can find the all the settings and by what name. Getting there the next step is to declare this static map by including�

DECLARE_SETTINGS_INFO(SMoreSettings)

�at the top of CObjectWithMoreSettings�s cpp file. Next step is to fill this list with all the settings. Each element in the map is an SGUISetting looking like this:

struct SGUISetting {

	size_t			m_Offset;
	EGUISettingsStruct	m_SettingsStruct;
	CStr			m_Type;		

};

The offset being from the object to the setting, and the type being a string version of what type, for instance �color�, which would indicated it is of type CColor. The actual reference name of the setting is of course the key value of the map. Do notice that the offset does not regard from SMoreSettings to m_ExSetting, it is from CObjectWIthMoreSettings to m_ExSetting. This way we can include any variable that�s within the object class to the settings list.

Look at this figure here, the largest rectangle being an object derived from CGUISettingsObject. The left rectangle being the base settings, and the right one being the extended settings. Now they aren�t located right next to eachother since it might be other variables and methods in between. So let�s say we�re looking for the setting sprite. So we look through our map of SGUISettings and finds a SGUISetting for sprite. It�s got an m_Offset at 24, an m_SettingsStruct at GUISS_EXTENDED, and an m_Type at �string�. The GUISS_EXTENDED is inputted in a virtual function that returns a void pointer to the respective struct. The variable is then located at that address + 24 bytes.

This system is important since when we�re reading from XML and when we�re designing JavaScript interface, we need to be able to handle settings only by reference name regardless of wether it�s a base setting, or an extended setting.

Left to mention is how to setup this settings info map, just take a look at CButton.cpp and you�ll see how it adds it in the constructor, notice also it checks so it only adds it once. When inputting we need to check offset of the variable, therefore we need to use a macro even though it�s ugly.

3.2 The class GUI No I�m not talking about the CGUI class, I�m talking about GUI. Since this class is more like a namespace than a real class, all functions are static and no instance should exist of this class. It�s a class that takes a template argument, so it�s kinda like a templated namespace. Usage for instance like (the redded text are the templated argument of the function):

GUI<IGUIObject*>::RecurseObject(0, pObj, &IGUIObject::UpdateMouse, pObj2);

This works much better than trying to template functions within non-templated classes (or globally). 3.3 Messages When creating a new object, the most important function is almost HandleMessage, since it tells us how the object reacts to certain events. When specifying HandleMessage we can decide how our object will react when for instance a mouse enters it, or when its settings has been updated. These messages will primarily be sent from CGUI that processes all objects like a whole (some messages might have been sent from the object itself though).

3.4 XML Reading XML Reading is done with Xerces C++ Parser, it is available for a wide selection of platforms, so it won�t be a problem when porting to different platforms.

http://xml.apache.org/xerces-c/

3.4.1 Flexibility I want the ability to very freely create new objects for the GUI. For instance, when reading in an object from XML and an <object> element encounters a child element it doesn�t recognize, it will send it to a virtual function in CGUIObject to see if it knows how to read it. This function will now return true or false depending on if it was gibberish or not. This means new objects can extend what can be inside <object> </object> with that type.

See 2.1.1.2 Type-dependent Elements for more information.

  1. JavaScript API

This part is reserved for documention about how you will be able to interact with the GUI from JavaScript scripts.

  1. Miscellaneous

Here are things that doesn�t really fit into the document chronologically.

5.1 Naming rules There are a lot of different databases that we work with within the GUI, and all has got the unique ID being a name. The sprites, the tooltips, the scrollbar-styles, the icons and so on are all separated lists of names; they share the following convention when it comes to how the names can look:

Use only a-z, A-Z, 0-9, dash (-) and underscore (_) and you will be fine. Using unusual characters will probably not be syntactically incorrect, but no guarantees can be made because these characters can now or in the future be used as delimiters and markers, basically all other characters but the mentioned ones are being reserved. You should know this by now, but do not use any semicolons at all because it is the standard delimiter for the GUI.

  1. Issues

Some problems arise whilst designing and developing. These issues have to be dealt with and removed eventually and many are here only temporarily until a definite decision has been made.

Last modified 16 years ago Last modified on Feb 23, 2008, 4:19:00 AM
Note: See TracWiki for help on using the wiki.