Irrlicht 1.8.4 IGUIElement/CameraSceneNodeMaya mouse bug?
Irrlicht 1.8.4 IGUIElement/CameraSceneNodeMaya mouse bug?
I have a Maya style camera and some gui elements. When I left click inside the gui and move the mouse the camera does not look around, which seems to me would be the expected behavior. But when I middle/right click and move the mouse the camera will still zoom and pan. is this intended?
Re: Irrlicht 1.8.4 IGUIElement/CameraSceneNodeMaya mouse bug
Events get handled in this order:
1. UserEventReceivers (the one you can set when creating a device)
2. UI
3. Input receivers (SceneManager), like cameras.
So if camera doesn't get some it means one of the earlier receivers returned "true" and marked the event as handled. And yeah - there is a bunch of UI elements which mark left-mouse clicks as handled. Including windows it seems (if handling events is correct or not in each case is up for discussion, the rules about that were slightly lax when the UI was created).
I generally prefer that behavior and even tend have code in my apps where I check if the mouse-cursor is above UI-elements and if so I often disable any other mouse-event handling.
If you still need that behavior... could be done with some workaround I think: You can disable the usual input receiver in camera with camera->setInputReceiverEnabled(false). Then use your own event-receiver (which is first to receive any event) and pass the events directly to the animator (camera->getAnimators()[0]->OnEvent).
That way the camera animator would receive them before the UI.
1. UserEventReceivers (the one you can set when creating a device)
2. UI
3. Input receivers (SceneManager), like cameras.
So if camera doesn't get some it means one of the earlier receivers returned "true" and marked the event as handled. And yeah - there is a bunch of UI elements which mark left-mouse clicks as handled. Including windows it seems (if handling events is correct or not in each case is up for discussion, the rules about that were slightly lax when the UI was created).
I generally prefer that behavior and even tend have code in my apps where I check if the mouse-cursor is above UI-elements and if so I often disable any other mouse-event handling.
If you still need that behavior... could be done with some workaround I think: You can disable the usual input receiver in camera with camera->setInputReceiverEnabled(false). Then use your own event-receiver (which is first to receive any event) and pass the events directly to the animator (camera->getAnimators()[0]->OnEvent).
That way the camera animator would receive them before the UI.
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
Re: Irrlicht 1.8.4 IGUIElement/CameraSceneNodeMaya mouse bug
Thanks for the guidance, it helped me out a lot to understand what was happening.
I think the best solution for my case would be to modify the IGUIElements themselves(To handle events for other mouse buttons.) and recompile Irrlicht.
I think the best solution for my case would be to modify the IGUIElements themselves(To handle events for other mouse buttons.) and recompile Irrlicht.
Re: Irrlicht 1.8.4 IGUIElement/CameraSceneNodeMaya mouse bug
I went another route and only changed the irrlicht event routing in postEventFromUser() to gain control over the events
(the application is the device event receiver and all events are sent to it first (as UserReceiver) in the irrlicht device instance.)
//! send the event to the right receiver
bool CIrrDeviceStub::postEventFromUser(const SEvent& event)
{
bool absorbed = false;
if (!absorbed && UserReceiver)
absorbed = UserReceiver->OnEvent(event);
// if (!absorbed && GUIEnvironment)
// absorbed = GUIEnvironment->postEventFromUser(event);
scene::ISceneManager* inputReceiver = InputReceivingSceneManager;
if (!inputReceiver)
inputReceiver = SceneManager;
if (!absorbed && inputReceiver)
absorbed = inputReceiver->postEventFromUser(event);
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return absorbed;
}
I send the events to the desktop, then the gui, then the level and lastly handle it at the app level if it still exists....
bool FSApplication::OnEvent(const SEvent& e)
{
if (getDesktop() && getDesktop()->OnEvent(e)) return true;
if (getGui()->postEventFromUser(e)) return true;
if (getActiveLevel() && getActiveLevel()->OnEvent(e)) return true;
if (FSEventHandler::OnEvent(e)) return true;
return false;
}
(the application is the device event receiver and all events are sent to it first (as UserReceiver) in the irrlicht device instance.)
//! send the event to the right receiver
bool CIrrDeviceStub::postEventFromUser(const SEvent& event)
{
bool absorbed = false;
if (!absorbed && UserReceiver)
absorbed = UserReceiver->OnEvent(event);
// if (!absorbed && GUIEnvironment)
// absorbed = GUIEnvironment->postEventFromUser(event);
scene::ISceneManager* inputReceiver = InputReceivingSceneManager;
if (!inputReceiver)
inputReceiver = SceneManager;
if (!absorbed && inputReceiver)
absorbed = inputReceiver->postEventFromUser(event);
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return absorbed;
}
I send the events to the desktop, then the gui, then the level and lastly handle it at the app level if it still exists....
bool FSApplication::OnEvent(const SEvent& e)
{
if (getDesktop() && getDesktop()->OnEvent(e)) return true;
if (getGui()->postEventFromUser(e)) return true;
if (getActiveLevel() && getActiveLevel()->OnEvent(e)) return true;
if (FSEventHandler::OnEvent(e)) return true;
return false;
}