Merge branch '138-toggle-free-look-with-hotkey' into main/gingo-test
[ryzomcore.git] / ryzom / client / src / interface_v3 / interface_ddx.cpp
blob230b7a2c2b7ba95691f868b5d4eb91d6dbf6dd89
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
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/>.
23 #include "stdpch.h"
25 #include "interface_manager.h"
26 #include "interface_ddx.h"
27 #include "nel/gui/action_handler.h"
28 #include "nel/gui/ctrl_button.h"
29 #include "nel/gui/group_modal.h"
30 #include "../client_cfg.h"
32 #include "nel/misc/xml_auto_ptr.h"
35 using namespace std;
36 using namespace NLMISC;
38 // ***************************************************************************
39 // CParam
40 // ***************************************************************************
42 // ***************************************************************************
43 void CInterfaceDDX::CParam::DBToWidget()
45 if (Type != DataBase) return;
46 CInterfaceManager *pIM = CInterfaceManager::getInstance();
48 if (Widget == ColorButton)
50 CRGBA col = CRGBA::White;
51 CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp(Link,false);
52 if (pNL != NULL)
54 uint32 intCol = (uint32)pNL->getValue32();
55 col.R = (uint8) (intCol & 0xff);
56 col.G = (uint8) ((intCol >> 8) & 0xff);
57 col.B = (uint8) ((intCol >> 16) & 0xff);
58 col.A = (uint8) ((intCol >> 24) & 0xff);
60 CCtrlBaseButton *pBut = dynamic_cast<CCtrlBaseButton*>(Elt.getPtr());
61 if (pBut != NULL)
63 pBut->setColor(col);
64 pBut->setColorPushed(col);
65 pBut->setColorOver(col);
68 else if (Widget == BoolButton)
70 bool bVal = 0;
71 CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp(Link,false);
72 if (pNL != NULL)
74 bVal = pNL->getValue32()==0?false:true;
76 CCtrlBaseButton *pBut = dynamic_cast<CCtrlBaseButton*>(Elt.getPtr());
77 if (pBut != NULL)
79 pBut->setPushed(bVal);
82 else if (Widget == ScrollBarInt)
84 sint32 nVal = 0;
85 CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp(Link,false);
86 if (pNL != NULL)
88 nVal = pNL->getValue32();
90 CCtrlScroll *pCS = dynamic_cast<CCtrlScroll*>(Elt.getPtr());
91 if (pCS != NULL)
93 pCS->setValue (nVal);
94 pCS->setMinMax (Min, Max);
96 updateScrollView(nVal);
101 // ***************************************************************************
102 void CInterfaceDDX::CParam::CFGToWidget()
104 if (Type != ConfigFile) return;
106 if (Widget == BoolButton)
108 bool bVal = ClientCfg.readBool(Link);
109 CCtrlBaseButton *pBut = dynamic_cast<CCtrlBaseButton*>(Elt.getPtr());
110 if (pBut != NULL)
112 pBut->setPushed(bVal);
115 else if (Widget == ScrollBarInt)
117 sint32 nVal = ClientCfg.readInt(Link);
118 sint32 nMin = ClientCfg.readInt(Link+"_min");
119 sint32 nMax = ClientCfg.readInt(Link+"_max");
120 sint32 step = ClientCfg.readIntNoWarning(Link+"_step");
121 CCtrlScroll *pCS = dynamic_cast<CCtrlScroll*>(Elt.getPtr());
122 if (pCS != NULL)
124 pCS->setMinMax (nMin, nMax);
125 pCS->setStepValue(step);
126 pCS->setValue(nVal);
128 updateScrollView(nVal);
130 else if (Widget == ScrollBarFloat)
132 double rVal= ClientCfg.readDouble(Link);
133 tryRound(rVal);
134 sint32 nVal = (sint32)(10000*rVal);
135 sint32 nMin = (sint32)(10000*ClientCfg.readDouble(Link+"_min"));
136 sint32 nMax = (sint32)(10000*ClientCfg.readDouble(Link+"_max"));
137 sint32 step = (sint32)(10000*ClientCfg.readDoubleNoWarning(Link+"_step"));
138 CCtrlScroll *pCS = dynamic_cast<CCtrlScroll*>(Elt.getPtr());
139 if (pCS != NULL)
141 pCS->setMinMax (nMin, nMax);
142 pCS->setStepValue(step);
143 pCS->setValue (nVal);
145 updateScrollView(rVal);
149 // ***************************************************************************
150 void CInterfaceDDX::CParam::WidgetToDB()
152 if (Type != DataBase) return;
153 CInterfaceManager *pIM = CInterfaceManager::getInstance();
155 if (Widget == ColorButton)
157 CRGBA col = CRGBA::White;
158 CCtrlBaseButton *pBut = dynamic_cast<CCtrlBaseButton*>(Elt.getPtr());
159 if (pBut != NULL)
160 col = pBut->getColor();
161 CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp(Link,false);
162 if (pNL != NULL)
163 pNL->setValue32(col.R+(col.G<<8)+(col.B<<16)+(col.A<<24));
165 else if (Widget == BoolButton)
167 bool bVal = false;
168 CCtrlBaseButton *pBut = dynamic_cast<CCtrlBaseButton*>(Elt.getPtr());
169 if (pBut != NULL)
170 bVal = pBut->getPushed();
171 CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp(Link,false);
172 if (pNL != NULL)
174 pNL->setValue32(bVal?1:0);
177 else if (Widget == ScrollBarFloat)
179 // TODO
181 else if (Widget == ScrollBarInt)
183 sint32 nVal = 0;
184 CCtrlScroll *pCS = dynamic_cast<CCtrlScroll*>(Elt.getPtr());
185 if (pCS != NULL)
186 nVal = pCS->getValue();
187 CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp(Link,false);
188 if (pNL != NULL)
189 pNL->setValue32(nVal);
193 // ***************************************************************************
194 void CInterfaceDDX::CParam::WidgetToCFG()
196 if (Type != ConfigFile) return;
198 if (Widget == BoolButton)
200 bool bVal = false;
201 CCtrlBaseButton *pBut = dynamic_cast<CCtrlBaseButton*>(Elt.getPtr());
202 if (pBut != NULL)
203 bVal = pBut->getPushed();
204 ClientCfg.writeBool(Link, bVal);
206 else if (Widget == ScrollBarInt)
208 sint32 nVal = 0;
209 CCtrlScroll *pCS = dynamic_cast<CCtrlScroll*>(Elt.getPtr());
210 if (pCS != NULL)
211 nVal = pCS->getValue();
212 ClientCfg.writeInt(Link, nVal);
214 else if (Widget == ScrollBarFloat)
216 sint32 nVal = 0;
217 CCtrlScroll *pCS = dynamic_cast<CCtrlScroll*>(Elt.getPtr());
218 if (pCS != NULL)
219 nVal = pCS->getValue();
220 double rVal= nVal/10000.0;
221 tryRound(rVal);
222 ClientCfg.writeDouble(Link, rVal);
226 // ***************************************************************************
227 void CInterfaceDDX::CParam::WidgetToResultView()
229 if (Widget == ScrollBarInt)
231 sint32 nVal = 0;
232 CCtrlScroll *pCS = dynamic_cast<CCtrlScroll*>(Elt.getPtr());
233 if (pCS != NULL)
234 nVal = pCS->getValue();
235 updateScrollView(nVal);
237 else if (Widget == ScrollBarFloat)
239 sint32 nVal = 0;
240 CCtrlScroll *pCS = dynamic_cast<CCtrlScroll*>(Elt.getPtr());
241 if (pCS != NULL)
242 nVal = pCS->getValue();
243 double rVal= nVal/10000.0;
244 tryRound(rVal);
245 updateScrollView(rVal);
249 // ***************************************************************************
250 void CInterfaceDDX::CParam::backupDB()
252 if (Type != DataBase) return;
253 CInterfaceManager *pIM = CInterfaceManager::getInstance();
255 if (Widget == ColorButton)
257 CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp(Link,false);
258 if (pNL != NULL)
260 uint32 intCol = (uint32)pNL->getValue32();
261 RTBackupValue = intCol;
264 else if (Widget == ScrollBarInt)
266 sint32 nVal = 0;
267 CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp(Link,false);
268 if (pNL != NULL)
270 nVal = pNL->getValue32();
272 RTBackupValue = nVal;
277 // ***************************************************************************
278 void CInterfaceDDX::CParam::backupCFG()
280 if (Type != ConfigFile) return;
282 if (Widget == BoolButton)
284 bool bVal = ClientCfg.readBool(Link);
285 RTBackupValue = bVal;
287 else if (Widget == ScrollBarInt)
289 sint32 nVal = ClientCfg.readInt(Link);
290 RTBackupValue = nVal;
292 else if (Widget == ScrollBarFloat)
294 double rVal= ClientCfg.readDouble(Link);
295 tryRound(rVal);
296 sint32 nVal = (sint32)(10000*rVal);
297 RTBackupValue = nVal;
301 // ***************************************************************************
302 void CInterfaceDDX::CParam::restoreDB()
304 if (Type != DataBase) return;
305 if (RealTimeMode==RTModeFalse) return;
307 CInterfaceManager *pIM = CInterfaceManager::getInstance();
309 if (Widget == ColorButton)
311 CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp(Link,false);
312 if (pNL != NULL)
313 pNL->setValue32(RTBackupValue);
315 else if (Widget == ScrollBarFloat)
317 // TODO
319 else if (Widget == ScrollBarInt)
321 CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp(Link,false);
322 if (pNL != NULL)
323 pNL->setValue32(RTBackupValue);
327 // ***************************************************************************
328 void CInterfaceDDX::CParam::restoreCFG()
330 if (Type != ConfigFile) return;
331 if (RealTimeMode==RTModeFalse) return;
333 if (Widget == BoolButton)
335 ClientCfg.writeBool(Link, (RTBackupValue == 0) ? false : true);
337 else if (Widget == ScrollBarInt)
339 ClientCfg.writeInt(Link, RTBackupValue);
341 else if (Widget == ScrollBarFloat)
343 double rVal= RTBackupValue/10000.0;
344 tryRound(rVal);
345 ClientCfg.writeDouble(Link, rVal);
349 // ***************************************************************************
350 void CInterfaceDDX::CParam::updateScrollView(sint32 nVal)
352 if(ResultView)
354 ResultView->setText(toString(nVal) + ResultUnit);
358 // ***************************************************************************
359 void CInterfaceDDX::CParam::updateScrollView(double nVal)
361 if(ResultView)
363 // allow N digits
364 string fmt= toString("%%.%df", ResultDecimal);
365 ResultView->setText(toString(fmt.c_str(), nVal) + ResultUnit);
369 // ***************************************************************************
370 void CInterfaceDDX::CParam::tryRound(double rVal)
372 // Round?
373 if(RoundMode)
374 rVal= floor(rVal+0.5);
377 // ***************************************************************************
378 void CInterfaceDDX::CParam::restoreCFGPreset(uint presetVal)
380 if (Type != ConfigFile) return;
382 if (Widget == BoolButton)
384 // try to get the preset from cfg
385 CConfigFile::CVar *varPtr = ClientCfg.ConfigFile.getVarPtr(Link+"_ps"+toString(presetVal));
386 if(varPtr)
388 bool bVal = varPtr->asInt() != 0;
389 CCtrlBaseButton *pBut = dynamic_cast<CCtrlBaseButton*>(Elt.getPtr());
390 if (pBut != NULL)
392 pBut->setPushed(bVal);
396 else if (Widget == ScrollBarInt)
398 // try to get the preset from cfg
399 CConfigFile::CVar *varPtr = ClientCfg.ConfigFile.getVarPtr(Link+"_ps"+toString(presetVal));
400 if(varPtr)
402 sint32 nVal = varPtr->asInt();
403 CCtrlScroll *pCS = dynamic_cast<CCtrlScroll*>(Elt.getPtr());
404 if (pCS != NULL)
406 pCS->setValue(nVal);
408 updateScrollView(nVal);
411 else if (Widget == ScrollBarFloat)
413 // try to get the preset from cfg
414 CConfigFile::CVar *varPtr = ClientCfg.ConfigFile.getVarPtr(Link+"_ps"+toString(presetVal));
415 if(varPtr)
417 double rVal = varPtr->asDouble();
418 tryRound(rVal);
419 sint32 nVal = (sint32)(10000*rVal);
420 CCtrlScroll *pCS = dynamic_cast<CCtrlScroll*>(Elt.getPtr());
421 if (pCS != NULL)
423 pCS->setValue (nVal);
425 updateScrollView(rVal);
430 // ***************************************************************************
431 uint32 CInterfaceDDX::CParam::getPresetPossibleBF()
433 if (Type != ConfigFile) return 0;
434 uint32 ret= 0;
436 if (Widget == BoolButton)
438 // get the current value from cfg
439 bool curVal= ClientCfg.readBool(Link);
441 // compare to each preset from cfg
442 for(uint i=0;i<CInterfaceDDX::NumPreset;i++)
444 CConfigFile::CVar *varPtr = ClientCfg.ConfigFile.getVarPtr(Link+"_ps"+toString(i));
445 if(varPtr)
447 bool bVal = varPtr->asInt() != 0;
448 // if same value, then the current value is compatible with the preset
449 if(bVal == curVal)
450 ret|= 1<<i;
454 else if (Widget == ScrollBarInt)
456 // get the current value from cfg
457 sint32 curVal= ClientCfg.readInt(Link);
459 // compare to each preset from cfg
460 for(uint i=0;i<CInterfaceDDX::NumPreset;i++)
462 CConfigFile::CVar *varPtr = ClientCfg.ConfigFile.getVarPtr(Link+"_ps"+toString(i));
463 if(varPtr)
465 sint32 nVal = varPtr->asInt();
466 // if same value, then the current value is compatible with the preset
467 if(nVal == curVal)
468 ret|= 1<<i;
472 else if (Widget == ScrollBarFloat)
474 // get the current value from cfg
475 double curVal= ClientCfg.readDouble(Link);
476 tryRound(curVal);
478 // compare to each preset from cfg
479 for(uint i=0;i<CInterfaceDDX::NumPreset;i++)
481 CConfigFile::CVar *varPtr = ClientCfg.ConfigFile.getVarPtr(Link+"_ps"+toString(i));
482 if(varPtr)
484 double rVal = varPtr->asDouble();
485 tryRound(rVal);
486 // if same value, then the current value is compatible with the preset
487 if(rVal == curVal)
488 ret|= 1<<i;
493 return ret;
497 // ***************************************************************************
498 // CInterfaceDDX
499 // ***************************************************************************
502 // ***************************************************************************
503 CInterfaceDDX::CInterfaceDDX()
505 _PresetObs.Owner= this;
506 _ApplyButton= NULL;
509 // ***************************************************************************
510 CInterfaceDDX::~CInterfaceDDX()
512 // unregister observer
513 std::set<CCDBNodeLeaf*>::iterator it;
514 for(it=_PresetNodes.begin();it!=_PresetNodes.end();it++)
516 ICDBNode::CTextId id;
517 (*it)->removeObserver(&_PresetObs, id);
520 _Parameters.clear();
521 _PresetNodes.clear();
524 // ***************************************************************************
525 bool CInterfaceDDX::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
527 CInterfaceManager *pIM = CInterfaceManager::getInstance();
528 if (!CInterfaceElement::parse(cur, parentGroup))
529 return false;
532 // bool ok = true;
533 cur = cur->children;
534 while (cur)
536 // Check that this is a param node
537 if ( stricmp((char*)cur->name,"param") == 0 )
539 CParam p;
540 bool bOK = true;
542 CXMLAutoPtr ptrUI((const char*)xmlGetProp (cur, (xmlChar*)"ui"));
543 p.Elt = _Parent->getId()+":"+string((const char*)ptrUI);
544 if (p.Elt == NULL) bOK = false;
546 CXMLAutoPtr ptrType((const char*)xmlGetProp (cur, (xmlChar*)"type"));
547 if (!ptrType) bOK = false;
548 if (stricmp((const char*)ptrType,"db") == 0)
549 p.Type = CParam::DataBase;
550 else if (stricmp((const char*)ptrType,"cfg") == 0)
551 p.Type = CParam::ConfigFile;
553 CXMLAutoPtr ptrWidget((const char*)xmlGetProp (cur, (xmlChar*)"widget"));
554 if (!ptrWidget) bOK = false;
555 if (stricmp((const char*)ptrWidget,"colbut") == 0)
556 p.Widget = CParam::ColorButton;
557 else if (stricmp((const char*)ptrWidget,"sbfloat") == 0)
558 p.Widget = CParam::ScrollBarFloat;
559 else if (stricmp((const char*)ptrWidget,"sbint") == 0)
560 p.Widget = CParam::ScrollBarInt;
561 else if (stricmp((const char*)ptrWidget,"boolbut") == 0)
562 p.Widget = CParam::BoolButton;
563 else if (stricmp((const char*)ptrWidget,"sbfloat_round") == 0)
565 p.Widget = CParam::ScrollBarFloat;
566 p.RoundMode = true;
569 CXMLAutoPtr ptrLink((const char*)xmlGetProp (cur, (xmlChar*)"link"));
570 if (!ptrLink) bOK = false;
571 else p.Link = (const char*)ptrLink;
573 if (p.Widget == CParam::ScrollBarInt)
575 CXMLAutoPtr ptrMin((const char*)xmlGetProp (cur, (xmlChar*)"min"));
576 if (!ptrMin) p.Min = 0;
577 else fromString((const char*)ptrMin, p.Min);
578 CXMLAutoPtr ptrMax((const char*)xmlGetProp (cur, (xmlChar*)"max"));
579 if (!ptrMax) p.Max = 255;
580 else fromString((const char*)ptrMax, p.Max);
583 CXMLAutoPtr ptrRealtime((const char*)xmlGetProp (cur, (xmlChar*)"realtime"));
584 if (!ptrRealtime) p.RealTimeMode = CParam::RTModeFalse;
585 else
587 if( !strcmp((const char*)ptrRealtime, "true"))
588 p.RealTimeMode= CParam::RTModeTrue;
589 else if( !strcmp((const char*)ptrRealtime, "end_scroll"))
590 p.RealTimeMode = CParam::RTModeEndScroll;
591 else
592 p.RealTimeMode = CParam::RTModeFalse;
595 // try to get the ui_view related
596 CXMLAutoPtr ptrUIView((const char*)xmlGetProp (cur, (xmlChar*)"ui_view"));
597 if(ptrUIView)
598 p.ResultView = _Parent->getId()+":"+string((const char*)ptrUIView);
599 CXMLAutoPtr ptrUIUnit((const char*)xmlGetProp (cur, (xmlChar*)"ui_unit"));
600 if(ptrUIUnit && ((const char*)ptrUIUnit)[0]!=0 )
601 p.ResultUnit = CI18N::get((const char*)ptrUIUnit);
602 CXMLAutoPtr ptrUIDecimal((const char*)xmlGetProp (cur, (xmlChar*)"ui_decimal"));
603 if(ptrUIDecimal)
604 fromString((const char*)ptrUIDecimal, p.ResultDecimal);
606 // try to get the preset db entry
607 if(p.Type==CParam::ConfigFile && bOK)
609 CXMLAutoPtr ptrPreset((const char*)xmlGetProp (cur, (xmlChar*)"preset"));
610 if(ptrPreset)
612 p.PresetDB = NLGUI::CDBManager::getInstance()->getDbProp((const char*)ptrPreset, false);
613 if(p.PresetDB)
615 // if not exist in the set, add it and register callback
616 if(_PresetNodes.insert(p.PresetDB).second)
618 ICDBNode::CTextId id;
619 p.PresetDB->addObserver(&_PresetObs, id);
625 // if ok, add this parameter!
626 if (bOK)
627 _Parameters.push_back(p);
629 // apply node?
630 else if( stricmp((char*)cur->name,"apply") == 0 )
632 CXMLAutoPtr ptrUI((const char*)xmlGetProp (cur, (xmlChar*)"ui"));
633 _ApplyButton = dynamic_cast<CCtrlBaseButton*>(CWidgetManager::getInstance()->getElementFromId(_Parent->getId(),(const char*)ptrUI));
636 cur = cur->next;
639 CDDXManager::getInstance()->add(this);
641 return true;
644 // ***************************************************************************
645 // Initialize parameters from external stuff (database, client.cfg ...)
646 void CInterfaceDDX::init()
648 // **** start values from CFG, and backup
649 for (uint i = 0; i < _Parameters.size(); ++i)
651 CParam &p = _Parameters[i];
653 if (p.Type == CParam::DataBase)
655 p.DBToWidget();
656 p.backupDB();
658 else if (p.Type == CParam::ConfigFile)
660 p.CFGToWidget();
661 p.backupCFG();
665 // **** initialize the preset
666 resetPreSet();
668 // **** Start apply frozen
669 if(_ApplyButton)
671 _ApplyButton->setFrozen(true);
675 // ***************************************************************************
676 void CInterfaceDDX::update()
678 for (uint i = 0; i < _Parameters.size(); ++i)
680 CParam &p = _Parameters[i];
681 if (p.Type == CParam::DataBase)
683 p.WidgetToDB();
684 p.backupDB();
686 else if (p.Type == CParam::ConfigFile)
688 p.WidgetToCFG();
689 p.backupCFG();
693 // Write the modified client.cfg
694 ClientCfg.IsInvalidated = true;
696 // **** set apply frozen
697 if(_ApplyButton)
699 _ApplyButton->setFrozen(true);
703 // ***************************************************************************
704 void CInterfaceDDX::cancel()
706 // Update scroll bars that are realtime
707 bool bMustSave = false;
708 uint i;
709 for (i = 0; i < _Parameters.size(); ++i)
711 CParam &p = _Parameters[i];
713 if (p.RealTimeMode==CParam::RTModeFalse) continue;
715 if (p.Type == CParam::DataBase)
717 p.restoreDB();
719 else if (p.Type == CParam::ConfigFile)
721 bMustSave = true;
722 p.restoreCFG();
726 if (bMustSave)
728 ClientCfg.IsInvalidated = true;
731 for (i = 0; i < _Parameters.size(); ++i)
733 CParam &p = _Parameters[i];
735 if (p.Type == CParam::DataBase)
737 p.DBToWidget();
739 else if (p.Type == CParam::ConfigFile)
741 p.CFGToWidget();
745 // **** reset the preset
746 resetPreSet();
748 // **** set apply frozen
749 if(_ApplyButton)
751 _ApplyButton->setFrozen(true);
755 // ***************************************************************************
756 void CInterfaceDDX::updateRealtime(CCtrlBase *pSB, bool updateOnScrollEnd)
758 // Update scroll bars that are realtime
759 bool bMustSave = false;
760 uint i;
761 for (i = 0; i < _Parameters.size(); ++i)
763 CParam &p = _Parameters[i];
765 if (p.Elt != pSB) continue;
767 if( (!updateOnScrollEnd && p.RealTimeMode==CParam::RTModeTrue) ||
768 (updateOnScrollEnd && p.RealTimeMode==CParam::RTModeEndScroll) )
770 if (p.Type == CParam::DataBase)
772 p.WidgetToDB();
774 else if (p.Type == CParam::ConfigFile)
776 bMustSave = true;
777 p.WidgetToCFG();
781 // even if not realtime, if has a preset setuped, set it to custom!
782 if(p.PresetDB)
784 p.PresetDB->setValue32(CustomPreset);
787 // even if not realtime, must update text view
788 p.WidgetToResultView();
791 if (bMustSave)
793 ClientCfg.IsInvalidated = true;
796 IngameDbMngr.flushObserverCalls();
797 NLGUI::CDBManager::getInstance()->flushObserverCalls();
799 for (i = 0; i < _Parameters.size(); ++i)
801 CParam &p = _Parameters[i];
803 if( (!updateOnScrollEnd && p.RealTimeMode==CParam::RTModeTrue) ||
804 (updateOnScrollEnd && p.RealTimeMode==CParam::RTModeEndScroll) )
806 if (p.Type == CParam::DataBase)
808 p.DBToWidget();
810 else if (p.Type == CParam::ConfigFile)
812 p.CFGToWidget();
817 // **** something changed, allow apply!
818 if(_ApplyButton)
820 _ApplyButton->setFrozen(false);
824 // ***************************************************************************
825 void CInterfaceDDX::updateParamPreset(CCDBNodeLeaf *presetChanged)
827 if(!presetChanged)
828 return;
829 // if not custom or bad id
830 uint presetVal= presetChanged->getValue32();
831 if(presetVal>=NumPreset)
832 return;
834 // **** check each parameter
835 for(uint i=0;i<_Parameters.size();i++)
837 CParam &param= _Parameters[i];
839 // if can be set by this preset modified
840 if(param.PresetDB == presetChanged)
842 // must be a config file param (see parse())
843 nlassert(param.Type==CParam::ConfigFile);
845 // restore preset
846 param.restoreCFGPreset(presetVal);
848 // if realTime, then must update CFG
849 if (param.RealTimeMode!=CParam::RTModeFalse)
851 param.WidgetToCFG();
852 ClientCfg.IsInvalidated= true;
857 // **** something changed, allow apply!
858 if(_ApplyButton)
860 _ApplyButton->setFrozen(false);
864 // ***************************************************************************
865 void CInterfaceDDX::validateApplyButton()
867 if(_ApplyButton)
869 _ApplyButton->setFrozen(false);
873 // ***************************************************************************
874 void CInterfaceDDX::resetPreSet()
876 nlassert(NumPreset<32);
877 // for each preset, assign a bitfield, where bit==1 <=> preset possible
878 std::map<CCDBNodeLeaf*, uint32> bfPreset;
879 std::set<CCDBNodeLeaf*>::iterator itSet;
880 // init as "preset possible"
881 for(itSet=_PresetNodes.begin();itSet!=_PresetNodes.end();itSet++)
883 bfPreset[*itSet]= (1<<NumPreset)-1;
886 // then for each parameter, invalidate preset according to value
887 for (uint i = 0; i < _Parameters.size(); ++i)
889 CParam &p = _Parameters[i];
891 if (p.Type == CParam::ConfigFile && p.PresetDB)
893 std::map<CCDBNodeLeaf*, uint32>::iterator it= bfPreset.find(p.PresetDB);
894 if(it!=bfPreset.end())
896 it->second&= p.getPresetPossibleBF();
901 // for each preset DB, assign the lowest preset possible
902 std::map<CCDBNodeLeaf*, uint32>::iterator itMap;
903 for(itMap= bfPreset.begin();itMap!=bfPreset.end();itMap++)
905 CCDBNodeLeaf *node= itMap->first;
906 uint32 bf= itMap->second;
908 // if no common preset is possible, then assign custom!
909 if(bf==0)
911 node->setValue32(CustomPreset);
913 // else assign the lowest bit
914 else
916 uint32 presetId= 0;
917 while( (bf&(1<<presetId)) == 0)
918 presetId++;
919 node->setValue32(presetId);
924 // ***************************************************************************
925 void CInterfaceDDX::CPresetObs::update(ICDBNode* node)
927 CCDBNodeLeaf *leaf= dynamic_cast<CCDBNodeLeaf*>(node);
928 if(leaf)
929 Owner->updateParamPreset(leaf);
932 // ***************************************************************************
933 // CDDXManager
934 // ***************************************************************************
936 // ***************************************************************************
937 CDDXManager* CDDXManager::_Instance = NULL;
939 // ***************************************************************************
940 CDDXManager::CDDXManager()
944 // ***************************************************************************
945 void CDDXManager::releaseInstance()
947 if( _Instance )
948 delete _Instance;
949 _Instance = NULL;
952 // ***************************************************************************
953 void CDDXManager::release()
955 std::map<std::string, CInterfaceDDX*>::iterator ite = _DDXes.begin();
956 while (ite != _DDXes.end())
958 delete ite->second;
960 ite++;
962 _DDXes.clear();
965 // ***************************************************************************
966 void CDDXManager::add(CInterfaceDDX *pDDX)
968 _DDXes.insert(pair<string,CInterfaceDDX*>(pDDX->getId(),pDDX));
971 // ***************************************************************************
972 CInterfaceDDX *CDDXManager::get(const std::string &ddxName)
974 map<string, CInterfaceDDX*>::iterator it = _DDXes.find(ddxName);
975 if (it == _DDXes.end())
977 it = _DDXes.find("ui:interface:"+ddxName);
979 if (it != _DDXes.end())
981 return it->second;
983 return NULL;
986 // ***************************************************************************
987 CInterfaceDDX *CDDXManager::getFromParent(const std::string &ddxParentName)
989 map<string, CInterfaceDDX*>::iterator it = _DDXes.begin();
990 while (it != _DDXes.end())
992 string parentName = it->first;
993 parentName = parentName.substr(0,parentName.rfind(":"));
994 if (parentName == ddxParentName)
995 return it->second;
996 it++;
998 return NULL;
1001 // ***************************************************************************
1002 // Update database or config file from the parameters (ddx memory zone)
1003 class CHandlerDDXUpdate : public IActionHandler
1005 public:
1006 void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
1008 CDDXManager *pDM = CDDXManager::getInstance();
1009 CInterfaceDDX *pDDX = pDM->get(sParams);
1010 if (pDDX != NULL)
1011 pDDX->update();
1013 protected:
1015 REGISTER_ACTION_HANDLER( CHandlerDDXUpdate, "ddx_update");
1017 // ***************************************************************************
1018 // Update the parameters (ddx mem zone) from database or config file
1019 class CHandlerDDXInit : public IActionHandler
1021 public:
1022 void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
1024 CDDXManager *pDM = CDDXManager::getInstance();
1025 CInterfaceDDX *pDDX = pDM->get(sParams);
1026 if (pDDX != NULL)
1027 pDDX->init();
1029 protected:
1031 REGISTER_ACTION_HANDLER( CHandlerDDXInit, "ddx_init");
1033 // ***************************************************************************
1034 // Cancel all realtime values
1035 class CHandlerDDXCancel : public IActionHandler
1037 public:
1038 void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
1040 CDDXManager *pDM = CDDXManager::getInstance();
1041 CInterfaceDDX *pDDX = pDM->get(sParams);
1042 if (pDDX != NULL)
1043 pDDX->cancel();
1045 protected:
1047 REGISTER_ACTION_HANDLER( CHandlerDDXCancel, "ddx_cancel");
1049 // ***************************************************************************
1050 class CHandlerDDXScroll : public IActionHandler
1052 public:
1053 void execute (CCtrlBase *pCaller, const std::string &sParams)
1055 CDDXManager *pDM = CDDXManager::getInstance();
1056 CInterfaceDDX *pDDX = pDM->get(sParams);
1057 if (pDDX != NULL)
1058 pDDX->updateRealtime(pCaller, false);
1060 protected:
1062 REGISTER_ACTION_HANDLER( CHandlerDDXScroll, "ddx_scroll");
1064 // ***************************************************************************
1065 class CHandlerDDXScrollEnd : public IActionHandler
1067 public:
1068 void execute (CCtrlBase *pCaller, const std::string &sParams)
1070 CDDXManager *pDM = CDDXManager::getInstance();
1071 CInterfaceDDX *pDDX = pDM->get(sParams);
1072 if (pDDX != NULL)
1073 pDDX->updateRealtime(pCaller, true);
1075 protected:
1077 REGISTER_ACTION_HANDLER( CHandlerDDXScrollEnd, "ddx_scroll_end");
1079 // ***************************************************************************
1080 // Automatically search for the ddx and launch an update
1081 class CHandlerDDXColor : public IActionHandler
1083 public:
1084 void execute (CCtrlBase *pCaller, const std::string &/* sParams */)
1086 CDDXManager *pDM = CDDXManager::getInstance();
1087 if (pCaller == NULL) return;
1088 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1089 CCtrlBase *pCB = CWidgetManager::getInstance()->getCtrlLaunchingModal();
1090 // Search for a ddx in the parents
1091 CInterfaceGroup *pIG = pCB->getParent();
1092 bool found = false;
1093 CInterfaceDDX *pDDX = NULL;
1094 while (!found)
1096 pDDX = pDM->getFromParent(pIG->getId());
1097 if (pDDX != NULL) found = true;
1098 else pIG = pIG->getParent();
1099 if (pIG == NULL) return;
1101 if (pDDX != NULL)
1102 pDDX->updateRealtime(pCB, false);
1104 protected:
1106 REGISTER_ACTION_HANDLER( CHandlerDDXColor , "ddx_color");
1109 // ***************************************************************************
1110 // Automatically search for the ddx and launch an update
1111 class CHandlerDDXBoolButton : public IActionHandler
1113 public:
1114 void execute (CCtrlBase *pCaller, const std::string &/* sParams */)
1116 CDDXManager *pDM = CDDXManager::getInstance();
1117 if (pCaller == NULL) return;
1118 // Search for a ddx in the parents
1119 CInterfaceGroup *pIG = pCaller->getParent();
1120 bool found = false;
1121 CInterfaceDDX *pDDX = NULL;
1122 while (!found)
1124 pDDX = pDM->getFromParent(pIG->getId());
1125 if (pDDX != NULL) found = true;
1126 else pIG = pIG->getParent();
1127 if (pIG == NULL) return;
1129 if (pDDX != NULL)
1130 pDDX->updateRealtime(pCaller, false);
1132 protected:
1134 REGISTER_ACTION_HANDLER( CHandlerDDXBoolButton , "ddx_bool_button");