Merge branch 'main/rendor-staging' into fixes
[ryzomcore.git] / nel / src / gui / group_tab.cpp
blob24d8b15067584b0116e4260b6755957f407a6e09
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 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "stdpch.h"
22 #include "nel/gui/group_tab.h"
23 #include "nel/misc/xml_auto_ptr.h"
24 #include "nel/gui/lua_ihm.h"
25 #include "nel/gui/widget_manager.h"
26 #include "nel/gui/interface_group.h"
27 #include "nel/gui/view_text.h"
29 using namespace std;
30 using namespace NLMISC;
32 #ifdef DEBUG_NEW
33 #define new DEBUG_NEW
34 #endif
36 NLMISC_REGISTER_OBJECT(CViewBase, CGroupTab, std::string, "tab");
38 namespace NLGUI
41 // ***************************************************************************
42 CGroupTab::CGroupTab(const TCtorParam &param)
43 : CInterfaceGroup(param)
45 _Selection= -1;
46 _NextSelection = -1;
47 _BaseRenderLayer= 0;
48 _Setuped= false;
49 _HideOutTabs = false;
50 _FirstTabIndex = -1;
51 _LastTabIndex = -1;
54 std::string CGroupTab::getProperty( const std::string &name ) const
56 if( name == "hide_out_tabs" )
58 return toString( _HideOutTabs );
60 else
61 if( name == "onchange" )
63 return _AHOnChange;
65 else
66 if( name == "onchange_params" )
68 return _ParamsOnChange;
70 else
71 return CInterfaceGroup::getProperty( name );
75 void CGroupTab::setProperty( const std::string &name, const std::string &value )
77 if( name == "hide_out_tabs" )
79 bool b;
80 if( fromString( value, b ) )
81 _HideOutTabs = b;
82 return;
84 else
85 if( name == "onchange" )
87 _AHOnChange = value;
88 return;
90 else
91 if( name == "onchange_params" )
93 _ParamsOnChange = value;
94 return;
96 else
97 CInterfaceGroup::setProperty( name, value );
100 xmlNodePtr CGroupTab::serialize( xmlNodePtr parentNode, const char *type ) const
102 xmlNodePtr node = CInterfaceGroup::serialize( parentNode, type );
103 if( node == NULL )
104 return NULL;
106 xmlSetProp( node, BAD_CAST "type", BAD_CAST "tab" );
107 xmlSetProp( node, BAD_CAST "hide_out_tabs", BAD_CAST toString( _HideOutTabs ).c_str() );
108 xmlSetProp( node, BAD_CAST "onchange", BAD_CAST _AHOnChange.c_str() );
109 xmlSetProp( node, BAD_CAST "onchange_params", BAD_CAST _ParamsOnChange.c_str() );
111 return node;
114 // ***************************************************************************
115 bool CGroupTab::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
117 if( !CInterfaceGroup::parse(cur, parentGroup) )
118 return false;
120 CXMLAutoPtr prop((const char*)xmlGetProp(cur, (xmlChar*)"hide_out_tabs"));
121 if (prop)
123 _HideOutTabs = convertBool(prop);
126 prop = (char*) xmlGetProp( cur, (xmlChar*)"onchange" );
127 if (prop) _AHOnChange = (const char *) prop;
128 prop = (char*) xmlGetProp( cur, (xmlChar*)"onchange_params" );
129 if (prop) _ParamsOnChange = (const char *) prop;
131 return true;
134 // ***************************************************************************
135 void CGroupTab::setup()
137 if(_Setuped)
138 return;
139 _Setuped= true;
141 _Buttons.clear();
142 _Groups.clear();
144 /* Buttons must be named tab0,tab1,tab2...
145 and tab_array0_0, tab_array0_1 .... (for vector of tab)
146 Only 10 tab array are allowed
148 for(sint tabArrayIndex= -1;tabArrayIndex<10;tabArrayIndex++)
150 // prefix according to array or not
151 string prefix;
152 if(tabArrayIndex==-1)
153 prefix= "tab";
154 else
155 prefix= toString("tab_array%d_", tabArrayIndex);
157 // for all tab of this type (standard tab or array of tab), find the Buttons and groups.
158 uint tabIndex=0;
159 for(;;)
161 // find the ctrl named "tab0"
162 CCtrlTabButton *but= dynamic_cast<CCtrlTabButton*>(getCtrl(toString("%s%d", prefix.c_str(), tabIndex)));
163 if(!but)
164 break;
166 // find the associated group
167 CInterfaceGroup *pGroup = NULL;
168 CInterfaceGroup *pFather = this;
170 while ((pGroup == NULL) && (pFather != NULL))
172 pGroup = pFather->getGroup(but->_AssociatedGroup);
173 pFather = pFather->getParent();
176 // add to the button and group list
177 _Buttons.push_back(but);
178 _Groups.push_back(pGroup);
180 // try next
181 tabIndex++;
185 // at the first setup, select by default the 1st
186 if(_Selection<0)
187 select(0);
190 // ***************************************************************************
191 void CGroupTab::addTab(CCtrlTabButton * tabB)
193 addCtrl(tabB);
194 _Setuped = false;
195 updateCoords();
196 selectFromCtrl(tabB);
198 if(_HideOutTabs && !_AHOnChange.empty())
199 CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
203 // ***************************************************************************
204 void CGroupTab::addTab(CCtrlTabButton * tabB, sint index)
206 if(index<(sint)_Buttons.size() && index>=0)
208 vector<CCtrlTabButton*> buttons = _Buttons;
210 for(sint i=0;i<(sint)_Buttons.size();i++)
211 delCtrl(_Buttons[i], true);
213 _Setuped = false;
214 updateCoords();
216 uint count=0;
217 CCtrlTabButton* lastTab=NULL;
218 for(sint i=0;i<(sint)buttons.size();i++)
220 if(i==index)
222 tabB->setId("tab" + NLMISC::toString(count));
223 tabB->setParentPos(lastTab);
224 if(i==0)
225 tabB->setParentPosRef(Hotspot_TL);
226 else
227 tabB->setParentPosRef(Hotspot_TR);
228 tabB->setPosRef(Hotspot_TL);
230 addCtrl(tabB);
231 lastTab = tabB;
232 count++;
235 buttons[i]->setId("tab" + NLMISC::toString(count));
236 buttons[i]->setParentPos(lastTab);
237 if(i==0 && index!=0)
238 buttons[i]->setParentPosRef(Hotspot_TL);
239 else
240 buttons[i]->setParentPosRef(Hotspot_TR);
241 buttons[i]->setPosRef(Hotspot_TL);
243 addCtrl(buttons[i]);
245 lastTab = buttons[i];
246 count++;
249 _Setuped = false;
250 updateCoords();
252 // we have added a new button in first position
253 // then it must recover the reference
254 if(index==0)
256 CCtrlTabButton * tab0 = _Buttons[0];
257 for(uint i=0; i<_Buttons.size(); ++i)
258 _Buttons[i]->initRBRefFromRadioButton(tab0);
260 select(_Selection);
262 else
264 CCtrlTabButton * tab0 = _Buttons[0];
265 _Buttons[index]->initRBRefFromRadioButton(tab0);
268 else
270 tabB->setId(string("tab") + NLMISC::toString(_Buttons.size()));
272 if(_Buttons.empty())
274 tabB->setParentPos(NULL);
275 tabB->setParentPosRef(Hotspot_TL);
277 else
279 tabB->setParentPos(_Buttons[_Buttons.size()-1]);
280 tabB->setParentPosRef(Hotspot_TR);
282 tabB->setPosRef(Hotspot_TL);
284 addCtrl(tabB);
287 _Setuped = false;
288 updateCoords();
290 if(_HideOutTabs && !_AHOnChange.empty())
291 CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
295 // ***************************************************************************
296 int CGroupTab::luaAddTab(CLuaState &ls)
298 CLuaIHM::checkArgCount(ls, "CGroupTab::addTab", 1);
299 CCtrlTabButton *tabB = dynamic_cast<CCtrlTabButton *>(CLuaIHM::getUIOnStack(ls, 1));
300 if (tabB)
302 // don't use addTab to avoid selection of new tab
303 addCtrl(tabB);
305 _Setuped = false;
306 updateCoords();
308 if(_HideOutTabs && !_AHOnChange.empty())
309 CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
312 return 0;
315 // ***************************************************************************
316 int CGroupTab::luaAddTabWithOrder(CLuaState &ls)
318 const char *funcName = "addTabWithOrder";
319 CLuaIHM::checkArgCount(ls, funcName, 2);
320 CLuaIHM::checkArgType(ls, funcName, 2, LUA_TNUMBER);
322 CCtrlTabButton *tabB = dynamic_cast<CCtrlTabButton *>(CLuaIHM::getUIOnStack(ls, 1));
323 if (tabB)
325 // don't use addTab to avoid selection of new tab
326 addTab(tabB, (sint) ls.toInteger(2));
328 return 0;
331 // ***************************************************************************
332 void CGroupTab::removeTab(sint index)
334 if(!(index>=0 && index<(sint)_Buttons.size()))
335 return;
337 vector<CCtrlTabButton*> buttons = _Buttons;
339 for(sint i=0;i<(sint)_Buttons.size();i++)
341 bool deleteElt = (i!=index);
342 CViewText* tabVT = _Buttons[i]->getViewText();
343 if(tabVT && !deleteElt)
344 delView(tabVT, deleteElt);
346 delCtrl(_Buttons[i], deleteElt);
348 if(!deleteElt)
349 (_Groups[i]->getParent())->delGroup(_Groups[i], deleteElt);
351 _Setuped = false;
352 updateCoords();
354 uint count=0;
355 CCtrlTabButton* lastTab = NULL;
356 for(sint i=0;i<(sint)buttons.size();i++)
358 if(i!=index)
360 buttons[i]->setId("tab"+NLMISC::toString(count));
361 buttons[i]->setParentPos(lastTab);
362 if((i==0) || (index==0 && i==1))
363 buttons[i]->setParentPosRef(Hotspot_TL);
364 else
365 _Buttons[i]->setParentPosRef(Hotspot_TR);
367 buttons[i]->setPosRef(Hotspot_TL);
369 lastTab = buttons[i];
370 addCtrl(buttons[i]);
371 count++;
375 _Setuped = false;
376 updateCoords();
378 // we have removed the first button which is the only one to own the reference
379 // then the new first button recovers the reference
380 if(index==0)
382 CCtrlTabButton * tab0 = _Buttons[0];
383 for(uint i=0; i<_Buttons.size(); ++i)
384 _Buttons[i]->initRBRefFromRadioButton(tab0);
386 select(_Selection);
389 if(_HideOutTabs)
391 select(_FirstTabIndex);
393 if(!_AHOnChange.empty())
394 CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
398 // ***************************************************************************
400 int CGroupTab::luaRemoveTab(CLuaState &ls)
402 const char *funcName = "removeTab";
403 CLuaIHM::checkArgCount(ls, funcName, 1);
404 CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
405 removeTab((uint) ls.toInteger(1));
406 return 0;
409 // ***************************************************************************
410 void CGroupTab::removeAll()
412 for(sint i=0;i<(sint)_Buttons.size();i++)
414 CViewText* tabVT = _Buttons[i]->getViewText();
415 if(tabVT)
416 delView(tabVT, false);
418 delCtrl(_Buttons[i], false);
419 (_Groups[i]->getParent())->delGroup(_Groups[i], false);
422 _Setuped = false;
423 updateCoords();
426 // ***************************************************************************
428 int CGroupTab::luaRemoveAll(CLuaState &ls)
430 CLuaIHM::checkArgCount(ls, "CGroupTab::removeAll", 0);
431 removeAll();
432 return 0;
435 // ***************************************************************************
436 CCtrlTabButton* CGroupTab::getTabButton(sint index)
438 if(index>=0 && index<(sint)_Buttons.size())
440 return _Buttons[index];
442 return NULL;
445 // ***************************************************************************
446 int CGroupTab::luaGetTabButton(CLuaState &ls)
448 const char *funcName = "getTabButton";
449 CLuaIHM::checkArgCount(ls, funcName, 1);
450 CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
451 CCtrlTabButton* tab = getTabButton((uint) ls.toInteger(1));
452 if(tab != NULL)
454 CLuaIHM::pushUIOnStack(ls, tab);
455 return 1;
457 return 0;
460 // ***************************************************************************
461 void CGroupTab::updateFirstTabButton()
463 if(!_HideOutTabs || (_Selection<0) || _Buttons.empty() || (_Parent->getWReal()<0)
464 || _FirstTabIndex>=(sint)_Buttons.size())
465 return;
467 sint oldFirstTabIndex = _FirstTabIndex;
468 sint oldLastTabIndex = _LastTabIndex;
470 if(_FirstTabIndex<0)
472 for(uint i=0; i<_Buttons.size(); i++)
474 CCtrlTabButton * tab = _Buttons[i];
475 if(tab->getActive())
477 _FirstTabIndex = i;
478 break;
483 sint selection = _Selection;
484 if(selection>=(sint)_Buttons.size())
485 selection = _FirstTabIndex;
487 if(selection < _FirstTabIndex)
488 _FirstTabIndex = selection;
490 sint32 maxWidth = _Parent->getWReal();
491 sint32 buttonsWidth = 0;
492 _LastTabIndex = 0;
494 // desactive first tabs
495 for(uint i=0; i<(uint)_FirstTabIndex; i++)
497 CCtrlTabButton * tab = _Buttons[i];
498 if(tab->getActive())
499 tab->setActive(false);
503 // active tabs from _FirstTabIndex and search for last showed tab
504 for(uint i=_FirstTabIndex; i<_Buttons.size(); i++)
506 CCtrlTabButton * tab = _Buttons[i];
507 sint32 tabWidth = tab->getWMax();
508 if(buttonsWidth+tabWidth <= maxWidth)
510 buttonsWidth += tabWidth;
511 if(!tab->getActive())
512 tab->setActive(true);
513 _LastTabIndex = i;
515 else
516 break;
519 // check if selected tab is in showed tabs
520 if(_LastTabIndex < selection)
522 for(uint i=_LastTabIndex+1; i<=(uint)selection; i++)
524 CCtrlTabButton * tab = _Buttons[i];
525 buttonsWidth += tab->getWMax();
526 if(!tab->getActive())
527 tab->setActive(true);
530 while(buttonsWidth>maxWidth)
532 CCtrlTabButton * tab = _Buttons[_FirstTabIndex];
533 buttonsWidth -= tab->getWMax();
534 _FirstTabIndex++;
535 if(tab->getActive())
536 tab->setActive(false);
540 // add tabs before the "_FirstTabIndex" one if it remains place
541 while(buttonsWidth<maxWidth && _FirstTabIndex>0)
543 CCtrlTabButton * tab = _Buttons[_FirstTabIndex-1];
544 buttonsWidth += tab->getWMax();
545 if(buttonsWidth<=maxWidth)
547 _FirstTabIndex--;
548 if(!tab->getActive())
549 tab->setActive(true);
553 // desactive last tabs
554 for(uint i=_LastTabIndex+1; i<_Buttons.size(); i++)
556 CCtrlTabButton * tab = _Buttons[i];
557 if(tab->getActive())
558 tab->setActive(false);
561 if(!_AHOnChange.empty() && ((oldFirstTabIndex!=_FirstTabIndex) || (oldLastTabIndex!=_LastTabIndex)))
562 CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
566 // ***************************************************************************
567 int CGroupTab::luaShowTabButton(CLuaState &ls)
569 const char *funcName = "showTabButton";
570 CLuaIHM::checkArgCount(ls, funcName, 1);
571 CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
572 sint showTab = (sint)ls.toInteger(1);
574 if(showTab>=0 && showTab<(sint)_Buttons.size())
576 sint32 maxWidth = _Parent->getWReal();
577 sint32 buttonsWidth = 0;
579 if(showTab<_FirstTabIndex)
581 _FirstTabIndex = showTab;
582 sint lastTabIndex = _FirstTabIndex;
583 for(uint i=_FirstTabIndex; i<_Buttons.size(); i++)
585 CCtrlTabButton * tab = _Buttons[i];
586 sint32 tabWidth = tab->getWMax();
587 if(buttonsWidth+tabWidth <= maxWidth)
589 buttonsWidth += tabWidth;
590 if(!tab->getActive())
591 tab->setActive(true);
592 lastTabIndex = i;
594 else
595 break;
598 if(lastTabIndex <_Selection)
599 select(lastTabIndex);
600 else
601 updateFirstTabButton();
603 else if(showTab>_LastTabIndex)
605 for(uint i=_FirstTabIndex; i<=(uint)showTab; i++)
606 buttonsWidth += _Buttons[i]->getWMax();
608 while(buttonsWidth>maxWidth)
610 buttonsWidth -= _Buttons[_FirstTabIndex]->getWMax();
611 _FirstTabIndex++;
614 if(_Selection<_FirstTabIndex)
615 select(_FirstTabIndex);
616 else
617 updateFirstTabButton();
621 return 0;
624 // ***************************************************************************
625 void CGroupTab::updateCoords ()
627 if(!_Setuped)
628 setup();
630 // special for groupTab. Because the ctrl may overlap each other from left to right, they are inserted in reverse
631 // order. BUT, for correct TR/TL coord handling, must updtae in the reverse sens too!
633 // **** just basis
634 CInterfaceGroup::doUpdateCoords();
636 // **** update in reverse order
637 _XReal += _OffsetX;
638 _YReal += _OffsetY;
639 vector<CViewBase*>::reverse_iterator ite;
640 for (ite = _EltOrder.rbegin() ; ite != _EltOrder.rend(); ite++)
642 CViewBase *pIE = *ite;
643 pIE->updateCoords();
645 _XReal -= _OffsetX;
646 _YReal -= _OffsetY;
648 // **** complete with child resize
649 CInterfaceGroup::updateCoords();
651 updateFirstTabButton();
654 // ***************************************************************************
655 void CGroupTab::select(sint index)
657 if(index<0)
658 index= -1;
660 if(index<(sint)_Buttons.size())
662 sint i;
664 // validate this radio button.
665 if(index>=0)
666 _Buttons[index]->setPushed(true);
667 else
668 for(i=0;i<(sint)_Buttons.size();i++)
669 _Buttons[i]->setPushed(false);
671 _NextSelection = index;
673 // set all render layer to their correct state
674 for(i=0;i<(sint)_Buttons.size();i++)
676 // set the selected one +1, so it will be over
677 _Buttons[i]->setRenderLayer(_BaseRenderLayer + (i==index?1:0) );
678 if (i==index)
680 _Buttons[i]->setBlink(false);
681 if (_Buttons[i]->_AHOnLeftClick2 != NULL)
682 // call like if press on it
683 _Buttons[i]->_AHOnLeftClick2->execute(_Buttons[i], _Buttons[i]->getParamsOnLeftClick());
687 // show/hide all the associated groups
688 for(i=0;i<(sint)_Groups.size();i++)
690 if(_Groups[i])
691 _Groups[i]->setActive(i==index);
694 // ok!
695 _Selection= index;
697 updateFirstTabButton();
701 // ***************************************************************************
702 void CGroupTab::selectFromCtrl(CCtrlTabButton *button)
704 // search in all buttons
705 for(uint i=0;i<_Buttons.size();i++)
707 // found?
708 if(_Buttons[i]==button)
710 select(i);
711 return;
716 // ***************************************************************************
717 void CGroupTab::selectDefault(CCtrlTabButton *ifSelectionIs)
719 if(!_HideOutTabs && _Selection>=0 && _Selection<(sint)_Buttons.size() && _Buttons[_Selection]==ifSelectionIs)
721 // parse all active button
722 for(uint i=0;i<_Buttons.size();i++)
724 if(_Buttons[i]->getActive())
726 select(i);
727 return;
731 // default: unselect
732 select(-1);
736 // ***************************************************************************
737 void CGroupTab::selectDefaultIfCurrentHid()
739 if(_Selection>=0 && _Selection<(sint)_Buttons.size() &&
740 _Buttons[_Selection]!=NULL && _Buttons[_Selection]->getActive()==false)
742 selectDefault(_Buttons[_Selection]);
746 // ***************************************************************************
747 sint CGroupTab::getSelection() const
749 return _Selection;
752 NLMISC_REGISTER_OBJECT(CViewBase, CCtrlTabButton, std::string, "tab_button");
754 // ***************************************************************************
755 std::string CGroupTab::getAssociatedGroupSelection() const
757 if(_Selection>=0 && _Selection<(sint)_Buttons.size())
759 return _Buttons[_Selection]->_AssociatedGroup;
761 return "";
764 // ***************************************************************************
765 CInterfaceGroup* CGroupTab::getGroup(sint index)
767 if(index>=0 && index<(sint)_Groups.size())
769 return _Groups[index];
771 return NULL;
774 // ***************************************************************************
775 int CGroupTab::luaGetGroup(CLuaState &ls)
777 const char *funcName = "getGroup";
778 CLuaIHM::checkArgCount(ls, funcName, 1);
779 CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
780 CInterfaceGroup* group = getGroup((uint) ls.toInteger(1));
781 if(group != NULL)
783 CLuaIHM::pushUIOnStack(ls, group);
784 return 1;
786 return 0;
789 // ***************************************************************************
790 CCtrlTabButton::CCtrlTabButton(const TCtorParam &param)
791 : CCtrlTextButton(param)
793 _DefaultX= 0;
794 _AHOnLeftClick2 = NULL;
795 _BlinkDate = 0;
796 _Blinking = false;
797 _BlinkState = false;
800 std::string CCtrlTabButton::getProperty( const std::string &name ) const
802 if( name == "group" )
803 return _AssociatedGroup;
804 else
805 return CCtrlTextButton::getProperty( name );
808 void CCtrlTabButton::setProperty( const std::string &name, const std::string &value )
810 if( name == "group" )
812 _AssociatedGroup = value;
814 else
815 CCtrlTextButton::setProperty( name, value );
818 xmlNodePtr CCtrlTabButton::serialize( xmlNodePtr parentNode, const char *type ) const
820 xmlNodePtr node = CCtrlTextButton::serialize( parentNode, type );
821 if( node == NULL )
822 return NULL;
824 xmlSetProp( node, BAD_CAST "type", BAD_CAST "tab" );
825 xmlNewProp( node, BAD_CAST "group", BAD_CAST _AssociatedGroup.c_str() );
827 return node;
830 // ***************************************************************************
831 bool CCtrlTabButton::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
833 if(!CCtrlTextButton::parse(cur, parentGroup))
834 return false;
836 // if left click not setuped, set default
837 _AHOnLeftClick2 = _AHOnLeftClick;
838 string dummy;
839 _AHOnLeftClick= CAHManager::getInstance()->getAH("tab_select", dummy);
841 // read the associated group to show/hide
842 CXMLAutoPtr prop;
843 prop = (char*) xmlGetProp( cur, (xmlChar*)"group" );
844 if(prop) _AssociatedGroup= (const char*)prop;
846 // backup the x
847 _DefaultX= _X;
849 return true;
852 // ***************************************************************************
853 void CCtrlTabButton::setActive(bool state)
855 if(state!=getActive())
857 CCtrlTextButton::setActive(state);
859 // special for correct display of textbuttons. reset to 0 when the button is hid
860 if(state)
861 setX(_DefaultX);
862 else
863 setX(0);
865 // if hide, and I was the selected tab, select a default active one
866 if(state==false)
868 CGroupTab *parent= dynamic_cast<CGroupTab*>(getParent());
869 if(parent)
870 parent->selectDefault(this);
875 // ***************************************************************************
876 bool CCtrlTabButton::handleEvent (const NLGUI::CEventDescriptor &event)
878 if (event.getType() == NLGUI::CEventDescriptor::system)
880 const NLGUI::CEventDescriptorSystem &systemEvent = (const NLGUI::CEventDescriptorSystem &) event;
881 if (systemEvent.getEventTypeExtended() == NLGUI::CEventDescriptorSystem::clocktick)
882 if (_Blinking)
884 uint dbclickDelay = CWidgetManager::getInstance()->getUserDblClickDelay();
885 const CWidgetManager::SInterfaceTimes &times = CWidgetManager::getInstance()->getInterfaceTimes();
887 if (( times.thisFrameMs - _BlinkDate) > dbclickDelay)
889 if (_BlinkState)
891 setTextColorNormal(CRGBA::White);
892 setTextModulateGlobalColorNormal(false);
894 else
896 setTextColorNormal(_TextColorNormalBlink);
897 setTextModulateGlobalColorNormal(_TextModulateGlobalColorNormalBlink);
899 _BlinkState = !_BlinkState;
900 _BlinkDate = times.thisFrameMs;
904 return CCtrlTextButton::handleEvent(event);
907 // ***************************************************************************
908 void CCtrlTabButton::setBlink (bool b)
910 if (b)
912 if (!_Blinking)
914 _TextColorNormalBlink = getTextColorNormal();
915 _TextModulateGlobalColorNormalBlink = getTextModulateGlobalColorNormal();
916 CWidgetManager::getInstance()->registerClockMsgTarget(this);
918 _Blinking = true;
920 else
922 if (_Blinking)
924 CWidgetManager::getInstance()->unregisterClockMsgTarget(this);
925 setTextColorNormal(_TextColorNormalBlink);
926 setTextModulateGlobalColorNormal(_TextModulateGlobalColorNormalBlink);
928 _Blinking = false;
932 // ***************************************************************************
933 // Action handler for Tab selection
934 class CHandlerTabSelect : public IActionHandler
936 public:
937 virtual void execute (CCtrlBase *pCaller, const string &/* Params */)
939 CCtrlTabButton *but= dynamic_cast<CCtrlTabButton*>(pCaller);
941 // get the parent TabGroup
942 CGroupTab *parent= dynamic_cast<CGroupTab*>(but->getParent());
943 if(parent)
944 parent->selectFromCtrl(but);
947 REGISTER_ACTION_HANDLER(CHandlerTabSelect, "tab_select" );