Merge branch 'main/rendor-staging' into fixes
[ryzomcore.git] / nel / src / gui / interface_element.cpp
blob5ceebdddb5e9a27b2983d83134099bbca25f1989
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2020 Winch Gate Property Limited
3 //
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>
7 //
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 "stdpch.h"
23 #include "nel/gui/interface_group.h"
24 #include "nel/gui/interface_property.h"
25 #include "nel/gui/view_renderer.h"
26 #include "nel/gui/widget_manager.h"
27 #include "nel/gui/db_manager.h"
28 #include "nel/gui/interface_link.h"
29 #include "nel/misc/xml_auto_ptr.h"
30 #include "nel/gui/lua_ihm.h"
31 #include "nel/gui/lua_ihm.h"
32 #include "nel/misc/mem_stream.h"
35 using namespace std;
36 using namespace NLMISC;
38 #ifdef DEBUG_NEW
39 #define new DEBUG_NEW
40 #endif
42 namespace NLGUI
44 bool CInterfaceElement::editorMode = false;
45 std::vector< CInterfaceElement::IDeletionWatcher* > CInterfaceElement::deletionWatchers;
47 // ------------------------------------------------------------------------------------------------
48 CInterfaceElement::~CInterfaceElement()
50 if (_Links) // remove any link that point to that element
52 for(TLinkVect::iterator it = _Links->begin(); it != _Links->end(); ++it)
54 (*it)->removeTarget(this);
56 delete _Links;
59 if( editorMode )
61 notifyDeletionWatchers();
62 if( _Parent != NULL )
63 _Parent->onWidgetDeleted( this );
67 // ------------------------------------------------------------------------------------------------
68 void CInterfaceElement::parseError(CInterfaceGroup * parentGroup, const char *reason)
70 string tmp = string("cannot parse view:")+getId()+", parent:"+parentGroup->getId();
71 nlinfo(tmp.c_str());
72 if (reason)
73 nlinfo("reason : %s", reason);
77 void CInterfaceElement::setIdRecurse(const std::string &newID)
79 std::string baseId = _Parent ? _Parent->getId() : "ui";
80 setId(baseId + ":" + newID);
83 // ------------------------------------------------------------------------------------------------
84 std::string CInterfaceElement::getShortId() const
86 std::string::size_type last = _Id.find_last_of(':');
87 if (last != std::string::npos)
89 return _Id.substr(last + 1);
91 return _Id;
94 std::string CInterfaceElement::stripId( const std::string &fullId )
96 std::string id = fullId;
97 std::string::size_type i = id.find_last_of( ':' );
98 if( i != std::string::npos )
99 id = id.substr( i + 1, id.size() - 1 );
100 return id;
103 std::string CInterfaceElement::getProperty( const std::string &name ) const
105 if( name == "id" )
107 return stripId( getId() );
109 else
110 if( name == "active" )
112 if( getActive() )
113 return "true";
114 else
115 return "false";
117 else
118 if( name == "x" )
120 return NLMISC::toString( getX() );
122 else
123 if( name == "y" )
125 return NLMISC::toString( getY() );
127 else
128 if( name == "w" )
130 return NLMISC::toString( getW() );
132 else
133 if( name == "h" )
135 return NLMISC::toString( getH() );
137 else
138 if( name == "posref" )
140 std::string posref;
141 posref += HotSpotToString( getPosRef() );
142 return posref;
144 else
145 if( name == "parentposref" )
147 std::string parentPosRef;
148 parentPosRef = HotSpotToString( getParentPosRef() );
149 return parentPosRef;
151 else
152 if( name == "sizeref" )
154 return getSizeRefAsString( _SizeRef, _SizeDivW, _SizeDivH );
156 if( name == "posparent" )
158 std::string pp;
159 getPosParent( pp );
160 return pp;
162 else
163 if( name == "sizeparent" )
165 std::string sp;
166 getSizeParent( sp );
167 return sp;
169 else
170 if( name == "global_color" )
172 return toString( _ModulateGlobalColor );
174 else
175 if( name == "render_layer" )
177 return toString( _RenderLayer );
179 else
180 if( name == "avoid_resize_parent" )
182 return toString( _AvoidResizeParent );
184 else
186 nlwarning( "Invalid property '%s' queried for widget '%s'", name.c_str(), _Id.c_str() );
187 return "";
191 void CInterfaceElement::setProperty( const std::string &name, const std::string &value )
193 if( name == "id" )
195 setIdRecurse( stripId( value ) );
196 return;
198 else
199 if( name == "active" )
201 bool b;
202 if( fromString( value, b ) )
203 setActive( b );
204 return;
206 else
207 if( name == "x" )
209 sint32 x;
210 if( fromString( value, x ) )
211 setX( x );
212 return;
214 else
215 if( name == "y" )
217 sint32 y;
218 if( fromString( value, y ) )
219 setY( y );
220 return;
222 else
223 if( name == "w" )
225 sint32 w;
226 if( fromString( value, w ) )
227 setW( w );
228 return;
230 else
231 if( name == "h" )
233 sint32 h;
234 if( fromString( value, h ) )
235 setH( h );
236 return;
238 else
239 if( name == "posref" )
241 _PosRef = convertHotSpot( value.c_str() );
242 return;
244 else
245 if( name == "parentposref" )
247 _ParentPosRef = convertHotSpot( value.c_str() );
249 else
250 if( name == "sizeref" )
252 parseSizeRef( value.c_str() );
253 return;
255 if( name == "posparent" )
257 setPosParent( value );
258 return;
260 else
261 if( name == "sizeparent" )
263 setSizeParent( value );
264 return;
266 else
267 if( name == "global_color" )
269 bool b;
270 if( fromString( value, b ) )
271 setModulateGlobalColor( b );
272 return;
274 else
275 if( name == "render_layer" )
277 sint8 l;
278 if( fromString( value, l ) )
279 setRenderLayer( l );
280 return;
282 else
283 if( name == "avoid_resize_parent" )
285 bool b;
286 if( fromString( value, b ) )
287 setAvoidResizeParent( b );
288 return;
290 else
291 nlwarning( "Tried to set invalid property '%s' for widget '%s'", name.c_str(), _Id.c_str() );
294 xmlNodePtr CInterfaceElement::serialize( xmlNodePtr parentNode, const char *type ) const
296 xmlNodePtr node = xmlNewNode( NULL, BAD_CAST type );
297 if( node == NULL )
298 return NULL;
300 xmlAddChild( parentNode, node );
302 xmlNewProp( node, BAD_CAST "id", BAD_CAST stripId( getId() ).c_str() );
303 xmlNewProp( node, BAD_CAST "active", BAD_CAST toString( _Active ).c_str() );
304 xmlNewProp( node, BAD_CAST "x", BAD_CAST toString( _X ).c_str() );
305 xmlNewProp( node, BAD_CAST "y", BAD_CAST toString( _Y ).c_str() );
306 xmlNewProp( node, BAD_CAST "w", BAD_CAST toString( _W ).c_str() );
307 xmlNewProp( node, BAD_CAST "h", BAD_CAST toString( _H ).c_str() );
308 xmlNewProp( node, BAD_CAST "posref", BAD_CAST HotSpotCoupleToString( _ParentPosRef, _PosRef ).c_str() );
310 std::string pp;
311 getPosParent( pp );
312 xmlNewProp( node, BAD_CAST "posparent", BAD_CAST pp.c_str() );
313 xmlNewProp( node, BAD_CAST "sizeref", BAD_CAST getSizeRefAsString().c_str() );
314 getSizeParent( pp );
315 xmlNewProp( node, BAD_CAST "sizeparent", BAD_CAST pp.c_str() );
317 xmlNewProp( node, BAD_CAST "global_color", BAD_CAST toString( _ModulateGlobalColor ).c_str() );
318 xmlNewProp( node, BAD_CAST "render_layer", BAD_CAST toString( _RenderLayer ).c_str() );
319 xmlNewProp( node, BAD_CAST "avoid_resize_parent", BAD_CAST toString( _AvoidResizeParent ).c_str() );
321 return node;
324 // ------------------------------------------------------------------------------------------------
325 bool CInterfaceElement::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
327 // parse the basic properties
328 CXMLAutoPtr ptr((const char*) xmlGetProp( cur, (xmlChar*)"id" ));
329 if (ptr)
331 if (parentGroup)
333 _Id = ( (CInterfaceElement*)parentGroup )->_Id;
335 else
337 _Id ="ui";
339 _Id += ":"+ string((const char*)ptr);
341 else
343 nlinfo(" error no id in an element");
344 return false;
347 ptr = (char*) xmlGetProp( cur, (xmlChar*)"active" );
348 _Active = true;
349 if (ptr)
351 _Active = convertBool(ptr);
354 _Parent = parentGroup;
356 // parse location. If these properties are not specified, set them to 0
357 ptr = (char*) xmlGetProp( cur, (xmlChar*)"x" );
358 _X = 0;
359 if (ptr) fromString((const char*)ptr, _X);
361 ptr = (char*) xmlGetProp( cur, (xmlChar*)"y" );
362 _Y = 0;
363 if (ptr) fromString((const char*)ptr, _Y);
365 ptr = (char*) xmlGetProp( cur, (xmlChar*)"w" );
366 _W = 0;
367 if (parentGroup != NULL)
368 _W = parentGroup->getW();
369 if (ptr) fromString((const char*)ptr, _W);
371 ptr = (char*) xmlGetProp( cur, (xmlChar*)"h" );
372 _H = 0;
373 if (parentGroup != NULL)
374 _H = parentGroup->getH();
375 if (ptr) fromString((const char*)ptr, _H);
377 // snapping
378 // ptr = (char*) xmlGetProp( cur, (xmlChar*)"snap" );
379 // _Snap = 1;
380 // if (ptr)
381 // fromString((const char*)ptr, _Snap);
382 // if (_Snap <= 0)
383 // {
384 // parseError(parentGroup, "snap must be > 0" );
385 // return false;
386 // }
388 ptr = (char*) xmlGetProp( cur, (xmlChar*) "posref" );
389 _ParentPosRef = Hotspot_BL;
390 _PosRef = Hotspot_BL;
391 if (ptr)
393 convertHotSpotCouple(ptr.getDatas(), _ParentPosRef, _PosRef);
396 ptr = (char*) xmlGetProp( cur, (xmlChar*)"posparent" );
397 if (ptr)
399 parsePosParent( (const char*)ptr );
402 ptr = (char*) xmlGetProp( cur, (xmlChar*)"sizeparent" );
403 if (ptr)
405 parseSizeParent( (const char*)ptr );
408 ptr = (char*) xmlGetProp (cur, (xmlChar*)"sizeref");
409 _SizeRef = 0;
410 _SizeDivW = 10;
411 _SizeDivH = 10;
412 if (ptr)
414 parseSizeRef(ptr.getDatas());
417 // snapSize();
419 ptr= (char*) xmlGetProp (cur, (xmlChar*)"global_color");
420 if(ptr)
422 _ModulateGlobalColor= convertBool(ptr);
425 ptr= (char*) xmlGetProp (cur, (xmlChar*)"render_layer");
426 if(ptr) fromString((const char*)ptr, _RenderLayer);
428 ptr= (char*) xmlGetProp (cur, (xmlChar*)"avoid_resize_parent");
429 if(ptr) _AvoidResizeParent= convertBool(ptr);
431 return true;
435 // ------------------------------------------------------------------------------------------------
436 void CInterfaceElement::setSizeRef(const std::string &sizeref)
438 parseSizeRef(sizeref.c_str());
441 // ------------------------------------------------------------------------------------------------
442 std::string CInterfaceElement::getSizeRefAsString() const
444 return getSizeRefAsString( _SizeRef, _SizeDivW, _SizeDivH );
447 std::string CInterfaceElement::getSizeRefAsString( const sint32 &sizeRef, const sint32 &sizeDivW, sint32 const &sizeDivH ) const
449 std::string s;
450 if( ( sizeRef & 1 ) != 0 )
452 s += "w";
453 if( sizeDivW < 10 )
454 s += toString( sizeDivW );
457 if( ( _SizeRef & 2 ) != 0 )
459 s += "h";
460 if( sizeDivH < 10 )
461 s += toString( sizeDivH );
464 return s;
467 // ------------------------------------------------------------------------------------------------
468 void CInterfaceElement::parseSizeRef(const char *sizeRefStr)
470 parseSizeRef(sizeRefStr, _SizeRef, _SizeDivW, _SizeDivH);
474 // ------------------------------------------------------------------------------------------------
475 void CInterfaceElement::parseSizeRef(const char *sizeRefStr, sint32 &sizeRef, sint32 &sizeDivW, sint32 &sizeDivH)
477 nlassert(sizeRefStr);
479 sizeRef = 0;
480 sizeDivW = 10;
481 sizeDivH = 10;
482 sint32 nWhat = 0;
483 const char *seekPtr = sizeRefStr;
484 while (*seekPtr != 0)
486 if ((*seekPtr=='w')||(*seekPtr=='W'))
488 sizeRef |= 1;
489 nWhat = 1;
492 if ((*seekPtr=='h')||(*seekPtr=='H'))
494 sizeRef |= 2;
495 nWhat = 2;
498 if ((*seekPtr>='1')&&(*seekPtr<='9'))
500 if (nWhat != 0)
502 if (nWhat == 1)
503 sizeDivW = *seekPtr-'0';
504 if (nWhat == 2)
505 sizeDivH = *seekPtr-'0';
509 ++seekPtr;
513 // ------------------------------------------------------------------------------------------------
514 sint32 CInterfaceElement::getInnerWidth() const
516 return _WReal - _MarginLeft;
519 // ------------------------------------------------------------------------------------------------
520 void CInterfaceElement::updateCoords()
522 _XReal = _X;
523 _YReal = _Y;
524 _WReal = getW();
525 _HReal = getH();
527 CInterfaceElement *el = NULL;
529 // Modif Pos
531 if (_ParentPos != NULL)
532 el = _ParentPos;
533 else
534 el = _Parent;
536 if (el == NULL)
537 return;
539 _XReal += el->_XReal;
540 _YReal += el->_YReal;
542 THotSpot hsParent = _ParentPosRef;
543 if (hsParent & Hotspot_Mx)
544 _YReal += el->_HReal/2;
545 if (hsParent & Hotspot_Tx)
546 _YReal += el->_HReal;
547 if (hsParent & Hotspot_xM)
548 _XReal += el->_WReal/2;
549 if (hsParent & Hotspot_xR)
550 _XReal += el->_WReal;
552 // Modif Size
554 if (_ParentSize != NULL)
556 el = _ParentSize;
558 else
560 if (_ParentPos != NULL)
561 el = _ParentPos;
562 else
563 el = _Parent;
566 if (el == NULL)
567 return;
569 if (_SizeRef&1)
570 _WReal += _SizeDivW * el->_WReal / 10;
572 if (_SizeRef&2)
573 _HReal += _SizeDivH * el->_HReal / 10;
575 THotSpot hs = _PosRef;
576 if (hs & Hotspot_Mx)
577 _YReal -= _HReal/2;
578 if (hs & Hotspot_Tx)
579 _YReal -= _HReal;
580 if (hs & Hotspot_xM)
581 _XReal -= _WReal/2;
582 if (hs & Hotspot_xR)
583 _XReal -= _WReal;
587 // ------------------------------------------------------------------------------------------------
588 void CInterfaceElement::getCorner(sint32 &px, sint32 &py, THotSpot hs)
590 px = _XReal;
591 py = _YReal;
592 if (hs & 1) px += _WReal;
593 if (hs & 2) px += _WReal >> 1;
594 if (hs & 8) py += _HReal;
595 if (hs & 16) py += _HReal >> 1;
598 // ------------------------------------------------------------------------------------------------
599 void CInterfaceElement::move (sint32 dx, sint32 dy)
601 _X += dx;
602 _Y += dy;
603 invalidateCoords();
608 // ------------------------------------------------------------------------------------------------
609 /*void CInterfaceElement::resizeBR (sint32 sizeW, sint32 sizeH)
611 uint32 i = i / 0;
612 THotSpot hs = _PosRef;
614 sint32 dw = sizeW - _W;
615 sint32 dh = sizeH - _H;
617 sint32 snap = _Snap;
618 nlassert(snap > 0);
620 if (hs&8) // is top ?
622 sint32 newH = dh + _H;
623 if (snap > 1)
624 newH -= newH % snap;
625 _H = newH;
627 if (hs&32) // is bottom ?
629 sint32 newH = dh + _H;
630 if (snap > 1)
631 newH -= newH % snap;
632 _Y = _H - newH + _Y;
633 _H = newH;
636 if (hs&1) // is right ?
638 sint32 newW = dw + _W;
639 if (snap > 1)
640 newW -= newW % snap;
641 _X = newW - _W + _X;
642 _W = newW;
644 if (hs&4) // is left ?
646 sint32 newW = dw + _W;
647 if (snap > 1)
648 newW -= newW % snap;
649 _W = newW;
652 // DO NOT TREAT THE MIDDLE HOTSPOT CASE
654 invalidateCoords();
658 // ------------------------------------------------------------------------------------------------
659 /*void CInterfaceElement::snapSize()
661 sint32 snap = _Snap;
662 nlassert(snap > 0);
663 if (snap > 1)
665 _W = _W - (_W % snap);
666 _H = _H - (_H % snap);
671 // ------------------------------------------------------------------------------------------------
672 void CInterfaceElement::setW (sint32 w)
674 _W = w;
675 // sint32 snap = _Snap;
676 // nlassert(snap > 0);
677 // if (snap > 1)
678 // {
679 // _W = _W - (_W % snap);
680 // }
684 // ------------------------------------------------------------------------------------------------
685 void CInterfaceElement::setH (sint32 h)
687 _H = h;
688 // sint32 snap = _Snap;
689 // nlassert(snap > 0);
690 // if (snap > 1)
691 // {
692 // _H = _H - (_H % snap);
693 // }
697 // ------------------------------------------------------------------------------------------------
698 CInterfaceGroup* CInterfaceElement::getRootWindow ()
700 if (_Parent == NULL)
701 return NULL;
702 if (_Parent->getParent() == NULL)
703 return dynamic_cast<CInterfaceGroup*>(this);
704 return _Parent->getRootWindow();
707 // ------------------------------------------------------------------------------------------------
708 uint CInterfaceElement::getParentDepth() const
710 uint depth= 0;
711 CInterfaceGroup *parent= _Parent;
712 while(parent!=NULL)
714 parent= parent->getParent();
715 depth++;
717 return depth;
720 // ------------------------------------------------------------------------------------------------
721 bool CInterfaceElement::isActiveThroughParents() const
723 if(!getActive())
724 return false;
725 if(_Parent == NULL)
726 return false;
727 // is it the root window?
728 if (_Parent->getParent() == NULL)
729 // yes and getActive() is true => the element is visible!
730 return true;
731 else
732 return _Parent->isActiveThroughParents();
735 // ------------------------------------------------------------------------------------------------
736 void CInterfaceElement::relativeSInt64Read (CInterfaceProperty &rIP, const string &prop, const char *val,
737 const string &defVal)
739 if (val == NULL)
741 rIP.readSInt64 (defVal.c_str(), _Id+":"+prop);
743 else
745 if ( isdigit(*val) || *val=='-')
747 rIP.readSInt64 (val, _Id+":"+prop);
748 return;
751 sint32 decal = 0;
752 if (val[0] == ':')
753 decal = 1;
754 if (NLGUI::CDBManager::getInstance()->getDbProp(val+decal, false) != NULL)
756 rIP.readSInt64 (val+decal, _Id+":"+prop);
757 return;
759 else
761 string sTmp;
762 CInterfaceElement *pIEL = this;
764 while (pIEL != NULL)
766 sTmp = pIEL->getId()+":"+string(val+decal);
767 if (NLGUI::CDBManager::getInstance()->getDbProp(sTmp, false) != NULL)
769 rIP.readSInt64 (sTmp.c_str(), _Id+":"+prop);
770 return;
772 pIEL = pIEL->getParent();
775 rIP.readSInt64 (val+decal, _Id+":"+prop);
781 // ------------------------------------------------------------------------------------------------
782 void CInterfaceElement::relativeSInt32Read (CInterfaceProperty &rIP, const string &prop, const char *val,
783 const string &defVal)
785 if (val == NULL)
787 rIP.readSInt32 (defVal.c_str(), _Id+":"+prop);
789 else
791 if ( isdigit(*val) || *val=='-')
793 rIP.readSInt32 (val, _Id+":"+prop);
794 return;
797 sint32 decal = 0;
798 if (val[0] == ':')
799 decal = 1;
800 if (NLGUI::CDBManager::getInstance()->getDbProp(val+decal, false) != NULL)
802 rIP.readSInt32 (val+decal, _Id+":"+prop);
803 return;
805 else
807 string sTmp;
808 CInterfaceElement *pIEL = this;
810 while (pIEL != NULL)
812 sTmp = pIEL->getId()+":"+string(val+decal);
813 if (NLGUI::CDBManager::getInstance()->getDbProp(sTmp, false) != NULL)
815 rIP.readSInt32 (sTmp.c_str(), _Id+":"+prop);
816 return;
818 pIEL = pIEL->getParent();
821 rIP.readSInt32 (val+decal, _Id+":"+prop);
827 // ------------------------------------------------------------------------------------------------
828 void CInterfaceElement::relativeBoolRead (CInterfaceProperty &rIP, const string &prop, const char *val,
829 const string &defVal)
831 if (val == NULL)
833 rIP.readBool (defVal.c_str(), _Id+":"+prop);
835 else
837 sint32 decal = 0;
838 if (val[0] == ':')
839 decal = 1;
840 if (NLGUI::CDBManager::getInstance()->getDbProp(val+decal, false) != NULL)
842 rIP.readBool (val+decal, _Id+":"+prop);
843 return;
845 else
847 string sTmp;
848 CInterfaceElement *pIEL = this;
850 while (pIEL != NULL)
852 sTmp = pIEL->getId()+":"+string(val+decal);
853 if (NLGUI::CDBManager::getInstance()->getDbProp(sTmp, false) != NULL)
855 rIP.readBool (sTmp.c_str(), _Id+":"+prop);
856 return;
858 pIEL = pIEL->getParent();
861 rIP.readBool (val+decal, _Id+":"+prop);
867 // ------------------------------------------------------------------------------------------------
868 void CInterfaceElement::relativeRGBARead(CInterfaceProperty &rIP,const std::string &prop,const char *val,const std::string &defVal)
870 if (val == NULL)
872 rIP.readRGBA (defVal.c_str(), _Id+":"+prop);
874 else
876 if ( isdigit(*val) || *val=='-')
878 rIP.readRGBA (val, _Id+":"+prop);
879 return;
882 sint32 decal = 0;
883 if (val[0] == ':')
884 decal = 1;
885 if (NLGUI::CDBManager::getInstance()->getDbProp(val+decal, false) != NULL)
887 rIP.readRGBA (val+decal, _Id+":"+prop);
888 return;
890 else
892 string sTmp;
893 CInterfaceElement *pIEL = this;
895 while (pIEL != NULL)
897 sTmp = pIEL->getId()+":"+string(val+decal);
898 if (NLGUI::CDBManager::getInstance()->getDbProp(sTmp, false) != NULL)
900 rIP.readRGBA (sTmp.c_str(), _Id+":"+prop);
901 return;
903 pIEL = pIEL->getParent();
906 rIP.readRGBA (val+decal, _Id+":"+prop);
911 std::string CInterfaceElement::HotSpotToString( THotSpot spot )
913 switch( spot )
915 case Hotspot_TL:
916 return "TL";
918 case Hotspot_TM:
919 return "TM";
921 case Hotspot_TR:
922 return "TR";
924 case Hotspot_ML:
925 return "ML";
927 case Hotspot_MM:
928 return "MM";
930 case Hotspot_MR:
931 return "MR";
933 case Hotspot_BL:
934 return "BL";
936 case Hotspot_BM:
937 return "BM";
939 case Hotspot_BR:
940 return "BR";
942 default:
943 break;
946 return "";
949 std::string CInterfaceElement::HotSpotCoupleToString( THotSpot parentPosRef, THotSpot posRef )
951 std::string hs;
952 hs = HotSpotToString( parentPosRef );
953 hs += " ";
954 hs += HotSpotToString( posRef );
956 return hs;
959 // ------------------------------------------------------------------------------------------------
960 THotSpot CInterfaceElement::convertHotSpot (const char *ptr)
962 if ( !strnicmp(ptr,"TL",2) )
964 return Hotspot_TL;
966 else if ( !strnicmp(ptr,"TM",2) )
968 return Hotspot_TM;
970 else if ( !strnicmp(ptr,"TR",2) )
972 return Hotspot_TR;
974 else if ( !strnicmp(ptr,"ML",2) )
976 return Hotspot_ML;
978 else if ( !strnicmp(ptr,"MM",2) )
980 return Hotspot_MM;
982 else if ( !strnicmp(ptr,"MR",2) )
984 return Hotspot_MR;
986 else if ( !strnicmp(ptr,"BL",2) )
988 return Hotspot_BL;
990 else if ( !strnicmp(ptr,"BM",2) )
992 return Hotspot_BM;
994 else if ( !strnicmp(ptr,"BR",2) )
996 return Hotspot_BR;
998 else
999 return Hotspot_BL;
1002 // ------------------------------------------------------------------------------------------------
1003 void CInterfaceElement::convertHotSpotCouple (const char *ptr, THotSpot &parentPosRef, THotSpot &posRef)
1005 nlassert(ptr);
1007 // *** first hotspot
1008 // skip any space or tab
1009 while(*ptr=='\t' || *ptr==' ')
1010 ptr++;
1011 // convert first
1012 parentPosRef = convertHotSpot (ptr);
1014 // *** second hotspot
1015 // must be at least 2 letter and a space
1016 nlassert(strlen(ptr)>=3);
1017 ptr+=3;
1018 // skip any space or tab
1019 while(*ptr=='\t' || *ptr==' ')
1020 ptr++;
1021 // convert second
1022 posRef = convertHotSpot (ptr);
1025 // ------------------------------------------------------------------------------------------------
1026 NLMISC::CRGBA CInterfaceElement::convertColor (const char *ptr)
1028 return NLMISC::CRGBA::stringToRGBA(ptr);
1031 // ------------------------------------------------------------------------------------------------
1032 bool CInterfaceElement::convertBool (const char *ptr)
1034 return NLMISC::toBool(ptr);
1037 // ------------------------------------------------------------------------------------------------
1038 NLMISC::CVector CInterfaceElement::convertVector (const char *ptr)
1040 float x = 0.0f, y = 0.0f, z = 0.0f;
1041 sscanf (ptr, "%f %f %f", &x, &y, &z);
1042 return CVector(x,y,z);
1045 // ------------------------------------------------------------------------------------------------
1046 void CInterfaceElement::convertPixelsOrRatio(const char *ptr, sint32 &pixels, float &ratio)
1048 std::string value = ptr;
1049 if (!value.empty())
1051 if (value[value.size() - 1] == '%')
1053 value.resize(value.size() - 1);
1054 fromString(value, ratio);
1055 ratio /= 100.f;
1056 clamp(ratio, 0.f, 1.f);
1058 else
1060 fromString(value, pixels);
1066 // ------------------------------------------------------------------------------------------------
1067 void CInterfaceElement::addLink(CInterfaceLink *link)
1069 nlassert(link != NULL);
1070 if (!_Links)
1072 _Links = new TLinkVect;
1074 TLinkSmartPtr linkPtr(link);
1075 TLinkVect::const_iterator it = std::find(_Links->begin(), _Links->end(), linkPtr);
1076 if (it != _Links->end())
1078 // Link already appened : this can be the case when a link has several targets property that belong to the same element, in this case, one single ptr in the vector is enough.
1079 // nlwarning("Link added twice");
1081 else
1083 _Links->push_back(linkPtr);
1088 // ------------------------------------------------------------------------------------------------
1089 void CInterfaceElement::removeLink(CInterfaceLink *link)
1091 nlassert(link != NULL);
1092 if (!_Links)
1094 nlwarning("No link added");
1095 return;
1097 TLinkVect::iterator it = std::find(_Links->begin(), _Links->end(), TLinkSmartPtr(link));
1098 if (it == _Links->end())
1100 nlwarning("Unknown link");
1101 return;
1103 _Links->erase(it); // kill the smart ptr, maybe deleting the link.
1104 if (_Links->empty())
1106 delete _Links;
1107 _Links = NULL;
1112 // ------------------------------------------------------------------------------------------------
1113 CInterfaceElement* CInterfaceElement::getMasterGroup() const
1115 if(getParent()==NULL)
1116 return const_cast<CInterfaceElement*>(this);
1117 else
1118 return getParent()->getMasterGroup();
1121 // ------------------------------------------------------------------------------------------------
1122 CInterfaceGroup* CInterfaceElement::getParentContainer()
1124 CInterfaceElement *parent = this;
1125 while (parent)
1127 CInterfaceGroup *gc = dynamic_cast< CInterfaceGroup* >( parent );
1128 if( ( gc != NULL ) && gc->isGroupContainer() )
1129 return gc;
1131 parent = parent->getParent();
1133 return NULL;
1136 // ------------------------------------------------------------------------------------------------
1137 bool CInterfaceElement::isIn(sint x, sint y) const
1139 return (x >= _XReal) &&
1140 (x < (_XReal + _WReal))&&
1141 (y > _YReal) &&
1142 (y <= (_YReal+ _HReal));
1145 // ------------------------------------------------------------------------------------------------
1146 bool CInterfaceElement::isIn(sint x, sint y, uint width, uint height) const
1148 return (x + (sint) width) >= _XReal &&
1149 (y + (sint) height) > _YReal &&
1150 x < (_XReal + _WReal) &&
1151 y <= (_YReal + _HReal);
1154 // ------------------------------------------------------------------------------------------------
1155 bool CInterfaceElement::isIn(const CInterfaceElement &other) const
1157 return isIn(other._XReal, other._YReal, other._WReal, other._HReal);
1160 // ------------------------------------------------------------------------------------------------
1161 void CInterfaceElement::setActive (bool state)
1163 if (_Active != state)
1165 _Active = state;
1166 invalidateCoords();
1167 // force invalidate CViewText/CGroupTable inner elements
1168 invalidateContent();
1173 // ***************************************************************************
1174 void CInterfaceElement::invalidateCoords(uint8 numPass)
1176 // Get the "Root Group" ie the 1st son of the master group of us (eg "ui:interface:rootgroup" )
1177 CInterfaceGroup *parent= getParent();
1178 // if our parent is NULL, then we are the master group (error!)
1179 if(parent==NULL)
1180 return;
1181 // if our grandfather is NULL, then our father is the Master Group => we are the "Root group"
1182 if(parent->getParent()==NULL)
1184 parent= dynamic_cast<CInterfaceGroup*>(this);
1186 else
1188 // parent is the root group when is grandFather is NULL
1189 while( parent->getParent()->getParent()!=NULL )
1191 parent= parent->getParent();
1195 // invalidate the "root group"
1196 if(parent)
1198 uint8 &val= static_cast<CInterfaceElement*>(parent)->_InvalidCoords;
1199 val= max(val, numPass);
1204 // ***************************************************************************
1205 void CInterfaceElement::checkCoords()
1209 // ***************************************************************************
1210 bool CInterfaceElement::isSonOf(const CInterfaceElement *other) const
1212 const CInterfaceElement *currElem = this;
1215 if (currElem == other) return true;
1216 currElem = currElem->_Parent;
1218 while (currElem);
1219 return false;
1222 // ***************************************************************************
1223 void CInterfaceElement::resetInvalidCoords()
1225 _InvalidCoords= 0;
1228 // ***************************************************************************
1229 void CInterfaceElement::updateAllLinks()
1231 if (_Links)
1233 for(TLinkVect::iterator it = _Links->begin(); it != _Links->end(); ++it)
1235 (*it)->update();
1240 // ***************************************************************************
1241 void CInterfaceElement::copyOptionFrom(const CInterfaceElement &other)
1243 _Active = other._Active;
1244 _InvalidCoords = other._InvalidCoords;
1245 _XReal = other._XReal;
1246 _YReal = other._YReal;
1247 _WReal = other._WReal;
1248 _HReal = other._HReal;
1249 _X = other._X;
1250 _Y = other._Y;
1251 _XReal = other._XReal;
1252 _YReal = other._YReal;
1253 _PosRef = other._PosRef;
1254 _ParentPosRef = other._ParentPosRef;
1255 _SizeRef = other._SizeRef;
1256 _SizeDivW = other._SizeDivW;
1257 _SizeDivH = other._SizeDivH;
1258 _ModulateGlobalColor = other._ModulateGlobalColor;
1259 _RenderLayer = other._RenderLayer;
1263 // ***************************************************************************
1264 void CInterfaceElement::center()
1266 // center the pc
1267 CViewRenderer &vr = *CViewRenderer::getInstance();
1268 uint32 sw, sh;
1269 vr.getScreenSize(sw, sh);
1270 setX(sw / 2 - getWReal() / 2);
1271 setY(sh / 2 + getHReal() / 2);
1274 // ***************************************************************************
1275 void CInterfaceElement::renderWiredQuads(TRenderWired type, const std::string &uiFilter)
1277 CCtrlBase *ctrlBase = dynamic_cast<CCtrlBase*>(this);
1278 CInterfaceGroup *groupBase = dynamic_cast<CInterfaceGroup*>(this);
1279 if (
1280 ((type == RenderView) && (ctrlBase==NULL) && (groupBase==NULL)) ||
1281 ((type == RenderCtrl) && (ctrlBase!=NULL) && (groupBase==NULL)) ||
1282 ((type == RenderGroup) && (ctrlBase!=NULL) && (groupBase!=NULL)))
1284 if (!_Active) return;
1285 // if there is an uiFilter, the end of _Id must match it
1286 if (!uiFilter.empty() && (uiFilter.size()>_Id.size() ||
1287 _Id.compare(_Id.size()-uiFilter.size(),string::npos,uiFilter)!=0)
1289 return;
1290 CViewRenderer &vr = *CViewRenderer::getInstance();
1291 vr.drawWiredQuad(_XReal, _YReal, _WReal, _HReal);
1292 drawHotSpot(_PosRef, CRGBA::Red);
1293 if (_Parent) _Parent->drawHotSpot(_ParentPosRef, CRGBA::Blue);
1297 // ***************************************************************************
1298 void CInterfaceElement::drawHotSpot(THotSpot hs, CRGBA col)
1300 const sint32 radius = 2;
1301 sint32 px, py;
1303 if (hs & Hotspot_Bx)
1305 py = _YReal + radius;
1307 else if (hs & Hotspot_Mx)
1309 py = _YReal + _HReal / 2;
1311 else
1313 py = _YReal + _HReal - radius;
1316 if (hs & Hotspot_xL)
1318 px = _XReal + radius;
1320 else if (hs & Hotspot_xM)
1322 px = _XReal + _WReal / 2;
1324 else
1326 px = _XReal + _WReal - radius;
1328 CViewRenderer &vr = *CViewRenderer::getInstance();
1329 vr.drawFilledQuad(px - radius, py - radius, radius * 2, radius * 2, col);
1333 void CInterfaceElement::drawHighlight()
1335 CViewRenderer::getInstance()->drawWiredQuad( _XReal, _YReal, _WReal, _HReal );
1338 // ***************************************************************************
1339 void CInterfaceElement::invalidateContent()
1341 CInterfaceElement *elm = this;
1342 while (elm)
1344 // Call back
1345 elm->onInvalidateContent();
1347 // Get the parent
1348 elm = elm->getParent();
1352 // ***************************************************************************
1353 void CInterfaceElement::visit(CInterfaceElementVisitor *visitor)
1355 nlassert(visitor);
1356 visitor->visit(this);
1359 // ***************************************************************************
1360 void CInterfaceElement::serialConfig(NLMISC::IStream &f)
1362 if (f.isReading())
1364 throw NLMISC::ENewerStream(f);
1365 nlassert(0);
1369 // ***************************************************************************
1370 void CInterfaceElement::onFrameUpdateWindowPos(sint dx, sint dy)
1372 _XReal+= dx;
1373 _YReal+= dy;
1376 // ***************************************************************************
1377 void CInterfaceElement::dummySet(sint32 /* value */)
1379 nlwarning("Element can't be written.");
1382 // ***************************************************************************
1383 void CInterfaceElement::dummySet(const std::string &/* value */)
1385 nlwarning("Element can't be written.");
1388 // ***************************************************************************
1389 int CInterfaceElement::luaUpdateCoords(CLuaState &ls)
1391 CLuaIHM::checkArgCount(ls, "updateCoords", 0);
1392 updateCoords();
1393 return 0;
1396 // ***************************************************************************
1397 int CInterfaceElement::luaInvalidateCoords(CLuaState &ls)
1399 CLuaIHM::checkArgCount(ls, "updateCoords", 0);
1400 invalidateCoords();
1401 return 0;
1404 // ***************************************************************************
1405 int CInterfaceElement::luaInvalidateContent(CLuaState &ls)
1407 CLuaIHM::checkArgCount(ls, "invalidateContent", 0);
1408 invalidateContent();
1409 return 0;
1412 // ***************************************************************************
1413 int CInterfaceElement::luaCenter(CLuaState &ls)
1415 CLuaIHM::checkArgCount(ls, "center", 0);
1416 center();
1417 return 0;
1420 // ***************************************************************************
1421 int CInterfaceElement::luaSetPosRef(CLuaState &ls)
1423 CLuaIHM::checkArgCount(ls, "setPosRef", 1);
1424 CLuaIHM::check(ls, ls.isString(1), "setPosRef() requires a string in param 1");
1426 // get hotspot
1427 THotSpot newParentPosRef, newPosRef;
1428 convertHotSpotCouple(ls.toString(1), newParentPosRef, newPosRef);
1430 // if different from current, set,a nd invalidate coords
1431 if(newParentPosRef!=getParentPosRef() || newPosRef!=getPosRef())
1433 setParentPosRef(newParentPosRef);
1434 setPosRef(newPosRef);
1435 invalidateCoords();
1438 return 0;
1441 // ***************************************************************************
1442 int CInterfaceElement::luaSetParentPos(CLuaState &ls)
1444 CLuaIHM::checkArgCount(ls, "setParentPos", 1);
1445 CInterfaceElement *ie = CLuaIHM::getUIOnStack(ls, 1);
1446 if(ie)
1448 setParentPos(ie);
1450 return 0;
1455 // ***************************************************************************
1456 CInterfaceElement *CInterfaceElement::clone()
1458 NLMISC::CMemStream dupStream;
1459 nlassert(!dupStream.isReading());
1460 CInterfaceGroup *oldParent = _Parent;
1461 _Parent = NULL;
1462 CInterfaceElement *oldParentPos = _ParentPos;
1463 CInterfaceElement *oldParentSize = _ParentSize;
1464 if (_ParentPos == oldParent) _ParentPos = NULL;
1465 if (_ParentSize == oldParent) _ParentSize = NULL;
1466 CInterfaceElement *begunThisCloneWarHas = NULL;
1469 if (dupStream.isReading())
1471 dupStream.invert();
1473 CInterfaceElement *self = this;
1474 dupStream.serialPolyPtr(self);
1475 std::vector<uint8> datas(dupStream.length());
1476 std::copy(dupStream.buffer(), dupStream.buffer() + dupStream.length(), datas.begin());
1477 dupStream.resetPtrTable();
1478 dupStream.invert();
1479 dupStream.fill(&datas[0], (uint32)datas.size());
1480 dupStream.serialPolyPtr(begunThisCloneWarHas);
1482 catch(const NLMISC::EStream &)
1484 // no-op -> caller has to handle the failure because NULL will be returned
1487 _Parent = oldParent;
1488 _ParentPos = oldParentPos;
1489 _ParentSize = oldParentSize;
1491 return begunThisCloneWarHas;
1494 // ***************************************************************************
1495 void CInterfaceElement::serial(NLMISC::IStream &f)
1497 f.serialPolyPtr(_Parent);
1498 f.serial(_Id);
1499 f.serial(_Active);
1500 f.serial(_InvalidCoords);
1501 f.serial(_XReal, _YReal, _WReal, _HReal);
1502 f.serial(_X, _Y, _W, _H);
1503 f.serialEnum(_PosRef);
1504 f.serialEnum(_ParentPosRef);
1505 _ParentPos.serialPolyPtr(f);
1506 f.serial(_SizeRef);
1507 f.serial(_SizeDivW, _SizeDivH);
1508 _ParentSize.serialPolyPtr(f);
1509 f.serial(_ModulateGlobalColor);
1510 f.serial(_RenderLayer);
1511 f.serial(_AvoidResizeParent);
1512 nlassert(_Links == NULL); // not supported
1516 // ***************************************************************************
1517 void CInterfaceElement::serialAH(NLMISC::IStream &f, IActionHandler *&ah)
1519 std::string ahName;
1520 if (f.isReading())
1522 f.serial(ahName);
1523 ah = CAHManager::getInstance()->getActionHandler(ahName);
1525 else
1527 ahName = CAHManager::getInstance()->getActionHandlerName(ah);
1528 f.serial(ahName);
1533 bool CInterfaceElement::isInGroup( CInterfaceGroup *group )
1535 CInterfaceGroup *parent = getParent();
1536 while( parent != NULL )
1538 if( parent == group )
1539 return true;
1540 else
1541 parent = parent->getParent();
1543 return false;
1546 void CInterfaceElement::parsePosParent( const std::string &id )
1548 CInterfaceElement *p = getParent();
1550 if( ( id == "parent" ) || ( id.empty() ) )
1552 setParentPos( p );
1553 return;
1556 std::string ppId;
1558 if( p != NULL )
1559 ppId = p->getId() + ":" + id;
1560 else
1561 ppId = std::string( "ui:" ) + id;
1563 CWidgetManager::getInstance()->getParser()->addParentPositionAssociation( this, ppId );
1566 void CInterfaceElement::setPosParent( const std::string &id )
1568 // Parent or empty id simply means the group parent
1569 if( ( id == "parent" ) || ( id.empty() ) )
1571 setParentPos( getParent() );
1572 return;
1575 CInterfaceElement *pp = NULL;
1577 // Check if it's a short Id
1578 std::string::size_type idx = id.find( "ui:" );
1579 if( idx == std::string::npos )
1581 // If it is, find the widget in the parent group and set as posparent
1582 CInterfaceGroup *p = getParent();
1583 if( p != NULL )
1585 pp = p->findFromShortId( id );
1588 else
1590 // If it is not, find using the widgetmanager
1591 // TODO: refactor, shouldn't use a singleton
1592 pp = CWidgetManager::getInstance()->getElementFromId( id );
1595 if( pp != NULL )
1596 setParentPos( pp );
1600 void CInterfaceElement::getPosParent( std::string &id ) const
1603 // If there's no pos parent set, then the parent group is the pos parent
1604 if( getParentPos() == NULL )
1606 id = "parent";
1607 return;
1610 // If pos parent and parent are the same then ofc the parent group is the pos parent...
1611 CInterfaceElement *p = getParent();
1612 if( getParentPos() == p )
1614 id = "parent";
1615 return;
1618 // If parent is in the same group, use the short id
1619 p = getParentPos();
1620 if( p->isInGroup( getParent() ) )
1622 id = p->getShortId();
1623 return;
1626 // Otherwise use the full id
1627 id = p->getId();
1630 void CInterfaceElement::parseSizeParent( const std::string &id )
1632 CInterfaceElement *p = getParent();
1634 if( ( id == "parent" ) || ( id.empty() ) )
1636 setParentSize( p );
1637 return;
1640 std::string spId;
1642 if( p != NULL )
1643 spId = p->getId() + ":" + id;
1644 else
1645 spId = std::string( "ui:" ) + id;
1647 CWidgetManager::getInstance()->getParser()->addParentSizeAssociation( this, spId );
1650 void CInterfaceElement::setSizeParent( const std::string &id )
1652 // Parent or empty id simply means the group parent
1653 if( ( id == "parent" ) || ( id.empty() ) )
1655 setParentSize( getParent() );
1656 return;
1659 CInterfaceElement *pp = NULL;
1661 // Check if it's a short Id
1662 std::string::size_type idx = id.find( "ui:" );
1663 if( idx == std::string::npos )
1665 // If it is, find the widget in the parent group and set as posparent
1666 CInterfaceGroup *p = getParent();
1667 if( p != NULL )
1669 pp = p->findFromShortId( id );
1672 else
1674 // If it is not, find using the widgetmanager
1675 // TODO: refactor, shouldn't use a singleton
1676 pp = CWidgetManager::getInstance()->getElementFromId( id );
1679 if( pp != NULL )
1680 setParentSize( pp );
1683 void CInterfaceElement::getSizeParent( std::string &id ) const
1685 CInterfaceElement *p = getParentSize();
1687 // If there's no parent set then the size parent is the parent
1688 if( p == NULL )
1690 id = "parent";
1691 return;
1694 // If the size parent is the same as the group parent, then the size parent is the parent ofc
1695 if( p == getParent() )
1697 id = "parent";
1698 return;
1701 // If the size parent is in the parent group, use the short Id
1702 if( p->isInGroup( getParent() ) )
1704 id = p->getShortId();
1705 return;
1708 // Otherwise use the full Id
1709 id = p->getId();
1712 void CInterfaceElement::registerDeletionWatcher( IDeletionWatcher *watcher )
1714 std::vector< IDeletionWatcher* >::iterator itr
1715 = std::find( deletionWatchers.begin(), deletionWatchers.end(), watcher );
1716 // Already registered
1717 if( itr != deletionWatchers.end() )
1718 return;
1719 deletionWatchers.push_back( watcher );
1722 void CInterfaceElement::unregisterDeletionWatcher( IDeletionWatcher *watcher )
1724 std::vector< IDeletionWatcher* >::iterator itr
1725 = std::find( deletionWatchers.begin(), deletionWatchers.end(), watcher );
1726 // Not registered
1727 if( itr == deletionWatchers.end() )
1728 return;
1729 deletionWatchers.erase( itr );
1732 void CInterfaceElement::notifyDeletionWatchers()
1734 std::vector< IDeletionWatcher* >::iterator itr = deletionWatchers.begin();
1735 while( itr != deletionWatchers.end() )
1737 (*itr)->onDeleted( _Id );
1738 ++itr;
1742 void CInterfaceElement::getHSCoords( const THotSpot &hs, sint32 &x, sint32 &y ) const
1744 x = _XReal;
1745 y = _YReal;
1747 if( ( hs & Hotspot_Mx ) != 0 )
1748 y += _HReal / 2;
1749 else
1750 if( ( hs & Hotspot_Tx ) != 0 )
1751 y += _HReal;
1754 if( ( hs & Hotspot_xM ) != 0 )
1755 x += _WReal / 2;
1756 else
1757 if( ( hs & Hotspot_xR ) != 0 )
1758 x += _WReal;
1761 void CInterfaceElement::getClosestHotSpot( const CInterfaceElement *other, THotSpot &hs )
1763 /// Iterate over the following hotspots, calculate the distance and store the closest
1766 static THotSpot hslist[] =
1768 Hotspot_BL,
1769 Hotspot_BR,
1770 Hotspot_MM,
1771 Hotspot_TL,
1772 Hotspot_TR
1775 int c = sizeof( hslist ) / sizeof( THotSpot );
1777 int x,y,ox,oy,vx,vy;
1778 float d;
1779 float closestd = 9999999.0f;
1780 THotSpot closestHS = Hotspot_TR;
1782 for( int i = 0; i < c; i++ )
1784 other->getHSCoords( hslist[ i ], ox, oy );
1785 getHSCoords( hslist[ i ], x, y );
1787 // Make a vector between the two hotspots
1788 vx = x - ox;
1789 vy = y - oy;
1791 // Calculate length
1792 d = sqrt( pow( vx, 2.0f ) + pow( vy, 2.0f ) );
1794 // If these hotspots are the closest, store the hotspot
1795 if( d < closestd )
1797 closestd = d;
1798 closestHS = hslist[ i ];
1802 hs = closestHS;
1805 void CInterfaceElement::alignTo( CInterfaceElement *other )
1807 if( other == this )
1808 return;
1810 // Check which hotspot is the closest
1811 THotSpot hs;
1812 other->getClosestHotSpot( this, hs );
1814 // Get the hotspot coordinates
1815 sint32 x, y, ox, oy;
1816 getHSCoords( hs, x, y );
1817 other->getHSCoords( hs, ox, oy );
1819 // Calculate the difference between the hotspot we found and our current position,
1820 sint32 dx = ox - x;
1821 sint32 dy = oy - y;
1823 // This difference is our offset, so we remain in the same position
1824 setX( -1 * dx );
1825 setY( -1 * dy );
1827 setPosRef( hs );
1828 setParentPosRef( hs );
1830 invalidateCoords();
1833 void CInterfaceElement::onWidgetDeleted( CInterfaceElement *e )
1835 if( e == getParentPos() )
1836 setParentPos( NULL );
1837 if( e == getParentSize() )
1838 setParentSize( NULL );
1841 CStringMapper* CStringShared::_UIStringMapper = NULL;
1844 void CStringShared::createStringMapper()
1846 if( _UIStringMapper == NULL )
1847 _UIStringMapper = CStringMapper::createLocalMapper();
1850 void CStringShared::deleteStringMapper()
1852 delete _UIStringMapper;