How to Access GuiTSCtrl::project...
by Lateral Punk · in Torque Game Engine · 07/17/2006 (7:28 am) · 11 replies
Hi There,
I have created a derived SceneObject class. In my renderObject() method I would like to use the function GuiTSCtrl::project. Unfortunately, to access that function I need access to the GuiTSCtrl object since it is non-static. And there are only two ways I know how to get it. One is if you derive from GuiControl, and the other is if you just do a Sim::findObject("PlayGui"). Well the first doesn't apply to my case, and I would rather not do the second because I don't feel comfortable hard-coding. So has anyone else come up with another method to use this function? I know of the corresponding dglPointToScreen() function, but I heard some bad things about it on the forums. Looking at the code though, it seems to do the same thing as ::project, so maybe I can just use that? Any info anyone?
thanks in advance
I have created a derived SceneObject class. In my renderObject() method I would like to use the function GuiTSCtrl::project. Unfortunately, to access that function I need access to the GuiTSCtrl object since it is non-static. And there are only two ways I know how to get it. One is if you derive from GuiControl, and the other is if you just do a Sim::findObject("PlayGui"). Well the first doesn't apply to my case, and I would rather not do the second because I don't feel comfortable hard-coding. So has anyone else come up with another method to use this function? I know of the corresponding dglPointToScreen() function, but I heard some bad things about it on the forums. Looking at the code though, it seems to do the same thing as ::project, so maybe I can just use that? Any info anyone?
thanks in advance
#2
a better way to do this would be to put a virtual method in the base class GuiControl which looks like this:
guiControl.h
.. and then override it in guiTSControl.h:
guiTSControl.h
(actually i don't think it even needs to be virtual)
and then change the code above to:
the advantage here is that the first implementation won't detect future controls which are derived from GuiTSCtrl, and the second will. the second is also just simpler.
07/17/2006 (8:14 am)
You know,a better way to do this would be to put a virtual method in the base class GuiControl which looks like this:
guiControl.h
virtual bool amGuiTSCtrl() { return false; }.. and then override it in guiTSControl.h:
guiTSControl.h
virtual bool amGuiTSCtrl() { return true; }(actually i don't think it even needs to be virtual)
and then change the code above to:
GuiTSControl* GuiControl::FindParentOrSelfOfTypeTSCtrl()
{
GuiControl* curr = this;
while (curr != NULL)
{
if (curr->amTSCtrl())
return curr;
curr = curr->parent();
}
return NULL;
}the advantage here is that the first implementation won't detect future controls which are derived from GuiTSCtrl, and the second will. the second is also just simpler.
#3
thanks for the posting. Unfortunately, both methods you described above wouldn't work in my case, because as I stated my ojbect derives from SceneObject not GuiControl. The methods you are talking about assumes a class that is derived from GuiControl in order to access the methods such as parent(). I require access to the project() method of GuiTSControl from a SceneObject class which there currently is no example/support for. But I am thinking to myself, that that method should almost be "static" because anyone (not just GUIs) would want such a handy function. So my question really is 1) can I somehow call project() from anywhere, and, 2) is dglPointToScreen() even working, because if it is, maybe I can just directly use that function.
07/17/2006 (10:20 am)
Hi Orion! thanks for the posting. Unfortunately, both methods you described above wouldn't work in my case, because as I stated my ojbect derives from SceneObject not GuiControl. The methods you are talking about assumes a class that is derived from GuiControl in order to access the methods such as parent(). I require access to the project() method of GuiTSControl from a SceneObject class which there currently is no example/support for. But I am thinking to myself, that that method should almost be "static" because anyone (not just GUIs) would want such a handy function. So my question really is 1) can I somehow call project() from anywhere, and, 2) is dglPointToScreen() even working, because if it is, maybe I can just directly use that function.
#4
07/17/2006 (10:23 am)
Orion, actually your second approach gives me an idea. If I can start from the root gui control, and scan through all the gui controls doing a dynamic_cast to GuiTSControl and finding the first such object, then voila I have it. What do you think? I can even do this one time say on ::onAdd() or something, so I don't have to keep finding it all the time in renderObject().
#5
Use like this:
07/17/2006 (10:30 am)
template<class T>
bool GuiControl::findParentOfType(T*&parent)
{
GuiControl* curr = this;
while (curr != NULL)
{
parent= dynamic_cast<T*>(curr);
if (parent!= NULL)
return true;
curr = curr->parent();
}
parent = NULL;
return false;
}Use like this:
GuiTSCtrl *gtsc;
if(findParentOfType(gtsc))
{
// do stuff
}
else
{
// whine
}
#6
yah, you could use the findFirstChild() method which is conveniently already in your codebase;
there's an example of using it in GuiConvBubbleCtrl::onRender().
(Lateral and i are working on the same project, folks)
But that sort of assumes there's only one GuiTSCtrl in the scene, which may not be true.
(Is not true for example in the case of Manoel's fabulous Cg water resource, which has two.)
Perhaps a better way to do it would be to explicitely declare one GuiTSControl as the one you're interested in.
For example,
in your sceneObject have a console method along the lines of "SetProjectingTSCtrl()" which just sets a member variable that's a pointer to a GuiTSCtrl. Then in script set it explicitely to PlayGui.
I'm curious tho why you want to project to screen-space if the results are not associated with a GuiControl.
07/17/2006 (10:34 am)
Heya Lateral - sorry for the misinterpretation.yah, you could use the findFirstChild() method which is conveniently already in your codebase;
there's an example of using it in GuiConvBubbleCtrl::onRender().
(Lateral and i are working on the same project, folks)
But that sort of assumes there's only one GuiTSCtrl in the scene, which may not be true.
(Is not true for example in the case of Manoel's fabulous Cg water resource, which has two.)
Perhaps a better way to do it would be to explicitely declare one GuiTSControl as the one you're interested in.
For example,
in your sceneObject have a console method along the lines of "SetProjectingTSCtrl()" which just sets a member variable that's a pointer to a GuiTSCtrl. Then in script set it explicitely to PlayGui.
I'm curious tho why you want to project to screen-space if the results are not associated with a GuiControl.
#7
07/17/2006 (10:36 am)
Ok, so what GuiControl object do I call this on? I was hoping to root GuiControl if there is such a thing? Remember, I am not a GuiControl but a SceneObject :)
#8
07/17/2006 (10:39 am)
Ben - sweet, thanks!
#9
07/17/2006 (10:41 am)
My previous posting was to Ben. Differnt ways of doing the same thing :) Orion I like your suggestion of the console method, bug again it seems "out of place". I was really hoping there would be one GuiTScontrol :) Ok Ben & Orion, can you answer the question regarding the funciton dglPointToScreen(). I mean I might as well just use that and it'll solve all my probs (if it works).
#10
07/17/2006 (1:21 pm)
DglPointToScreen() ?? :)
#11
07/17/2006 (7:45 pm)
DglPointToScreen does not work as expected. GuiTsCtrl::project works better than expected :)
Associate Orion Elenzil
Real Life Plus
i posted a similar question once and ben garney suggested just walking up the parent heirarchy doing dynamic-casts to GuiTSCtrl.
i believe there's a couple examples of this in the code, but i'm not sure where.
the code would look something like this
GuiTSControl* GuiControl::FindParentOrSelfOfTypeTSCtrl() { GuiTSControl* found = NULL; GuiControl* curr = this; while (curr != NULL) { found = dynamic_cast<GuiTSControl*>(curr); if (found != NULL) return found; curr = curr->parent(); } return NULL; }this code sort of blows in the way that it's hard-coded for GuiTSControl,
what would be ideal is if you could actually pass in the Class type itself,
but that's beyond [my] c++ abilities.
i do present a slight generalization of this sort of thing in a resource for finding a child control of a given type,
where you at least pass in a callback which is then the hardcoded test for classtype.
it's slightly better because the heirarchy traversal is written only once.
i totally agree with you that doing a findObject("PlayGui") is too hard-coded.