GUI questions
GUI questions
getting along with my interface, I face several problems on which I seem to be unable to find an answer.
First and foremost, how do you switch between different GUI environments, Let's say I have a screen with these controls, a screen with other controls etc. (a pretty common setting, I imagine), it would seem easiest to just create an environment for every screen and then switch between them (like, if I go to the options-screen, set the option-gui to visible and enable it, and when switching to another screen disabling and hiding it again). However, I am unable to find any commands for the GUI environment that would let me enable or disable the whole environment (for hiding and showing it's the same).
The other big question is, what's the easiest way to make the MastEventReceiver work with the standard irrlicht GUI?
First and foremost, how do you switch between different GUI environments, Let's say I have a screen with these controls, a screen with other controls etc. (a pretty common setting, I imagine), it would seem easiest to just create an environment for every screen and then switch between them (like, if I go to the options-screen, set the option-gui to visible and enable it, and when switching to another screen disabling and hiding it again). However, I am unable to find any commands for the GUI environment that would let me enable or disable the whole environment (for hiding and showing it's the same).
The other big question is, what's the easiest way to make the MastEventReceiver work with the standard irrlicht GUI?
-
- Posts: 1186
- Joined: Fri Dec 29, 2006 12:04 am
Re: GUI questions
I'd use a state machine.
What do you expect, what did you try and what does not work?UncleBob wrote: The other big question is, what's the easiest way to make the MastEventReceiver work with the standard irrlicht GUI?
"Whoops..."
I use an invisible parent element for different screens. So I can disable/enable those. As invisible element I use currently a custom gui element which looks like that:
Note that it has to be large enough (larger than any of it's children) because currently we can't disable clipping for a parent but only for childs.
And MGUIET_EMPTY is just a constant which you can set for example to irr::gui::EGUIET_COUNT+1.
Code: Select all
class CGUIEmptyElement : public irr::gui::IGUIElement
{
public:
CGUIEmptyElement(irr::gui::IGUIEnvironment* environment, irr::gui::IGUIElement* parent)
: irr::gui::IGUIElement((irr::gui::EGUI_ELEMENT_TYPE)MGUIET_EMPTY, environment, parent, -1, irr::core::rect<irr::s32>(0,0,100,100)) {}
irr::gui::IGUIEnvironment* GetEnvironment() { return Environment; }
virtual const irr::c8* getTypeName() const { return "empty"; }
virtual bool isPointInside(const irr::core::position2d<irr::s32>& point) const
{
return false;
}
virtual bool bringToFront(IGUIElement* element)
{
bool result = IGUIElement::bringToFront(element);
// pass that on
if ( Parent )
{
Parent->bringToFront(this);
}
return result;
}
};
And MGUIET_EMPTY is just a constant which you can set for example to irr::gui::EGUIET_COUNT+1.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Argh, that looks like lots of work with lots of things I don't know yet... oh well, I'll see if I can get something together.I'd use a state machine.
Well, it would be nice to have GUI elements recognize their events (like mouseover and click). More I don't need. So far I tried to simply put them there, noticed they didn't work, searched around and found that there seems to be a general problem with the MastEventReceiver and the GUI, but didn't find a general solution for it. So I thought I'd ask if such a solution exists.What do you expect, what did you try and what does not work?
-
- Posts: 1186
- Joined: Fri Dec 29, 2006 12:04 am
It is a bit of work to understand the concept of a state machine at the beginning but it is worth it. It's a very flexible solution not only for multiple guis but also scenes.UncleBob wrote:Argh, that looks like lots of work with lots of things I don't know yet... oh well, I'll see if I can get something together.
I use this code for detecting mouse over for buttonsUncleBob wrote: Well, it would be nice to have GUI elements recognize their events (like mouseover and click)
Code: Select all
case irr::EET_GUI_EVENT:
{
if (event.GUIEvent.EventType == irr::gui::EGET_ELEMENT_HOVERED)
{
const irr::gui::EGUI_ELEMENT_TYPE& type = event.GUIEvent.Caller->getType();
if (type == irr::gui::EGUIET_BUTTON)
{
((irr::gui::IGUIButton*)event.GUIEvent.Caller)->setPressed(true);
return true;
}
}
else if (event.GUIEvent.EventType == irr::gui::EGET_ELEMENT_LEFT)
{
const irr::gui::EGUI_ELEMENT_TYPE& type = event.GUIEvent.Caller->getType();
if (type == irr::gui::EGUIET_BUTTON)
{
((irr::gui::IGUIButton*)event.GUIEvent.Caller)->setPressed(false);
return true;
}
}
}
"Whoops..."
Hmmm... how do I create an empty IGUIEnvironment (I.E. one that is not just a pointer to the environment of the device?) if I could do that, that might already help a lot (or result in a crash once I try out my ideas, but there's no harm in that)
I'm afraid I'm not too hot on the deeper aspects of object oriented programing, so stuff like abstract classes etc. are rather confusing to me. I'm used to being able to create a new instance of a class with "new"
I'm afraid I'm not too hot on the deeper aspects of object oriented programing, so stuff like abstract classes etc. are rather confusing to me. I'm used to being able to create a new instance of a class with "new"
You can't, there is only one guienvironment.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Uhm... I told you above a way to do it. That's actually the way I've been doing gui already in a few projects.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Maybe I should use the visible-version in the next project. Currently the states of my project create the GUI on activation and clear it on deactivation. Works fine for me (but I don't have any in-game GUI stuff to switch, so it's just main menu, options, select level...)
Dustbin::Games on the web: https://www.dustbin-online.de/
Dustbin::Games on facebook: https://www.facebook.com/dustbingames/
Dustbin::Games on twitter: https://twitter.com/dustbingames
Dustbin::Games on facebook: https://www.facebook.com/dustbingames/
Dustbin::Games on twitter: https://twitter.com/dustbingames
Sorry, I missed your post (was posted almost at the same time as mine).Uhm... I told you above a way to do it. That's actually the way I've been doing gui already in a few projects.
Also I'm a bit slow here, since I don't really know what parents and childs are actually for (in programming, that is). As I said, I'm only a hobby programer and not too familiar with the deeper aspects of object oriented programing.
If I understood that right, you're just having an empty element that covers the current GUI. that seems reasonable for hiding gui elements, but I still don't quite understand how that helps you to display other elements on top of it...?
(dang, who would've thought that setting up a GUI is more difficult than setting up a scene?)
Parent-childs work similar to magnets. The bottom one is the parent. If you put other magnets on top of that they will stick there. You move the bottom magnet (parent) the top ones (childs) will move with it. You hide the parent everything on it is also hidden. And you can give position of the childs always relative to the top-left corner of the parent. Moving around the childs does not influence the parent. So if you put all elements for one screen on one parent you can move around/hide all elements just by doing that to the parent. You can even rescale it and make childs rescale the same (ok, you can't scale magnets so there the analogy breaks, any better analogy is welcome).UncleBob wrote: Also I'm a bit slow here, since I don't really know what parents and childs are actually for (in programming, that is). As I said, I'm only a hobby programer and not too familiar with the deeper aspects of object oriented programing.
One empty element per screen - all the real gui elements are childs of that. You display only that element - all it's childs will then also be displayed. Then you enabled always the correct empty element with setVisible(true) and disable the old one with setVisible(false).UncleBob wrote: If I understood that right, you're just having an empty element that covers the current GUI. that seems reasonable for hiding gui elements, but I still don't quite understand how that helps you to display other elements on top of it...?
Yeah, GUI complexity is always surprising. When we wrote our racer I also was surprised afterwards that the task costing by far the most time had been gui programming.UncleBob wrote: (dang, who would've thought that setting up a GUI is more difficult than setting up a scene?)
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Ahhh, NOW I get it. Seems like a nice way to go. I'll try it out.One empty element per screen - all the real gui elements are childs of that. You display only that element - all it's childs will then also be displayed. Then you enabled always the correct empty element with setVisible(true) and disable the old one with setVisible(false).
One problem popping up here, "MGUIET_EMPTY" does not seem to be a known TypeName (nor does EGUIET_EMPTY). How do I have to define it so it works?
anotherr edit: just noticed that you already answered my question. thanks. let's see if I can get this working...
Hmmm... I could define it alright, like this:
CGUIEmptyElement StarMapGUI(mGUI, 0);
Is that correct so far?
because, I'm a bit dumbfounded on how to work with it. I do not see how I can get a handle to the actual IGUIElement underlying it, which I would need as a parent element when defining the child elements, or am I screwing things up completely here?
CGUIEmptyElement StarMapGUI(mGUI, 0);
Is that correct so far?
because, I'm a bit dumbfounded on how to work with it. I do not see how I can get a handle to the actual IGUIElement underlying it, which I would need as a parent element when defining the child elements, or am I screwing things up completely here?
CGUIEmptyElement is a sub-class of IGUIElement, therefor you can treat any CGUIEmptyElement as an IGUIElement.
Also follow the analogy:
I have a car and it can drive. I also have a Porche. Since my Porche is a car, it can also drive.
the description of what the 'plain' car can do = IGUIElement
the Porche = CGUIEmptyElement
in code:
[EDIT]
since it is a sub-class, you can also use all public methods of the base-class, without having to cast your object to the basetype
[/EDIT]
Also follow the analogy:
I have a car and it can drive. I also have a Porche. Since my Porche is a car, it can also drive.
the description of what the 'plain' car can do = IGUIElement
the Porche = CGUIEmptyElement
in code:
Code: Select all
CGUIEmptyElement StarMapGUI(mGUI, 0);
IGUIElement element = (IGUIElement)StarMapGUI;
//or even better
IGUIElement* iPointToTheEmptyOne = (IGUIElement*)(&StarMapGUI);
since it is a sub-class, you can also use all public methods of the base-class, without having to cast your object to the basetype
Code: Select all
CGUIEmptyElement StarMapGUI(mGUI, 0);
s32 id = StarMapGui.getID(); //getID() is a method of IGUIElement