Complete event handler

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.
RoboWarrior
Posts: 4
Joined: Fri Sep 03, 2010 8:31 am

Complete event handler

Post by RoboWarrior »

Is there an event handler that works for keyboard, mouse and gui event like this?

IGUIButton* b=blabla;
if(bpressed) do this;
if(key_A) do this;
if(leftmouse) do this;
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

Yes there is, put some effort into it and search yourself, do your 'homework' first. :wink:
Working on game: Marrbles (Currently stopped).
RoboWarrior
Posts: 4
Joined: Fri Sep 03, 2010 8:31 am

Post by RoboWarrior »

could someone help me, please?
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Post by Seven »

Code: Select all

#pragma once

#include "IrrLicht.h"

class IrrEventHandler : public IEventReceiver
{
public:

	// Enumeration for UP, DOWN, PRESSED and RELEASED key states. Also used for mouse button states.
	enum keyStatesENUM {UP, DOWN, PRESSED, RELEASED};
	
	// Keyboard key states.
	keyStatesENUM keyState[KEY_KEY_CODES_COUNT];

	// Mouse data.
	struct mouseData
	{
		int X;
		int Y;
		bool LButtonDown;
		bool RButtonDown;
		bool MButtonDown;
		float Wheel; 
		float WheelDelta;
	};

	struct mouseData m_Mouse;
	int MouseX()			{ return m_Mouse.X;				};
	int MouseY()			{ return m_Mouse.Y;				};
	float MouseWheel()		{ return m_Mouse.Wheel;			};
	float MouseWheelDelta()	{ return m_Mouse.WheelDelta;	};

	IrrEventHandler(void)			
	{
		for (int i = 0; i < KEY_KEY_CODES_COUNT; i++) keyState[i] = RELEASED;
		m_Mouse.X = 0;
		m_Mouse.Y = 0;
		m_Mouse.Wheel = 0;
		m_Mouse.WheelDelta = 0;
		m_Mouse.LButtonDown = false;
		m_Mouse.RButtonDown = false;
		m_Mouse.MButtonDown = false;
	};

	virtual ~IrrEventHandler(void)	{};

	// keyboard events
	virtual bool OnKeyInputEvent(const SEvent& e)	{	return false;														};
	virtual bool IsKeyPressed(char keycode)			{	return (keyState[keycode] == PRESSED);								};
	virtual bool IsKeyDown(char keycode)			{	return (keyState[keycode] == DOWN || keyState[keycode] == PRESSED); };
	virtual bool IsKeyUp(char keycode)				{	return (keyState[keycode] == UP || keyState[keycode] == RELEASED);	};
	virtual bool IsKeyReleased(char keycode)		{	return (keyState[keycode] == RELEASED);								};

	// guievents
	virtual bool OnButtonClicked(const SEvent& e)			{	return false;	};
	virtual bool OnScrollBarChanged(const SEvent& e)		{	return false;	};
	virtual bool OnCheckBoxChanged(const SEvent& e)			{	return false;	};
	virtual bool OnListBoxChanged(const SEvent& e)			{	return false;	};
	virtual bool OnListBoxSelectedAgain(const SEvent& e)	{	return false;	};
	virtual bool OnFileSelected(const SEvent& e)			{	return false;	};
	virtual bool OnMessageBoxYes(const SEvent& e)			{	return false;	};
	virtual bool OnMessageBoxNo(const SEvent& e)			{	return false;	};
	virtual bool OnMessageBoxOk(const SEvent& e)			{	return false;	};
	virtual bool OnMessageBoxCancel(const SEvent& e)		{	return false;	};
	virtual bool OnEditBoxEnter(const SEvent& e)			{	return false;	};
	virtual bool OnTabChanged(const SEvent& e)				{	return false;	};
	virtual bool OnComboBoxChanged(const SEvent& e)			{	return false;	};
	virtual bool OnSpinBoxChanged(const SEvent& e)			{	return false;	};

	// mouse events
	virtual bool OnLMousePressedDown(const SEvent& e)		{	return false;	};
	virtual bool OnRMousePressedDown(const SEvent& e)		{	return false;	};
	virtual bool OnMMousePressedDown(const SEvent& e)		{	return false;	};
	virtual bool OnLMouseLeftUp(const SEvent& e)			{	return false;	};
	virtual bool OnRMouseLeftUp(const SEvent& e)			{	return false;	};
	virtual bool OnMMouseLeftUp(const SEvent& e)			{	return false;	};
	virtual bool OnMouseMoved(const SEvent& e)				{	return false;	};
	virtual bool OnMouseWheel(const SEvent& e)				{	return false;	};

