Refactored the CEvent -> CEventDescriptor code in CInputHandlerManager. Extracted it as a new class CInputHandler, and moved some of it to CInterfaceManager.

This commit is contained in:
dfighter1985 2012-05-17 03:28:50 +02:00
parent e3d72333dd
commit 88cc7df755
8 changed files with 598 additions and 330 deletions

View file

@ -0,0 +1,36 @@
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef INPUTEVENTLISTENER_H
#define INPUTEVENTLISTENER_H
#include "nel/misc/types_nl.h"
#include "nel/gui/event_descriptor.h"
namespace NLGUI
{
/**
@brief Interface for accepting GUI input events.
*/
class IInputEventListener
{
public:
virtual ~IInputEventListener(){}
virtual bool handleEvent( const CEventDescriptor &eventDesc ) = 0;
};
}
#endif

View file

@ -0,0 +1,57 @@
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef INPUT_HANDLER_H
#define INPUT_HANDLER_H
#include "nel/misc/events.h"
#include "nel/gui/event_descriptor.h"
#include "nel/gui/input_event_listener.h"
namespace NLGUI{
/**
@brief The input event entry point of the GUI library.
Translates the NEL input events and forwards them.
*/
class CInputHandler
{
public:
CInputHandler();
~CInputHandler();
bool handleEvent( const NLMISC::CEvent &evnt );
bool handleSetFocusEvent( const NLMISC::CEvent &evnt );
bool handleKeyboardEvent( const NLMISC::CEvent &evnt );
bool handleMouseEvent( const NLMISC::CEvent &evnt );
bool handleMouseMoveEvent( const NLMISC::CEvent &evnt );
bool handleMouseButtonDownEvent( const NLMISC::CEvent &evnt );
bool handleMouseButtonUpEvent( const NLMISC::CEvent &evnt );
bool handleMouseDblClickEvent( const NLMISC::CEvent &evnt );
bool handleMouseWheelEvent( const NLMISC::CEvent &evnt );
void setListener( IInputEventListener* listener );
private:
IInputEventListener *listener;
};
}
#endif

View file

