1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 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 "libxml/globals.h"
24 #include "nel/misc/debug.h"
25 #include "nel/misc/xml_auto_ptr.h"
26 #include "nel/gui/lua_ihm.h"
27 #include "nel/gui/ctrl_base.h"
28 #include "nel/gui/interface_group.h"
29 #include "nel/gui/widget_manager.h"
30 #include "nel/misc/i18n.h"
32 using namespace NLMISC
;
40 std::map
< std::string
, std::map
< std::string
, std::string
> > CCtrlBase::AHCache
;
42 // ***************************************************************************
43 CCtrlBase::~CCtrlBase()
45 CWidgetManager::getInstance()->removeRefOnCtrl (this);
48 // ***************************************************************************
49 bool CCtrlBase::handleEvent(const NLGUI::CEventDescriptor
&event
)
51 if( CViewBase::handleEvent( event
) )
54 if (event
.getType() == NLGUI::CEventDescriptor::system
)
56 NLGUI::CEventDescriptorSystem
&eds
= (NLGUI::CEventDescriptorSystem
&)event
;
57 if (eds
.getEventTypeExtended() == NLGUI::CEventDescriptorSystem::activecalledonparent
)
59 if (!((NLGUI::CEventDescriptorActiveCalledOnParent
&) eds
).getActive())
61 // the mouse capture should be lost when the ctrl is hidden
62 if (CWidgetManager::getInstance()->getCapturePointerLeft() == this)
64 CWidgetManager::getInstance()->setCapturePointerLeft(NULL
);
66 if (CWidgetManager::getInstance()->getCapturePointerRight() == this)
68 CWidgetManager::getInstance()->setCapturePointerRight(NULL
);
70 // NB : don't call return here because derived class may be interested
71 // in handling event more speciffically
78 std::string
CCtrlBase::tooltipParentToString( TToolTipParentType type
)
101 CCtrlBase::TToolTipParentType
CCtrlBase::stringToToolTipParent( const std::string
&str
)
103 std::string s
= toLowerAscii( str
);
112 return TTSpecialWindow
;
117 // ***************************************************************************
118 bool CCtrlBase::parse (xmlNodePtr cur
, CInterfaceGroup
*parentGroup
)
120 if(!CViewBase::parse(cur
, parentGroup
))
125 // get static toolTip
126 prop
= (char *)xmlGetProp(cur
, (xmlChar
*)"tooltip_i18n");
127 if ((bool)prop
&& strlen((const char *)prop
) > 0)
129 // Force I18N tooltip
131 _ContextHelp
= CI18N::get((const char *)prop
);
133 _ContextHelp
= (const char *)prop
;
137 // get static toolTip
138 prop
= (char *)xmlGetProp(cur
, (xmlChar
*)"tooltip");
141 if (!editorMode
&& NLMISC::startsWith((const char *)prop
, "ui"))
142 _ContextHelp
= CI18N::get((const char *)prop
);
144 _ContextHelp
= (const char *)prop
;
148 // get dynamic toolTip ActionHandler
149 prop
= (char*) xmlGetProp( cur
, (xmlChar
*)"on_tooltip" );
152 _OnContextHelp
= (const char*)prop
;
154 prop
= (char*) xmlGetProp( cur
, (xmlChar
*)"on_tooltip_params" );
157 _OnContextHelpParams
= (const char*)prop
;
161 prop
= (char*) xmlGetProp( cur
, (xmlChar
*)"tooltip_parent" );
162 _ToolTipParent
= TTCtrl
;
165 _ToolTipParent
= stringToToolTipParent( std::string( (const char*)prop
) );
168 // Tooltip special parent
169 prop
= (char*) xmlGetProp( cur
, (xmlChar
*)"tooltip_special_parent" );
170 _ToolTipSpecialParent
= CStringShared();
173 _ToolTipSpecialParent
= (const char*)prop
;
177 THotSpot tmpParentHS
, tmpChildHS
;
178 prop
= (char*) xmlGetProp( cur
, (xmlChar
*)"tooltip_posref" );
179 convertTooltipHotSpot(prop
, tmpParentHS
, tmpChildHS
);
180 _ToolTipParentPosRef
= tmpParentHS
;
181 _ToolTipPosRef
= tmpChildHS
;
183 // Alternative tooltip posref : this one will be chosen
184 prop
= (char*) xmlGetProp( cur
, (xmlChar
*)"tooltip_posref_alt" );
185 convertTooltipHotSpot(prop
, tmpParentHS
, tmpChildHS
);
186 _ToolTipParentPosRefAlt
= tmpParentHS
;
187 _ToolTipPosRefAlt
= tmpChildHS
;
190 prop
= (char*) xmlGetProp( cur
, (xmlChar
*)"instant_help");
191 _ToolTipInstant
= true;
192 if (prop
) _ToolTipInstant
= convertBool(prop
);
197 std::string
CCtrlBase::getProperty( const std::string
&name
) const
199 if( name
== "tooltip" )
204 if( name
== "tooltip_i18n" )
209 if( name
== "on_tooltip" )
211 return _OnContextHelp
.toString();
214 if( name
== "on_tooltip_params" )
216 return _OnContextHelpParams
.toString();
219 if( name
== "tooltip_parent" )
221 return tooltipParentToString( _ToolTipParent
);
224 if( name
== "tooltip_special_parent" )
226 return _ToolTipSpecialParent
.toString();
229 if( name
== "tooltip_posref" )
231 return TooltipHotSpotToString( _ToolTipPosRef
);
234 if( name
== "tooltip_parent_posref" )
236 return TooltipHotSpotToString( _ToolTipParentPosRef
);
239 if( name
== "tooltip_posref_alt" )
241 return TooltipHotSpotToString( _ToolTipPosRefAlt
);
244 if( name
== "tooltip_parent_posref_alt" )
246 return TooltipHotSpotToString( _ToolTipParentPosRefAlt
);
249 if( name
== "instant_help" )
251 return toString( _ToolTipInstant
);
254 return CInterfaceElement::getProperty( name
);
258 void CCtrlBase::setProperty( const std::string
&name
, const std::string
&value
)
260 if( name
== "tooltip" )
262 if (!editorMode
&& NLMISC::startsWith(value
, "ui"))
263 _ContextHelp
= CI18N::get(value
);
265 _ContextHelp
= value
;
269 if( name
== "tooltip_i18n" )
272 _ContextHelp
= CI18N::get(value
);
274 _ContextHelp
= value
;
278 if( name
== "on_tooltip" )
280 _OnContextHelp
= value
;
284 if( name
== "on_tooltip_params" )
286 _OnContextHelpParams
= value
;
290 if( name
== "tooltip_parent" )
292 _ToolTipParent
= stringToToolTipParent( value
);
296 if( name
== "tooltip_special_parent" )
298 _ToolTipSpecialParent
= value
;
302 if( name
== "tooltip_posref" )
305 convertTooltipHotSpot( value
.c_str(), HS
);
308 // When auto is set, both of them need to be auto
309 if( _ToolTipPosRef
== Hotspot_TTAuto
)
310 _ToolTipParentPosRef
= Hotspot_TTAuto
;
312 if( _ToolTipParentPosRef
== Hotspot_TTAuto
)
313 _ToolTipParentPosRef
= _ToolTipPosRef
;
318 if( name
== "tooltip_parent_posref" )
321 convertTooltipHotSpot( value
.c_str(), HS
);
322 _ToolTipParentPosRef
= HS
;
324 // When auto is set, both of them need to be auto
325 if( _ToolTipParentPosRef
== Hotspot_TTAuto
)
326 _ToolTipPosRef
= Hotspot_TTAuto
;
328 if( _ToolTipPosRef
== Hotspot_TTAuto
)
329 _ToolTipPosRef
= _ToolTipParentPosRef
;
334 if( name
== "tooltip_posref_alt" )
337 convertTooltipHotSpot( value
.c_str(), HS
);
338 _ToolTipPosRefAlt
= HS
;
340 // When auto is set, both of them need to be auto
341 if( _ToolTipPosRefAlt
== Hotspot_TTAuto
)
342 _ToolTipParentPosRefAlt
= Hotspot_TTAuto
;
344 if( _ToolTipParentPosRefAlt
== Hotspot_TTAuto
)
345 _ToolTipPosRefAlt
= _ToolTipParentPosRefAlt
;
350 if( name
== "tooltip_parent_posref_alt" )
353 convertTooltipHotSpot( value
.c_str(), HS
);
354 _ToolTipParentPosRefAlt
= HS
;
356 // When auto is set, both of them need to be auto
357 if( _ToolTipParentPosRefAlt
== Hotspot_TTAuto
)
358 _ToolTipPosRefAlt
= Hotspot_TTAuto
;
360 if( _ToolTipPosRefAlt
== Hotspot_TTAuto
)
361 _ToolTipPosRefAlt
= _ToolTipParentPosRefAlt
;
366 if( name
== "instant_help" )
369 if( fromString( value
, b
) )
374 CInterfaceElement::setProperty( name
, value
);
378 xmlNodePtr
CCtrlBase::serialize( xmlNodePtr parentNode
, const char *type
) const
381 CInterfaceElement::serialize( parentNode
, type
);
386 xmlNewProp( node
, BAD_CAST
"tooltip", BAD_CAST _ContextHelp
.c_str() );
387 xmlNewProp( node
, BAD_CAST
"tooltip_i18n", BAD_CAST _ContextHelp
.c_str() );
388 xmlNewProp( node
, BAD_CAST
"on_tooltip", BAD_CAST _OnContextHelp
.toString().c_str() );
389 xmlNewProp( node
, BAD_CAST
"on_tooltip_params", BAD_CAST _OnContextHelpParams
.toString().c_str() );
390 xmlNewProp( node
, BAD_CAST
"tooltip_parent", BAD_CAST
tooltipParentToString( _ToolTipParent
).c_str() );
391 xmlNewProp( node
, BAD_CAST
"tooltip_special_parent", BAD_CAST _ToolTipSpecialParent
.toString().c_str() );
393 xmlNewProp( node
, BAD_CAST
"tooltip_posref",
394 BAD_CAST
TooltipHotSpotToString( _ToolTipParentPosRef
, _ToolTipPosRef
).c_str() );
396 xmlNewProp( node
, BAD_CAST
"tooltip_posref_alt",
397 BAD_CAST
TooltipHotSpotToString( _ToolTipParentPosRefAlt
, _ToolTipPosRefAlt
).c_str() );
399 xmlNewProp( node
, BAD_CAST
"instant_help", BAD_CAST
toString( _ToolTipInstant
).c_str() );
404 // ***************************************************************************
405 void CCtrlBase::convertTooltipHotSpot(const char *prop
, THotSpot
&parentHS
, THotSpot
&childHS
)
407 parentHS
= Hotspot_TTAuto
;
408 childHS
= Hotspot_TTAuto
;
411 const char *ptr
= (const char*)prop
;
412 if(stricmp(ptr
, "auto")==0)
414 parentHS
= Hotspot_TTAuto
;
415 childHS
= Hotspot_TTAuto
;
418 else if(strlen(ptr
)>=5)
420 THotSpot parentPosRef
;
422 CInterfaceElement::convertHotSpotCouple(ptr
, parentPosRef
, posRef
);
423 parentHS
= parentPosRef
;
429 void CCtrlBase::convertTooltipHotSpot(const char *prop
, THotSpot
&HS
)
433 const char *ptr
= (const char*)prop
;
434 if(stricmp(ptr
, "auto")==0)
438 else if(strlen(ptr
)==2)
440 HS
= convertHotSpot(ptr
);
445 std::string
CCtrlBase::TooltipHotSpotToString( THotSpot parent
, THotSpot child
)
449 if( ( parent
== Hotspot_TTAuto
) && ( child
== Hotspot_TTAuto
) )
455 s
= CInterfaceElement::HotSpotToString( parent
);
457 s
+= CInterfaceElement::HotSpotToString( child
);
463 std::string
CCtrlBase::TooltipHotSpotToString( THotSpot HS
)
466 if( HS
== Hotspot_TTAuto
)
472 s
= HotSpotToString( HS
);
477 // ***************************************************************************
478 bool CCtrlBase::emptyContextHelp() const
481 getContextHelp(help
);
482 std::string sTmp
= _OnContextHelp
;
483 return help
.empty() && sTmp
.empty();
486 // ***************************************************************************
487 void CCtrlBase::visit(CInterfaceElementVisitor
*visitor
)
490 visitor
->visitCtrl(this);
491 CInterfaceElement::visit(visitor
);
494 // ***************************************************************************
495 void CCtrlBase::serial(NLMISC::IStream
&f
)
497 CViewBase::serial(f
);
499 uint version
= f
.serialVersion(1);
502 f
.serial(_ContextHelp
);
503 f
.serial(_OnContextHelp
);
504 f
.serial(_OnContextHelpParams
);
505 f
.serial(_ToolTipSpecialParent
);
506 f
.serialEnum(_ToolTipParent
);
508 THotSpot tmpToolTipParentPosRef
= _ToolTipParentPosRef
;
509 THotSpot tmpToolTipPosRef
= _ToolTipPosRef
;
510 THotSpot tmpToolTipParentPosRefAlt
= _ToolTipParentPosRefAlt
;
511 THotSpot tmpToolTipPosRefAlt
= _ToolTipPosRefAlt
;
513 f
.serialEnum(tmpToolTipParentPosRef
);
514 f
.serialEnum(tmpToolTipPosRef
);
515 f
.serialEnum(tmpToolTipParentPosRefAlt
);
516 f
.serialEnum(tmpToolTipPosRefAlt
);
518 _ToolTipParentPosRef
= tmpToolTipParentPosRef
;
519 _ToolTipPosRef
= tmpToolTipPosRef
;
520 _ToolTipParentPosRefAlt
= tmpToolTipParentPosRefAlt
;
521 _ToolTipPosRefAlt
= tmpToolTipPosRefAlt
;
523 nlSerialBitBool(f
, _ToolTipInstant
);
526 // ***************************************************************************
527 std::string
CCtrlBase::getContextHelpWindowName() const
529 return "context_help";
532 uint32
CCtrlBase::getDepth( CInterfaceGroup
*group
)
535 CInterfaceGroup
*parent
= getParent();
537 while( parent
!= NULL
)
539 if ( parent
== group
)
542 parent
= parent
->getParent();
545 // The Resizer Ctrls take the precedence over Sons controls.
546 return depth
+ getDeltaDepth();
550 void CCtrlBase::mapAHString( const std::string
&key
, const std::string
&value
)
552 std::map
< std::string
, std::map
< std::string
, std::string
> >::iterator itr
= AHCache
.find( getId() );
553 if( itr
== AHCache
.end() )
556 itr
= AHCache
.find( getId() );
559 std::map
< std::string
, std::string
> &AHMap
= itr
->second
;
560 AHMap
[ key
] = value
;
563 std::string
CCtrlBase::getAHString( const std::string
&key
) const
565 std::map
< std::string
, std::map
< std::string
, std::string
> >::const_iterator itr
= AHCache
.find( getId() );
566 if( itr
== AHCache
.end() )
569 std::map
< std::string
, std::string
>::const_iterator itr2
= itr
->second
.find( key
);
570 if( itr2
== itr
->second
.end() )
576 #ifdef RYZOM_LUA_UCSTRING
577 // ***************************************************************************
578 int CCtrlBase::luaSetTooltipUtf8(CLuaState
&ls
)
580 const char *funcName
= "setTooltipUtf8";
581 CLuaIHM::checkArgCount(ls
, funcName
, 1);
582 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TSTRING
);
583 std::string tooltip
= ls
.toString(1);
585 setDefaultContextHelp(tooltip
);