	// user events
	virtual bool OnUserEvent(const SEvent& e)				{	return false;	};

	virtual bool OnEvent(const SEvent& e)
	{

		switch (e.EventType)
		{
			case EET_KEY_INPUT_EVENT : 
				{
					if (e.KeyInput.PressedDown == true)
					{
						if (keyState[e.KeyInput.Key] != DOWN) 
							keyState[e.KeyInput.Key] = PRESSED; 
						else keyState[e.KeyInput.Key] = DOWN; 
					}
					else
					if (keyState[e.KeyInput.Key] != UP)	
						keyState[e.KeyInput.Key] = RELEASED; 

					if (e.KeyInput.PressedDown == true) return OnKeyInputEvent(e); 
				} 	break;

			case EET_GUI_EVENT :
				{
					switch (e.GUIEvent.EventType)
					{
						case EGET_BUTTON_CLICKED			: return OnButtonClicked(e);
						case EGET_SCROLL_BAR_CHANGED		: return OnScrollBarChanged(e);
						case EGET_CHECKBOX_CHANGED			: return OnCheckBoxChanged(e);
						case EGET_LISTBOX_CHANGED			: return OnListBoxChanged(e);
						case EGET_LISTBOX_SELECTED_AGAIN	: return OnListBoxSelectedAgain(e);
						case EGET_FILE_SELECTED				: return OnFileSelected(e);
						case EGET_MESSAGEBOX_YES			: return OnMessageBoxYes(e);
						case EGET_MESSAGEBOX_NO				: return OnMessageBoxNo(e);
						case EGET_MESSAGEBOX_OK				: return OnMessageBoxOk(e);
						case EGET_MESSAGEBOX_CANCEL			: return OnMessageBoxCancel(e);
						case EGET_EDITBOX_ENTER				: return OnEditBoxEnter(e);
						case EGET_TAB_CHANGED				: return OnTabChanged(e);
						case EGET_COMBO_BOX_CHANGED			: return OnComboBoxChanged(e);
						case EGET_SPINBOX_CHANGED			: return OnSpinBoxChanged(e);
						default : return false;
					}
				} break; 

			case EET_MOUSE_INPUT_EVENT :
				{
					m_Mouse.X = e.MouseInput.X;
					m_Mouse.Y = e.MouseInput.Y;

					switch (e.MouseInput.Event)
					{
						case EMIE_LMOUSE_PRESSED_DOWN	:	m_Mouse.LButtonDown = true; return OnLMousePressedDown(e);
						case EMIE_RMOUSE_PRESSED_DOWN	:	m_Mouse.RButtonDown = true; return OnRMousePressedDown(e);
						case EMIE_MMOUSE_PRESSED_DOWN	:	m_Mouse.MButtonDown = true; return OnMMousePressedDown(e);
						case EMIE_LMOUSE_LEFT_UP		:	m_Mouse.LButtonDown = false; return OnLMouseLeftUp(e);
						case EMIE_RMOUSE_LEFT_UP		:	m_Mouse.RButtonDown = false; return OnRMouseLeftUp(e);
						case EMIE_MMOUSE_LEFT_UP		:	m_Mouse.MButtonDown = false; return OnMMouseLeftUp(e);
						case EMIE_MOUSE_MOVED			:	return OnMouseMoved(e);
						case EMIE_MOUSE_WHEEL			:	
							{
								m_Mouse.WheelDelta = m_Mouse.Wheel - e.MouseInput.Wheel; 
								m_Mouse.Wheel += e.MouseInput.Wheel;
								return OnMouseWheel(e);
							}
						default : return false;
					}
				} break;

			case EET_USER_EVENT : 
				{
					return OnUserEvent(e);
					default : return false;
				} break;
		}
		return false;
	}
};
jurgel
Posts: 7
Joined: Sat Oct 02, 2010 2:11 pm

Post by jurgel »

Seven wrote:

Code: Select all

#pragma once

#include "IrrLicht.h"

class IrrEventHandler : public IEventReceiver
{
public:

	// Enumeration for UP, DOWN, PRESSED and RELEASED key states. Also used for mouse button states.
	enum keyStatesENUM {UP, DOWN, PRESSED, RELEASED};
	
	// Keyboard key states.
	keyStatesENUM keyState[KEY_KEY_CODES_COUNT];

