CHANGED: #1471 Moved the input event handling code from CInterfaceManager to CWidgetManager.

This commit is contained in:
dfighter1985 2012-07-11 06:44:34 +02:00
parent 86302f6a39
commit 6506989e14
9 changed files with 549 additions and 510 deletions

View file

@ -147,6 +147,9 @@ namespace NLGUI
virtual bool getMouseOverShape(std::string &/* texName */, uint8 &/* rot */, NLMISC::CRGBA &/* col */) { return false; } virtual bool getMouseOverShape(std::string &/* texName */, uint8 &/* rot */, NLMISC::CRGBA &/* col */) { return false; }
virtual void serial(NLMISC::IStream &f); virtual void serial(NLMISC::IStream &f);
uint32 getDepth( CInterfaceGroup *group );
protected: protected:
// This is the ContextHelp filled by default in parse() // This is the ContextHelp filled by default in parse()
ucstring _ContextHelp; ucstring _ContextHelp;

View file

@ -456,6 +456,8 @@ namespace NLGUI
return ""; return "";
} }
bool isInGroup( CInterfaceGroup *group );
protected: protected:
///the parent ///the parent

View file

@ -26,6 +26,7 @@
#include "nel/misc/types_nl.h" #include "nel/misc/types_nl.h"
#include "nel/gui/interface_common.h" #include "nel/gui/interface_common.h"
#include "nel/gui/interface_options.h" #include "nel/gui/interface_options.h"
#include "nel/gui/event_descriptor.h"
#include "nel/3d/u_camera.h" #include "nel/3d/u_camera.h"
namespace NLMISC namespace NLMISC
@ -317,6 +318,10 @@ namespace NLGUI
void drawViews( NL3D::UCamera camera ); void drawViews( NL3D::UCamera camera );
bool handleEvent( const CEventDescriptor &eventDesc );
bool handleMouseMoveEvent( const CEventDescriptor &eventDesc );
// Relative move of pointer // Relative move of pointer
void movePointer (sint32 dx, sint32 dy); void movePointer (sint32 dx, sint32 dy);
// Set absolute coordinates of pointer // Set absolute coordinates of pointer
@ -380,6 +385,8 @@ namespace NLGUI
// Enable mouse Events to interface. if false, release Captures. // Enable mouse Events to interface. if false, release Captures.
void enableMouseHandling( bool handle ); void enableMouseHandling( bool handle );
bool isMouseHandlingEnabled() const{ return _MouseHandlingEnabled; } bool isMouseHandlingEnabled() const{ return _MouseHandlingEnabled; }
bool isMouseOverWindow() const{ return _MouseOverWindow; }
void setMouseOverWindow( bool b ){ _MouseOverWindow = b; }
// Get the User DblClick Delay (according to save...), in milisecond // Get the User DblClick Delay (according to save...), in milisecond
uint getUserDblClickDelay(); uint getUserDblClickDelay();
@ -513,6 +520,8 @@ namespace NLGUI
bool _ContextHelpActive; bool _ContextHelpActive;
bool inGame; bool inGame;
bool _MouseOverWindow;
uint32 screenH; uint32 screenH;
uint32 screenW; uint32 screenW;

View file

@ -223,5 +223,22 @@ namespace NLGUI
return "context_help"; return "context_help";
} }
uint32 CCtrlBase::getDepth( CInterfaceGroup *group )
{
uint32 depth = 1;
CInterfaceGroup *parent = getParent();
while( parent != NULL )
{
if ( parent == group )
break;
else
parent = parent->getParent();
depth++;
}
// The Resizer Ctrls take the precedence over Sons controls.
return depth + getDeltaDepth();
}
} }

View file

@ -1257,6 +1257,19 @@ namespace NLGUI
} }
} }
bool CInterfaceElement::isInGroup( CInterfaceGroup *group )
{
CInterfaceGroup *parent = getParent();
while( parent != NULL )
{
if( parent == group )
return true;
else
parent = parent->getParent();
}
return false;
}
} }

View file

