GUIHandler - XML Based GUI Generation(updated 2/18/04)

Announce new projects or updates of Irrlicht Engine related tools, games, and applications.
Also check the Wiki
Post Reply
saigumi
Posts: 921
Joined: Fri Aug 22, 2003 11:31 am
Location: St. Louis, MO USA
Contact:

GUIHandler - XML Based GUI Generation(updated 2/18/04)

Post by saigumi »

GUIHandler is a Class that allows for the loading of GUI sets via XML. The author would only need to specify a layout and perform one function call to load the entire GUI. The GUIs are handled in a parent-child relationship, so destruction of the GUI is only one functional call also.

There is plentiful documentation on it's usage in the header file, plus an example based on Irrlicht Tutorial 5, and a readme.txt file.

Link: http://www.saigumi.net/guihandler.zip
Image of it in action: http://www.saigumi.net/images/guihandler-potw.png

Update 2/18/2004:
Added 0.5 elements and swapped the core changes that I made with the ones that Niko included in Irrlicht 0.5.

Update 2/17/2004:
Started modifying to handle new gui elements added in 0.5

Below is the element tags for the new elements, code to handle these elements is being written.

Code: Select all

<element type="IGUIEditBox" id="" top="" left="" height="" width="" color="" font="" maximum="" border="" visible="" />
			<element type="IGUITabControl" id="" top="" left="" height="" width="" fill="" border="">
				<element type="IGUITab" id="" top="" left="" height="" width="" active="" color=""/>
			</element>
			<element type="IGUIContextMenu" id="" top="" left="" height="" width="">
				<element type="MenuItem" id="" text="" enabled="">
					<!-- Repeat Layerable IGUIContextMenu -->
					<element type="IGUIContextMenu" />
				</element>
				<element type="MenuSeperator"/>
			</element>
			<element type="IGUIMenu" id="" >
				<element type="MenuItem" id="" text="" enabled="">
					<!-- Repeat Layerable IGUIContextMenu -->
					<element type="IGUIContextMenu" />
				</element>
				<element type="MenuSeperator"/>
			</element>
Old updates

Update 1/26/04:
Converted to TinyXML instead of libXML
Gonna start working on new controls. This controls will be part of core Irrlicht, but calllable from GUIHandler

Update 1/22/04:
Finally tracked down the list bug. I added a new element type IGUIEmpty to handle placeholders for other elements. The source has been sent to Niko as well as updated GUIEnvironment and IGUIElement files that make it more consistent with ISceneNode.

I've tripped over a few more Irrlicht defects, like invisible parents will have visible children, that I am fixing.

New image of it in action: http://www.saigumi.net/images/guihandler-potw.png
Last edited by saigumi on Wed Feb 18, 2004 7:23 pm, edited 7 times in total.
Crud, how do I do this again?
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

excellent. if it matures (no mem leaks :wink: ) maybe I'll steal it for ICE! :twisted:
a screen cap is worth 0x100000 DWORDS
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

hrm, when i try to download the .zip, i get a 0 byte file
a screen cap is worth 0x100000 DWORDS
saigumi
Posts: 921
Joined: Fri Aug 22, 2003 11:31 am
Location: St. Louis, MO USA
Contact:

Post by saigumi »

Weird, the file is there, and I'm getting 0 byte retrieves now:

This one works -
http://www.saigumi.net/guihandler-retry.zip

I have already fixed all of the 'if (char* = "") problems'. I guess I hit one of the most newb C++ errors. I have fixed it and am now doing 'if (strcmp(char*, "") ==0)'

Also, I think I got all the memory places plugged, but I don't like it. I was doing mallocs for the wchar_t* 's. But whenever I did a free(), it would blow. I think I was doing something else to break the pointer before the free. I will look into it tonight, but for now, I have switched all the wchar_t* 's to wchar_t[255]. <-- I don't like the 255 limit. :cry:
Crud, how do I do this again?
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

well, since you're dealing with screen space, theres only so much that will be displayed anyway: for buttons, etc. so for those, you shouldnt worry about even using a 64 element array.

larger boxes of text are another story
a screen cap is worth 0x100000 DWORDS
saigumi
Posts: 921
Joined: Fri Aug 22, 2003 11:31 am
Location: St. Louis, MO USA
Contact:

Post by saigumi »

My thought is that only two elements that should every have large bodies of text are the IMessageBox and IStaticText.

More than 255 chars on a Window caption or a button is just outright silly.

255 on a Listbox line is... possible, but semi-silly

I also am of the belief that if you hit a 255 limit, you should just create a second box to hold more text.
Crud, how do I do this again?
saigumi
Posts: 921
Joined: Fri Aug 22, 2003 11:31 am
Location: St. Louis, MO USA
Contact:

Post by saigumi »

