Tutorial 5 User Interface 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.
Post Reply
namespace
Posts: 7
Joined: Thu Jul 09, 2009 6:30 pm

Tutorial 5 User Interface questions

Post by namespace »

Code: Select all

#include <irrlicht.h>
#include <iostream>

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif

// Declare a structure to hold some context for the event receiver so that it
// has it available inside its OnEvent() method.
struct SAppContext
{
	IrrlichtDevice *device;
	s32				counter;
	IGUIListBox*	listbox;
};
Ok, whats struct, is it like a class? These appear to be pointers, I'll assume for instance that listbox when called calls the IGUIListBox.
s32 is type of variable, from what the definition said, so whats counter, a variable?

Code: Select all

{
	GUI_ID_QUIT_BUTTON = 101,
	GUI_ID_NEW_WINDOW_BUTTON,
	GUI_ID_FILE_OPEN_BUTTON,
	GUI_ID_TRANSPARENCY_SCROLL_BAR
};
This has always been a little odd for me, I get it, they all get an increasing value by one assigned to them, I assume there standard long or short variables. I'm not quite sure what you can do with the number 102 assigned to new window button, but maybe I'll catch it this time. (I've been through all this code in detail at least once.) (I've just never seen a useful example)

Code: Select all

class MyEventReceiver : public IEventReceiver
{
public:
	MyEventReceiver(SAppContext & context) : Context(context) { }