@ -0,0 +1,212 @@
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "nel/gui/input_handler.h"
namespace NLGUI
{
CInputHandler::CInputHandler()
{
listener = NULL;
}
CInputHandler::~CInputHandler()
{
listener = NULL;
}
bool CInputHandler::handleEvent( const NLMISC::CEvent &evnt )
{
if( evnt == NLMISC::EventSetFocusId )
return handleSetFocusEvent( evnt );
else
if( evnt == NLMISC::EventKeyDownId ||
evnt == NLMISC::EventKeyUpId ||
evnt == NLMISC::EventCharId ||
evnt == NLMISC::EventStringId )
return handleKeyboardEvent( evnt );
else
if( evnt == NLMISC::EventMouseMoveId ||
evnt == NLMISC::EventMouseDownId ||
evnt == NLMISC::EventMouseUpId ||
evnt == NLMISC::EventMouseWheelId ||
evnt == NLMISC::EventMouseDblClkId )
return handleMouseEvent( evnt );
return false;
}
bool CInputHandler::handleSetFocusEvent( const NLMISC::CEvent &evnt )
{
nlassert( evnt == NLMISC::EventSetFocusId );
const NLMISC::CEventSetFocus *e = reinterpret_cast< const NLMISC::CEventSetFocus* >( &evnt );
return listener->handleEvent( CEventDescriptorSetFocus( e->Get ) );
}
bool CInputHandler::handleKeyboardEvent( const NLMISC::CEvent &evnt )
{
bool ok = false;
if( evnt == NLMISC::EventKeyDownId ||
evnt == NLMISC::EventKeyUpId ||
evnt == NLMISC::EventCharId ||
evnt == NLMISC::EventStringId )
ok = true;
nlassert( ok );
return listener->handleEvent( NLGUI::CEventDescriptorKey( reinterpret_cast< const NLMISC::CEventKey& >( evnt ) ) );
}
bool CInputHandler::handleMouseEvent( const NLMISC::CEvent &evnt )
{
if( evnt == NLMISC::EventMouseMoveId )
return handleMouseMoveEvent( evnt );
else
if( evnt == NLMISC::EventMouseDownId )
return handleMouseButtonDownEvent( evnt );
else
if( evnt == NLMISC::EventMouseUpId )
return handleMouseButtonUpEvent( evnt );
else
if( evnt == NLMISC::EventMouseDblClkId )
return handleMouseDblClickEvent( evnt );
else
if( evnt == NLMISC::EventMouseWheelId )
return handleMouseWheelEvent( evnt );
return false;
}
bool CInputHandler::handleMouseMoveEvent( const NLMISC::CEvent &evnt )
{
const NLMISC::CEventMouseMove &mouseMoveEvent = static_cast< const NLMISC::CEventMouseMove& >( evnt );
CEventDescriptorMouse eventDesc;
float x = mouseMoveEvent.X;
float y = mouseMoveEvent.Y;
// These bloody hacks here are used so that we can send the x, and y float coordinates
// from the NEL mouse move event, to the GUI event listener, without having to change
// CEventDescriptorMouse or without having to couple with the consumer class
eventDesc.setX( *reinterpret_cast< sint32* >( &x ) );
eventDesc.setY( *reinterpret_cast< sint32* >( &y ) );
eventDesc.setEventTypeExtended( CEventDescriptorMouse::mousemove );
return listener->handleEvent( eventDesc );
}
bool CInputHandler::handleMouseButtonDownEvent( const NLMISC::CEvent &evnt )
{
nlassert( evnt == NLMISC::EventMouseDownId );
CEventDescriptorMouse eventDesc;
const NLMISC::CEventMouseDown *mouseDownEvent = static_cast< const NLMISC::CEventMouseDown* >( &evnt );
if( mouseDownEvent->Button & NLMISC::leftButton )
{
eventDesc.setEventTypeExtended( CEventDescriptorMouse::mouseleftdown );
return listener->handleEvent( eventDesc );
}
if(mouseDownEvent->Button & NLMISC::rightButton)
{
eventDesc.setEventTypeExtended( CEventDescriptorMouse::mouserightdown );
return listener->handleEvent( eventDesc );
}
return false;
}
bool CInputHandler::handleMouseButtonUpEvent( const NLMISC::CEvent &evnt )
{
nlassert( evnt == NLMISC::EventMouseUpId );
CEventDescriptorMouse eventDesc;
const NLMISC::CEventMouseUp *mouseUpEvent = static_cast< const NLMISC::CEventMouseUp* >( &evnt );
if( mouseUpEvent->Button & NLMISC::leftButton )
{
eventDesc.setEventTypeExtended( CEventDescriptorMouse::mouseleftup );
return listener->handleEvent( eventDesc );
}
if( mouseUpEvent->Button & NLMISC::rightButton )
{
eventDesc.setEventTypeExtended( CEventDescriptorMouse::mouserightup );
return listener->handleEvent( eventDesc );
}
return false;
}
bool CInputHandler::handleMouseDblClickEvent( const NLMISC::CEvent &evnt )
{
nlassert( evnt == NLMISC::EventMouseDblClkId );
CEventDescriptorMouse eventDesc;
const NLMISC::CEventMouseDblClk *dblClickEvent = static_cast< const NLMISC::CEventMouseDblClk* >( &evnt );
if( dblClickEvent->Button & NLMISC::leftButton )
{
eventDesc.setEventTypeExtended( CEventDescriptorMouse::mouseleftdblclk );
return listener->handleEvent (eventDesc);
}
if( dblClickEvent->Button & NLMISC::rightButton )
{
eventDesc.setEventTypeExtended(NLGUI::CEventDescriptorMouse::mouserightdblclk);
return listener->handleEvent (eventDesc);
}
return false;
}
bool CInputHandler::handleMouseWheelEvent( const NLMISC::CEvent &evnt )
{
nlassert( evnt == NLMISC::EventMouseWheelId );
CEventDescriptorMouse eventDesc;
sint32 mouseWheel = 0;
const NLMISC::CEventMouseWheel *wheelEvent = static_cast< const NLMISC::CEventMouseWheel* >( &evnt );
if( wheelEvent->Direction )
mouseWheel = 1;
else
mouseWheel = -1;
if( mouseWheel != 0 )
{
eventDesc.setEventTypeExtended( CEventDescriptorMouse::mousewheel );
eventDesc.setWheel( mouseWheel );
return listener->handleEvent( eventDesc );
}
return false;
}
void CInputHandler::setListener( IInputEventListener *listener )
{
this->listener = listener;
}
}

View file

@ -1067,6 +1067,13 @@ void prelogInit()
if(GenericMat.empty()) if(GenericMat.empty())
nlerror("init: Cannot Create the generic material."); nlerror("init: Cannot Create the generic material.");
// Create a text context. We need to put the full path because we not already add search path
// resetTextContext ("bremenb.ttf", false);
resetTextContext ("ryzom.ttf", false);
CInterfaceManager::create( Driver, TextContext );
// Yoyo: initialize NOW the InputHandler for Event filtering. // Yoyo: initialize NOW the InputHandler for Event filtering.
CInputHandlerManager *InputHandlerManager = CInputHandlerManager::getInstance(); CInputHandlerManager *InputHandlerManager = CInputHandlerManager::getInstance();
InputHandlerManager->addToServer (&Driver->EventServer); InputHandlerManager->addToServer (&Driver->EventServer);
@ -1075,12 +1082,6 @@ void prelogInit()
if( !filename.empty() ) if( !filename.empty() )
InputHandlerManager->readInputConfigFile( filename ); InputHandlerManager->readInputConfigFile( filename );
// Create a text context. We need to put the full path because we not already add search path
// resetTextContext ("bremenb.ttf", false);
resetTextContext ("ryzom.ttf", false);
CInterfaceManager::create( Driver, TextContext );
ProgressBar.setFontFactor(0.85f); ProgressBar.setFontFactor(0.85f);
nmsg = "Loading background..."; nmsg = "Loading background...";

View file

