GUI questions

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
UncleBob
Posts: 106
Joined: Fri May 01, 2009 8:46 am

GUI questions

Post by UncleBob »

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?
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Re: GUI questions

Post by randomMesh »

I'd use a state machine.
UncleBob wrote: The other big question is, what's the easiest way to make the MastEventReceiver work with the standard irrlicht GUI?
What do you expect, what did you try and what does not work?
"Whoops..."
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

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:

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;
	}

};
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.
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
UncleBob
Posts: 106
Joined: Fri May 01, 2009 8:46 am

Post by UncleBob »

I'd use a state machine.
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.
What do you expect, what did you try and what does not work?
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.
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Post by randomMesh »

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.
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: Well, it would be nice to have GUI elements recognize their events (like mouseover and click)
I use this code for detecting mouse over for buttons

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..."
UncleBob
Posts: 106
Joined: Fri May 01, 2009 8:46 am

Post by UncleBob »

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" :lol:
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

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
UncleBob
Posts: 106
Joined: Fri May 01, 2009 8:46 am

Post by UncleBob »

oh heck, that complicates things...

In that case, though, what will a state machine exactly do? just reset the environment every time a state changes? is that really the only way to do it?
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

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
Brainsaw
Posts: 1183
Joined: Wed Jan 07, 2004 12:57 pm
Location: Bavaria

Post by Brainsaw »

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
UncleBob
Posts: 106
Joined: Fri May 01, 2009 8:46 am

Post by UncleBob »

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.
Sorry, I missed your post (was posted almost at the same time as mine).

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?)
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

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.
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: 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...?
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: (dang, who would've thought that setting up a GUI is more difficult than setting up a scene?)
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.
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
UncleBob
Posts: 106
Joined: Fri May 01, 2009 8:46 am

Post by UncleBob »

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).
Ahhh, NOW I get it. Seems like a nice way to go. I'll try it out.

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...
UncleBob
Posts: 106
Joined: Fri May 01, 2009 8:46 am

Post by UncleBob »

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?
jeetee
Posts: 15
Joined: Tue Oct 13, 2009 3:09 pm
Contact:

Post by jeetee »

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:

Code: Select all

CGUIEmptyElement StarMapGUI(mGUI, 0);
IGUIElement element = (IGUIElement)StarMapGUI;
//or even better
IGUIElement* iPointToTheEmptyOne = (IGUIElement*)(&StarMapGUI);
[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

Code: Select all

CGUIEmptyElement StarMapGUI(mGUI, 0);
s32 id = StarMapGui.getID(); //getID() is a method of IGUIElement
[/EDIT]
Post Reply