1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2021 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) 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/group_paragraph.h"
24 #include "nel/gui/group_html.h"
25 #include "nel/gui/widget_manager.h"
26 #include "nel/gui/interface_element.h"
27 #include "nel/gui/view_pointer_base.h"
28 #include "nel/gui/view_bitmap.h"
29 #include "nel/gui/view_text_id.h"
30 #include "nel/gui/group_container.h"
31 #include "nel/misc/i_xml.h"
32 #include "nel/misc/i18n.h"
33 #include "nel/misc/xml_auto_ptr.h"
36 using namespace NLMISC
;
42 NLMISC_REGISTER_OBJECT(CViewBase
, CCtrlLink
, std::string
, "button_link");
47 // ----------------------------------------------------------------------------
48 CGroupParagraph::CGroupParagraph(const TCtorParam
¶m
)
49 : CInterfaceGroup(param
),
60 _OverColor
= CRGBA(255,255,255,32);
66 _FirstViewIndentView
= false;
68 _TextAlign
= AlignLeft
;
71 // ----------------------------------------------------------------------------
72 void CGroupParagraph::addChild (CViewBase
* child
, bool deleteOnRemove
)
76 nlwarning("<CGroupParagraph::addChild> : tried to add a NULL view");
80 // add child at last index
81 addChildAtIndex(child
, (uint
)_Elements
.size(), deleteOnRemove
);
82 if (_Elements
.size() >= 2)
84 setOrder((uint
)_Elements
.size() - 1, getOrder((uint
)_Elements
.size() - 2) + 1);
89 // ----------------------------------------------------------------------------
90 CGroupParagraph::~CGroupParagraph()
95 // ----------------------------------------------------------------------------
96 // Set Hotspot of the first element in reference to the group
97 /*void CGroupParagraph::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 CGroupParagraph::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(space);
170 else if (addElt == Top)
173 view->_ParentPosRef = Hotspot_TL;
174 else // align == Right
175 view->_ParentPosRef = Hotspot_TR;
176 view->_Y = abs(space);
184 view->_ParentPosRef = Hotspot_TL;
185 else // align == Bottom
186 view->_ParentPosRef = Hotspot_BL;
187 view->_X = -abs(space);
189 else if (addElt == Right)
192 view->_ParentPosRef = Hotspot_TR;
193 else // align == Bottom
194 view->_ParentPosRef = Hotspot_BR;
195 view->_X = abs(space);
201 std::string
CGroupParagraph::getProperty( const std::string
&name
) const
203 if( name
== "addelt" )
225 if( name
== "align" )
247 if( name
== "space" )
249 return toString( _Space
);
254 return toString( _Over
);
257 if( name
== "col_over" )
259 return toString( _OverColor
);
262 if( name
== "hardtext" )
267 if( name
== "textid" )
269 return toString( _TextId
);
272 return CInterfaceGroup::getProperty( name
);
275 void CGroupParagraph::setProperty( const std::string
&name
, const std::string
&value
)
277 if( name
== "addelt" )
295 if( name
== "align" )
312 if( name
== "space" )
315 if( fromString( value
, i
) )
323 if( fromString( value
, b
) )
328 if( name
== "col_over" )
331 if( fromString( value
, c
) )
335 if( name
== "hardtext" )
343 if( name
== "textid" )
346 if( fromString( value
, i
) )
356 CInterfaceGroup::setProperty( name
, value
);
360 xmlNodePtr
CGroupParagraph::serialize( xmlNodePtr parentNode
, const char *type
) const
362 xmlNodePtr node
= CInterfaceGroup::serialize( parentNode
, type
);
407 xmlSetProp( node
, BAD_CAST
"addelt", BAD_CAST addelt
.c_str() );
408 xmlSetProp( node
, BAD_CAST
"align", BAD_CAST align
.c_str() );
409 xmlSetProp( node
, BAD_CAST
"space", BAD_CAST
toString( _Space
).c_str() );
410 xmlSetProp( node
, BAD_CAST
"over", BAD_CAST
toString( _Over
).c_str() );
411 xmlSetProp( node
, BAD_CAST
"col_over", BAD_CAST
toString( _OverColor
).c_str() );
412 xmlSetProp( node
, BAD_CAST
"hardtext", BAD_CAST _HardText
.c_str() );
413 xmlSetProp( node
, BAD_CAST
"textid", BAD_CAST
toString( _TextId
).c_str() );
418 // ----------------------------------------------------------------------------
419 bool CGroupParagraph::parse (xmlNodePtr cur
, CInterfaceGroup
* parentGroup
)
421 if (!CInterfaceGroup::parse(cur
,parentGroup
))
424 // Parse location. If these properties are not specified, set them to 0
426 CXMLAutoPtr
ptr((const char*) xmlGetProp( cur
, (xmlChar
*)"addelt" ));
430 if (stricmp(ptr
,"B") == 0)
432 else if (stricmp(ptr
,"T") == 0)
434 else if (stricmp(ptr
,"L") == 0)
436 else if (stricmp(ptr
,"R") == 0)
440 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"align" );
444 if (stricmp(ptr
,"B") == 0)
446 else if (stricmp(ptr
,"T") == 0)
448 else if (stricmp(ptr
,"L") == 0)
450 else if (stricmp(ptr
,"R") == 0)
456 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"space" );
459 fromString((const char*)ptr
, _Space
);
461 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"over" );
463 if (ptr
) _Over
= convertBool(ptr
);
465 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"col_over" );
466 _OverColor
= CRGBA(255,255,255,32);
467 if (ptr
) _OverColor
= convertColor(ptr
);
470 // TEMPLATE TEXT SETUP
472 // justification parameters
473 _Templ
.parseTextOptions (cur
);
476 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"hardtext" );
479 _HardText
= std::string( (const char*)ptr
);
480 const char *propPtr
= ptr
;
481 if (NLMISC::startsWith(propPtr
, "ui"))
482 addTextChild(CI18N::get(propPtr
));
484 addTextChild(propPtr
);
488 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"textid" );
491 fromString((const char*)ptr
, _TextId
);
492 addTextChildID( _TextId
);
499 // ----------------------------------------------------------------------------
500 void CGroupParagraph::addTextChild(const std::string
& line
, bool multiLine
/*= true*/)
502 const string elid
= _Id
+ ":el" + toString(_IdCounter
); ++_IdCounter
;
503 CViewText
*view
= new CViewText (elid
, string(""), _Templ
.getFontSize(), _Templ
.getColor(), _Templ
.getShadow());
504 view
->_Parent
= this;
505 view
->setMultiLine (multiLine
);
506 view
->setTextMode(_Templ
.getTextMode());
507 if (multiLine
) view
->setMultiLineSpace (_Space
);
508 view
->setText (line
);
509 // Herit global-coloring
510 view
->setModulateGlobalColor(getModulateGlobalColor());
517 // ----------------------------------------------------------------------------
518 void CGroupParagraph::addTextChild(const std::string
& line
, const CRGBA
& textColor
, bool multiLine
/*= true*/)
520 const string elid
= _Id
+ ":el" + toString(_IdCounter
); ++_IdCounter
;
521 CViewText
*view
= new CViewText (elid
, string(""), _Templ
.getFontSize(), _Templ
.getColor(), _Templ
.getShadow());
522 view
->_Parent
= this;
523 view
->setMultiLine (multiLine
);
524 if (multiLine
) view
->setMultiLineSpace (_Space
);
525 view
->setText (line
);
526 view
->setColor (textColor
);
527 // Herit global-coloring
528 view
->setModulateGlobalColor(getModulateGlobalColor());
533 // ----------------------------------------------------------------------------
534 void CGroupParagraph::addTextChildID (uint32 nID
, bool multiLine
)
536 const string elid
= _Id
+ ":el" + toString(_IdCounter
); ++_IdCounter
;
537 CViewTextID
*view
= new CViewTextID (elid
, nID
, _Templ
.getFontSize(), _Templ
.getColor(), _Templ
.getShadow());
538 view
->_Parent
= this;
539 view
->setMultiLine (multiLine
);
540 if (multiLine
) view
->setMultiLineSpace (_Space
);
541 // Herit global-coloring
542 view
->setModulateGlobalColor(getModulateGlobalColor());
547 // ----------------------------------------------------------------------------
548 void CGroupParagraph::addTextChildID(const std::string
&dbPath
,bool multiLine
/*=true*/)
550 const string elid
= _Id
+ ":el" + toString(_IdCounter
); ++_IdCounter
;
551 CViewTextID
*view
= new CViewTextID (elid
, dbPath
, _Templ
.getFontSize(), _Templ
.getColor(), _Templ
.getShadow());
552 view
->_Parent
= this;
553 view
->setMultiLine (multiLine
);
554 if (multiLine
) view
->setMultiLineSpace (_Space
);
555 // Herit global-coloring
556 view
->setModulateGlobalColor(getModulateGlobalColor());
561 // ----------------------------------------------------------------------------
562 void CGroupParagraph::delChild (CViewBase
* childToDel
)
565 uint posChildToDel
= 0;
566 for (posChildToDel
= 0; posChildToDel
< _Elements
.size(); ++posChildToDel
)
568 CElementInfo rEI
= _Elements
[posChildToDel
];
569 if (rEI
.Element
== childToDel
)
573 if (posChildToDel
== _Elements
.size())
575 nlwarning("Can't del child %s, it does not exist in the list", childToDel
->getId().c_str());
578 delChild(posChildToDel
);
581 // ----------------------------------------------------------------------------
582 void CGroupParagraph::delChild(uint posChildToDel
)
584 if (posChildToDel
>= (uint
) _Elements
.size())
586 nlwarning("<CGroupParagraph::delChild> bad index");
590 CViewBase
* childToDel
= _Elements
[posChildToDel
].Element
;
591 bool ElementMustBeDeleted
= _Elements
[posChildToDel
].EltDeleteOnRemove
;
592 _Elements
.erase (_Elements
.begin()+posChildToDel
);
593 // Remove from drawing
594 if (dynamic_cast<CInterfaceGroup
*>(childToDel
)) delGroup(static_cast<CInterfaceGroup
*>(childToDel
), !ElementMustBeDeleted
);
595 else if (dynamic_cast<CCtrlBase
*>(childToDel
)) delCtrl(static_cast<CCtrlBase
*>(childToDel
), !ElementMustBeDeleted
);
596 else delView(childToDel
, !ElementMustBeDeleted
);
598 // Bind the new first element
599 if (posChildToDel
< _Elements
.size())
601 CViewBase
*pVB
= _Elements
[posChildToDel
].Element
;
602 if (posChildToDel
== 0)
604 pVB
->_ParentPos
= NULL
;
605 // setHSGroup (pVB, _AddElt, _Align);
606 if ((_AddElt
== Top
) || (_AddElt
== Bottom
))
612 pVB
->_ParentPos
= _Elements
[posChildToDel
-1].Element
;
616 // ----------------------------------------------------------------------------
617 /*void CGroupParagraph::removeHead ()
619 if (_Elements.empty())
621 nlwarning("<CGroupParagraph::removeHead> Can't remove head, list is empty");
624 delChild (_Elements.begin()->Element);*/
625 /*CViewBase *pVB = _Elements.begin()->Element;
626 if ((_AddElt == Top) || (_AddElt == Bottom))
628 sint32 shift = _H - (pVB->getH() + _Space);
633 sint32 shift = _W - (pVB->getW() + _Space);
637 bool FirstElementMustBeDeleted = _Elements.begin()->EltDeleteOnRemove;
638 if (FirstElementMustBeDeleted)
640 _Elements.erase (_Elements.begin());
641 // Remove from drawing
642 for (vector<CInterfaceGroup*>::iterator itg = _ChildrenGroups.begin(); itg != _ChildrenGroups.end(); itg++)
645 _ChildrenGroups.erase (itg);
648 for (vector<CCtrlBase*>::iterator itc = _Controls.begin(); itc != _Controls.end(); itc++)
651 _Controls.erase (itc);
654 for (vector<CViewBase*>::iterator itv = _Views.begin(); itv != _Views.end(); itv++)
662 // Bind the new first element
663 pVB = _Elements.begin()->Element;
664 pVB->_ParentPos = NULL;
665 setHSGroup (pVB, _AddElt, _Align);
666 if ((_AddElt == Top) || (_AddElt == Bottom))
672 // ----------------------------------------------------------------------------
673 void CGroupParagraph::setTextTemplate(const CViewText
& templ
)
679 // ----------------------------------------------------------------------------
680 void CGroupParagraph::updateCoords()
684 if (!_ContentValidated
)
687 CInterfaceElement::updateCoords();
691 sint32 y
=-(sint32
)_TopSpace
;
694 sint width
= std::min(getMaxWReal(), getWReal());
696 // For each elements, place them
697 uint firstElementOnLine
= 0;
698 const uint elmCount
= (uint
)_Elements
.size();
700 for (i
= 0; i
< elmCount
+1; ++i
)
702 // Force flush for the last element
703 bool changeLine
= (i
== elmCount
);
704 uint lastLineElement
= i
+1;
706 // Not the end of the element
710 if (_Elements
[i
].Element
->getActive())
712 _Elements
[i
].Element
->updateCoords();
714 CViewText
*viewText
= dynamic_cast<CViewText
*>(_Elements
[i
].Element
);
717 // FIXME: this does not work with multiple view text on same line
718 if (_TextAlign
== AlignCenter
&& elmCount
== 1)
719 viewText
->setTextMode(CViewText::Centered
);
721 viewText
->setFirstLineX(x
+ ((i
==0)?_FirstViewIndentView
:0));
723 viewText
->updateTextContext();
727 _Elements
[i
].Element
->setX(x
+ ((i
==0)?_FirstViewIndentView
:0));
729 _Elements
[i
].Element
->setPosRef(Hotspot_TL
);
730 _Elements
[i
].Element
->setParentPosRef(Hotspot_TL
);
732 // Update coords for this element
733 _Elements
[i
].Element
->updateCoords();
735 // Does we balance the last line height ?
738 if (_TextAlign
== AlignCenter
&& elmCount
== 1)
740 sint pad
= width
- viewText
->getWReal();
741 viewText
->setX(pad
/2);
744 changeLine
= viewText
->getNumLine() > 1;
745 if (!viewText
->getText().empty() && *(viewText
->getText().rbegin()) == '\n')
752 // If this element is too big for the line, place it next time
753 if ((i
!=firstElementOnLine
) && ((_Elements
[i
].Element
->getX() + _Elements
[i
].Element
->getW()) > width
))
763 x
= _Elements
[i
].Element
->getX() + _Elements
[i
].Element
->getWReal();
769 // Balance line height
775 uint multiLineHeight
= 0;
777 uint lastLineWidth
= _Indent
;
779 for (j
=firstElementOnLine
; j
<lastLineElement
; j
++)
783 CViewText
*viewTextOnLine
= dynamic_cast<CViewText
*>(_Elements
[j
].Element
);
788 // Height is just under the first line letter
789 newHeight
= viewTextOnLine
->getFontHeight() - viewTextOnLine
->getFontLegHeight();
791 // Leg height for this view
792 legHeight
= std::max(legHeight
, viewTextOnLine
->getFontLegHeight());
794 // Last element is a text multi line
795 if (j
==(lastLineElement
-1))
797 const uint numLine
= viewTextOnLine
->getNumLine();
800 multiLineHeight
= (numLine
-2) * viewTextOnLine
->getFontHeight() + (numLine
-1) * viewTextOnLine
->getMultiLineSpace();
801 lastLineWidth
= _Indent
+ viewTextOnLine
->getLastLineW ();
807 newHeight
= _Elements
[j
].Element
->getH();
808 CGroupHTMLInputOffset
*inputOffset
= dynamic_cast<CGroupHTMLInputOffset
*>(_Elements
[j
].Element
);
809 if (inputOffset
&& inputOffset
->Offset
< 0)
811 newHeight
+= inputOffset
->Offset
;
812 legHeight
= max(-(inputOffset
->Offset
), sint32(legHeight
));
816 if (lineHeight
< newHeight
)
817 lineHeight
= newHeight
;
820 // Repos element on the line
821 for (j
=firstElementOnLine
; j
<lastLineElement
; j
++)
825 CViewText
*viewTextOnLine
= dynamic_cast<CViewText
*>(_Elements
[j
].Element
);
828 CGroupHTMLInputOffset
*inputOffset
= dynamic_cast<CGroupHTMLInputOffset
*>(_Elements
[j
].Element
);
830 offsetY
= inputOffset
->Offset
;
833 newHeight
= viewTextOnLine
->getFontHeight() - viewTextOnLine
->getFontLegHeight() - offsetY
;
835 newHeight
= _Elements
[j
].Element
->getH();
837 sint32 posY
= y
-lineHeight
+newHeight
+offsetY
;
838 _Elements
[j
].Element
->setY(posY
);
843 nlassert(lastLineElement
>0);
844 nlassert(lastLineElement
-1<elmCount
);
848 y
-= lineHeight
+ multiLineHeight
+ legHeight
;
852 firstElementOnLine
= lastLineElement
;
856 // Update control view
857 for (i
= 0; i
<_Links
.size(); ++i
)
860 CLink
&link
= _Links
[i
];
862 // Number of link needed
863 uint links
= std::min((uint
)3, link
.Link
->getNumLine());
871 // Create the control ?
872 CCtrlLink
*ctrl
= link
.CtrlLink
[j
];
876 ctrl
= new CCtrlLink(CViewBase::TCtorParam());
877 link
.CtrlLink
[j
] = ctrl
;
878 ctrl
->setId(getId()+":"+"links"+toString(i
)+"-"+toString(j
));
879 ctrl
->setParent (this);
880 ctrl
->setParentSize (this);
881 ctrl
->setParentPos (this);
882 ctrl
->setParentPosRef (Hotspot_TL
);
883 ctrl
->setPosRef (Hotspot_TL
);
884 ctrl
->setActive(true);
885 ctrl
->setActionOnLeftClick(link
.Link
->getActionOnLeftClick());
886 ctrl
->setParamsOnLeftClick(link
.Link
->getParamsOnLeftClick());
887 ctrl
->setScale(true);
892 int x
, y
, width
, height
;
893 int fontSize
= link
.Link
->getFontHeight();
894 int fontLineSpace
= link
.Link
->getMultiLineSpace();
897 x
= (j
== 0) ? link
.Link
->getFirstLineX() : link
.Link
->getX();
901 y
= link
.Link
->getY() - (fontSize
+fontLineSpace
) * j
;
903 y
= link
.Link
->getY() - ((fontSize
+fontLineSpace
) * (link
.Link
->getNumLine()-1));
909 width
= link
.Link
->getLastLineW ();
912 width
= link
.Link
->getW();
916 width
-= (link
.Link
->getFirstLineX() - link
.Link
->getX());
919 if ((j
== 1) && (links
==3))
920 height
= (fontSize
+fontLineSpace
)*(link
.Link
->getNumLine()-2);
931 if (link
.CtrlLink
[j
])
933 delCtrl (link
.CtrlLink
[j
]);
934 link
.CtrlLink
[j
] = NULL
;
941 CInterfaceGroup::updateCoords();
944 _ContentValidated
= true;
947 // ----------------------------------------------------------------------------
948 void CGroupParagraph::checkCoords ()
952 sint parentWidth
= std::min(_Parent
->getMaxWReal(), _Parent
->getWReal());
953 if (_LastW
!= (sint
) parentWidth
)
955 CCtrlBase
*pCB
= CWidgetManager::getInstance()->getCapturePointerLeft();
958 CCtrlResizer
*pCR
= dynamic_cast<CCtrlResizer
*>(pCB
);
961 // We are resizing !!!!
965 _LastW
= parentWidth
;
971 _LastW
= parentWidth
;
976 CInterfaceGroup::checkCoords();
979 // ----------------------------------------------------------------------------
980 void CGroupParagraph::draw ()
983 //CViewRenderer &rVR = *CViewRenderer::getInstance();
984 //rVR.drawRotFlipBitmap _RenderLayer, (_XReal, _YReal, _WReal, _HReal, 0, false, rVR.getBlankTextureId(), CRGBA(0,255,0,255) );
985 if (_Over
|| _TempOver
)
987 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
989 if (CWidgetManager::getInstance()->getModalWindow() == NULL
)
991 sint32 x
= CWidgetManager::getInstance()->getPointer()->getX();
992 sint32 y
= CWidgetManager::getInstance()->getPointer()->getY();
994 CInterfaceGroup
*pIG
= CWidgetManager::getInstance()->getWindowUnder(x
,y
);
995 CInterfaceGroup
*pParent
= this;
997 while (pParent
!= NULL
)
1004 pParent
= pParent
->getParent();
1007 sint32 clipx
,clipy
,clipw
,cliph
;
1008 getClip(clipx
,clipy
,clipw
,cliph
);
1010 (x
> (clipx
+ clipw
)) ||
1012 (y
> (clipy
+ cliph
)) || !bFound
)
1018 for (uint32 i
= 0; i
< _Elements
.size(); ++i
)
1019 if (_Elements
[i
].Element
->getActive())
1021 CViewBase
*pVB
= _Elements
[i
].Element
;
1022 if ((x
>= pVB
->getXReal()) &&
1023 (x
< (pVB
->getXReal() + pVB
->getWReal()))&&
1024 (y
>= pVB
->getYReal()) &&
1025 (y
< (pVB
->getYReal() + pVB
->getHReal())))
1035 CViewBase
*pVB
= _Elements
[_OverElt
].Element
;
1036 CRGBA col
= _OverColor
;
1037 if(getModulateGlobalColor())
1039 col
.modulateFromColor (_OverColor
, CWidgetManager::getInstance()->getGlobalColorForContent());
1044 col
.A
= (uint8
)(((sint32
)col
.A
*((sint32
)CWidgetManager::getInstance()->getGlobalColorForContent().A
+1))>>8);
1046 rVR
.drawRotFlipBitmap (_RenderLayer
, pVB
->getXReal(), pVB
->getYReal(),
1047 pVB
->getWReal(), pVB
->getHReal(), 0, false, rVR
.getBlankTextureId(),
1053 CInterfaceGroup::draw ();
1056 // ----------------------------------------------------------------------------
1057 bool CGroupParagraph::handleEvent (const NLGUI::CEventDescriptor
& event
)
1062 bool bReturn
= CInterfaceGroup::handleEvent(event
);
1064 if (event
.getType() == NLGUI::CEventDescriptor::mouse
)
1066 const NLGUI::CEventDescriptorMouse
&eventDesc
= (const NLGUI::CEventDescriptorMouse
&)event
;
1069 if (!isIn(eventDesc
.getX(), eventDesc
.getY()))
1075 for (uint32 i
= 0; i
< _Elements
.size(); ++i
)
1076 if (_Elements
[i
].Element
->getActive())
1078 CViewBase
*pVB
= _Elements
[i
].Element
;
1079 if ((eventDesc
.getX() >= pVB
->getXReal()) &&
1080 (eventDesc
.getX() < (pVB
->getXReal() + pVB
->getWReal()))&&
1081 (eventDesc
.getY() >= pVB
->getYReal()) &&
1082 (eventDesc
.getY() < (pVB
->getYReal() + pVB
->getHReal())))
1094 // predicate to remove a view from the list of element
1095 struct CRemoveViewPred
1097 bool operator()(const CGroupParagraph::CElementInfo
&info
) const { return dynamic_cast<CViewBase
*>(info
.Element
) != NULL
; }
1100 // predicate to remove a ctrl from the list of element
1101 struct CRemoveCtrlPred
1103 bool operator()(const CGroupParagraph::CElementInfo
&info
) const { return dynamic_cast<CCtrlBase
*>(info
.Element
) != NULL
; }
1106 // predicate to remove a group from the list of element
1107 struct CRemoveGroupPred
1109 bool operator()(const CGroupParagraph::CElementInfo
&info
) const { return dynamic_cast<CInterfaceGroup
*>(info
.Element
) != NULL
; }
1113 // ----------------------------------------------------------------------------
1114 void CGroupParagraph::clearViews()
1117 // remove views from the list of elements
1118 _Elements
.erase(std::remove_if(_Elements
.begin(), _Elements
.end(), CRemoveViewPred()), _Elements
.end());
1119 CInterfaceGroup::clearViews();
1123 // ----------------------------------------------------------------------------
1124 void CGroupParagraph::clearControls()
1127 // remove views from the list of elements
1128 _Elements
.erase(std::remove_if(_Elements
.begin(), _Elements
.end(), CRemoveCtrlPred()), _Elements
.end());
1129 CInterfaceGroup::clearControls();
1133 // ----------------------------------------------------------------------------
1134 void CGroupParagraph::clearGroups()
1137 // remove views from the list of elements
1138 _Elements
.erase(std::remove_if(_Elements
.begin(), _Elements
.end(), CRemoveGroupPred()), _Elements
.end());
1139 CInterfaceGroup::clearGroups();
1143 // ----------------------------------------------------------------------------
1144 void CGroupParagraph::forceSizeW (sint32 newSizeW
)
1147 for (uint32 i
= 0; i
< _Elements
.size(); ++i
)
1149 _Elements
[i
].Element
->setW (_W
);
1150 _Elements
[i
].Element
->CInterfaceElement::updateCoords();
1154 // ----------------------------------------------------------------------------
1155 void CGroupParagraph::forceSizeH (sint32 newSizeH
)
1158 for (uint32 i
= 0; i
< _Elements
.size(); ++i
)
1160 _Elements
[i
].Element
->setH (_H
);
1161 _Elements
[i
].Element
->CInterfaceElement::updateCoords();
1165 // ----------------------------------------------------------------------------
1166 void CGroupParagraph::setMinW(sint32 minW
)
1172 // ----------------------------------------------------------------------------
1173 void CGroupParagraph::setMinH(sint32 minH
)
1179 // ----------------------------------------------------------------------------
1180 bool CGroupParagraph::addChildAtIndex(CViewBase
*child
, uint index
, bool deleteOnRemove
/*=true*/)
1184 nlwarning("<CGroupParagraph::addChild> : tried to add a NULL view");
1187 if (index
> _Elements
.size())
1191 child
->_Parent
= this;
1192 child
->_ParentPos
= NULL
;
1193 child
->_Active
= true;
1196 child
->_RenderLayer
= this->_RenderLayer
;
1197 // Can't have sizeref on the coordinate corresponding to alignement
1202 child
->_SizeRef
&= 1; // sizeref on w is permitted
1206 child
->_SizeRef
&= 2; // sizeref on h is permitted
1209 nlwarning("<CGroupParagraph::addChild> bad align");
1210 child
->_SizeRef
= 0;
1214 child
->_SizeDivW
= 10;
1215 child
->_SizeDivH
= 10;
1217 // Position the element according to the list alignement
1218 // setHSGroup (child, _AddElt, _Align);
1220 // update coords of the element (it may use child_resize_h or w)
1221 //child->updateCoords();
1222 child
->invalidateCoords();
1225 if ((_AddElt
== Top
) || (_AddElt
== Bottom
))
1227 // update the list size
1228 sint32 newH
= _H
+ child
->getH();
1229 if (!_Elements
.empty())
1233 if ((_SizeRef
&1) == 0) // No parent size reference in W
1235 sint32 newW
= max (_W
, child
->getW());
1241 // Update the list coords
1242 sint32 newW
= _W
+ child
->getW();
1243 if (!_Elements
.empty())
1247 if ((_SizeRef
&2) == 0) // No parent size reference in H
1249 sint32 newH
= max (_H
, child
->getH());
1256 ei
.EltDeleteOnRemove
= deleteOnRemove
;
1261 // update alignement
1262 // setHSParent(child, _AddElt, _Align, _Space);
1263 // child->_ParentPos = _Elements[index - 1].Element;
1265 _Elements
.insert(_Elements
.begin() + index
, ei
);
1266 // link next element to this one
1267 if (index
< _Elements
.size() - 1)
1269 // _Elements[index + 1].Element->_ParentPos = child;
1270 // setHSParent(_Elements[index + 1].Element, _AddElt, _Align, _Space);
1273 // Add this element for drawing
1275 CInterfaceGroup
*pIG
= dynamic_cast<CInterfaceGroup
*>(child
);
1278 addGroup (pIG
, (sint
) index
);
1281 CCtrlBase
*pCB
= dynamic_cast<CCtrlBase
*>(child
);
1284 addCtrl (pCB
, (sint
) index
);
1287 CViewBase
*pVB
= dynamic_cast<CViewBase
*>(child
);
1290 addView (pVB
, (sint
) index
);
1299 // ----------------------------------------------------------------------------
1300 sint32
CGroupParagraph::getElementIndex(CViewBase
* child
) const
1302 for(uint k
= 0; k
< _Elements
.size(); ++k
)
1304 if (_Elements
[k
].Element
== child
) return k
;
1309 // ----------------------------------------------------------------------------
1310 /*void CGroupParagraph::swapChildren(uint index1, uint index2)
1312 if (index1 >= _Elements.size()
1313 || index2 >= _Elements.size())
1315 nlwarning("<CGroupParagraph::swapChildren> bad indexes");
1318 // prevent elements from being deleted
1319 bool oldMustDelete1 = _Elements[index1].EltDeleteOnRemove;
1320 bool oldMustDelete2 = _Elements[index2].EltDeleteOnRemove;
1322 uint order1 = _Elements[index1].Order;
1323 uint order2 = _Elements[index2].Order;
1325 _Elements[index1].EltDeleteOnRemove = false;
1326 _Elements[index2].EltDeleteOnRemove = false;
1328 CViewBase *v1 = _Elements[index1].Element;
1329 CViewBase *v2 = _Elements[index2].Element;
1332 if (index1 < index2)
1336 addChildAtIndex(v2, index1, oldMustDelete2);
1337 setOrder(index1, order2);
1338 addChildAtIndex(v1, index2, oldMustDelete1);
1339 setOrder(index2, order1);
1345 addChildAtIndex(v1, index2, oldMustDelete1);
1346 setOrder(index2, order1);
1347 addChildAtIndex(v2, index1, oldMustDelete2);
1348 setOrder(index1, order2);
1352 // ----------------------------------------------------------------------------
1353 void CGroupParagraph::deleteAllChildren()
1355 uint numChildren
= getNbElement();
1356 for(uint k
= 0; k
< numChildren
; ++k
)
1358 delChild(numChildren
- 1 - k
); // delete in reverse order to avoid unnecessary vector copies
1362 // ----------------------------------------------------------------------------
1363 uint
CGroupParagraph::getNumActiveChildren() const
1365 uint numChildren
= 0;
1366 for(uint k
= 0; k
< _Elements
.size(); ++k
)
1368 if (_Elements
[k
].Element
->getActive()) ++numChildren
;
1373 // ----------------------------------------------------------------------------
1374 void CGroupParagraph::setDelOnRemove(uint index
, bool delOnRemove
)
1376 if (index
>= _Elements
.size())
1378 nlwarning("bad index");
1381 _Elements
[index
].EltDeleteOnRemove
= delOnRemove
;
1384 // ----------------------------------------------------------------------------
1385 bool CGroupParagraph::getDelOnRemove(uint index
) const
1387 if (index
>= _Elements
.size())
1389 nlwarning("bad index");
1392 return _Elements
[index
].EltDeleteOnRemove
;
1395 // ----------------------------------------------------------------------------
1396 void CGroupParagraph::addChildLink (CViewLink
* child
, bool deleteOnRemove
)
1399 addChild (child
, deleteOnRemove
);
1402 _Links
.push_back (CLink(child
));
1405 // ----------------------------------------------------------------------------
1406 CGroupParagraph::CLink::CLink (CViewLink
*link
)
1414 // ----------------------------------------------------------------------------
1415 void CGroupParagraph::onInvalidateContent()
1417 _ContentValidated
= false;
1421 // ----------------------------------------------------------------------------
1422 sint32
CGroupParagraph::getMaxUsedW() const
1424 // The paragraph max is the sum of the components max
1426 for (uint k
= 0; k
< _Elements
.size(); ++k
)
1428 // Get the child width
1429 maxWidth
+= _Elements
[k
].Element
->getMaxUsedW();
1431 return maxWidth
+ _MarginLeft
;
1434 // ----------------------------------------------------------------------------
1435 sint32
CGroupParagraph::getMinUsedW() const
1437 // The paragraph min is the max of the components min
1438 sint32 minWidth
= 0;
1439 for (uint k
= 0; k
< _Elements
.size(); ++k
)
1441 // Get the child width
1442 sint32 width
= _Elements
[k
].Element
->getMinUsedW();
1443 if (width
> minWidth
)
1446 return minWidth
+ _MarginLeft
;
1450 void CGroupParagraph::setupSizes()
1452 EAlign addElt
= _AddElt
;
1453 _GroupSizeRef
= _SizeRef
;
1454 if ((addElt
== Top
) || (addElt
== Bottom
))
1459 _SizeRef
= _SizeRef
&(~2);
1466 _SizeRef
= _SizeRef
&(~1);
1471 void CGroupParagraph::onTextChanged()
1473 if( _Elements
.empty() )
1476 CElementInfo
&e
= _Elements
[ 0 ];
1478 CViewText
*t
= dynamic_cast< CViewText
* >( e
.Element
);
1481 t
->setText( _HardText
);
1486 CViewTextID
*ti
= dynamic_cast< CViewTextID
* >( e
.Element
);
1489 ti
->setTextId( _TextId
);