I got all the memory issues worked out. Added a lot of error catching and XML format checking. I've added 2 custom control sets by pasting together already created controls: Icon + Progress Bar.

The one flaw is that I my code to register GUIElements for usage by the parent application is causing guienv->drawall() to fail. I put a post about it in the Advanced Help forum. Registering allows the parent application to use the created GUI elements.

Once this is fixed, I will have a stable and usable class that will only need enhancing with no structural changes.

On the TODO list is:
Add more Error Handling and Messages
Custom GUI Items (Consoles...)
Add xml property for SetVisible()
GUI Input Handling(forward events from OnEvent to GUIHandler to manipulate elements)
Complete AddMeshViewer()
Add Color Loader for Color Override in Static Text(sscanf() didn't work)
Add Resize all elements when Scaling Ratio changes or is turned on/changed
Add GUI Skin Modification
Add Custom Style Templates to enhance default skin calls
Crud, how do I do this again?
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

two questions:

1) I see you're using libxml:
would you consider using tinyXML instead? The reason I ask is because two of us (me and powerpop) already are-- its easier to distribute with your code because it has a very open liscense and is only 6 files (2 headers), so you can simply chunk it in with the rest of your code. This is much easier for distribution, then having people go and download libXML and linking it in.

2) Use:
A)I see your class loads in XML and attaches GUI elements to IrrLicht. Do you have an example of how you actually catch the events that are caused by these? I assume you can set the ID of the GUI elements in your XML, and you can simply expect to recieve events with these IDs in your onEvent handler?

B)Is there a way to remove all of what was constructed?
C)Is there a possibily of using two different instances of this class at the same time? ie: one instance for your regular GUI, and another instance for a dialog. When the dialog pops up, you leave the old GUI sitting there and merely load in the dialog.XML object. when its done, you just delete that object.

keep up the good work.
a screen cap is worth 0x100000 DWORDS
saigumi
Posts: 921
Joined: Fri Aug 22, 2003 11:31 am
Location: St. Louis, MO USA
Contact:

Post by saigumi »

1. I looked at tinyXML before, but didn't plan on using it because it didn't have XPath functionality. Now that you mentioned it, I googled "tinyXML xpath" and found "tinyXPath" which uses tinyXML. I use XPath because I like nodesets and not having to write code that crawls a whole document to find one node if there is something else that will do it for me.

2a. Yep, the ID is there so that you can reference the created GUI Elements. The function RegisterGUIElement will retrieve a pointer to the Element for you. Unfortunately, Irrlicht 0.4.2 doesn't have a getElementbyID function like sceneNodes do. So I coded it in... but for some reason it's stomping the element list somehow that I can't find. (See the "getElementbyID Memory problem" thread in the advanced forum. As soon as that is fixed, I will be able to push onto added wrapper style functionality for handling GUI events.

2b. There will be. I noticed that my code doesn't make a root node properly. It was something I was going to go back and add in. I am going to add a function to IGUIEnvironment that allows the creation of a Dummy GUI Element. Then have each GUI set use it as a parent. Then the whole set can be wiped by calling for a delete of the parent GUI element.

2c. Sort of. The GUI handler can create multiple layouts at the same time and the XML can hold many layouts. You can split your GUI layout groupings into multiple XML documents though.

Here is my demo set. I have 3 layouts: a loading screen, a main hud, and a character creation scene. Each is loaded when they are needed and tossed when they are not. The ID is important because that is the easiest way to uniquely identify the Element in Irrlicht.

Code: Select all