@ -59,14 +59,14 @@ CInputHandlerManager* CInputHandlerManager::_Instance = NULL;
CInputHandlerManager::CInputHandlerManager() CInputHandlerManager::CInputHandlerManager()
{ {
_EventServer= NULL; _EventServer= NULL;
_MouseButtonsReleased = noButton;
_MouseButtonsDown = noButton;
_MouseButtonsState = noButton; _MouseButtonsState = noButton;
_MouseX = _MouseY = _MouseLastX = _MouseLastY = 0; _MouseX = _MouseY = _MouseLastX = _MouseLastY = 0;
_Focus = true; _Focus = true;
_MouseWheel = 0; _MouseWheel = 0;
_SkipInterfaceManager=false; _SkipInterfaceManager=false;
_RecoverFocusLost = false; _RecoverFocusLost = false;
inputHandler.setListener( CInterfaceManager::getInstance() );
} }
// *************************************************************************** // ***************************************************************************
@ -153,24 +153,13 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
if (!pEvent->Get) if (!pEvent->Get)
{ {
// Deactivate all keys // Deactivate all keys
_MouseButtonsDown = noButton;
_MouseButtonsReleased = noButton;
_MouseButtonsState = noButton; _MouseButtonsState = noButton;
_Focus = false; _Focus = false;
if (!_SkipInterfaceManager) if (!_SkipInterfaceManager)
{ {
// if there was some control capturing the mouse, warn them that they lost the focus // if there was some control capturing the mouse, warn them that they lost the focus
if (pIM->getCapturePointerLeft()) inputHandler.handleSetFocusEvent( event );
{
pIM->getCapturePointerLeft()->handleEvent(NLGUI::CEventDescriptorSetFocus(pEvent->Get));
}
pIM->setCapturePointerLeft(NULL);
if (pIM->getCapturePointerRight())
{
pIM->getCapturePointerRight()->handleEvent(NLGUI::CEventDescriptorSetFocus(pEvent->Get));
}
pIM->setCapturePointerRight(NULL);
UserControls.stopFreeLook(); UserControls.stopFreeLook();
} }
// be nice with other app : let the mouse reappear (useful in direct 3D mode with no hardware cursor) // be nice with other app : let the mouse reappear (useful in direct 3D mode with no hardware cursor)
@ -214,7 +203,6 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
return; return;
} }
// **** Event Focus // **** Event Focus
// **** Event Keyboard // **** Event Keyboard
@ -224,7 +212,7 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
event == EventStringId) event == EventStringId)
{ {
// if not handled, post to Action Manager // if not handled, post to Action Manager
if( !pIM->handleEvent( NLGUI::CEventDescriptorKey((const CEventKey &) event) ) ) if( !inputHandler.handleKeyboardEvent( event ) )
{ {
// See if handled by editor // See if handled by editor
bool handled = false; bool handled = false;
@ -283,6 +271,7 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
CViewPointer &rIP = *pIM->getPointer(); CViewPointer &rIP = *pIM->getPointer();
NLGUI::CEventDescriptorMouse eventDesc; NLGUI::CEventDescriptorMouse eventDesc;
sint32 x,y; sint32 x,y;
rIP.getPointerDispPos (x, y); rIP.getPointerDispPos (x, y);
eventDesc.setX (x); eventDesc.setX (x);
@ -313,71 +302,18 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
handled |= R2::getEditor().handleEvent(eventDesc); handled |= R2::getEditor().handleEvent(eventDesc);
} }
} }
handled |= inputHandler.handleMouseButtonDownEvent( event );
CEventMouseDown *pEvent=(CEventMouseDown*)&event;
// update states
_MouseButtonsDown = (TMouseButton) (_MouseButtonsDown | pEvent->Button);
_MouseButtonsReleased =(TMouseButton) (_MouseButtonsReleased & ~(pEvent->Button));
_MouseButtonsState = (TMouseButton) (_MouseButtonsState | pEvent->Button);
rIP.setButtonState(_MouseButtonsState);
// handle Event
if(pEvent->Button & leftButton)
{
eventDesc.setEventTypeExtended(NLGUI::CEventDescriptorMouse::mouseleftdown);
handled|= pIM->handleEvent (eventDesc);
}
if(pEvent->Button & rightButton)
{
eventDesc.setEventTypeExtended(NLGUI::CEventDescriptorMouse::mouserightdown);
handled|= pIM->handleEvent (eventDesc);
}
} }
// button up ? // button up ?
else if (event==EventMouseUpId) else if (event==EventMouseUpId)
{ {
CEventMouseUp *pEvent=(CEventMouseUp*)&event; handled |= inputHandler.handleMouseButtonUpEvent( event );
// update states
_MouseButtonsReleased = (TMouseButton) (_MouseButtonsReleased | pEvent->Button);
_MouseButtonsDown =(TMouseButton) (_MouseButtonsDown & ~(pEvent->Button));
_MouseButtonsState = (TMouseButton) (_MouseButtonsState & ~(pEvent->Button));
rIP.setButtonState(_MouseButtonsState);
// handle Event
if(pEvent->Button & leftButton)
{
eventDesc.setEventTypeExtended(NLGUI::CEventDescriptorMouse::mouseleftup);
handled|= pIM->handleEvent (eventDesc);
}
if(pEvent->Button & rightButton)
{
eventDesc.setEventTypeExtended(NLGUI::CEventDescriptorMouse::mouserightup);
handled|= pIM->handleEvent (eventDesc);
}
} }
// db click ? // db click ?
else if (event == EventMouseDblClkId ) else if (event == EventMouseDblClkId )
{ {
// TODO: yoyo make it work if needed (for now, seems preferable to manage in each ActionHandler) // TODO: yoyo make it work if needed (for now, seems preferable to manage in each ActionHandler)
handled |= inputHandler.handleMouseDblClickEvent( event );
CEventMouseDblClk* pEvent=(CEventMouseDblClk*)&event;
// handle Event
if(pEvent->Button & leftButton)
{
eventDesc.setEventTypeExtended(NLGUI::CEventDescriptorMouse::mouseleftdblclk);
handled|= pIM->handleEvent (eventDesc);
}
if(pEvent->Button & rightButton)
{
eventDesc.setEventTypeExtended(NLGUI::CEventDescriptorMouse::mouserightdblclk);
handled|= pIM->handleEvent (eventDesc);
}
} }
// mouse move? // mouse move?
else if(event == EventMouseMoveId) else if(event == EventMouseMoveId)
@ -386,20 +322,7 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
} }
else if (event == EventMouseWheelId) else if (event == EventMouseWheelId)
{ {
CEventMouseWheel *pEvent=(CEventMouseWheel*)&event; handled |= inputHandler.handleMouseWheelEvent( event );
if (pEvent->Direction)
_MouseWheel += 1;
else
_MouseWheel -= 1;
// handle Event now.
if (_MouseWheel != 0)
{
eventDesc.setEventTypeExtended(NLGUI::CEventDescriptorMouse::mousewheel);
eventDesc.setWheel(_MouseWheel);
handled|= pIM->handleEvent (eventDesc);
_MouseWheel = 0;
}
} }
} }
@ -432,39 +355,8 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
bool CInputHandlerManager::updateMousePos(NLMISC::CEventMouse &event, NLGUI::CEventDescriptorMouse &eventDesc) bool CInputHandlerManager::updateMousePos(NLMISC::CEventMouse &event, NLGUI::CEventDescriptorMouse &eventDesc)
{ {
if (!IsMouseFreeLook()) if (!IsMouseFreeLook())
{ return inputHandler.handleMouseMoveEvent( event );
CEventMouseMove* mouseEvent=(CEventMouseMove*)&event;
uint32 w, h;
CInterfaceManager::getInstance()->getViewRenderer().getScreenSize(w, h);
// compute new coords
_MouseLastX = _MouseX;
_MouseLastY = _MouseY;
_MouseX = (sint32)(mouseEvent->X*w + 0.5f);
_MouseY = (sint32)(mouseEvent->Y*h + 0.5f);
// Process Move message only if not Null move
if(_MouseX!=_MouseLastX || _MouseY!=_MouseLastY)
{
// Move the pointer
//pIM->movePointer (_MouseX-_MouseLastX, _MouseY-_MouseLastY);
CInterfaceManager *pIM = CInterfaceManager::getInstance();
pIM->movePointerAbs(_MouseX, _MouseY);
CViewPointer &rIP = *pIM->getPointer();
// get new pointer pos.
sint32 x,y;
rIP.getPointerDispPos (x, y);
eventDesc.setX (x);
eventDesc.setY (y);
// handle Event now.
eventDesc.setEventTypeExtended(NLGUI::CEventDescriptorMouse::mousemove);
return pIM->handleEvent (eventDesc);
}
}
return false; return false;
} }

