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@pyro.nu 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 2. XML FILES 8 2.1 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 13 2.2.1 Creating styles 13 2.3 14 2.3.1 Skip a step 15 2.4 15 2.4.1 15 2.4.1.1 Appearing text-box 16 2.4.1.2 Existing text-box 16 2.4.2 16 2.4.3 17 2.5 INLINE JAVA-SCRIPT 17 2.5.1 The <-solution 17 2.5.2 The CDATA-solution 18 3. 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 4. JAVASCRIPT API 22 5. MISCELLANEOUS 23 5.1 NAMING RULES 23 6. 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 (, etc). � Examples added. � A lot of additions to the objects� chapter, such as standard actions. � Whole new chapter 4. added. � Whole new chapter 5. 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 �� 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 , , and 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 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: Select 1 Select 2 DoThis() DoThat() 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 ) 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: Inline script part PlaySound("click") Inline script part � and that might be enough. 1.3.3 Custom This section refers to things you declare in other XML files than , but they are of course used within the ; 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. 2. 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 and . Each different root element will have its own chapter ahead. 2.1 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 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 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 StringType-dependent ElementsActionsChildren 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 Gee, 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 . The action tag takes one option and that is �on�, like this: JavaScript goes here 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. 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: 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: 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 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 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