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 activeAnims
.clear();
1054 editorSelection
.clear();
1058 // ------------------------------------------------------------------------------------------------
1059 void CWidgetManager::checkCoords()
1061 H_AUTO ( RZ_Interface_validateCoords
)
1063 uint32 nMasterGroup
;
1066 H_AUTO ( RZ_Interface_checkCoords
)
1068 // checkCoords all the windows
1069 for (nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
1071 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
1072 if (rMG
.Group
->getActive())
1074 for (uint8 nPriority
= 0; nPriority
< WIN_PRIORITY_MAX
; nPriority
++)
1076 std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
];
1077 std::list
<CInterfaceGroup
*>::const_iterator itw
;
1078 for (itw
= rList
.begin(); itw
!= rList
.end();)
1080 CInterfaceGroup
*pIG
= *itw
;
1081 itw
++; // since checkCoords invalidate the iterator, be sure we move to the next one before
1082 if (pIG
->getActive())
1083 pIG
->checkCoords ();
1090 bool bRecomputeCtrlUnderPtr
= false;
1092 H_AUTO ( RZ_Interface_updateCoords
)
1094 // updateCoords all the needed windows
1095 for (nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
1097 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
1098 if (rMG
.Group
->getActive())
1100 for (uint8 nPriority
= 0; nPriority
< WIN_PRIORITY_MAX
; nPriority
++)
1102 std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
];
1103 std::list
<CInterfaceGroup
*>::const_iterator itw
;
1104 for (itw
= rList
.begin(); itw
!= rList
.end(); itw
++)
1106 CInterfaceGroup
*pIG
= *itw
;
1107 bool updateCoordCalled
= false;
1108 // updateCoords the window only if the master group is his parent and if need it
1109 // do it until updateCoords() no more invalidate coordinates!!
1111 // add deadlock counter to prevent endless loop (Issue #73: web browser long scroll lockup)
1113 while (--deadlock
> 0 && pIG
->getParent()==rMG
.Group
&& (pIG
->getInvalidCoords()>0))
1115 bRecomputeCtrlUnderPtr
= true;
1116 // Update as many pass wanted (3 time for complex resizing, 1 for scroll for example)
1117 uint numPass
= pIG
->getInvalidCoords();
1118 // reset before updateCoords
1119 pIG
->resetInvalidCoords();
1120 for(uint i
=0;i
<numPass
;i
++)
1122 pIG
->updateCoords ();
1124 updateCoordCalled
= true;
1126 // If the group need to update pos each frame (eg: CGroupInScene),
1127 // and updateCoords not called
1128 if(pIG
->getParent()==rMG
.Group
&& !updateCoordCalled
&& pIG
->isNeedFrameUpdatePos())
1130 // This Group will compute the delta to apply.
1131 pIG
->onFrameUpdateWindowPos(0,0);
1138 if ( getPointer() != NULL
)
1139 getPointer()->updateCoords();
1144 if (bRecomputeCtrlUnderPtr
)
1146 H_AUTO ( RZ_Interface_RecomputeCtrlUnderPtr
)
1147 if ( getPointer() != NULL
)
1149 sint32 mx
= _Pointer
->getX();
1150 sint32 my
= _Pointer
->getY();
1151 getViewsUnder (mx
, my
, _ViewsUnderPointer
);
1152 getCtrlsUnder (mx
, my
, _CtrlsUnderPointer
);
1153 getGroupsUnder (mx
, my
, _GroupsUnderPointer
);
1154 CInterfaceGroup
*ptr
= getWindowUnder (mx
, my
);
1161 // ----------------------------------------------------------------------------
1162 CInterfaceGroup
* CWidgetManager::getWindowForActiveMasterGroup( const std::string
&window
)
1164 // Search for all elements
1165 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
1167 const SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
1168 if (rMG
.Group
->getActive())
1170 CInterfaceElement
*pEL
= getElementFromId( rMG
.Group
->getId() + ":" + window
);
1171 if(pEL
&& pEL
->isGroup())
1172 return (CInterfaceGroup
*)pEL
;
1180 // ***************************************************************************
1181 void CWidgetManager::drawOverExtendViewText()
1183 if( getOverExtendViewText() )
1185 CViewText
*vtSrc
= dynamic_cast<CViewText
*>( getOverExtendViewText() );
1187 CInterfaceGroup
*groupOver
= getWindowForActiveMasterGroup("over_extend_view_text");
1190 CViewText
*vtDst
= dynamic_cast<CViewText
*>(groupOver
->getView("text"));
1193 groupOver
->setParentPos(vtSrc
);
1195 sint32 backupX
= groupOver
->getX();
1197 // Copy all aspects to the view
1198 vtDst
->setLocalized (vtSrc
->isLocalized());
1199 vtDst
->setText (vtSrc
->getText());
1200 vtDst
->setFontSize (vtSrc
->getFontSize());
1201 vtDst
->setColor (vtSrc
->getColor());
1202 vtDst
->setModulateGlobalColor(vtSrc
->getModulateGlobalColor());
1203 vtDst
->setShadow(vtSrc
->getShadow());
1204 vtDst
->setShadowOutline(vtSrc
->getShadowOutline());
1205 vtDst
->setShadowColor(vtSrc
->getShadowColor());
1206 vtDst
->setCaseMode(vtSrc
->getCaseMode());
1207 vtDst
->setUnderlined(vtSrc
->getUnderlined());
1210 CViewBitmap
*pBack
= dynamic_cast<CViewBitmap
*>(groupOver
->getView("midback"));
1211 CViewBitmap
*pOutline
= dynamic_cast<CViewBitmap
*>(groupOver
->getView("midoutline"));
1213 pBack
->setColor( getOverExtendViewTextBackColor() );
1216 pOutline
->setColor(vtSrc
->getColor());
1217 pOutline
->setModulateGlobalColor(vtSrc
->getModulateGlobalColor());
1220 // update one time only to get correct W/H
1221 groupOver
->updateCoords ();
1223 // align and clamp to screen coords
1224 sint32 x
= -backupX
;
1225 if (vtSrc
->isClampRight())
1227 x
+= std::max(0, (groupOver
->getXReal() + groupOver
->getWReal()) - (groupOver
->getParent()->getXReal() + groupOver
->getParent()->getWReal()));
1231 x
+= vtDst
->getWReal() - vtSrc
->getWReal();
1232 if ( x
> (groupOver
->getXReal() - groupOver
->getParent()->getXReal()) )
1234 x
-= x
- (groupOver
->getXReal() - groupOver
->getParent()->getXReal());
1237 if (x
!= 0) groupOver
->setX(-x
);
1239 // TODO: there should be no overflow on y, unless barely visible and next to screen border
1241 groupOver
->updateCoords();
1246 CViewRenderer::getInstance()->flush();
1248 // restore backup values
1249 if (x
!= 0) groupOver
->setX(backupX
);
1253 // Reset the ptr so at next frame, won't be rendered (but if reset)
1254 setOverExtendViewText( NULL
, getOverExtendViewTextBackColor() );
1258 // ----------------------------------------------------------------------------
1259 void CWidgetManager::snapIfClose(CInterfaceGroup
*group
)
1261 if (!group
|| _WindowSnapDistance
== 0 || _WindowSnapInvert
!= lastKeyEvent
.isShiftDown())
1264 uint hsnap
= _WindowSnapDistance
;
1265 uint vsnap
= _WindowSnapDistance
;
1267 sint32 newX
= group
->getX();
1268 sint32 newY
= group
->getY();
1270 // new coords for window without snap
1271 // used to calculate distance from target
1273 sint gRight
= newX
+ group
->getWReal();
1275 sint gBottom
= newY
- group
->getHReal();
1277 // current window coords as if already snaped
1278 // used to calculate target for snap
1279 sint gLeftR
= group
->getXReal();
1280 sint gRightR
= gLeftR
+ group
->getWReal();
1281 sint gBottomR
= group
->getYReal();
1282 sint gTopR
= gBottomR
+ group
->getHReal();
1284 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
1286 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
1287 if (!rMG
.Group
->getActive()) continue;
1289 for (uint8 nPriority
= WIN_PRIORITY_MAX
; nPriority
> 0 ; nPriority
--)
1291 const std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
-1];
1292 std::list
<CInterfaceGroup
*>::const_reverse_iterator itw
;
1293 for (itw
= rList
.rbegin(); itw
!= rList
.rend(); itw
++)
1295 CInterfaceGroup
*pIG
= *itw
;
1296 // do not snap to self, inactive, or not using mouse interaction
1297 if (group
== pIG
|| !(pIG
->getActive() && pIG
->getUseCursor()))
1301 sint wLeft
= pIG
->getXReal();
1302 sint wRight
= pIG
->getXReal() + pIG
->getWReal();
1303 sint wTop
= pIG
->getYReal() + pIG
->getHReal();
1304 sint wBottom
= pIG
->getYReal();
1307 if (gTopR
>= wBottom
&& gBottomR
<= wTop
)
1309 delta
= abs(gRight
- wLeft
);
1313 newX
= wLeft
- group
->getWReal();
1316 delta
= abs(gLeft
- wRight
);
1323 delta
= abs(gLeft
- wLeft
);
1330 delta
= abs(gRight
- wRight
);
1334 newX
= wRight
- group
->getWReal();
1338 if (gLeftR
<= wRight
&& gRightR
>= wLeft
)
1340 delta
= abs(gTop
- wBottom
);
1347 delta
= abs(gBottom
- wTop
);
1351 newY
= wTop
+ group
->getHReal();
1354 delta
= abs(gTop
- wTop
);
1361 delta
= abs(gBottom
- wBottom
);
1365 newY
= wBottom
+ group
->getHReal();
1376 // ----------------------------------------------------------------------------
1377 uint
CWidgetManager::adjustTooltipPosition( CCtrlBase
*newCtrl
, CInterfaceGroup
*win
, THotSpot ttParentRef
,
1378 THotSpot ttPosRef
, sint32 xParent
, sint32 yParent
,
1379 sint32 wParent
, sint32 hParent
)
1381 CCtrlBase::TToolTipParentType parentType
= newCtrl
->getToolTipParent();
1382 CInterfaceGroup
*groupContextHelp
=
1383 getWindowForActiveMasterGroup(newCtrl
->getContextHelpWindowName());
1385 uint32 _ScreenH
, _ScreenW
;
1386 CViewRenderer::getInstance()->getScreenSize( _ScreenW
, _ScreenH
);
1388 if(ttPosRef
==Hotspot_TTAuto
|| ttParentRef
==Hotspot_TTAuto
)
1390 // NB: keep the special window if type is specialwindow (defined above)
1392 win
= newCtrl
->getRootWindow();
1399 xWin
= win
->getXReal();
1400 yWin
= win
->getYReal();
1401 wWin
= win
->getWReal();
1402 hWin
= win
->getHReal();
1404 // for Window, display top or bottom according to window pos/size
1405 if(parentType
==CCtrlBase::TTWindow
|| parentType
==CCtrlBase::TTSpecialWindow
)
1407 sint32 top
= (sint32
)_ScreenH
- (yWin
+hWin
);
1408 sint32 bottom
= yWin
;
1411 ttParentRef
= Hotspot_TL
;
1412 ttPosRef
= Hotspot_BL
;
1416 ttParentRef
= Hotspot_BL
;
1417 ttPosRef
= Hotspot_TL
;
1420 // for Ctrl, display top, left or right according to window pos/size
1421 else if(parentType
==CCtrlBase::TTCtrl
)
1423 sint32 right
= (sint32
)_ScreenW
- (xWin
+wWin
);
1427 ttParentRef
= Hotspot_TR
;
1428 ttPosRef
= Hotspot_BL
;
1432 ttParentRef
= Hotspot_TL
;
1433 ttPosRef
= Hotspot_BR
;
1439 ttParentRef
= Hotspot_BL
;
1440 ttPosRef
= Hotspot_BL
;
1444 // **** compute coordinates of the tooltip
1447 if (ttParentRef
& Hotspot_Mx
)
1449 if (ttParentRef
& Hotspot_Tx
)
1451 if (ttParentRef
& Hotspot_xM
)
1453 if (ttParentRef
& Hotspot_xR
)
1456 // adjust according to self posref
1457 if (ttPosRef
& Hotspot_Mx
)
1458 y
-= groupContextHelp
->getHReal()/2;
1459 if (ttPosRef
& Hotspot_Tx
)
1460 y
-= groupContextHelp
->getHReal();
1461 if (ttPosRef
& Hotspot_xM
)
1462 x
-= groupContextHelp
->getWReal()/2;
1463 if (ttPosRef
& Hotspot_xR
)
1464 x
-= groupContextHelp
->getWReal();
1467 // **** clamp to screen coords, and set
1468 uint clampCount
= 0;
1470 if ((x
+groupContextHelp
->getW()) > groupContextHelp
->getParent()->getWReal())
1473 x
= groupContextHelp
->getParent()->getWReal() - groupContextHelp
->getW();
1480 if ((y
+groupContextHelp
->getH()) > groupContextHelp
->getParent()->getHReal())
1482 y
= groupContextHelp
->getParent()->getHReal() - groupContextHelp
->getH();
1491 // update coords 3 times is required
1492 groupContextHelp
->setX (x
);
1493 groupContextHelp
->setY (y
);
1494 groupContextHelp
->updateCoords ();
1495 groupContextHelp
->updateCoords ();
1496 groupContextHelp
->updateCoords ();
1501 // ----------------------------------------------------------------------------
1502 void CWidgetManager::updateTooltipCoords()
1504 updateTooltipCoords( getCurContextHelp() );
1507 void CWidgetManager::updateTooltipCoords( CCtrlBase
*newCtrl
)
1509 if (!newCtrl
) return;
1510 if (!newCtrl
->getInvalidCoords()) return;
1512 CInterfaceGroup
*groupContextHelp
=
1513 getWindowForActiveMasterGroup(newCtrl
->getContextHelpWindowName());
1515 if(groupContextHelp
)
1517 CViewText
*pTxt
= (CViewText
*)groupContextHelp
->getView("text");
1520 pTxt
->setTextFormatTaged(_ContextHelpText
);
1521 // update only to get correct W/H
1522 groupContextHelp
->updateCoords ();
1525 // **** Compute parent coordinates
1526 CCtrlBase::TToolTipParentType parentType
= newCtrl
->getToolTipParent();
1527 CInterfaceGroup
*win
= NULL
;
1528 // adjust to the mouse by default
1529 sint32 xParent
= getPointer()->getX();
1530 sint32 yParent
= getPointer()->getY();
1533 // adjust to the window
1534 if(parentType
==CCtrlBase::TTWindow
|| parentType
==CCtrlBase::TTSpecialWindow
)
1536 if(parentType
==CCtrlBase::TTWindow
)
1537 win
= newCtrl
->getRootWindow();
1540 dynamic_cast<CInterfaceGroup
*>( getElementFromId(newCtrl
->getToolTipSpecialParent()));
1544 xParent
= win
->getXReal();
1545 yParent
= win
->getYReal();
1546 wParent
= win
->getWReal();
1547 hParent
= win
->getHReal();
1549 // Bug...: leave default to pointer
1551 // adjust to the ctrl
1552 else if (parentType
==CCtrlBase::TTCtrl
)
1554 xParent
= newCtrl
->getXReal();
1555 yParent
= newCtrl
->getYReal();
1556 wParent
= newCtrl
->getWReal();
1557 hParent
= newCtrl
->getHReal();
1558 // Additionaly, must clip this ctrl with its parent
1559 // (else animals are buggy for instance)
1560 CInterfaceGroup
*parent
= newCtrl
->getParent();
1563 sint32 xClip
,yClip
,wClip
,hClip
;
1564 parent
->getClip(xClip
,yClip
,wClip
,hClip
);
1566 xParent
= std::max(xParent
, xClip
);
1567 yParent
= std::max(yParent
, yClip
);
1569 sint32 xrParent
= std::min(xParent
+ wParent
, xClip
+wClip
);
1570 sint32 ytParent
= std::min(yParent
+ hParent
, yClip
+hClip
);
1571 wParent
= std::max((sint32
)0, xrParent
-xParent
);
1572 hParent
= std::max((sint32
)0, ytParent
-yParent
);
1577 // **** resolve auto posref
1579 adjustTooltipPosition( newCtrl
, win
, newCtrl
->getToolTipParentPosRef(),
1580 newCtrl
->getToolTipPosRef(), xParent
, yParent
,
1583 if (clampCount
!= 0)
1585 // try to fallback on alternate tooltip posref
1586 uint altClampCount
=
1587 adjustTooltipPosition( newCtrl
, win
, newCtrl
->getToolTipParentPosRefAlt(),
1588 newCtrl
->getToolTipPosRefAlt(), xParent
, yParent
,
1591 if (altClampCount
> clampCount
)
1593 // worst ? resume to first posref
1594 adjustTooltipPosition( newCtrl
, win
, newCtrl
->getToolTipParentPosRef(),
1595 newCtrl
->getToolTipPosRef(), xParent
, yParent
,
1603 // ------------------------------------------------------------------------------------------------
1604 void CWidgetManager::disableContextHelp()
1606 setCurContextHelp( NULL
);
1607 _DeltaTimeStopingContextHelp
= 0;
1610 // ------------------------------------------------------------------------------------------------
1611 void CWidgetManager::disableContextHelpForControl( CCtrlBase
*pCtrl
)
1616 if( getCurContextHelp() == pCtrl
)
1617 disableContextHelp();
1620 // ----------------------------------------------------------------------------
1621 CCtrlBase
* CWidgetManager::getNewContextHelpCtrl()
1623 // get the top most ctrl under us
1624 CCtrlBase
*best
= NULL
;
1625 sint8 bestRenderLayer
= -128;
1627 for (sint i
= (sint32
)_CtrlsUnderPointer
.size()-1; i
>=0; i
--)
1629 CCtrlBase
*pICL
= _CtrlsUnderPointer
[i
];
1630 if (pICL
->getRenderLayer() > bestRenderLayer
)
1632 if ((pICL
->getActive()) && (!pICL
->emptyContextHelp()))
1634 if (!getPointer()) return pICL
;
1636 getPointer()->getPointerPos(mx
, my
);
1637 if (pICL
->preciseHitTest(mx
, my
))
1640 bestRenderLayer
= pICL
->getRenderLayer();
1647 // if a control was not found, try with the groups
1648 sint8 bestRenderLayer
= -128;
1650 for (sint i
= (sint32
)_GroupsUnderPointer
.size()-1; i
>=0; i
--)
1652 CCtrlBase
*pICL
= _GroupsUnderPointer
[i
];
1653 if (pICL
->getRenderLayer() > bestRenderLayer
)
1655 if ((pICL
->getActive()) && (!pICL
->emptyContextHelp()))
1657 if (!getPointer()) return pICL
;
1659 getPointer()->getPointerPos(mx
, my
);
1660 if (pICL
->preciseHitTest(mx
, my
))
1663 bestRenderLayer
= pICL
->getRenderLayer();
1672 // ----------------------------------------------------------------------------
1673 void CWidgetManager::drawContextHelp ()
1675 if (!getPointer() || !_ContextHelpActive
)
1679 sint32 x
= getPointer()->getX();
1680 sint32 y
= getPointer()->getY();
1684 // **** try to disable
1686 // test disable first, so can recheck asap if another present. see below
1687 CCtrlBase
*_CurCtrlContextHelp
= getCurContextHelp();
1688 if( _CurCtrlContextHelp
)
1690 if(x
!=_LastXContextHelp
|| y
!=_LastYContextHelp
)
1692 // May change of ctrl!! => disable context help
1693 CCtrlBase
*newCtrl
= getNewContextHelpCtrl();
1694 if(newCtrl
!=_CurCtrlContextHelp
)
1697 disableContextHelp();
1701 // Check if _CurCtrlContextHelp is visible
1702 if (_CurCtrlContextHelp
== NULL
)
1704 disableContextHelp();
1708 bool bVisible
= true;
1709 if (_CurCtrlContextHelp
->getActive() == false)
1711 CInterfaceGroup
*pParent
= _CurCtrlContextHelp
->getParent();
1712 while (pParent
!= NULL
)
1714 if (pParent
->getActive() == false)
1716 pParent
= pParent
->getParent();
1719 disableContextHelp();
1725 // **** try to acquire
1727 if(!_CurCtrlContextHelp
)
1729 // get the ctrl of interset
1730 CCtrlBase
*newCtrl
= getNewContextHelpCtrl();
1732 if(x
==_LastXContextHelp
&& y
==_LastYContextHelp
)
1733 _DeltaTimeStopingContextHelp
+= ( interfaceTimes
.frameDiffMs
/ 1000.0f
);
1735 _DeltaTimeStopingContextHelp
= 0;
1737 // If reach the time limit
1738 if( ( _DeltaTimeStopingContextHelp
> _MaxTimeStopingContextHelp
)
1739 || (newCtrl
&& newCtrl
->wantInstantContextHelp()))
1741 // if present, get the ctx help text.
1745 //newCtrl->getContextHelpToolTip(_ContextHelpText);
1746 newCtrl
->getContextHelp( getContextHelpText() );
1747 // UserDefined context help
1748 if( !newCtrl
->getContextHelpActionHandler().empty() )
1750 CAHManager::getInstance()->runActionHandler(newCtrl
->getContextHelpActionHandler(), newCtrl
, newCtrl
->getContextHelpAHParams() );
1753 // If the text is finally empty (Special AH case), abort
1754 if( getContextHelpText().empty() )
1758 // not present? wait furthermore to move the mouse.
1760 _DeltaTimeStopingContextHelp
= 0;
1764 setCurContextHelp( newCtrl
);
1765 newCtrl
->invalidateCoords();
1770 updateTooltipCoords(_CurCtrlContextHelp
);
1776 if(_CurCtrlContextHelp
)
1778 CInterfaceGroup
*groupContextHelp
=
1779 getWindowForActiveMasterGroup(_CurCtrlContextHelp
->getContextHelpWindowName());
1781 if(groupContextHelp
)
1783 /** If there's a modal box around, should be sure that the context help doesn't intersect it.
1784 * If this is the case, we just disable it, unless the tooltip was generated by the current modal window
1788 CInterfaceGroup
*mw
= getModal().ModalWindow
;
1789 if (mw
&& mw
->isIn(*groupContextHelp
))
1791 if (_CurCtrlContextHelp
->isSonOf(mw
))
1793 groupContextHelp
->executeLuaScriptOnDraw();
1794 groupContextHelp
->draw ();
1796 CViewRenderer::getInstance()->flush();
1801 groupContextHelp
->executeLuaScriptOnDraw();
1802 groupContextHelp
->draw ();
1804 CViewRenderer::getInstance()->flush();
1809 groupContextHelp
->executeLuaScriptOnDraw();
1810 groupContextHelp
->draw ();
1812 CViewRenderer::getInstance()->flush();
1818 _LastXContextHelp
= x
;
1819 _LastYContextHelp
= y
;
1822 void CWidgetManager::setContextHelpActive(bool active
)
1826 disableContextHelp();
1828 _ContextHelpActive
= active
;
1832 // ------------------------------------------------------------------------------------------------
1833 void CWidgetManager::getNewWindowCoordToNewScreenSize( sint32
&x
, sint32
&y
, sint32 w
, sint32 h
,
1834 sint32 newScreenW
, sint32 newScreenH
) const
1836 // NB: x is relative to Left of the window (and Left of screen)
1837 // NB: y is relative to Top of the window (but Bottom of screen)
1840 The goal here is to move the window so it fit the new resolution
1841 But we don't want to change its size (because somes windows just can't)
1842 We also cannot use specific code according to each window because user may completly modify his interface
1843 So the strategy is to dectect on which "side" (or center) the window is the best sticked,
1844 and then just move the window according to this position
1847 // *** First detect from which screen position the window is the more sticked (borders or center)
1848 // In X: best hotspot is left, middle or right?
1849 sint32 posXToLeft
= x
;
1850 sint32 posXToMiddle
= x
+w
/2-_ScreenW
/2;
1851 sint32 posXToRight
= _ScreenW
-(x
+w
);
1852 sint32 bestXHotSpot
= Hotspot_xL
;
1853 sint32 bestXPosVal
= posXToLeft
;
1854 if(abs(posXToMiddle
) < bestXPosVal
)
1856 bestXHotSpot
= Hotspot_xM
;
1857 bestXPosVal
= abs(posXToMiddle
);
1859 if(posXToRight
< bestXPosVal
)
1861 bestXHotSpot
= Hotspot_xR
;
1862 bestXPosVal
= posXToRight
;
1865 // Same In Y: best hotspot is bottom, middle or top?
1866 // remember here that y is the top of window (relative to bottom of screen)
1867 sint32 posYToBottom
= y
-h
;
1868 sint32 posYToMiddle
= y
-h
/2-_ScreenH
/2;
1869 sint32 posYToTop
= _ScreenH
-y
;
1870 sint32 bestYHotSpot
= Hotspot_Bx
;
1871 sint32 bestYPosVal
= posYToBottom
;
1872 const sint32 middleYWeight
= 6; // Avoid default Mission/Team/Map/ContactList positions to be considered as "middle"
1873 if(abs(posYToMiddle
)*middleYWeight
< bestYPosVal
)
1875 bestYHotSpot
= Hotspot_Mx
;
1876 bestYPosVal
= abs(posYToMiddle
)*middleYWeight
;
1878 if(posYToTop
< bestYPosVal
)
1880 bestYHotSpot
= Hotspot_Tx
;
1881 bestYPosVal
= posYToTop
;
1884 // *** According to best matching hotspot, and new screen resolution, move the window
1886 if(bestXHotSpot
==Hotspot_xM
)
1887 x
= newScreenW
/2 + posXToMiddle
- w
/2;
1888 else if(bestXHotSpot
==Hotspot_xR
)
1889 x
= newScreenW
- posXToRight
- w
;
1891 if(bestYHotSpot
==Hotspot_Mx
)
1892 y
= newScreenH
/2 + posYToMiddle
+ h
/2;
1893 else if(bestYHotSpot
==Hotspot_Tx
)
1894 y
= newScreenH
- posYToTop
;
1897 // ------------------------------------------------------------------------------------------------
1898 void CWidgetManager::moveAllWindowsToNewScreenSize(uint32 newScreenW
, uint32 newScreenH
, bool fixCurrentUI
)
1900 std::vector
< CWidgetManager::SMasterGroup
> &_MasterGroups
= getAllMasterGroup();
1901 // If resolutions correctly setuped, and really different from new setup
1902 if( _ScreenW
>0 && _ScreenH
>0 &&
1903 newScreenW
>0 && newScreenH
>0 &&
1904 ( _ScreenW
!= newScreenW
|| _ScreenH
!= newScreenH
)
1907 // *** Do it for the Active Desktop (if wanted)
1910 // only for ui:interface (not login, nor outgame)
1911 for (uint nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
1913 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
1914 if (!rMG
.Group
|| rMG
.Group
->getId() != "ui:interface")
1917 // For all priorities, but the worldspace one
1918 for (uint8 nPriority
= 0; nPriority
< WIN_PRIORITY_MAX
; nPriority
++)
1920 if (nPriority
==WIN_PRIORITY_WORLD_SPACE
)
1923 // For All windows (only layer 0 group container)
1924 std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
];
1925 std::list
<CInterfaceGroup
*>::const_iterator itw
;
1926 for (itw
= rList
.begin(); itw
!= rList
.end(); itw
++)
1928 CInterfaceGroup
*pIG
= *itw
;
1929 if(!pIG
->isGroupContainer())
1931 CGroupContainer
*gc
= dynamic_cast<CGroupContainer
*>(pIG
);
1932 if(gc
->getLayerSetup()!=0)
1934 // should all be BL / TL
1935 if(gc
->getParentPosRef()!=Hotspot_BL
|| gc
->getPosRef()!=Hotspot_TL
)
1938 // Get current window coordinates
1939 sint32 x
= pIG
->getX(); // x is relative to Left of the window
1940 sint32 y
= pIG
->getY(); // y is relative to Top of the window
1941 sint32 w
= pIG
->getW(false); // the window may be hid, still get the correct(or estimated) W
1942 sint32 h
= pIG
->getH(false); // the window may be hid, still get the correct(or estimated) H
1944 // Compute the new coordinate
1945 getNewWindowCoordToNewScreenSize(x
, y
, w
, h
, newScreenW
, newScreenH
);
1955 std::vector
< INewScreenSizeHandler
* >::iterator itr
;
1956 for( itr
= newScreenSizeHandlers
.begin(); itr
!= newScreenSizeHandlers
.end(); ++itr
)
1958 INewScreenSizeHandler
*handler
= *itr
;
1959 handler
->process( newScreenW
, newScreenH
);
1963 // Now those are the last screen coordinates used for window position correction
1964 if(newScreenW
>0 && newScreenH
>0)
1966 _ScreenW
= newScreenW
;
1967 _ScreenH
= newScreenH
;
1971 class InvalidateTextVisitor
: public CInterfaceElementVisitor
1974 InvalidateTextVisitor( bool reset
)
1976 this->reset
= reset
;
1979 void visitGroup( CInterfaceGroup
*group
)
1981 const std::vector
< CViewBase
* > &vs
= group
->getViews();
1982 for( std::vector
< CViewBase
* >::const_iterator itr
= vs
.begin(); itr
!= vs
.end(); ++itr
)
1984 CViewText
*vt
= dynamic_cast< CViewText
* >( *itr
);
1988 vt
->resetTextIndex();
1989 vt
->updateTextContext();
1998 // ------------------------------------------------------------------------------------------------
1999 void CWidgetManager::updateAllLocalisedElements()
2002 uint32 nMasterGroup
;
2005 CViewRenderer::getInstance()->checkNewScreenSize ();
2006 CViewRenderer::getInstance()->getScreenSize (w
, h
);
2008 // Update ui:* (limit the master containers to the height of the screen)
2009 for (nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
2011 SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
2012 rMG
.Group
->setW (w
);
2013 rMG
.Group
->setH (h
);
2015 CViewRenderer::getInstance()->setClipWindow(0, 0, w
, h
);
2017 bool scaleChanged
= _InterfaceScale
!= CViewRenderer::getInstance()->getInterfaceScale();
2020 _InterfaceScale
= CViewRenderer::getInstance()->getInterfaceScale();
2021 notifyInterfaceScaleWatchers();
2024 // If all conditions are OK, move windows so they fit correctly with new screen size
2025 // Do this work only InGame when Config is loaded
2026 moveAllWindowsToNewScreenSize(w
,h
,true);
2028 // Invalidate coordinates of all Windows of each MasterGroup
2029 for (nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
2031 SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
2033 InvalidateTextVisitor
inv( false);
2035 rMG
.Group
->visitGroupAndChildren( &inv
);
2036 rMG
.Group
->invalidateCoords ();
2037 for (uint8 nPriority
= 0; nPriority
< WIN_PRIORITY_MAX
; nPriority
++)
2039 std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
];
2040 std::list
<CInterfaceGroup
*>::const_iterator itw
;
2041 for (itw
= rList
.begin(); itw
!= rList
.end(); itw
++)
2043 CInterfaceGroup
*pIG
= *itw
;
2044 pIG
->visitGroupAndChildren( &inv
);
2045 pIG
->invalidateCoords ();
2051 for (nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
2053 SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
2054 bool bActive
= rMG
.Group
->getActive ();
2055 rMG
.Group
->setActive (true);
2056 rMG
.Group
->updateCoords ();
2057 rMG
.Group
->setActive (bActive
);
2060 // update coords one
2063 // Action by default (container opening
2064 for (nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
2066 SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
2067 rMG
.Group
->launch ();
2072 void CWidgetManager::drawViews( NL3D::UCamera camera
)
2074 CViewRenderer::getInstance()->activateWorldSpaceMatrix (false);
2075 NL3D::UDriver
*driver
= CViewRenderer::getInstance()->getDriver();
2077 // If an element has captured the keyboard, make sure it is alway visible (all parent windows active)
2078 if( getCaptureKeyboard() != NULL
)
2080 CCtrlBase
*cb
= getCaptureKeyboard();
2083 if (!cb
->getActive())
2085 setCaptureKeyboard(NULL
);
2088 cb
= cb
->getParent();
2093 // Check if screen size changed
2095 CViewRenderer::getInstance()->checkNewScreenSize ();
2096 CViewRenderer::getInstance()->getScreenSize (w
, h
);
2097 if ((w
!= _ScreenW
) || (h
!= _ScreenH
))
2099 // No Op if screen minimized
2100 if(w
!=0 && h
!=0 && !CViewRenderer::getInstance()->isMinimized())
2102 updateAllLocalisedElements ();
2107 // Update global color from database
2110 _RProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:R");
2111 _GProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:G");
2112 _BProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:B");
2113 _AProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:A");
2116 setGlobalColor(NLMISC::CRGBA(
2117 (uint8
)_RProp
->getValue32(),
2118 (uint8
)_GProp
->getValue32(),
2119 (uint8
)_BProp
->getValue32(),
2120 (uint8
)_AProp
->getValue32()));
2122 NLMISC::CRGBA c
= getGlobalColorForContent();
2123 NLMISC::CRGBA gc
= getGlobalColor();
2127 c
.A
= (uint8
) (( (uint16
) c
.A
* (uint16
) getContentAlpha() ) >> 8);
2128 setGlobalColorForContent( c
);
2130 // Update global alphaS from database
2131 updateGlobalAlphas();
2133 /* Draw all the windows
2134 To minimize texture swapping, we first sort per Window, then we sort per layer, then we render per Global Texture.
2135 Computed String are rendered in on big drawQuads at last part of each layer
2137 CDBManager::getInstance()->flushObserverCalls();
2139 for (uint32 nMasterGroup
= 0; nMasterGroup
< _MasterGroups
.size(); nMasterGroup
++)
2141 CWidgetManager::SMasterGroup
&rMG
= _MasterGroups
[nMasterGroup
];
2142 if (rMG
.Group
->getActive())
2144 // Sort world space windows
2145 rMG
.sortWorldSpaceGroup ();
2147 for (uint8 nPriority
= 0; nPriority
< WIN_PRIORITY_MAX
; ++nPriority
)
2149 if ( (nPriority
== WIN_PRIORITY_WORLD_SPACE
) && !camera
.empty())
2151 driver
->setViewMatrix( NL3D::CMatrix::Identity
);
2152 driver
->setModelMatrix( NL3D::CMatrix::Identity
);
2153 driver
->setFrustum(camera
.getFrustum());
2154 CViewRenderer::getInstance()->activateWorldSpaceMatrix (true);
2157 std::list
<CInterfaceGroup
*> &rList
= rMG
.PrioritizedWindows
[nPriority
];
2158 std::list
<CInterfaceGroup
*>::const_iterator itw
;
2160 for (itw
= rList
.begin(); itw
!= rList
.end(); itw
++)
2162 CInterfaceGroup
*pIG
= *itw
;
2163 if( pIG
) // TODO: debug null pointer in PrioritizedWindows list
2165 if (pIG
->getActive())
2167 // Draw all the elements of this window in the layers in ViewRendered
2170 CViewRenderer::getInstance()->flush ();
2175 if( draggedElement
!= NULL
)
2177 CInterfaceElement
*e
= draggedElement
;
2178 static_cast< CViewBase
* >( e
)->draw();
2181 if ( (nPriority
== WIN_PRIORITY_WORLD_SPACE
) && !camera
.empty())
2183 driver
->setMatrixMode2D11();
2184 CViewRenderer::getInstance()->activateWorldSpaceMatrix (false);
2190 CDBManager::getInstance()->flushObserverCalls();
2192 // draw the special over extend text
2193 drawOverExtendViewText();
2195 // draw the context help
2198 std::vector
< IOnWidgetsDrawnHandler
* >::iterator itr
;
2199 for( itr
= onWidgetsDrawnHandlers
.begin(); itr
!= onWidgetsDrawnHandlers
.end(); ++itr
)
2201 IOnWidgetsDrawnHandler
*handler
= *itr
;
2205 // Draw the pointer and DND Item
2206 if (getPointer() != NULL
)
2208 if (getPointer()->getActive())
2209 getPointer()->draw ();
2212 if (CInterfaceElement::getEditorMode())
2214 for(uint i
= 0; i
< editorSelection
.size(); ++i
)
2216 CInterfaceElement
*e
= getElementFromId(editorSelection
[i
]);
2223 CViewRenderer::getInstance()->flush();
2225 // todo hulud remove Return in 2d world
2226 driver
->setMatrixMode2D11();
2228 CDBManager::getInstance()->flushObserverCalls();
2231 bool CWidgetManager::handleEvent( const CEventDescriptor
&evnt
)
2233 // Check if we can receive events (no anims!)
2234 for( uint32 i
= 0; i
< activeAnims
.size(); ++i
)
2235 if( activeAnims
[i
]->isDisableButtons() )
2238 bool handled
= false;
2240 if( evnt
.getType() == CEventDescriptor::system
)
2242 handleSystemEvent( evnt
);
2245 if (evnt
.getType() == CEventDescriptor::key
)
2247 handled
= handleKeyboardEvent( evnt
);
2249 else if (evnt
.getType() == CEventDescriptor::mouse
)
2251 handled
= handleMouseEvent( evnt
);
2254 CDBManager::getInstance()->flushObserverCalls();
2259 bool CWidgetManager::handleSystemEvent( const CEventDescriptor
&evnt
)
2261 const CEventDescriptorSystem
&systemEvent
= reinterpret_cast< const CEventDescriptorSystem
& >( evnt
);
2262 if( systemEvent
.getEventTypeExtended() == CEventDescriptorSystem::setfocus
)
2264 if( getCapturePointerLeft() != NULL
)
2266 getCapturePointerLeft()->handleEvent( evnt
);
2267 setCapturePointerLeft( NULL
);
2270 if( getCapturePointerRight() != NULL
)
2272 getCapturePointerRight()->handleEvent( evnt
);
2273 setCapturePointerRight( NULL
);
2276 if( _CapturedView
!= NULL
)
2278 _CapturedView
->handleEvent( evnt
);
2279 _CapturedView
= NULL
;
2286 bool CWidgetManager::handleKeyboardEvent( const CEventDescriptor
&evnt
)
2288 bool handled
= false;
2290 CEventDescriptorKey
&eventDesc
= (CEventDescriptorKey
&)evnt
;
2292 //_LastEventKeyDesc = eventDesc;
2294 // Any Key event disable the ContextHelp
2295 disableContextHelp();
2297 // Hide menu if the key is pushed
2298 // if ((eventDesc.getKeyEventType() == CEventDescriptorKey::keydown) && !_ModalStack.empty() && !eventDesc.getKeyAlt() && !eventDesc.getKeyCtrl() && !eventDesc.getKeyShift())
2299 // Hide menu (or popup menu) is ESCAPE pressed
2300 if( eventDesc
.getKeyEventType() == CEventDescriptorKey::keydown
&& eventDesc
.getKey() == NLMISC::KeyESCAPE
)
2304 SModalWndInfo mwi
= getModal();
2305 if (mwi
.ModalExitKeyPushed
)
2306 disableModalWindow();
2310 // Manage "quit window" If the Key is ESCAPE, no captureKeyboard
2311 if( eventDesc
.getKeyEventType() == CEventDescriptorKey::keydown
&& eventDesc
.getKey() == NLMISC::KeyESCAPE
)
2313 // Get the last escapable active top window. NB: this is ergonomically better.
2314 CInterfaceGroup
*win
= getLastEscapableTopWindow();
2317 // If the window is a modal, must pop it.
2318 if( dynamic_cast<CGroupModal
*>(win
) )
2320 if(!win
->getAHOnEscape().empty())
2321 CAHManager::getInstance()->runActionHandler(win
->getAHOnEscape(), win
, win
->getAHOnEscapeParams());
2325 // else just disable it.
2326 // Special case: leave the escape Key to the CaptureKeyboard .
2327 else if( !getCaptureKeyboard() )
2329 if(!win
->getAHOnEscape().empty())
2330 CAHManager::getInstance()->runActionHandler(win
->getAHOnEscape(), win
, win
->getAHOnEscapeParams());
2331 win
->setActive(false);
2337 // Manage complex "Enter"
2338 if( eventDesc
.getKeyEventType() == CEventDescriptorKey::keychar
&& eventDesc
.getChar() == NLMISC::KeyRETURN
&& !eventDesc
.getKeyCtrl() )
2340 // If the top window has Enter AH
2341 CInterfaceGroup
*tw
= getTopWindow();
2342 if(tw
&& !tw
->getAHOnEnter().empty())
2344 // if the captured keyboard is in this Modal window, then must handle him in priority
2345 if( getCaptureKeyboard() && getCaptureKeyboard()->getRootWindow()==tw
)
2347 bool result
= getCaptureKeyboard()->handleEvent(evnt
);
2348 CDBManager::getInstance()->flushObserverCalls();
2353 // The window or modal control the OnEnter. Execute, and don't go to the chat.
2354 CAHManager::getInstance()->runActionHandler(tw
->getAHOnEnter(), tw
, tw
->getAHOnEnterParams());
2359 // else the 'return' key bring back to the last edit box (if possible)
2360 CCtrlBase
*oldCapture
= getOldCaptureKeyboard() ? getOldCaptureKeyboard() : getDefaultCaptureKeyboard();
2361 if ( getCaptureKeyboard() == NULL
&& oldCapture
&& !handled
)
2363 /* If the editbox does not want to recover focus, then abort. This possibility is normaly avoided
2364 through setCaptureKeyboard() which already test getRecoverFocusOnEnter(), but it is still possible
2365 for the default capture (main chat) or the old captured window to not want to recover
2366 (temporary Read Only chat for instance)
2368 if(!dynamic_cast<CGroupEditBoxBase
*>(oldCapture
) ||
2369 dynamic_cast<CGroupEditBoxBase
*>(oldCapture
)->getRecoverFocusOnEnter())
2371 setCaptureKeyboard( oldCapture
);
2372 notifyElementCaptured(getCaptureKeyboard() );
2373 // make sure all parent windows are active
2374 CCtrlBase
*cb
= getCaptureKeyboard();
2375 CGroupContainer
*lastContainer
= NULL
;
2379 CGroupContainer
*gc
= dynamic_cast<CGroupContainer
*>(cb
);
2380 if (gc
) lastContainer
= gc
;
2382 if (cb
->getParent())
2384 cb
= cb
->getParent();
2388 cb
->invalidateCoords();
2394 setTopWindow(lastContainer
);
2395 lastContainer
->enableBlink(1);
2402 // General case: handle it in the Captured keyboard
2403 if ( getCaptureKeyboard() != NULL
&& !handled
)
2405 bool result
= getCaptureKeyboard()->handleEvent(evnt
);
2406 CDBManager::getInstance()->flushObserverCalls();
2410 lastKeyEvent
= eventDesc
;
2415 bool CWidgetManager::handleMouseEvent( const CEventDescriptor
&evnt
)
2417 bool handled
= false;
2419 CEventDescriptorMouse
&eventDesc
= (CEventDescriptorMouse
&)evnt
;
2421 if( eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown
)
2422 _Pointer
->setButtonState( static_cast< NLMISC::TMouseButton
>( _Pointer
->getButtonState() | NLMISC::leftButton
) );
2424 if( eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown
)
2425 _Pointer
->setButtonState( static_cast< NLMISC::TMouseButton
>( _Pointer
->getButtonState() | NLMISC::rightButton
) );
2427 if( eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup
)
2428 _Pointer
->setButtonState( static_cast< NLMISC::TMouseButton
>( _Pointer
->getButtonState() & ~NLMISC::leftButton
) );
2429 if( eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightup
)
2430 _Pointer
->setButtonState( static_cast< NLMISC::TMouseButton
>( _Pointer
->getButtonState() & ~NLMISC::rightButton
) );
2432 if( eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mousemove
)
2433 handleMouseMoveEvent( eventDesc
);
2435 eventDesc
.setX( _Pointer
->getX() );
2436 eventDesc
.setY( _Pointer
->getY() );
2438 if( CInterfaceElement::getEditorMode() )
2440 // Let's pretend we've handled the event... or actually we have!
2441 if( ( eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown
) ||
2442 ( eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightup
) )
2446 if( isMouseHandlingEnabled() )
2448 // First thing to do : Capture handling
2449 if ( getCapturePointerLeft() != NULL
)
2450 handled
|= getCapturePointerLeft()->handleEvent(evnt
);
2452 if ( getCapturePointerRight() != NULL
&&
2453 getCapturePointerLeft() != getCapturePointerRight() )
2454 handled
|= getCapturePointerRight()->handleEvent(evnt
);
2456 if( _CapturedView
!= NULL
&&
2457 _CapturedView
!= getCapturePointerLeft() &&
2458 _CapturedView
!= getCapturePointerRight() )
2459 _CapturedView
->handleEvent( evnt
);
2461 CInterfaceGroup
*ptr
= getWindowUnder (eventDesc
.getX(), eventDesc
.getY());
2462 setCurrentWindowUnder( ptr
);
2464 // Any Mouse event but move disable the ContextHelp
2465 if(eventDesc
.getEventTypeExtended() != CEventDescriptorMouse::mousemove
)
2467 disableContextHelp();
2470 // get the group under the mouse
2471 CInterfaceGroup
*pNewCurrentWnd
= getCurrentWindowUnder();
2472 setMouseOverWindow( pNewCurrentWnd
!= NULL
);
2475 NLMISC::CRefPtr
<CGroupModal
> clickedOutModalWindow
;
2477 // modal special features
2480 CWidgetManager::SModalWndInfo mwi
= getModal();
2483 // If we are not in "click out" mode so we dont handle controls other than those of the modal
2484 if (pNewCurrentWnd
!= mwi
.ModalWindow
&& !mwi
.ModalExitClickOut
)
2486 pNewCurrentWnd
= NULL
;
2490 // If there is a handler on click out launch it
2491 if (pNewCurrentWnd
!= mwi
.ModalWindow
)
2492 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown
||
2493 (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown
))
2494 if (!mwi
.ModalHandlerClickOut
.empty())
2495 CAHManager::getInstance()->runActionHandler(mwi
.ModalHandlerClickOut
,NULL
,mwi
.ModalClickOutParams
);
2497 // If the current window is not the modal and if must quit on click out
2498 if(pNewCurrentWnd
!= mwi
.ModalWindow
&& mwi
.ModalExitClickOut
)
2500 // NB: don't force handle==true because to quit a modal does not avoid other actions
2502 // quit if click outside
2503 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown
||
2504 (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown
))
2506 clickedOutModalWindow
= dynamic_cast<CGroupModal
*>((CInterfaceGroup
*)mwi
.ModalWindow
);
2507 // disable the modal
2511 // don't handle event unless it is a previous modal window
2512 if( !isPreviousModal( pNewCurrentWnd
) )
2513 pNewCurrentWnd
= NULL
; // can't handle event before we have left all modal windows
2515 movePointer (0,0); // Reget controls under pointer
2522 // Manage LeftClick.
2523 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown
)
2525 if ((pNewCurrentWnd
!= NULL
) && (!hasModal()) && (pNewCurrentWnd
->getOverlappable()))
2527 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(pNewCurrentWnd
);
2530 if (!pGC
->isGrayed()) setTopWindow(pNewCurrentWnd
);
2534 setTopWindow(pNewCurrentWnd
);
2538 bool captured
= false;
2540 // must not capture a new element if a sheet is currentlty being dragged.
2541 // This may happen when alt-tab has been used => the sheet is dragged but the left button is up
2542 if (!CCtrlDraggable::getDraggedSheet())
2544 if( CInterfaceElement::getEditorMode() && _GroupSelection
)
2546 for( sint32 i
= _GroupsUnderPointer
.size() - 1; i
>= 0; i
-- )
2548 CInterfaceGroup
*g
= _GroupsUnderPointer
[ i
];
2549 if( ( g
!= NULL
) && ( g
->isInGroup( pNewCurrentWnd
) ) )
2560 // Take the top most control.
2562 const std::vector
< CCtrlBase
* >& _CtrlsUnderPointer
= getCtrlsUnderPointer();
2563 for (sint32 i
= (sint32
)_CtrlsUnderPointer
.size()-1; i
>= 0; i
--)
2565 CCtrlBase
*ctrl
= _CtrlsUnderPointer
[i
];
2566 if (ctrl
&& ctrl
->isCapturable() && ctrl
->isInGroup( pNewCurrentWnd
) )
2568 if( CInterfaceElement::getEditorMode() && !ctrl
->isEditorSelectable() )
2571 uint d
= ctrl
->getDepth( pNewCurrentWnd
);
2575 setCapturePointerLeft( ctrl
);
2582 if( CInterfaceElement::getEditorMode() && !captured
)
2584 for( sint32 i
= _ViewsUnderPointer
.size()-1; i
>= 0; i
-- )
2586 CViewBase
*v
= _ViewsUnderPointer
[i
];
2587 if( ( v
!= NULL
) && v
->isInGroup( pNewCurrentWnd
) )
2589 if( CInterfaceElement::getEditorMode() && !v
->isEditorSelectable() )
2599 notifyElementCaptured( getCapturePointerLeft() );
2600 if (clickedOutModalWindow
&& !clickedOutModalWindow
->OnPostClickOut
.empty())
2602 CAHManager::getInstance()->runActionHandler(clickedOutModalWindow
->OnPostClickOut
, getCapturePointerLeft(), clickedOutModalWindow
->OnPostClickOutParams
);
2608 // consider clicking on a control implies handling of the event.
2611 if( getCapturePointerLeft() != NULL
)
2612 _CapturedView
= getCapturePointerLeft();
2614 // handle the capture
2615 _CapturedView
->handleEvent( evnt
);
2619 if( CInterfaceElement::getEditorMode() )
2620 clearEditorSelection();
2624 // Manage RightClick
2625 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown
)
2627 if ((pNewCurrentWnd
!= NULL
) && (!hasModal()) && (pNewCurrentWnd
->getOverlappable()))
2629 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(pNewCurrentWnd
);
2632 if (!pGC
->isGrayed()) setTopWindow(pNewCurrentWnd
);
2636 setTopWindow(pNewCurrentWnd
);
2640 // Take the top most control.
2643 const std::vector
< CCtrlBase
* >& _CtrlsUnderPointer
= getCtrlsUnderPointer();
2644 for (sint32 i
= (sint32
)_CtrlsUnderPointer
.size()-1; i
>= 0; i
--)
2646 CCtrlBase
*ctrl
= _CtrlsUnderPointer
[i
];
2647 if (ctrl
&& ctrl
->isCapturable() && ctrl
->isInGroup( pNewCurrentWnd
) )
2649 uint d
= ctrl
->getDepth( pNewCurrentWnd
);
2653 setCapturePointerRight( ctrl
);
2657 notifyElementCaptured( getCapturePointerRight() );
2658 if (clickedOutModalWindow
&& !clickedOutModalWindow
->OnPostClickOut
.empty())
2660 CAHManager::getInstance()->runActionHandler(clickedOutModalWindow
->OnPostClickOut
, getCapturePointerRight(), clickedOutModalWindow
->OnPostClickOutParams
);
2664 if ( getCapturePointerRight() != NULL
)
2666 // handle the capture
2667 handled
|= getCapturePointerRight()->handleEvent(evnt
);
2672 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightup
)
2675 if (pNewCurrentWnd
!= NULL
)
2676 pNewCurrentWnd
->handleEvent(evnt
);
2677 if ( getCapturePointerRight() != NULL
)
2679 setCapturePointerRight(NULL
);
2684 // window handling. if not handled by a control
2687 if (((pNewCurrentWnd
!= NULL
) && !hasModal()) ||
2688 ((hasModal() && getModal().ModalWindow
== pNewCurrentWnd
)))
2690 CEventDescriptorMouse ev2
= eventDesc
;
2691 sint32 x
= eventDesc
.getX(), y
= eventDesc
.getY();
2694 pNewCurrentWnd
->absoluteToRelative (x
, y
);
2695 ev2
.setX (x
); ev2
.setY (y
);
2696 handled
|= pNewCurrentWnd
->handleEvent (ev2
);
2699 // After handle event of a left click, may set window Top if movable (infos etc...)
2700 //if( (eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouseleftdown) && pNewCurrentWnd->isMovable() )
2701 // setTopWindow(pNewCurrentWnd);
2705 // Put here to let a chance to the window to handle if the capture dont
2706 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup
)
2708 if ( getCapturePointerLeft() != NULL
)
2712 CCtrlBase
*c
= getCapturePointerLeft();
2713 c
->handleEvent( evnt
);
2716 setCapturePointerLeft(NULL
);
2720 _CapturedView
= NULL
;
2722 if( CInterfaceElement::getEditorMode() )
2727 // If the current window is the modal, may Modal quit. Do it after standard event handle
2728 if(hasModal() && pNewCurrentWnd
== getModal().ModalWindow
)
2730 // NB: don't force handle==true because to quit a modal does not avoid other actions
2731 CWidgetManager::SModalWndInfo mwi
= getModal();
2732 // and if must quit on click right
2733 if(mwi
.ModalExitClickR
)
2735 // quit if click right
2736 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouserightup
)
2737 // disable the modal
2738 disableModalWindow();
2741 // and if must quit on click left
2742 if(mwi
.ModalExitClickL
)
2744 // quit if click right
2745 if (eventDesc
.getEventTypeExtended() == CEventDescriptorMouse::mouseleftup
)
2746 // disable the modal
2747 disableModalWindow();
2751 // If the mouse is over a window, always consider the event is taken (avoid click behind)
2752 handled
|= isMouseOverWindow();
2754 // If mouse click was not on interface and we have keyboard captured, then release keyboard
2755 if (!handled
&& getCaptureKeyboard() != NULL
&& eventDesc
.getEventTypeExtended() != CEventDescriptorMouse::mousemove
)
2756 CWidgetManager::getInstance()->setCaptureKeyboard(NULL
);
2762 bool CWidgetManager::handleMouseMoveEvent( const CEventDescriptor
&eventDesc
)
2764 if( getPointer() == NULL
)
2767 if( eventDesc
.getType() != CEventDescriptor::mouse
)
2770 const CEventDescriptorMouse
&e
= static_cast< const CEventDescriptorMouse
& >( eventDesc
);
2772 if( e
.getEventTypeExtended() != CEventDescriptorMouse::mousemove
)
2775 uint32 screenW
, screenH
;
2776 CViewRenderer::getInstance()->getScreenSize( screenW
, screenH
);
2777 sint32 oldX
= getPointer()->getX();
2778 sint32 oldY
= getPointer()->getY();
2780 sint32 x
= e
.getX();
2781 sint32 y
= e
.getY();
2783 // These are floats packed in the sint32 from the NEL events that provide them as float
2784 // see comment in CInputHandler::handleMouseMoveEvent
2785 sint32 newX
= static_cast< sint32
>( std::floor( *reinterpret_cast< float* >( &x
) * screenW
+ 0.5f
) );
2786 sint32 newY
= static_cast< sint32
>( std::floor( *reinterpret_cast< float* >( &y
) * screenH
+ 0.5f
) );
2788 if( ( oldX
!= newX
) || ( oldY
!= newY
) )
2790 movePointerAbs( newX
, newY
);
2791 CEventDescriptorMouse
&ve
= const_cast< CEventDescriptorMouse
& >( e
);
2792 ve
.setX( getPointer()->getX() );
2793 ve
.setY( getPointer()->getY() );
2796 if( CInterfaceElement::getEditorMode() )
2798 if( ( _CapturedView
!= NULL
) && ( draggedElement
== NULL
) )
2803 if( draggedElement
!= NULL
)
2805 sint32 dx
= newX
- oldX
;
2806 sint32 dy
= newY
- oldY
;
2808 draggedElement
->moveBy( dx
, dy
);
2815 // ------------------------------------------------------------------------------------------------
2816 bool CWidgetManager::startDragging()
2818 CInterfaceElement
*e
= NULL
;
2820 CInterfaceGroup
*g
= _CapturedView
->getParent();
2823 e
= g
->takeElement( _CapturedView
);
2826 nlinfo( "Something went horribly wrong :(" );
2833 e
->setParent( NULL
);
2839 void CWidgetManager::stopDragging()
2841 if( draggedElement
!= NULL
)
2843 CInterfaceGroup
*g
= getGroupUnder( draggedElement
->getXReal(), draggedElement
->getYReal() );
2844 CInterfaceElement
*e
= draggedElement
;
2845 CInterfaceGroup
*tw
= getTopWindow();
2850 std::string oldid
= e
->getId();
2853 e
->setIdRecurse( e
->getShortId() );
2854 e
->setParentPos( g
);
2855 e
->setParentSize( g
);
2859 //e->setName( "==MARKED==" );
2861 draggedElement
= NULL
;
2863 onWidgetMoved( oldid
, e
->getId() );
2867 // ------------------------------------------------------------------------------------------------
2868 void CWidgetManager::movePointer (sint32 dx
, sint32 dy
)
2873 uint32 nScrW
, nScrH
;
2874 sint32 oldpx
, oldpy
, newpx
, newpy
, disppx
, disppy
, olddisppx
, olddisppy
;
2876 CViewRenderer::getInstance()->getScreenSize (nScrW
, nScrH
);
2877 _Pointer
->getPointerPos (oldpx
, oldpy
);
2885 if (newpx
< 0) newpx
= 0;
2886 if (newpy
< 0) newpy
= 0;
2887 if (newpx
> (sint32
)nScrW
) newpx
= nScrW
;
2888 if (newpy
> (sint32
)nScrH
) newpy
= nScrH
;
2895 _Pointer
->setPointerPos (newpx
, newpy
);
2896 _Pointer
->setPointerDispPos (disppx
, disppy
);
2898 // must get back coordinates because of snapping
2899 sint32 mx
= _Pointer
->getX();
2900 sint32 my
= _Pointer
->getY();
2901 getViewsUnder (mx
, my
, _ViewsUnderPointer
);
2902 getCtrlsUnder (mx
, my
, _CtrlsUnderPointer
);
2903 getGroupsUnder (mx
, my
, _GroupsUnderPointer
);
2906 // ------------------------------------------------------------------------------------------------
2907 void CWidgetManager::movePointerAbs(sint32 px
, sint32 py
)
2912 uint32 nScrW
, nScrH
;
2913 CViewRenderer::getInstance()->getScreenSize (nScrW
, nScrH
);
2914 NLMISC::clamp(px
, 0, (sint32
) nScrW
);
2915 NLMISC::clamp(py
, 0, (sint32
) nScrH
);
2917 _Pointer
->setPointerPos (px
, py
);
2918 _Pointer
->setPointerDispPos (px
, py
);
2920 getViewsUnder (px
, py
, _ViewsUnderPointer
);
2921 getCtrlsUnder (px
, py
, _CtrlsUnderPointer
);
2922 getGroupsUnder (px
, py
, _GroupsUnderPointer
);
2925 // ***************************************************************************
2926 void CWidgetManager::setCapturePointerLeft(CCtrlBase
*c
)
2928 _CapturedView
= NULL
;
2930 // additionally, abort any dragging
2931 if( CCtrlDraggable::getDraggedSheet() != NULL
)
2932 CCtrlDraggable::getDraggedSheet()->abortDragging();
2934 _CapturePointerLeft
= c
;
2935 notifyElementCaptured(c
);
2938 // ***************************************************************************
2939 void CWidgetManager::setCapturePointerRight(CCtrlBase
*c
)
2941 _CapturePointerRight
= c
;
2942 notifyElementCaptured(c
);
2945 // ------------------------------------------------------------------------------------------------
2946 void CWidgetManager::setCaptureKeyboard(CCtrlBase
*c
)
2948 CGroupEditBoxBase
*oldEb
= dynamic_cast<CGroupEditBoxBase
*>((CCtrlBase
*)_CaptureKeyboard
);
2949 CGroupEditBoxBase
*newEb
= dynamic_cast<CGroupEditBoxBase
*>(c
);
2951 if (_CaptureKeyboard
&& _CaptureKeyboard
!= c
)
2953 _CaptureKeyboard
->onKeyboardCaptureLost();
2955 // If the old capturedKeyboard is an editBox and allow recoverFocusOnEnter
2956 if ( oldEb
&& oldEb
->getRecoverFocusOnEnter() )
2958 _OldCaptureKeyboard
= _CaptureKeyboard
;
2962 CGroupEditBoxBase::disableSelection();
2964 if (!newEb
->getAHOnFocus().empty())
2966 CAHManager::getInstance()->runActionHandler(newEb
->getAHOnFocus(), newEb
, newEb
->getAHOnFocusParams());
2970 _CaptureKeyboard
= c
;
2971 notifyElementCaptured(c
);
2974 // ------------------------------------------------------------------------------------------------
2975 void CWidgetManager::resetCaptureKeyboard()
2977 CCtrlBase
*captureKeyboard
= _CaptureKeyboard
;
2978 _OldCaptureKeyboard
= NULL
;
2979 _CaptureKeyboard
= NULL
;
2980 if (captureKeyboard
)
2982 captureKeyboard
->onKeyboardCaptureLost();
2986 // ***************************************************************************
2987 void CWidgetManager::registerClockMsgTarget(CCtrlBase
*vb
)
2990 if (isClockMsgTarget(vb
))
2992 nlwarning("<CInterfaceManager::registerClockMsgTarget> Element %s is already registered", vb
->getId().c_str());
2995 _ClockMsgTargets
.push_back(vb
);
2998 // ***************************************************************************
2999 void CWidgetManager::unregisterClockMsgTarget(CCtrlBase
*vb
)
3002 std::list
<CCtrlBase
*>::iterator it
= std::find(_ClockMsgTargets
.begin(), _ClockMsgTargets
.end(), vb
);
3003 if (it
!= _ClockMsgTargets
.end())
3005 // instead of deleting, just mark as deleted incase we are inside iterating loop,
3006 // it will be removed in sendClockTickEvent
3011 // ***************************************************************************
3012 bool CWidgetManager::isClockMsgTarget(CCtrlBase
*vb
) const
3014 std::list
<CCtrlBase
*>::const_iterator it
= std::find(_ClockMsgTargets
.begin(), _ClockMsgTargets
.end(), vb
);
3015 return it
!= _ClockMsgTargets
.end();
3018 void CWidgetManager::sendClockTickEvent()
3020 CEventDescriptorSystem clockTick
;
3021 clockTick
.setEventTypeExtended(CEventDescriptorSystem::clocktick
);
3023 if (_CapturePointerLeft
)
3025 _CapturePointerLeft
->handleEvent(clockTick
);
3027 if (_CapturePointerRight
)
3029 _CapturePointerRight
->handleEvent(clockTick
);
3032 // and send clock tick msg to ctrl that are registered
3033 for(std::list
<CCtrlBase
*>::iterator it
= _ClockMsgTargets
.begin(); it
!= _ClockMsgTargets
.end();)
3035 CCtrlBase
* ctrl
= *it
;
3038 ctrl
->handleEvent(clockTick
);
3042 it
= _ClockMsgTargets
.erase(it
);
3046 // ------------------------------------------------------------------------------------------------
3047 void CWidgetManager::notifyElementCaptured(CCtrlBase
*c
)
3049 std::set
<CCtrlBase
*> seen
;
3050 CCtrlBase
*curr
= c
;
3054 curr
->elementCaptured(c
);
3055 curr
= curr
->getParent();
3057 // also warn the ctrl under the pointer
3058 for (uint i
= 0; i
< (uint
) _CtrlsUnderPointer
.size(); ++i
)
3060 if (!seen
.count(_CtrlsUnderPointer
[i
]))
3062 _CtrlsUnderPointer
[i
]->elementCaptured(c
);
3067 // ------------------------------------------------------------------------------------------------
3068 void CWidgetManager::makeWindow(CInterfaceGroup
*group
)
3074 for (i
= 0; i
< _MasterGroups
.size(); ++i
)
3076 if (_MasterGroups
[i
].Group
== group
->getParent())
3080 if (i
== _MasterGroups
.size())
3082 std::string stmp
= std::string("not found master group for window: ")+group
->getId();
3083 nlwarning (stmp
.c_str());
3088 // check if group hasn't been inserted twice.
3089 if (_MasterGroups
[i
].isWindowPresent(group
))
3091 nlwarning("Window inserted twice");
3095 _MasterGroups
[i
].addWindow(group
,group
->getPriority());
3100 // ------------------------------------------------------------------------------------------------
3101 void CWidgetManager::unMakeWindow(CInterfaceGroup
*group
, bool noWarning
)
3107 for (i
= 0; i
< _MasterGroups
.size(); ++i
)
3109 if (_MasterGroups
[i
].Group
== group
->getParent())
3113 if (i
== _MasterGroups
.size())
3117 std::string stmp
= std::string("not found master group for window: ")+group
->getId();
3118 nlwarning (stmp
.c_str());
3124 // check if group hasn't been inserted twice.
3125 if (!_MasterGroups
[i
].isWindowPresent(group
))
3128 nlwarning("Window not inserted in master group");
3132 _MasterGroups
[i
].delWindow(group
);
3137 // ------------------------------------------------------------------------------------------------
3138 void CWidgetManager::setGlobalColor (NLMISC::CRGBA col
)
3142 _RProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:R");
3143 _GProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:G");
3144 _BProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:B");
3145 _AProp
= CDBManager::getInstance()->getDbProp("UI:SAVE:COLOR:A");
3147 _RProp
->setValue32 (col
.R
);
3148 _GProp
->setValue32 (col
.G
);
3149 _BProp
->setValue32 (col
.B
);
3150 _AProp
->setValue32 (col
.A
);
3154 // set the global color for content (the same with modulated alpha)
3155 _GlobalColorForContent
= _GlobalColor
;
3156 _GlobalColorForContent
.A
= (uint8
) (( (uint16
) _GlobalColorForContent
.A
* (uint16
) _ContentAlpha
) >> 8);
3159 // ***************************************************************************
3160 void CWidgetManager::setContentAlpha(uint8 alpha
)
3162 _ContentAlpha
= alpha
;
3163 // update alpha of global color
3164 _GlobalColorForContent
.A
= alpha
;/*(uint8) (( (uint16) _GlobalColor.A * (uint16) _ContentAlpha) >> 8);*/
3167 void CWidgetManager::resetColorProps()
3175 // ------------------------------------------------------------------------------------------------
3176 CInterfaceOptions
* CWidgetManager::getOptions( const std::string
&name
)
3178 std::map
< std::string
, NLMISC::CSmartPtr
< CInterfaceOptions
> >::iterator it
= _OptionsMap
.find( name
);
3179 if( it
== _OptionsMap
.end() )
3185 void CWidgetManager::addOptions( std::string name
, CInterfaceOptions
*options
)
3187 _OptionsMap
.insert( std::map
< std::string
, CInterfaceOptions
* >::value_type( name
, options
) );
3190 void CWidgetManager::removeOptions( std::string name
)
3192 _OptionsMap
.erase( name
);
3195 void CWidgetManager::removeAllOptions()
3197 _OptionsMap
.clear();
3201 bool CWidgetManager::serializeOptions( xmlNodePtr parentNode
) const
3203 if( parentNode
== NULL
)
3206 std::map
< std::string
, NLMISC::CSmartPtr
< CInterfaceOptions
> >::const_iterator itr
;
3207 for( itr
= _OptionsMap
.begin(); itr
!= _OptionsMap
.end(); ++itr
)
3209 if( itr
->second
->serialize( parentNode
, itr
->first
) == NULL
)
3217 bool CWidgetManager::serializeTreeData( xmlNodePtr parentNode
) const
3219 if( parentNode
== NULL
)
3222 std::vector
< SMasterGroup
>::size_type i
;
3223 for( i
= 0; i
< _MasterGroups
.size(); i
++ )
3225 const SMasterGroup
&mg
= _MasterGroups
[ i
];
3227 std::vector
< CInterfaceGroup
* >::size_type j
;
3228 for( j
= 0; j
< mg
.Group
->getNumGroup(); j
++ )
3230 CInterfaceGroup
*g
= mg
.Group
->getGroup( j
);
3233 if( dynamic_cast< CGroupModal
* >( g
) != NULL
)
3236 if( g
->serializeTreeData( parentNode
) == NULL
)
3245 // ***************************************************************************
3246 void CWidgetManager::enableMouseHandling( bool handle
)
3248 _MouseHandlingEnabled
= handle
;
3254 // If Left captured, reset
3255 if( getCapturePointerLeft() )
3256 setCapturePointerLeft( NULL
);
3259 if( getCapturePointerRight() )
3260 setCapturePointerRight( NULL
);
3262 // Avoid any problem with modals
3263 disableModalWindow();
3267 // ***************************************************************************
3268 uint
CWidgetManager::getUserDblClickDelay()
3271 NLMISC::CCDBNodeLeaf
*pNL
= CDBManager::getInstance()->getDbProp("UI:SAVE:DOUBLE_CLICK_SPEED");
3273 nVal
= pNL
->getValue32();
3275 uint dbclickDelay
= (uint
)(DOUBLE_CLICK_MIN
+ (DOUBLE_CLICK_MAX
-DOUBLE_CLICK_MIN
) * (float)nVal
/ 100.0f
);
3276 return dbclickDelay
;
3279 // ------------------------------------------------------------------------------------------------
3280 void CWidgetManager::setupOptions()
3282 // After parsing options and templates node -> init system options.
3283 CInterfaceOptions
*opt
= getOptions( "system" );
3286 // List here all Special options
3287 _SystemOptions
[OptionCtrlSheetGrayColor
]= opt
->getValue("ctrl_sheet_gray_color");
3288 _SystemOptions
[OptionCtrlTextGrayColor
]= opt
->getValue("ctrl_text_gray_color");
3289 _SystemOptions
[OptionCtrlSheetRedifyColor
]= opt
->getValue("ctrl_sheet_redify_color");
3290 _SystemOptions
[OptionCtrlTextRedifyColor
]= opt
->getValue("ctrl_text_redify_color");
3291 _SystemOptions
[OptionCtrlSheetGreenifyColor
]= opt
->getValue("ctrl_sheet_greenify_color");
3292 _SystemOptions
[OptionCtrlTextGreenifyColor
]= opt
->getValue("ctrl_text_greenify_color");
3293 _SystemOptions
[OptionViewTextOverBackColor
]= opt
->getValue("text_over_back_color");
3294 _SystemOptions
[OptionFont
]= opt
->getValue("font");
3295 _SystemOptions
[OptionAddCoefFont
]= opt
->getValue("add_coef_font");
3296 _SystemOptions
[OptionMulCoefAnim
]= opt
->getValue("mul_coef_anim");
3297 _SystemOptions
[OptionTimeoutBubbles
]= opt
->getValue("bubbles_timeout");
3298 _SystemOptions
[OptionTimeoutMessages
]= opt
->getValue("messages_timeout");
3299 _SystemOptions
[OptionTimeoutContext
]= opt
->getValue("context_timeout");
3300 _SystemOptions
[OptionTimeoutContextHtml
]= opt
->getValue("context_html_timeout");
3301 _SystemOptions
[OptionMonospaceFont
]= opt
->getValue("monospace_font");
3306 // Get the alpha roll over speed
3307 float CWidgetManager::getAlphaRolloverSpeed()
3309 if( _AlphaRolloverSpeedDB
== NULL
)
3310 _AlphaRolloverSpeedDB
= CDBManager::getInstance()->getDbProp("UI:SAVE:ALPHA_ROLLOVER_SPEED");
3311 float fTmp
= ROLLOVER_MIN_DELTA_PER_MS
+ (ROLLOVER_MAX_DELTA_PER_MS
- ROLLOVER_MIN_DELTA_PER_MS
) * 0.01f
* (100 - _AlphaRolloverSpeedDB
->getValue32());
3312 return fTmp
*fTmp
*fTmp
;
3315 void CWidgetManager::resetAlphaRolloverSpeedProps()
3317 _AlphaRolloverSpeedDB
= NULL
;
3320 void CWidgetManager::setContainerAlpha(uint8 alpha
)
3322 _ContainerAlpha
= alpha
;
3323 // update alpha of global color
3324 NLMISC::CRGBA c
= getGlobalColor();
3325 c
.A
= alpha
;/*(uint8) (( (uint16) _GlobalColor.A * (uint16) _ContainerAlpha) >> 8); */
3326 setGlobalColor( c
);
3329 void CWidgetManager::updateGlobalAlphas()
3331 if (!_GlobalContentAlphaDB
)
3333 _GlobalContentAlphaDB
= CDBManager::getInstance()->getDbProp("UI:SAVE:CONTENT_ALPHA");
3334 nlassert(_GlobalContentAlphaDB
);
3335 _GlobalContainerAlphaDB
= CDBManager::getInstance()->getDbProp("UI:SAVE:CONTAINER_ALPHA");
3336 nlassert(_GlobalContainerAlphaDB
);
3337 _GlobalContentRolloverFactorDB
= CDBManager::getInstance()->getDbProp("UI:SAVE:CONTENT_ROLLOVER_FACTOR");
3338 nlassert(_GlobalContentRolloverFactorDB
);
3339 _GlobalContainerRolloverFactorDB
= CDBManager::getInstance()->getDbProp("UI:SAVE:CONTAINER_ROLLOVER_FACTOR");
3340 nlassert(_GlobalContainerRolloverFactorDB
);
3342 _GlobalContentAlpha
= (uint8
)_GlobalContentAlphaDB
->getValue32();
3343 _GlobalContainerAlpha
= (uint8
)_GlobalContainerAlphaDB
->getValue32();
3344 _GlobalRolloverFactorContent
= (uint8
)_GlobalContentRolloverFactorDB
->getValue32();
3345 _GlobalRolloverFactorContainer
= (uint8
)_GlobalContainerRolloverFactorDB
->getValue32();
3348 void CWidgetManager::resetGlobalAlphasProps()
3350 _GlobalContentAlphaDB
= NULL
;
3351 _GlobalContainerAlphaDB
= NULL
;
3352 _GlobalContentRolloverFactorDB
= NULL
;
3353 _GlobalContainerRolloverFactorDB
= NULL
;
3356 void CWidgetManager::registerNewScreenSizeHandler( INewScreenSizeHandler
*handler
)
3358 std::vector
< INewScreenSizeHandler
* >::iterator itr
=
3359 std::find( newScreenSizeHandlers
.begin(), newScreenSizeHandlers
.end(), handler
);
3361 if( itr
!= newScreenSizeHandlers
.end() )
3364 newScreenSizeHandlers
.push_back( handler
);
3367 void CWidgetManager::removeNewScreenSizeHandler( INewScreenSizeHandler
*handler
)
3369 std::vector
< INewScreenSizeHandler
* >::iterator itr
=
3370 std::find( newScreenSizeHandlers
.begin(), newScreenSizeHandlers
.end(), handler
);
3372 if( itr
== newScreenSizeHandlers
.end() )
3375 newScreenSizeHandlers
.erase( itr
);
3378 void CWidgetManager::registerOnWidgetsDrawnHandler( IOnWidgetsDrawnHandler
* handler
)
3380 std::vector
< IOnWidgetsDrawnHandler
* >::iterator itr
=
3381 std::find( onWidgetsDrawnHandlers
.begin(), onWidgetsDrawnHandlers
.end(), handler
);
3383 if( itr
!= onWidgetsDrawnHandlers
.end() )
3386 onWidgetsDrawnHandlers
.push_back( handler
);
3389 void CWidgetManager::removeOnWidgetsDrawnHandler( IOnWidgetsDrawnHandler
* handler
)
3391 std::vector
< IOnWidgetsDrawnHandler
* >::iterator itr
=
3392 std::find( onWidgetsDrawnHandlers
.begin(), onWidgetsDrawnHandlers
.end(), handler
);
3394 if( itr
== onWidgetsDrawnHandlers
.end() )
3397 onWidgetsDrawnHandlers
.erase( itr
);
3400 // ------------------------------------------------------------------------------------------------
3401 void CWidgetManager::startAnim( const std::string
&animId
)
3403 CInterfaceAnim
*pIT
= _Parser
->getAnim( animId
);
3409 activeAnims
.push_back( pIT
);
3412 void CWidgetManager::removeFinishedAnims()
3415 for( i
= 0; i
< (sint32
)activeAnims
.size(); ++i
)
3417 CInterfaceAnim
*pIA
= activeAnims
[i
];
3418 if (pIA
->isFinished())
3420 activeAnims
.erase( activeAnims
.begin() + i
);
3426 // ------------------------------------------------------------------------------------------------
3427 void CWidgetManager::stopAnim( const std::string
&animId
)
3429 CInterfaceAnim
*pIT
= _Parser
->getAnim( animId
);
3431 for( uint i
= 0; i
< activeAnims
.size(); ++i
)
3432 if( activeAnims
[ i
] == pIT
)
3434 activeAnims
.erase( activeAnims
.begin() + i
);
3435 if( !pIT
->isFinished() )
3441 void CWidgetManager::updateAnims()
3443 for( std::vector
< CInterfaceAnim
* >::size_type i
= 0; i
< activeAnims
.size(); i
++ )
3444 activeAnims
[ i
]->update();
3448 // ------------------------------------------------------------------------------------------------
3449 void CWidgetManager::runProcedure( const std::string
&procName
, CCtrlBase
*pCaller
,
3450 const std::vector
< std::string
> ¶mList
)
3452 CProcedure
*procp
= _Parser
->getProc( procName
);
3456 CProcedure
&proc
= *procp
;
3459 for( uint i
= 0; i
< proc
.Actions
.size(); i
++ )
3461 const CProcAction
&action
= proc
.Actions
[i
];
3462 // test if the condition for the action is valid
3463 if (!action
.CondBlocks
.empty())
3465 CInterfaceExprValue result
;
3466 result
.setBool( false );
3468 action
.buildCond( paramList
, cond
);
3469 CInterfaceExpr::eval( cond
, result
, NULL
);
3471 if( result
.toBool() )
3472 if( !result
.getBool() )
3475 // build the params sting
3477 action
.buildParams( paramList
, params
);
3479 //nlwarning("step %d : %s, %s", (int) i, action.Action.c_str(), params.c_str());
3480 CAHManager::getInstance()->runActionHandler( action
.Action
, pCaller
, params
);
3484 // ------------------------------------------------------------------------------------------------
3485 void CWidgetManager::setProcedureAction( const std::string
&procName
, uint actionIndex
,
3486 const std::string
&ah
, const std::string
¶ms
)
3488 CProcedure
*procp
= _Parser
->getProc( procName
);
3492 CProcedure
&proc
= *procp
;
3494 // set wanted action
3495 if( actionIndex
<proc
.Actions
.size() )
3497 CProcAction
&action
= proc
.Actions
[ actionIndex
];
3499 action
.ParamBlocks
.clear();
3500 action
.ParamBlocks
.resize( 1 );
3501 action
.ParamBlocks
[ 0 ].String
= params
;
3505 void CWidgetManager::getEditorSelection( std::vector
< std::string
> &selection
)
3508 for(uint i
= 0; i
< editorSelection
.size(); ++i
)
3509 selection
.push_back(editorSelection
[i
]);
3512 void CWidgetManager::selectWidget( const std::string
&name
)
3514 std::vector
< std::string
>::iterator itr
3515 = std::find( editorSelection
.begin(), editorSelection
.end(), name
);
3517 CInterfaceElement
*e
= getElementFromId( name
);
3519 if( itr
!= editorSelection
.end() )
3521 // If multiselection is on unselect if already selected
3522 if( multiSelection
)
3524 editorSelection
.erase( itr
);
3526 e
->setEditorSelected( false );
3531 // Select if not yet selected
3534 // If multiselection is off, we can only have 1 widget selected
3535 if( !multiSelection
)
3537 editorSelection
.clear();
3540 e
->setEditorSelected( true );
3541 editorSelection
.push_back( name
);
3546 notifySelectionWatchers();
3549 void CWidgetManager::clearEditorSelection()
3551 editorSelection
.clear();
3552 notifySelectionWatchers();
3555 void CWidgetManager::notifySelectionWatchers()
3557 std::vector
< IEditorSelectionWatcher
* >::iterator itr
= selectionWatchers
.begin();
3558 while( itr
!= selectionWatchers
.end() )
3560 (*itr
)->selectionChanged();
3565 void CWidgetManager::registerSelectionWatcher( IEditorSelectionWatcher
*watcher
)
3567 std::vector
< IEditorSelectionWatcher
* >::iterator itr
=
3568 std::find( selectionWatchers
.begin(), selectionWatchers
.end(), watcher
);
3570 // We already have this watcher
3571 if( itr
!= selectionWatchers
.end() )
3574 selectionWatchers
.push_back( watcher
);
3577 void CWidgetManager::unregisterSelectionWatcher( IEditorSelectionWatcher
*watcher
)
3579 std::vector
< IEditorSelectionWatcher
* >::iterator itr
=
3580 std::find( selectionWatchers
.begin(), selectionWatchers
.end(), watcher
);
3582 // We don't have this watcher
3583 if( itr
== selectionWatchers
.end() )
3586 selectionWatchers
.erase( itr
);
3589 void CWidgetManager::onWidgetAdded( const std::string
&id
)
3591 std::vector
< IWidgetWatcher
* >::const_iterator itr
= widgetWatchers
.begin();
3592 while( itr
!= widgetWatchers
.end() )
3594 (*itr
)->onWidgetAdded( id
);
3599 void CWidgetManager::onWidgetMoved( const std::string
&oldid
, const std::string
&newid
)
3601 std::vector
< IWidgetWatcher
* >::const_iterator itr
= widgetWatchers
.begin();
3602 while( itr
!= widgetWatchers
.end() )
3604 (*itr
)->onWidgetMoved( oldid
, newid
);
3609 void CWidgetManager::registerWidgetWatcher( IWidgetWatcher
*watcher
)
3611 std::vector
< IWidgetWatcher
* >::const_iterator itr
3612 = std::find( widgetWatchers
.begin(), widgetWatchers
.end(), watcher
);
3614 if( itr
!= widgetWatchers
.end() )
3617 widgetWatchers
.push_back( watcher
);
3620 void CWidgetManager::unregisterWidgetWatcher( IWidgetWatcher
*watcher
)
3622 std::vector
< IWidgetWatcher
* >::iterator itr
3623 = std::find( widgetWatchers
.begin(), widgetWatchers
.end(), watcher
);
3625 if( itr
== widgetWatchers
.end() )
3628 widgetWatchers
.erase( itr
);
3631 CInterfaceElement
* CWidgetManager::addWidgetToGroup( std::string
&group
, std::string
&widgetClass
, std::string
&widgetName
)
3633 // Check if this group exists
3634 CInterfaceElement
*e
= getElementFromId( group
);
3637 CInterfaceGroup
*g
= dynamic_cast< CInterfaceGroup
* >( e
);
3641 // Check if an element already exists with that name
3642 if( g
->getElement( widgetName
) != NULL
)
3645 // Create and add the new widget
3646 CViewBase
*v
= getParser()->createClass( widgetClass
);
3650 v
->setId( std::string( g
->getId() + ":" + widgetName
) );
3654 g
->addGroup( dynamic_cast< CInterfaceGroup
* >( v
) );
3657 g
->addCtrl( dynamic_cast< CCtrlBase
* >( v
) );
3661 onWidgetAdded( v
->getId() );
3666 bool CWidgetManager::groupSelection()
3668 std::vector
< CInterfaceElement
* > elms
;
3670 // Resolve the widget names
3671 for(uint i
= 0; i
< editorSelection
.size(); ++i
)
3673 CInterfaceElement
*e
= getElementFromId(editorSelection
[i
]);
3678 editorSelection
.clear();
3683 // Create the group as the subgroup of the top window
3684 CInterfaceGroup
*g
= static_cast< CInterfaceGroup
* >( getParser()->createClass( "interface_group" ) );
3685 getTopWindow()->addGroup( g
);
3686 g
->setParent( getTopWindow() );
3687 g
->setIdRecurse( std::string( "group" ) + NLMISC::toString( _WidgetCount
) );
3689 onWidgetAdded( g
->getId() );
3693 // Reparent the widgets to the new group
3694 for(uint i
= 0; i
< elms
.size(); ++i
)
3696 CInterfaceElement
*e
= elms
[i
];
3698 CInterfaceGroup
*p
= e
->getParent();
3705 e
->setParentSize(g
);
3706 e
->setIdRecurse(e
->getShortId());
3708 onWidgetMoved(oldId
, e
->getId());
3712 // Make sure widgets aren't clipped because the group isn't big enough
3714 // Make sure widgets are aligned
3716 // Align the new group to the top window
3717 g
->alignTo( getTopWindow() );
3719 g
->setActive( true );
3724 bool CWidgetManager::unGroupSelection()
3726 if( editorSelection
.size() != 1 )
3729 // Does the element exist?
3730 CInterfaceElement
*e
= getElementFromId( editorSelection
[ 0 ] );
3734 // Is the element a group?
3735 CInterfaceGroup
*g
= dynamic_cast< CInterfaceGroup
* >( e
);
3739 // Can't blow up a root group :(
3740 CInterfaceGroup
*p
= g
->getParent();
3745 bool ok
= g
->explode();
3751 clearEditorSelection();
3759 bool CWidgetManager::createNewGUI( const std::string
&project
, const std::string
&window
)
3763 for(uint i
= 0; i
< _MasterGroups
.size(); ++i
)
3764 delete _MasterGroups
[i
].Group
;
3765 _MasterGroups
.clear();
3767 // First create the master group
3768 CRootGroup
*root
= new CRootGroup( CViewBase::TCtorParam() );
3773 root
->setIdRecurse( project
);
3776 root
->setActive( true );
3778 // Create the first / main window
3779 CInterfaceGroup
*wnd
= new CInterfaceGroup( CViewBase::TCtorParam() );
3782 wnd
->setParent( root
);
3783 wnd
->setParentPos( root
);
3784 wnd
->setParentSize( root
);
3785 wnd
->setPosRef( Hotspot_MM
);
3786 wnd
->setParentPosRef( Hotspot_MM
);
3787 wnd
->setIdRecurse( window
);
3788 wnd
->setActive( true );
3791 root
->addElement( wnd
);
3792 mg
.addWindow( wnd
, wnd
->getPriority() );
3793 _MasterGroups
.push_back( mg
);
3795 _Pointer
= new CViewPointer( CViewBase::TCtorParam() );
3797 IParser
*parser
= getParser();
3800 // Set base color to white
3805 v
.entry
= "UI:SAVE:COLOR:R";
3806 parser
->setVariable( v
);
3808 v
.entry
= "UI:SAVE:COLOR:G";
3809 parser
->setVariable( v
);
3811 v
.entry
= "UI:SAVE:COLOR:B";
3812 parser
->setVariable( v
);
3814 v
.entry
= "UI:SAVE:COLOR:A";
3815 parser
->setVariable( v
);
3821 // ------------------------------------------------------------------------------------------------
3822 void CWidgetManager::notifyInterfaceScaleWatchers()
3824 std::vector
< IInterfaceScaleWatcher
* >::iterator itr
= scaleWatchers
.begin();
3825 while( itr
!= scaleWatchers
.end() )
3827 (*itr
)->onInterfaceScaleChanged();
3832 // ------------------------------------------------------------------------------------------------
3833 void CWidgetManager::registerInterfaceScaleWatcher( IInterfaceScaleWatcher
*watcher
)
3835 std::vector
< IInterfaceScaleWatcher
* >::const_iterator itr
3836 = std::find( scaleWatchers
.begin(), scaleWatchers
.end(), watcher
);
3838 if( itr
!= scaleWatchers
.end() )
3841 scaleWatchers
.push_back( watcher
);
3844 // ------------------------------------------------------------------------------------------------
3845 void CWidgetManager::unregisterInterfaceScaleWatcher( IInterfaceScaleWatcher
*watcher
)
3847 std::vector
< IInterfaceScaleWatcher
* >::iterator itr
3848 = std::find( scaleWatchers
.begin(), scaleWatchers
.end(), watcher
);
3850 if( itr
== scaleWatchers
.end() )
3853 scaleWatchers
.erase( itr
);
3856 // ------------------------------------------------------------------------------------------------
3857 CWidgetManager::CWidgetManager()
3860 CStringShared::createStringMapper();
3862 CReflectableRegister::registerClasses();
3864 _Parser
= IParser::createParser();
3867 curContextHelp
= NULL
;
3868 _ContextHelpActive
= true;
3869 _DeltaTimeStopingContextHelp
= 0;
3870 _MaxTimeStopingContextHelp
= 0.2f
;
3871 _LastXContextHelp
= -10000;
3872 _LastYContextHelp
= -10000;
3875 resetAlphaRolloverSpeedProps();
3876 resetGlobalAlphasProps();
3878 _GlobalColor
= NLMISC::CRGBA(255,255,255,255);
3879 _GlobalColorForContent
= _GlobalColor
;
3880 _ContentAlpha
= 255;
3881 _ContainerAlpha
= 255;
3882 _GlobalContentAlpha
= 255;
3883 _GlobalContainerAlpha
= 255;
3884 _GlobalRolloverFactorContent
= 255;
3885 _GlobalRolloverFactorContainer
= 255;
3886 _AlphaRolloverSpeedDB
= NULL
;
3888 _MouseHandlingEnabled
= true;
3889 _MouseOverWindow
= false;
3893 _InterfaceScale
= 1.0f
;
3895 _WindowSnapDistance
= 10;
3896 _WindowSnapInvert
= false;
3898 _GroupSelection
= false;
3899 multiSelection
= false;
3903 CWidgetManager::~CWidgetManager()
3905 for (uint32 i
= 0; i
< _MasterGroups
.size(); ++i
)
3907 delete _MasterGroups
[i
].Group
;
3914 curContextHelp
= NULL
;
3916 CStringShared::deleteStringMapper();
3918 editorSelection
.clear();