Bug? Focused window ruins EGET_MENU_ITEM event?
Bug? Focused window ruins EGET_MENU_ITEM event?
I ran across something strange while playing around with a Table and a ContextMenu. Strange thing is that EGET_MENU_ITEM works very well, until i select something from the Table, then i stop getting EGET_MENU_ITEM events. Also, are EGET_MENU_ITEM not working with sub-menus?
Last edited by Virror on Tue May 10, 2011 9:43 am, edited 1 time in total.
I don't know about such a bug so far.
It would help if you could post code which I can use to reproduce the problem (it's easier for you to do this, as you can start with a reproducible bug, while I would have to go on a wild hunt writing examples until I might or might not run in a problem and often people here see the problem anyway as soon as they see the code).
It would help if you could post code which I can use to reproduce the problem (it's easier for you to do this, as you can start with a reproducible bug, while I would have to go on a wild hunt writing examples until I might or might not run in a problem and often people here see the problem anyway as soon as they see the code).
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
Hmm, realized that it happens when the window the table is in has focus, not only when an item is selected. Currently i do this:
Maybe it cant be done that way when i have focus on a window? Wrong event caller?
And, why cant i get event on a submenu? Is it not possible?
Edit code for Gui creation:
Code: Select all
if(event.GUIEvent.Caller == contextMenu)
{
if(event.GUIEvent.EventType == EGET_MENU_ITEM_SELECTED)
{
switch(contextMenu->getSelectedItem())
{
And, why cant i get event on a submenu? Is it not possible?
Edit code for Gui creation:
Code: Select all
// Inventory
IGUIWindow * inventoryWindow = irrGui->addWindow(rect<s32>(674, 100, 994, 600), false, L"Inventory");
inventoryWindow->setVisible(false);
irrGui->addStaticText(L"Equipment",rect<s32>(10, 30, 310, 45),false,true,inventoryWindow);
IGUITable * equipmentTree = irrGui->addTable(rect<s32>(10, 45, 310, 75),inventoryWindow, -1, false);
equipmentTree->addColumn(L"Body part");
equipmentTree->addColumn(L"Item");
equipmentTree->addColumn(L"Weight");
equipmentTree->setColumnWidth(0,78);
equipmentTree->setColumnWidth(1,170);
equipmentTree->addRow(0);
equipmentTree->setCellText(0,0,L"Hand:");
irrGui->addStaticText(L"Items",rect<s32>(10, 85, 310, 100),false,true,inventoryWindow);
IGUITable * invTree = irrGui->addTable(rect<s32>(10, 100, 310, 470),inventoryWindow, -1, false);
invTree->addColumn(L"Item");
invTree->addColumn(L"Weight");
invTree->setColumnWidth(0,248);
irrGui->addStaticText(L"Total weight: 2.0kg / 100kg",rect<s32>(10, 480, 310, 495),false,true,inventoryWindow);
// Contex menu
IGUIContextMenu * contextMenu = irrGui->addContextMenu((rect<s32>(0,0,0,0)),0,30);
contextMenu->setCloseHandling(ECMC_HIDE);
contextMenu->addItem(L"Equip",11);
u32 craftMenu = contextMenu->addItem(L"Craft",12, true, true);
contextMenu->getSubMenu(craftMenu)->addItem(L"Stone axe",15);
contextMenu->getSubMenu(craftMenu)->addItem(L"Stone hammer",16);
contextMenu->addItem(L"Drop",13);
contextMenu->addItem(L"Examine",14);
contextMenu->setVisible(false);
irrGui->removeFocus(irrGui->getFocus());
contextMenu->setItemEnabled(0, false);
contextMenu->setItemEnabled(1, false);
contextMenu->setItemEnabled(2, false);
contextMenu->setItemEnabled(3, false);
The idea behind posting code is to make it reproducible for others to get the bug. Setting windows invisible, putting the context-menu on 0,0,0,0 (which makes it obviously not visible), making it invisible additionally - well - really not sure what exactly you want me to look at.
I suspect you make it visible again at some other part of your application and maybe do resize it, etc... but well, I'm not able to look at your monitor - so really - I have no idea.
I've adapted your code a little bit so it compiles at least - so please take that as a starting-point and show us how to reproduce the problems exactly. It would also be nice if you remove every line that's not needed to show the bug.
So slightly reworked code that shows the Window and context-menu:
I suspect you make it visible again at some other part of your application and maybe do resize it, etc... but well, I'm not able to look at your monitor - so really - I have no idea.
I've adapted your code a little bit so it compiles at least - so please take that as a starting-point and show us how to reproduce the problems exactly. It would also be nice if you remove every line that's not needed to show the bug.
So slightly reworked code that shows the Window and context-menu:
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
struct SAppContext
{
IrrlichtDevice * device;
IGUIContextMenu * contextMenu;
};
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(SAppContext & context) : Context(context) { }
virtual bool OnEvent(const SEvent& event)
{
if (event.EventType == EET_GUI_EVENT)
{
if ( event.GUIEvent.Caller == Context.contextMenu )
{
if(event.GUIEvent.EventType == EGET_MENU_ITEM_SELECTED)
std::cout << "item selected: " << Context.contextMenu->getSelectedItem() << std::endl;
}
}
return false;
}
private:
SAppContext & Context;
};
int main()
{
video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
IrrlichtDevice * device = createDevice(driverType, core::dimension2d<u32>(1024, 768));
if (device == 0)
return 1; // could not create selected driver.
video::IVideoDriver* driver = device->getVideoDriver();
IGUIEnvironment* irrGui = device->getGUIEnvironment();
IGUIWindow * inventoryWindow = irrGui->addWindow(rect<s32>(674, 100, 994, 600), false, L"Inventory");
// inventoryWindow->setVisible(false);
irrGui->addStaticText(L"Equipment",rect<s32>(10, 30, 310, 45),false,true,inventoryWindow);
IGUITable * equipmentTree = irrGui->addTable(rect<s32>(10, 45, 310, 75),inventoryWindow, -1, false);
equipmentTree->addColumn(L"Body part");
equipmentTree->addColumn(L"Item");
equipmentTree->addColumn(L"Weight");
equipmentTree->setColumnWidth(0,78);
equipmentTree->setColumnWidth(1,170);
equipmentTree->addRow(0);
equipmentTree->setCellText(0,0,L"Hand:");
irrGui->addStaticText(L"Items",rect<s32>(10, 85, 310, 100),false,true,inventoryWindow);
IGUITable * invTree = irrGui->addTable(rect<s32>(10, 100, 310, 470),inventoryWindow, -1, false);
invTree->addColumn(L"Item");
invTree->addColumn(L"Weight");
invTree->setColumnWidth(0,248);
irrGui->addStaticText(L"Total weight: 2.0kg / 100kg",rect<s32>(10, 480, 310, 495),false,true,inventoryWindow);
// Contex menu
IGUIContextMenu * contextMenu = irrGui->addContextMenu((rect<s32>(0,0,100,30)),0,30);
contextMenu->setCloseHandling(ECMC_HIDE);
contextMenu->addItem(L"Equip",11);
u32 craftMenu = contextMenu->addItem(L"Craft",12, true, true);
contextMenu->getSubMenu(craftMenu)->addItem(L"Stone axe",15);
contextMenu->getSubMenu(craftMenu)->addItem(L"Stone hammer",16);
contextMenu->addItem(L"Drop",13);
contextMenu->addItem(L"Examine",14);
// contextMenu->setVisible(false);
// irrGui->removeFocus(irrGui->getFocus());
contextMenu->setItemEnabled(0, false);
contextMenu->setItemEnabled(1, false);
contextMenu->setItemEnabled(2, false);
contextMenu->setItemEnabled(3, false);
SAppContext context;
context.device = device;
context.contextMenu = contextMenu;
MyEventReceiver receiver(context);
device->setEventReceiver(&receiver);
while(device->run() && driver)
{
if (device->isWindowActive())
{
driver->beginScene(true, true, SColor(0,200,200,200));
irrGui->drawAll();
driver->endScene();
}
}
device->drop();
return 0;
}
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
Hehe, sorry about that. Here comes better code i hope:
Creating menu:
Event handler:
This works great, until i focus the inventory window, thats the window i click in to create the context menu. Code:
Creating window and table:
Event that runs on right-click. To only show menu when clicking on table and to extract index of table:
As soon as this window gets focus, the EGET_MENU_ITEM_SELECTED event stops for some reason. It Works if i focus another window, just not the same as i click in.
Creating menu:
Code: Select all
IGUIContextMenu * contextMenu = irrGui->addContextMenu((rect<s32>(0,0,0,0)),0,30);
contextMenu->addItem(L"Equip",11);
u32 craftMenu = contextMenu->addItem(L"Craft",12, true, true);
contextMenu->getSubMenu(craftMenu)->addItem(L"Stone axe",15);
contextMenu->getSubMenu(craftMenu)->addItem(L"Stone hammer",16);
contextMenu->addItem(L"Drop",13);
contextMenu->addItem(L"Examine",14);
Code: Select all
bool EventReceiver::OnEvent(const SEvent& event)
{
....
else if(event.EventType == EET_GUI_EVENT)
{
....
else if(event.GUIEvent.Caller == contextMenu)
{
if(event.GUIEvent.EventType == EGET_MENU_ITEM_SELECTED)
{
switch(contextMenu->getSelectedItem())
{
case 0: // Equip
Creating window and table:
Code: Select all
IGUIWindow * inventoryWindow = irrGui->addWindow(rect<s32>(674, 100, 994, 600), false, L"Inventory");
IGUITable * equipmentTree = irrGui->addTable(rect<s32>(10, 45, 310, 75),inventoryWindow, -1, false);
Code: Select all
void EventReceiver::EventRightDown(const SEvent& event) //Item list
{
rightButtonDown = true;
if(0 != invTree->getElementFromPoint(vector2d<s32>(event.MouseInput.X, event.MouseInput.Y)))
{
int pos = event.MouseInput.Y - invTree->getAbsolutePosition().UpperLeftCorner.Y;
int index = pos / 15 - 1;
if(index >= 0 && index < myPlayer->getInvCount())
{
contextMenu->setRelativePosition(vector2d<s32>(event.MouseInput.X, event.MouseInput.Y));
contextMenu->setVisible(true);
irrGui->setFocus(contextMenu);
irrDevice->getCursorControl()->setVisible(true);
camera->setInputReceiverEnabled(false);
myPlayer->setClickedItem(myPlayer->GetItem(index));
myPlayer->setSelectedItem(myPlayer->GetItem(invTree->getSelected()));
if(myPlayer->getClickedItem() != myPlayer->getSelectedItem() &&
myPlayer->getClickedItem()->getType() == IT_COMPONENT &&
myPlayer->getSelectedItem()->getType() == IT_COMPONENT)
{//Rest just selects what menus to enable
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
Ehh, no. Compilable code means 'copy all and press compile'. You only show some code fragments. If chosen wisely, this can be enough. But as you were already told that the problem is not that easily visible, you have to provide moree if you really need some help. Just take your *full code* and remove methods and code parts until the problem does not appear anymore. Go back one step and clean up other places of your code the same way. If you cannot find any code fragment which can be removed, post the code here.
Hybrid was faster than me ;-) But a note about event-handling in Irrlicht: mouse-events are always going to the focused element.
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
EGET_MENU_ITEM_SELECTED also works for sub-menus. You get the menu in Caller and the item with getSelectedItem. Notice that you can pass custom command-id's to menu-items, which is often needed when you work with dynamic menues to identify the items easy.
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
Ok, here we go again : )
This time its code that should be copy-paste-compilable : p
Still same issue, when window is focused, i cant get anymore EGET_MENU_ITEM_SELECTED events. Also i would be greatful if someone showed me an example on how the get the submenu here give event.
[/code]
This time its code that should be copy-paste-compilable : p
Still same issue, when window is focused, i cant get anymore EGET_MENU_ITEM_SELECTED events. Also i would be greatful if someone showed me an example on how the get the submenu here give event.
Code: Select all
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
class EventReceiver :
public IEventReceiver
{
public:
EventReceiver::EventReceiver(IGUIContextMenu * newContextMenu, IGUIEnvironment * myGui)
{
contextMenu = newContextMenu;
irrGui = myGui;
}
bool EventReceiver::OnEvent(const SEvent& event)
{
if(event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN)
{
if(event.EventType == EET_MOUSE_INPUT_EVENT)
{
contextMenu->setRelativePosition(vector2d<s32>(event.MouseInput.X, event.MouseInput.Y));
contextMenu->setVisible(true);
irrGui->setFocus(contextMenu);
return true;
}
}
else if(event.EventType == EET_GUI_EVENT)
{
if(event.GUIEvent.Caller == contextMenu)
{
if(event.GUIEvent.EventType == EGET_MENU_ITEM_SELECTED)
{
switch(contextMenu->getSelectedItem())
{
case 0:
break;
case 1:
break;
case 2:
break;
}
return true;
}
}
}
return false;
}
private:
IGUIContextMenu * contextMenu;
IGUIEnvironment * irrGui;
};
int main()
{
IrrlichtDevice * irrDevice = createDevice(EDT_DIRECT3D9, dimension2d<u32>(1024,768));
IGUIEnvironment* irrGui = irrDevice->getGUIEnvironment();
IVideoDriver * irrVideo = irrDevice->getVideoDriver();
ISceneManager* irrScene = irrDevice->getSceneManager();
//Gui
IGUIWindow * inventoryWindow = irrGui->addWindow(rect<s32>(674, 100, 994, 600), false, L"Inventory");
IGUITable * invTree = irrGui->addTable(rect<s32>(10, 100, 310, 470),inventoryWindow, -1, false);
invTree->addColumn(L"Item");
invTree->addRow(0);
invTree->setCellText(0,0,L"Cell");
IGUIContextMenu * contextMenu = irrGui->addContextMenu((rect<s32>(0,0,0,0)),0,30);
contextMenu->setCloseHandling(ECMC_HIDE);
contextMenu->addItem(L"Equip",11);
u32 craftMenu = contextMenu->addItem(L"Craft",12, true, true);
contextMenu->getSubMenu(craftMenu)->addItem(L"Stone axe",15);
contextMenu->getSubMenu(craftMenu)->addItem(L"Stone hammer",16);
contextMenu->addItem(L"Drop",13);
contextMenu->addItem(L"Examine",14);
contextMenu->setVisible(false);
EventReceiver receiver(contextMenu, irrGui);
irrDevice->setEventReceiver(&receiver);
// Main loop
while(irrDevice->run())
{
irrVideo->beginScene(true, true, SColor(0,0,0,0));
irrScene->drawAll();
irrGui->drawAll();
irrVideo->endScene();
}
irrDevice->drop();
return 0;
}
I'm still at work, but on a quick view I see 2 problems. The first one is simply that it's not nice checking for MouseInput.Event before checking for event.EventType, you should do this the other way round (you don't know if you have a valid MouseInput before you check for EET_MOUSE_INPUT_EVENT).
The other problem is that you return true which marks the event as handled and so it will not be further processed. So the Irrlicht gui never receives the EMIE_RMOUSE_PRESSED_DOWN events. Try returning false instead.
The other problem is that you return true which marks the event as handled and so it will not be further processed. So the Irrlicht gui never receives the EMIE_RMOUSE_PRESSED_DOWN events. Try returning false instead.
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
Hehe, the first point is very valid ; )
Did no notice that, very bad practice. But i see now in my original code that i do it right there.
About the other issue, i will test and see.
Edit: I think i found the issue, the problems seems to be that the contextMenu is created behind the inventory, so when inventory is focused the keypresses don't hit the menu, but the window instead. Not sure how to fix this though, the "bringToFront" function don't seem to do the trick...
Did no notice that, very bad practice. But i see now in my original code that i do it right there.
About the other issue, i will test and see.
Edit: I think i found the issue, the problems seems to be that the contextMenu is created behind the inventory, so when inventory is focused the keypresses don't hit the menu, but the window instead. Not sure how to fix this though, the "bringToFront" function don't seem to do the trick...
bringToFront works relative to other childs which have the same parent. Not sure if you still use the same test-case (where it doesn't seem to have a parent, so it should work), but in general you should give context-menus no parent except the gui-environment itself to make sure a bringToFront on them brings them really to the top.
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