Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / src / gui / ctrl_base.cpp
blobfa790d9d48181893c43f18a66e72d1e7ab754daa
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 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 "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;
34 #ifdef DEBUG_NEW
35 #define new DEBUG_NEW
36 #endif
38 namespace NLGUI
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 ) )
52 return true;
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
75 return false;
78 std::string CCtrlBase::tooltipParentToString( TToolTipParentType type )
80 switch( type )
82 case TTMouse:
83 return "mouse";
84 break;
86 case TTWindow:
87 return "win";
88 break;
90 case TTSpecialWindow:
91 return "special";
92 break;
94 default:
95 break;
98 return "control";
101 CCtrlBase::TToolTipParentType CCtrlBase::stringToToolTipParent( const std::string &str )
103 std::string s = toLowerAscii( str );
105 if( s == "mouse" )
106 return TTMouse;
107 else
108 if( s == "win" )
109 return TTWindow;
110 else
111 if( s == "special" )
112 return TTSpecialWindow;
113 else
114 return TTCtrl;
117 // ***************************************************************************
118 bool CCtrlBase::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
120 if(!CViewBase::parse(cur, parentGroup))
121 return false;
123 CXMLAutoPtr prop;
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
130 if (!editorMode)
131 _ContextHelp = CI18N::get((const char *)prop);
132 else
133 _ContextHelp = (const char *)prop;
135 else
137 // get static toolTip
138 prop = (char *)xmlGetProp(cur, (xmlChar *)"tooltip");
139 if (prop)
141 if (!editorMode && NLMISC::startsWith((const char *)prop, "ui"))
142 _ContextHelp = CI18N::get((const char *)prop);
143 else
144 _ContextHelp = (const char *)prop;
148 // get dynamic toolTip ActionHandler
149 prop = (char*) xmlGetProp( cur, (xmlChar*)"on_tooltip" );
150 if (prop)
152 _OnContextHelp= (const char*)prop;
154 prop = (char*) xmlGetProp( cur, (xmlChar*)"on_tooltip_params" );
155 if (prop)
157 _OnContextHelpParams= (const char*)prop;
160 // Tooltip parent
161 prop = (char*) xmlGetProp( cur, (xmlChar*)"tooltip_parent" );
162 _ToolTipParent= TTCtrl;
163 if(prop)
165 _ToolTipParent = stringToToolTipParent( std::string( (const char*)prop ) );
168 // Tooltip special parent
169 prop = (char*) xmlGetProp( cur, (xmlChar*)"tooltip_special_parent" );
170 _ToolTipSpecialParent= CStringShared();
171 if(prop)
173 _ToolTipSpecialParent= (const char*)prop;
176 // Tooltip posref
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;
189 // ToolTip instant
190 prop = (char*) xmlGetProp( cur, (xmlChar*)"instant_help");
191 _ToolTipInstant= true;
192 if (prop) _ToolTipInstant = convertBool(prop);
194 return true;
197 std::string CCtrlBase::getProperty( const std::string &name ) const
199 if( name == "tooltip" )
201 return _ContextHelp;
203 else
204 if( name == "tooltip_i18n" )
206 return _ContextHelp;
208 else
209 if( name == "on_tooltip" )
211 return _OnContextHelp.toString();
213 else
214 if( name == "on_tooltip_params" )
216 return _OnContextHelpParams.toString();
218 else
219 if( name == "tooltip_parent" )
221 return tooltipParentToString( _ToolTipParent );
223 else
224 if( name == "tooltip_special_parent" )
226 return _ToolTipSpecialParent.toString();
228 else
229 if( name == "tooltip_posref" )
231 return TooltipHotSpotToString( _ToolTipPosRef );
233 else
234 if( name == "tooltip_parent_posref" )
236 return TooltipHotSpotToString( _ToolTipParentPosRef );
238 else
239 if( name == "tooltip_posref_alt" )
241 return TooltipHotSpotToString( _ToolTipPosRefAlt );
243 else
244 if( name == "tooltip_parent_posref_alt" )
246 return TooltipHotSpotToString( _ToolTipParentPosRefAlt );
248 else
249 if( name == "instant_help" )
251 return toString( _ToolTipInstant );
253 else
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);
264 else
265 _ContextHelp = value;
266 return;
268 else
269 if( name == "tooltip_i18n" )
271 if (!editorMode)
272 _ContextHelp = CI18N::get(value);
273 else
274 _ContextHelp = value;
275 return;
277 else
278 if( name == "on_tooltip" )
280 _OnContextHelp = value;
281 return;
283 else
284 if( name == "on_tooltip_params" )
286 _OnContextHelpParams = value;
287 return;
289 else
290 if( name == "tooltip_parent" )
292 _ToolTipParent = stringToToolTipParent( value );
293 return;
295 else
296 if( name == "tooltip_special_parent" )
298 _ToolTipSpecialParent = value;
299 return;
301 else
302 if( name == "tooltip_posref" )
304 THotSpot HS;
305 convertTooltipHotSpot( value.c_str(), HS );
306 _ToolTipPosRef = HS;
308 // When auto is set, both of them need to be auto
309 if( _ToolTipPosRef == Hotspot_TTAuto )
310 _ToolTipParentPosRef = Hotspot_TTAuto;
311 else
312 if( _ToolTipParentPosRef == Hotspot_TTAuto )
313 _ToolTipParentPosRef = _ToolTipPosRef;
315 return;
317 else
318 if( name == "tooltip_parent_posref" )
320 THotSpot HS;
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;
327 else
328 if( _ToolTipPosRef == Hotspot_TTAuto )
329 _ToolTipPosRef = _ToolTipParentPosRef;
331 return;
333 else
334 if( name == "tooltip_posref_alt" )
336 THotSpot HS;
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;
343 else
344 if( _ToolTipParentPosRefAlt == Hotspot_TTAuto )
345 _ToolTipPosRefAlt = _ToolTipParentPosRefAlt;
347 return;
349 else
350 if( name == "tooltip_parent_posref_alt" )
352 THotSpot HS;
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;
359 else
360 if( _ToolTipPosRefAlt == Hotspot_TTAuto )
361 _ToolTipPosRefAlt = _ToolTipParentPosRefAlt;
363 return;
365 else
366 if( name == "instant_help" )
368 bool b;
369 if( fromString( value, b ) )
370 _ToolTipInstant = b;
371 return;
373 else
374 CInterfaceElement::setProperty( name, value );
378 xmlNodePtr CCtrlBase::serialize( xmlNodePtr parentNode, const char *type ) const
380 xmlNodePtr node =
381 CInterfaceElement::serialize( parentNode, type );
383 if( node == NULL )
384 return NULL;
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() );
401 return node;
404 // ***************************************************************************
405 void CCtrlBase::convertTooltipHotSpot(const char *prop, THotSpot &parentHS, THotSpot &childHS)
407 parentHS = Hotspot_TTAuto;
408 childHS = Hotspot_TTAuto;
409 if(prop)
411 const char *ptr= (const char*)prop;
412 if(stricmp(ptr, "auto")==0)
414 parentHS = Hotspot_TTAuto;
415 childHS = Hotspot_TTAuto;
417 // valid ref?
418 else if(strlen(ptr)>=5)
420 THotSpot parentPosRef;
421 THotSpot posRef;
422 CInterfaceElement::convertHotSpotCouple(ptr, parentPosRef, posRef);
423 parentHS = parentPosRef;
424 childHS = posRef;
429 void CCtrlBase::convertTooltipHotSpot(const char *prop, THotSpot &HS )
431 if(prop)
433 const char *ptr = (const char*)prop;
434 if(stricmp(ptr, "auto")==0)
436 HS = Hotspot_TTAuto;
438 else if(strlen(ptr)==2)
440 HS = convertHotSpot(ptr);
445 std::string CCtrlBase::TooltipHotSpotToString( THotSpot parent, THotSpot child )
447 std::string s;
449 if( ( parent == Hotspot_TTAuto ) && ( child == Hotspot_TTAuto ) )
451 s = "auto";
453 else
455 s = CInterfaceElement::HotSpotToString( parent );
456 s += " ";
457 s += CInterfaceElement::HotSpotToString( child );
460 return s;
463 std::string CCtrlBase::TooltipHotSpotToString( THotSpot HS )
465 std::string s;
466 if( HS == Hotspot_TTAuto )
468 s = "auto";
470 else
472 s = HotSpotToString( HS );
474 return s;
477 // ***************************************************************************
478 bool CCtrlBase::emptyContextHelp() const
480 std::string help;
481 getContextHelp(help);
482 std::string sTmp = _OnContextHelp;
483 return help.empty() && sTmp.empty();
486 // ***************************************************************************
487 void CCtrlBase::visit(CInterfaceElementVisitor *visitor)
489 nlassert(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);
500 nlassert(version);
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 )
534 uint32 depth = 1;
535 CInterfaceGroup *parent = getParent();
537 while( parent != NULL )
539 if ( parent == group )
540 break;
541 else
542 parent = parent->getParent();
543 depth++;
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() )
555 AHCache[ getId() ];
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() )
567 return "";
569 std::map< std::string, std::string >::const_iterator itr2 = itr->second.find( key );
570 if( itr2 == itr->second.end() )
571 return "";
572 else
573 return itr2->second;
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);
587 return 0;
589 #endif