1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2020 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013-2014 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2013-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "nel/gui/db_manager.h"
24 #include "nel/gui/view_renderer.h"
25 #include "nel/gui/widget_manager.h"
26 #include "nel/gui/view_pointer.h"
27 #include "nel/gui/ctrl_draggable.h"
28 #include "nel/gui/interface_group.h"
29 #include "nel/gui/group_container_base.h"
30 #include "nel/gui/group_modal.h"
31 #include "nel/gui/group_editbox_base.h"
32 #include "nel/gui/interface_options.h"
33 #include "nel/gui/view_text.h"
34 #include "nel/gui/view_bitmap.h"
35 #include "nel/gui/group_container.h"
36 #include "nel/gui/interface_anim.h"
37 #include "nel/gui/proc.h"
38 #include "nel/gui/interface_expr.h"
39 #include "nel/gui/reflect_register.h"
40 #include "nel/gui/editor_selection_watcher.h"
41 #include "nel/misc/events.h"
42 #include "nel/gui/root_group.h"
55 const uint DOUBLE_CLICK_MIN
= 50;
56 const uint DOUBLE_CLICK_MAX
= 750;
57 const float ROLLOVER_MIN_DELTA_PER_MS
= 0.28f
;
58 const float ROLLOVER_MAX_DELTA_PER_MS
= 0.12f
;
68 CWidgetManager
* CWidgetManager::instance
= NULL
;
69 std::string
CWidgetManager::_CtrlLaunchingModalId
= "ctrl_launch_modal";
70 // ----------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------
74 // ----------------------------------------------------------------------------
75 void CWidgetManager::SMasterGroup::addWindow(CInterfaceGroup
*pIG
, uint8 nPrio
)
77 nlassert(nPrio
<WIN_PRIORITY_MAX
);
79 // Priority WIN_PRIORITY_WORLD_SPACE is only for CGroupInScene !
80 // Add this group in another priority list
81 nlassert ((nPrio
!=WIN_PRIORITY_MAX
) || pIG
->isGroupInScene() );
83 for (uint8 i
= 0; i
< WIN_PRIORITY_MAX
; ++i
)
85 std::list
<CInterfaceGroup
*>::iterator it
= PrioritizedWindows
[i
].begin();
86 while (it
!= PrioritizedWindows
[i
].end())
88 // If the element already exists in the list return !
94 PrioritizedWindows
[nPrio
].push_back(pIG
);
97 // ----------------------------------------------------------------------------
98 void CWidgetManager::SMasterGroup::delWindow(CInterfaceGroup
*pIG
)
100 for (uint8 i
= 0; i
< WIN_PRIORITY_MAX
; ++i
)
102 std::list
<CInterfaceGroup
*>::iterator it
= PrioritizedWindows
[i
].begin();
103 while (it
!= PrioritizedWindows
[i
].end())
107 PrioritizedWindows
[i
].erase(it
);
115 // ----------------------------------------------------------------------------
116 CInterfaceGroup
* CWidgetManager::SMasterGroup::getWindowFromId(const std::string
&winID
)
118 for (uint8 i
= 0; i
< WIN_PRIORITY_MAX
; ++i
)
120 std::list
<CInterfaceGroup
*>::iterator it
= PrioritizedWindows
[i
].begin();
121 while (it
!= PrioritizedWindows
[i
].end())
123 if ((*it
)->getId() == winID
)
131 // ----------------------------------------------------------------------------
132 bool CWidgetManager::SMasterGroup::isWindowPresent(CInterfaceGroup
*pIG
)
134 for (uint8 i
= 0; i
< WIN_PRIORITY_MAX
; ++i
)
136 std::list
<CInterfaceGroup
*>::iterator it
= PrioritizedWindows
[i
].begin();
137 while (it
!= PrioritizedWindows
[i
].end())
147 // Set a window top in its priority queue
148 // ----------------------------------------------------------------------------
149 void CWidgetManager::SMasterGroup::setTopWindow(CInterfaceGroup
*pIG
)
151 for (uint8 i
= 0; i
< WIN_PRIORITY_MAX
; ++i
)
153 std::list
<CInterfaceGroup
*>::iterator it
= PrioritizedWindows
[i
].begin();
154 while (it
!= PrioritizedWindows
[i
].end())
158 PrioritizedWindows
[i
].erase(it
);
159 PrioritizedWindows
[i
].push_back(pIG
);
160 LastTopWindowPriority
= i
;
166 // todo hulud interface syntax error
167 nlwarning("window %s do not exist in a priority list", pIG
->getId().c_str());
170 // ----------------------------------------------------------------------------
171 void CWidgetManager::SMasterGroup::setBackWindow(CInterfaceGroup
*pIG
)
173 for (uint8 i
= 0; i
< WIN_PRIORITY_MAX
; ++i
)
175 std::list
<CInterfaceGroup
*>::iterator it
= PrioritizedWindows
[i
].begin();
176 while (it
!= PrioritizedWindows
[i
].end())
180 PrioritizedWindows
[i
].erase(it
);
181 PrioritizedWindows
[i
].push_front(pIG
);
187 // todo hulud interface syntax error
188 nlwarning("window %s do not exist in a priority list", pIG
->getId().c_str());
191 // ----------------------------------------------------------------------------
192 void CWidgetManager::SMasterGroup::deactiveAllContainers()
194 std::vector
<CGroupContainerBase
*> gcs
;
196 // Make first a list of all window (Warning: all group container are not window!)
197 for (uint8 i
= 0; i
< WIN_PRIORITY_MAX
; ++i
)
199 std::list
<CInterfaceGroup
*>::iterator it
= PrioritizedWindows
[i
].begin();
200 while (it
!= PrioritizedWindows
[i
].end())
202 CGroupContainerBase
*pGC
= dynamic_cast<CGroupContainerBase
*>(*it
);
209 // Then hide them. Must do this in 2 times, because setActive(false) change PrioritizedWindows,
210 // and hence invalidate its.
211 for (uint32 i
= 0; i
< gcs
.size(); ++i
)
213 gcs
[i
]->setActive(false);
217 // ----------------------------------------------------------------------------
218 void CWidgetManager::SMasterGroup::centerAllContainers()
220 for (uint8 i
= 0; i
< WIN_PRIORITY_MAX
; ++i
)
222 std::list
<CInterfaceGroup
*>::iterator it
= PrioritizedWindows
[i
].begin();
223 while (it
!= PrioritizedWindows
[i
].end())
225 CGroupContainerBase
*pGC
= dynamic_cast<CGroupContainerBase
*>(*it
);
226 if ((pGC
!= NULL
) && (pGC
->getParent() != NULL
))
228 sint32 wParent
= pGC
->getParent()->getW(false);
229 sint32 w
= pGC
->getW(false);
230 pGC
->setXAndInvalidateCoords((wParent
- w
) / 2);
231 sint32 hParent
= pGC
->getParent()->getH(false);
232 sint32 h
= pGC
->getH(false);
233 pGC
->setYAndInvalidateCoords(h
+(hParent
- h
) / 2);
241 // ----------------------------------------------------------------------------
242 void CWidgetManager::SMasterGroup::unlockAllContainers()
244 for (uint8 i
= 0; i
< WIN_PRIORITY_MAX
; ++i
)
246 std::list
<CInterfaceGroup
*>::iterator it
= PrioritizedWindows
[i
].begin();
247 while (it
!= PrioritizedWindows
[i
].end())
249 CGroupContainerBase
*pGC
= dynamic_cast<CGroupContainerBase
*>(*it
);
251 pGC
->setLocked(false);
261 CInterfaceGroup
*pIG
;
263 bool operator< (const CElementToSort
& other
) const
265 // We want first farest views
266 return Distance
> other
.Distance
;
270 void CWidgetManager::SMasterGroup::sortWorldSpaceGroup ()
272 static std::vector
<CElementToSort
> sortTable
;
275 // Fill the sort table
276 std::list
<CInterfaceGroup
*>::iterator it
= PrioritizedWindows
[WIN_PRIORITY_WORLD_SPACE
].begin();
277 while (it
!= PrioritizedWindows
[WIN_PRIORITY_WORLD_SPACE
].end())
279 sortTable
.push_back (CElementToSort ());
280 CElementToSort
&elm
= sortTable
.back();
282 elm
.Distance
= (*it
)->getDepthForZSort();
288 std::sort (sortTable
.begin(), sortTable
.end());
290 // Fill the final table
292 it
= PrioritizedWindows
[WIN_PRIORITY_WORLD_SPACE
].begin();
293 while (it
!= PrioritizedWindows
[WIN_PRIORITY_WORLD_SPACE
].end())
295 *it
= sortTable
[i
].pIG
;
303 CWidgetManager
* CWidgetManager::getInstance()
305 if( instance
== NULL
)
306 instance
= new CWidgetManager
;
311 void CWidgetManager::release()
317 // ----------------------------------------------------------------------------
318 CInterfaceGroup
* CWidgetManager::getMasterGroupFromId (const std::string
&MasterGroupName
)
320 for (uint32 i
= 0; i
< _MasterGroups
.size(); ++i
)
322 if (_MasterGroups
[i
].Group
->getId() == MasterGroupName
)
323 return _MasterGroups
[i
].Group
;
328 // ----------------------------------------------------------------------------
329 CInterfaceGroup
* CWidgetManager::getWindowFromId (const std::string
& groupId
)
331 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
333 SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
334 CInterfaceGroup
*pIG
= rMG
.getWindowFromId(groupId
);
341 // ----------------------------------------------------------------------------
342 void CWidgetManager::addWindowToMasterGroup (const std::string
&sMasterGroupName
, CInterfaceGroup
*pIG
)
344 // Warning this function is not smart : its a o(n) !
345 if (pIG
== NULL
) return;
346 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); ++nMasterGroup
)
348 SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
349 if (rMG
.Group
->getId() == sMasterGroupName
)
351 rMG
.addWindow(pIG
, pIG
->getPriority());
356 // ----------------------------------------------------------------------------
357 void CWidgetManager::removeWindowFromMasterGroup(const std::string
&sMasterGroupName
,CInterfaceGroup
*pIG
)
359 // Warning this function is not smart : its a o(n) !
360 if (pIG
== NULL
) return;
361 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); ++nMasterGroup
)
363 SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
364 if (rMG
.Group
->getId() == sMasterGroupName
)
371 void unlinkAllContainers (CInterfaceGroup
*pIG
)
373 const std::vector
<CInterfaceGroup
*> &rG
= pIG
->getGroups();
374 for(uint i
= 0; i
< rG
.size(); ++i
)
375 unlinkAllContainers (rG
[i
]);
377 CGroupContainerBase
*pGC
= dynamic_cast<CGroupContainerBase
*>(pIG
);
379 pGC
->removeAllContainers();
382 // ***************************************************************************
383 void CWidgetManager::removeAllMasterGroups()
387 for (i
= 0; i
< _MasterGroups
.size(); ++i
)
388 unlinkAllContainers (_MasterGroups
[i
].Group
);
390 // Yoyo: important to not Leave NULL in the array, because of CGroupHTML and LibWWW callback
391 // that may call CInterfaceManager::getElementFromId() (and this method hates having NULL in the arrays ^^)
392 while(!_MasterGroups
.empty())
394 delete _MasterGroups
.back().Group
;
395 _MasterGroups
.pop_back();
400 // ------------------------------------------------------------------------------------------------
401 void CWidgetManager::activateMasterGroup (const std::string
&sMasterGroupName
, bool bActive
)
403 CInterfaceGroup
*pIG
= getMasterGroupFromId (sMasterGroupName
);
406 pIG
->setActive(bActive
);
407 pIG
->invalidateCoords();
411 // ------------------------------------------------------------------------------------------------
412 CInterfaceGroup
* CWidgetManager::getWindow(CInterfaceElement
*pIE
)
414 CInterfaceGroup
*pIG
= pIE
->getParent();
415 if (pIG
== NULL
) return NULL
;
416 if (pIG
->getParent() == NULL
) return NULL
;
417 while (pIG
->getParent()->getParent() != NULL
)
419 pIG
= pIG
->getParent();
425 // ------------------------------------------------------------------------------------------------
426 CInterfaceElement
* CWidgetManager::getElementFromId (const std::string
&sEltId
)
429 if(sEltId
== _CtrlLaunchingModalId
)
430 return getCtrlLaunchingModal();
432 // Search for all elements
433 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
435 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
436 CInterfaceElement
*pIEL
= rMG
.Group
->getElement (sEltId
);
443 // ------------------------------------------------------------------------------------------------
444 CInterfaceElement
* CWidgetManager::getElementFromId (const std::string
&sStart
, const std::string
&sEltId
)
446 CInterfaceElement
*pIEL
= getElementFromId (sEltId
);
449 std::string sZeStart
= sStart
, sTmp
;
450 if (sZeStart
[sZeStart
.size()-1] == ':')
451 sZeStart
= sZeStart
.substr(0, sZeStart
.size()-1);
453 while (!sZeStart
.empty())
455 if (sEltId
[0] == ':')
456 sTmp
= sZeStart
+ sEltId
;
458 sTmp
= sZeStart
+ ":" + sEltId
;
459 pIEL
= getElementFromId (sTmp
);
462 std::string::size_type nextPos
= sZeStart
.rfind(':');
463 if (nextPos
== std::string::npos
) break;
464 sZeStart
= sZeStart
.substr(0, nextPos
);
470 // ------------------------------------------------------------------------------------------------
471 CInterfaceElement
* CWidgetManager::getElementFromDefine( const std::string
&defineId
)
473 return getElementFromId( _Parser
->getDefine( defineId
) );
476 // ------------------------------------------------------------------------------------------------
477 void CWidgetManager::setTopWindow (CInterfaceGroup
* win
)
479 //find the window in the window list
480 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
482 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
483 if (rMG
.Group
->getActive())
484 rMG
.setTopWindow(win
);
488 // ------------------------------------------------------------------------------------------------
489 void CWidgetManager::setBackWindow(CInterfaceGroup
* win
)
491 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
493 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
494 if (rMG
.Group
->getActive())
495 rMG
.setBackWindow(win
);
499 // ------------------------------------------------------------------------------------------------
500 CInterfaceGroup
* CWidgetManager::getTopWindow (uint8 nPriority
) const
502 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
504 const CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
505 if (rMG
.Group
->getActive())
508 if(rMG
.PrioritizedWindows
[nPriority
].empty())
511 return rMG
.PrioritizedWindows
[nPriority
].back();
518 // ------------------------------------------------------------------------------------------------
519 CInterfaceGroup
* CWidgetManager::getBackWindow (uint8 nPriority
) const
521 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
523 const CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
524 if (rMG
.Group
->getActive())
527 if(rMG
.PrioritizedWindows
[nPriority
].empty())
530 return rMG
.PrioritizedWindows
[nPriority
].front();
536 // ***************************************************************************
537 CInterfaceGroup
* CWidgetManager::getLastEscapableTopWindow() const
539 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
541 const CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
542 if (rMG
.Group
->getActive())
544 for (uint8 nPriority
= WIN_PRIORITY_MAX
; nPriority
> 0; nPriority
--)
546 const std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
-1];
547 std::list
<CInterfaceGroup
*>::const_reverse_iterator it
;
549 for(;it
!=rList
.rend();it
++)
551 if((*it
)->getActive() && (*it
)->getEscapable())
560 // ***************************************************************************
561 void CWidgetManager::setWindowPriority (CInterfaceGroup
*pWin
, uint8 nNewPriority
)
563 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
565 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
566 if (rMG
.Group
->getActive())
568 if (rMG
.isWindowPresent(pWin
))
571 rMG
.addWindow(pWin
, nNewPriority
);
577 // ***************************************************************************
578 uint8
CWidgetManager::getLastTopWindowPriority() const
580 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
582 const CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
583 if (rMG
.Group
->getActive())
585 return rMG
.LastTopWindowPriority
;
591 bool CWidgetManager::hasModal() const
593 if( !_ModalStack
.empty() )
599 CWidgetManager::SModalWndInfo
& CWidgetManager::getModal()
601 return _ModalStack
.back();
604 bool CWidgetManager::isPreviousModal( CInterfaceGroup
*wnd
) const
606 std::vector
< SModalWndInfo
>::size_type s
= _ModalStack
.size();
607 for( std::vector
< SModalWndInfo
>::size_type i
= 0; i
< s
; i
++ )
608 if( _ModalStack
[ i
].ModalWindow
== wnd
)
614 // ------------------------------------------------------------------------------------------------
615 void CWidgetManager::enableModalWindow (CCtrlBase
*ctrlLaunchingModal
, CInterfaceGroup
*pIG
)
617 // disable any modal before. release keyboard
618 disableModalWindow();
619 pushModalWindow(ctrlLaunchingModal
, pIG
);
622 // ------------------------------------------------------------------------------------------------
623 void CWidgetManager::enableModalWindow (CCtrlBase
*CtrlLaunchingModal
, const std::string
&groupName
)
625 CInterfaceGroup
*group
= dynamic_cast<CGroupModal
*>( getElementFromId(groupName
) );
629 enableModalWindow(CtrlLaunchingModal
, group
);
633 // ------------------------------------------------------------------------------------------------
634 void CWidgetManager::disableModalWindow ()
636 while (!_ModalStack
.empty())
638 SModalWndInfo winInfo
= _ModalStack
.back();
639 _ModalStack
.pop_back(); // must pop back as early as possible because 'setActive' may trigger another 'popModalWindow', leading to a crash
640 // disable old modal window
641 if(winInfo
.ModalWindow
)
643 setBackWindow(winInfo
.ModalWindow
);
644 winInfo
.ModalWindow
->setActive(false);
648 // disable any context help
649 setCurContextHelp( NULL
);
650 _DeltaTimeStopingContextHelp
= 0;
653 // ------------------------------------------------------------------------------------------------
654 void CWidgetManager::pushModalWindow(CCtrlBase
*ctrlLaunchingModal
, CInterfaceGroup
*pIG
)
656 // enable the wanted modal
660 mwi
.ModalWindow
= pIG
;
661 mwi
.CtrlLaunchingModal
= ctrlLaunchingModal
;
662 // setup special group
663 CGroupModal
*groupModal
= dynamic_cast<CGroupModal
*>(pIG
);
666 mwi
.ModalExitClickOut
= groupModal
->ExitClickOut
;
667 mwi
.ModalExitClickL
= groupModal
->ExitClickL
;
668 mwi
.ModalExitClickR
= groupModal
->ExitClickR
;
669 mwi
.ModalHandlerClickOut
= groupModal
->OnClickOut
;
670 mwi
.ModalClickOutParams
= groupModal
->OnClickOutParams
;
671 mwi
.ModalExitKeyPushed
= groupModal
->ExitKeyPushed
;
672 // update coords of the modal
673 if(groupModal
->SpawnOnMousePos
)
675 groupModal
->SpawnMouseX
= _Pointer
->getX();
676 groupModal
->SpawnMouseY
= _Pointer
->getY();
681 // default for group not modal. Backward compatibility
682 mwi
.ModalExitClickOut
= false;
683 mwi
.ModalExitClickL
= false;
684 mwi
.ModalExitClickR
= false;
685 mwi
.ModalExitKeyPushed
= false;
688 _ModalStack
.push_back(mwi
);
690 // update coords and activate the modal
691 mwi
.ModalWindow
->invalidateCoords();
692 mwi
.ModalWindow
->setActive(true);
693 setTopWindow(mwi
.ModalWindow
);
697 // ------------------------------------------------------------------------------------------------
698 void CWidgetManager::pushModalWindow(CCtrlBase
*ctrlLaunchingModal
, const std::string
&groupName
)
700 CInterfaceGroup
*group
= dynamic_cast<CGroupModal
*>( getElementFromId(groupName
) );
704 enableModalWindow(ctrlLaunchingModal
, group
);
708 // ------------------------------------------------------------------------------------------------
709 void CWidgetManager::popModalWindow()
711 if (!_ModalStack
.empty())
713 SModalWndInfo winInfo
= _ModalStack
.back();
714 _ModalStack
.pop_back(); // must pop back as early as possible because 'setActive' may trigger another 'popModalWindow', leading to a crash
715 if(winInfo
.ModalWindow
)
717 setBackWindow(winInfo
.ModalWindow
);
718 winInfo
.ModalWindow
->setActive(false);
720 if (!_ModalStack
.empty())
722 if(_ModalStack
.back().ModalWindow
)
724 _ModalStack
.back().ModalWindow
->setActive(true);
725 setTopWindow(_ModalStack
.back().ModalWindow
);
731 // ------------------------------------------------------------------------------------------------
732 void CWidgetManager::popModalWindowCategory(const std::string
&category
)
736 if (_ModalStack
.empty()) break;
737 if (!_ModalStack
.back().ModalWindow
) break;
738 CGroupModal
*gm
= dynamic_cast<CGroupModal
*>((CInterfaceGroup
*)(_ModalStack
.back().ModalWindow
));
739 if (gm
&& gm
->Category
== category
)
741 _ModalStack
.back().ModalWindow
->setActive(false);
742 _ModalStack
.pop_back();
751 // ***************************************************************************
752 void CWidgetManager::hideAllWindows()
754 for (uint nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
756 SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
757 if (rMG
.Group
->getActive())
759 for (uint8 nPriority
= 0; nPriority
< WIN_PRIORITY_MAX
; nPriority
++)
761 std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
];
762 std::list
<CInterfaceGroup
*>::const_iterator itw
;
763 for (itw
= rList
.begin(); itw
!= rList
.end();)
765 CInterfaceGroup
*pIG
= *itw
;
766 itw
++; // since setActive invalidate the iterator, be sure we move to the next one before
767 pIG
->setActive(false);
774 // ***************************************************************************
775 void CWidgetManager::hideAllNonSavableWindows()
777 for (uint nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
779 SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
780 if (rMG
.Group
->getActive())
782 for (uint8 nPriority
= 0; nPriority
< WIN_PRIORITY_MAX
; nPriority
++)
784 std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
];
785 std::list
<CInterfaceGroup
*>::const_iterator itw
;
786 for (itw
= rList
.begin(); itw
!= rList
.end();)
788 CInterfaceGroup
*pIG
= *itw
;
789 CGroupContainer
*cont
= dynamic_cast<CGroupContainer
*>(pIG
);
790 itw
++; // since setActive invalidate the iterator, be sure we move to the next one before
791 if (!cont
|| !cont
->isSavable())
793 pIG
->setActive(false);
801 // ------------------------------------------------------------------------------------------------
802 CInterfaceGroup
* CWidgetManager::getWindowUnder (sint32 x
, sint32 y
)
804 H_AUTO (RZ_Interface_Window_Under
)
806 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
808 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
809 if (rMG
.Group
->getActive())
811 for (uint8 nPriority
= WIN_PRIORITY_MAX
; nPriority
> 0; nPriority
--)
813 const std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
-1];
814 std::list
<CInterfaceGroup
*>::const_reverse_iterator itw
;
815 for (itw
= rList
.rbegin(); itw
!= rList
.rend(); itw
++)
817 CInterfaceGroup
*pIG
= *itw
;
818 if (pIG
->getActive() && pIG
->getUseCursor())
820 if (pIG
->isWindowUnder (x
, y
))
830 // ------------------------------------------------------------------------------------------------
831 CInterfaceGroup
* CWidgetManager::getGroupUnder (sint32 x
, sint32 y
)
833 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
835 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
836 if (rMG
.Group
->getActive())
838 for (uint8 nPriority
= WIN_PRIORITY_MAX
; nPriority
> 0; nPriority
--)
840 const std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
-1];
841 std::list
<CInterfaceGroup
*>::const_reverse_iterator itw
;
842 for (itw
= rList
.rbegin(); itw
!= rList
.rend(); itw
++)
844 CInterfaceGroup
*pIG
= *itw
;
845 if (pIG
->getActive() && pIG
->getUseCursor())
847 CInterfaceGroup
*pIGunder
= pIG
->getGroupUnder (x
,y
);
848 if (pIGunder
!= NULL
)
858 // ------------------------------------------------------------------------------------------------
859 void CWidgetManager::getViewsUnder (sint32 x
, sint32 y
, std::vector
<CViewBase
*> &vVB
)
863 // No Op if screen minimized
864 if(CViewRenderer::getInstance()->isMinimized())
868 CViewRenderer::getInstance()->getScreenSize(sw
, sh
);
869 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
871 SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
872 if (rMG
.Group
->getActive())
874 for (uint8 nPriority
= WIN_PRIORITY_MAX
; nPriority
> 0; nPriority
--)
876 const std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
-1];
877 std::list
<CInterfaceGroup
*>::const_reverse_iterator itw
;
878 for (itw
= rList
.rbegin(); itw
!= rList
.rend(); itw
++)
880 CInterfaceGroup
*pIG
= *itw
;
882 // Accecpt if not modal clip
883 if (pIG
->getActive() && pIG
->getUseCursor())
885 if (pIG
->getViewsUnder (x
, y
, 0, 0, (sint32
) sw
, (sint32
) sh
, vVB
))
894 // ------------------------------------------------------------------------------------------------
895 void CWidgetManager::getCtrlsUnder (sint32 x
, sint32 y
, std::vector
<CCtrlBase
*> &vICL
)
899 // No Op if screen minimized
900 if(CViewRenderer::getInstance()->isMinimized())
904 CViewRenderer::getInstance()->getScreenSize(sw
, sh
);
905 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
907 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
908 if (rMG
.Group
->getActive())
910 for (uint8 nPriority
= WIN_PRIORITY_MAX
; nPriority
> 0 ; nPriority
--)
912 const std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
-1];
913 std::list
<CInterfaceGroup
*>::const_reverse_iterator itw
;
914 for (itw
= rList
.rbegin(); itw
!= rList
.rend(); itw
++)
916 CInterfaceGroup
*pIG
= *itw
;
918 // Accecpt if not modal clip
919 if (!hasModal() || getModal().ModalWindow
== pIG
|| getModal().ModalExitClickOut
)
920 if (pIG
->getActive() && pIG
->getUseCursor())
922 if (pIG
->getCtrlsUnder (x
, y
, 0, 0, (sint32
) sw
, (sint32
) sh
, vICL
))
932 // ------------------------------------------------------------------------------------------------
933 void CWidgetManager::getGroupsUnder (sint32 x
, sint32 y
, std::vector
<CInterfaceGroup
*> &vIGL
)
937 // No Op if screen minimized
938 if(CViewRenderer::getInstance()->isMinimized())
942 CViewRenderer::getInstance()->getScreenSize(sw
, sh
);
943 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
945 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
946 if (rMG
.Group
->getActive())
948 for (uint8 nPriority
= WIN_PRIORITY_MAX
; nPriority
> 0 ; nPriority
--)
950 const std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
-1];
951 std::list
<CInterfaceGroup
*>::const_reverse_iterator itw
;
952 for (itw
= rList
.rbegin(); itw
!= rList
.rend(); itw
++)
954 CInterfaceGroup
*pIG
= *itw
;
956 // Accecpt if not modal clip
957 if (!hasModal() || getModal().ModalWindow
== pIG
||
958 getModal().ModalExitClickOut
)
959 if (pIG
->getActive() && pIG
->getUseCursor())
964 pIG
->getGroupsUnder (x
, y
, 0, 0, (sint32
) sw
, (sint32
) sh
, vIGL
);
975 // ***************************************************************************
976 void CWidgetManager::removeRefOnView( CViewBase
*viewBase
)
979 for (i
=0; i
<_ViewsUnderPointer
.size(); i
++)
981 if (_ViewsUnderPointer
[i
] == viewBase
)
983 _ViewsUnderPointer
.erase (_ViewsUnderPointer
.begin()+i
);
989 // ***************************************************************************
990 void CWidgetManager::removeRefOnCtrl(CCtrlBase
*ctrlBase
)
992 if ( getCurContextHelp() == ctrlBase
)
993 setCurContextHelp( NULL
);
994 if (getCapturePointerLeft() == ctrlBase
)
995 setCapturePointerLeft(NULL
);
996 if (getCapturePointerRight() == ctrlBase
)
997 setCapturePointerRight (NULL
);
998 if (getCaptureKeyboard() == ctrlBase
)
999 setCaptureKeyboard(NULL
);
1000 if (getOldCaptureKeyboard() == ctrlBase
)
1001 setOldCaptureKeyboard(NULL
);
1002 if (getDefaultCaptureKeyboard() == ctrlBase
)
1003 setDefaultCaptureKeyboard(NULL
);
1005 for (i
=0; i
<_CtrlsUnderPointer
.size(); i
++)
1007 if (_CtrlsUnderPointer
[i
] == ctrlBase
)
1009 _CtrlsUnderPointer
.erase (_CtrlsUnderPointer
.begin()+i
);
1014 // Unregister from ClockMsgTargets
1015 unregisterClockMsgTarget(ctrlBase
);
1019 // ***************************************************************************
1020 void CWidgetManager::removeRefOnGroup (CInterfaceGroup
*group
)
1023 for (i
=0; i
<_GroupsUnderPointer
.size(); i
++)
1025 if (_GroupsUnderPointer
[i
] == group
)
1027 _GroupsUnderPointer
.erase (_GroupsUnderPointer
.begin()+i
);
1034 void CWidgetManager::reset()
1036 setCurContextHelp( NULL
);
1038 _ViewsUnderPointer
.clear();
1039 _CtrlsUnderPointer
.clear();
1040 _GroupsUnderPointer
.clear();
1042 _CaptureKeyboard
= NULL
;
1043 _OldCaptureKeyboard
= NULL
;
1044 setCapturePointerLeft(NULL
);
1045 setCapturePointerRight(NULL
);
1046 _CapturedView
= NULL
;
1049 resetAlphaRolloverSpeedProps();
1050 resetGlobalAlphasProps();
1052 _ContextHelpContentAlphaDB
= NULL
;
1053 _ContextHelpContainerColorDB
= NULL
;
1054 _ContextHelpContainerAlphaDB
= NULL
;
1056 activeAnims
.clear();
1058 editorSelection
.clear();
1062 // ------------------------------------------------------------------------------------------------
1063 void CWidgetManager::checkCoords()
1065 H_AUTO ( RZ_Interface_validateCoords
)
1067 uint32 nMasterGroup
;
1070 H_AUTO ( RZ_Interface_checkCoords
)
1072 // checkCoords all the windows
1073 for (nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
1075 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
1076 if (rMG
.Group
->getActive())
1078 for (uint8 nPriority
= 0; nPriority
< WIN_PRIORITY_MAX
; nPriority
++)
1080 std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
];
1081 std::list
<CInterfaceGroup
*>::const_iterator itw
;
1082 for (itw
= rList
.begin(); itw
!= rList
.end();)
1084 CInterfaceGroup
*pIG
= *itw
;
1085 itw
++; // since checkCoords invalidate the iterator, be sure we move to the next one before
1086 if (pIG
->getActive())
1087 pIG
->checkCoords ();
1094 bool bRecomputeCtrlUnderPtr
= false;
1096 H_AUTO ( RZ_Interface_updateCoords
)
1098 // updateCoords all the needed windows
1099 for (nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
1101 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
1102 if (rMG
.Group
->getActive())
1104 for (uint8 nPriority
= 0; nPriority
< WIN_PRIORITY_MAX
; nPriority
++)
1106 std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
];
1107 std::list
<CInterfaceGroup
*>::const_iterator itw
;
1108 for (itw
= rList
.begin(); itw
!= rList
.end(); itw
++)
1110 CInterfaceGroup
*pIG
= *itw
;
1111 bool updateCoordCalled
= false;
1112 // updateCoords the window only if the master group is his parent and if need it
1113 // do it until updateCoords() no more invalidate coordinates!!
1115 // add deadlock counter to prevent endless loop (Issue #73: web browser long scroll lockup)
1117 while (--deadlock
> 0 && pIG
->getParent()==rMG
.Group
&& (pIG
->getInvalidCoords()>0))
1119 bRecomputeCtrlUnderPtr
= true;
1120 // Update as many pass wanted (3 time for complex resizing, 1 for scroll for example)
1121 uint numPass
= pIG
->getInvalidCoords();
1122 // reset before updateCoords
1123 pIG
->resetInvalidCoords();
1124 for(uint i
=0;i
<numPass
;i
++)
1126 pIG
->updateCoords ();
1128 updateCoordCalled
= true;
1130 // If the group need to update pos each frame (eg: CGroupInScene),
1131 // and updateCoords not called
1132 if(pIG
->getParent()==rMG
.Group
&& !updateCoordCalled
&& pIG
->isNeedFrameUpdatePos())
1134 // This Group will compute the delta to apply.
1135 pIG
->onFrameUpdateWindowPos(0,0);
1142 if ( getPointer() != NULL
)
1143 getPointer()->updateCoords();
1148 if (bRecomputeCtrlUnderPtr
)
1150 H_AUTO ( RZ_Interface_RecomputeCtrlUnderPtr
)
1151 if ( getPointer() != NULL
)
1153 sint32 mx
= _Pointer
->getX();
1154 sint32 my
= _Pointer
->getY();
1155 getViewsUnder (mx
, my
, _ViewsUnderPointer
);
1156 getCtrlsUnder (mx
, my
, _CtrlsUnderPointer
);
1157 getGroupsUnder (mx
, my
, _GroupsUnderPointer
);
1158 CInterfaceGroup
*ptr
= getWindowUnder (mx
, my
);
1165 // ----------------------------------------------------------------------------
1166 CInterfaceGroup
* CWidgetManager::getWindowForActiveMasterGroup( const std::string
&window
)
1168 // Search for all elements
1169 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
1171 const SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
1172 if (rMG
.Group
->getActive())
1174 CInterfaceElement
*pEL
= getElementFromId( rMG
.Group
->getId() + ":" + window
);
1175 if(pEL
&& pEL
->isGroup())
1176 return (CInterfaceGroup
*)pEL
;
1184 // ***************************************************************************
1185 void CWidgetManager::drawOverExtendViewText()
1187 if( getOverExtendViewText() )
1189 CViewText
*vtSrc
= dynamic_cast<CViewText
*>( getOverExtendViewText() );
1191 CInterfaceGroup
*groupOver
= getWindowForActiveMasterGroup("over_extend_view_text");
1194 CViewText
*vtDst
= dynamic_cast<CViewText
*>(groupOver
->getView("text"));
1197 groupOver
->setParentPos(vtSrc
);
1199 sint32 backupX
= groupOver
->getX();
1201 // Copy all aspects to the view
1202 vtDst
->setLocalized (vtSrc
->isLocalized());
1203 vtDst
->setText (vtSrc
->getText());
1204 vtDst
->setFontSize (vtSrc
->getFontSize());
1205 vtDst
->setColor (vtSrc
->getColor());
1206 vtDst
->setModulateGlobalColor(vtSrc
->getModulateGlobalColor());
1207 vtDst
->setShadow(vtSrc
->getShadow());
1208 vtDst
->setShadowOutline(vtSrc
->getShadowOutline());
1209 vtDst
->setShadowColor(vtSrc
->getShadowColor());
1210 vtDst
->setCaseMode(vtSrc
->getCaseMode());
1211 vtDst
->setUnderlined(vtSrc
->getUnderlined());
1214 CViewBitmap
*pBack
= dynamic_cast<CViewBitmap
*>(groupOver
->getView("midback"));
1215 CViewBitmap
*pOutline
= dynamic_cast<CViewBitmap
*>(groupOver
->getView("midoutline"));
1217 pBack
->setColor( getOverExtendViewTextBackColor() );
1220 pOutline
->setColor(vtSrc
->getColor());
1221 pOutline
->setModulateGlobalColor(vtSrc
->getModulateGlobalColor());
1224 // update one time only to get correct W/H
1225 groupOver
->updateCoords ();
1227 // align and clamp to screen coords
1228 sint32 x
= -backupX
;
1229 if (vtSrc
->isClampRight())
1231 x
+= std::max(0, (groupOver
->getXReal() + groupOver
->getWReal()) - (groupOver
->getParent()->getXReal() + groupOver
->getParent()->getWReal()));
1235 x
+= vtDst
->getWReal() - vtSrc
->getWReal();
1236 if ( x
> (groupOver
->getXReal() - groupOver
->getParent()->getXReal()) )
1238 x
-= x
- (groupOver
->getXReal() - groupOver
->getParent()->getXReal());
1241 if (x
!= 0) groupOver
->setX(-x
);
1243 // TODO: there should be no overflow on y, unless barely visible and next to screen border
1245 groupOver
->updateCoords();
1250 CViewRenderer::getInstance()->flush();
1252 // restore backup values
1253 if (x
!= 0) groupOver
->setX(backupX
);
1257 // Reset the ptr so at next frame, won't be rendered (but if reset)
1258 setOverExtendViewText( NULL
, getOverExtendViewTextBackColor() );
1262 // ----------------------------------------------------------------------------
1263 void CWidgetManager::snapIfClose(CInterfaceGroup
*group
)
1265 if (!group
|| _WindowSnapDistance
== 0 || _WindowSnapInvert
!= lastKeyEvent
.isShiftDown())
1268 uint hsnap
= _WindowSnapDistance
;
1269 uint vsnap
= _WindowSnapDistance
;
1271 sint32 newX
= group
->getX();
1272 sint32 newY
= group
->getY();
1274 // new coords for window without snap
1275 // used to calculate distance from target
1277 sint gRight
= newX
+ group
->getWReal();
1279 sint gBottom
= newY
- group
->getHReal();
1281 // current window coords as if already snaped
1282 // used to calculate target for snap
1283 sint gLeftR
= group
->getXReal();
1284 sint gRightR
= gLeftR
+ group
->getWReal();
1285 sint gBottomR
= group
->getYReal();
1286 sint gTopR
= gBottomR
+ group
->getHReal();
1288 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
1290 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
1291 if (!rMG
.Group
->getActive()) continue;
1293 for (uint8 nPriority
= WIN_PRIORITY_MAX
; nPriority
> 0 ; nPriority
--)
1295 const std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
-1];
1296 std::list
<CInterfaceGroup
*>::const_reverse_iterator itw
;
1297 for (itw
= rList
.rbegin(); itw
!= rList
.rend(); itw
++)
1299 CInterfaceGroup
*pIG
= *itw
;
1300 // do not snap to self, inactive, or not using mouse interaction
1301 if (group
== pIG
|| !(pIG
->getActive() && pIG
->getUseCursor()))
1305 sint wLeft
= pIG
->getXReal();
1306 sint wRight
= pIG
->getXReal() + pIG
->getWReal();
1307 sint wTop
= pIG
->getYReal() + pIG
->getHReal();
1308 sint wBottom
= pIG
->getYReal();
1311 if (gTopR
>= wBottom
&& gBottomR
<= wTop
)
1313 delta
= abs(gRight
- wLeft
);
1317 newX
= wLeft
- group
->getWReal();
1320 delta
= abs(gLeft
- wRight
);
1327 delta
= abs(gLeft
- wLeft
);
1334 delta
= abs(gRight
- wRight
);
1338 newX
= wRight
- group
->getWReal();
1342 if (gLeftR
<= wRight
&& gRightR
>= wLeft
)
1344 delta
= abs(gTop
- wBottom
);
1351 delta
= abs(gBottom
- wTop
);
1355 newY
= wTop
+ group
->getHReal();
1358 delta
= abs(gTop
- wTop
);
1365 delta
= abs(gBottom
- wBottom
);
1369 newY
= wBottom
+ group
->getHReal();
1380 // ----------------------------------------------------------------------------
1381 uint
CWidgetManager::adjustTooltipPosition( CCtrlBase
*newCtrl
, CInterfaceGroup
*win
, THotSpot ttParentRef
,
1382 THotSpot ttPosRef
, sint32 xParent
, sint32 yParent
,
1383 sint32 wParent
, sint32 hParent
)
1385 CCtrlBase::TToolTipParentType parentType
= newCtrl
->getToolTipParent();
1386 CInterfaceGroup
*groupContextHelp
=
1387 getWindowForActiveMasterGroup(newCtrl
->getContextHelpWindowName());
1389 uint32 _ScreenH
, _ScreenW
;
1390 CViewRenderer::getInstance()->getScreenSize( _ScreenW
, _ScreenH
);
1392 if(ttPosRef
==Hotspot_TTAuto
|| ttParentRef
==Hotspot_TTAuto
)
1394 // NB: keep the special window if type is specialwindow (defined above)
1396 win
= newCtrl
->getRootWindow();
1403 xWin
= win
->getXReal();
1404 yWin
= win
->getYReal();
1405 wWin
= win
->getWReal();
1406 hWin
= win
->getHReal();
1408 // for Window, display top or bottom according to window pos/size
1409 if(parentType
==CCtrlBase::TTWindow
|| parentType
==CCtrlBase::TTSpecialWindow
)
1411 sint32 top
= (sint32
)_ScreenH
- (yWin
+hWin
);
1412 sint32 bottom
= yWin
;
1415 ttParentRef
= Hotspot_TL
;
1416 ttPosRef
= Hotspot_BL
;
1420 ttParentRef
= Hotspot_BL
;
1421 ttPosRef
= Hotspot_TL
;
1424 // for Ctrl, display top, left or right according to window pos/size
1425 else if(parentType
==CCtrlBase::TTCtrl
)
1427 sint32 right
= (sint32
)_ScreenW
- (xWin
+wWin
);
1431 ttParentRef
= Hotspot_TR
;
1432 ttPosRef
= Hotspot_BL
;
1436 ttParentRef
= Hotspot_TL
;
1437 ttPosRef
= Hotspot_BR
;
1443 ttParentRef
= Hotspot_BL
;
1444 ttPosRef
= Hotspot_BL
;
1448 // **** compute coordinates of the tooltip
1451 if (ttParentRef
& Hotspot_Mx
)
1453 if (ttParentRef
& Hotspot_Tx
)
1455 if (ttParentRef
& Hotspot_xM
)
1457 if (ttParentRef
& Hotspot_xR
)
1460 // adjust according to self posref
1461 if (ttPosRef
& Hotspot_Mx
)
1462 y
-= groupContextHelp
->getHReal()/2;
1463 if (ttPosRef
& Hotspot_Tx
)
1464 y
-= groupContextHelp
->getHReal();
1465 if (ttPosRef
& Hotspot_xM
)
1466 x
-= groupContextHelp
->getWReal()/2;
1467 if (ttPosRef
& Hotspot_xR
)
1468 x
-= groupContextHelp
->getWReal();
1471 // **** clamp to screen coords, and set
1472 uint clampCount
= 0;
1474 if ((x
+groupContextHelp
->getW()) > groupContextHelp
->getParent()->getWReal())
1477 x
= groupContextHelp
->getParent()->getWReal() - groupContextHelp
->getW();
1484 if ((y
+groupContextHelp
->getH()) > groupContextHelp
->getParent()->getHReal())
1486 y
= groupContextHelp
->getParent()->getHReal() - groupContextHelp
->getH();
1495 // update coords 3 times is required
1496 groupContextHelp
->setX (x
);
1497 groupContextHelp
->setY (y
);
1498 groupContextHelp
->updateCoords ();
1499 groupContextHelp
->updateCoords ();
1500 groupContextHelp
->updateCoords ();
1505 // ----------------------------------------------------------------------------
1506 void CWidgetManager::updateTooltipCoords()
1508 updateTooltipCoords( getCurContextHelp() );
1511 void CWidgetManager::updateTooltipCoords( CCtrlBase
*newCtrl
)
1513 if (!newCtrl
) return;
1514 if (!newCtrl
->getInvalidCoords()) return;
1516 CInterfaceGroup
*groupContextHelp
=
1517 getWindowForActiveMasterGroup(newCtrl
->getContextHelpWindowName());
1519 if(groupContextHelp
)
1521 CViewText
*pTxt
= (CViewText
*)groupContextHelp
->getView("text");
1524 pTxt
->setTextFormatTaged(_ContextHelpText
);
1525 // update only to get correct W/H
1526 groupContextHelp
->updateCoords ();
1529 // **** Compute parent coordinates
1530 CCtrlBase::TToolTipParentType parentType
= newCtrl
->getToolTipParent();
1531 CInterfaceGroup
*win
= NULL
;
1532 // adjust to the mouse by default
1533 sint32 xParent
= getPointer()->getX();
1534 sint32 yParent
= getPointer()->getY();
1537 // adjust to the window
1538 if(parentType
==CCtrlBase::TTWindow
|| parentType
==CCtrlBase::TTSpecialWindow
)
1540 if(parentType
==CCtrlBase::TTWindow
)
1541 win
= newCtrl
->getRootWindow();
1544 dynamic_cast<CInterfaceGroup
*>( getElementFromId(newCtrl
->getToolTipSpecialParent()));
1548 xParent
= win
->getXReal();
1549 yParent
= win
->getYReal();
1550 wParent
= win
->getWReal();
1551 hParent
= win
->getHReal();
1553 // Bug...: leave default to pointer
1555 // adjust to the ctrl
1556 else if (parentType
==CCtrlBase::TTCtrl
)
1558 xParent
= newCtrl
->getXReal();
1559 yParent
= newCtrl
->getYReal();
1560 wParent
= newCtrl
->getWReal();
1561 hParent
= newCtrl
->getHReal();
1562 // Additionaly, must clip this ctrl with its parent
1563 // (else animals are buggy for instance)
1564 CInterfaceGroup
*parent
= newCtrl
->getParent();
1567 sint32 xClip
,yClip
,wClip
,hClip
;
1568 parent
->getClip(xClip
,yClip
,wClip
,hClip
);
1570 xParent
= std::max(xParent
, xClip
);
1571 yParent
= std::max(yParent
, yClip
);
1573 sint32 xrParent
= std::min(xParent
+ wParent
, xClip
+wClip
);
1574 sint32 ytParent
= std::min(yParent
+ hParent
, yClip
+hClip
);
1575 wParent
= std::max((sint32
)0, xrParent
-xParent
);
1576 hParent
= std::max((sint32
)0, ytParent
-yParent
);
1581 // **** resolve auto posref
1583 adjustTooltipPosition( newCtrl
, win
, newCtrl
->getToolTipParentPosRef(),
1584 newCtrl
->getToolTipPosRef(), xParent
, yParent
,
1587 if (clampCount
!= 0)
1589 // try to fallback on alternate tooltip posref
1590 uint altClampCount
=
1591 adjustTooltipPosition( newCtrl
, win
, newCtrl
->getToolTipParentPosRefAlt(),
1592 newCtrl
->getToolTipPosRefAlt(), xParent
, yParent
,
1595 if (altClampCount
> clampCount
)
1597 // worst ? resume to first posref
1598 adjustTooltipPosition( newCtrl
, win
, newCtrl
->getToolTipParentPosRef(),
1599 newCtrl
->getToolTipPosRef(), xParent
, yParent
,
1607 // ------------------------------------------------------------------------------------------------
1608 void CWidgetManager::updateContextHelpColors()
1610 // TODO: should only update when dbProp changes and not on every frame
1611 if (!_ContextHelpContentAlphaDB
)
1613 _ContextHelpContentAlphaDB
= CDBManager::getInstance()->getDbProp("UI:SAVE:CONTEXT_HELP_CONTENT_ALPHA");
1614 _ContextHelpContainerColorDB
= CDBManager::getInstance()->getDbProp("UI:SAVE:CONTEXT_HELP_CONTAINER_COLOR");
1615 _ContextHelpContainerAlphaDB
= CDBManager::getInstance()->getDbProp("UI:SAVE:CONTEXT_HELP_CONTAINER_ALPHA");
1618 // tooltip content alpha
1619 _ContextHelpContentAlpha
= (uint8
) _ContextHelpContentAlphaDB
->getValue32();
1621 // tooltip container (background) color
1622 CInterfaceProperty ip
;
1623 ip
.setNodePtr(_ContextHelpContainerColorDB
);
1624 _ContextHelpContainerColor
= ip
.getRGBA();
1625 _ContextHelpContainerColor
.A
= (uint8
) _ContextHelpContainerAlphaDB
->getValue32();
1628 // ------------------------------------------------------------------------------------------------
1629 void CWidgetManager::disableContextHelp()
1631 setCurContextHelp( NULL
);
1632 _DeltaTimeStopingContextHelp
= 0;
1635 // ------------------------------------------------------------------------------------------------
1636 void CWidgetManager::disableContextHelpForControl( CCtrlBase
*pCtrl
)
1641 if( getCurContextHelp() == pCtrl
)
1642 disableContextHelp();
1645 // ----------------------------------------------------------------------------
1646 CCtrlBase
* CWidgetManager::getNewContextHelpCtrl()
1648 // get the top most ctrl under us
1649 CCtrlBase
*best
= NULL
;
1650 sint8 bestRenderLayer
= -128;
1652 for (sint i
= (sint32
)_CtrlsUnderPointer
.size()-1; i
>=0; i
--)
1654 CCtrlBase
*pICL
= _CtrlsUnderPointer
[i
];
1655 if (pICL
->getRenderLayer() > bestRenderLayer
)
1657 if ((pICL
->getActive()) && (!pICL
->emptyContextHelp()))
1659 if (!getPointer()) return pICL
;
1661 getPointer()->getPointerPos(mx
, my
);
1662 if (pICL
->preciseHitTest(mx
, my
))
1665 bestRenderLayer
= pICL
->getRenderLayer();
1672 // if a control was not found, try with the groups
1673 sint8 bestRenderLayer
= -128;
1675 for (sint i
= (sint32
)_GroupsUnderPointer
.size()-1; i
>=0; i
--)
1677 CCtrlBase
*pICL
= _GroupsUnderPointer
[i
];
1678 if (pICL
->getRenderLayer() > bestRenderLayer
)
1680 if ((pICL
->getActive()) && (!pICL
->emptyContextHelp()))
1682 if (!getPointer()) return pICL
;
1684 getPointer()->getPointerPos(mx
, my
);
1685 if (pICL
->preciseHitTest(mx
, my
))
1688 bestRenderLayer
= pICL
->getRenderLayer();
1697 // ----------------------------------------------------------------------------
1698 void CWidgetManager::drawContextHelp ()
1700 if (!getPointer() || !_ContextHelpActive
)
1704 sint32 x
= getPointer()->getX();
1705 sint32 y
= getPointer()->getY();
1709 // **** try to disable
1711 // test disable first, so can recheck asap if another present. see below
1712 CCtrlBase
*_CurCtrlContextHelp
= getCurContextHelp();
1713 if( _CurCtrlContextHelp
)
1715 if(x
!=_LastXContextHelp
|| y
!=_LastYContextHelp
)
1717 // May change of ctrl!! => disable context help
1718 CCtrlBase
*newCtrl
= getNewContextHelpCtrl();
1719 if(newCtrl
!=_CurCtrlContextHelp
)
1722 disableContextHelp();
1726 // Check if _CurCtrlContextHelp is visible
1727 if (_CurCtrlContextHelp
== NULL
)
1729 disableContextHelp();
1733 bool bVisible
= true;
1734 if (_CurCtrlContextHelp
->getActive() == false)
1736 CInterfaceGroup
*pParent
= _CurCtrlContextHelp
->getParent();
1737 while (pParent
!= NULL
)
1739 if (pParent
->getActive() == false)
1741 pParent
= pParent
->getParent();
1744 disableContextHelp();
1750 // **** try to acquire
1752 if(!_CurCtrlContextHelp
)
1754 // get the ctrl of interset
1755 CCtrlBase
*newCtrl
= getNewContextHelpCtrl();
1757 if(x
==_LastXContextHelp
&& y
==_LastYContextHelp
)
1758 _DeltaTimeStopingContextHelp
+= ( interfaceTimes
.frameDiffMs
/ 1000.0f
);
1760 _DeltaTimeStopingContextHelp
= 0;
1762 // If reach the time limit
1763 if( ( _DeltaTimeStopingContextHelp
> _MaxTimeStopingContextHelp
)
1764 || (newCtrl
&& newCtrl
->wantInstantContextHelp()))
1766 // if present, get the ctx help text.
1770 //newCtrl->getContextHelpToolTip(_ContextHelpText);
1771 newCtrl
->getContextHelp( getContextHelpText() );
1772 // UserDefined context help
1773 if( !newCtrl
->getContextHelpActionHandler().empty() )
1775 CAHManager::getInstance()->runActionHandler(newCtrl
->getContextHelpActionHandler(), newCtrl
, newCtrl
->getContextHelpAHParams() );
1778 // If the text is finally empty (Special AH case), abort
1779 if( getContextHelpText().empty() )
1783 // not present? wait furthermore to move the mouse.
1785 _DeltaTimeStopingContextHelp
= 0;
1789 setCurContextHelp( newCtrl
);
1790 newCtrl
->invalidateCoords();
1795 updateTooltipCoords(_CurCtrlContextHelp
);
1801 if(_CurCtrlContextHelp
)
1803 CInterfaceGroup
*groupContextHelp
=
1804 getWindowForActiveMasterGroup(_CurCtrlContextHelp
->getContextHelpWindowName());
1806 if(groupContextHelp
)
1808 updateContextHelpColors();
1810 // setup new global color for tooltip
1811 NLMISC::CRGBA oldGlobalColorForContent
= getGlobalColorForContent();
1812 NLMISC::CRGBA newGlobalColorForContent
= oldGlobalColorForContent
;
1813 newGlobalColorForContent
.A
= _ContextHelpContentAlpha
;
1814 setGlobalColorForContent(newGlobalColorForContent
);
1817 CViewBase
*pVB
= groupContextHelp
->getView("midcolor");
1820 CViewBitmap
*bg
= dynamic_cast<CViewBitmap
*>(pVB
);
1823 bg
->setColor(_ContextHelpContainerColor
);
1827 /** If there's a modal box around, should be sure that the context help doesn't intersect it.
1828 * If this is the case, we just disable it, unless the tooltip was generated by the current modal window
1832 CInterfaceGroup
*mw
= getModal().ModalWindow
;
1833 if (mw
&& mw
->isIn(*groupContextHelp
))
1835 if (_CurCtrlContextHelp
->isSonOf(mw
))
1837 groupContextHelp
->executeLuaScriptOnDraw();
1838 groupContextHelp
->draw ();
1840 CViewRenderer::getInstance()->flush();
1845 groupContextHelp
->executeLuaScriptOnDraw();
1846 groupContextHelp
->draw ();
1848 CViewRenderer::getInstance()->flush();
1853 groupContextHelp
->executeLuaScriptOnDraw();
1854 groupContextHelp
->draw ();
1856 CViewRenderer::getInstance()->flush();
1859 // restore global color
1860 setGlobalColorForContent(oldGlobalColorForContent
);
1865 _LastXContextHelp
= x
;
1866 _LastYContextHelp
= y
;
1869 void CWidgetManager::setContextHelpActive(bool active
)
1873 disableContextHelp();
1875 _ContextHelpActive
= active
;
1879 // ------------------------------------------------------------------------------------------------
1880 void CWidgetManager::getNewWindowCoordToNewScreenSize( sint32
&x
, sint32
&y
, sint32 w
, sint32 h
,
1881 sint32 newScreenW
, sint32 newScreenH
) const
1883 // NB: x is relative to Left of the window (and Left of screen)
1884 // NB: y is relative to Top of the window (but Bottom of screen)
1887 The goal here is to move the window so it fit the new resolution
1888 But we don't want to change its size (because somes windows just can't)
1889 We also cannot use specific code according to each window because user may completly modify his interface
1890 So the strategy is to dectect on which "side" (or center) the window is the best sticked,
1891 and then just move the window according to this position
1894 // *** First detect from which screen position the window is the more sticked (borders or center)
1895 // In X: best hotspot is left, middle or right?
1896 sint32 posXToLeft
= x
;
1897 sint32 posXToMiddle
= x
+w
/2-_ScreenW
/2;
1898 sint32 posXToRight
= _ScreenW
-(x
+w
);
1899 sint32 bestXHotSpot
= Hotspot_xL
;
1900 sint32 bestXPosVal
= posXToLeft
;
1901 if(abs(posXToMiddle
) < bestXPosVal
)
1903 bestXHotSpot
= Hotspot_xM
;
1904 bestXPosVal
= abs(posXToMiddle
);
1906 if(posXToRight
< bestXPosVal
)
1908 bestXHotSpot
= Hotspot_xR
;
1909 bestXPosVal
= posXToRight
;
1912 // Same In Y: best hotspot is bottom, middle or top?
1913 // remember here that y is the top of window (relative to bottom of screen)
1914 sint32 posYToBottom
= y
-h
;
1915 sint32 posYToMiddle
= y
-h
/2-_ScreenH
/2;
1916 sint32 posYToTop
= _ScreenH
-y
;
1917 sint32 bestYHotSpot
= Hotspot_Bx
;
1918 sint32 bestYPosVal
= posYToBottom
;
1919 const sint32 middleYWeight
= 6; // Avoid default Mission/Team/Map/ContactList positions to be considered as "middle"
1920 if(abs(posYToMiddle
)*middleYWeight
< bestYPosVal
)
1922 bestYHotSpot
= Hotspot_Mx
;
1923 bestYPosVal
= abs(posYToMiddle
)*middleYWeight
;
1925 if(posYToTop
< bestYPosVal
)
1927 bestYHotSpot
= Hotspot_Tx
;
1928 bestYPosVal
= posYToTop
;
1931 // *** According to best matching hotspot, and new screen resolution, move the window
1933 if(bestXHotSpot
==Hotspot_xM
)
1934 x
= newScreenW
/2 + posXToMiddle
- w
/2;
1935 else if(bestXHotSpot
==Hotspot_xR
)
1936 x
= newScreenW
- posXToRight
- w
;
1938 if(bestYHotSpot
==Hotspot_Mx
)
1939 y
= newScreenH
/2 + posYToMiddle
+ h
/2;
1940 else if(bestYHotSpot
==Hotspot_Tx
)
1941 y
= newScreenH
- posYToTop
;
1944 // ------------------------------------------------------------------------------------------------
1945 void CWidgetManager::moveAllWindowsToNewScreenSize(uint32 newScreenW
, uint32 newScreenH
, bool fixCurrentUI
)
1947 std::vector
< CWidgetManager::SMasterGroup
> &_MasterGroups
= getAllMasterGroup();
1948 // If resolutions correctly setuped, and really different from new setup
1949 if( _ScreenW
>0 && _ScreenH
>0 &&
1950 newScreenW
>0 && newScreenH
>0 &&
1951 ( _ScreenW
!= newScreenW
|| _ScreenH
!= newScreenH
)
1954 // *** Do it for the Active Desktop (if wanted)
1957 // only for ui:interface (not login, nor outgame)
1958 for (uint nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
1960 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
1961 if (!rMG
.Group
|| rMG
.Group
->getId() != "ui:interface")
1964 // For all priorities, but the worldspace one
1965 for (uint8 nPriority
= 0; nPriority
< WIN_PRIORITY_MAX
; nPriority
++)
1967 if (nPriority
==WIN_PRIORITY_WORLD_SPACE
)
1970 // For All windows (only layer 0 group container)
1971 std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
];
1972 std::list
<CInterfaceGroup
*>::const_iterator itw
;
1973 for (itw
= rList
.begin(); itw
!= rList
.end(); itw
++)
1975 CInterfaceGroup
*pIG
= *itw
;
1976 if(!pIG
->isGroupContainer())
1978 CGroupContainer
*gc
= dynamic_cast<CGroupContainer
*>(pIG
);
1979 if(gc
->getLayerSetup()!=0)
1981 // should all be BL / TL
1982 if(gc
->getParentPosRef()!=Hotspot_BL
|| gc
->getPosRef()!=Hotspot_TL
)
1985 // Get current window coordinates
1986 sint32 x
= pIG
->getX(); // x is relative to Left of the window
1987 sint32 y
= pIG
->getY(); // y is relative to Top of the window
1988 sint32 w
= pIG
->getW(false); // the window may be hid, still get the correct(or estimated) W
1989 sint32 h
= pIG
->getH(false); // the window may be hid, still get the correct(or estimated) H
1991 // Compute the new coordinate
1992 getNewWindowCoordToNewScreenSize(x
, y
, w
, h
, newScreenW
, newScreenH
);
2002 std::vector
< INewScreenSizeHandler
* >::iterator itr
;
2003 for( itr
= newScreenSizeHandlers
.begin(); itr
!= newScreenSizeHandlers
.end(); ++itr
)
2005 INewScreenSizeHandler
*handler
= *itr
;
2006 handler
->process( newScreenW
, newScreenH
);
2010 // Now those are the last screen coordinates used for window position correction
2011 if(newScreenW
>0 && newScreenH
>0)
2013 _ScreenW
= newScreenW
;
2014 _ScreenH
= newScreenH
;
2018 class InvalidateTextVisitor
: public CInterfaceElementVisitor
2021 InvalidateTextVisitor( bool reset
)
2023 this->reset
= reset
;
2026 void visitGroup( CInterfaceGroup
*group
)
2028 const std::vector
< CViewBase
* > &vs
= group
->getViews();
2029 for( std::vector
< CViewBase
* >::const_iterator itr
= vs
.begin(); itr
!= vs
.end(); ++itr
)
2031 CViewText
*vt
= dynamic_cast< CViewText
* >( *itr
);
2035 vt
->resetTextIndex();
2036 vt
->updateTextContext();
2045 // ------------------------------------------------------------------------------------------------
2046 void CWidgetManager::updateAllLocalisedElements()
2049 uint32 nMasterGroup
;
2052 CViewRenderer::getInstance()->checkNewScreenSize ();
2053 CViewRenderer::getInstance()->getScreenSize (w
, h
);
2055 // Update ui:* (limit the master containers to the height of the screen)
2056 for (nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
2058 SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
2059 rMG
.Group
->setW (w
);
2060 rMG
.Group
->setH (h
);
2062 CViewRenderer::getInstance()->setClipWindow(0, 0, w
, h
);
2064 bool scaleChanged
= _InterfaceScale
!= CViewRenderer::getInstance()->getInterfaceScale();
2067 _InterfaceScale
= CViewRenderer::getInstance()->getInterfaceScale();
2068 notifyInterfaceScaleWatchers();
2071 // If all conditions are OK, move windows so they fit correctly with new screen size
2072 // Do this work only InGame when Config is loaded
2073 moveAllWindowsToNewScreenSize(w
,h
,true);
2075 // Invalidate coordinates of all Windows of each MasterGroup
2076 for (nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
2078 SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
2080 InvalidateTextVisitor
inv( false);
2082 rMG
.Group
->visitGroupAndChildren( &inv
);
2083 rMG
.Group
->invalidateCoords ();
2084 for (uint8 nPriority
= 0; nPriority
< WIN_PRIORITY_MAX
; nPriority
++)
2086 std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
];
2087 std::list
<CInterfaceGroup
*>::const_iterator itw
;
2088 for (itw
= rList
.begin(); itw
!= rList
.end(); itw
++)
2090 CInterfaceGroup
*pIG
= *itw
;
2091 pIG
->visitGroupAndChildren( &inv
);
2092 pIG
->invalidateCoords ();
2098 for (nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
2100 SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
2101 bool bActive
= rMG
.Group
->getActive ();
2102 rMG
.Group
->setActive (true);
2103 rMG
.Group
->updateCoords ();
2104 rMG
.Group
->setActive (bActive
);
2107 // update coords one
2110 // Action by default (container opening
2111 for (nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
2113 SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
2114 rMG
.Group
->launch ();
2119 void CWidgetManager::drawViews( NL3D::UCamera camera
)
2121 CViewRenderer::getInstance()->activateWorldSpaceMatrix (false);
2122 NL3D::UDriver
*driver
= CViewRenderer::getInstance()->getDriver();
2124 // If an element has captured the keyboard, make sure it is alway visible (all parent windows active)
2125 if( getCaptureKeyboard() != NULL
)
2127 CCtrlBase
*cb
= getCaptureKeyboard();
2130 if (!cb
->getActive())
2132 setCaptureKeyboard(NULL
);
2135 cb
= cb
->getParent();
2140 // Check if screen size changed
2142 CViewRenderer::getInstance()->checkNewScreenSize ();
2143 CViewRenderer::getInstance()->getScreenSize (w
, h
);
2144 if ((w
!= _ScreenW
) || (h
!= _ScreenH
))
2146 // No Op if screen minimized
2147 if(w
!=0 && h
!=0 && !CViewRenderer::getInstance()->isMinimized())
2149 updateAllLocalisedElements ();
2154 // Update global color from database
2157 _RProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:R");
2158 _GProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:G");
2159 _BProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:B");
2160 _AProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:A");
2163 setGlobalColor(NLMISC::CRGBA(
2164 (uint8
)_RProp
->getValue32(),
2165 (uint8
)_GProp
->getValue32(),
2166 (uint8
)_BProp
->getValue32(),
2167 (uint8
)_AProp
->getValue32()));
2169 NLMISC::CRGBA c
= getGlobalColorForContent();
2170 NLMISC::CRGBA gc
= getGlobalColor();
2174 c
.A
= (uint8
) (( (uint16
) c
.A
* (uint16
) getContentAlpha() ) >> 8);
2175 setGlobalColorForContent( c
);
2177 // Update global alphaS from database
2178 updateGlobalAlphas();
2180 /* Draw all the windows
2181 To minimize texture swapping, we first sort per Window, then we sort per layer, then we render per Global Texture.
2182 Computed String are rendered in on big drawQuads at last part of each layer
2184 CDBManager::getInstance()->flushObserverCalls();
2186 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
2188 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
2189 if (rMG
.Group
->getActive())
2191 // Sort world space windows
2192 rMG
.sortWorldSpaceGroup ();
2194 for (uint8 nPriority
= 0; nPriority
< WIN_PRIORITY_MAX
; ++nPriority
)
2196 if ( (nPriority
== WIN_PRIORITY_WORLD_SPACE
) && !camera
.empty())
2198 driver
->setViewMatrix( NL3D::CMatrix::Identity
);
2199 driver
->setModelMatrix( NL3D::CMatrix::Identity
);
2200 driver
->setFrustum(camera
.getFrustum());
2201 CViewRenderer::getInstance()->activateWorldSpaceMatrix (true);
2204 std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
];
2205 std::list
<CInterfaceGroup
*>::const_iterator itw
;
2207 for (itw
= rList
.begin(); itw
!= rList
.end(); itw
++)
2209 CInterfaceGroup
*pIG
= *itw
;
2210 if( pIG
) // TODO: debug null pointer in PrioritizedWindows list
2212 if (pIG
->getActive())
2214 // Draw all the elements of this window in the layers in ViewRendered
2217 CViewRenderer::getInstance()->flush ();
2222 if( draggedElement
!= NULL
)
2224 CInterfaceElement
*e
= draggedElement
;
2225 static_cast< CViewBase
* >( e
)->draw();
2228 if ( (nPriority
== WIN_PRIORITY_WORLD_SPACE
) && !camera
.empty())
2230 driver
->setMatrixMode2D11();
2231 CViewRenderer::getInstance()->activateWorldSpaceMatrix (false);
2237 CDBManager::getInstance()->flushObserverCalls();
2239 // draw the special over extend text
2240 drawOverExtendViewText();
2242 // draw the context help
2245 std::vector
< IOnWidgetsDrawnHandler
* >::iterator itr
;
2246 for( itr
= onWidgetsDrawnHandlers
.begin(); itr
!= onWidgetsDrawnHandlers
.end(); ++itr
)
2248 IOnWidgetsDrawnHandler
*handler
= *itr
;
2252 // Draw the pointer and DND Item
2253 if (getPointer() != NULL
)
2255 if (getPointer()->getActive())
2256 getPointer()->draw ();
2259 if (CInterfaceElement::getEditorMode())
2261 for(uint i
= 0; i
< editorSelection
.size(); ++i
)
2263 CInterfaceElement
*e
= getElementFromId(editorSelection
[i
]);
2270 CViewRenderer::getInstance()->flush();
2272 // todo hulud remove Return in 2d world
2273 driver
->setMatrixMode2D11();
2275 CDBManager::getInstance()->flushObserverCalls();
2278 bool CWidgetManager::handleEvent( const CEventDescriptor
&evnt
)
2280 // Check if we can receive events (no anims!)
2281 for( uint32 i
= 0; i
< activeAnims
.size(); ++i
)
2282 if( activeAnims
[i
]->isDisableButtons() )
2285 bool handled
= false;
2287 if( evnt
.getType() == CEventDescriptor::system
)
2289 handleSystemEvent( evnt
);
2292 if (evnt
.getType() == CEventDescriptor::key
)
2294 handled
= handleKeyboardEvent( evnt
);
2296 else if (evnt
.getType() == CEventDescriptor::mouse
)
2298 handled
= handleMouseEvent( evnt
);
2301 CDBManager::getInstance()->flushObserverCalls();
2306 bool CWidgetManager::handleSystemEvent( const CEventDescriptor
&evnt
)
2308 const CEventDescriptorSystem
&systemEvent
= reinterpret_cast< const CEventDescriptorSystem
& >( evnt
);
2309 if( systemEvent
.getEventTypeExtended() == CEventDescriptorSystem::setfocus
)
2311 if( getCapturePointerLeft() != NULL
)
2313 getCapturePointerLeft()->handleEvent( evnt
);
2314 setCapturePointerLeft( NULL
);
2317 if( getCapturePointerRight() != NULL
)
2319 getCapturePointerRight()->handleEvent( evnt
);
2320 setCapturePointerRight( NULL
);
2323 if( _CapturedView
!= NULL
)
2325 _CapturedView
->handleEvent( evnt
);
2326 _CapturedView
= NULL
;
2333 bool CWidgetManager::handleKeyboardEvent( const CEventDescriptor
&evnt
)
2335 bool handled
= false;
2337 CEventDescriptorKey
&eventDesc
= (CEventDescriptorKey
&)evnt
;
2339 //_LastEventKeyDesc = eventDesc;
2341 // Any Key event disable the ContextHelp
2342 disableContextHelp();
2344 // Hide menu if the key is pushed
2345 // if ((eventDesc.getKeyEventType() == CEventDescriptorKey::keydown) && !_ModalStack.empty() && !eventDesc.getKeyAlt() && !eventDesc.getKeyCtrl() && !eventDesc.getKeyShift())
2346 // Hide menu (or popup menu) is ESCAPE pressed
2347 if( eventDesc
.getKeyEventType() == CEventDescriptorKey::keydown
&& eventDesc
.getKey() == NLMISC::KeyESCAPE
)
2351 SModalWndInfo mwi
= getModal();
2352 if (mwi
.ModalExitKeyPushed
)
2353 disableModalWindow();
2358 CInterfaceGroup
*win
= getLastEscapableTopWindow();
2361 // Manage "quit window" If the Key is ESCAPE, no captureKeyboard
2362 // Get the last escapable active top window. NB: this is ergonomically better.
2364 // If the window is a modal, must pop it.
2365 if( dynamic_cast<CGroupModal
*>(win
) )
2367 if(!win
->getAHOnEscape().empty())
2368 CAHManager::getInstance()->runActionHandler(win
->getAHOnEscape(), win
, win
->getAHOnEscapeParams());
2372 // else just disable it.
2373 // Special case: leave the escape Key to the CaptureKeyboard .
2374 else if( !getCaptureKeyboard() )
2376 if(!win
->getAHOnEscape().empty())
2377 CAHManager::getInstance()->runActionHandler(win
->getAHOnEscape(), win
, win
->getAHOnEscapeParams());
2378 win
->setActive(false);
2384 // Manage complex "Enter"
2385 if( eventDesc
.getKeyEventType() == CEventDescriptorKey::keychar
&& eventDesc
.getChar() == NLMISC::KeyRETURN
&& !eventDesc
.getKeyCtrl() )
2387 // If the top window has Enter AH
2388 CInterfaceGroup
*tw
= getTopWindow();
2389 if(tw
&& !tw
->getAHOnEnter().empty())
2391 // if the captured keyboard is in this Modal window, then must handle him in priority
2392 if( getCaptureKeyboard() && getCaptureKeyboard()->getRootWindow()==tw
)
2394 bool result
= getCaptureKeyboard()->handleEvent(evnt
);
2395 CDBManager::getInstance()->flushObserverCalls();
2400 // The window or modal control the OnEnter. Execute, and don't go to the chat.
2401 CAHManager::getInstance()->runActionHandler(tw
->getAHOnEnter(), tw
, tw
->getAHOnEnterParams());
2406 // else the 'return' key bring back to the last edit box (if possible)
2407 CCtrlBase
*oldCapture
= getOldCaptureKeyboard() ? getOldCaptureKeyboard() : getDefaultCaptureKeyboard();
2408 if ( getCaptureKeyboard() == NULL
&& oldCapture
&& !handled
)
2410 /* If the editbox does not want to recover focus, then abort. This possibility is normaly avoided
2411 through setCaptureKeyboard() which already test getRecoverFocusOnEnter(), but it is still possible
2412 for the default capture (main chat) or the old captured window to not want to recover
2413 (temporary Read Only chat for instance)
2415 if(!dynamic_cast<CGroupEditBoxBase
*>(oldCapture
) ||
2416 dynamic_cast<CGroupEditBoxBase
*>(oldCapture
)->getRecoverFocusOnEnter())
2418 setCaptureKeyboard( oldCapture
);
2419 notifyElementCaptured(getCaptureKeyboard() );
2420 // make sure all parent windows are active
2421 CCtrlBase
*cb
= getCaptureKeyboard();
2422 CGroupContainer
*lastContainer
= NULL
;
2426 CGroupContainer
*gc
= dynamic_cast<CGroupContainer
*>(cb
);
2427 if (gc
) lastContainer
= gc
;
2429 if (cb
->getParent())
2431 cb
= cb
->getParent();
2435 cb
->invalidateCoords();
2441 setTopWindow(lastContainer
);
2442 lastContainer
->enableBlink(1);
2449 // General case: handle it in the Captured keyboard
2450 if (!handled
&& getCaptureKeyboard() != NULL
)
2452 bool result
= getCaptureKeyboard()->handleEvent(evnt
);
2453 CDBManager::getInstance()->flushObserverCalls();
2457 if (!handled
&& eventDesc
.getKeyEventType() == CEventDescriptorKey::keydown
&& eventDesc
.getKey() == NLMISC::KeyESCAPE
)
2459 CAHManager::getInstance()->runActionHandler("enter_modal", NULL
, "group=ui:interface:quit_dialog");
2463 lastKeyEvent
= eventDesc
;
2468 bool CWidgetManager::handleMouseEvent( const CEventDescriptor
&evnt
)
2470 bool handled
= false;
2472 CEventDescriptorMouse
&eventDesc
= (CEventDescriptorMouse
&)evnt
;
2474 if( eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown
)
2475 _Pointer
->setButtonState( static_cast< NLMISC::TMouseButton
>( _Pointer
->getButtonState() | NLMISC::leftButton
) );
2477 if( eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown
)
2478 _Pointer
->setButtonState( static_cast< NLMISC::TMouseButton
>( _Pointer
->getButtonState() | NLMISC::rightButton
) );
2480 if( eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup
)
2481 _Pointer
->setButtonState( static_cast< NLMISC::TMouseButton
>( _Pointer
->getButtonState() & ~NLMISC::leftButton
) );
2482 if( eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightup
)
2483 _Pointer
->setButtonState( static_cast< NLMISC::TMouseButton
>( _Pointer
->getButtonState() & ~NLMISC::rightButton
) );
2485 if( eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mousemove
)
2486 handleMouseMoveEvent( eventDesc
);
2488 eventDesc
.setX( _Pointer
->getX() );
2489 eventDesc
.setY( _Pointer
->getY() );
2491 if( CInterfaceElement::getEditorMode() )
2493 // Let's pretend we've handled the event... or actually we have!
2494 if( ( eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown
) ||
2495 ( eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightup
) )
2499 if( isMouseHandlingEnabled() )
2501 // First thing to do : Capture handling
2502 if ( getCapturePointerLeft() != NULL
)
2503 handled
|= getCapturePointerLeft()->handleEvent(evnt
);
2505 if ( getCapturePointerRight() != NULL
&&
2506 getCapturePointerLeft() != getCapturePointerRight() )
2507 handled
|= getCapturePointerRight()->handleEvent(evnt
);
2509 if( _CapturedView
!= NULL
&&
2510 _CapturedView
!= getCapturePointerLeft() &&
2511 _CapturedView
!= getCapturePointerRight() )
2512 _CapturedView
->handleEvent( evnt
);
2514 CInterfaceGroup
*ptr
= getWindowUnder (eventDesc
.getX(), eventDesc
.getY());
2515 setCurrentWindowUnder( ptr
);
2517 // Any Mouse event but move disable the ContextHelp
2518 if(eventDesc
.getEventTypeExtended() != CEventDescriptorMouse::mousemove
)
2520 disableContextHelp();
2523 // get the group under the mouse
2524 CInterfaceGroup
*pNewCurrentWnd
= getCurrentWindowUnder();
2525 setMouseOverWindow( pNewCurrentWnd
!= NULL
);
2528 NLMISC::CRefPtr
<CGroupModal
> clickedOutModalWindow
;
2530 // modal special features
2533 CWidgetManager::SModalWndInfo mwi
= getModal();
2536 // If we are not in "click out" mode so we dont handle controls other than those of the modal
2537 if (pNewCurrentWnd
!= mwi
.ModalWindow
&& !mwi
.ModalExitClickOut
)
2539 pNewCurrentWnd
= NULL
;
2543 // If there is a handler on click out launch it
2544 if (pNewCurrentWnd
!= mwi
.ModalWindow
)
2545 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown
||
2546 (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown
))
2547 if (!mwi
.ModalHandlerClickOut
.empty())
2548 CAHManager::getInstance()->runActionHandler(mwi
.ModalHandlerClickOut
,NULL
,mwi
.ModalClickOutParams
);
2550 // If the current window is not the modal and if must quit on click out
2551 if(pNewCurrentWnd
!= mwi
.ModalWindow
&& mwi
.ModalExitClickOut
)
2553 // NB: don't force handle==true because to quit a modal does not avoid other actions
2555 // quit if click outside
2556 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown
||
2557 (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown
))
2559 clickedOutModalWindow
= dynamic_cast<CGroupModal
*>((CInterfaceGroup
*)mwi
.ModalWindow
);
2560 // disable the modal
2564 // don't handle event unless it is a previous modal window
2565 if( !isPreviousModal( pNewCurrentWnd
) )
2566 pNewCurrentWnd
= NULL
; // can't handle event before we have left all modal windows
2568 movePointer (0,0); // Reget controls under pointer
2575 // Manage LeftClick.
2576 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown
)
2578 if ((pNewCurrentWnd
!= NULL
) && (!hasModal()) && (pNewCurrentWnd
->getOverlappable()))
2580 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(pNewCurrentWnd
);
2583 if (!pGC
->isGrayed()) setTopWindow(pNewCurrentWnd
);
2587 setTopWindow(pNewCurrentWnd
);
2591 bool captured
= false;
2593 // must not capture a new element if a sheet is currentlty being dragged.
2594 // This may happen when alt-tab has been used => the sheet is dragged but the left button is up
2595 if (!CCtrlDraggable::getDraggedSheet())
2597 if( CInterfaceElement::getEditorMode() && _GroupSelection
)
2599 for( sint32 i
= _GroupsUnderPointer
.size() - 1; i
>= 0; i
-- )
2601 CInterfaceGroup
*g
= _GroupsUnderPointer
[ i
];
2602 if( ( g
!= NULL
) && ( g
->isInGroup( pNewCurrentWnd
) ) )
2613 // Take the top most control.
2615 const std::vector
< CCtrlBase
* >& _CtrlsUnderPointer
= getCtrlsUnderPointer();
2616 for (sint32 i
= (sint32
)_CtrlsUnderPointer
.size()-1; i
>= 0; i
--)
2618 CCtrlBase
*ctrl
= _CtrlsUnderPointer
[i
];
2619 if (ctrl
&& ctrl
->isCapturable() && ctrl
->isInGroup( pNewCurrentWnd
) )
2621 if( CInterfaceElement::getEditorMode() && !ctrl
->isEditorSelectable() )
2624 uint d
= ctrl
->getDepth( pNewCurrentWnd
);
2628 setCapturePointerLeft( ctrl
);
2635 if( CInterfaceElement::getEditorMode() && !captured
)
2637 for( sint32 i
= _ViewsUnderPointer
.size()-1; i
>= 0; i
-- )
2639 CViewBase
*v
= _ViewsUnderPointer
[i
];
2640 if( ( v
!= NULL
) && v
->isInGroup( pNewCurrentWnd
) )
2642 if( CInterfaceElement::getEditorMode() && !v
->isEditorSelectable() )
2652 notifyElementCaptured( getCapturePointerLeft() );
2653 if (clickedOutModalWindow
&& !clickedOutModalWindow
->OnPostClickOut
.empty())
2655 CAHManager::getInstance()->runActionHandler(clickedOutModalWindow
->OnPostClickOut
, getCapturePointerLeft(), clickedOutModalWindow
->OnPostClickOutParams
);
2661 // consider clicking on a control implies handling of the event.
2664 if( getCapturePointerLeft() != NULL
)
2665 _CapturedView
= getCapturePointerLeft();
2667 // handle the capture
2668 _CapturedView
->handleEvent( evnt
);
2672 if( CInterfaceElement::getEditorMode() )
2673 clearEditorSelection();
2677 // Manage RightClick
2678 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown
)
2680 if ((pNewCurrentWnd
!= NULL
) && (!hasModal()) && (pNewCurrentWnd
->getOverlappable()))
2682 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(pNewCurrentWnd
);
2685 if (!pGC
->isGrayed()) setTopWindow(pNewCurrentWnd
);
2689 setTopWindow(pNewCurrentWnd
);
2693 // Take the top most control.
2696 const std::vector
< CCtrlBase
* >& _CtrlsUnderPointer
= getCtrlsUnderPointer();
2697 for (sint32 i
= (sint32
)_CtrlsUnderPointer
.size()-1; i
>= 0; i
--)
2699 CCtrlBase
*ctrl
= _CtrlsUnderPointer
[i
];
2700 if (ctrl
&& ctrl
->isCapturable() && ctrl
->isInGroup( pNewCurrentWnd
) )
2702 uint d
= ctrl
->getDepth( pNewCurrentWnd
);
2706 setCapturePointerRight( ctrl
);
2710 notifyElementCaptured( getCapturePointerRight() );
2711 if (clickedOutModalWindow
&& !clickedOutModalWindow
->OnPostClickOut
.empty())
2713 CAHManager::getInstance()->runActionHandler(clickedOutModalWindow
->OnPostClickOut
, getCapturePointerRight(), clickedOutModalWindow
->OnPostClickOutParams
);
2717 if ( getCapturePointerRight() != NULL
)
2719 // handle the capture
2720 handled
|= getCapturePointerRight()->handleEvent(evnt
);
2725 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightup
)
2728 if (pNewCurrentWnd
!= NULL
)
2729 pNewCurrentWnd
->handleEvent(evnt
);
2730 if ( getCapturePointerRight() != NULL
)
2732 setCapturePointerRight(NULL
);
2737 // window handling. if not handled by a control
2740 if (((pNewCurrentWnd
!= NULL
) && !hasModal()) ||
2741 ((hasModal() && getModal().ModalWindow
== pNewCurrentWnd
)))
2743 CEventDescriptorMouse ev2
= eventDesc
;
2744 sint32 x
= eventDesc
.getX(), y
= eventDesc
.getY();
2747 pNewCurrentWnd
->absoluteToRelative (x
, y
);
2748 ev2
.setX (x
); ev2
.setY (y
);
2749 handled
|= pNewCurrentWnd
->handleEvent (ev2
);
2752 // After handle event of a left click, may set window Top if movable (infos etc...)
2753 //if( (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown) && pNewCurrentWnd->isMovable() )
2754 // setTopWindow(pNewCurrentWnd);
2758 // Put here to let a chance to the window to handle if the capture dont
2759 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup
)
2761 if ( getCapturePointerLeft() != NULL
)
2765 CCtrlBase
*c
= getCapturePointerLeft();
2766 c
->handleEvent( evnt
);
2769 setCapturePointerLeft(NULL
);
2773 _CapturedView
= NULL
;
2775 if( CInterfaceElement::getEditorMode() )
2780 // If the current window is the modal, may Modal quit. Do it after standard event handle
2781 if(hasModal() && pNewCurrentWnd
== getModal().ModalWindow
)
2783 // NB: don't force handle==true because to quit a modal does not avoid other actions
2784 CWidgetManager::SModalWndInfo mwi
= getModal();
2785 // and if must quit on click right
2786 if(mwi
.ModalExitClickR
)
2788 // quit if click right
2789 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightup
)
2790 // disable the modal
2791 disableModalWindow();
2794 // and if must quit on click left
2795 if(mwi
.ModalExitClickL
)
2797 // quit if click right
2798 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup
)
2799 // disable the modal
2800 disableModalWindow();
2804 // If the mouse is over a window, always consider the event is taken (avoid click behind)
2805 handled
|= isMouseOverWindow();
2807 // If mouse click was not on interface and we have keyboard captured, then release keyboard
2808 if (!handled
&& getCaptureKeyboard() != NULL
&& eventDesc
.getEventTypeExtended() != CEventDescriptorMouse::mousemove
)
2809 CWidgetManager::getInstance()->setCaptureKeyboard(NULL
);
2815 bool CWidgetManager::handleMouseMoveEvent( const CEventDescriptor
&eventDesc
)
2817 if( getPointer() == NULL
)
2820 if( eventDesc
.getType() != CEventDescriptor::mouse
)
2823 const CEventDescriptorMouse
&e
= static_cast< const CEventDescriptorMouse
& >( eventDesc
);
2825 if( e
.getEventTypeExtended() != CEventDescriptorMouse::mousemove
)
2828 uint32 screenW
, screenH
;
2829 CViewRenderer::getInstance()->getScreenSize( screenW
, screenH
);
2830 sint32 oldX
= getPointer()->getX();
2831 sint32 oldY
= getPointer()->getY();
2833 sint32 x
= e
.getX();
2834 sint32 y
= e
.getY();
2836 // These are floats packed in the sint32 from the NEL events that provide them as float
2837 // see comment in CInputHandler::handleMouseMoveEvent
2838 sint32 newX
= static_cast< sint32
>( std::floor( *reinterpret_cast< float* >( &x
) * screenW
+ 0.5f
) );
2839 sint32 newY
= static_cast< sint32
>( std::floor( *reinterpret_cast< float* >( &y
) * screenH
+ 0.5f
) );
2841 if( ( oldX
!= newX
) || ( oldY
!= newY
) )
2843 movePointerAbs( newX
, newY
);
2844 CEventDescriptorMouse
&ve
= const_cast< CEventDescriptorMouse
& >( e
);
2845 ve
.setX( getPointer()->getX() );
2846 ve
.setY( getPointer()->getY() );
2849 if( CInterfaceElement::getEditorMode() )
2851 if( ( _CapturedView
!= NULL
) && ( draggedElement
== NULL
) )
2856 if( draggedElement
!= NULL
)
2858 sint32 dx
= newX
- oldX
;
2859 sint32 dy
= newY
- oldY
;
2861 draggedElement
->moveBy( dx
, dy
);
2868 // ------------------------------------------------------------------------------------------------
2869 bool CWidgetManager::startDragging()
2871 CInterfaceElement
*e
= NULL
;
2873 CInterfaceGroup
*g
= _CapturedView
->getParent();
2876 e
= g
->takeElement( _CapturedView
);
2879 nlinfo( "Something went horribly wrong :(" );
2886 e
->setParent( NULL
);
2892 void CWidgetManager::stopDragging()
2894 if( draggedElement
!= NULL
)
2896 CInterfaceGroup
*g
= getGroupUnder( draggedElement
->getXReal(), draggedElement
->getYReal() );
2897 CInterfaceElement
*e
= draggedElement
;
2898 CInterfaceGroup
*tw
= getTopWindow();
2903 std::string oldid
= e
->getId();
2906 e
->setIdRecurse( e
->getShortId() );
2907 e
->setParentPos( g
);
2908 e
->setParentSize( g
);
2912 //e->setName( "==MARKED==" );
2914 draggedElement
= NULL
;
2916 onWidgetMoved( oldid
, e
->getId() );
2920 // ------------------------------------------------------------------------------------------------
2921 void CWidgetManager::movePointer (sint32 dx
, sint32 dy
)
2926 uint32 nScrW
, nScrH
;
2927 sint32 oldpx
, oldpy
, newpx
, newpy
, disppx
, disppy
, olddisppx
, olddisppy
;
2929 CViewRenderer::getInstance()->getScreenSize (nScrW
, nScrH
);
2930 _Pointer
->getPointerPos (oldpx
, oldpy
);
2938 if (newpx
< 0) newpx
= 0;
2939 if (newpy
< 0) newpy
= 0;
2940 if (newpx
> (sint32
)nScrW
) newpx
= nScrW
;
2941 if (newpy
> (sint32
)nScrH
) newpy
= nScrH
;
2948 _Pointer
->setPointerPos (newpx
, newpy
);
2949 _Pointer
->setPointerDispPos (disppx
, disppy
);
2951 // must get back coordinates because of snapping
2952 sint32 mx
= _Pointer
->getX();
2953 sint32 my
= _Pointer
->getY();
2954 getViewsUnder (mx
, my
, _ViewsUnderPointer
);
2955 getCtrlsUnder (mx
, my
, _CtrlsUnderPointer
);
2956 getGroupsUnder (mx
, my
, _GroupsUnderPointer
);
2959 // ------------------------------------------------------------------------------------------------
2960 void CWidgetManager::movePointerAbs(sint32 px
, sint32 py
)
2965 uint32 nScrW
, nScrH
;
2966 CViewRenderer::getInstance()->getScreenSize (nScrW
, nScrH
);
2967 NLMISC::clamp(px
, 0, (sint32
) nScrW
);
2968 NLMISC::clamp(py
, 0, (sint32
) nScrH
);
2970 _Pointer
->setPointerPos (px
, py
);
2971 _Pointer
->setPointerDispPos (px
, py
);
2973 getViewsUnder (px
, py
, _ViewsUnderPointer
);
2974 getCtrlsUnder (px
, py
, _CtrlsUnderPointer
);
2975 getGroupsUnder (px
, py
, _GroupsUnderPointer
);
2978 // ***************************************************************************
2979 void CWidgetManager::setCapturePointerLeft(CCtrlBase
*c
)
2981 _CapturedView
= NULL
;
2983 // additionally, abort any dragging
2984 if( CCtrlDraggable::getDraggedSheet() != NULL
)
2985 CCtrlDraggable::getDraggedSheet()->abortDragging();
2987 _CapturePointerLeft
= c
;
2988 notifyElementCaptured(c
);
2991 // ***************************************************************************
2992 void CWidgetManager::setCapturePointerRight(CCtrlBase
*c
)
2994 _CapturePointerRight
= c
;
2995 notifyElementCaptured(c
);
2998 // ------------------------------------------------------------------------------------------------
2999 void CWidgetManager::setCaptureKeyboard(CCtrlBase
*c
)
3001 CGroupEditBoxBase
*oldEb
= dynamic_cast<CGroupEditBoxBase
*>((CCtrlBase
*)_CaptureKeyboard
);
3002 CGroupEditBoxBase
*newEb
= dynamic_cast<CGroupEditBoxBase
*>(c
);
3004 if (_CaptureKeyboard
&& _CaptureKeyboard
!= c
)
3006 _CaptureKeyboard
->onKeyboardCaptureLost();
3008 // If the old capturedKeyboard is an editBox and allow recoverFocusOnEnter
3009 if ( oldEb
&& oldEb
->getRecoverFocusOnEnter() )
3011 _OldCaptureKeyboard
= _CaptureKeyboard
;
3015 CGroupEditBoxBase::disableSelection();
3017 if (!newEb
->getAHOnFocus().empty())
3019 CAHManager::getInstance()->runActionHandler(newEb
->getAHOnFocus(), newEb
, newEb
->getAHOnFocusParams());
3023 _CaptureKeyboard
= c
;
3024 notifyElementCaptured(c
);
3027 // ------------------------------------------------------------------------------------------------
3028 void CWidgetManager::resetCaptureKeyboard()
3030 CCtrlBase
*captureKeyboard
= _CaptureKeyboard
;
3031 _OldCaptureKeyboard
= NULL
;
3032 _CaptureKeyboard
= NULL
;
3033 if (captureKeyboard
)
3035 captureKeyboard
->onKeyboardCaptureLost();
3039 // ***************************************************************************
3040 void CWidgetManager::registerClockMsgTarget(CCtrlBase
*vb
)
3043 if (isClockMsgTarget(vb
))
3045 nlwarning("<CInterfaceManager::registerClockMsgTarget> Element %s is already registered", vb
->getId().c_str());
3048 _ClockMsgTargets
.push_back(vb
);
3051 // ***************************************************************************
3052 void CWidgetManager::unregisterClockMsgTarget(CCtrlBase
*vb
)
3055 std::list
<CCtrlBase
*>::iterator it
= std::find(_ClockMsgTargets
.begin(), _ClockMsgTargets
.end(), vb
);
3056 if (it
!= _ClockMsgTargets
.end())
3058 // instead of deleting, just mark as deleted incase we are inside iterating loop,
3059 // it will be removed in sendClockTickEvent
3064 // ***************************************************************************
3065 bool CWidgetManager::isClockMsgTarget(CCtrlBase
*vb
) const
3067 std::list
<CCtrlBase
*>::const_iterator it
= std::find(_ClockMsgTargets
.begin(), _ClockMsgTargets
.end(), vb
);
3068 return it
!= _ClockMsgTargets
.end();
3071 void CWidgetManager::sendClockTickEvent()
3073 CEventDescriptorSystem clockTick
;
3074 clockTick
.setEventTypeExtended(CEventDescriptorSystem::clocktick
);
3076 if (_CapturePointerLeft
)
3078 _CapturePointerLeft
->handleEvent(clockTick
);
3080 if (_CapturePointerRight
)
3082 _CapturePointerRight
->handleEvent(clockTick
);
3085 // and send clock tick msg to ctrl that are registered
3086 for(std::list
<CCtrlBase
*>::iterator it
= _ClockMsgTargets
.begin(); it
!= _ClockMsgTargets
.end();)
3088 CCtrlBase
* ctrl
= *it
;
3091 ctrl
->handleEvent(clockTick
);
3095 it
= _ClockMsgTargets
.erase(it
);
3099 // ------------------------------------------------------------------------------------------------
3100 void CWidgetManager::notifyElementCaptured(CCtrlBase
*c
)
3102 std::set
<CCtrlBase
*> seen
;
3103 CCtrlBase
*curr
= c
;
3107 curr
->elementCaptured(c
);
3108 curr
= curr
->getParent();
3110 // also warn the ctrl under the pointer
3111 for (uint i
= 0; i
< (uint
) _CtrlsUnderPointer
.size(); ++i
)
3113 if (!seen
.count(_CtrlsUnderPointer
[i
]))
3115 _CtrlsUnderPointer
[i
]->elementCaptured(c
);
3120 // ------------------------------------------------------------------------------------------------
3121 void CWidgetManager::makeWindow(CInterfaceGroup
*group
)
3127 for (i
= 0; i
< _MasterGroups
.size(); ++i
)
3129 if (_MasterGroups
[i
].Group
== group
->getParent())
3133 if (i
== _MasterGroups
.size())
3135 std::string stmp
= std::string("not found master group for window: ")+group
->getId();
3136 nlwarning (stmp
.c_str());
3141 // check if group hasn't been inserted twice.
3142 if (_MasterGroups
[i
].isWindowPresent(group
))
3144 nlwarning("Window inserted twice");
3148 _MasterGroups
[i
].addWindow(group
,group
->getPriority());
3153 // ------------------------------------------------------------------------------------------------
3154 void CWidgetManager::unMakeWindow(CInterfaceGroup
*group
, bool noWarning
)
3160 for (i
= 0; i
< _MasterGroups
.size(); ++i
)
3162 if (_MasterGroups
[i
].Group
== group
->getParent())
3166 if (i
== _MasterGroups
.size())
3170 std::string stmp
= std::string("not found master group for window: ")+group
->getId();
3171 nlwarning (stmp
.c_str());
3177 // check if group hasn't been inserted twice.
3178 if (!_MasterGroups
[i
].isWindowPresent(group
))
3181 nlwarning("Window not inserted in master group");
3185 _MasterGroups
[i
].delWindow(group
);
3190 // ------------------------------------------------------------------------------------------------
3191 void CWidgetManager::setGlobalColor (NLMISC::CRGBA col
)
3195 _RProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:R");
3196 _GProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:G");
3197 _BProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:B");
3198 _AProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:A");
3200 _RProp
->setValue32 (col
.R
);
3201 _GProp
->setValue32 (col
.G
);
3202 _BProp
->setValue32 (col
.B
);
3203 _AProp
->setValue32 (col
.A
);
3207 // set the global color for content (the same with modulated alpha)
3208 _GlobalColorForContent
= _GlobalColor
;
3209 _GlobalColorForContent
.A
= (uint8
) (( (uint16
) _GlobalColorForContent
.A
* (uint16
) _ContentAlpha
) >> 8);
3212 // ***************************************************************************
3213 void CWidgetManager::setContentAlpha(uint8 alpha
)
3215 _ContentAlpha
= alpha
;
3216 // update alpha of global color
3217 _GlobalColorForContent
.A
= alpha
;/*(uint8) (( (uint16) _GlobalColor.A * (uint16) _ContentAlpha) >> 8);*/
3220 void CWidgetManager::resetColorProps()
3228 // ------------------------------------------------------------------------------------------------
3229 CInterfaceOptions
* CWidgetManager::getOptions( const std::string
&name
)
3231 std::map
< std::string
, NLMISC::CSmartPtr
< CInterfaceOptions
> >::iterator it
= _OptionsMap
.find( name
);
3232 if( it
== _OptionsMap
.end() )
3238 void CWidgetManager::addOptions( std::string name
, CInterfaceOptions
*options
)
3240 _OptionsMap
.insert( std::map
< std::string
, CInterfaceOptions
* >::value_type( name
, options
) );
3243 void CWidgetManager::removeOptions( std::string name
)
3245 _OptionsMap
.erase( name
);
3248 void CWidgetManager::removeAllOptions()
3250 _OptionsMap
.clear();
3254 bool CWidgetManager::serializeOptions( xmlNodePtr parentNode
) const
3256 if( parentNode
== NULL
)
3259 std::map
< std::string
, NLMISC::CSmartPtr
< CInterfaceOptions
> >::const_iterator itr
;
3260 for( itr
= _OptionsMap
.begin(); itr
!= _OptionsMap
.end(); ++itr
)
3262 if( itr
->second
->serialize( parentNode
, itr
->first
) == NULL
)
3270 bool CWidgetManager::serializeTreeData( xmlNodePtr parentNode
) const
3272 if( parentNode
== NULL
)
3275 std::vector
< SMasterGroup
>::size_type i
;
3276 for( i
= 0; i
< _MasterGroups
.size(); i
++ )
3278 const SMasterGroup
&mg
= _MasterGroups
[ i
];
3280 std::vector
< CInterfaceGroup
* >::size_type j
;
3281 for( j
= 0; j
< mg
.Group
->getNumGroup(); j
++ )
3283 CInterfaceGroup
*g
= mg
.Group
->getGroup( j
);
3286 if( dynamic_cast< CGroupModal
* >( g
) != NULL
)
3289 if( g
->serializeTreeData( parentNode
) == NULL
)
3298 // ***************************************************************************
3299 void CWidgetManager::enableMouseHandling( bool handle
)
3301 _MouseHandlingEnabled
= handle
;
3307 // If Left captured, reset
3308 if( getCapturePointerLeft() )
3309 setCapturePointerLeft( NULL
);
3312 if( getCapturePointerRight() )
3313 setCapturePointerRight( NULL
);
3315 // Avoid any problem with modals
3316 disableModalWindow();
3320 // ***************************************************************************
3321 uint
CWidgetManager::getUserDblClickDelay()
3324 NLMISC::CCDBNodeLeaf
*pNL
= CDBManager::getInstance()->getDbProp("UI:SAVE:DOUBLE_CLICK_SPEED");
3326 nVal
= pNL
->getValue32();
3328 uint dbclickDelay
= (uint
)(DOUBLE_CLICK_MIN
+ (DOUBLE_CLICK_MAX
-DOUBLE_CLICK_MIN
) * (float)nVal
/ 100.0f
);
3329 return dbclickDelay
;
3332 // ------------------------------------------------------------------------------------------------
3333 void CWidgetManager::setupOptions()
3335 // After parsing options and templates node -> init system options.
3336 CInterfaceOptions
*opt
= getOptions( "system" );
3339 // List here all Special options
3340 _SystemOptions
[OptionCtrlSheetGrayColor
]= opt
->getValue("ctrl_sheet_gray_color");
3341 _SystemOptions
[OptionCtrlTextGrayColor
]= opt
->getValue("ctrl_text_gray_color");
3342 _SystemOptions
[OptionCtrlSheetRedifyColor
]= opt
->getValue("ctrl_sheet_redify_color");
3343 _SystemOptions
[OptionCtrlTextRedifyColor
]= opt
->getValue("ctrl_text_redify_color");
3344 _SystemOptions
[OptionCtrlSheetGreenifyColor
]= opt
->getValue("ctrl_sheet_greenify_color");
3345 _SystemOptions
[OptionCtrlTextGreenifyColor
]= opt
->getValue("ctrl_text_greenify_color");
3346 _SystemOptions
[OptionViewTextOverBackColor
]= opt
->getValue("text_over_back_color");
3347 _SystemOptions
[OptionFont
]= opt
->getValue("font");
3348 _SystemOptions
[OptionAddCoefFont
]= opt
->getValue("add_coef_font");
3349 _SystemOptions
[OptionMulCoefAnim
]= opt
->getValue("mul_coef_anim");
3350 _SystemOptions
[OptionTimeoutBubbles
]= opt
->getValue("bubbles_timeout");
3351 _SystemOptions
[OptionTimeoutMessages
]= opt
->getValue("messages_timeout");
3352 _SystemOptions
[OptionTimeoutContext
]= opt
->getValue("context_timeout");
3353 _SystemOptions
[OptionTimeoutContextHtml
]= opt
->getValue("context_html_timeout");
3354 _SystemOptions
[OptionMonospaceFont
]= opt
->getValue("monospace_font");
3359 // Get the alpha roll over speed
3360 float CWidgetManager::getAlphaRolloverSpeed()
3362 if( _AlphaRolloverSpeedDB
== NULL
)
3363 _AlphaRolloverSpeedDB
= CDBManager::getInstance()->getDbProp("UI:SAVE:ALPHA_ROLLOVER_SPEED");
3364 float fTmp
= ROLLOVER_MIN_DELTA_PER_MS
+ (ROLLOVER_MAX_DELTA_PER_MS
- ROLLOVER_MIN_DELTA_PER_MS
) * 0.01f
* (100 - _AlphaRolloverSpeedDB
->getValue32());
3365 return fTmp
*fTmp
*fTmp
;
3368 void CWidgetManager::resetAlphaRolloverSpeedProps()
3370 _AlphaRolloverSpeedDB
= NULL
;
3373 void CWidgetManager::setContainerAlpha(uint8 alpha
)
3375 _ContainerAlpha
= alpha
;
3376 // update alpha of global color
3377 NLMISC::CRGBA c
= getGlobalColor();
3378 c
.A
= alpha
;/*(uint8) (( (uint16) _GlobalColor.A * (uint16) _ContainerAlpha) >> 8); */
3379 setGlobalColor( c
);
3382 void CWidgetManager::updateGlobalAlphas()
3384 if (!_GlobalContentAlphaDB
)
3386 _GlobalContentAlphaDB
= CDBManager::getInstance()->getDbProp("UI:SAVE:CONTENT_ALPHA");
3387 nlassert(_GlobalContentAlphaDB
);
3388 _GlobalContainerAlphaDB
= CDBManager::getInstance()->getDbProp("UI:SAVE:CONTAINER_ALPHA");
3389 nlassert(_GlobalContainerAlphaDB
);
3390 _GlobalContentRolloverFactorDB
= CDBManager::getInstance()->getDbProp("UI:SAVE:CONTENT_ROLLOVER_FACTOR");
3391 nlassert(_GlobalContentRolloverFactorDB
);
3392 _GlobalContainerRolloverFactorDB
= CDBManager::getInstance()->getDbProp("UI:SAVE:CONTAINER_ROLLOVER_FACTOR");
3393 nlassert(_GlobalContainerRolloverFactorDB
);
3395 _GlobalContentAlpha
= (uint8
)_GlobalContentAlphaDB
->getValue32();
3396 _GlobalContainerAlpha
= (uint8
)_GlobalContainerAlphaDB
->getValue32();
3397 _GlobalRolloverFactorContent
= (uint8
)_GlobalContentRolloverFactorDB
->getValue32();
3398 _GlobalRolloverFactorContainer
= (uint8
)_GlobalContainerRolloverFactorDB
->getValue32();
3401 void CWidgetManager::resetGlobalAlphasProps()
3403 _GlobalContentAlphaDB
= NULL
;
3404 _GlobalContainerAlphaDB
= NULL
;
3405 _GlobalContentRolloverFactorDB
= NULL
;
3406 _GlobalContainerRolloverFactorDB
= NULL
;
3409 void CWidgetManager::registerNewScreenSizeHandler( INewScreenSizeHandler
*handler
)
3411 std::vector
< INewScreenSizeHandler
* >::iterator itr
=
3412 std::find( newScreenSizeHandlers
.begin(), newScreenSizeHandlers
.end(), handler
);
3414 if( itr
!= newScreenSizeHandlers
.end() )
3417 newScreenSizeHandlers
.push_back( handler
);
3420 void CWidgetManager::removeNewScreenSizeHandler( INewScreenSizeHandler
*handler
)
3422 std::vector
< INewScreenSizeHandler
* >::iterator itr
=
3423 std::find( newScreenSizeHandlers
.begin(), newScreenSizeHandlers
.end(), handler
);
3425 if( itr
== newScreenSizeHandlers
.end() )
3428 newScreenSizeHandlers
.erase( itr
);
3431 void CWidgetManager::registerOnWidgetsDrawnHandler( IOnWidgetsDrawnHandler
* handler
)
3433 std::vector
< IOnWidgetsDrawnHandler
* >::iterator itr
=
3434 std::find( onWidgetsDrawnHandlers
.begin(), onWidgetsDrawnHandlers
.end(), handler
);
3436 if( itr
!= onWidgetsDrawnHandlers
.end() )
3439 onWidgetsDrawnHandlers
.push_back( handler
);
3442 void CWidgetManager::removeOnWidgetsDrawnHandler( IOnWidgetsDrawnHandler
* handler
)
3444 std::vector
< IOnWidgetsDrawnHandler
* >::iterator itr
=
3445 std::find( onWidgetsDrawnHandlers
.begin(), onWidgetsDrawnHandlers
.end(), handler
);
3447 if( itr
== onWidgetsDrawnHandlers
.end() )
3450 onWidgetsDrawnHandlers
.erase( itr
);
3453 // ------------------------------------------------------------------------------------------------
3454 void CWidgetManager::startAnim( const std::string
&animId
)
3456 CInterfaceAnim
*pIT
= _Parser
->getAnim( animId
);
3462 activeAnims
.push_back( pIT
);
3465 void CWidgetManager::removeFinishedAnims()
3468 for( i
= 0; i
< (sint32
)activeAnims
.size(); ++i
)
3470 CInterfaceAnim
*pIA
= activeAnims
[i
];
3471 if (pIA
->isFinished())
3473 activeAnims
.erase( activeAnims
.begin() + i
);
3479 // ------------------------------------------------------------------------------------------------
3480 void CWidgetManager::stopAnim( const std::string
&animId
)
3482 CInterfaceAnim
*pIT
= _Parser
->getAnim( animId
);
3484 for( uint i
= 0; i
< activeAnims
.size(); ++i
)
3485 if( activeAnims
[ i
] == pIT
)
3487 activeAnims
.erase( activeAnims
.begin() + i
);
3488 if( !pIT
->isFinished() )
3494 void CWidgetManager::updateAnims()
3496 for( std::vector
< CInterfaceAnim
* >::size_type i
= 0; i
< activeAnims
.size(); i
++ )
3497 activeAnims
[ i
]->update();
3501 // ------------------------------------------------------------------------------------------------
3502 void CWidgetManager::runProcedure( const std::string
&procName
, CCtrlBase
*pCaller
,
3503 const std::vector
< std::string
> ¶mList
)
3505 CProcedure
*procp
= _Parser
->getProc( procName
);
3509 CProcedure
&proc
= *procp
;
3512 for( uint i
= 0; i
< proc
.Actions
.size(); i
++ )
3514 const CProcAction
&action
= proc
.Actions
[i
];
3515 // test if the condition for the action is valid
3516 if (!action
.CondBlocks
.empty())
3518 CInterfaceExprValue result
;
3519 result
.setBool( false );
3521 action
.buildCond( paramList
, cond
);
3522 CInterfaceExpr::eval( cond
, result
, NULL
);
3524 if( result
.toBool() )
3525 if( !result
.getBool() )
3528 // build the params sting
3530 action
.buildParams( paramList
, params
);
3532 //nlwarning("step %d : %s, %s", (int) i, action.Action.c_str(), params.c_str());
3533 CAHManager::getInstance()->runActionHandler( action
.Action
, pCaller
, params
);
3537 // ------------------------------------------------------------------------------------------------
3538 void CWidgetManager::setProcedureAction( const std::string
&procName
, uint actionIndex
,
3539 const std::string
&ah
, const std::string
¶ms
)
3541 CProcedure
*procp
= _Parser
->getProc( procName
);
3545 CProcedure
&proc
= *procp
;
3547 // set wanted action
3548 if( actionIndex
<proc
.Actions
.size() )
3550 CProcAction
&action
= proc
.Actions
[ actionIndex
];
3552 action
.ParamBlocks
.clear();
3553 action
.ParamBlocks
.resize( 1 );
3554 action
.ParamBlocks
[ 0 ].String
= params
;
3558 void CWidgetManager::getEditorSelection( std::vector
< std::string
> &selection
)
3561 for(uint i
= 0; i
< editorSelection
.size(); ++i
)
3562 selection
.push_back(editorSelection
[i
]);
3565 void CWidgetManager::selectWidget( const std::string
&name
)
3567 std::vector
< std::string
>::iterator itr
3568 = std::find( editorSelection
.begin(), editorSelection
.end(), name
);
3570 CInterfaceElement
*e
= getElementFromId( name
);
3572 if( itr
!= editorSelection
.end() )
3574 // If multiselection is on unselect if already selected
3575 if( multiSelection
)
3577 editorSelection
.erase( itr
);
3579 e
->setEditorSelected( false );
3584 // Select if not yet selected
3587 // If multiselection is off, we can only have 1 widget selected
3588 if( !multiSelection
)
3590 editorSelection
.clear();
3593 e
->setEditorSelected( true );
3594 editorSelection
.push_back( name
);
3599 notifySelectionWatchers();
3602 void CWidgetManager::clearEditorSelection()
3604 editorSelection
.clear();
3605 notifySelectionWatchers();
3608 void CWidgetManager::notifySelectionWatchers()
3610 std::vector
< IEditorSelectionWatcher
* >::iterator itr
= selectionWatchers
.begin();
3611 while( itr
!= selectionWatchers
.end() )
3613 (*itr
)->selectionChanged();
3618 void CWidgetManager::registerSelectionWatcher( IEditorSelectionWatcher
*watcher
)
3620 std::vector
< IEditorSelectionWatcher
* >::iterator itr
=
3621 std::find( selectionWatchers
.begin(), selectionWatchers
.end(), watcher
);
3623 // We already have this watcher
3624 if( itr
!= selectionWatchers
.end() )
3627 selectionWatchers
.push_back( watcher
);
3630 void CWidgetManager::unregisterSelectionWatcher( IEditorSelectionWatcher
*watcher
)
3632 std::vector
< IEditorSelectionWatcher
* >::iterator itr
=
3633 std::find( selectionWatchers
.begin(), selectionWatchers
.end(), watcher
);
3635 // We don't have this watcher
3636 if( itr
== selectionWatchers
.end() )
3639 selectionWatchers
.erase( itr
);
3642 void CWidgetManager::onWidgetAdded( const std::string
&id
)
3644 std::vector
< IWidgetWatcher
* >::const_iterator itr
= widgetWatchers
.begin();
3645 while( itr
!= widgetWatchers
.end() )
3647 (*itr
)->onWidgetAdded( id
);
3652 void CWidgetManager::onWidgetMoved( const std::string
&oldid
, const std::string
&newid
)
3654 std::vector
< IWidgetWatcher
* >::const_iterator itr
= widgetWatchers
.begin();
3655 while( itr
!= widgetWatchers
.end() )
3657 (*itr
)->onWidgetMoved( oldid
, newid
);
3662 void CWidgetManager::registerWidgetWatcher( IWidgetWatcher
*watcher
)
3664 std::vector
< IWidgetWatcher
* >::const_iterator itr
3665 = std::find( widgetWatchers
.begin(), widgetWatchers
.end(), watcher
);
3667 if( itr
!= widgetWatchers
.end() )
3670 widgetWatchers
.push_back( watcher
);
3673 void CWidgetManager::unregisterWidgetWatcher( IWidgetWatcher
*watcher
)
3675 std::vector
< IWidgetWatcher
* >::iterator itr
3676 = std::find( widgetWatchers
.begin(), widgetWatchers
.end(), watcher
);
3678 if( itr
== widgetWatchers
.end() )
3681 widgetWatchers
.erase( itr
);
3684 CInterfaceElement
* CWidgetManager::addWidgetToGroup( std::string
&group
, std::string
&widgetClass
, std::string
&widgetName
)
3686 // Check if this group exists
3687 CInterfaceElement
*e
= getElementFromId( group
);
3690 CInterfaceGroup
*g
= dynamic_cast< CInterfaceGroup
* >( e
);
3694 // Check if an element already exists with that name
3695 if( g
->getElement( widgetName
) != NULL
)
3698 // Create and add the new widget
3699 CViewBase
*v
= getParser()->createClass( widgetClass
);
3703 v
->setId( std::string( g
->getId() + ":" + widgetName
) );
3707 g
->addGroup( dynamic_cast< CInterfaceGroup
* >( v
) );
3710 g
->addCtrl( dynamic_cast< CCtrlBase
* >( v
) );
3714 onWidgetAdded( v
->getId() );
3719 bool CWidgetManager::groupSelection()
3721 std::vector
< CInterfaceElement
* > elms
;
3723 // Resolve the widget names
3724 for(uint i
= 0; i
< editorSelection
.size(); ++i
)
3726 CInterfaceElement
*e
= getElementFromId(editorSelection
[i
]);
3731 editorSelection
.clear();
3736 // Create the group as the subgroup of the top window
3737 CInterfaceGroup
*g
= static_cast< CInterfaceGroup
* >( getParser()->createClass( "interface_group" ) );
3738 getTopWindow()->addGroup( g
);
3739 g
->setParent( getTopWindow() );
3740 g
->setIdRecurse( std::string( "group" ) + NLMISC::toString( _WidgetCount
) );
3742 onWidgetAdded( g
->getId() );
3746 // Reparent the widgets to the new group
3747 for(uint i
= 0; i
< elms
.size(); ++i
)
3749 CInterfaceElement
*e
= elms
[i
];
3751 CInterfaceGroup
*p
= e
->getParent();
3758 e
->setParentSize(g
);
3759 e
->setIdRecurse(e
->getShortId());
3761 onWidgetMoved(oldId
, e
->getId());
3765 // Make sure widgets aren't clipped because the group isn't big enough
3767 // Make sure widgets are aligned
3769 // Align the new group to the top window
3770 g
->alignTo( getTopWindow() );
3772 g
->setActive( true );
3777 bool CWidgetManager::unGroupSelection()
3779 if( editorSelection
.size() != 1 )
3782 // Does the element exist?
3783 CInterfaceElement
*e
= getElementFromId( editorSelection
[ 0 ] );
3787 // Is the element a group?
3788 CInterfaceGroup
*g
= dynamic_cast< CInterfaceGroup
* >( e
);
3792 // Can't blow up a root group :(
3793 CInterfaceGroup
*p
= g
->getParent();
3798 bool ok
= g
->explode();
3804 clearEditorSelection();
3812 bool CWidgetManager::createNewGUI( const std::string
&project
, const std::string
&window
)
3816 for(uint i
= 0; i
< _MasterGroups
.size(); ++i
)
3817 delete _MasterGroups
[i
].Group
;
3818 _MasterGroups
.clear();
3820 // First create the master group
3821 CRootGroup
*root
= new CRootGroup( CViewBase::TCtorParam() );
3826 root
->setIdRecurse( project
);
3829 root
->setActive( true );
3831 // Create the first / main window
3832 CInterfaceGroup
*wnd
= new CInterfaceGroup( CViewBase::TCtorParam() );
3835 wnd
->setParent( root
);
3836 wnd
->setParentPos( root
);
3837 wnd
->setParentSize( root
);
3838 wnd
->setPosRef( Hotspot_MM
);
3839 wnd
->setParentPosRef( Hotspot_MM
);
3840 wnd
->setIdRecurse( window
);
3841 wnd
->setActive( true );
3844 root
->addElement( wnd
);
3845 mg
.addWindow( wnd
, wnd
->getPriority() );
3846 _MasterGroups
.push_back( mg
);
3848 _Pointer
= new CViewPointer( CViewBase::TCtorParam() );
3850 IParser
*parser
= getParser();
3853 // Set base color to white
3858 v
.entry
= "UI:SAVE:COLOR:R";
3859 parser
->setVariable( v
);
3861 v
.entry
= "UI:SAVE:COLOR:G";
3862 parser
->setVariable( v
);
3864 v
.entry
= "UI:SAVE:COLOR:B";
3865 parser
->setVariable( v
);
3867 v
.entry
= "UI:SAVE:COLOR:A";
3868 parser
->setVariable( v
);
3874 // ------------------------------------------------------------------------------------------------
3875 void CWidgetManager::notifyInterfaceScaleWatchers()
3877 std::vector
< IInterfaceScaleWatcher
* >::iterator itr
= scaleWatchers
.begin();
3878 while( itr
!= scaleWatchers
.end() )
3880 (*itr
)->onInterfaceScaleChanged();
3885 // ------------------------------------------------------------------------------------------------
3886 void CWidgetManager::registerInterfaceScaleWatcher( IInterfaceScaleWatcher
*watcher
)
3888 std::vector
< IInterfaceScaleWatcher
* >::const_iterator itr
3889 = std::find( scaleWatchers
.begin(), scaleWatchers
.end(), watcher
);
3891 if( itr
!= scaleWatchers
.end() )
3894 scaleWatchers
.push_back( watcher
);
3897 // ------------------------------------------------------------------------------------------------
3898 void CWidgetManager::unregisterInterfaceScaleWatcher( IInterfaceScaleWatcher
*watcher
)
3900 std::vector
< IInterfaceScaleWatcher
* >::iterator itr
3901 = std::find( scaleWatchers
.begin(), scaleWatchers
.end(), watcher
);
3903 if( itr
== scaleWatchers
.end() )
3906 scaleWatchers
.erase( itr
);
3909 // ------------------------------------------------------------------------------------------------
3910 CWidgetManager::CWidgetManager()
3913 CStringShared::createStringMapper();
3915 CReflectableRegister::registerClasses();
3917 _Parser
= IParser::createParser();
3920 curContextHelp
= NULL
;
3921 _ContextHelpActive
= true;
3922 _DeltaTimeStopingContextHelp
= 0;
3923 _MaxTimeStopingContextHelp
= 0.2f
;
3924 _LastXContextHelp
= -10000;
3925 _LastYContextHelp
= -10000;
3928 resetAlphaRolloverSpeedProps();
3929 resetGlobalAlphasProps();
3931 _GlobalColor
= NLMISC::CRGBA(255,255,255,255);
3932 _GlobalColorForContent
= _GlobalColor
;
3933 _ContentAlpha
= 255;
3934 _ContainerAlpha
= 255;
3935 _GlobalContentAlpha
= 255;
3936 _GlobalContainerAlpha
= 255;
3937 _GlobalRolloverFactorContent
= 255;
3938 _GlobalRolloverFactorContainer
= 255;
3939 _AlphaRolloverSpeedDB
= NULL
;
3941 _MouseHandlingEnabled
= true;
3942 _MouseOverWindow
= false;
3946 _InterfaceScale
= 1.0f
;
3948 _WindowSnapDistance
= 10;
3949 _WindowSnapInvert
= false;
3951 _GroupSelection
= false;
3952 multiSelection
= false;
3955 _ContextHelpContainerColor
= NLMISC::CRGBA(255,255,159,255);
3956 _ContextHelpContentAlpha
= 255;
3957 _ContextHelpContentAlphaDB
= NULL
;
3958 _ContextHelpContainerColorDB
= NULL
;
3959 _ContextHelpContainerAlphaDB
= NULL
;
3962 CWidgetManager::~CWidgetManager()
3964 for (uint32 i
= 0; i
< _MasterGroups
.size(); ++i
)
3966 delete _MasterGroups
[i
].Group
;
3973 curContextHelp
= NULL
;
3975 CStringShared::deleteStringMapper();
3977 editorSelection
.clear();