	// Mouse data.
	struct mouseData
	{
		int X;
		int Y;
		bool LButtonDown;
		bool RButtonDown;
		bool MButtonDown;
		float Wheel; 
		float WheelDelta;
	};

	struct mouseData m_Mouse;
	int MouseX()			{ return m_Mouse.X;				};
	int MouseY()			{ return m_Mouse.Y;				};
	float MouseWheel()		{ return m_Mouse.Wheel;			};
	float MouseWheelDelta()	{ return m_Mouse.WheelDelta;	};

	IrrEventHandler(void)			
	{
		for (int i = 0; i < KEY_KEY_CODES_COUNT; i++) keyState[i] = RELEASED;
		m_Mouse.X = 0;
		m_Mouse.Y = 0;
		m_Mouse.Wheel = 0;
		m_Mouse.WheelDelta = 0;
		m_Mouse.LButtonDown = false;
		m_Mouse.RButtonDown = false;
		m_Mouse.MButtonDown = false;
	};

	virtual ~IrrEventHandler(void)	{};

	// keyboard events
	virtual bool OnKeyInputEvent(const SEvent& e)	{	return false;														};
	virtual bool IsKeyPressed(char keycode)			{	return (keyState[keycode] == PRESSED);								};
	virtual bool IsKeyDown(char keycode)			{	return (keyState[keycode] == DOWN || keyState[keycode] == PRESSED); };
	virtual bool IsKeyUp(char keycode)				{	return (keyState[keycode] == UP || keyState[keycode] == RELEASED);	};
	virtual bool IsKeyReleased(char keycode)		{	return (keyState[keycode] == RELEASED);								};

	// guievents
	virtual bool OnButtonClicked(const SEvent& e)			{	return false;	};
	virtual bool OnScrollBarChanged(const SEvent& e)		{	return false;	};
	virtual bool OnCheckBoxChanged(const SEvent& e)			{	return false;	};
	virtual bool OnListBoxChanged(const SEvent& e)			{	return false;	};
	virtual bool OnListBoxSelectedAgain(const SEvent& e)	{	return false;	};
	virtual bool OnFileSelected(const SEvent& e)			{	return false;	};
	virtual bool OnMessageBoxYes(const SEvent& e)			{	return false;	};
	virtual bool OnMessageBoxNo(const SEvent& e)			{	return false;	};
	virtual bool OnMessageBoxOk(const SEvent& e)			{	return false;	};
	virtual bool OnMessageBoxCancel(const SEvent& e)		{	return false;	};
	virtual bool OnEditBoxEnter(const SEvent& e)			{	return false;	};
	virtual bool OnTabChanged(const SEvent& e)				{	return false;	};
	virtual bool OnComboBoxChanged(const SEvent& e)			{	return false;	};
	virtual bool OnSpinBoxChanged(const SEvent& e)			{	return false;	};

	// mouse events
	virtual bool OnLMousePressedDown(const SEvent& e)		{	return false;	};
	virtual bool OnRMousePressedDown(const SEvent& e)		{	return false;	};
	virtual bool OnMMousePressedDown(const SEvent& e)		{	return false;	};
	virtual bool OnLMouseLeftUp(const SEvent& e)			{	return false;	};
	virtual bool OnRMouseLeftUp(const SEvent& e)			{	return false;	};
	virtual bool OnMMouseLeftUp(const SEvent& e)			{	return false;	};
	virtual bool OnMouseMoved(const SEvent& e)				{	return false;	};
	virtual bool OnMouseWheel(const SEvent& e)				{	return false;	};

	// user events
	virtual bool OnUserEvent(const SEvent& e)				{	return false;	};