View file

@ -25,6 +25,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include "nel/gui/event_descriptor.h" #include "nel/gui/event_descriptor.h"
#include "nel/gui/input_handler.h"
/** /**
@ -38,9 +39,6 @@
* \date 2002 * \date 2002
*/ */
class CInputHandlerBase;
class CViewText;
class CInputHandlerManager : public NLMISC::IEventListener class CInputHandlerManager : public NLMISC::IEventListener
{ {
@ -133,8 +131,6 @@ private:
NLMISC::CEventServer* _EventServer; NLMISC::CEventServer* _EventServer;
// Mouse Infos // Mouse Infos
NLMISC::TMouseButton _MouseButtonsReleased;
NLMISC::TMouseButton _MouseButtonsDown;
NLMISC::TMouseButton _MouseButtonsState; NLMISC::TMouseButton _MouseButtonsState;
sint32 _MouseX, _MouseY; sint32 _MouseX, _MouseY;
@ -180,6 +176,8 @@ private:
// return true if handled // return true if handled
bool updateMousePos(NLMISC::CEventMouse &event, NLGUI::CEventDescriptorMouse &eventDesc); bool updateMousePos(NLMISC::CEventMouse &event, NLGUI::CEventDescriptorMouse &eventDesc);
NLGUI::CInputHandler inputHandler;
}; };
#endif // NL_INPUT_HANDLER_MANAGER_H #endif // NL_INPUT_HANDLER_MANAGER_H

View file

