CHANGED: #1471 Moved the widget drawing code from CInterfaceManager to CWidgetManager, so the GUI library can now draw the widgets!

This commit is contained in:
dfighter1985 2012-07-10 23:01:09 +02:00
parent 8b36d60fad
commit 68ad30434e
6 changed files with 532 additions and 410 deletions

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/3d/u_camera.h"
namespace NLMISC namespace NLMISC
{ {
@ -58,8 +59,23 @@ namespace NLGUI
/// Manages the GUI widgets /// Manages the GUI widgets
class CWidgetManager{ class CWidgetManager{
public: public:
class INewScreenSizeHandler
{
public:
virtual ~INewScreenSizeHandler(){}
virtual void process( uint32 w, uint32 h ) = 0;
};
class IOnWidgetsDrawnHandler
{
public:
virtual ~IOnWidgetsDrawnHandler(){};
virtual void process() = 0;
};
struct SInterfaceTimes struct SInterfaceTimes
{ {
public: public:
@ -291,6 +307,16 @@ namespace NLGUI
void setContextHelpActive(bool active); void setContextHelpActive(bool active);
void getNewWindowCoordToNewScreenSize( sint32 &x, sint32 &y, sint32 w, sint32 h,
sint32 newW, sint32 newH) const;
// move windows according to new screen size
void moveAllWindowsToNewScreenSize(sint32 newScreenW, sint32 newScreenH, bool fixCurrentUI );
void updateAllLocalisedElements();
void drawViews( NL3D::UCamera camera );
// 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
@ -415,6 +441,14 @@ namespace NLGUI
void setIngame( bool i ){ inGame = i; } void setIngame( bool i ){ inGame = i; }
bool isIngame() const{ return inGame; } bool isIngame() const{ return inGame; }
void setScreenWH( uint32 w, uint32 h ){ screenW = w; screenH = h; }
void registerNewScreenSizeHandler( INewScreenSizeHandler *handler );
void removeNewScreenSizeHandler( INewScreenSizeHandler *handler );
void registerOnWidgetsDrawnHandler( IOnWidgetsDrawnHandler* handler );
void removeOnWidgetsDrawnHandler( IOnWidgetsDrawnHandler *handler );
static IParser *parser; static IParser *parser;
private: private:
@ -479,6 +513,12 @@ namespace NLGUI
bool _ContextHelpActive; bool _ContextHelpActive;
bool inGame; bool inGame;
uint32 screenH;
uint32 screenW;
std::vector< INewScreenSizeHandler* > newScreenSizeHandlers;
std::vector< IOnWidgetsDrawnHandler* > onWidgetsDrawnHandlers;
}; };
} }

View file

@ -26,6 +26,7 @@
#include "nel/gui/interface_options.h" #include "nel/gui/interface_options.h"
#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"
namespace NLGUI namespace NLGUI
{ {
@ -1630,6 +1631,377 @@ namespace NLGUI
_ContextHelpActive = active; _ContextHelpActive = active;
} }
// ------------------------------------------------------------------------------------------------
void CWidgetManager::getNewWindowCoordToNewScreenSize( sint32 &x, sint32 &y, sint32 w, sint32 h,
sint32 newScreenW, sint32 newScreenH) const
{
// NB: x is relative to Left of the window (and Left of screen)
// NB: y is relative to Top of the window (but Bottom of screen)
/*
The goal here is to move the window so it fit the new resolution
But we don't want to change its size (because somes windows just can't)
We also cannot use specific code according to each window because user may completly modify his interface
So the strategy is to dectect on which "side" (or center) the window is the best sticked,
and then just move the window according to this position
*/
// *** First detect from which screen position the window is the more sticked (borders or center)
// In X: best hotspot is left, middle or right?
sint32 posXToLeft= x;
sint32 posXToMiddle= x+w/2-screenW/2;
sint32 posXToRight= screenW-(x+w);
sint32 bestXHotSpot= Hotspot_xL;
sint32 bestXPosVal= posXToLeft;
if(abs(posXToMiddle) < bestXPosVal)
{
bestXHotSpot= Hotspot_xM;
bestXPosVal= abs(posXToMiddle);
}
if(posXToRight < bestXPosVal)
{
bestXHotSpot= Hotspot_xR;
bestXPosVal= posXToRight;
}
// Same In Y: best hotspot is bottom, middle or top?
// remember here that y is the top of window (relative to bottom of screen)
sint32 posYToBottom= y-h;
sint32 posYToMiddle= y-h/2-screenH/2;
sint32 posYToTop= screenH-y;
sint32 bestYHotSpot= Hotspot_Bx;
sint32 bestYPosVal= posYToBottom;
const sint32 middleYWeight= 6; // Avoid default Mission/Team/Map/ContactList positions to be considered as "middle"
if(abs(posYToMiddle)*middleYWeight < bestYPosVal)
{
bestYHotSpot= Hotspot_Mx;
bestYPosVal= abs(posYToMiddle)*middleYWeight;
}
if(posYToTop < bestYPosVal)
{
bestYHotSpot= Hotspot_Tx;
bestYPosVal= posYToTop;
}
// *** According to best matching hotspot, and new screen resolution, move the window
// x
if(bestXHotSpot==Hotspot_xL)
x= x;
else if(bestXHotSpot==Hotspot_xM)
x= newScreenW/2 + posXToMiddle - w/2;
else if(bestXHotSpot==Hotspot_xR)
x= newScreenW - posXToRight - w;
// y
if(bestYHotSpot==Hotspot_Bx)
y= y;
else if(bestYHotSpot==Hotspot_Mx)
y= newScreenH/2 + posYToMiddle + h/2;
else if(bestYHotSpot==Hotspot_Tx)
y= newScreenH - posYToTop;
}
// ------------------------------------------------------------------------------------------------
void CWidgetManager::moveAllWindowsToNewScreenSize(sint32 newScreenW, sint32 newScreenH, bool fixCurrentUI)
{
std::vector< CWidgetManager::SMasterGroup > &_MasterGroups = CWidgetManager::getInstance()->getAllMasterGroup();
// If resolutions correctly setuped, and really different from new setup
if( screenW >0 && screenH>0 &&
newScreenW >0 && newScreenH>0 &&
( screenW != newScreenW || screenH != newScreenH)
)
{
// *** Do it for the Active Desktop (if wanted)
if(fixCurrentUI)
{
// only for ui:interface (not login, nor outgame)
for (uint nMasterGroup = 0; nMasterGroup < _MasterGroups.size(); nMasterGroup++)
{
CWidgetManager::SMasterGroup &rMG = _MasterGroups[nMasterGroup];
if(!rMG.Group || rMG.Group->getId()!="ui:interface")
continue;
// For all priorities, but the worldspace one
for (uint8 nPriority = 0; nPriority < WIN_PRIORITY_MAX; nPriority++)
{
if(nPriority==WIN_PRIORITY_WORLD_SPACE)
continue;
// For All windows (only layer 0 group container)
std::list<CInterfaceGroup*> &rList = rMG.PrioritizedWindows[nPriority];
std::list<CInterfaceGroup*>::const_iterator itw;
for (itw = rList.begin(); itw != rList.end(); itw++)
{
CInterfaceGroup *pIG = *itw;
if(!pIG->isGroupContainer())
continue;
CGroupContainer *gc= dynamic_cast<CGroupContainer*>(pIG);
if(gc->getLayerSetup()!=0)
continue;
// should all be BL / TL
if(gc->getParentPosRef()!=Hotspot_BL || gc->getPosRef()!=Hotspot_TL)
continue;
// Get current window coordinates
sint32 x= pIG->getX(); // x is relative to Left of the window
sint32 y= pIG->getY(); // y is relative to Top of the window
sint32 w= pIG->getW(false); // the window may be hid, still get the correct(or estimated) W
sint32 h= pIG->getH(false); // the window may be hid, still get the correct(or estimated) H
// Compute the new coordinate
CWidgetManager::getInstance()->getNewWindowCoordToNewScreenSize(x, y, w, h, newScreenW, newScreenH);
// Change
pIG->setX(x);
pIG->setY(y);
}
}
}
}
std::vector< INewScreenSizeHandler* >::iterator itr;
for( itr = newScreenSizeHandlers.begin(); itr != newScreenSizeHandlers.end(); ++itr )
{
INewScreenSizeHandler *handler = *itr;
handler->process( newScreenW, newScreenH );
}
}
// Now those are the last screen coordinates used for window position correction
if(newScreenW >0 && newScreenH>0)
{
screenW = newScreenW;
screenH = newScreenH;
}
}
class InvalidateTextVisitor : public CInterfaceElementVisitor
{
public:
InvalidateTextVisitor( bool reset )
{
this->reset = reset;
}
void visitGroup( CInterfaceGroup *group )
{
const std::vector< CViewBase* > &vs = group->getViews();
for( std::vector< CViewBase* >::const_iterator itr = vs.begin(); itr != vs.end(); ++itr )
{
CViewText *vt = dynamic_cast< CViewText* >( *itr );
if( vt != NULL )
{
if( reset )
vt->resetTextIndex();
vt->updateTextContext();
}
}
}
private:
bool reset;
};
// ------------------------------------------------------------------------------------------------
void CWidgetManager::updateAllLocalisedElements()
{
uint32 nMasterGroup;
uint32 w, h;
CViewRenderer::getInstance()->checkNewScreenSize ();
CViewRenderer::getInstance()->getScreenSize (w, h);
// Update ui:* (limit the master containers to the height of the screen)
for (nMasterGroup = 0; nMasterGroup < _MasterGroups.size(); nMasterGroup++)
{
SMasterGroup &rMG = _MasterGroups[nMasterGroup];
rMG.Group->setW (w);
rMG.Group->setH (h);
}
CViewRenderer::getInstance()->setClipWindow(0, 0, w, h);
// If all conditions are OK, move windows so they fit correctly with new screen size
// Do this work only InGame when Config is loaded
moveAllWindowsToNewScreenSize(w,h,true);
// Invalidate coordinates of all Windows of each MasterGroup
for (nMasterGroup = 0; nMasterGroup < _MasterGroups.size(); nMasterGroup++)
{
SMasterGroup &rMG = _MasterGroups[nMasterGroup];
InvalidateTextVisitor inv( false );
rMG.Group->visitGroupAndChildren( &inv );
rMG.Group->invalidateCoords ();
for (uint8 nPriority = 0; nPriority < WIN_PRIORITY_MAX; nPriority++)
{
std::list<CInterfaceGroup*> &rList = rMG.PrioritizedWindows[nPriority];
std::list<CInterfaceGroup*>::const_iterator itw;
for (itw = rList.begin(); itw != rList.end(); itw++)
{
CInterfaceGroup *pIG = *itw;
pIG->visitGroupAndChildren( &inv );
pIG->invalidateCoords ();
}
}
}
// setup for all
for (nMasterGroup = 0; nMasterGroup < _MasterGroups.size(); nMasterGroup++)
{
SMasterGroup &rMG = _MasterGroups[nMasterGroup];
bool bActive = rMG.Group->getActive ();
rMG.Group->setActive (true);
rMG.Group->updateCoords ();
rMG.Group->setActive (bActive);
}
// update coords one
checkCoords();
// Action by default (container opening
for (nMasterGroup = 0; nMasterGroup < _MasterGroups.size(); nMasterGroup++)
{
SMasterGroup &rMG = _MasterGroups[nMasterGroup];
rMG.Group->launch ();
}
}
void CWidgetManager::drawViews( NL3D::UCamera camera )
{
CViewRenderer::getInstance()->activateWorldSpaceMatrix (false);
NL3D::UDriver *driver = CViewRenderer::getInstance()->getDriver();
// If an element has captured the keyboard, make sure it is alway visible (all parent windows active)
if( getCaptureKeyboard() != NULL)
{
CCtrlBase *cb = getCaptureKeyboard();
do
{
if (!cb->getActive())
{
setCaptureKeyboard(NULL);
break;
}
cb = cb->getParent();
}
while (cb);
}
// Check if screen size changed
uint32 w, h;
CViewRenderer::getInstance()->checkNewScreenSize ();
CViewRenderer::getInstance()->getScreenSize (w, h);
if ((w != screenW) || (h != screenH))
{
// No Op if screen minimized
if(w!=0 && h!=0 && !CViewRenderer::getInstance()->isMinimized())
{
updateAllLocalisedElements ();
setScreenWH( w, h );
}
}
// Update global color from database
setGlobalColor( NLMISC::CRGBA ( (uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:R")->getValue32(),
(uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:G")->getValue32(),
(uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:B")->getValue32(),
(uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:A")->getValue32() ) );
NLMISC::CRGBA c = getGlobalColorForContent();
NLMISC::CRGBA gc = getGlobalColor();
c.R = gc.R;
c.G = gc.G;
c.B = gc.B;
c.A = (uint8) (( (uint16) c.A * (uint16) getContentAlpha() ) >> 8);
setGlobalColorForContent( c );
// Update global alphaS from database
updateGlobalAlphas();
/* Draw all the windows
To minimize texture swapping, we first sort per Window, then we sort per layer, then we render per Global Texture.
Computed String are rendered in on big drawQuads at last part of each layer
*/
CDBManager::getInstance()->flushObserverCalls();
for (uint32 nMasterGroup = 0; nMasterGroup < _MasterGroups.size(); nMasterGroup++)
{
CWidgetManager::SMasterGroup &rMG = _MasterGroups[nMasterGroup];
if (rMG.Group->getActive())
{
// Sort world space windows
rMG.sortWorldSpaceGroup ();
for (uint8 nPriority = 0; nPriority < WIN_PRIORITY_MAX; ++nPriority)
{
if ( (nPriority == WIN_PRIORITY_WORLD_SPACE) && !camera.empty())
{
driver->setViewMatrix( NL3D::CMatrix::Identity);
driver->setModelMatrix( NL3D::CMatrix::Identity);
driver->setFrustum(camera.getFrustum());
CViewRenderer::getInstance()->activateWorldSpaceMatrix (true);
}
std::list<CInterfaceGroup*> &rList = rMG.PrioritizedWindows[nPriority];
std::list<CInterfaceGroup*>::const_iterator itw;
for (itw = rList.begin(); itw != rList.end(); itw++)
{
CInterfaceGroup *pIG = *itw;
if( pIG ) // TODO: debug null pointer in PrioritizedWindows list
{
if (pIG->getActive())
{
// Draw all the elements of this window in the layers in ViewRendered
pIG->draw ();
// flush the layers
CViewRenderer::getInstance()->flush ();
}
}
}
if ( (nPriority == WIN_PRIORITY_WORLD_SPACE) && !camera.empty())
{
driver->setMatrixMode2D11();
CViewRenderer::getInstance()->activateWorldSpaceMatrix (false);
}
}
}
}
CDBManager::getInstance()->flushObserverCalls();
// draw the special over extend text
drawOverExtendViewText();
// draw the context help
drawContextHelp ();
std::vector< IOnWidgetsDrawnHandler* >::iterator itr;
for( itr = onWidgetsDrawnHandlers.begin(); itr != onWidgetsDrawnHandlers.end(); ++itr )
{
IOnWidgetsDrawnHandler *handler = *itr;
handler->process();
}
// Draw the pointer and DND Item
if( getPointer() != NULL)
{
if ( getPointer()->getActive())
getPointer()->draw ();
}
// flush layers
CViewRenderer::getInstance()->flush();
// todo hulud remove Return in 2d world
driver->setMatrixMode2D11();
CDBManager::getInstance()->flushObserverCalls();
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void CWidgetManager::movePointer (sint32 dx, sint32 dy) void CWidgetManager::movePointer (sint32 dx, sint32 dy)
{ {
@ -2045,6 +2417,50 @@ namespace NLGUI
_GlobalRolloverFactorContainer = (uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CONTAINER_ROLLOVER_FACTOR")->getValue32(); _GlobalRolloverFactorContainer = (uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CONTAINER_ROLLOVER_FACTOR")->getValue32();
} }
void CWidgetManager::registerNewScreenSizeHandler( INewScreenSizeHandler *handler )
{
std::vector< INewScreenSizeHandler* >::iterator itr =
std::find( newScreenSizeHandlers.begin(), newScreenSizeHandlers.end(), handler );
if( itr != newScreenSizeHandlers.end() )
return;
newScreenSizeHandlers.push_back( handler );
}
void CWidgetManager::removeNewScreenSizeHandler( INewScreenSizeHandler *handler )
{
std::vector< INewScreenSizeHandler* >::iterator itr =
std::find( newScreenSizeHandlers.begin(), newScreenSizeHandlers.end(), handler );
if( itr == newScreenSizeHandlers.end() )
return;
newScreenSizeHandlers.erase( itr );
}
void CWidgetManager::registerOnWidgetsDrawnHandler( IOnWidgetsDrawnHandler* handler )
{
std::vector< IOnWidgetsDrawnHandler* >::iterator itr =
std::find( onWidgetsDrawnHandlers.begin(), onWidgetsDrawnHandlers.end(), handler );
if( itr != onWidgetsDrawnHandlers.end() )
return;
onWidgetsDrawnHandlers.push_back( handler );
}
void CWidgetManager::removeOnWidgetsDrawnHandler( IOnWidgetsDrawnHandler* handler )
{
std::vector< IOnWidgetsDrawnHandler* >::iterator itr =
std::find( onWidgetsDrawnHandlers.begin(), onWidgetsDrawnHandlers.end(), handler );
if( itr == onWidgetsDrawnHandlers.end() )
return;
onWidgetsDrawnHandlers.erase( itr );
}
CWidgetManager::CWidgetManager() CWidgetManager::CWidgetManager()
{ {
_Pointer = NULL; _Pointer = NULL;
@ -2069,6 +2485,8 @@ namespace NLGUI
_MouseHandlingEnabled = true; _MouseHandlingEnabled = true;
inGame = false; inGame = false;
setScreenWH( 0, 0 );
} }
CWidgetManager::~CWidgetManager() CWidgetManager::~CWidgetManager()

View file

@ -259,6 +259,43 @@ int CInterfaceManager::DebugTrackGroupsGetId( CInterfaceGroup *pIG )
#endif // AJM_DEBUG_TRACK_INTERFACE_GROUPS #endif // AJM_DEBUG_TRACK_INTERFACE_GROUPS
class CDesktopUpdater : public CWidgetManager::INewScreenSizeHandler
{
public:
void process( uint32 w, uint32 h )
{
CInterfaceManager::getInstance()->updateDesktops( w, h );
}
};
class CDrawDraggedSheet : public CWidgetManager::IOnWidgetsDrawnHandler
{
public:
void process()
{
if ( CWidgetManager::getInstance()->getPointer()->show())
{
CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>( CWidgetManager::getInstance()->getCapturePointerLeft() );
if ((pCS != NULL) && (pCS->isDragged()))
{
sint x= CWidgetManager::getInstance()->getPointer()->getX() - pCS->getDeltaDragX();
sint y= CWidgetManager::getInstance()->getPointer()->getY() - pCS->getDeltaDragY();
pCS->drawSheet (x, y, false, false);
// if the control support CopyDrag, and if copy key pressed, display a tiny "+"
if(pCS->canDragCopy() && CInterfaceManager::getInstance()->testDragCopyKey())
{
CViewRenderer &rVR = *CViewRenderer::getInstance();
sint w= rVR.getSystemTextureW(CViewRenderer::DragCopyTexture);
sint h= rVR.getSystemTextureW(CViewRenderer::DragCopyTexture);
rVR.draw11RotFlipBitmap (pCS->getRenderLayer()+1, x-w/2, y-h/2, 0, false,
rVR.getSystemTextureId(CViewRenderer::DragCopyTexture));
}
}
}
}
};
class CStringManagerTextProvider : public CViewTextID::IViewTextProvider class CStringManagerTextProvider : public CViewTextID::IViewTextProvider
{ {
@ -405,6 +442,8 @@ CInterfaceManager::CInterfaceManager( NL3D::UDriver *driver, NL3D::UTextContext
addModule( "command", new CCommandParser() ); addModule( "command", new CCommandParser() );
addModule( "key", new CKeyParser() ); addModule( "key", new CKeyParser() );
addModule( "macro", new CMacroParser() ); addModule( "macro", new CMacroParser() );
CWidgetManager::getInstance()->registerNewScreenSizeHandler( new CDesktopUpdater() );
CWidgetManager::getInstance()->registerOnWidgetsDrawnHandler( new CDrawDraggedSheet() );
setCacheUIParsing( ClientCfg.CacheUIParsing ); setCacheUIParsing( ClientCfg.CacheUIParsing );
@ -445,6 +484,11 @@ CInterfaceManager::CInterfaceManager( NL3D::UDriver *driver, NL3D::UTextContext
// Interface Manager init // Interface Manager init
CViewRenderer::getInstance()->checkNewScreenSize(); CViewRenderer::getInstance()->checkNewScreenSize();
{
uint32 w,h;
CViewRenderer::getInstance()->getScreenSize( w, h );
CWidgetManager::getInstance()->setScreenWH( w, h );
}
CViewRenderer::getInstance()->init(); CViewRenderer::getInstance()->init();
_CurrentMode = 0; _CurrentMode = 0;
@ -632,7 +676,7 @@ void CInterfaceManager::initLogin()
parseInterface (ClientCfg.XMLLoginInterfaceFiles, false); parseInterface (ClientCfg.XMLLoginInterfaceFiles, false);
updateAllLocalisedElements(); CWidgetManager::getInstance()->updateAllLocalisedElements();
CWidgetManager::getInstance()->activateMasterGroup ("ui:login", true); CWidgetManager::getInstance()->activateMasterGroup ("ui:login", true);
@ -722,7 +766,7 @@ void CInterfaceManager::initOutGame()
parseInterface (ClientCfg.XMLOutGameInterfaceFiles, false); parseInterface (ClientCfg.XMLOutGameInterfaceFiles, false);
updateAllLocalisedElements(); CWidgetManager::getInstance()->updateAllLocalisedElements();
CWidgetManager::getInstance()->activateMasterGroup ("ui:outgame", true); CWidgetManager::getInstance()->activateMasterGroup ("ui:outgame", true);
@ -926,7 +970,7 @@ void CInterfaceManager::initInGame()
{ {
H_AUTO( RZUpdAll ) H_AUTO( RZUpdAll )
updateAllLocalisedElements(); // To init all things CWidgetManager::getInstance()->updateAllLocalisedElements(); // To init all things
} }
// Interface config // Interface config
@ -1735,7 +1779,8 @@ bool CInterfaceManager::loadConfig (const string &filename)
{ {
// NB: we are typically InGame here (even though the _InGame flag is not yet set) // NB: we are typically InGame here (even though the _InGame flag is not yet set)
// Use the screen size of the config file. Don't update current UI, just _Modes // Use the screen size of the config file. Don't update current UI, just _Modes
moveAllWindowsToNewScreenSize(ClientCfg.Width, ClientCfg.Height, false); CWidgetManager::getInstance()->moveAllWindowsToNewScreenSize(ClientCfg.Width, ClientCfg.Height, false);
updateDesktops( ClientCfg.Width, ClientCfg.Height );
} }
// *** apply the current mode // *** apply the current mode
@ -1916,191 +1961,18 @@ bool CInterfaceManager::saveConfig (const string &filename)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void CInterfaceManager::drawViews(NL3D::UCamera camera) void CInterfaceManager::drawViews(NL3D::UCamera camera)
{ {
{
H_AUTO ( RZ_Interface_DrawViews_Setup )
CViewRenderer::getInstance()->activateWorldSpaceMatrix (false);
IngameDbMngr.flushObserverCalls(); IngameDbMngr.flushObserverCalls();
NLGUI::CDBManager::getInstance()->flushObserverCalls(); NLGUI::CDBManager::getInstance()->flushObserverCalls();
// If an element has captured the keyboard, make sure it is alway visible (all parent windows active)
if( CWidgetManager::getInstance()->getCaptureKeyboard() != NULL)
{
CCtrlBase *cb = CWidgetManager::getInstance()->getCaptureKeyboard();
do
{
if (!cb->getActive())
{
CWidgetManager::getInstance()->setCaptureKeyboard(NULL);
break;
}
cb = cb->getParent();
}
while (cb);
}
// Check if screen size changed
uint32 w, h;
CViewRenderer::getInstance()->checkNewScreenSize ();
CViewRenderer::getInstance()->getScreenSize (w, h);
if ((w != _ScreenW) || (h != _ScreenH))
{
// No Op if screen minimized
if(w!=0 && h!=0 && !CViewRenderer::getInstance()->isMinimized())
{
updateAllLocalisedElements ();
_ScreenW = w;
_ScreenH = h;
}
}
// Update global color from database
CWidgetManager::getInstance()->setGlobalColor( CRGBA ( (uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:R")->getValue32(),
(uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:G")->getValue32(),
(uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:B")->getValue32(),
(uint8)NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:A")->getValue32() ) );
CRGBA c = CWidgetManager::getInstance()->getGlobalColorForContent();
CRGBA gc = CWidgetManager::getInstance()->getGlobalColor();
c.R = gc.R;
c.G = gc.G;
c.B = gc.B;
c.A = (uint8) (( (uint16) c.A * (uint16) CWidgetManager::getInstance()->getContentAlpha() ) >> 8);
CWidgetManager::getInstance()->setGlobalColorForContent( c );
// Update global alphaS from database
CWidgetManager::getInstance()->updateGlobalAlphas();
// Update Player characteristics (for Item carac requirement Redifying) // Update Player characteristics (for Item carac requirement Redifying)
nlctassert(CHARACTERISTICS::NUM_CHARACTERISTICS==8); nlctassert(CHARACTERISTICS::NUM_CHARACTERISTICS==8);
for (uint i=0; i<CHARACTERISTICS::NUM_CHARACTERISTICS; ++i) for (uint i=0; i<CHARACTERISTICS::NUM_CHARACTERISTICS; ++i)
_CurrentPlayerCharac[i]= NLGUI::CDBManager::getInstance()->getDbValue32(toString("SERVER:CHARACTER_INFO:CHARACTERISTICS%d:VALUE", i)); _CurrentPlayerCharac[i]= NLGUI::CDBManager::getInstance()->getDbValue32(toString("SERVER:CHARACTER_INFO:CHARACTERISTICS%d:VALUE", i));
// _CurrentPlayerCharac[CHARACTERISTICS::constitution]= getDbValue32("SERVER:CHARACTER_INFO:CHARACTERISTICS:Constitution"); CWidgetManager::getInstance()->drawViews( camera );
// _CurrentPlayerCharac[CHARACTERISTICS::constitution]= getDbValue32("SERVER:CHARACTER_INFO:CHARACTERISTICS:Constitution");
// _CurrentPlayerCharac[CHARACTERISTICS::metabolism]= getDbValue32("SERVER:CHARACTER_INFO:CHARACTERISTICS:Metabolism");
// _CurrentPlayerCharac[CHARACTERISTICS::intelligence]= getDbValue32("SERVER:CHARACTER_INFO:CHARACTERISTICS:Intelligence");
// _CurrentPlayerCharac[CHARACTERISTICS::wisdom]= getDbValue32("SERVER:CHARACTER_INFO:CHARACTERISTICS:Wisdom");
// _CurrentPlayerCharac[CHARACTERISTICS::strength]= getDbValue32("SERVER:CHARACTER_INFO:CHARACTERISTICS:Strength");
// _CurrentPlayerCharac[CHARACTERISTICS::well_balanced]= getDbValue32("SERVER:CHARACTER_INFO:CHARACTERISTICS:WellBalanced");
// _CurrentPlayerCharac[CHARACTERISTICS::dexterity]= getDbValue32("SERVER:CHARACTER_INFO:CHARACTERISTICS:Dexterity");
// _CurrentPlayerCharac[CHARACTERISTICS::will]= getDbValue32("SERVER:CHARACTER_INFO:CHARACTERISTICS:Will");
}
{
H_AUTO ( RZ_Interface_DrawWindows )
/* Draw all the windows
To minimize texture swapping, we first sort per Window, then we sort per layer, then we render per Global Texture.
Computed String are rendered in on big drawQuads at last part of each layer
*/
std::vector< CWidgetManager::SMasterGroup > &_MasterGroups = CWidgetManager::getInstance()->getAllMasterGroup();
IngameDbMngr.flushObserverCalls();
NLGUI::CDBManager::getInstance()->flushObserverCalls();
//
for (uint32 nMasterGroup = 0; nMasterGroup < _MasterGroups.size(); nMasterGroup++)
{
CWidgetManager::SMasterGroup &rMG = _MasterGroups[nMasterGroup];
if (rMG.Group->getActive())
{
// Sort world space windows
rMG.sortWorldSpaceGroup ();
for (uint8 nPriority = 0; nPriority < WIN_PRIORITY_MAX; ++nPriority)
{
if ( (nPriority == WIN_PRIORITY_WORLD_SPACE) && !camera.empty())
{
driver->setViewMatrix(CMatrix::Identity);
driver->setModelMatrix(CMatrix::Identity);
driver->setFrustum(camera.getFrustum());
CViewRenderer::getInstance()->activateWorldSpaceMatrix (true);
}
list<CInterfaceGroup*> &rList = rMG.PrioritizedWindows[nPriority];
list<CInterfaceGroup*>::const_iterator itw;
for (itw = rList.begin(); itw != rList.end(); itw++)
{
CInterfaceGroup *pIG = *itw;
if( pIG ) // TODO: debug null pointer in PrioritizedWindows list
{
if (pIG->getActive())
{
// Draw all the elements of this window in the layers in ViewRendered
pIG->draw ();
// flush the layers
CViewRenderer::getInstance()->flush ();
}
}
}
if ( (nPriority == WIN_PRIORITY_WORLD_SPACE) && !camera.empty())
{
driver->setMatrixMode2D11();
CViewRenderer::getInstance()->activateWorldSpaceMatrix (false);
}
}
}
}
}
{
H_AUTO ( RZ_Interface_DrawViews_After )
IngameDbMngr.flushObserverCalls();
NLGUI::CDBManager::getInstance()->flushObserverCalls();
// draw the special over extend text
CWidgetManager::getInstance()->drawOverExtendViewText();
// draw the context help
CWidgetManager::getInstance()->drawContextHelp ();
// Draw the pointer and DND Item
if ( CWidgetManager::getInstance()->getPointer() != NULL)
{
//_Pointer->updateCoords();
if ( CWidgetManager::getInstance()->getPointer()->show())
{
CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>( CWidgetManager::getInstance()->getCapturePointerLeft() );
if ((pCS != NULL) && (pCS->isDragged()))
{
sint x= CWidgetManager::getInstance()->getPointer()->getX() - pCS->getDeltaDragX();
sint y= CWidgetManager::getInstance()->getPointer()->getY() - pCS->getDeltaDragY();
pCS->drawSheet (x, y, false, false);
// if the control support CopyDrag, and if copy key pressed, display a tiny "+"
if(pCS->canDragCopy() && testDragCopyKey())
{
CViewRenderer &rVR = *CViewRenderer::getInstance();
sint w= rVR.getSystemTextureW(CViewRenderer::DragCopyTexture);
sint h= rVR.getSystemTextureW(CViewRenderer::DragCopyTexture);
rVR.draw11RotFlipBitmap (pCS->getRenderLayer()+1, x-w/2, y-h/2, 0, false,
rVR.getSystemTextureId(CViewRenderer::DragCopyTexture));
}
}
}
// Even if hardware, Force draw if the cursor is a string (ATTACK etc...)
/*if (_Pointer->getActive() && (!IsMouseCursorHardware () || _Pointer->getStringMode()) )
_Pointer->draw ();*/
if (CWidgetManager::getInstance()->getPointer()->getActive())
CWidgetManager::getInstance()->getPointer()->draw ();
}
// flush layers
CViewRenderer::getInstance()->flush();
// todo hulud remove Return in 2d world
driver->setMatrixMode2D11();
// flush obs // flush obs
IngameDbMngr.flushObserverCalls(); IngameDbMngr.flushObserverCalls();
NLGUI::CDBManager::getInstance()->flushObserverCalls();
}
} }
@ -2596,132 +2468,8 @@ bool CInterfaceManager::handleMouseMoveEvent( const NLGUI::CEventDescriptor &eve
return true; return true;
} }
// ------------------------------------------------------------------------------------------------ void CInterfaceManager::updateDesktops( uint32 newScreenW, uint32 newScreenH )
void CInterfaceManager::getNewWindowCoordToNewScreenSize(sint32 &x, sint32 &y, sint32 w, sint32 h, sint32 newScreenW, sint32 newScreenH) const
{ {
// NB: x is relative to Left of the window (and Left of screen)
// NB: y is relative to Top of the window (but Bottom of screen)
/*
The goal here is to move the window so it fit the new resolution
But we don't want to change its size (because somes windows just can't)
We also cannot use specific code according to each window because user may completly modify his interface
So the strategy is to dectect on which "side" (or center) the window is the best sticked,
and then just move the window according to this position
*/
// *** First detect from which screen position the window is the more sticked (borders or center)
// In X: best hotspot is left, middle or right?
sint32 posXToLeft= x;
sint32 posXToMiddle= x+w/2-_LastInGameScreenW/2;
sint32 posXToRight= _LastInGameScreenW-(x+w);
sint32 bestXHotSpot= Hotspot_xL;
sint32 bestXPosVal= posXToLeft;
if(abs(posXToMiddle) < bestXPosVal)
{
bestXHotSpot= Hotspot_xM;
bestXPosVal= abs(posXToMiddle);
}
if(posXToRight < bestXPosVal)
{
bestXHotSpot= Hotspot_xR;
bestXPosVal= posXToRight;
}
// Same In Y: best hotspot is bottom, middle or top?
// remember here that y is the top of window (relative to bottom of screen)
sint32 posYToBottom= y-h;
sint32 posYToMiddle= y-h/2-_LastInGameScreenH/2;
sint32 posYToTop= _LastInGameScreenH-y;
sint32 bestYHotSpot= Hotspot_Bx;
sint32 bestYPosVal= posYToBottom;
const sint32 middleYWeight= 6; // Avoid default Mission/Team/Map/ContactList positions to be considered as "middle"
if(abs(posYToMiddle)*middleYWeight < bestYPosVal)
{
bestYHotSpot= Hotspot_Mx;
bestYPosVal= abs(posYToMiddle)*middleYWeight;
}
if(posYToTop < bestYPosVal)
{
bestYHotSpot= Hotspot_Tx;
bestYPosVal= posYToTop;
}
// *** According to best matching hotspot, and new screen resolution, move the window
// x
if(bestXHotSpot==Hotspot_xL)
x= x;
else if(bestXHotSpot==Hotspot_xM)
x= newScreenW/2 + posXToMiddle - w/2;
else if(bestXHotSpot==Hotspot_xR)
x= newScreenW - posXToRight - w;
// y
if(bestYHotSpot==Hotspot_Bx)
y= y;
else if(bestYHotSpot==Hotspot_Mx)
y= newScreenH/2 + posYToMiddle + h/2;
else if(bestYHotSpot==Hotspot_Tx)
y= newScreenH - posYToTop;
}
// ------------------------------------------------------------------------------------------------
void CInterfaceManager::moveAllWindowsToNewScreenSize(sint32 newScreenW, sint32 newScreenH, bool fixCurrentUI)
{
std::vector< CWidgetManager::SMasterGroup > &_MasterGroups = CWidgetManager::getInstance()->getAllMasterGroup();
// If resolutions correctly setuped, and really different from new setup
if( _LastInGameScreenW >0 && _LastInGameScreenH>0 &&
newScreenW >0 && newScreenH>0 &&
(_LastInGameScreenW != newScreenW || _LastInGameScreenH != newScreenH)
)
{
// *** Do it for the Active Desktop (if wanted)
if(fixCurrentUI)
{
// only for ui:interface (not login, nor outgame)
for (uint nMasterGroup = 0; nMasterGroup < _MasterGroups.size(); nMasterGroup++)
{
CWidgetManager::SMasterGroup &rMG = _MasterGroups[nMasterGroup];
if(!rMG.Group || rMG.Group->getId()!="ui:interface")
continue;
// For all priorities, but the worldspace one
for (uint8 nPriority = 0; nPriority < WIN_PRIORITY_MAX; nPriority++)
{
if(nPriority==WIN_PRIORITY_WORLD_SPACE)
continue;
// For All windows (only layer 0 group container)
list<CInterfaceGroup*> &rList = rMG.PrioritizedWindows[nPriority];
list<CInterfaceGroup*>::const_iterator itw;
for (itw = rList.begin(); itw != rList.end(); itw++)
{
CInterfaceGroup *pIG = *itw;
if(!pIG->isGroupContainer())
continue;
CGroupContainer *gc= safe_cast<CGroupContainer*>(pIG);
if(gc->getLayerSetup()!=0)
continue;
// should all be BL / TL
if(gc->getParentPosRef()!=Hotspot_BL || gc->getPosRef()!=Hotspot_TL)
continue;
// Get current window coordinates
sint32 x= pIG->getX(); // x is relative to Left of the window
sint32 y= pIG->getY(); // y is relative to Top of the window
sint32 w= pIG->getW(false); // the window may be hid, still get the correct(or estimated) W
sint32 h= pIG->getH(false); // the window may be hid, still get the correct(or estimated) H
// Compute the new coordinate
getNewWindowCoordToNewScreenSize(x, y, w, h, newScreenW, newScreenH);
// Change
pIG->setX(x);
pIG->setY(y);
}
}
}
}
// *** Do it for All Backuped Desktops // *** Do it for All Backuped Desktops
for(uint md=0;md<MAX_NUM_MODES;md++) for(uint md=0;md<MAX_NUM_MODES;md++)
{ {
@ -2731,17 +2479,9 @@ void CInterfaceManager::moveAllWindowsToNewScreenSize(sint32 newScreenW, sint32
{ {
CInterfaceConfig::SCont &gcCont= mode.GCImages[gc]; CInterfaceConfig::SCont &gcCont= mode.GCImages[gc];
// Compute the new coordinate, directly in the X/Y fields of the structure // Compute the new coordinate, directly in the X/Y fields of the structure
getNewWindowCoordToNewScreenSize(gcCont.X, gcCont.Y, gcCont.W, gcCont.H ,newScreenW, newScreenH); CWidgetManager::getInstance()->getNewWindowCoordToNewScreenSize(gcCont.X, gcCont.Y, gcCont.W, gcCont.H ,newScreenW, newScreenH);
} }
} }
}
// Now those are the last screen coordinates used for window position correction
if(newScreenW >0 && newScreenH>0)
{
_LastInGameScreenW= newScreenW;
_LastInGameScreenH= newScreenH;
}
} }
class InvalidateTextVisitor : public CInterfaceElementVisitor class InvalidateTextVisitor : public CInterfaceElementVisitor
@ -2771,75 +2511,6 @@ private:
bool reset; bool reset;
}; };
// ------------------------------------------------------------------------------------------------
void CInterfaceManager::updateAllLocalisedElements()
{
uint32 nMasterGroup;
uint32 w, h;
CViewRenderer::getInstance()->checkNewScreenSize ();
CViewRenderer::getInstance()->getScreenSize (w, h);
std::vector< CWidgetManager::SMasterGroup > &_MasterGroups = CWidgetManager::getInstance()->getAllMasterGroup();
// Update ui:* (limit the master containers to the height of the screen)
for (nMasterGroup = 0; nMasterGroup < _MasterGroups.size(); nMasterGroup++)
{
CWidgetManager::SMasterGroup &rMG = _MasterGroups[nMasterGroup];
rMG.Group->setW (w);
rMG.Group->setH (h);
}
CViewRenderer::getInstance()->setClipWindow(0, 0, w, h);
// If all conditions are OK, move windows so they fit correctly with new screen size
// Do this work only InGame when Config is loaded
if( _InGame && _ConfigLoaded )
moveAllWindowsToNewScreenSize(w,h,true);
// Invalidate coordinates of all Windows of each MasterGroup
for (nMasterGroup = 0; nMasterGroup < _MasterGroups.size(); nMasterGroup++)
{
CWidgetManager::SMasterGroup &rMG = _MasterGroups[nMasterGroup];
InvalidateTextVisitor inv( false );
rMG.Group->visitGroupAndChildren( &inv );
rMG.Group->invalidateCoords ();
for (uint8 nPriority = 0; nPriority < WIN_PRIORITY_MAX; nPriority++)
{
list<CInterfaceGroup*> &rList = rMG.PrioritizedWindows[nPriority];
list<CInterfaceGroup*>::const_iterator itw;
for (itw = rList.begin(); itw != rList.end(); itw++)
{
CInterfaceGroup *pIG = *itw;
pIG->visitGroupAndChildren( &inv );
pIG->invalidateCoords ();
}
}
}
// setup for all
for (nMasterGroup = 0; nMasterGroup < _MasterGroups.size(); nMasterGroup++)
{
CWidgetManager::SMasterGroup &rMG = _MasterGroups[nMasterGroup];
bool bActive = rMG.Group->getActive ();
rMG.Group->setActive (true);
rMG.Group->updateCoords ();
rMG.Group->setActive (bActive);
}
// update coords one
CWidgetManager::getInstance()->checkCoords();
// Action by default (container opening
for (nMasterGroup = 0; nMasterGroup < _MasterGroups.size(); nMasterGroup++)
{
CWidgetManager::SMasterGroup &rMG = _MasterGroups[nMasterGroup];
rMG.Group->launch ();
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void CInterfaceManager::addServerString (const std::string &sTarget, uint32 id, IStringProcess *cb) void CInterfaceManager::addServerString (const std::string &sTarget, uint32 id, IStringProcess *cb)
@ -3704,7 +3375,7 @@ NLMISC_COMMAND(loadui, "Load an interface file", "<loadui [all]/interface.xml>")
#endif #endif
// Invalidate the texts // Invalidate the texts
im->updateAllLocalisedElements(); CWidgetManager::getInstance()->updateAllLocalisedElements();
// reset captures // reset captures
CWidgetManager::getInstance()->setCapturePointerLeft(NULL); CWidgetManager::getInstance()->setCapturePointerLeft(NULL);

View file

@ -286,11 +286,6 @@ public:
* Draw views * Draw views
*/ */
void drawViews (NL3D::UCamera camera); void drawViews (NL3D::UCamera camera);
void drawAutoAdd ();
//void drawContextMenu ();
/// Update all the elements
void updateAllLocalisedElements ();
// display a debug info // display a debug info
void displayDebugInfo(const ucstring &str, TSystemInfoMode mode = InfoMsg); void displayDebugInfo(const ucstring &str, TSystemInfoMode mode = InfoMsg);
@ -591,6 +586,8 @@ public:
NLMISC::CCDBNodeLeaf *_DB_UI_DUMMY_PREREQUISIT_VALID; NLMISC::CCDBNodeLeaf *_DB_UI_DUMMY_PREREQUISIT_VALID;
NLMISC::CCDBNodeLeaf *_DB_UI_DUMMY_FACTION_TYPE; NLMISC::CCDBNodeLeaf *_DB_UI_DUMMY_FACTION_TYPE;
void updateDesktops( uint32 newScreenW, uint32 newScreenH );
private: private:
NLMISC::CCDBNodeLeaf *_CheckMailNode; NLMISC::CCDBNodeLeaf *_CheckMailNode;
@ -696,10 +693,6 @@ private:
CServerToLocalAutoCopy ServerToLocalAutoCopySkillPoints; CServerToLocalAutoCopy ServerToLocalAutoCopySkillPoints;
CServerToLocalAutoCopy ServerToLocalAutoCopyDMGift; CServerToLocalAutoCopy ServerToLocalAutoCopyDMGift;
// move windows according to new screen size
void moveAllWindowsToNewScreenSize(sint32 newScreenW, sint32 newScreenH, bool fixCurrentUI);
void getNewWindowCoordToNewScreenSize(sint32 &x, sint32 &y, sint32 w, sint32 h, sint32 newW, sint32 newH) const;
// Pop a new message box. If the message box was found, returns a pointer on it // Pop a new message box. If the message box was found, returns a pointer on it
void messageBoxInternal(const std::string &msgBoxGroup, const ucstring &text, const std::string &masterGroup, TCaseMode caseMode); void messageBoxInternal(const std::string &msgBoxGroup, const ucstring &text, const std::string &masterGroup, TCaseMode caseMode);

View file

@ -1693,7 +1693,7 @@ int CLuaIHMRyzom::updateAllLocalisedElements(CLuaState &ls)
CLuaStackChecker lsc(&ls); CLuaStackChecker lsc(&ls);
CLuaIHM::checkArgCount(ls, "updateAllLocalisedElements", 0); CLuaIHM::checkArgCount(ls, "updateAllLocalisedElements", 0);
CInterfaceManager *pIM= CInterfaceManager::getInstance(); CInterfaceManager *pIM= CInterfaceManager::getInstance();
pIM->updateAllLocalisedElements(); CWidgetManager::getInstance()->updateAllLocalisedElements();
// //
TTime endTime = CTime::getLocalTime(); TTime endTime = CTime::getLocalTime();
if (ClientCfg.R2EDVerboseParseTime) if (ClientCfg.R2EDVerboseParseTime)

View file

@ -2231,7 +2231,7 @@ void CEditor::loadStandardUI()
ClientCfg.R2EDEnabled = false; ClientCfg.R2EDEnabled = false;
loadUIConfig(""); loadUIConfig("");
ClientCfg.R2EDEnabled = true; ClientCfg.R2EDEnabled = true;
getUI().updateAllLocalisedElements(); CWidgetManager::getInstance()->updateAllLocalisedElements();
} }
// ********************************************************************************************************* // *********************************************************************************************************
@ -2708,7 +2708,7 @@ void CEditor::init(TMode initialMode, TAccessMode accessMode)
{ {
CVerboseClock clock("Update of localized elements"); CVerboseClock clock("Update of localized elements");
getUI().updateAllLocalisedElements(); CWidgetManager::getInstance()->updateAllLocalisedElements();
} }
} }