	virtual bool OnEvent(const SEvent& e)
	{

		switch (e.EventType)
		{
			case EET_KEY_INPUT_EVENT : 
				{
					if (e.KeyInput.PressedDown == true)
					{
						if (keyState[e.KeyInput.Key] != DOWN) 
							keyState[e.KeyInput.Key] = PRESSED; 
						else keyState[e.KeyInput.Key] = DOWN; 
					}
					else
					if (keyState[e.KeyInput.Key] != UP)	
						keyState[e.KeyInput.Key] = RELEASED; 

					if (e.KeyInput.PressedDown == true) return OnKeyInputEvent(e); 
				} 	break;

			case EET_GUI_EVENT :
				{
					switch (e.GUIEvent.EventType)
					{
						case EGET_BUTTON_CLICKED			: return OnButtonClicked(e);
						case EGET_SCROLL_BAR_CHANGED		: return OnScrollBarChanged(e);
						case EGET_CHECKBOX_CHANGED			: return OnCheckBoxChanged(e);
						case EGET_LISTBOX_CHANGED			: return OnListBoxChanged(e);
						case EGET_LISTBOX_SELECTED_AGAIN	: return OnListBoxSelectedAgain(e);
						case EGET_FILE_SELECTED				: return OnFileSelected(e);
						case EGET_MESSAGEBOX_YES			: return OnMessageBoxYes(e);
						case EGET_MESSAGEBOX_NO				: return OnMessageBoxNo(e);
						case EGET_MESSAGEBOX_OK				: return OnMessageBoxOk(e);
						case EGET_MESSAGEBOX_CANCEL			: return OnMessageBoxCancel(e);
						case EGET_EDITBOX_ENTER				: return OnEditBoxEnter(e);
						case EGET_TAB_CHANGED				: return OnTabChanged(e);
						case EGET_COMBO_BOX_CHANGED			: return OnComboBoxChanged(e);
						case EGET_SPINBOX_CHANGED			: return OnSpinBoxChanged(e);
						default : return false;
					}
				} break; 

			case EET_MOUSE_INPUT_EVENT :
				{
					m_Mouse.X = e.MouseInput.X;
					m_Mouse.Y = e.MouseInput.Y;

					switch (e.MouseInput.Event)
					{
						case EMIE_LMOUSE_PRESSED_DOWN	:	m_Mouse.LButtonDown = true; return OnLMousePressedDown(e);
						case EMIE_RMOUSE_PRESSED_DOWN	:	m_Mouse.RButtonDown = true; return OnRMousePressedDown(e);
						case EMIE_MMOUSE_PRESSED_DOWN	:	m_Mouse.MButtonDown = true; return OnMMousePressedDown(e);
						case EMIE_LMOUSE_LEFT_UP		:	m_Mouse.LButtonDown = false; return OnLMouseLeftUp(e);
						case EMIE_RMOUSE_LEFT_UP		:	m_Mouse.RButtonDown = false; return OnRMouseLeftUp(e);
						case EMIE_MMOUSE_LEFT_UP		:	m_Mouse.MButtonDown = false; return OnMMouseLeftUp(e);
						case EMIE_MOUSE_MOVED			:	return OnMouseMoved(e);
						case EMIE_MOUSE_WHEEL			:	
							{
								m_Mouse.WheelDelta = m_Mouse.Wheel - e.MouseInput.Wheel; 
								m_Mouse.Wheel += e.MouseInput.Wheel;
								return OnMouseWheel(e);
							}
						default : return false;
					}
				} break;

			case EET_USER_EVENT : 
				{
					return OnUserEvent(e);
					default : return false;
				} break;
		}
		return false;
	}
};
wow :o :o
that's a complete code,
I'll use it, it's ok?

very thanks indeed. :D :D
SARIN
Posts: 139
Joined: Fri Oct 29, 2004 3:53 am

Post by SARIN »

yeah, is it cool if we use this? i assume you wouldnt have posted if we couldnt
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Post by Seven »

no problem with you using it. I am sure that I had lots of help with it way back when, so dont think that it is just mine. the forums have code like this pasted throughout and it is normal to paste together lots of different posts to get a single item.

I did want to let you know though. we use this as the base class for lots of classes. for example...

