1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2017 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 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/>.
22 #include "nel/gui/group_list.h"
24 #include "nel/gui/interface_element.h"
25 #include "nel/gui/view_bitmap.h"
26 #include "nel/gui/view_text_id.h"
27 #include "nel/gui/group_container_base.h"
28 #include "nel/gui/lua_ihm.h"
29 #include "nel/misc/xml_auto_ptr.h"
30 #include "nel/gui/widget_manager.h"
31 #include "nel/gui/view_pointer_base.h"
32 #include "nel/misc/i18n.h"
35 using namespace NLMISC
;
41 NLMISC_REGISTER_OBJECT(CViewBase
, CGroupList
, std::string
, "list");
46 // ----------------------------------------------------------------------------
47 CGroupList::CGroupList(const TCtorParam
¶m
)
48 : CInterfaceGroup(param
),
56 _DynamicDisplaySize
= false;
60 _OverColor
= CRGBA(255, 255, 255, 32);
66 // ----------------------------------------------------------------------------
67 void CGroupList::addChild (CViewBase
* child
, bool deleteOnRemove
)
71 nlwarning("<CGroupList::addChild> : tried to add a NULL view");
75 // Make sure there's room for the element
76 if ((sint32
)_Elements
.size() == _MaxElements
)
81 // add child at last index
82 addChildAtIndex(child
, (uint
)_Elements
.size(), deleteOnRemove
);
83 if (_Elements
.size() >= 2)
85 setOrder((uint
)_Elements
.size() - 1, getOrder((uint
)_Elements
.size() - 2) + 1);
89 // ----------------------------------------------------------------------------
90 CGroupList::~CGroupList()
95 // ----------------------------------------------------------------------------
96 // Set Hotspot of the first element in reference to the group
97 void CGroupList::setHSGroup (CViewBase
*child
, EAlign addElt
, EAlign align
)
104 child
->_ParentPosRef
= Hotspot_TL
;
105 child
->_PosRef
= Hotspot_TL
;
107 else // align == Right
109 child
->_ParentPosRef
= Hotspot_TR
;
110 child
->_PosRef
= Hotspot_TR
;
116 child
->_ParentPosRef
= Hotspot_TR
;
117 child
->_PosRef
= Hotspot_TR
;
119 else // align == Bottom
121 child
->_ParentPosRef
= Hotspot_BR
;
122 child
->_PosRef
= Hotspot_BR
;
128 child
->_ParentPosRef
= Hotspot_BL
;
129 child
->_PosRef
= Hotspot_BL
;
131 else // align == Right
133 child
->_ParentPosRef
= Hotspot_BR
;
134 child
->_PosRef
= Hotspot_BR
;
140 child
->_ParentPosRef
= Hotspot_TL
;
141 child
->_PosRef
= Hotspot_TL
;
143 else // align == Bottom
145 child
->_ParentPosRef
= Hotspot_BL
;
146 child
->_PosRef
= Hotspot_BL
;
155 // ----------------------------------------------------------------------------
156 /** align an element towards its parent in the group
158 void CGroupList::setHSParent(CViewBase
*view
, EAlign addElt
, EAlign
/* align */, uint space
)
160 if ((addElt
== Top
) || (addElt
== Bottom
))
162 if (addElt
== Bottom
)
165 view
->_ParentPosRef
= Hotspot_BL
;
166 else // align == Right
167 view
->_ParentPosRef
= Hotspot_BR
;
168 //view->_Y = -abs((sint32)space);
169 view
->_Y
= - (sint32
)space
;
171 else if (addElt
== Top
)
174 view
->_ParentPosRef
= Hotspot_TL
;
175 else // align == Right
176 view
->_ParentPosRef
= Hotspot_TR
;
177 // view->_Y = abs((sint32)space);
178 view
->_Y
= (sint32
)space
;
186 view
->_ParentPosRef
= Hotspot_TL
;
187 else // align == Bottom
188 view
->_ParentPosRef
= Hotspot_BL
;
189 //view->_X = -abs((sint32)space);
190 view
->_X
= -(sint32
)space
;
192 else if (addElt
== Right
)
195 view
->_ParentPosRef
= Hotspot_TR
;
196 else // align == Bottom
197 view
->_ParentPosRef
= Hotspot_BR
;
198 //view->_X = abs((sint32)space);
199 view
->_X
= (sint32
)space
;
204 std::string
CGroupList::getProperty( const std::string
&name
) const
206 if( name
== "maxelements" )
208 return toString( _MaxElements
);
211 if( name
== "addelt" )
231 if( name
== "align" )
251 if( name
== "space" )
253 return toString( _Space
);
258 return toString( _Over
);
261 if( name
== "dynamic_display_size" )
263 return toString( _DynamicDisplaySize
);
266 if( name
== "col_over" )
268 return toString( _OverColor
);
271 if( name
== "hardtext" )
276 if( name
== "textid" )
278 return toString( _TextId
);
281 return CInterfaceGroup::getProperty( name
);
284 void CGroupList::setProperty( const std::string
&name
, const std::string
&value
)
286 if( name
== "maxelements" )
289 if( fromString( value
, i
) )
294 if( name
== "addelt" )
312 if( name
== "align" )
329 if( name
== "space" )
332 if( fromString( value
, i
) )
340 if( fromString( value
, b
) )
345 if( name
== "dynamic_display_size" )
348 if( fromString( value
, b
) )
349 _DynamicDisplaySize
= b
;
353 if( name
== "col_over" )
356 if( fromString( value
, c
) )
361 if( name
== "hardtext" )
369 if( name
== "textid" )
372 if( fromString( value
, i
) )
379 CInterfaceGroup::setProperty( name
, value
);
383 xmlNodePtr
CGroupList::serialize( xmlNodePtr parentNode
, const char *type
) const
385 xmlNodePtr node
= CInterfaceGroup::serialize( parentNode
, type
);
389 xmlSetProp( node
, BAD_CAST
"type", BAD_CAST
"list" );
390 xmlSetProp( node
, BAD_CAST
"maxelements", BAD_CAST
toString( _MaxElements
).c_str() );
433 xmlSetProp( node
, BAD_CAST
"addelt", BAD_CAST addelt
.c_str() );
434 xmlSetProp( node
, BAD_CAST
"align", BAD_CAST align
.c_str() );
435 xmlSetProp( node
, BAD_CAST
"space", BAD_CAST
toString( _Space
).c_str() );
436 xmlSetProp( node
, BAD_CAST
"over", BAD_CAST
toString( _Over
).c_str() );
437 xmlSetProp( node
, BAD_CAST
"dynamic_display_size", BAD_CAST
toString( _DynamicDisplaySize
).c_str() );
438 xmlSetProp( node
, BAD_CAST
"col_over", BAD_CAST
toString( _OverColor
).c_str() );
439 xmlSetProp( node
, BAD_CAST
"hardtext", BAD_CAST _HardText
.c_str() );
440 xmlSetProp( node
, BAD_CAST
"textid", BAD_CAST
toString( _TextId
).c_str() );
445 // ----------------------------------------------------------------------------
446 bool CGroupList::parse (xmlNodePtr cur
, CInterfaceGroup
* parentGroup
)
448 if (!CInterfaceGroup::parse(cur
, parentGroup
))
451 // Parse location. If these properties are not specified, set them to 0
453 CXMLAutoPtr
ptr((const char*) xmlGetProp( cur
, (xmlChar
*)"maxelements" ));
457 if (!fromString((const char*)ptr
, _MaxElements
))
459 nlwarning("<CGroupList::parse> Can't parse the 'maxelements' field ");
463 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"addelt" );
467 if (stricmp(ptr
, "B") == 0)
469 else if (stricmp(ptr
, "T") == 0)
471 else if (stricmp(ptr
, "L") == 0)
473 else if (stricmp(ptr
, "R") == 0)
477 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"align" );
481 if (stricmp(ptr
, "B") == 0)
483 else if (stricmp(ptr
, "T") == 0)
485 else if (stricmp(ptr
, "L") == 0)
487 else if (stricmp(ptr
, "R") == 0)
491 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"space" );
494 fromString((const char*)ptr
, _Space
);
498 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"over" );
500 if (ptr
) _Over
= convertBool(ptr
);
502 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"dynamic_display_size" );
503 _DynamicDisplaySize
= false;
504 if (ptr
) _DynamicDisplaySize
= convertBool(ptr
);
506 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"col_over" );
507 _OverColor
= CRGBA(255, 255, 255, 32);
508 if (ptr
) _OverColor
= convertColor(ptr
);
511 // TEMPLATE TEXT SETUP
513 // justification parameters
514 _Templ
.parseTextOptions (cur
);
517 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"hardtext" );
520 _HardText
= std::string( (const char*)ptr
);
521 const char *propPtr
= ptr
;
522 if (NLMISC::startsWith(propPtr
, "ui"))
523 addTextChild(CI18N::get(propPtr
));
525 addTextChild(propPtr
);
529 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"textid" );
532 fromString((const char*)ptr
, _TextId
);
533 addTextChildID( _TextId
);
542 // ----------------------------------------------------------------------------
543 void CGroupList::addTextChild(const std::string
& line
, bool multiLine
/*= true*/)
545 const string elid
= _Id
+ ":el" + toString(_IdCounter
); ++_IdCounter
;
546 CViewText
*view
= new CViewText (elid
, string(""), _Templ
.getFontSize(), _Templ
.getColor(), _Templ
.getShadow());
547 view
->setSerializable( false );
548 view
->_Parent
= this;
549 view
->setMultiLine (multiLine
);
550 view
->setTextMode(_Templ
.getTextMode());
551 if (multiLine
) view
->setMultiLineSpace (_Space
);
552 view
->setText (line
);
553 // Herit global-coloring
554 view
->setModulateGlobalColor(getModulateGlobalColor());
561 // ----------------------------------------------------------------------------
562 void CGroupList::addTextChild(const std::string
& line
, const CRGBA
& textColor
, bool multiLine
/*= true*/)
564 const string elid
= _Id
+ ":el" + toString(_IdCounter
); ++_IdCounter
;
565 CViewText
*view
= new CViewText (elid
, string(""), _Templ
.getFontSize(), _Templ
.getColor(), _Templ
.getShadow());
566 view
->setSerializable( false );
567 view
->_Parent
= this;
568 view
->setMultiLine (multiLine
);
569 if (multiLine
) view
->setMultiLineSpace (_Space
);
570 view
->setText (line
);
571 view
->setColor (textColor
);
572 // Herit global-coloring
573 view
->setModulateGlobalColor(getModulateGlobalColor());
578 // ----------------------------------------------------------------------------
579 void CGroupList::addTextChildID (uint32 nID
, bool multiLine
)
581 const string elid
= _Id
+ ":el" + toString(_IdCounter
); ++_IdCounter
;
582 CViewTextID
*view
= new CViewTextID (elid
, nID
, _Templ
.getFontSize(), _Templ
.getColor(), _Templ
.getShadow());
583 view
->setSerializable( false );
584 view
->_Parent
= this;
585 view
->setMultiLine (multiLine
);
586 if (multiLine
) view
->setMultiLineSpace (_Space
);
587 // Herit global-coloring
588 view
->setModulateGlobalColor(getModulateGlobalColor());
593 // ----------------------------------------------------------------------------
594 void CGroupList::addTextChildID(const std::string
&dbPath
, bool multiLine
/*=true*/)
596 const string elid
= _Id
+ ":el" + toString(_IdCounter
); ++_IdCounter
;
597 CViewTextID
*view
= new CViewTextID (elid
, dbPath
, _Templ
.getFontSize(), _Templ
.getColor(), _Templ
.getShadow());
598 view
->setSerializable( false );
599 view
->_Parent
= this;
600 view
->setMultiLine (multiLine
);
601 if (multiLine
) view
->setMultiLineSpace (_Space
);
602 // Herit global-coloring
603 view
->setModulateGlobalColor(getModulateGlobalColor());
608 // ----------------------------------------------------------------------------
609 bool CGroupList::delChild (CViewBase
* childToDel
, bool noWarning
, bool forceDontDelete
)
612 uint posChildToDel
= 0;
613 for (posChildToDel
= 0; posChildToDel
< _Elements
.size(); ++posChildToDel
)
615 CElementInfo rEI
= _Elements
[posChildToDel
];
616 if (rEI
.Element
== childToDel
)
620 if (posChildToDel
== _Elements
.size())
623 nlwarning("Can't del child %s, it does not exist in the list", childToDel
->getId().c_str());
626 return delChild(posChildToDel
, forceDontDelete
);
629 // ----------------------------------------------------------------------------
630 bool CGroupList::delChild(uint posChildToDel
, bool forceDontDelete
)
632 if (posChildToDel
>= (uint
) _Elements
.size())
634 nlwarning("<CGroupList::delChild> bad index");
638 CViewBase
* childToDel
= _Elements
[posChildToDel
].Element
;
640 childToDel
->_Parent
= NULL
;
642 bool elementMustBeDeleted
= _Elements
[posChildToDel
].EltDeleteOnRemove
&& !forceDontDelete
;
643 _Elements
.erase (_Elements
.begin()+posChildToDel
);
644 // Remove from drawing
645 if (dynamic_cast<CInterfaceGroup
*>(childToDel
)) delGroup(static_cast<CInterfaceGroup
*>(childToDel
), !elementMustBeDeleted
);
646 else if (dynamic_cast<CCtrlBase
*>(childToDel
)) delCtrl(static_cast<CCtrlBase
*>(childToDel
), !elementMustBeDeleted
);
647 else delView(childToDel
, !elementMustBeDeleted
);
649 // Bind the new first element
650 if (posChildToDel
< _Elements
.size())
652 CViewBase
*pVB
= _Elements
[posChildToDel
].Element
;
653 if (posChildToDel
== 0)
655 pVB
->_ParentPos
= NULL
;
656 setHSGroup (pVB
, _AddElt
, _Align
);
657 if ((_AddElt
== Top
) || (_AddElt
== Bottom
))
663 pVB
->_ParentPos
= _Elements
[posChildToDel
-1].Element
;
668 // ----------------------------------------------------------------------------
669 void CGroupList::removeHead ()
671 if (_Elements
.empty())
673 nlwarning("<CGroupList::removeHead> Can't remove head, list is empty");
676 delChild (_Elements
.begin()->Element
);
677 /*CViewBase *pVB = _Elements.begin()->Element;
678 if ((_AddElt == Top) || (_AddElt == Bottom))
680 sint32 shift = _H - (pVB->getH() + _Space);
685 sint32 shift = _W - (pVB->getW() + _Space);
689 bool FirstElementMustBeDeleted = _Elements.begin()->EltDeleteOnRemove;
690 if (FirstElementMustBeDeleted)
692 _Elements.erase (_Elements.begin());
693 // Remove from drawing
694 for (vector<CInterfaceGroup*>::iterator itg = _ChildrenGroups.begin(); itg != _ChildrenGroups.end(); itg++)
697 _ChildrenGroups.erase (itg);
700 for (vector<CCtrlBase*>::iterator itc = _Controls.begin(); itc != _Controls.end(); itc++)
703 _Controls.erase (itc);
706 for (vector<CViewBase*>::iterator itv = _Views.begin(); itv != _Views.end(); itv++)
714 // Bind the new first element
715 pVB = _Elements.begin()->Element;
716 pVB->_ParentPos = NULL;
717 setHSGroup (pVB, _AddElt, _Align);
718 if ((_AddElt == Top) || (_AddElt == Bottom))
724 // ----------------------------------------------------------------------------
725 void CGroupList::setTextTemplate(const CViewText
& templ
)
731 // ----------------------------------------------------------------------------
732 void CGroupList::updateCoords()
734 if (!_Active
) return;
735 // Handle if elements are not active
736 for (sint32 i
= 0; i
< ((sint32
)_Elements
.size()-1); ++i
)
738 if (_Elements
[i
].Element
->getActive())
739 setHSParent(_Elements
[i
+1].Element
, _AddElt
, _Align
, _Space
);
741 setHSParent(_Elements
[i
+1].Element
, _AddElt
, _Align
, 0);
744 CInterfaceGroup::updateCoords();
746 EAlign addElt
= _AddElt
;
747 if ((addElt
== Top
) || (addElt
== Bottom
))
753 for (uint32 i
= 0; i
< _Elements
.size(); ++i
)
754 if (_Elements
[i
].Element
->getActive())
756 newH
+= _Elements
[i
].Element
->getH();
761 _H
= max(newH
, _MinH
);
762 if (_DynamicDisplaySize
)
767 if (_H
< _MaxH
) setOfsY(0);
769 // if width is not from parent, then ensure minimum size
770 if ((_SizeRef
& 1) == 0) _W
= max(_W
, _MinW
);
777 for (uint32 i
= 0; i
< _Elements
.size(); ++i
)
778 if (_Elements
[i
].Element
->getActive())
780 newW
+= _Elements
[i
].Element
->getW();
785 _W
= max(newW
, _MinW
);
786 if (_DynamicDisplaySize
)
791 if (_W
< _MaxW
) setOfsX(0);
793 // if height is not from parent, then ensure minimum size
794 if ((_SizeRef
& 2) == 0) _H
= max(_H
, _MinH
);
797 CInterfaceElement::updateCoords();
800 // ----------------------------------------------------------------------------
801 void CGroupList::draw ()
804 //CViewRenderer &rVR = *CViewRenderer::getInstance();
805 //rVR.drawRotFlipBitmap _RenderLayer, (_XReal, _YReal, _WReal, _HReal, 0, false, rVR.getBlankTextureId(), CRGBA(0, 255, 0, 255) );
808 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
810 if (CWidgetManager::getInstance()->getModalWindow() == NULL
)
812 sint32 x
= CWidgetManager::getInstance()->getPointer()->getX();
813 sint32 y
= CWidgetManager::getInstance()->getPointer()->getY();
815 CInterfaceGroup
*pIG
= CWidgetManager::getInstance()->getWindowUnder(x
, y
);
816 CInterfaceGroup
*pParent
= this;
818 while (pParent
!= NULL
)
825 pParent
= pParent
->getParent();
828 sint32 clipx
, clipy
, clipw
, cliph
;
829 getClip(clipx
, clipy
, clipw
, cliph
);
831 (x
> (clipx
+ clipw
)) ||
833 (y
> (clipy
+ cliph
)) || !bFound
)
839 for (uint32 i
= 0; i
< _Elements
.size(); ++i
)
840 if (_Elements
[i
].Element
->getActive())
842 CViewBase
*pVB
= _Elements
[i
].Element
;
843 if ((x
>= pVB
->getXReal()) &&
844 (x
< (pVB
->getXReal() + pVB
->getWReal()))&&
845 (y
>= pVB
->getYReal()) &&
846 (y
< (pVB
->getYReal() + pVB
->getHReal())))
856 // Find the first container
857 CInterfaceGroup
*pIG
= _Parent
;
858 CGroupContainerBase
*pGC
= dynamic_cast<CGroupContainerBase
*>(pIG
);
862 if (pIG
== NULL
) break;
863 if (dynamic_cast<CGroupContainerBase
*>(pIG
) != NULL
)
864 pGC
= dynamic_cast<CGroupContainerBase
*>(pIG
);
867 bool bDisplayOverSelection
= true;
871 bDisplayOverSelection
= false;
874 if (bDisplayOverSelection
)
876 CViewBase
*pVB
= _Elements
[_OverElt
].Element
;
877 CRGBA col
= _OverColor
;
878 if(getModulateGlobalColor())
880 col
.modulateFromColor (_OverColor
, CWidgetManager::getInstance()->getGlobalColorForContent());
885 col
.A
= (uint8
)(((sint32
)col
.A
*((sint32
)CWidgetManager::getInstance()->getGlobalColorForContent().A
+1))>>8);
887 rVR
.drawRotFlipBitmap (_RenderLayer
, pVB
->getXReal(), pVB
->getYReal(),
888 pVB
->getWReal(), pVB
->getHReal(), 0, false, rVR
.getBlankTextureId(),
895 CInterfaceGroup::draw ();
898 // ----------------------------------------------------------------------------
899 bool CGroupList::handleEvent (const NLGUI::CEventDescriptor
& event
)
904 bool bReturn
= CInterfaceGroup::handleEvent(event
);
906 if (event
.getType() == NLGUI::CEventDescriptor::mouse
)
908 const NLGUI::CEventDescriptorMouse
&eventDesc
= (const NLGUI::CEventDescriptorMouse
&)event
;
911 if (!isIn(eventDesc
.getX(), eventDesc
.getY()))
914 for (uint32 i
= 0; i
< _Elements
.size(); ++i
)
915 if (_Elements
[i
].Element
->getActive())
917 CViewBase
*pVB
= _Elements
[i
].Element
;
918 if ((eventDesc
.getX() >= pVB
->getXReal()) &&
919 (eventDesc
.getX() < (pVB
->getXReal() + pVB
->getWReal()))&&
920 (eventDesc
.getY() >= pVB
->getYReal()) &&
921 (eventDesc
.getY() < (pVB
->getYReal() + pVB
->getHReal())))
933 // predicate to remove a view from the list of element
934 struct CRemoveViewPred
936 bool operator()(const CGroupList::CElementInfo
&info
) const { return dynamic_cast<CViewBase
*>(info
.Element
) != NULL
; }
939 // predicate to remove a ctrl from the list of element
940 struct CRemoveCtrlPred
942 bool operator()(const CGroupList::CElementInfo
&info
) const { return dynamic_cast<CCtrlBase
*>(info
.Element
) != NULL
; }
945 // predicate to remove a group from the list of element
946 struct CRemoveGroupPred
948 bool operator()(const CGroupList::CElementInfo
&info
) const { return dynamic_cast<CInterfaceGroup
*>(info
.Element
) != NULL
; }
952 // ----------------------------------------------------------------------------
953 void CGroupList::clearViews()
956 // remove views from the list of elements
957 _Elements
.erase(std::remove_if(_Elements
.begin(), _Elements
.end(), CRemoveViewPred()), _Elements
.end());
958 CInterfaceGroup::clearViews();
962 // ----------------------------------------------------------------------------
963 void CGroupList::clearControls()
966 // remove views from the list of elements
967 _Elements
.erase(std::remove_if(_Elements
.begin(), _Elements
.end(), CRemoveCtrlPred()), _Elements
.end());
968 CInterfaceGroup::clearControls();
972 // ----------------------------------------------------------------------------
973 void CGroupList::clearGroups()
976 // remove views from the list of elements
977 _Elements
.erase(std::remove_if(_Elements
.begin(), _Elements
.end(), CRemoveGroupPred()), _Elements
.end());
978 CInterfaceGroup::clearGroups();
982 // ----------------------------------------------------------------------------
983 void CGroupList::forceSizeW (sint32 newSizeW
)
986 for (uint32 i
= 0; i
< _Elements
.size(); ++i
)
988 _Elements
[i
].Element
->setW (_W
);
989 _Elements
[i
].Element
->CInterfaceElement::updateCoords();
993 // ----------------------------------------------------------------------------
994 void CGroupList::forceSizeH (sint32 newSizeH
)
997 for (uint32 i
= 0; i
< _Elements
.size(); ++i
)
999 _Elements
[i
].Element
->setH (_H
);
1000 _Elements
[i
].Element
->CInterfaceElement::updateCoords();
1004 // ----------------------------------------------------------------------------
1005 void CGroupList::setMinW(sint32 minW
)
1011 // ----------------------------------------------------------------------------
1012 void CGroupList::setMinH(sint32 minH
)
1018 // ----------------------------------------------------------------------------
1019 bool CGroupList::addChildAtIndex(CViewBase
*child
, uint index
, bool deleteOnRemove
/*=true*/)
1023 nlwarning("<CGroupList::addChild> : tried to add a NULL view");
1026 if (index
> _Elements
.size())
1030 child
->_Parent
= this;
1031 child
->_ParentPos
= NULL
;
1034 child
->_RenderLayer
= this->_RenderLayer
;
1035 // Can't have sizeref on the coordinate corresponding to alignement
1040 child
->_SizeRef
&= 1; // sizeref on w is permitted
1044 child
->_SizeRef
&= 2; // sizeref on h is permitted
1047 nlwarning("<CGroupList::addChild> bad align");
1048 child
->_SizeRef
= 0;
1052 child
->_SizeDivW
= 10;
1053 child
->_SizeDivH
= 10;
1055 // Position the element according to the list alignement
1056 setHSGroup (child
, _AddElt
, _Align
);
1058 // update coords of the element (it may use child_resize_h or w)
1059 //child->updateCoords();
1060 child
->invalidateCoords();
1063 if ((_AddElt
== Top
) || (_AddElt
== Bottom
))
1065 // update the list size
1066 sint32 newH
= _H
+ child
->getH();
1067 if (!_Elements
.empty())
1071 if ((_SizeRef
&1) == 0) // No parent size reference in W
1073 sint32 newW
= max (_W
, child
->getW());
1079 // Update the list coords
1080 sint32 newW
= _W
+ child
->getW();
1081 if (!_Elements
.empty())
1085 if ((_SizeRef
&2) == 0) // No parent size reference in H
1087 sint32 newH
= max (_H
, child
->getH());
1094 ei
.EltDeleteOnRemove
= deleteOnRemove
;
1099 // update alignement
1100 setHSParent(child
, _AddElt
, _Align
, _Space
);
1101 child
->_ParentPos
= _Elements
[index
- 1].Element
;
1103 _Elements
.insert(_Elements
.begin() + index
, ei
);
1104 // link next element to this one
1105 if (index
< _Elements
.size() - 1)
1107 _Elements
[index
+ 1].Element
->_ParentPos
= child
;
1108 setHSParent(_Elements
[index
+ 1].Element
, _AddElt
, _Align
, _Space
);
1111 // Add this element for drawing
1113 child
->setSerializable( false );
1114 CInterfaceGroup
*pIG
= dynamic_cast<CInterfaceGroup
*>(child
);
1117 addGroup (pIG
, (sint
) index
);
1120 CCtrlBase
*pCB
= dynamic_cast<CCtrlBase
*>(child
);
1123 addCtrl (pCB
, (sint
) index
);
1126 CViewBase
*pVB
= dynamic_cast<CViewBase
*>(child
);
1129 addView (pVB
, (sint
) index
);
1138 // ----------------------------------------------------------------------------
1139 sint32
CGroupList::getElementIndex(CViewBase
* child
) const
1141 for(uint k
= 0; k
< _Elements
.size(); ++k
)
1143 if (_Elements
[k
].Element
== child
) return k
;
1148 // ----------------------------------------------------------------------------
1149 int CGroupList::luaGetElementIndex(CLuaState
&ls
)
1151 CLuaIHM::checkArgCount(ls
, "getElementIndex", 1);
1152 CViewBase
* viewBase
= dynamic_cast<CViewBase
*>(CLuaIHM::getUIOnStack(ls
, 1));
1153 ls
.push(getElementIndex(viewBase
));
1157 // ----------------------------------------------------------------------------
1158 void CGroupList::swapChildren(uint index1
, uint index2
)
1160 if (index1
>= _Elements
.size()
1161 || index2
>= _Elements
.size())
1163 nlwarning("<CGroupList::swapChildren> bad indexes");
1166 // prevent elements from being deleted
1167 bool oldMustDelete1
= _Elements
[index1
].EltDeleteOnRemove
;
1168 bool oldMustDelete2
= _Elements
[index2
].EltDeleteOnRemove
;
1170 uint order1
= _Elements
[index1
].Order
;
1171 uint order2
= _Elements
[index2
].Order
;
1173 _Elements
[index1
].EltDeleteOnRemove
= false;
1174 _Elements
[index2
].EltDeleteOnRemove
= false;
1176 CViewBase
*v1
= _Elements
[index1
].Element
;
1177 CViewBase
*v2
= _Elements
[index2
].Element
;
1180 if (index1
< index2
)
1184 addChildAtIndex(v2
, index1
, oldMustDelete2
);
1185 setOrder(index1
, order2
);
1186 addChildAtIndex(v1
, index2
, oldMustDelete1
);
1187 setOrder(index2
, order1
);
1193 addChildAtIndex(v1
, index2
, oldMustDelete1
);
1194 setOrder(index2
, order1
);
1195 addChildAtIndex(v2
, index1
, oldMustDelete2
);
1196 setOrder(index1
, order2
);
1200 // ----------------------------------------------------------------------------
1201 int CGroupList::luaUpChild(CLuaState
&ls
)
1203 CLuaIHM::checkArgCount(ls
, "upChild", 1);
1204 CViewBase
* viewBase
= dynamic_cast<CViewBase
*>(CLuaIHM::getUIOnStack(ls
, 1));
1205 sint32 indexUpChild
= getElementIndex(viewBase
);
1206 if(indexUpChild
> 0)
1208 swapChildren(indexUpChild
, indexUpChild
-1);
1213 // ----------------------------------------------------------------------------
1214 int CGroupList::luaDownChild(CLuaState
&ls
)
1216 CLuaIHM::checkArgCount(ls
, "downChild", 1);
1217 CViewBase
* viewBase
= dynamic_cast<CViewBase
*>(CLuaIHM::getUIOnStack(ls
, 1));
1218 sint32 indexDownChild
= getElementIndex(viewBase
);
1219 if(indexDownChild
< (sint32
) (_Elements
.size()-1))
1221 swapChildren(indexDownChild
, indexDownChild
+1);
1226 // ----------------------------------------------------------------------------
1227 int CGroupList::luaGetChild(CLuaState
&ls
)
1229 const char *funcName
= "getChild";
1230 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1231 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1232 sint index
= (sint
) ls
.toInteger(1);
1233 if(index
< 0 || index
>= (sint
) _Elements
.size())
1235 CLuaIHM::fails(ls
, "getChild : trying to access element %d in list '%s', which has %d elements",
1236 index
, getId().c_str(), (int) _Elements
.size());
1238 CLuaIHM::pushUIOnStack(ls
, getChild((uint
) index
));
1242 // ----------------------------------------------------------------------------
1243 void CGroupList::deleteAllChildren()
1245 uint numChildren
= getNbElement();
1246 for(uint k
= 0; k
< numChildren
; ++k
)
1248 delChild(numChildren
- 1 - k
); // delete in reverse order to avoid unnecessary vector copies
1252 // ----------------------------------------------------------------------------
1253 uint
CGroupList::getNumActiveChildren() const
1255 uint numChildren
= 0;
1256 for(uint k
= 0; k
< _Elements
.size(); ++k
)
1258 if (_Elements
[k
].Element
->getActive()) ++numChildren
;
1263 // ----------------------------------------------------------------------------
1264 void CGroupList::setDelOnRemove(uint index
, bool delOnRemove
)
1266 if (index
>= _Elements
.size())
1268 nlwarning("bad index");
1271 _Elements
[index
].EltDeleteOnRemove
= delOnRemove
;
1274 // ----------------------------------------------------------------------------
1275 bool CGroupList::getDelOnRemove(uint index
) const
1277 if (index
>= _Elements
.size())
1279 nlwarning("bad index");
1282 return _Elements
[index
].EltDeleteOnRemove
;
1286 // ----------------------------------------------------------------------------
1287 int CGroupList::luaAddTextChild(CLuaState
&ls
)
1289 const char *funcName
= "addTextChild";
1290 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1291 #ifdef RYZOM_LUA_UCSTRING
1292 ucstring text
; // Compatibility
1293 if(CLuaIHM::pop(ls
, text
))
1295 addTextChild(text
.toUtf8());
1298 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TSTRING
);
1299 addTextChild(ls
.toString(1));
1304 // ----------------------------------------------------------------------------
1305 int CGroupList::luaAddColoredTextChild(CLuaState
&ls
)
1307 const char *funcName
= "addColoredTextChild";
1308 CLuaIHM::checkArgCount(ls
, funcName
, 5);
1309 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TSTRING
);
1310 CLuaIHM::checkArgType(ls
, funcName
, 2, LUA_TNUMBER
);
1311 CLuaIHM::checkArgType(ls
, funcName
, 3, LUA_TNUMBER
);
1312 CLuaIHM::checkArgType(ls
, funcName
, 4, LUA_TNUMBER
);
1313 CLuaIHM::checkArgType(ls
, funcName
, 5, LUA_TNUMBER
);
1314 string text
= ls
.toString(1);
1316 uint r
= (uint
) ls
.toInteger(2);
1317 uint g
= (uint
) ls
.toInteger(3);
1318 uint b
= (uint
) ls
.toInteger(4);
1319 uint a
= (uint
) ls
.toInteger(5);
1321 addTextChild(text
, CRGBA(r
, g
, b
, a
));
1326 // ----------------------------------------------------------------------------
1327 int CGroupList::luaAddChild(CLuaState
&ls
)
1329 const char *funcName
= "addChild";
1330 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1331 CViewBase
*vb
= dynamic_cast<CViewBase
*>(CLuaIHM::getUIOnStack(ls
, 1));
1334 CLuaIHM::fails(ls
, "%s requires a view, group or control", funcName
);
1343 // ----------------------------------------------------------------------------
1344 int CGroupList::luaAddChildAtIndex(CLuaState
&ls
)
1346 const char *funcName
= "addChildAtIndex";
1347 CLuaIHM::checkArgCount(ls
, funcName
, 2);
1348 CLuaIHM::checkArgType(ls
, funcName
, 2, LUA_TNUMBER
);
1349 CViewBase
*vb
= dynamic_cast<CViewBase
*>(CLuaIHM::getUIOnStack(ls
, 1));
1352 CLuaIHM::fails(ls
, "%s requires a view, group or control", funcName
);
1356 addChildAtIndex(vb
, (uint
) ls
.toInteger(2));
1361 // ----------------------------------------------------------------------------
1362 int CGroupList::luaDetachChild(CLuaState
&ls
)
1364 const char *funcName
= "detachChild";
1365 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1366 CViewBase
*vb
= dynamic_cast<CViewBase
*>(CLuaIHM::getUIOnStack(ls
, 1));
1369 nlwarning("%s requires a view, group or control", funcName
);
1374 ls
.push(delChild(vb
, false, true));
1379 // ----------------------------------------------------------------------------
1380 int CGroupList::luaDelChild(CLuaState
&ls
)
1382 CLuaIHM::checkArgCount(ls
, "CGroupList::delChild", 1);
1383 CViewBase
*vb
= dynamic_cast<CViewBase
*>(CLuaIHM::getUIOnStack(ls
, 1));
1384 if (vb
) delChild(vb
);
1391 // ----------------------------------------------------------------------------
1392 int CGroupList::luaClear(CLuaState
&ls
)
1394 CLuaIHM::checkArgCount(ls
, "clear", 0);
1395 deleteAllChildren();
1399 void CGroupList::setupSizes()
1401 _GroupSizeRef
= _SizeRef
;
1402 if ((_AddElt
== Top
) || (_AddElt
== Bottom
))
1407 _SizeRef
= _SizeRef
& (~2);
1414 _SizeRef
= _SizeRef
& (~1);
1418 void CGroupList::onTextChanged()
1420 if( _Elements
.empty() )
1423 CElementInfo
&e
= _Elements
[ 0 ];
1425 CViewText
*t
= dynamic_cast< CViewText
* >( e
.Element
);
1428 t
->setText( _HardText
);
1433 CViewTextID
*ti
= dynamic_cast< CViewTextID
* >( e
.Element
);
1436 ti
->setTextId( _TextId
);