Menu-Messages wirh Irrlicht

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
TomTim
Posts: 72
Joined: Mon Aug 16, 2010 5:32 pm
Location: NRW, Germany

Menu-Messages wirh Irrlicht

Post by TomTim »

I've attached an menu on the window's edge. Now I'm going to write an own message receiver, but I got a problem with OnEvent: Every time I select an item from an submenu of my menu, the caller's ID is equal with my menu's ID. I can't check which subentry was selected, only that my menu was clicked.

Any ideas how to avoid the bug?
Dareltibus
Posts: 115
Joined: Mon May 17, 2010 7:42 am

Post by Dareltibus »

it is not a bug. when you add an item to the guienv you have also to select an arbitrary ID to give.


The defaul ID is "-1" and mean "no id choosen"
In this example the ID is 101.

Code: Select all


guienv->addGUIElement("myButton", IGUIButton(core::rect< s32> (0,0,200,50), 0, 101, wchar_t "mybutton", wchar_t "clickhere")  )

now when you try to get the caller id you get 101 only if the button was clicked.

[/code]
TomTim
Posts: 72
Joined: Mon Aug 16, 2010 5:32 pm
Location: NRW, Germany

Post by TomTim »

Dareltibus wrote:it is not a bug. when you add an item to the guienv you have also to select an arbitrary ID to give.


The defaul ID is "-1" and mean "no id choosen"
In this example the ID is 101.

Code: Select all


guienv->addGUIElement("myButton", IGUIButton(core::rect< s32> (0,0,200,50), 0, 101, wchar_t "mybutton", wchar_t "clickhere")  )

now when you try to get the caller id you get 101 only if the button was clicked.

[/code]
I already knew this. The problem: I don't use a button, but items in a context menu. And I gave them my own IDs, predefined constants.
Dareltibus
Posts: 115
Joined: Mon May 17, 2010 7:42 am

Post by Dareltibus »

ok i will try to use menus and check if i get the bug. some code will be helpfull.
TomTim
Posts: 72
Joined: Mon Aug 16, 2010 5:32 pm
Location: NRW, Germany

Post by TomTim »

Dareltibus wrote:ok i will try to use menus and check if i get the bug. some code will be helpfull.
Here's the source code:

Code: Select all

bool IG3Receiver::OnEvent(const irr::SEvent&EventInfo)
{
	//Check what event type has happend.
	switch(EventInfo.EventType)
	{
	case irr::EET_GUI_EVENT:
		{
			//Fine, the GUI has got a message.
			switch(EventInfo.GUIEvent.EventType)
			{
			case irr::gui::EGET_MENU_ITEM_SELECTED:
				//Better, a menu item was selected. Now
				//get the caller's ID ...
				irr::s32 ID=EventInfo.GUIEvent.Caller->getID();

				//... but unfourtunaly, it's just the ID of the 
				//submenu, not the actual caller's ID.
				switch(ID)
				{
					//Check what shall happen. Though, it does
					//not work.
				case ID_MAINMENU_FILE_NEW:
					return OnNew();
				case ID_MAINMENU_FILE_ADDFILE:
					return OnAddFile();
				case ID_MAINMENU_FILE_ADDDIRECTORY:
					return OnAddDirectory();
				case ID_MAINMENU_FILE_ADDPAK:
					return OnAddPAK();
				case ID_MAINMENU_FILE_CLOSE:
					return OnClose();
				}
			}
		}
	}
	return false;
}
The On-functions don't matter, so I saved them from posting here.
Dareltibus
Posts: 115
Joined: Mon May 17, 2010 7:42 am

Post by Dareltibus »

you are right. id of the context menu's items is not catched by the event receiver.

the only way i think you can do that until that issue will be solved is check the selected item in you menu this way.


IGUIContextMenu *menu
menu->getSelectedItem
TomTim
Posts: 72
Joined: Mon Aug 16, 2010 5:32 pm
Location: NRW, Germany

Post by TomTim »

Then, I think, I've found a bug which should be fixed in the next version of Irrlicht. Thanks anyway.
project23
Posts: 4
Joined: Mon Apr 12, 2010 8:28 pm

Post by project23 »

It just so happens that I spent last night ripping out a skeleton framework from Tutorial 9:Mesh Viewer.
The code below has a working menu bar and event receiver and really nothing else.

Of interest to your problem here, check out the OnMenuItemSelected() function. It demonstrates how to do what you are wanting to do.

Code: Select all

#include <irrlicht.h>		//for graphics fun
#include "driverChoice.h"	//runtime select video drivers
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
//#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") //disrupts driverChoiceConsole when enabled
#endif
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
scene::ICameraSceneNode* Camera[2] = {0,0};
IrrlichtDevice *Device = 0;
core::stringw MessageText = "MessageText";
core::stringw Caption = "CaptionText";

