Another GUI tutorial with example files
by Gonzo T. Clown · 09/28/2004 (8:55 pm) · 5 comments
Download Code File
** NOTE ** At the time of this writing there is a bug in TGE that will prevent this demo from working properly. The issue is addressed in This Thread. You must either manually repair your TGE as I illustrated, or wait for a review, and assuming it was approved, subsequent inclusion into the HEAD version.
While reinforcing the concepts from the first tutorial this demo will be going a step or two further into detail than the first demo did using different controls and their functions. We'll also be taking a closer look at the scripts as well. Our main focus will be to compare some of the differences between the way the first demo and this demo were built as well as understanding the controls in use and reasons for using each
First the Files:
I've set this demo up using a loader file (DemoLoadTwo.cs) to keep the pathing simple, to make the installation and removal of this demo as easy as possible, and to keep your files clean while the demo is in use. Simply drop the folder and the loader file into whatever directory you want them loaded from and make sure they are exec'ed at the proper time when TGE starts up. NOTE: To make this demo work right you need to open DemoGuiTwo.gui in your editor and change the $DemoBackgroundPath variable to the path that you installed this demo to. My path is "Client/GUIs/DemoGuiTwo/" and yours is bound to be different. If you were using the example's "starter.fps" for example your path would likely be "starter.fps/client/ui/DemoGuiTwo/". This is only neccesary because of the nature of the controls I am demonstrating and how they are properly used.
While you have the gui file open in your editor to change the path, lets look at how it's built. Our GUI begins with a "GuiChunkedBitmapCtrl" instead of a "GuiControl" like the first demo did. The first demo assumes that you want a clean overlay onto your current GUI and using a "GuiControl" allows for a transparent overlay. For this demo it's assumed you wish to change the background no matter what GUI you are looking at, so we use the "GuiChunkedBitmapCtrl" to start our GUI and overlay a new background at the same time. "Why not use a regular 'GuiBitmapCtrl'?" you might ask. Because for this demo we want to be able to use two features that a regular bitmap control does not have access to. The first feature is 'Tiling'. Once this GUI is opened you'll see the effect. Notice in the datablock I removed almost everything. The reason for this was to show exactly what is relevant to this demo's functionality and TGE's ability to do the rest. The first control in your GUI is always going to get stretched to the full screen size, so no matter what I set my size at, TGE will auto resize anyway, so there is no need for a declaration of "extent", "position", "horizSizing", or "vertSizing" because TGE will override them. We gave this control the name "DemoGuiTwo" so we could open and close it as well as have it perform functions all by name instead of by object number.
Our next control is also a "GuiChunkedBitmapCtrl" to help us demonstrate the difference in function modes for this type of control. It's named "DemoTwoControls" because we'll need to make adjustments to it as well. And our next control is a regular bitmap control because it's need is simple and only needs the basic functions. It does have it's own name as well because it will need to be adjusted from script like the others and we want to make it simple. The rest of the controls have no names because we have no need to adjust them from script. Their usage will be done in-game so TGE will handle them in default modes.
Ok, at this point, assuming you have saved the pathway change, lets load up TGE and the DemoGui. To start this GUI simply copy this command without the quotes "GTCDemoTwo();" and paste it into your TGE console.
Now you should be looking a tiled window that is full sized and a single window that is centered and filled with a preview window and some button controls. All three bitmap controls are using the same background which is 400 x 300. The preview window is only 186 x 186 so TGE scales it down to match the defined size. TGE will also scale up as you will see in a minute. This is handy for using one graphic in multiple instances without having to create a separate graphic for each instance. Tiled might be good for seamless images but it's quite annoying for a bordered graphic so lets change it by clicking on the "Background No Tile" text. Now TGE has removed the tiled attribute and scaled the 400 x 300 image up to match your resolution size. Now click on "Background Tiled" and then "Background No Tile" again. Notice that one button turns off the other? This is because these radio buttons are grouped together and only one radio button in a group can be active, more on this later.
If you'll click on the "Controls Background A" text you'll notice in the small preview window the border has become gold. Click on the "Controls Background B" and it will change to green. Click on "Controls Default" and notice it goes back to the grey border. Notice also that the radio button is following your choice no matter which of the three you choose. Once again this is because these 3 buttons are grouped and you can only have one button in a group active. Notice also that they operate without affecting the first radio button group. This is to show that you can have multiple groups of buttons all on the same page without having to jump through hoops to make it work, or even having to write scripts for them.
Ok, now click on "Controls Background A" and hit apply. Now your controls are bordered with the gold border. "Why apply? Can't this be automatic like the first group?" Yes, it could, but there are a few reasons I'm doing it this way. One is to illustrate that there is more than one way to use this stuff, another is that you can give people multiple choices and let them view those choices before they make changes. I'm also using it to demonstrate again that a control can do operations upon itself or even a parent without affecting the other in the process.
"Ok Gonzo, I like the gold but it looks strange with the grey background should I change it back?" No, here's where we learn why "GuiChunkedBitmapCtrl" packs more power than a standard "GuiBitmapCtrl". Hit 'F10' to load your GUI editor up and load DemoGuiTwo into the editor. Expand the tree view at the upper right and click on "DemoTwoControls" to highlight the controls window. In the GUI properties window beneath it you should see a checkbox button labled "useVariable" and it's currently checked. Up above that you should see "variable" and the text "DemoGuiBackground" right next to it. This is very important because what is does is force the control to use the graphic that is specified by the global variable "$DemoGuiBackground". Every time a "GuiChunkedBitmapCtrl" is awakened the engine checks to see if it is using a static bitmap or the result of a variable. Since the variable is a global, changing it will alter which background this control displays the next time it is opened. This means that your one GUI can have many different backgrounds instead of one static background. Which means instead of having to recreate the same GUI with several different static backgrounds, one will do the job. Not bad, but it gets even better. Click on "DemoGuiTwo" in the tree view and then look at the properties. In the blank next to "variable" type in "DemoGuiBackground", check the "useVariable" box, and then apply the changes to the control. Close the GUI editor and if the DemoGui is not still active then open your console and type in "gtcdemotwo();" to reopen it. It should already have the gold border like you wanted. Now change to one of the other borders (green or default) and hit apply. Now both your GUI and your controls window will apply the change at the same time without even having to change the scripts.
If all your GUIs used "GuiChunkedBitmapCtrl" and all were assigned to the same variable then you can change the background graphic of ALL of them by just altering the one variable instead of having to alter every single GUI separately. That is power and efficiency. Two most likely uses for such a feature are either to allow a user to customize his entire interface from various choices and save those custom variables in his preferences file, or to have a popup window display various graphics instead of the same graphic every time. You could accomplish the same things with regular bitmap controls, but there would be substantial code to deal with depending on the number of GUI's involved and it's kind of pointless to do so when you can get better performance from these already existing controls when you use them correctly.
Now lets open the DemoGui back up into the GUI editor and look at those radio buttons. The reason we are using radio styled buttons instead of regular push buttons is simply to teach you how to use them. Start by clicking on the "Background Tiled" text to display it's properties. Next to "command" is "DemoGuiTwo.tile = 1;" The first control in our GUI is named DemoGuiTwo, and it has a property called "tile", so we can simply issue a command from this button that changes the base controls "tile" value to "1" and the change takes effect immediately inside TGE. Take notice that the "groupNum" property has a 1 for its value. Click on the "Background No Tile" text and the properties will reveal the "command" of "DemoGuiTwo.tile = 0;" which sets the main control's "tile" value to zero and a "groupNum" of "1" which groups this control with the previous control. Because they are grouped, only one can be on ata time, and each will turn the other off if it is activated.
Clicking on any of the next three buttons will reveal that all of them are grouped into "groupNum" two and just like the first group, only one can be active at a time. Because they are in a different group, they do not affect the first group. If the group of a radio button is set to "-1" then the radio button will function as a single toggle switch that simply changes the value of it's assigned variable. Now each of the group two buttons calls upon the function "backgroundSwap();" using the "DemoGuiTwo" object by name as it's representative via 'command = "DemoGuiTwo.backgroundSwap();";' and two of them pass an extra piece of information, either "A" or "B". Although "Apply" is not a radio button it uses the same function they do and simply passes "Apply" as it's arguement. Viewing the GUI files reveals a relatively simple Switch/Case function to manage the DemoGui and its controls. I would like to point out that I have two lines commented out instead of deleted. If you were to remove the canvas push/pop commands and comment those lines back in, the result would be the same visually and the only real difference is the GUI doesn't close to change. However, I wanted to make sure you understood the point that TGE autochecks the variable every time the control opens, so manually setting one with the commented commands is never really neccesary. The only reason any of the commands are included with this GUI at all are to demonstrate the different applications possible, and to allow you to instantly see your changes. If these GUIs were being used dynamically in a game (routine on/off cycles like a popup) then all you would need to do is alter the global variable and the next time one of those GUIs opens it will automatically reflect the change.
Stay tuned for more tutorials under similar headings. And as always, if you have any questions, suggestions, or requests, please feel free to post them or email me.
I've considered also writing an exact step by step instruction list for each GUI I make to show GUI editor newbies exactly the steps it takes to create a good GUI structure without a bunch of editing or mistakes that lead to frustration. Would anyone be interested in something like that? Using the techniques I use making a GUI like this takes about 15 minutes and typing up the tut takes about 3 hours, lol.
** NOTE ** At the time of this writing there is a bug in TGE that will prevent this demo from working properly. The issue is addressed in This Thread. You must either manually repair your TGE as I illustrated, or wait for a review, and assuming it was approved, subsequent inclusion into the HEAD version.
While reinforcing the concepts from the first tutorial this demo will be going a step or two further into detail than the first demo did using different controls and their functions. We'll also be taking a closer look at the scripts as well. Our main focus will be to compare some of the differences between the way the first demo and this demo were built as well as understanding the controls in use and reasons for using each
First the Files:
I've set this demo up using a loader file (DemoLoadTwo.cs) to keep the pathing simple, to make the installation and removal of this demo as easy as possible, and to keep your files clean while the demo is in use. Simply drop the folder and the loader file into whatever directory you want them loaded from and make sure they are exec'ed at the proper time when TGE starts up. NOTE: To make this demo work right you need to open DemoGuiTwo.gui in your editor and change the $DemoBackgroundPath variable to the path that you installed this demo to. My path is "Client/GUIs/DemoGuiTwo/" and yours is bound to be different. If you were using the example's "starter.fps" for example your path would likely be "starter.fps/client/ui/DemoGuiTwo/". This is only neccesary because of the nature of the controls I am demonstrating and how they are properly used.
While you have the gui file open in your editor to change the path, lets look at how it's built. Our GUI begins with a "GuiChunkedBitmapCtrl" instead of a "GuiControl" like the first demo did. The first demo assumes that you want a clean overlay onto your current GUI and using a "GuiControl" allows for a transparent overlay. For this demo it's assumed you wish to change the background no matter what GUI you are looking at, so we use the "GuiChunkedBitmapCtrl" to start our GUI and overlay a new background at the same time. "Why not use a regular 'GuiBitmapCtrl'?" you might ask. Because for this demo we want to be able to use two features that a regular bitmap control does not have access to. The first feature is 'Tiling'. Once this GUI is opened you'll see the effect. Notice in the datablock I removed almost everything. The reason for this was to show exactly what is relevant to this demo's functionality and TGE's ability to do the rest. The first control in your GUI is always going to get stretched to the full screen size, so no matter what I set my size at, TGE will auto resize anyway, so there is no need for a declaration of "extent", "position", "horizSizing", or "vertSizing" because TGE will override them. We gave this control the name "DemoGuiTwo" so we could open and close it as well as have it perform functions all by name instead of by object number.
Our next control is also a "GuiChunkedBitmapCtrl" to help us demonstrate the difference in function modes for this type of control. It's named "DemoTwoControls" because we'll need to make adjustments to it as well. And our next control is a regular bitmap control because it's need is simple and only needs the basic functions. It does have it's own name as well because it will need to be adjusted from script like the others and we want to make it simple. The rest of the controls have no names because we have no need to adjust them from script. Their usage will be done in-game so TGE will handle them in default modes.
Ok, at this point, assuming you have saved the pathway change, lets load up TGE and the DemoGui. To start this GUI simply copy this command without the quotes "GTCDemoTwo();" and paste it into your TGE console.
Now you should be looking a tiled window that is full sized and a single window that is centered and filled with a preview window and some button controls. All three bitmap controls are using the same background which is 400 x 300. The preview window is only 186 x 186 so TGE scales it down to match the defined size. TGE will also scale up as you will see in a minute. This is handy for using one graphic in multiple instances without having to create a separate graphic for each instance. Tiled might be good for seamless images but it's quite annoying for a bordered graphic so lets change it by clicking on the "Background No Tile" text. Now TGE has removed the tiled attribute and scaled the 400 x 300 image up to match your resolution size. Now click on "Background Tiled" and then "Background No Tile" again. Notice that one button turns off the other? This is because these radio buttons are grouped together and only one radio button in a group can be active, more on this later.
If you'll click on the "Controls Background A" text you'll notice in the small preview window the border has become gold. Click on the "Controls Background B" and it will change to green. Click on "Controls Default" and notice it goes back to the grey border. Notice also that the radio button is following your choice no matter which of the three you choose. Once again this is because these 3 buttons are grouped and you can only have one button in a group active. Notice also that they operate without affecting the first radio button group. This is to show that you can have multiple groups of buttons all on the same page without having to jump through hoops to make it work, or even having to write scripts for them.
Ok, now click on "Controls Background A" and hit apply. Now your controls are bordered with the gold border. "Why apply? Can't this be automatic like the first group?" Yes, it could, but there are a few reasons I'm doing it this way. One is to illustrate that there is more than one way to use this stuff, another is that you can give people multiple choices and let them view those choices before they make changes. I'm also using it to demonstrate again that a control can do operations upon itself or even a parent without affecting the other in the process.
"Ok Gonzo, I like the gold but it looks strange with the grey background should I change it back?" No, here's where we learn why "GuiChunkedBitmapCtrl" packs more power than a standard "GuiBitmapCtrl". Hit 'F10' to load your GUI editor up and load DemoGuiTwo into the editor. Expand the tree view at the upper right and click on "DemoTwoControls" to highlight the controls window. In the GUI properties window beneath it you should see a checkbox button labled "useVariable" and it's currently checked. Up above that you should see "variable" and the text "DemoGuiBackground" right next to it. This is very important because what is does is force the control to use the graphic that is specified by the global variable "$DemoGuiBackground". Every time a "GuiChunkedBitmapCtrl" is awakened the engine checks to see if it is using a static bitmap or the result of a variable. Since the variable is a global, changing it will alter which background this control displays the next time it is opened. This means that your one GUI can have many different backgrounds instead of one static background. Which means instead of having to recreate the same GUI with several different static backgrounds, one will do the job. Not bad, but it gets even better. Click on "DemoGuiTwo" in the tree view and then look at the properties. In the blank next to "variable" type in "DemoGuiBackground", check the "useVariable" box, and then apply the changes to the control. Close the GUI editor and if the DemoGui is not still active then open your console and type in "gtcdemotwo();" to reopen it. It should already have the gold border like you wanted. Now change to one of the other borders (green or default) and hit apply. Now both your GUI and your controls window will apply the change at the same time without even having to change the scripts.
If all your GUIs used "GuiChunkedBitmapCtrl" and all were assigned to the same variable then you can change the background graphic of ALL of them by just altering the one variable instead of having to alter every single GUI separately. That is power and efficiency. Two most likely uses for such a feature are either to allow a user to customize his entire interface from various choices and save those custom variables in his preferences file, or to have a popup window display various graphics instead of the same graphic every time. You could accomplish the same things with regular bitmap controls, but there would be substantial code to deal with depending on the number of GUI's involved and it's kind of pointless to do so when you can get better performance from these already existing controls when you use them correctly.
Now lets open the DemoGui back up into the GUI editor and look at those radio buttons. The reason we are using radio styled buttons instead of regular push buttons is simply to teach you how to use them. Start by clicking on the "Background Tiled" text to display it's properties. Next to "command" is "DemoGuiTwo.tile = 1;" The first control in our GUI is named DemoGuiTwo, and it has a property called "tile", so we can simply issue a command from this button that changes the base controls "tile" value to "1" and the change takes effect immediately inside TGE. Take notice that the "groupNum" property has a 1 for its value. Click on the "Background No Tile" text and the properties will reveal the "command" of "DemoGuiTwo.tile = 0;" which sets the main control's "tile" value to zero and a "groupNum" of "1" which groups this control with the previous control. Because they are grouped, only one can be on ata time, and each will turn the other off if it is activated.
Clicking on any of the next three buttons will reveal that all of them are grouped into "groupNum" two and just like the first group, only one can be active at a time. Because they are in a different group, they do not affect the first group. If the group of a radio button is set to "-1" then the radio button will function as a single toggle switch that simply changes the value of it's assigned variable. Now each of the group two buttons calls upon the function "backgroundSwap();" using the "DemoGuiTwo" object by name as it's representative via 'command = "DemoGuiTwo.backgroundSwap();";' and two of them pass an extra piece of information, either "A" or "B". Although "Apply" is not a radio button it uses the same function they do and simply passes "Apply" as it's arguement. Viewing the GUI files reveals a relatively simple Switch/Case function to manage the DemoGui and its controls. I would like to point out that I have two lines commented out instead of deleted. If you were to remove the canvas push/pop commands and comment those lines back in, the result would be the same visually and the only real difference is the GUI doesn't close to change. However, I wanted to make sure you understood the point that TGE autochecks the variable every time the control opens, so manually setting one with the commented commands is never really neccesary. The only reason any of the commands are included with this GUI at all are to demonstrate the different applications possible, and to allow you to instantly see your changes. If these GUIs were being used dynamically in a game (routine on/off cycles like a popup) then all you would need to do is alter the global variable and the next time one of those GUIs opens it will automatically reflect the change.
Stay tuned for more tutorials under similar headings. And as always, if you have any questions, suggestions, or requests, please feel free to post them or email me.
I've considered also writing an exact step by step instruction list for each GUI I make to show GUI editor newbies exactly the steps it takes to create a good GUI structure without a bunch of editing or mistakes that lead to frustration. Would anyone be interested in something like that? Using the techniques I use making a GUI like this takes about 15 minutes and typing up the tut takes about 3 hours, lol.
About the author
#2
12/07/2004 (6:14 am)
again very usefull resource Gonzo, lol I've been scanning through your profile and your comments/posts, all of your posts seem to give me further insight into the game engine and scripting... again thanks for the tutorials, I'm slowly disecting them and implimenting them... a customized good looking gui really makes a huge difference
#3
12/07/2004 (11:28 pm)
Thanks Matthew. Appreciate the kind words. I've been pretty sick the last few weeks but I'll be back in action pretty soon and I'll see if I can get some more useful stuff out. And as always, if you need specific help, just ask and I'll give you the best answers I can offer.
#4
By the way, I had to re-type this because after I cliked "Notify when new comments are posted", my browser re-loaded the screen and my comment was gone...any way to avoid that, without making that choice before typing?
01/16/2005 (1:03 pm)
Both one and two very very helpful! I would love to have more similar tutorials and examples. As for specific requests; anything that would ease GUI creation for an RPG: a stat screen accessible in-game and a character creation screen...maybe with some sliders to allow for initial point distribution among the skills. Thanks for all your effort!By the way, I had to re-type this because after I cliked "Notify when new comments are posted", my browser re-loaded the screen and my comment was gone...any way to avoid that, without making that choice before typing?
#5
I put a bitmapChunkGui on my screen and went back into my game where my mouse buttons actually navigate the avatar. Everything was ok and my graphic was still on screen.
I closed the app, the exports occurred ( TGE 1.5 ) and on opening the application, i was unable to use the mouse for navigation though the keyboard commands still worked. I put debug msgs in the yaw() and pitch() functions and found that they were no longer being called.
I found that by typing into the console this command - yaw(15);, the command actually worked, my debug statement showed up and of course the character turned as expected. But since modifying the playGui screen, and watching the export occur, my mouse navigation is no longer enabled. Looking in config.cs and default.bind.cs did not appear to show that anything there had changed but obviously something had.
So, my question is, why would putting a GuiChunkekBitmapCtrl on my playGui screen cause my mouse navigation to quite suddenly stop working?
P.S.
Have now tested this thrice, same result.
08/05/2007 (3:32 am)
Gonzo, I also found this very helpful. Perhaps I can ask a question related to GUI's?I put a bitmapChunkGui on my screen and went back into my game where my mouse buttons actually navigate the avatar. Everything was ok and my graphic was still on screen.
I closed the app, the exports occurred ( TGE 1.5 ) and on opening the application, i was unable to use the mouse for navigation though the keyboard commands still worked. I put debug msgs in the yaw() and pitch() functions and found that they were no longer being called.
I found that by typing into the console this command - yaw(15);, the command actually worked, my debug statement showed up and of course the character turned as expected. But since modifying the playGui screen, and watching the export occur, my mouse navigation is no longer enabled. Looking in config.cs and default.bind.cs did not appear to show that anything there had changed but obviously something had.
So, my question is, why would putting a GuiChunkekBitmapCtrl on my playGui screen cause my mouse navigation to quite suddenly stop working?
P.S.
Have now tested this thrice, same result.

Torque 3D Owner Matthew Langley
Torque