@ -17,7 +17,7 @@
#include "nel/gui/db_manager.h" #include "nel/gui/db_manager.h"
#include "nel/gui/view_renderer.h" #include "nel/gui/view_renderer.h"
#include "nel/gui/widget_manager.h" #include "nel/gui/widget_manager.h"
#include "nel/gui/view_pointer_base.h" #include "nel/gui/view_pointer.h"
#include "nel/gui/ctrl_draggable.h" #include "nel/gui/ctrl_draggable.h"
#include "nel/gui/interface_group.h" #include "nel/gui/interface_group.h"
#include "nel/gui/group_container_base.h" #include "nel/gui/group_container_base.h"
@ -27,6 +27,7 @@
#include "nel/gui/view_text.h" #include "nel/gui/view_text.h"
#include "nel/gui/view_bitmap.h" #include "nel/gui/view_bitmap.h"
#include "nel/gui/group_container.h" #include "nel/gui/group_container.h"
#include "nel/misc/events.h"
namespace NLGUI namespace NLGUI
{ {
@ -42,7 +43,7 @@ namespace
void Hack() void Hack()
{ {
NLGUI::LinkHack(); LinkHack();
} }
} }
@ -385,7 +386,7 @@ namespace NLGUI
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void CWidgetManager::activateMasterGroup (const std::string &sMasterGroupName, bool bActive) void CWidgetManager::activateMasterGroup (const std::string &sMasterGroupName, bool bActive)
{ {
CInterfaceGroup *pIG = CWidgetManager::getInstance()->getMasterGroupFromId (sMasterGroupName); CInterfaceGroup *pIG = getMasterGroupFromId (sMasterGroupName);
if (pIG != NULL) if (pIG != NULL)
{ {
pIG->setActive(bActive); pIG->setActive(bActive);
@ -626,7 +627,7 @@ namespace NLGUI
// disable any context help // disable any context help
setCurContextHelp( NULL ); setCurContextHelp( NULL );
CWidgetManager::getInstance()->_DeltaTimeStopingContextHelp = 0; _DeltaTimeStopingContextHelp = 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -845,7 +846,7 @@ namespace NLGUI
CInterfaceGroup *pIG = *itw; CInterfaceGroup *pIG = *itw;
// Accecpt if not modal clip // Accecpt if not modal clip
if (!CWidgetManager::getInstance()->hasModal() || CWidgetManager::getInstance()->getModal().ModalWindow == pIG || CWidgetManager::getInstance()->getModal().ModalExitClickOut) if (!hasModal() || getModal().ModalWindow == pIG || getModal().ModalExitClickOut)
if (pIG->getActive() && pIG->getUseCursor()) if (pIG->getActive() && pIG->getUseCursor())
{ {
if (pIG->getCtrlsUnder (x, y, 0, 0, (sint32) sw, (sint32) sh, vICL)) if (pIG->getCtrlsUnder (x, y, 0, 0, (sint32) sw, (sint32) sh, vICL))
@ -883,8 +884,8 @@ namespace NLGUI
CInterfaceGroup *pIG = *itw; CInterfaceGroup *pIG = *itw;
// Accecpt if not modal clip // Accecpt if not modal clip
if (!CWidgetManager::getInstance()->hasModal() || CWidgetManager::getInstance()->getModal().ModalWindow == pIG || if (!hasModal() || getModal().ModalWindow == pIG ||
CWidgetManager::getInstance()->getModal().ModalExitClickOut) getModal().ModalExitClickOut)
if (pIG->getActive() && pIG->getUseCursor()) if (pIG->getActive() && pIG->getUseCursor())
{ {
if (pIG->isIn(x, y)) if (pIG->isIn(x, y))
@ -1056,8 +1057,8 @@ namespace NLGUI
} }
} }
if ( CWidgetManager::getInstance()->getPointer() != NULL) if ( getPointer() != NULL)
CWidgetManager::getInstance()->getPointer()->updateCoords(); getPointer()->updateCoords();
} }
@ -1065,7 +1066,7 @@ namespace NLGUI
if (bRecomputeCtrlUnderPtr) if (bRecomputeCtrlUnderPtr)
{ {
H_AUTO ( RZ_Interface_RecomputeCtrlUnderPtr ) H_AUTO ( RZ_Interface_RecomputeCtrlUnderPtr )
if ( CWidgetManager::getInstance()->getPointer() != NULL ) if ( getPointer() != NULL )
{ {
sint32 mx = _Pointer->getX(); sint32 mx = _Pointer->getX();
sint32 my = _Pointer->getY(); sint32 my = _Pointer->getY();
@ -1704,7 +1705,7 @@ namespace NLGUI
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void CWidgetManager::moveAllWindowsToNewScreenSize(sint32 newScreenW, sint32 newScreenH, bool fixCurrentUI) void CWidgetManager::moveAllWindowsToNewScreenSize(sint32 newScreenW, sint32 newScreenH, bool fixCurrentUI)
{ {
std::vector< CWidgetManager::SMasterGroup > &_MasterGroups = CWidgetManager::getInstance()->getAllMasterGroup(); std::vector< CWidgetManager::SMasterGroup > &_MasterGroups = getAllMasterGroup();
// If resolutions correctly setuped, and really different from new setup // If resolutions correctly setuped, and really different from new setup
if( screenW >0 && screenH>0 && if( screenW >0 && screenH>0 &&
newScreenW >0 && newScreenH>0 && newScreenW >0 && newScreenH>0 &&
@ -1749,7 +1750,7 @@ namespace NLGUI
sint32 h= pIG->getH(false); // the window may be hid, still get the correct(or estimated) H sint32 h= pIG->getH(false); // the window may be hid, still get the correct(or estimated) H
// Compute the new coordinate // Compute the new coordinate
CWidgetManager::getInstance()->getNewWindowCoordToNewScreenSize(x, y, w, h, newScreenW, newScreenH); getNewWindowCoordToNewScreenSize(x, y, w, h, newScreenW, newScreenH);
// Change // Change
pIG->setX(x); pIG->setX(x);
@ -1904,10 +1905,10 @@ namespace NLGUI
} }
// Update global color from database // Update global color from database
setGlobalColor( NLMISC::CRGBA ( (uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:R")->getValue32(), setGlobalColor( NLMISC::CRGBA ( (uint8)CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:R")->getValue32(),
(uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:G")->getValue32(), (uint8)CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:G")->getValue32(),
(uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:B")->getValue32(), (uint8)CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:B")->getValue32(),
(uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:A")->getValue32() ) ); (uint8)CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:A")->getValue32() ) );
NLMISC::CRGBA c = getGlobalColorForContent(); NLMISC::CRGBA c = getGlobalColorForContent();
NLMISC::CRGBA gc = getGlobalColor(); NLMISC::CRGBA gc = getGlobalColor();
@ -2001,6 +2002,460 @@ namespace NLGUI
CDBManager::getInstance()->flushObserverCalls(); CDBManager::getInstance()->flushObserverCalls();
} }
bool CWidgetManager::handleEvent( const CEventDescriptor &evnt )
{
if( evnt.getType() == CEventDescriptor::system )
{
const CEventDescriptorSystem &systemEvent = reinterpret_cast< const CEventDescriptorSystem& >( evnt );
if( systemEvent.getEventTypeExtended() == CEventDescriptorSystem::setfocus )
{
if( getCapturePointerLeft() != NULL )
{
getCapturePointerLeft()->handleEvent( evnt );
setCapturePointerLeft( NULL );
}
if( getCapturePointerRight() != NULL )
{
getCapturePointerRight()->handleEvent( evnt );
setCapturePointerRight( NULL );
}
}
}
bool handled = false;
CViewPointer *_Pointer = static_cast< CViewPointer* >( getPointer() );
if (evnt.getType() == CEventDescriptor::key)
{
CEventDescriptorKey &eventDesc = (CEventDescriptorKey&)evnt;
//_LastEventKeyDesc = eventDesc;
// Any Key event disable the ContextHelp
disableContextHelp();
// Hide menu if the key is pushed
// if ((eventDesc.getKeyEventType() == CEventDescriptorKey::keydown) && !_ModalStack.empty() && !eventDesc.getKeyAlt() && !eventDesc.getKeyCtrl() && !eventDesc.getKeyShift())
// Hide menu (or popup menu) is ESCAPE pressed
if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyESCAPE )
{
if( hasModal() )
{
SModalWndInfo mwi = getModal();
if (mwi.ModalExitKeyPushed)
disableModalWindow();
}
}
// Manage "quit window" If the Key is ESCAPE, no captureKeyboard
if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyESCAPE )
{
// Get the last escapable active top window. NB: this is ergonomically better.
CInterfaceGroup *win= getLastEscapableTopWindow();
if( win )
{
// If the window is a modal, must pop it.
if( dynamic_cast<CGroupModal*>(win) )
{
if(!win->getAHOnEscape().empty())
CAHManager::getInstance()->runActionHandler(win->getAHOnEscape(), win, win->getAHOnEscapeParams());
popModalWindow();
handled= true;
}
// else just disable it.
// Special case: leave the escape Key to the CaptureKeyboard .
else if( !getCaptureKeyboard() )
{
if(!win->getAHOnEscape().empty())
CAHManager::getInstance()->runActionHandler(win->getAHOnEscape(), win, win->getAHOnEscapeParams());
win->setActive(false);
handled= true;
}
}
}
// Manage complex "Enter"
if (eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyRETURN)
{
// If the top window has Enter AH
CInterfaceGroup *tw= getTopWindow();
if(tw && !tw->getAHOnEnter().empty())
{
// if the captured keyboard is in this Modal window, then must handle him in priority
if( getCaptureKeyboard() && getCaptureKeyboard()->getRootWindow()==tw)
{
bool result = getCaptureKeyboard()->handleEvent(evnt);
CDBManager::getInstance()->flushObserverCalls();
return result;
}
else
{
// The window or modal control the OnEnter. Execute, and don't go to the chat.
CAHManager::getInstance()->runActionHandler(tw->getAHOnEnter(), tw, tw->getAHOnEnterParams());
handled= true;
}
}
// else the 'return' key bring back to the last edit box (if possible)
CCtrlBase *oldCapture = getOldCaptureKeyboard() ? getOldCaptureKeyboard() : getDefaultCaptureKeyboard();
if ( getCaptureKeyboard() == NULL && oldCapture && !handled)
{
/* If the editbox does not want to recover focus, then abort. This possibility is normaly avoided
through setCaptureKeyboard() which already test getRecoverFocusOnEnter(), but it is still possible
for the default capture (main chat) or the old captured window to not want to recover
(temporary Read Only chat for instance)
*/
if(!dynamic_cast<CGroupEditBoxBase*>(oldCapture) ||
dynamic_cast<CGroupEditBoxBase*>(oldCapture)->getRecoverFocusOnEnter())
{
setCaptureKeyboard( oldCapture );
notifyElementCaptured(getCaptureKeyboard() );
// make sure all parent windows are active
CCtrlBase *cb = getCaptureKeyboard();
CGroupContainer *lastContainer = NULL;
for(;;)
{
CGroupContainer *gc = dynamic_cast<CGroupContainer *>(cb);
if (gc) lastContainer = gc;
cb->forceOpen();
if (cb->getParent())
{
cb = cb->getParent();
}
else
{
cb->invalidateCoords();
break;
}
}
if (lastContainer)
{
setTopWindow(lastContainer);
lastContainer->enableBlink(1);
}
handled= true;
}
}
}
// General case: handle it in the Captured keyboard
if ( getCaptureKeyboard() != NULL && !handled)
{
bool result = getCaptureKeyboard()->handleEvent(evnt);
CDBManager::getInstance()->flushObserverCalls();
return result;
}
}
//////////////////////////////////////////////// Keyboard handling ends here ////////////////////////////////////
else if (evnt.getType() == CEventDescriptor::mouse )
{
CEventDescriptorMouse &eventDesc = (CEventDescriptorMouse&)evnt;
if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown )
_Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() | NLMISC::leftButton ) );
else
if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown )
_Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() | NLMISC::rightButton ) );
else
if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup )
_Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() & ~NLMISC::leftButton ) );
if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup )
_Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() & ~NLMISC::rightButton ) );
if( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mousemove )
handleMouseMoveEvent( eventDesc );
eventDesc.setX( _Pointer->getX() );
eventDesc.setY( _Pointer->getY() );
if( isMouseHandlingEnabled() )
{
// First thing to do : Capture handling
if ( getCapturePointerLeft() != NULL)
handled|= getCapturePointerLeft()->handleEvent(evnt);
if ( getCapturePointerRight() != NULL &&
getCapturePointerLeft() != getCapturePointerRight() )
handled|= getCapturePointerRight()->handleEvent(evnt);
CInterfaceGroup *ptr = getWindowUnder (eventDesc.getX(), eventDesc.getY());
setCurrentWindowUnder( ptr );
// Any Mouse event but move disable the ContextHelp
if(eventDesc.getEventTypeExtended() != CEventDescriptorMouse::mousemove)
{
disableContextHelp();
}
// get the group under the mouse
CInterfaceGroup *pNewCurrentWnd = getCurrentWindowUnder();
setMouseOverWindow( pNewCurrentWnd != NULL );
NLMISC::CRefPtr<CGroupModal> clickedOutModalWindow;
// modal special features
if ( hasModal() )
{
CWidgetManager::SModalWndInfo mwi = getModal();
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)
{
pNewCurrentWnd = NULL;
}
else
{
// If there is a handler on click out launch it
if (pNewCurrentWnd != mwi.ModalWindow)
if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown ||
(eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown))
if (!mwi.ModalHandlerClickOut.empty())
CAHManager::getInstance()->runActionHandler(mwi.ModalHandlerClickOut,NULL,mwi.ModalClickOutParams);
// If the current window is not the modal and if must quit on click out
if(pNewCurrentWnd != mwi.ModalWindow && mwi.ModalExitClickOut)
{
// NB: don't force handle==true because to quit a modal does not avoid other actions
// quit if click outside
if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown ||
(eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown))
{
clickedOutModalWindow = dynamic_cast<CGroupModal *>((CInterfaceGroup*)mwi.ModalWindow);
// disable the modal
popModalWindow();
if ( hasModal() )
{
// don't handle event unless it is a previous modal window
if( !isPreviousModal( pNewCurrentWnd ) )
pNewCurrentWnd = NULL; // can't handle event before we have left all modal windows
}
movePointer (0,0); // Reget controls under pointer
}
}
}
}
}
// Manage LeftClick.
if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown)
{
if ((pNewCurrentWnd != NULL) && (!hasModal()) && (pNewCurrentWnd->getOverlappable()))
{
CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(pNewCurrentWnd);
if (pGC != NULL)
{
if (!pGC->isGrayed()) setTopWindow(pNewCurrentWnd);
}
else
{
setTopWindow(pNewCurrentWnd);
}
}
// 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 (!CCtrlDraggable::getDraggedSheet())
{
// Take the top most control.
uint nMaxDepth = 0;
const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer();
for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--)
{
CCtrlBase *ctrl= _CtrlsUnderPointer[i];
if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) )
{
uint d = ctrl->getDepth( pNewCurrentWnd );
if (d > nMaxDepth)
{
nMaxDepth = d;
setCapturePointerLeft( ctrl );
}
}
}
notifyElementCaptured( getCapturePointerLeft() );
if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty())
{
CAHManager::getInstance()->runActionHandler(clickedOutModalWindow->OnPostClickOut, getCapturePointerLeft(), clickedOutModalWindow->OnPostClickOutParams);
}
}
//if found
if ( getCapturePointerLeft() != NULL)
{
// consider clicking on a control implies handling of the event.
handled= true;
// handle the capture
getCapturePointerLeft()->handleEvent(evnt);
}
}
// Manage RightClick
if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown)
{
if ((pNewCurrentWnd != NULL) && (!hasModal()) && (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;
const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer();
for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--)
{
CCtrlBase *ctrl= _CtrlsUnderPointer[i];
if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) )
{
uint d = ctrl->getDepth( pNewCurrentWnd );
if (d > nMaxDepth)
{
nMaxDepth = d;
setCapturePointerRight( ctrl );
}
}
}
notifyElementCaptured( getCapturePointerRight() );
if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty())
{
CAHManager::getInstance()->runActionHandler(clickedOutModalWindow->OnPostClickOut, getCapturePointerRight(), clickedOutModalWindow->OnPostClickOutParams);
}
}
//if found
if ( getCapturePointerRight() != NULL)
{
// handle the capture
handled |= getCapturePointerRight()->handleEvent(evnt);
}
}
if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup)
{
if (!handled)
if (pNewCurrentWnd != NULL)
pNewCurrentWnd->handleEvent(evnt);
if ( getCapturePointerRight() != NULL)
{
setCapturePointerRight(NULL);
handled= true;
}
}
// window handling. if not handled by a control
if (!handled)
{
if (((pNewCurrentWnd != NULL) && !hasModal()) ||
((hasModal() && getModal().ModalWindow == pNewCurrentWnd)))
{
CEventDescriptorMouse ev2 = eventDesc;
sint32 x= eventDesc.getX(), y = eventDesc.getY();
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() == CEventDescriptorMouse::mouseleftdown) && pNewCurrentWnd->isMovable() )
// setTopWindow(pNewCurrentWnd);
}
}
// Put here to let a chance to the window to handle if the capture dont
if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup)
{
if ( getCapturePointerLeft() != NULL)
{
setCapturePointerLeft(NULL);
handled = true;
}
}
// If the current window is the modal, may Modal quit. Do it after standard event handle
if(hasModal() && pNewCurrentWnd == getModal().ModalWindow)
{
// NB: don't force handle==true because to quit a modal does not avoid other actions
CWidgetManager::SModalWndInfo mwi = getModal();
// and if must quit on click right
if(mwi.ModalExitClickR)
{
// quit if click right
if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup)
// disable the modal
disableModalWindow();
}
// and if must quit on click left
if(mwi.ModalExitClickL)
{
// quit if click right
if (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup)
// disable the modal
disableModalWindow();
}
}
// If the mouse is over a window, always consider the event is taken (avoid click behind)
handled|= isMouseOverWindow();
}
}
CDBManager::getInstance()->flushObserverCalls();
return handled;
}
bool CWidgetManager::handleMouseMoveEvent( const CEventDescriptor &eventDesc )
{
if( eventDesc.getType() != CEventDescriptor::mouse )
return false;
const CEventDescriptorMouse &e = static_cast< const CEventDescriptorMouse& >( eventDesc );
if( e.getEventTypeExtended() != CEventDescriptorMouse::mousemove )
return false;
uint32 screenW, screenH;
CViewRenderer::getInstance()->getScreenSize( screenW, screenH );
sint32 oldX = getPointer()->getX();
sint32 oldY = getPointer()->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 );
CEventDescriptorMouse &ve = const_cast< CEventDescriptorMouse& >( e );
ve.setX( getPointer()->getX() );
ve.setY( getPointer()->getY() );
}
return true;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void CWidgetManager::movePointer (sint32 dx, sint32 dy) void CWidgetManager::movePointer (sint32 dx, sint32 dy)
@ -2044,7 +2499,7 @@ namespace NLGUI
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void CWidgetManager::movePointerAbs(sint32 px, sint32 py) void CWidgetManager::movePointerAbs(sint32 px, sint32 py)
{ {
if(!CWidgetManager::getInstance()->getPointer()) if(!getPointer())
return; return;
uint32 nScrW, nScrH; uint32 nScrW, nScrH;
@ -2151,8 +2606,8 @@ namespace NLGUI
void CWidgetManager::sendClockTickEvent() void CWidgetManager::sendClockTickEvent()
{ {
NLGUI::CEventDescriptorSystem clockTick; CEventDescriptorSystem clockTick;
clockTick.setEventTypeExtended(NLGUI::CEventDescriptorSystem::clocktick); clockTick.setEventTypeExtended(CEventDescriptorSystem::clocktick);
if (_CapturePointerLeft) if (_CapturePointerLeft)
{ {
@ -2267,10 +2722,10 @@ namespace NLGUI
{ {
if (!_RProp) if (!_RProp)
{ {
_RProp = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:R"); _RProp = CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:R");
_GProp = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:G"); _GProp = CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:G");
_BProp = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:B"); _BProp = CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:B");
_AProp = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:A"); _AProp = CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:A");
} }
_RProp ->setValue32 (col.R); _RProp ->setValue32 (col.R);
_GProp ->setValue32 (col.G); _GProp ->setValue32 (col.G);
@ -2352,7 +2807,7 @@ namespace NLGUI
uint CWidgetManager::getUserDblClickDelay() uint CWidgetManager::getUserDblClickDelay()
{ {
uint nVal = 50; uint nVal = 50;
NLMISC::CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:DOUBLE_CLICK_SPEED"); NLMISC::CCDBNodeLeaf *pNL = CDBManager::getInstance()->getDbProp("UI:SAVE:DOUBLE_CLICK_SPEED");
if( pNL != NULL ) if( pNL != NULL )
nVal = pNL->getValue32(); nVal = pNL->getValue32();
@ -2390,7 +2845,7 @@ namespace NLGUI
float CWidgetManager::getAlphaRolloverSpeed() float CWidgetManager::getAlphaRolloverSpeed()
{ {
if( _AlphaRolloverSpeedDB == NULL ) if( _AlphaRolloverSpeedDB == NULL )
_AlphaRolloverSpeedDB = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:ALPHA_ROLLOVER_SPEED"); _AlphaRolloverSpeedDB = CDBManager::getInstance()->getDbProp("UI:SAVE:ALPHA_ROLLOVER_SPEED");
float fTmp = ROLLOVER_MIN_DELTA_PER_MS + (ROLLOVER_MAX_DELTA_PER_MS - ROLLOVER_MIN_DELTA_PER_MS) * 0.01f * (100 - _AlphaRolloverSpeedDB->getValue32()); float fTmp = ROLLOVER_MIN_DELTA_PER_MS + (ROLLOVER_MAX_DELTA_PER_MS - ROLLOVER_MIN_DELTA_PER_MS) * 0.01f * (100 - _AlphaRolloverSpeedDB->getValue32());
return fTmp*fTmp*fTmp; return fTmp*fTmp*fTmp;
} }
@ -2411,10 +2866,10 @@ namespace NLGUI
void CWidgetManager::updateGlobalAlphas() void CWidgetManager::updateGlobalAlphas()
{ {
_GlobalContentAlpha = (uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CONTENT_ALPHA")->getValue32(); _GlobalContentAlpha = (uint8)CDBManager::getInstance()->getDbProp("UI:SAVE:CONTENT_ALPHA")->getValue32();
_GlobalContainerAlpha = (uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CONTAINER_ALPHA")->getValue32(); _GlobalContainerAlpha = (uint8)CDBManager::getInstance()->getDbProp("UI:SAVE:CONTAINER_ALPHA")->getValue32();
_GlobalRolloverFactorContent = (uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CONTENT_ROLLOVER_FACTOR")->getValue32(); _GlobalRolloverFactorContent = (uint8)CDBManager::getInstance()->getDbProp("UI:SAVE:CONTENT_ROLLOVER_FACTOR")->getValue32();
_GlobalRolloverFactorContainer = (uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CONTAINER_ROLLOVER_FACTOR")->getValue32(); _GlobalRolloverFactorContainer = (uint8)CDBManager::getInstance()->getDbProp("UI:SAVE:CONTAINER_ROLLOVER_FACTOR")->getValue32();
} }
void CWidgetManager::registerNewScreenSizeHandler( INewScreenSizeHandler *handler ) void CWidgetManager::registerNewScreenSizeHandler( INewScreenSizeHandler *handler )
@ -2484,6 +2939,7 @@ namespace NLGUI
_AlphaRolloverSpeedDB = NULL; _AlphaRolloverSpeedDB = NULL;
_MouseHandlingEnabled = true; _MouseHandlingEnabled = true;
_MouseOverWindow = false;
inGame = false; inGame = false;
setScreenWH( 0, 0 ); setScreenWH( 0, 0 );

View file

@ -468,7 +468,6 @@ CInterfaceManager::CInterfaceManager( NL3D::UDriver *driver, NL3D::UTextContext
_ScreenW = _ScreenH = 0; _ScreenW = _ScreenH = 0;
_LastInGameScreenW = _LastInGameScreenH = 0; _LastInGameScreenW = _LastInGameScreenH = 0;
_DescTextTarget = NULL; _DescTextTarget = NULL;
_MouseOverWindow= false;
_ConfigLoaded = false; _ConfigLoaded = false;
_LogState = false; _LogState = false;
_KeysLoaded = false; _KeysLoaded = false;
@ -1976,498 +1975,46 @@ void CInterfaceManager::drawViews(NL3D::UCamera camera)
} }
// ------------------------------------------------------------------------------------------------
bool CInterfaceManager::isControlInWindow (CCtrlBase *ctrl, CInterfaceGroup *pNewCurrentWnd)
{
// We don't want to capture control if they are not owned by the top most window selected.
// Check all the parent of the control, one must be pNewCurrentWnd, else NULL
CInterfaceGroup *parent= ctrl->getParent();
while(parent!=NULL)
{
if(parent==pNewCurrentWnd)
return true;
else
parent= parent->getParent();
}
// not found => must not capture it
return false;
}
// ------------------------------------------------------------------------------------------------
uint CInterfaceManager::getDepth (CCtrlBase *ctrl, CInterfaceGroup *pNewCurrentWnd)
{
uint depth = 1;
CInterfaceGroup *parent= ctrl->getParent();
while (parent != NULL)
{
if (parent == pNewCurrentWnd)
break;
else
parent = parent->getParent();
depth++;
}
// The Resizer Ctrls take the precedence over Sons controls.
return depth + ctrl->getDeltaDepth();
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool CInterfaceManager::handleEvent (const NLGUI::CEventDescriptor& event) bool CInterfaceManager::handleEvent (const NLGUI::CEventDescriptor& event)
{ {
bool handled= false;
CViewPointer *_Pointer = static_cast< CViewPointer* >( CWidgetManager::getInstance()->getPointer() );
if( event.getType() == NLGUI::CEventDescriptor::system )
{
const NLGUI::CEventDescriptorSystem &eventDesc = reinterpret_cast< const NLGUI::CEventDescriptorSystem& >( event );
if( eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorSystem::setfocus )
{
if( CWidgetManager::getInstance()->getCapturePointerLeft() != NULL )
{
CWidgetManager::getInstance()->getCapturePointerLeft()->handleEvent( event );
CWidgetManager::getInstance()->setCapturePointerLeft( NULL );
}
if( CWidgetManager::getInstance()->getCapturePointerRight() != NULL )
{
CWidgetManager::getInstance()->getCapturePointerRight()->handleEvent( event );
CWidgetManager::getInstance()->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())
return false; return false;
if (event.getType() == NLGUI::CEventDescriptor::key) bool handled = false;
{
NLGUI::CEventDescriptorKey &eventDesc = (NLGUI::CEventDescriptorKey&)event;
_LastEventKeyDesc = eventDesc;
// Any Key event disable the ContextHelp handled = CWidgetManager::getInstance()->handleEvent( event );
CWidgetManager::getInstance()->disableContextHelp();
// Hide menu if the key is pushed if( event.getType() == NLGUI::CEventDescriptor::mouse )
// if ((eventDesc.getKeyEventType() == NLGUI::CEventDescriptorKey::keydown) && !_ModalStack.empty() && !eventDesc.getKeyAlt() && !eventDesc.getKeyCtrl() && !eventDesc.getKeyShift())
// Hide menu (or popup menu) is ESCAPE pressed
if( eventDesc.getKeyEventType() == NLGUI::CEventDescriptorKey::keychar && eventDesc.getChar() == KeyESCAPE )
{
if( CWidgetManager::getInstance()->hasModal() )
{
CWidgetManager::SModalWndInfo mwi = CWidgetManager::getInstance()->getModal();
if (mwi.ModalExitKeyPushed)
CWidgetManager::getInstance()->disableModalWindow();
}
}
// Manage "quit window" If the Key is ESCAPE, no captureKeyboard
if( eventDesc.getKeyEventType() == NLGUI::CEventDescriptorKey::keychar && eventDesc.getChar() == KeyESCAPE )
{
// Get the last escapable active top window. NB: this is ergonomically better.
CInterfaceGroup *win= CWidgetManager::getInstance()->getLastEscapableTopWindow();
if( win )
{
// If the window is a modal, must pop it.
if( dynamic_cast<CGroupModal*>(win) )
{
if(!win->getAHOnEscape().empty())
CAHManager::getInstance()->runActionHandler(win->getAHOnEscape(), win, win->getAHOnEscapeParams());
CWidgetManager::getInstance()->popModalWindow();
handled= true;
}
// else just disable it.
// Special case: leave the escape Key to the CaptureKeyboard .
else if(! CWidgetManager::getInstance()->getCaptureKeyboard() )
{
if(!win->getAHOnEscape().empty())
CAHManager::getInstance()->runActionHandler(win->getAHOnEscape(), win, win->getAHOnEscapeParams());
win->setActive(false);
handled= true;
}
}
}
// Manage complex "Enter"
if (eventDesc.getKeyEventType() == NLGUI::CEventDescriptorKey::keychar && eventDesc.getChar() == KeyRETURN)
{
// If the top window has Enter AH
CInterfaceGroup *tw= CWidgetManager::getInstance()->getTopWindow();
if(tw && !tw->getAHOnEnter().empty())
{
// if the captured keyboard is in this Modal window, then must handle him in priority
if( CWidgetManager::getInstance()->getCaptureKeyboard() && CWidgetManager::getInstance()->getCaptureKeyboard()->getRootWindow()==tw)
{
bool result = CWidgetManager::getInstance()->getCaptureKeyboard()->handleEvent(event);
IngameDbMngr.flushObserverCalls();
NLGUI::CDBManager::getInstance()->flushObserverCalls();
return result;
}
else
{
// The window or modal control the OnEnter. Execute, and don't go to the chat.
CAHManager::getInstance()->runActionHandler(tw->getAHOnEnter(), tw, tw->getAHOnEnterParams());
handled= true;
}
}
// else the 'return' key bring back to the last edit box (if possible)
CCtrlBase *oldCapture = CWidgetManager::getInstance()->getOldCaptureKeyboard() ? CWidgetManager::getInstance()->getOldCaptureKeyboard() : CWidgetManager::getInstance()->getDefaultCaptureKeyboard();
if ( CWidgetManager::getInstance()->getCaptureKeyboard() == NULL && oldCapture && !handled)
{
/* If the editbox does not want to recover focus, then abort. This possibility is normaly avoided
through setCaptureKeyboard() which already test getRecoverFocusOnEnter(), but it is still possible
for the default capture (main chat) or the old captured window to not want to recover
(temporary Read Only chat for instance)
*/
if(!dynamic_cast<CGroupEditBox*>(oldCapture) ||
dynamic_cast<CGroupEditBox*>(oldCapture)->getRecoverFocusOnEnter())
{
CWidgetManager::getInstance()->setCaptureKeyboard( oldCapture );
CWidgetManager::getInstance()->notifyElementCaptured( CWidgetManager::getInstance()->getCaptureKeyboard() );
// make sure all parent windows are active
CCtrlBase *cb = CWidgetManager::getInstance()->getCaptureKeyboard();
CGroupContainer *lastContainer = NULL;
for(;;)
{
CGroupContainer *gc = dynamic_cast<CGroupContainer *>(cb);
if (gc) lastContainer = gc;
cb->forceOpen();
if (cb->getParent())
{
cb = cb->getParent();
}
else
{
cb->invalidateCoords();
break;
}
}
if (lastContainer)
{
CWidgetManager::getInstance()->setTopWindow(lastContainer);
lastContainer->enableBlink(1);
}
handled= true;
}
}
}
// General case: handle it in the Captured keyboard
if ( CWidgetManager::getInstance()->getCaptureKeyboard() != NULL && !handled)
{
bool result = CWidgetManager::getInstance()->getCaptureKeyboard()->handleEvent(event);
IngameDbMngr.flushObserverCalls();
NLGUI::CDBManager::getInstance()->flushObserverCalls();
return result;
}
}
else if (event.getType() == NLGUI::CEventDescriptor::mouse )
{ {
NLGUI::CEventDescriptorMouse &eventDesc = (NLGUI::CEventDescriptorMouse&)event; NLGUI::CEventDescriptorMouse &eventDesc = (NLGUI::CEventDescriptorMouse&)event;
if( eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown ) if( ( eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup ) && handled )
_Pointer->setButtonState( static_cast< NLMISC::TMouseButton >( _Pointer->getButtonState() | NLMISC::leftButton ) );
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( eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousemove )
handleMouseMoveEvent( eventDesc );
eventDesc.setX( _Pointer->getX() );
eventDesc.setY( _Pointer->getY() );
if( CWidgetManager::getInstance()->isMouseHandlingEnabled() )
{ {
// First thing to do : Capture handling // prevent 'click in scene' as mouse was previously captured
if ( CWidgetManager::getInstance()->getCapturePointerLeft() != NULL) // (more a patch that anything, but 'UserControls' test for 'mouse up'
handled|= CWidgetManager::getInstance()->getCapturePointerLeft()->handleEvent(event); // directly later in the main loop (not through message queue), so it has no way of knowing that the event was handled...
if( CWidgetManager::getInstance()->getCapturePointerRight() == NULL )
if ( CWidgetManager::getInstance()->getCapturePointerRight() != NULL && EventsListener.addUIHandledButtonMask(rightButton);
CWidgetManager::getInstance()->getCapturePointerLeft() != CWidgetManager::getInstance()->getCapturePointerRight() ) }else
handled|= CWidgetManager::getInstance()->getCapturePointerRight()->handleEvent(event); if( ( eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup ) && handled )
{
CInterfaceGroup *ptr = CWidgetManager::getInstance()->getWindowUnder (eventDesc.getX(), eventDesc.getY()); // prevent 'click in scene' as mouse was previously captured
CWidgetManager::getInstance()->setCurrentWindowUnder( ptr ); // (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...
// Any Mouse event but move disable the ContextHelp if( CWidgetManager::getInstance()->getCapturePointerLeft() == NULL )
if(eventDesc.getEventTypeExtended() != NLGUI::CEventDescriptorMouse::mousemove) EventsListener.addUIHandledButtonMask(leftButton);
{
CWidgetManager::getInstance()->disableContextHelp();
}
// get the group under the mouse
CInterfaceGroup *pNewCurrentWnd = CWidgetManager::getInstance()->getCurrentWindowUnder();
_MouseOverWindow= pNewCurrentWnd!=NULL;
NLMISC::CRefPtr<CGroupModal> clickedOutModalWindow;
// modal special features
if ( CWidgetManager::getInstance()->hasModal() )
{
CWidgetManager::SModalWndInfo mwi = CWidgetManager::getInstance()->getModal();
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)
{
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())
CAHManager::getInstance()->runActionHandler(mwi.ModalHandlerClickOut,NULL,mwi.ModalClickOutParams);
// If the current window is not the modal and if must quit on click out
if(pNewCurrentWnd != mwi.ModalWindow && mwi.ModalExitClickOut)
{
// NB: don't force handle==true because to quit a modal does not avoid other actions
// quit if click outside
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown ||
(eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown))
{
clickedOutModalWindow = dynamic_cast<CGroupModal *>((CInterfaceGroup*)mwi.ModalWindow);
// disable the modal
CWidgetManager::getInstance()->popModalWindow();
if ( CWidgetManager::getInstance()->hasModal() )
{
// don't handle event unless it is a previous modal window
if( !CWidgetManager::getInstance()->isPreviousModal( pNewCurrentWnd ) )
pNewCurrentWnd = NULL; // can't handle event before we have left all modal windows
}
CWidgetManager::getInstance()->movePointer (0,0); // Reget controls under pointer
}
}
}
}
}
// Manage LeftClick.
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown)
{
if ((pNewCurrentWnd != NULL) && (!CWidgetManager::getInstance()->hasModal()) && (pNewCurrentWnd->getOverlappable()))
{
CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(pNewCurrentWnd);
if (pGC != NULL)
{
if (!pGC->isGrayed()) CWidgetManager::getInstance()->setTopWindow(pNewCurrentWnd);
}
else
{
CWidgetManager::getInstance()->setTopWindow(pNewCurrentWnd);
}
}
// 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())
{
// Take the top most control.
uint nMaxDepth = 0;
const std::vector< CCtrlBase* >& _CtrlsUnderPointer = CWidgetManager::getInstance()->getCtrlsUnderPointer();
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;
CWidgetManager::getInstance()->setCapturePointerLeft( ctrl );
}
}
}
CWidgetManager::getInstance()->notifyElementCaptured( CWidgetManager::getInstance()->getCapturePointerLeft() );
if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty())
{
CAHManager::getInstance()->runActionHandler(clickedOutModalWindow->OnPostClickOut, CWidgetManager::getInstance()->getCapturePointerLeft(), clickedOutModalWindow->OnPostClickOutParams);
}
}
//if found
if ( CWidgetManager::getInstance()->getCapturePointerLeft() != NULL)
{
// consider clicking on a control implies handling of the event.
handled= true;
// handle the capture
CWidgetManager::getInstance()->getCapturePointerLeft()->handleEvent(event);
}
}
// Manage RightClick
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown)
{
if ((pNewCurrentWnd != NULL) && (!CWidgetManager::getInstance()->hasModal()) && (pNewCurrentWnd->getOverlappable()))
{
CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(pNewCurrentWnd);
if (pGC != NULL)
{
if (!pGC->isGrayed()) CWidgetManager::getInstance()->setTopWindow(pNewCurrentWnd);
}
else
{
CWidgetManager::getInstance()->setTopWindow(pNewCurrentWnd);
}
}
// Take the top most control.
{
uint nMaxDepth = 0;
const std::vector< CCtrlBase* >& _CtrlsUnderPointer = CWidgetManager::getInstance()->getCtrlsUnderPointer();
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;
CWidgetManager::getInstance()->setCapturePointerRight( ctrl );
}
}
}
CWidgetManager::getInstance()->notifyElementCaptured( CWidgetManager::getInstance()->getCapturePointerRight() );
if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty())
{
CAHManager::getInstance()->runActionHandler(clickedOutModalWindow->OnPostClickOut, CWidgetManager::getInstance()->getCapturePointerRight(), clickedOutModalWindow->OnPostClickOutParams);
}
}
//if found
if ( CWidgetManager::getInstance()->getCapturePointerRight() != NULL)
{
// handle the capture
handled |= CWidgetManager::getInstance()->getCapturePointerRight()->handleEvent(event);
}
}
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup)
{
if (!handled)
if (pNewCurrentWnd != NULL)
pNewCurrentWnd->handleEvent(event);
if ( CWidgetManager::getInstance()->getCapturePointerRight() != 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...
CWidgetManager::getInstance()->setCapturePointerRight(NULL);
handled= true;
}
}
// window handling. if not handled by a control
if (!handled)
{
if (((pNewCurrentWnd != NULL) && !CWidgetManager::getInstance()->hasModal()) ||
((CWidgetManager::getInstance()->hasModal() && CWidgetManager::getInstance()->getModal().ModalWindow == pNewCurrentWnd)))
{
NLGUI::CEventDescriptorMouse ev2 = eventDesc;
sint32 x= eventDesc.getX(), y = eventDesc.getY();
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 ( CWidgetManager::getInstance()->getCapturePointerLeft() != 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...
CWidgetManager::getInstance()->setCapturePointerLeft(NULL);
//handled= true;
}
}
// If the current window is the modal, may Modal quit. Do it after standard event handle
if(CWidgetManager::getInstance()->hasModal() && pNewCurrentWnd == CWidgetManager::getInstance()->getModal().ModalWindow)
{
// NB: don't force handle==true because to quit a modal does not avoid other actions
CWidgetManager::SModalWndInfo mwi = CWidgetManager::getInstance()->getModal();
// and if must quit on click right
if(mwi.ModalExitClickR)
{
// quit if click right
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup)
// disable the modal
CWidgetManager::getInstance()->disableModalWindow();
}
// and if must quit on click left
if(mwi.ModalExitClickL)
{
// quit if click right
if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup)
// disable the modal
CWidgetManager::getInstance()->disableModalWindow();
}
}
// If the mouse is over a window, always consider the event is taken (avoid click behind)
handled|= _MouseOverWindow;
} }
} }
IngameDbMngr.flushObserverCalls(); IngameDbMngr.flushObserverCalls();
NLGUI::CDBManager::getInstance()->flushObserverCalls();
// event handled? // event handled?
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;
CViewRenderer::getInstance()->getScreenSize( screenW, screenH );
sint32 oldX = CWidgetManager::getInstance()->getPointer()->getX();
sint32 oldY = CWidgetManager::getInstance()->getPointer()->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 ) )
{
CWidgetManager::getInstance()->movePointerAbs( newX, newY );
NLGUI::CEventDescriptorMouse &ve = const_cast< NLGUI::CEventDescriptorMouse& >( e );
ve.setX( CWidgetManager::getInstance()->getPointer()->getX() );
ve.setY( CWidgetManager::getInstance()->getPointer()->getY() );
}
return true;
}
void CInterfaceManager::updateDesktops( uint32 newScreenW, uint32 newScreenH ) void CInterfaceManager::updateDesktops( uint32 newScreenW, uint32 newScreenH )
{ {
// *** Do it for All Backuped Desktops // *** Do it for All Backuped Desktops

View file

@ -268,7 +268,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 );
// execute a procedure. give a list of parameters. NB: the first param is the name of the proc (skipped)... // execute a procedure. give a list of parameters. NB: the first param is the name of the proc (skipped)...
void runProcedure(const std::string &procName, CCtrlBase *pCaller, const std::vector<std::string> &paramList); void runProcedure(const std::string &procName, CCtrlBase *pCaller, const std::vector<std::string> &paramList);
// replace an action in a procedure (if possible) // replace an action in a procedure (if possible)
@ -325,8 +325,6 @@ public:
*/ */
bool getCurrentValidMessageBoxOnOk(std::string &ahOnOk, const std::string &masterGroup="ui:interface"); bool getCurrentValidMessageBoxOnOk(std::string &ahOnOk, const std::string &masterGroup="ui:interface");
bool isMouseOverWindow() const {return _MouseOverWindow;}
// Modes // Modes
void setMode(uint8 newMode); void setMode(uint8 newMode);
uint8 getMode() const { return _CurrentMode; } uint8 getMode() const { return _CurrentMode; }
@ -619,8 +617,6 @@ private:
NLMISC::CCDBNodeLeaf *_DescTextTarget; NLMISC::CCDBNodeLeaf *_DescTextTarget;
bool _MouseOverWindow;
/// Current waiting id and string from server /// Current waiting id and string from server
struct SIDStringWaiter struct SIDStringWaiter
{ {
@ -638,9 +634,6 @@ private:
// List of active Anims // List of active Anims
std::vector<CInterfaceAnim*> _ActiveAnims; std::vector<CInterfaceAnim*> _ActiveAnims;
bool isControlInWindow (CCtrlBase *ctrl, CInterfaceGroup *pNewCurrentWnd);
uint getDepth (CCtrlBase *ctrl, CInterfaceGroup *pNewCurrentWnd);
// Modes // Modes
CInterfaceConfig::CDesktopImage _Modes[MAX_NUM_MODES]; CInterfaceConfig::CDesktopImage _Modes[MAX_NUM_MODES];
uint8 _CurrentMode; uint8 _CurrentMode;

View file

@ -1183,8 +1183,7 @@ string CUserControls::modeStr() const
void CUserControls::execActionCursorPos(bool rightClick, bool dblClick) void CUserControls::execActionCursorPos(bool rightClick, bool dblClick)
{ {
// Check there is no interface under the cursor. // Check there is no interface under the cursor.
CInterfaceManager *IM = CInterfaceManager::getInstance(); if( CWidgetManager::getInstance()->isMouseOverWindow())
if(IM->isMouseOverWindow())
return; return;
// Update the cursor. // Update the cursor.
ContextCur.check(); ContextCur.check();