enum {
	GUI_ID_DIALOG_ROOT_WINDOW  = 0x10000,
	GUI_ID_POSITION_TEXT,
	GUI_ID_ABOUT,
	GUI_ID_WINDOW,
	GUI_ID_QUIT,
};
void setActiveCamera(scene::ICameraSceneNode* newActive)
{
        if (0 == Device)
                return;

        scene::ICameraSceneNode * active = Device->getSceneManager()->getActiveCamera();
        active->setInputReceiverEnabled(false);

        newActive->setInputReceiverEnabled(true);
        Device->getSceneManager()->setActiveCamera(newActive);
}
void showAboutText() // create modal message box with the text
{
	Device->getGUIEnvironment()->addMessageBox( Caption.c_str(), MessageText.c_str() );
}
void showWindow() //create a window for the fun of it
{
	Device->getGUIEnvironment()->addWindow( core::rect<s32>(300,45,800,480),false,L"Character Window",0,GUI_ID_DIALOG_ROOT_WINDOW);
}
class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(const SEvent& event)
	{
		if (event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown == false)
		{
			if ( OnKeyUp(event.KeyInput.Key) ) return true;
		}
		if (event.EventType == EET_GUI_EVENT)
		{
			s32 id = event.GUIEvent.Caller->getID();
			IGUIEnvironment* env = Device->getGUIEnvironment();
			switch(event.GUIEvent.EventType)
			{
				case EGET_MENU_ITEM_SELECTED: // a menu item was clicked
				 OnMenuItemSelected( (IGUIContextMenu*)event.GUIEvent.Caller );
				 break;
				default:
				 break;
			}
		}
		return false;
	}
bool OnKeyUp(irr::EKEY_CODE keyCode)
{
	if (keyCode == irr::KEY_ESCAPE)
	{
		if (Device)
		{
			scene::ICameraSceneNode * camera = Device->getSceneManager()->getActiveCamera();
			if (camera)
			{
				camera->setInputReceiverEnabled( !camera->isInputReceiverEnabled() );
			}
			return true;
		}
	}
return false;
}
void OnMenuItemSelected( IGUIContextMenu* menu )
{
s32 id = menu->getItemCommandId(menu->getSelectedItem());
IGUIEnvironment* env = Device->getGUIEnvironment();
switch(id)
{
	case GUI_ID_QUIT:
		Device->closeDevice();
		break;
	case GUI_ID_ABOUT:
		showAboutText();
		break;
	case GUI_ID_WINDOW:
		showWindow();
		break;
}
}
};
int main()
{
	//irrlicht event receiver
	MyEventReceiver receiver;

	//ask the user for the video driver to use 
	video::E_DRIVER_TYPE driverType=driverChoiceConsole();
        if (driverType==video::EDT_COUNT) return 1;

	//irrlicht device
	Device = createDevice(driverType, dimension2d<u32>(800, 600), 16, false, false, false, &receiver);
        if (!Device) return 1;

	//irrlicht services
	IVideoDriver*		driver	= Device->getVideoDriver();
        ISceneManager*		smgr	= Device->getSceneManager();
        IGUIEnvironment*	env		= Device->getGUIEnvironment();

	//make our players camera
	smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));

	//our top menu bar
	IGUIContextMenu* menu = env->addMenu();
        menu->addItem(L"File", -1, true, true);
        menu->addItem(L"Help", -1, true, true);
	IGUIContextMenu* submenu;
        submenu = menu->getSubMenu(0);
        submenu->addSeparator();
        submenu->addItem(L"Quit", GUI_ID_QUIT);
	submenu = menu->getSubMenu(1);
	submenu->addItem(L"TestWindow", GUI_ID_WINDOW);
        submenu->addItem(L"About", GUI_ID_ABOUT);

	//anchor our fpstext on the screen (we update it from inside the main loop)
	IGUIStaticText* fpstext = env->addStaticText(L"", core::rect<s32>(400,4,570,23), true, false, menu);

	// set window caption
        Caption += " - [";
        Caption += driver->getName();
        Caption += "]";
        Device->setWindowCaption(Caption.c_str());

	// add our camera scene nodes
        Camera[0] = smgr->addCameraSceneNodeMaya();
        Camera[0]->setFarValue(20000.f);
        // Maya cameras reposition themselves relative to their target, so target the location
        // where the mesh scene node is placed.
        Camera[0]->setTarget(core::vector3df(0,30,0));
	Camera[1] = smgr->addCameraSceneNodeFPS();
        Camera[1]->setFarValue(20000.f);
        Camera[1]->setPosition(core::vector3df(0,0,-70));
        Camera[1]->setTarget(core::vector3df(0,30,0));
	setActiveCamera(Camera[0]);

		while(Device->run()) //our main loop
		{
		driver->beginScene(true, true, SColor(255,100,101,140));
		smgr->drawAll();
		env->drawAll();
		driver->endScene();
		int fps = driver->getFPS();
		int lastFPS = -1;
		if (lastFPS != fps) 
		{
			core::stringw tmp(L"[");
			tmp += driver->getName();
			tmp += L"] fps: ";
			tmp += fps;
			fpstext->setText(tmp.c_str());
			lastFPS = fps;
		}
		Device->yield();
	}
	Device->drop();
	return 0;
}
Post Reply