@ -2675,6 +2675,25 @@ bool CInterfaceManager::handleEvent (const NLGUI::CEventDescriptor& event)
{ {
bool handled= false; bool handled= false;
if( event.getType() == NLGUI::CEventDescriptor::system )
{
const NLGUI::CEventDescriptorSystem &eventDesc = reinterpret_cast< const NLGUI::CEventDescriptorSystem& >( event );
if( eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorSystem::setfocus )
{
if( _CapturePointerLeft != NULL )
{
_CapturePointerLeft->handleEvent( event );
setCapturePointerLeft( NULL );
}
if( _CapturePointerRight != NULL )
{
_CapturePointerRight->handleEvent( event );
setCapturePointerRight( NULL );
}
}
}
// Check if we can receive events (no anims!) // Check if we can receive events (no anims!)
for (uint i = 0; i < _ActiveAnims.size(); ++i) for (uint i = 0; i < _ActiveAnims.size(); ++i)
if (_ActiveAnims[i]->isDisableButtons()) if (_ActiveAnims[i]->isDisableButtons())
@ -2802,260 +2821,280 @@ bool CInterfaceManager::handleEvent (const NLGUI::CEventDescriptor& event)
return result; return result;
} }
} }
else if (event.getType() == NLGUI::CEventDescriptor::mouse && _MouseHandlingEnabled ) else if (event.getType() == NLGUI::CEventDescriptor::mouse )
{ {
NLGUI::CEventDescriptorMouse &eventDesc = (NLGUI::CEventDescriptorMouse&)event; NLGUI::CEventDescriptorMouse &eventDesc = (NLGUI::CEventDescriptorMouse&)event;
// First thing to do : Capture handling if( eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown )
if (_CapturePointerLeft != NULL) _Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() | NLMISC::leftButton ) );
handled|= _CapturePointerLeft->handleEvent(event); else
if( eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown )
_Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() | NLMISC::rightButton ) );
else
if( eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup )
_Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() & ~NLMISC::leftButton ) );
if( eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup )
_Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() & ~NLMISC::rightButton ) );
if (_CapturePointerRight != NULL && _CapturePointerRight!=_CapturePointerLeft) if( eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousemove )
handled|= _CapturePointerRight->handleEvent(event); handleMouseMoveEvent( eventDesc );
CInterfaceGroup *ptr = getWindowUnder (eventDesc.getX(), eventDesc.getY()); eventDesc.setX( _Pointer->getX() );
_WindowUnder = ptr?ptr->getId():""; eventDesc.setY( _Pointer->getY() );
// Any Mouse event but move disable the ContextHelp if( _MouseHandlingEnabled )
if(eventDesc.getEventTypeExtended() != NLGUI::CEventDescriptorMouse::mousemove)
{ {
disableContextHelp(); // First thing to do : Capture handling
} if (_CapturePointerLeft != NULL)
handled|= _CapturePointerLeft->handleEvent(event);
// get the group under the mouse if (_CapturePointerRight != NULL && _CapturePointerRight!=_CapturePointerLeft)
CInterfaceGroup *pNewCurrentWnd = _WindowUnder; handled|= _CapturePointerRight->handleEvent(event);
_MouseOverWindow= pNewCurrentWnd!=NULL;
CInterfaceGroup *ptr = getWindowUnder (eventDesc.getX(), eventDesc.getY());
_WindowUnder = ptr?ptr->getId():"";
NLMISC::CRefPtr<CGroupModal> clickedOutModalWindow; // Any Mouse event but move disable the ContextHelp
if(eventDesc.getEventTypeExtended() != NLGUI::CEventDescriptorMouse::mousemove)
// modal special features
if (!_ModalStack.empty())
{
CModalWndInfo mwi = _ModalStack.back();
if(mwi.ModalWindow)
{ {
// If we are not in "click out" mode so we dont handle controls other than those of the modal disableContextHelp();
if (pNewCurrentWnd != mwi.ModalWindow && !mwi.ModalExitClickOut) }
{
pNewCurrentWnd = NULL;
}
else
{
// If there is a handler on click out launch it
if (pNewCurrentWnd != mwi.ModalWindow)
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown ||
(eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown))
if (!mwi.ModalHandlerClickOut.empty())
runActionHandler(mwi.ModalHandlerClickOut,NULL,mwi.ModalClickOutParams);
// If the current window is not the modal and if must quit on click out // get the group under the mouse
if(pNewCurrentWnd != mwi.ModalWindow && mwi.ModalExitClickOut) CInterfaceGroup *pNewCurrentWnd = _WindowUnder;
_MouseOverWindow= pNewCurrentWnd!=NULL;
NLMISC::CRefPtr<CGroupModal> clickedOutModalWindow;
// modal special features
if (!_ModalStack.empty())
{
CModalWndInfo mwi = _ModalStack.back();
if(mwi.ModalWindow)
{
// If we are not in "click out" mode so we dont handle controls other than those of the modal
if (pNewCurrentWnd != mwi.ModalWindow && !mwi.ModalExitClickOut)
{ {
// NB: don't force handle==true because to quit a modal does not avoid other actions pNewCurrentWnd = NULL;
}
else
{
// If there is a handler on click out launch it
if (pNewCurrentWnd != mwi.ModalWindow)
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown ||
(eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown))
if (!mwi.ModalHandlerClickOut.empty())
runActionHandler(mwi.ModalHandlerClickOut,NULL,mwi.ModalClickOutParams);
// quit if click outside // If the current window is not the modal and if must quit on click out
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown || if(pNewCurrentWnd != mwi.ModalWindow && mwi.ModalExitClickOut)
(eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown))
{ {
clickedOutModalWindow = dynamic_cast<CGroupModal *>((CInterfaceGroup*)mwi.ModalWindow); // NB: don't force handle==true because to quit a modal does not avoid other actions
// disable the modal
popModalWindow(); // quit if click outside
if (!_ModalStack.empty()) if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown ||
(eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown))
{ {
// don't handle event unless it is a previous modal window clickedOutModalWindow = dynamic_cast<CGroupModal *>((CInterfaceGroup*)mwi.ModalWindow);
uint k = 0; // disable the modal
for(k = 0; k < _ModalStack.size(); ++k) popModalWindow();
if (!_ModalStack.empty())
{ {
if (_ModalStack[k].ModalWindow == pNewCurrentWnd) // don't handle event unless it is a previous modal window
uint k = 0;
for(k = 0; k < _ModalStack.size(); ++k)
{ {
break; if (_ModalStack[k].ModalWindow == pNewCurrentWnd)
{
break;
}
}
if (k == _ModalStack.size())
{
pNewCurrentWnd = NULL; // can't handle event before we have left all modal windows
} }
} }
if (k == _ModalStack.size()) movePointer (0,0); // Reget controls under pointer
{
pNewCurrentWnd = NULL; // can't handle event before we have left all modal windows
}
} }
movePointer (0,0); // Reget controls under pointer
} }
} }
} }
} }
}
// Manage LeftClick. // Manage LeftClick.
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown) if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown)
{
if ((pNewCurrentWnd != NULL) && (_ModalStack.empty()) && (pNewCurrentWnd->getOverlappable()))
{ {
CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(pNewCurrentWnd); if ((pNewCurrentWnd != NULL) && (_ModalStack.empty()) && (pNewCurrentWnd->getOverlappable()))
if (pGC != NULL)
{ {
if (!pGC->isGrayed()) setTopWindow(pNewCurrentWnd); CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(pNewCurrentWnd);
if (pGC != NULL)
{
if (!pGC->isGrayed()) setTopWindow(pNewCurrentWnd);
}
else
{
setTopWindow(pNewCurrentWnd);
}
} }
else
// must not capture a new element if a sheet is currentlty being dragged.
// This may happen when alt-tab has been used => the sheet is dragged but the left button is up
if (!CDBCtrlSheet::getDraggedSheet())
{ {
setTopWindow(pNewCurrentWnd); // Take the top most control.
uint nMaxDepth = 0;
for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--)
{
CCtrlBase *ctrl= _CtrlsUnderPointer[i];
if (ctrl && ctrl->isCapturable() && isControlInWindow(ctrl, pNewCurrentWnd))
{
uint d = getDepth(ctrl, pNewCurrentWnd);
if (d > nMaxDepth)
{
nMaxDepth = d;
_CapturePointerLeft = ctrl;
}
}
}
notifyElementCaptured(_CapturePointerLeft);
if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty())
{
runActionHandler(clickedOutModalWindow->OnPostClickOut, _CapturePointerLeft, clickedOutModalWindow->OnPostClickOutParams);
}
}
//if found
if (_CapturePointerLeft != NULL)
{
// consider clicking on a control implies handling of the event.
handled= true;
// handle the capture
_CapturePointerLeft->handleEvent(event);
} }
} }
// must not capture a new element if a sheet is currentlty being dragged. // Manage RightClick
// This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown)
if (!CDBCtrlSheet::getDraggedSheet())
{ {
if ((pNewCurrentWnd != NULL) && (_ModalStack.empty()) && (pNewCurrentWnd->getOverlappable()))
{
CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(pNewCurrentWnd);
if (pGC != NULL)
{
if (!pGC->isGrayed()) setTopWindow(pNewCurrentWnd);
}
else
{
setTopWindow(pNewCurrentWnd);
}
}
// Take the top most control. // Take the top most control.
uint nMaxDepth = 0;
for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--)
{ {
CCtrlBase *ctrl= _CtrlsUnderPointer[i]; uint nMaxDepth = 0;
if (ctrl && ctrl->isCapturable() && isControlInWindow(ctrl, pNewCurrentWnd)) for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--)
{ {
uint d = getDepth(ctrl, pNewCurrentWnd); CCtrlBase *ctrl= _CtrlsUnderPointer[i];
if (d > nMaxDepth) if (ctrl && ctrl->isCapturable() && isControlInWindow(ctrl, pNewCurrentWnd))
{ {
nMaxDepth = d; uint d = getDepth(ctrl , pNewCurrentWnd);
_CapturePointerLeft = ctrl; if (d > nMaxDepth)
{
nMaxDepth = d;
_CapturePointerRight = ctrl;
}
} }
} }
} notifyElementCaptured(_CapturePointerRight);
notifyElementCaptured(_CapturePointerLeft); if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty())
if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty())
{
runActionHandler(clickedOutModalWindow->OnPostClickOut, _CapturePointerLeft, clickedOutModalWindow->OnPostClickOutParams);
}
}
//if found
if (_CapturePointerLeft != NULL)
{
// consider clicking on a control implies handling of the event.
handled= true;
// handle the capture
_CapturePointerLeft->handleEvent(event);
}
}
// Manage RightClick
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown)
{
if ((pNewCurrentWnd != NULL) && (_ModalStack.empty()) && (pNewCurrentWnd->getOverlappable()))
{
CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(pNewCurrentWnd);
if (pGC != NULL)
{
if (!pGC->isGrayed()) setTopWindow(pNewCurrentWnd);
}
else
{
setTopWindow(pNewCurrentWnd);
}
}
// Take the top most control.
{
uint nMaxDepth = 0;
for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--)
{
CCtrlBase *ctrl= _CtrlsUnderPointer[i];
if (ctrl && ctrl->isCapturable() && isControlInWindow(ctrl, pNewCurrentWnd))
{ {
uint d = getDepth(ctrl , pNewCurrentWnd); runActionHandler(clickedOutModalWindow->OnPostClickOut, _CapturePointerRight, clickedOutModalWindow->OnPostClickOutParams);
if (d > nMaxDepth)
{
nMaxDepth = d;
_CapturePointerRight = ctrl;
}
} }
} }
notifyElementCaptured(_CapturePointerRight); //if found
if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty()) if (_CapturePointerRight != NULL)
{ {
runActionHandler(clickedOutModalWindow->OnPostClickOut, _CapturePointerRight, clickedOutModalWindow->OnPostClickOutParams); // handle the capture
handled |= _CapturePointerRight->handleEvent(event);
} }
} }
//if found if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup)
if (_CapturePointerRight != NULL)
{ {
// handle the capture if (!handled)
handled |= _CapturePointerRight->handleEvent(event); if (pNewCurrentWnd != NULL)
pNewCurrentWnd->handleEvent(event);
if (_CapturePointerRight != NULL)
{
EventsListener.addUIHandledButtonMask(rightButton); // prevent 'click in scene' as mouse was previously captured
// (more a patch that anything, but 'UserControls' test for 'mouse up'
// directly later in the main loop (not through message queue), so it has no way of knowing that the event was handled...
setCapturePointerRight(NULL);
handled= true;
}
} }
}
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup) // window handling. if not handled by a control
{
if (!handled) if (!handled)
if (pNewCurrentWnd != NULL)
pNewCurrentWnd->handleEvent(event);
if (_CapturePointerRight != NULL)
{ {
EventsListener.addUIHandledButtonMask(rightButton); // prevent 'click in scene' as mouse was previously captured if (((pNewCurrentWnd != NULL) && _ModalStack.empty()) || ((!_ModalStack.empty() && _ModalStack.back().ModalWindow == pNewCurrentWnd)))
// (more a patch that anything, but 'UserControls' test for 'mouse up'
// directly later in the main loop (not through message queue), so it has no way of knowing that the event was handled...
setCapturePointerRight(NULL);
handled= true;
}
}
// window handling. if not handled by a control
if (!handled)
{
if (((pNewCurrentWnd != NULL) && _ModalStack.empty()) || ((!_ModalStack.empty() && _ModalStack.back().ModalWindow == pNewCurrentWnd)))
{
NLGUI::CEventDescriptorMouse ev2 = eventDesc;
sint32 x= eventDesc.getX(), y = eventDesc.getY();
if (pNewCurrentWnd)
{ {
pNewCurrentWnd->absoluteToRelative (x, y); NLGUI::CEventDescriptorMouse ev2 = eventDesc;
ev2.setX (x); ev2.setY (y); sint32 x= eventDesc.getX(), y = eventDesc.getY();
handled|= pNewCurrentWnd->handleEvent (ev2); if (pNewCurrentWnd)
{
pNewCurrentWnd->absoluteToRelative (x, y);
ev2.setX (x); ev2.setY (y);
handled|= pNewCurrentWnd->handleEvent (ev2);
}
// After handle event of a left click, may set window Top if movable (infos etc...)
//if( (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown) && pNewCurrentWnd->isMovable() )
// setTopWindow(pNewCurrentWnd);
}
}
// Put here to let a chance to the window to handle if the capture dont
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup)
{
if (_CapturePointerLeft != NULL)
{
EventsListener.addUIHandledButtonMask (leftButton); // prevent 'click in scene' as mouse was previously captured
// (more a patch that anything, but 'UserControls' test for 'mouse up'
// directly later in the main loop (not through message queue), so it has no way of knowing that the event was handled...
setCapturePointerLeft(NULL);
//handled= true;
}
}
// If the current window is the modal, may Modal quit. Do it after standard event handle
if(!_ModalStack.empty() && pNewCurrentWnd == _ModalStack.back().ModalWindow)
{
// NB: don't force handle==true because to quit a modal does not avoid other actions
CModalWndInfo mwi = _ModalStack.back();
// and if must quit on click right
if(mwi.ModalExitClickR)
{
// quit if click right
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup)
// disable the modal
disableModalWindow();
} }
// After handle event of a left click, may set window Top if movable (infos etc...) // and if must quit on click left
//if( (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown) && pNewCurrentWnd->isMovable() ) if(mwi.ModalExitClickL)
// setTopWindow(pNewCurrentWnd); {
// quit if click right
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup)
// disable the modal
disableModalWindow();
}
} }
// If the mouse is over a window, always consider the event is taken (avoid click behind)
handled|= _MouseOverWindow;
} }
// Put here to let a chance to the window to handle if the capture dont
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup)
{
if (_CapturePointerLeft != NULL)
{
EventsListener.addUIHandledButtonMask (leftButton); // prevent 'click in scene' as mouse was previously captured
// (more a patch that anything, but 'UserControls' test for 'mouse up'
// directly later in the main loop (not through message queue), so it has no way of knowing that the event was handled...
setCapturePointerLeft(NULL);
//handled= true;
}
}
// If the current window is the modal, may Modal quit. Do it after standard event handle
if(!_ModalStack.empty() && pNewCurrentWnd == _ModalStack.back().ModalWindow)
{
// NB: don't force handle==true because to quit a modal does not avoid other actions
CModalWndInfo mwi = _ModalStack.back();
// and if must quit on click right
if(mwi.ModalExitClickR)
{
// quit if click right
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup)
// disable the modal
disableModalWindow();
}
// and if must quit on click left
if(mwi.ModalExitClickL)
{
// quit if click right
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup)
// disable the modal
disableModalWindow();
}
}
// If the mouse is over a window, always consider the event is taken (avoid click behind)
handled|= _MouseOverWindow;
} }
IngameDbMngr.flushObserverCalls(); IngameDbMngr.flushObserverCalls();
@ -3064,6 +3103,36 @@ bool CInterfaceManager::handleEvent (const NLGUI::CEventDescriptor& event)
return handled; return handled;
} }
bool CInterfaceManager::handleMouseMoveEvent( const NLGUI::CEventDescriptor &eventDesc )
{
nlassert( eventDesc.getType() == NLGUI::CEventDescriptor::mouse );
const NLGUI::CEventDescriptorMouse &e = static_cast< const NLGUI::CEventDescriptorMouse& >( eventDesc );
nlassert( e.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousemove );
uint32 screenW, screenH;
_ViewRenderer.getScreenSize( screenW, screenH );
sint32 oldX = _Pointer->getX();
sint32 oldY = _Pointer->getY();
sint32 x = e.getX();
sint32 y = e.getY();
// These are floats packed in the sint32 from the NEL events that provide them as float
// see comment in CInputHandler::handleMouseMoveEvent
sint32 newX = static_cast< sint32 >( std::floor( *reinterpret_cast< float* >( &x ) * screenW + 0.5f ) );
sint32 newY = static_cast< sint32 >( std::floor( *reinterpret_cast< float* >( &y ) * screenH + 0.5f ) );
if( ( oldX != newX ) || ( oldY != newY ) )
{
movePointerAbs( newX, newY );
NLGUI::CEventDescriptorMouse &ve = const_cast< NLGUI::CEventDescriptorMouse& >( e );
ve.setX( _Pointer->getX() );
ve.setY( _Pointer->getY() );
}
return true;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void CInterfaceManager::movePointer (sint32 dx, sint32 dy) void CInterfaceManager::movePointer (sint32 dx, sint32 dy)
{ {

View file

@ -42,6 +42,8 @@
#include "interface_pointer.h" #include "interface_pointer.h"
#include "flying_text_manager.h" #include "flying_text_manager.h"
#include "nel/gui/input_event_listener.h"
// CLIENT // CLIENT
#include "../string_manager_client.h" #include "../string_manager_client.h"
#include "yubo_chat.h" #include "yubo_chat.h"
@ -75,7 +77,7 @@ class CGroupMenu;
* \author Nevrax France * \author Nevrax France
* \date 2002 * \date 2002
*/ */
class CInterfaceManager : public CInterfaceParser, public NLMISC::CCDBManager class CInterfaceManager : public CInterfaceParser, public NLMISC::CCDBManager, public NLGUI::IInputEventListener
{ {
public: public:
@ -339,6 +341,7 @@ public:
/// Handle The Event. return true if the interfaceManager catch it and if must not send to the Game Action Manager /// Handle The Event. return true if the interfaceManager catch it and if must not send to the Game Action Manager
bool handleEvent (const NLGUI::CEventDescriptor &eventDesc); bool handleEvent (const NLGUI::CEventDescriptor &eventDesc);
bool handleMouseMoveEvent( const NLGUI::CEventDescriptor &eventDesc );
void runActionHandler (const std::string &AHName, CCtrlBase *pCaller, void runActionHandler (const std::string &AHName, CCtrlBase *pCaller,
const std::string &Params=std::string("")); const std::string &Params=std::string(""));
void runActionHandler (IActionHandler *ah, CCtrlBase *pCaller, void runActionHandler (IActionHandler *ah, CCtrlBase *pCaller,