Showing GUI on the fly multiple times - question [Answered]
by Colin Richardson · in Torque Game Builder · 07/30/2009 (7:53 am) · 8 replies
Hello,
I'm getting on well with our game, coming up next is for me to show up a GUI (that shows the data for the item they've found).
I can do this easily, i have made the GUI (in the Editor), i set the text/graphics and then pop/push when needed.
But is it possible to show the same GUI more than once at the same time?
Ie they've opened up one bag, and want to open up another.
From what i can see the name of the GUI is unique and thus i can only pop it once, is there a way to give it a unique name before its shown so i can use the same GUI many times.
I'll have another look tonight as the only way doing what i can involves me creating the GUI from script which i'm to do but would like to know if there's a simpler way.
Cheers
Colin
I'm getting on well with our game, coming up next is for me to show up a GUI (that shows the data for the item they've found).
I can do this easily, i have made the GUI (in the Editor), i set the text/graphics and then pop/push when needed.
But is it possible to show the same GUI more than once at the same time?
Ie they've opened up one bag, and want to open up another.
From what i can see the name of the GUI is unique and thus i can only pop it once, is there a way to give it a unique name before its shown so i can use the same GUI many times.
I'll have another look tonight as the only way doing what i can involves me creating the GUI from script which i'm to do but would like to know if there's a simpler way.
Cheers
Colin
#2
Thanks for the pointers.
I presume you're telling me that i will have to script it all and that there's no way of me taking my gui (itemWindow.gui) and just creating a copy on the fly that i can show and then destroy.
I presume to create on the fly using script i'll have to:
As if i do try that i get an error "unable to insantiate non-conobject class GuiCtrl".
Sorry to ask some dumb questions, still learning tons here, but glad where i am, as now i'm onto the real fun stuff.
Cheers
07/31/2009 (7:50 am)
Hello Ted,Thanks for the pointers.
I presume you're telling me that i will have to script it all and that there's no way of me taking my gui (itemWindow.gui) and just creating a copy on the fly that i can show and then destroy.
I presume to create on the fly using script i'll have to:
%name = "TheNextItemWindow" @ %i; // Equates to TheNextItemWindow1
%ctrl = new GuiCtrl(%name) {
cansavedynamicfields = "0";
isContainer = "1";
Profile="GuiItemWindow";
...
new GuiScrollControl() {
cansavedynamicfields = "0";
isContainer = "1";
Profile="GuiItemWindow";
...
...
new GuiMLTextCtrl() {
...
...
};
};
};As if i do try that i get an error "unable to insantiate non-conobject class GuiCtrl".
Sorry to ask some dumb questions, still learning tons here, but glad where i am, as now i'm onto the real fun stuff.
Cheers
#3
Also, you don't need to specify it every time, you can store the GUI as a string. Ever see in the .gui files the %guictrl = new ... line? I haven't tried this, but you can change that %guiCtrl to something like $itemWindowCtrl to access it from other scripts, and then muck with the name before pushing and popping, like:
Now, you can make %i a global ($i or $windowID or something) variable if you're going to store it, and if you've got several of these windows, you may want to do that. Give it a shot and let me know if it works for you.
07/31/2009 (9:59 am)
It's GuiControl, I believe, not GuiCtrl...Also, you don't need to specify it every time, you can store the GUI as a string. Ever see in the .gui files the %guictrl = new ... line? I haven't tried this, but you can change that %guiCtrl to something like $itemWindowCtrl to access it from other scripts, and then muck with the name before pushing and popping, like:
%name = "itemWindow" @ %i++; //%i would be defined somewhere else %ctrl = new $itemWindowCtrl; //Set up the %ctrl variable from template %ctrl.setName(%name); //Set the new name Canvas.pushDialog(%name); //push it out to screen
Now, you can make %i a global ($i or $windowID or something) variable if you're going to store it, and if you've got several of these windows, you may want to do that. Give it a shot and let me know if it works for you.
#4
Thanks for your help, we're getting there :)
First using script, i just copy my gui into a gameScript file, exec that script and then i can call that function i made to create the GUI on the fly.
Good stuff, so that's one way of doing it, however your latest reply makes me think i can just copy it. I'll try that later now i have the scripting version working.
However when the script pushes the dialog to the canvas, i've found that the gui i had active no longer responds until i close the new itemWindow, is it not possible to have multi-gui on the screen with each responding?
Cheers
07/31/2009 (2:26 pm)
Ted,Thanks for your help, we're getting there :)
First using script, i just copy my gui into a gameScript file, exec that script and then i can call that function i made to create the GUI on the fly.
Good stuff, so that's one way of doing it, however your latest reply makes me think i can just copy it. I'll try that later now i have the scripting version working.
However when the script pushes the dialog to the canvas, i've found that the gui i had active no longer responds until i close the new itemWindow, is it not possible to have multi-gui on the screen with each responding?
Cheers
#5
here's how i go about stuff like this.
first, let's say that the canvas has a gui called PlayGUI on it,
eg set with Canvas.setContent(playGui);
then i would write something like:
playGui.add(getNewDialogFoo());
and have something like the following in a .cs file somewhere which has been exec'd:
note that there are no global names involved.
ie, "new GuiControl(foo)" doesn't appear.
this is, imo, better practice in general since globals can lead to messy code, but it does make some things a bit of a hassle, such as implementing a close button. in the example above, the close button's command is "$ThisControl.getGoup().delete()". $ThisControl is a special global set up by the engine to point to the GuiControl which is executing the command; in this case the button. (beware! not all controls implement $ThisControl properly. if it's not working, it may be a bug in the engine and you should just fix it, it's not hard) getGroup() is a method of all SimObjects, and returns the SimGroup which contains the object in question, if there is one. All GuiControls are SimGroups, so this will return the parent control, ie, the GuiWindowCtrl. Delete() is obvious, it deletes the control, and all children.
note this GetGroup() pattern is a little fragile because if you or some other coder comes along later and moves the close button inside of some other control, eg: Window [ SomeOtherControl [ CloseButton]]] then GetGroup() will yield SomeOtherControl. You could get around that by doing something like this:
in that example, the "%window" resolves to the SimID of the just-created window control. so if %window = 1234, it's effectively the same as writing command = "1234.delete();";
while i'm at it, i'll also mention that my approach to putting together GuiControls is to sort of sketch them out in the Gui editor, but do all the real coding by hand. It lets you do stuff like using variables during control creation, which allows for more sophisticated layouts, and it's also cleaner and more precise.
apologies for the huge post, i hope it helps somewhat or at least gives you some ideas !
07/31/2009 (4:21 pm)
hey colin -here's how i go about stuff like this.
first, let's say that the canvas has a gui called PlayGUI on it,
eg set with Canvas.setContent(playGui);
then i would write something like:
playGui.add(getNewDialogFoo());
and have something like the following in a .cs file somewhere which has been exec'd:
function getNewDialogFoo()
{
%dlg = new GuiWindowControl() {
// profile, position, etc, etc
new GuiButtonCtrl() {
// profile, position, etc, etc
command = "$ThisControl.getGroup().delete();";
text = "close";
};
new SomeOtherGuiCtrl() {
};
// and so on
};
return %dlg;
}note that there are no global names involved.
ie, "new GuiControl(foo)" doesn't appear.
this is, imo, better practice in general since globals can lead to messy code, but it does make some things a bit of a hassle, such as implementing a close button. in the example above, the close button's command is "$ThisControl.getGoup().delete()". $ThisControl is a special global set up by the engine to point to the GuiControl which is executing the command; in this case the button. (beware! not all controls implement $ThisControl properly. if it's not working, it may be a bug in the engine and you should just fix it, it's not hard) getGroup() is a method of all SimObjects, and returns the SimGroup which contains the object in question, if there is one. All GuiControls are SimGroups, so this will return the parent control, ie, the GuiWindowCtrl. Delete() is obvious, it deletes the control, and all children.
note this GetGroup() pattern is a little fragile because if you or some other coder comes along later and moves the close button inside of some other control, eg: Window [ SomeOtherControl [ CloseButton]]] then GetGroup() will yield SomeOtherControl. You could get around that by doing something like this:
function getDialogFoo()
{
%window = new GuiWindowCrl() {
// position etc
};
%window.add(new GuiControl() {
// position etc
new GuiButtonCtrl() {
// position etc;
command = %window @ ".delete();";
};
};
return %window;
}in that example, the "%window" resolves to the SimID of the just-created window control. so if %window = 1234, it's effectively the same as writing command = "1234.delete();";
while i'm at it, i'll also mention that my approach to putting together GuiControls is to sort of sketch them out in the Gui editor, but do all the real coding by hand. It lets you do stuff like using variables during control creation, which allows for more sophisticated layouts, and it's also cleaner and more precise.
apologies for the huge post, i hope it helps somewhat or at least gives you some ideas !
#6
Wow, that reads so easily and looks like it's going to do the trick. I have struggled to close the GUI down as %This.getParent().safedelete() on the button just crashes TGB...
I've modified my script to work like yours, so you are correct that no Global is needed, and that by returning the ID i can then send that ID to my script to populate the GUI before i show it.
Showing it is now the problem.
If i pushDialog(%newWindowID) then it appears where i wanted it to appear and has the controls i wanted it to have, however the GUI currently on the screen is inactive (which i don't want).
If i canvas.setContent(%newWindowID) then as i'm only using a small part of the screen the rest of the screen is now not responding and the cursor just repeats.
So the pushDialog seems to be the best method, however how is it possible to have two active GUI's on the screen at the same time?
I've too have found that the GUI Editor is ok to a point, then it gets a little frustrating to do some of the simplest things, so i think i'll move to scripting them once i'm happy with it all.
I am suffering from being an experienced coder that i sometimes see something, get it working, run with it and find i'm stuck, where as if i started slowly i'd not be in the same prediciment.
Cheers!
08/01/2009 (4:34 am)
Morning Orion,Wow, that reads so easily and looks like it's going to do the trick. I have struggled to close the GUI down as %This.getParent().safedelete() on the button just crashes TGB...
I've modified my script to work like yours, so you are correct that no Global is needed, and that by returning the ID i can then send that ID to my script to populate the GUI before i show it.
Showing it is now the problem.
If i pushDialog(%newWindowID) then it appears where i wanted it to appear and has the controls i wanted it to have, however the GUI currently on the screen is inactive (which i don't want).
If i canvas.setContent(%newWindowID) then as i'm only using a small part of the screen the rest of the screen is now not responding and the cursor just repeats.
So the pushDialog seems to be the best method, however how is it possible to have two active GUI's on the screen at the same time?
I've too have found that the GUI Editor is ok to a point, then it gets a little frustrating to do some of the simplest things, so i think i'll move to scripting them once i'm happy with it all.
I am suffering from being an experienced coder that i sometimes see something, get it working, run with it and find i'm stuck, where as if i started slowly i'd not be in the same prediciment.
Cheers!
#7
Ok i still can't understand what i'm doing wrong, so i've stepped back a bit and made things to much simpler.
I have a two GUI's, both for the sake of simpleness made with the GUI editor.
One is called 'mainScreenGUI' and the other 'itemWindowGUI'
Both of these are loaded in the game.cs

When i click on the 'X Test' button the following code is run:
And then up pops the Item Window GUI (here's an example)

This appears in the centre of the screen, and you can see the full extent of this.
So i still have the Hotkey buttons at the bottom, however these don't respond, it's as if the ItemWindowGUI is modal and it stops the other GUI's from respondng (as the game itself responds to the character walking about).
I have made a GUI Profile with the modal = true; and modal = false; and attached it to my ItemWindowGUI, however it still doesn't work.
Does anyone have an answer? How can i stop this from happening, i need both GUI's to work, please, please i hope this can be done.
Thanks in advance,
Colin
08/02/2009 (5:25 am)
Hello,Ok i still can't understand what i'm doing wrong, so i've stepped back a bit and made things to much simpler.
I have a two GUI's, both for the sake of simpleness made with the GUI editor.
One is called 'mainScreenGUI' and the other 'itemWindowGUI'
Both of these are loaded in the game.cs
exec("~/gui/mainScreenGui.gui");
exec("~/gui/itemWindowGui.gui");
Canvas.setContent(mainScreenGui); //shows our in-game HUD
Canvas.setCursor(DefaultCursor);Here's a screen shot of what the basic game screen looks like and shows the part with our hotbuttons/keys.
When i click on the 'X Test' button the following code is run:
canvas.pushDialog(itemWindowGUI);
And then up pops the Item Window GUI (here's an example)

This appears in the centre of the screen, and you can see the full extent of this.
So i still have the Hotkey buttons at the bottom, however these don't respond, it's as if the ItemWindowGUI is modal and it stops the other GUI's from respondng (as the game itself responds to the character walking about).
I have made a GUI Profile with the modal = true; and modal = false; and attached it to my ItemWindowGUI, however it still doesn't work.
Does anyone have an answer? How can i stop this from happening, i need both GUI's to work, please, please i hope this can be done.
Thanks in advance,
Colin
#8
Thank the gods (as spoken in Battlestar Galatica).
It was me being daft, and now that i've been so daft i've learnt so much more trying other stuff.
I had to set the guiProfile that i was using to use modeless, ie modal = false;
Then what i had to do was to also set this to be the profile for all the GUI's i've been pushing, either by script, or by console command... and it works :)
So i now know how to make Dialog boxes appear modeless (for my Item Example) and i know how to make the appear Modal for 'Delete this item?' kind of questions.
Happy bunny now, but i wouldn't be this far without the replies above.
Cheers folks :)
08/02/2009 (9:04 am)
Solved :)Thank the gods (as spoken in Battlestar Galatica).
It was me being daft, and now that i've been so daft i've learnt so much more trying other stuff.
I had to set the guiProfile that i was using to use modeless, ie modal = false;
Then what i had to do was to also set this to be the profile for all the GUI's i've been pushing, either by script, or by console command... and it works :)
So i now know how to make Dialog boxes appear modeless (for my Item Example) and i know how to make the appear Modal for 'Delete this item?' kind of questions.
Happy bunny now, but i wouldn't be this far without the replies above.
Cheers folks :)
Torque 3D Owner Ted Southard
%ctrl = new GuiCtrl(%name){ ...Gui stuff here...};
%ctrl.doStuff();
First line is the most important, the other two is just pseudocode. Hope it helps :)