	virtual bool OnEvent(const SEvent& event)
	{
		if (event.EventType == EET_GUI_EVENT)
		{
			s32 id = event.GUIEvent.Caller->getID();
			IGUIEnvironment* env = Context.device->getGUIEnvironment();

			switch(event.GUIEvent.EventType)
			{
Ok, so you make a new class called MyEventReceiver, and go to define public variable IEventReciever?
You enter public again? and then use the class you just created, in the class your defining? and then you assign context to point to the structure SAppContext you just created?
Then two more contexts?
You then declare a variable OnEvent in which you define a constant? and have the word event, I'm not sure how event is related to the contstant, but the constant you defined is an irr class dealing with events, so event after the irr event variable means?
Then you say, if the event is a gui event, make a variable id and assign it whatever caused the event. I'm not really sure what kind of things return from this, so I'm not sure how to handle them, is it like, IPushButton?
Then makes a variable env which points to GetGUIEnviorment of type IGUIEnviorment.
Then, switch(event.GUIEvent.EventType) how does it know which piece of code to pick based on this, and the periods I assume mean something like > ?
btw, is there any common element to the I's before variable types?

Code: Select all

                        /*
	                If a scrollbar changed its scroll position, and it is
			'our' scrollbar (the one with id GUI_ID_TRANSPARENCY_SCROLL_BAR), then we change
			the transparency of all gui elements. This is a very
			easy task: There is a skin object, in which all color
			settings are stored. We simply go through all colors
			stored in the skin and change their alpha value.
			*/
			case EGET_SCROLL_BAR_CHANGED:
				if (id == GUI_ID_TRANSPARENCY_SCROLL_BAR)
				{
					s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
					
					for (u32 i=0; i<EGDC_COUNT ; ++i)
					{
						SColor col = env->getSkin()->getColor((EGUI_DEFAULT_COLOR)i);
						col.setAlpha(pos);
						env->getSkin()->setColor((EGUI_DEFAULT_COLOR)i, col);
					}
					
				}
				break;
I'm not sure where we got the scroll bar, I suppose were defining MyEventReciever still and we'll use it later. If scroll bar changed see if the id value is the same as the gui scroll bar value, which is like 103. I don't know how id knows that the value we created would be 103 or anything?? (how does id know)
You create a new variable called pos and make it = to ( see getPos() is a function of IGUIScrollBar but I don't see a reason for the * or event.GUIEvent.Caller in parentheses.
For new variable i = 0, i < colors available, add one to i? How is that useful?
Then you use, pre existing variable col, or new variable, type SColor, and set it to the colors available. (how do you set it to all of the colors available, including alpha, or does it only pull the color your setting?
Then set it to the position.

I think this covers most of the basics, after this I'll just be asking the same questions over again.

Code: Select all

			/*
			If a button was clicked, it could be one of 'our'
			three buttons. If it is the first, we shut down the engine.
			If it is the second, we create a little window with some
			text on it. We also add a string to the list box to log
			what happened. And if it is the third button, we create
			a file open dialo
			That's all for the event receiver.
			*/
			case EGET_BUTTON_CLICKED:
				switch(id)
				{
				case GUI_ID_QUIT_BUTTON:
					Context.device->closeDevice();
					return true;

				case GUI_ID_NEW_WINDOW_BUTTON:
					{
					Context.listbox->addItem(L"Window created");
					Context.counter += 30;
					if (Context.counter > 200)
						Context.counter = 0;

					IGUIWindow* window = env->addWindow(
						rect<s32>(100 + Context.counter, 100 + Context.counter, 300 + Context.counter, 200 + Context.counter),
						false, // modal?
						L"Test window");

					env->addStaticText(L"Please close me",
						rect<s32>(35,35,140,50),
						true, // border?
						false, // wordwrap?
						window);
					}
					return true;

				case GUI_ID_FILE_OPEN_BUTTON:
					Context.listbox->addItem(L"File open");
					env->addFileOpenDialog(L"Please choose a file.");
					return true;

				default:
					return false;
				}
				break;

			default:
				break;
			}
		}

		return false;
	}

private:
	SAppContext & Context;
};


/*
Ok, now for the more interesting part. First, create the Irrlicht device. As in
some examples before, we ask the user which driver he wants to use for this
example:
*/
int main()
{
	// ask user for driver
	
	video::E_DRIVER_TYPE driverType;

	printf("Please select the driver you want for this example:\n"\
		" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
		" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
		" (f) NullDevice\n (otherKey) exit\n\n");

	char i;
	std::cin >> i;

	switch(i)
	{
		case 'a': driverType = video::EDT_DIRECT3D9;break;
		case 'b': driverType = video::EDT_DIRECT3D8;break;
		case 'c': driverType = video::EDT_OPENGL;   break;
		case 'd': driverType = video::EDT_SOFTWARE; break;
		case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
		case 'f': driverType = video::EDT_NULL;     break;
		default: return 1;
	}	

	// create device and exit if creation failed

	IrrlichtDevice * device = createDevice(driverType, core::dimension2d<s32>(640, 480));

	if (device == 0)
		return 1; // could not create selected driver.

	/* The creation was successful, now we set the event receiver and
		store pointers to the driver and to the gui environment. */

	device->setWindowCaption(L"Irrlicht Engine - User Interface Demo");

	video::IVideoDriver* driver = device->getVideoDriver();
	IGUIEnvironment* env = device->getGUIEnvironment();

	/*
	To make the font a little bit nicer, we load an external font
	and set it as the new default font in the skin.
	To keep the standard font for tool tip text, we set it to
	the built-in font.
	*/

	IGUISkin* skin = env->getSkin();
	IGUIFont* font = env->getFont("../../media/fonthaettenschweiler.bmp");
	if (font)
		skin->setFont(font);

	skin->setFont(env->getBuiltInFont(), EGDF_TOOLTIP);

	/*
	We add three buttons. The first one closes the engine. The second
	creates a window and the third opens a file open dialog. The third
	parameter is the id of the button, with which we can easily identify
	the button in the event receiver.
	*/	

	env->addButton(rect<s32>(10,240,110,240 + 32), 0, GUI_ID_QUIT_BUTTON,
			L"Quit", L"Exits Program");
	env->addButton(rect<s32>(10,280,110,280 + 32), 0, GUI_ID_NEW_WINDOW_BUTTON,
			L"New Window", L"Launches a new Window");
	env->addButton(rect<s32>(10,320,110,320 + 32), 0, GUI_ID_FILE_OPEN_BUTTON,
			L"File Open", L"Opens a file");

	/*
	Now, we add a static text and a scrollbar, which modifies the
	transparency of all gui elements. We set the maximum value of
	the scrollbar to 255, because that's the maximal value for
	a color value.
	Then we create an other static text and a list box.
	*/

	env->addStaticText(L"Transparent Control:", rect<s32>(150,20,350,40), true);
	IGUIScrollBar* scrollbar = env->addScrollBar(true,
			rect<s32>(150, 45, 350, 60), 0, GUI_ID_TRANSPARENCY_SCROLL_BAR);
	scrollbar->setMax(255);

	// set scrollbar position to alpha value of an arbitrary element
	scrollbar->setPos(env->getSkin()->getColor(EGDC_WINDOW).getAlpha());

	env->addStaticText(L"Logging ListBox:", rect<s32>(50,110,250,130), true);
	IGUIListBox * listbox = env->addListBox(rect<s32>(50, 140, 250, 210));
	env->addEditBox(L"Editable Text", rect<s32>(350, 80, 550, 100));

	// Store the appropriate data in a context structure.
	SAppContext context;
	context.device = device;
	context.counter = 0;
	context.listbox = listbox;

	// Then create the event receiver, giving it that context structure.
	MyEventReceiver receiver(context);

	// And tell the device to use our custom event receiver.
	device->setEventReceiver(&receiver);


	/*
	And at last, we create a nice Irrlicht Engine logo in the top left corner. 
	*/
	env->addImage(driver->getTexture("../../media/irrlichtlogo2.png"),
			position2d<int>(10,10));


	/*
	That's all, we only have to draw everything.
	*/

	while(device->run() && driver)
	if (device->isWindowActive())
	{
		driver->beginScene(true, true, SColor(0,200,200,200));

		env->drawAll();
	
		driver->endScene();
	}

	device->drop();

	return 0;
}

/*
**/
Camel
Posts: 5
Joined: Sun Jul 12, 2009 10:28 am

Re: Tutorial 5 User Interface questions

Post by Camel »

namespace wrote:

Code: Select all

#include <irrlicht.h>
#include <iostream>

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif

// Declare a structure to hold some context for the event receiver so that it
// has it available inside its OnEvent() method.
struct SAppContext
{
	IrrlichtDevice *device;
	s32				counter;
	IGUIListBox*	listbox;
};
Ok, whats struct, is it like a class? These appear to be pointers, I'll assume for instance that listbox when called calls the IGUIListBox.
s32 is type of variable, from what the definition said, so whats counter, a variable?
A struct is like a simple class. Its just a container for a group of variables.

Code: Select all

{
	GUI_ID_QUIT_BUTTON = 101,
	GUI_ID_NEW_WINDOW_BUTTON,
	GUI_ID_FILE_OPEN_BUTTON,
	GUI_ID_TRANSPARENCY_SCROLL_BAR
};
This has always been a little odd for me, I get it, they all get an increasing value by one assigned to them, I assume there standard long or short variables. I'm not quite sure what you can do with the number 102 assigned to new window button, but maybe I'll catch it this time. (I've been through all this code in detail at least once.) (I've just never seen a useful example)
The number is like an ID number for that specific button. In your event receiver you check which button was clicked (or whatever) by looking at the ID number of that button.

blarg, I don't know enough about Irrlicht to answer anything else with certainty. but at least I've tried to help. :)
namespace
Posts: 7
Joined: Thu Jul 09, 2009 6:30 pm

Post by namespace »

No, that's great thanks :) There's just a few of these things I need to get straight and then I'll be able to understand most of the tutorials. I've already looked ahead and chose this one because it covered most of my questions.

Can anyone help me with the rest?
CuteAlien
Admin
Posts: 9721
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Tutorial 5 User Interface questions

Post by CuteAlien »

namespace wrote: s32 is type of variable, from what the definition said, so whats counter, a variable?
Yes

About the enums: Those replace numbers and make it easier not to accidentally use the same number several times. This is to help yourself - if you write code then you will 3 week later have forgotten what the number 101 is for while a name like GUI_ID_QUIT_BUTTON will be obvious. Having numbers in code is usually called magic-numbers because you have no idea what they are doing (so it is meant to be bad usage of numbers). So always use enums, consts or defines instead (preferably in that order - use enums if you can, consts otherwise and defines as a last resort).

Next questions are basically stuff you should learn from a c++ tutorial.
namespace wrote: Ok, so you make a new class called MyEventReceiver, and go to define public variable IEventReciever?
No you derive class MyEventReceiver from class IEventReciever without further restricting access to the baseclass (public).
namespace wrote:You enter public again?
Read up on access control in c++.
namespace wrote: and then use the class you just created, in the class your defining? and then you assign context to point to the structure SAppContext you just created?
Then two more contexts?
Read up on constructors and destructors.
namespace wrote: You then declare a variable OnEvent in which you define a constant? and have the word event, I'm not sure how event is related to the contstant, but the constant you defined is an irr class dealing with events, so event after the irr event variable means?
OnEvent is a memberfunction not a variable. event is of type const SEvent&.

ok... I'm finished with my breakfast and have to work now. Please stop asking all the basic questions about c++ in the forum. We help once in a while - but what you really should do is work your way through some c++ tutorial/book first (there are free books online!). That will answer all your questions and is a lot less exhausting for everyone.
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
Post Reply