class IrrApp : public IrrEventHandler ( this allows us to set our application class as the Irrlicht eventhandler. inside the app onEvent() we route message to whichhever class we want. example : the Irrlevel class is derived from IrrEventHandelr also, as are all of the object classes. it then looks like this


irrlicht sends event to app class. app class routces message to active level. active level routes mesages to objects that have registered to receive messages. so for example, a 'seeing eye spell' object, when created, might put a gui element on the main screen and then regirster to receive messages. when the user selects that icon, the message goes to the app, to the level, to the spell object who then 'searches' around the player to detect hidden doors. if the door is found, the icon 'eye' opens and a small sound is played. if no door is found, the eye stays closed.

if you would like ot see small demo let me know and i will put something together when i get back in the states.

Seven
jurgel
Posts: 7
Joined: Sat Oct 02, 2010 2:11 pm

Post by jurgel »

hey Seven,
I'm test your code,
and I think there is a bug,

what different between isKeyDown() and IsKeyPressed() ??
isKeyPressed give the same result as isKeyDown,
it should be doing the action 1x not like as isKeyDown that doing the action every frame,

I test your code using this:

if (mReceiver->IsKeyPressed(KEY_UP))
printf("keyPressed");

when I press KEY_UP, the "keyPressed" text show a lot,
it should be 1, isn't it?
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Post by Seven »

hmmmm......... it seems that the keystate is never set to DOWN.
Maybe this is better code.

Code: Select all

case EET_KEY_INPUT_EVENT : 
            { 
               if (e.KeyInput.PressedDown == true) 
               { 
                  // if this is the first scan then set to PRESSED
                  if (keyState[e.KeyInput.Key] != DOWN) 
                     keyState[e.KeyInput.Key] = PRESSED; 

                  // if this is the 2nd + scan then set to DOWN
                  else if (keyState[e.KeyInput.Key] == PRESSED) 
                     keyState[e.KeyInput.Key] = DOWN; 
               } 
               else 
               {
                 // if this is the first scan then set to RELEASED
                 if (keyState[e.KeyInput.Key] != UP)    
                     keyState[e.KeyInput.Key] = RELEASED; 
                 else
                  // if this is the 2nd + scan then set to UP
                 if (keyState[e.KeyInput.Key] == RELEASED)    
                     keyState[e.KeyInput.Key] = UP; 
                }

               // call the overridden handler
               if (e.KeyInput.PressedDown == true) 
                  return OnKeyInputEvent(e);
 
            }    break; 
I did not test the changes, but you could let me know how it works.

Seven
jurgel
Posts: 7
Joined: Sat Oct 02, 2010 2:11 pm

Post by jurgel »

Seven wrote:hmmmm......... it seems that the keystate is never set to DOWN.
Maybe this is better code.

Seven
the problem isn't the keystate is never set to DOWN, but keystate is never set to PRESSED,

I've test your code and result the same as before.

the result of function isKeyPress() is same as isKeyDown()
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Post by Seven »

hmm. I dont have a compiler here. when I return to the states, i will check it out further.
jurgel
Posts: 7
Joined: Sat Oct 02, 2010 2:11 pm

Post by jurgel »

lol, :lol:

It wasting my time if my waiting for you back to your states,
it must be a looong time,

ok thanks :D

I'll check it by myself,

don't forget to tell me if you already back, ok :D
even it's several years later , lol :lol: :lol:
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Post by Bate »

You don't need a compiler for that :)

Code: Select all

if (keyState[e.KeyInput.Key] != DOWN) // true if PRESSED
  keyState[e.KeyInput.Key] = PRESSED;

else if (keyState[e.KeyInput.Key] == PRESSED) // so this is never executed
  keyState[e.KeyInput.Key] = DOWN;
That's probably what you want:

Code: Select all

if (keyState[e.KeyInput.Key] == PRESSED)
  keyState[e.KeyInput.Key] = DOWN;

else if (keyState[e.KeyInput.Key] != DOWN)
  keyState[e.KeyInput.Key] = PRESSED;


Never take advice from someone who likes to give advice, so take my advice and don't take it.
jurgel
Posts: 7
Joined: Sat Oct 02, 2010 2:11 pm

Post by jurgel »

Bate wrote:You don't need a compiler for that :)

Code: Select all

if (keyState[e.KeyInput.Key] != DOWN) // true if PRESSED
  keyState[e.KeyInput.Key] = PRESSED;

else if (keyState[e.KeyInput.Key] == PRESSED) // so this is never executed
  keyState[e.KeyInput.Key] = DOWN;
That's probably what you want:

Code: Select all

if (keyState[e.KeyInput.Key] == PRESSED)
  keyState[e.KeyInput.Key] = DOWN;

else if (keyState[e.KeyInput.Key] != DOWN)
  keyState[e.KeyInput.Key] = PRESSED;


I'm give up,
the code looks fine and should run perfectly
but why the result always wrong

I test with this

Code: Select all

if (mReceiver->IsKeyDown(KEY_UP))
            printf("Down");
if (mReceiver->IsKeyPressed(KEY_UP))
            printf("Pressed");
the result :
DownPressedDownPressedDownPressed........(very long)

why ??
jurgel
Posts: 7
Joined: Sat Oct 02, 2010 2:11 pm

Post by jurgel »

ahh, finally I got the answer
I'm mix your code with "MastEventReceiver.cpp" from other thread,
and it's working perfectly now,

if someone want my code,
you can pm me :D

or should I put in this thread?
Post Reply