<gui>
	<layouts>
		<layout id="0" name="loadingscreen" skin="0">
			<element type="IGUIImage" id="203" top="8" left="8" height="14" width="624"/>
			<element type="IGUIStaticText" id="204" top="10" left="10" height="10" width="620" border="true" color="FFFFFF" wordwrap="false" text="Loading..."/> 
		</layout>
		<layout id="1" name="mainhud" skin="0">
			<element type="IGUIImage" id="1" top="8" left="8" height="14" width="624" filename="bgtile.bmp"/>
			<element type="IGUIStaticText" id="2" top="10" left="10" height="10" width="620" border="true" color="FFFFFF" wordwrap="false" text="Debug Area - FPS: %d * Vertices: %d = %d VPS"/> 
			<element type="IGUIListBox" id="3" top="330" left="560" height="140" width="70" iconfont="fontcomic.bmp">
				<element type="ListItem" icon="A" text="Move"/>
				<element type="ListItem" icon="B" text="Attack"/>
				<element type="ListItem" icon="C" text="End Turn"/>
				<element type="ListItem" icon="D" text="Cancel"/>
			</element>
		</layout>
		<layout id="2" name="charactercreation" skin="0">
			<element type="IGUIStaticText" id="100" top="10" left="10" height="10" width="50" text="Name"/> 
			<element type="IGUIStaticText" id="101" top="30" left="10" height="10" width="50" text="Gender"/> 
			<element type="IGUIStaticText" id="102" top="60" left="10" height="10" width="50" text="Strength"/> 
			<element type="IGUIScrollBar"  id="103" top="60" left="70" height="10" width="200" horizontal="true" maximum="20" value="8"/>
			<element type="IGUIStaticText" id="104" top="80" left="10" height="10" width="50" text="Dexterity"/> 
			<element type="IGUIScrollBar"  id="105" top="80" left="70" height="10" width="200" horizontal="true" maximum="20" value="8"/>
			<element type="IGUIStaticText" id="106" top="100" left="10" height="10" width="50" text="Intellegence"/> 
			<element type="IGUIScrollBar"  id="107" top="100" left="70" height="10" width="200" horizontal="true" maximum="20" value="8"/>
			<element type="IGUIStaticText" id="108" top="120" left="10" height="10" width="50" text="Wisdom"/> 
			<element type="IGUIScrollBar"  id="109" top="120" left="70" height="10" width="200" horizontal="true" maximum="20" value="8"/>
			<element type="IGUIStaticText" id="110" top="140" left="10" height="10" width="50" text="Charisma"/> 
			<element type="IGUIScrollBar"  id="111" top="140" left="70" height="10" width="200" horizontal="true" maximum="20" value="8"/>
			<element type="IGUIStaticText" id="112" top="170" left="10" height="10" width="50" text="Fortitude"/> 
			<element type="IGUIScrollBar"  id="113" top="170" left="70" height="10" width="200" horizontal="true" maximum="20" value="8"/>
			<element type="IGUIStaticText" id="114" top="190" left="10" height="10" width="50" text="Reflex"/> 
			<element type="IGUIScrollBar"  id="115" top="190" left="70" height="10" width="200" horizontal="true" maximum="20" value="8"/>
			<element type="IGUIStaticText" id="116" top="210" left="10" height="10" width="50" text="Will"/>
			<element type="IGUIScrollBar"  id="117" top="210" left="70" height="10" width="200" horizontal="true" maximum="20" value="8"/>
			
			<element type="IGUIImage" id="118" top="10" left="280" height="60" width="60" filename="bgtile.bmp"/>
		</layout>
	</layouts>
</gui>
Crud, how do I do this again?
saigumi
Posts: 921
Joined: Fri Aug 22, 2003 11:31 am
Location: St. Louis, MO USA
Contact:

Post by saigumi »

Updated.
Crud, how do I do this again?
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

IrrLicht 5.0 is out-- how soon will you be moving to it?
a screen cap is worth 0x100000 DWORDS
saigumi
Posts: 921
Joined: Fri Aug 22, 2003 11:31 am
Location: St. Louis, MO USA
Contact:

Post by saigumi »

Well, when I posted it... I just started. The new tags up there will handle the new elements. I've added controlling code and am debugging now.

Also, from the Irrlicht change docs, it looks like there won't need to be any custom Irrlicht core changes needed. I haven't gotten to the point of testing visibilty and position changes to see if children move and go visible with their parents.

The only thing I see is that there isn't an addEmptyGUIElement(), but I think I can add code to shim one in or use a blank IGUIImage.

My goal is to trim all the needed code down to 2 files, a header and a cpp.
Crud, how do I do this again?
niko
Site Admin
Posts: 1759
Joined: Fri Aug 22, 2003 4:44 am
Location: Vienna, Austria
Contact:

Post by niko »

saigumi wrote:The only thing I see is that there isn't an addEmptyGUIElement(), but I think I can add code to shim one in or use a blank IGUIImage.
You could try to use a Tab instead of this.
patlecat
Posts: 27
Joined: Wed Feb 18, 2004 11:19 am
Location: Switzerland

Post by patlecat »

Hi SauGummi

It's a great addition to irrLicht indeed. Yet as a total beginner I fail to understand how to use it. Would you mind adding 2-3 examples (with c++ code!) to it and a ReadMe file explaining how and where to install it?

Next of course comes up the question of: "Wouldn't it be nice to have a GUI Editor?" :lol: YES it would :!:


Greetz, pat le cat
saigumi
Posts: 921
Joined: Fri Aug 22, 2003 11:31 am
Location: St. Louis, MO USA
Contact:

Post by saigumi »

GUI Editor, yes. It won't be soon though.

I added a readme. It's the exact same instructions that are in the Header file. It's already detailed on how to use it. There is also a file called "guilayout-template.xml" that has all of the possible syntax.

I also added an example, which is basically Irrlicht Tutorial #5, done with GUIHandler instead of defining it all in the code.
Crud, how do I do this again?
Post Reply