diff --git a/code/nel/include/nel/gui/group_tab.h b/code/nel/include/nel/gui/group_tab.h
new file mode 100644
index 000000000..1836ed797
--- /dev/null
+++ b/code/nel/include/nel/gui/group_tab.h
@@ -0,0 +1,180 @@
+// Ryzom - MMORPG Framework
+// Copyright (C) 2010 Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+
+
+#ifndef NL_GROUP_TAB_H
+#define NL_GROUP_TAB_H
+
+#include "nel/misc/types_nl.h"
+#include "nel/gui/interface_group.h"
+#include "nel/gui/ctrl_text_button.h"
+
+namespace NLGUI
+{
+ class CCtrlTabButton;
+
+
+
+ // ***************************************************************************
+ /**
+ * Group handling Ctrl Tab, to easily simulate Tab ctrl.
+ * NB: controlled groups doesn't have to be child of the GroupTab, they are searched in order:
+ * - in this group
+ * - in the parent group
+ * - in global
+ * \author Lionel Berenguier
+ * \author Nevrax France
+ * \date 2003
+ */
+ class CGroupTab : public CInterfaceGroup
+ {
+ public:
+
+ /// Constructor
+ CGroupTab(const TCtorParam ¶m);
+
+ virtual bool parse (xmlNodePtr cur, CInterfaceGroup *parentGroup);
+ virtual void updateCoords ();
+
+ // select the ctrl tab. -1 will invalidate all.
+ void select(sint index);
+ sint getSelection() const;
+
+ // select with a CCtrlTabButton ptr
+ void selectFromCtrl(CCtrlTabButton *button);
+
+ // select a default activated tab, if the current is a special ctrlTab
+ void selectDefault(CCtrlTabButton *ifSelectionIs);
+
+ // select a default activated tab, if the current is hid
+ void selectDefaultIfCurrentHid();
+
+ // add new tab
+ void addTab(CCtrlTabButton *tabB);
+ void addTab(CCtrlTabButton *tabB, sint index);
+ int luaAddTab(CLuaState &ls);
+ int luaAddTabWithOrder(CLuaState &ls);
+
+ // remove selected tab
+ void removeTab(sint index);
+ int luaRemoveTab(CLuaState &ls);
+
+ // remove all tabs
+ void removeAll();
+ int luaRemoveAll(CLuaState &ls);
+
+ // tab number
+ void setTabButtonNb(sint32 /* val */){}
+ sint32 getTabButtonNb() const {return (sint32)_Buttons.size();}
+
+ // selection index
+ void setIndexSelection(sint32 val){select((sint)val);}
+ sint32 getIndexSelection() const {return (sint32)_NextSelection;}
+
+ // selection index
+ void setAssociatedGroupSelection(const std::string & /* assG */){}
+ std::string getAssociatedGroupSelection() const;
+
+ // get group from index
+ CInterfaceGroup* getGroup(sint index);
+ int luaGetGroup(CLuaState &ls);
+
+ // get tab from index
+ CCtrlTabButton* getTabButton(sint index);
+ int luaGetTabButton(CLuaState &ls);
+
+ // first showed tab button
+ sint32 getFirstTabButton() const {return (sint32)_FirstTabIndex;}
+
+ // last showed tab button
+ sint32 getLastTabButton() const {return (sint32)_LastTabIndex;}
+
+ // update showed tab buttons on function of GroupTab width
+ void updateFirstTabButton();
+ int luaShowTabButton(CLuaState &ls);
+
+ void dummySet(sint32 /* value */){}
+
+ REFLECT_EXPORT_START(CGroupTab, CInterfaceGroup)
+ REFLECT_LUA_METHOD("addTab", luaAddTab)
+ REFLECT_LUA_METHOD("addTabWithOrder", luaAddTabWithOrder)
+ REFLECT_LUA_METHOD("removeTab", luaRemoveTab)
+ REFLECT_LUA_METHOD("removeAll", luaRemoveAll)
+ REFLECT_LUA_METHOD("getGroup", luaGetGroup)
+ REFLECT_LUA_METHOD("getTabButton", luaGetTabButton)
+ REFLECT_LUA_METHOD("showTabButton", luaShowTabButton)
+ REFLECT_SINT32 ("tabButtonNb", getTabButtonNb, setTabButtonNb)
+ REFLECT_SINT32 ("selection", getIndexSelection, setIndexSelection)
+ REFLECT_SINT32 ("firstTabButton", getFirstTabButton, dummySet)
+ REFLECT_SINT32 ("lastTabButton", getLastTabButton, dummySet)
+ REFLECT_STRING ("associatedGroupSelection", getAssociatedGroupSelection, setAssociatedGroupSelection)
+ REFLECT_EXPORT_END
+
+ private:
+
+ std::vector _Buttons; // can't be NULL.
+ std::vector _Groups; // may be NULL
+ sint _Selection;
+ sint _NextSelection;
+ sint _BaseRenderLayer;
+ bool _Setuped;
+ bool _HideOutTabs;
+ sint _FirstTabIndex;
+ sint _LastTabIndex;
+
+ std::string _AHOnChange;
+ std::string _ParamsOnChange;
+
+ void setup();
+ };
+
+ // ***************************************************************************
+ /**
+ * Used with CGroupTab
+ */
+ class CCtrlTabButton : public CCtrlTextButton
+ {
+ public:
+
+ CCtrlTabButton(const TCtorParam ¶m);
+
+ virtual bool parse (xmlNodePtr cur, CInterfaceGroup *parentGroup);
+
+ virtual void setActive(bool state);
+
+ virtual bool handleEvent (const NLGUI::CEventDescriptor &event);
+
+ void setBlink (bool b);
+
+ std::string _AssociatedGroup;
+ IActionHandler *_AHOnLeftClick2;
+
+ private:
+
+ sint32 _DefaultX;
+ bool _Blinking;
+ NLMISC::CRGBA _TextColorNormalBlink;
+ bool _TextModulateGlobalColorNormalBlink;
+ sint64 _BlinkDate;
+ bool _BlinkState;
+ };
+
+}
+
+#endif // NL_GROUP_TAB_H
+
+/* End of group_tab.h */
diff --git a/code/nel/src/gui/group_tab.cpp b/code/nel/src/gui/group_tab.cpp
new file mode 100644
index 000000000..a286d661f
--- /dev/null
+++ b/code/nel/src/gui/group_tab.cpp
@@ -0,0 +1,852 @@
+// Ryzom - MMORPG Framework
+// Copyright (C) 2010 Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#include "nel/gui/group_tab.h"
+#include "nel/misc/xml_auto_ptr.h"
+#include "nel/gui/lua_ihm.h"
+#include "nel/gui/widget_manager.h"
+#include "nel/gui/interface_group.h"
+#include "nel/gui/view_text.h"
+
+using namespace std;
+using namespace NLMISC;
+
+NLMISC_REGISTER_OBJECT(CViewBase, CGroupTab, std::string, "tab");
+
+namespace NLGUI
+{
+
+ // ***************************************************************************
+ CGroupTab::CGroupTab(const TCtorParam ¶m)
+ : CInterfaceGroup(param)
+ {
+ _Selection= -1;
+ _NextSelection = -1;
+ _BaseRenderLayer= 0;
+ _Setuped= false;
+ _HideOutTabs = false;
+ _FirstTabIndex = -1;
+ _LastTabIndex = -1;
+ }
+
+
+ // ***************************************************************************
+ bool CGroupTab::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
+ {
+ if( !CInterfaceGroup::parse(cur, parentGroup) )
+ return false;
+
+ CXMLAutoPtr prop((const char*)xmlGetProp(cur, (xmlChar*)"hide_out_tabs"));
+ if (prop)
+ {
+ _HideOutTabs = convertBool(prop);
+ }
+
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"onchange" );
+ if (prop) _AHOnChange = (const char *) prop;
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"onchange_params" );
+ if (prop) _ParamsOnChange = (const char *) prop;
+
+ return true;
+ }
+
+ // ***************************************************************************
+ void CGroupTab::setup()
+ {
+ if(_Setuped)
+ return;
+ _Setuped= true;
+
+ _Buttons.clear();
+ _Groups.clear();
+
+ /* Buttons must be named tab0,tab1,tab2...
+ and tab_array0_0, tab_array0_1 .... (for vector of tab)
+ Only 10 tab array are allowed
+ */
+ for(sint tabArrayIndex= -1;tabArrayIndex<10;tabArrayIndex++)
+ {
+ // prefix according to array or not
+ string prefix;
+ if(tabArrayIndex==-1)
+ prefix= "tab";
+ else
+ prefix= toString("tab_array%d_", tabArrayIndex);
+
+ // for all tab of this type (standard tab or array of tab), find the Buttons and groups.
+ uint tabIndex=0;
+ for(;;)
+ {
+ // find the ctrl named "tab0"
+ CCtrlTabButton *but= dynamic_cast(getCtrl(toString("%s%d", prefix.c_str(), tabIndex)));
+ if(!but)
+ break;
+
+ // find the associated group
+ CInterfaceGroup *pGroup = NULL;
+ CInterfaceGroup *pFather = this;
+
+ while ((pGroup == NULL) && (pFather != NULL))
+ {
+ pGroup = pFather->getGroup(but->_AssociatedGroup);
+ pFather = pFather->getParent();
+ }
+
+ // add to the button and group list
+ _Buttons.push_back(but);
+ _Groups.push_back(pGroup);
+
+ // try next
+ tabIndex++;
+ }
+ }
+
+ // at the first setup, select by default the 1st
+ if(_Selection<0)
+ select(0);
+ }
+
+ // ***************************************************************************
+ void CGroupTab::addTab(CCtrlTabButton * tabB)
+ {
+ addCtrl(tabB);
+ _Setuped = false;
+ updateCoords();
+ selectFromCtrl(tabB);
+
+ if(_HideOutTabs && !_AHOnChange.empty())
+ CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
+
+ }
+
+ // ***************************************************************************
+ void CGroupTab::addTab(CCtrlTabButton * tabB, sint index)
+ {
+ if(index<(sint)_Buttons.size() && index>=0)
+ {
+ vector buttons = _Buttons;
+
+ for(sint i=0;i<(sint)_Buttons.size();i++)
+ delCtrl(_Buttons[i], true);
+
+ _Setuped = false;
+ updateCoords();
+
+ uint count=0;
+ CCtrlTabButton* lastTab=NULL;
+ for(sint i=0;i<(sint)buttons.size();i++)
+ {
+ if(i==index)
+ {
+ tabB->setId("tab" + NLMISC::toString(count));
+ tabB->setParentPos(lastTab);
+ if(i==0)
+ tabB->setParentPosRef(Hotspot_TL);
+ else
+ tabB->setParentPosRef(Hotspot_TR);
+ tabB->setPosRef(Hotspot_TL);
+
+ addCtrl(tabB);
+ lastTab = tabB;
+ count++;
+ }
+
+ buttons[i]->setId("tab" + NLMISC::toString(count));
+ buttons[i]->setParentPos(lastTab);
+ if(i==0 && index!=0)
+ buttons[i]->setParentPosRef(Hotspot_TL);
+ else
+ buttons[i]->setParentPosRef(Hotspot_TR);
+ buttons[i]->setPosRef(Hotspot_TL);
+
+ addCtrl(buttons[i]);
+
+ lastTab = buttons[i];
+ count++;
+ }
+
+ _Setuped = false;
+ updateCoords();
+
+ // we have added a new button in first position
+ // then it must recover the reference
+ if(index==0)
+ {
+ CCtrlTabButton * tab0 = _Buttons[0];
+ for(uint i=0; i<_Buttons.size(); ++i)
+ _Buttons[i]->initRBRefFromRadioButton(tab0);
+
+ select(_Selection);
+ }
+ else
+ {
+ CCtrlTabButton * tab0 = _Buttons[0];
+ _Buttons[index]->initRBRefFromRadioButton(tab0);
+ }
+ }
+ else
+ {
+ tabB->setId(string("tab") + NLMISC::toString(_Buttons.size()));
+
+ if(_Buttons.size()==0)
+ {
+ tabB->setParentPos(NULL);
+ tabB->setParentPosRef(Hotspot_TL);
+ }
+ else
+ {
+ tabB->setParentPos(_Buttons[_Buttons.size()-1]);
+ tabB->setParentPosRef(Hotspot_TR);
+ }
+ tabB->setPosRef(Hotspot_TL);
+
+ addCtrl(tabB);
+ }
+
+ _Setuped = false;
+ updateCoords();
+
+ if(_HideOutTabs && !_AHOnChange.empty())
+ CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
+
+ }
+
+ // ***************************************************************************
+ int CGroupTab::luaAddTab(CLuaState &ls)
+ {
+ CLuaIHM::checkArgCount(ls, "CGroupTab::addTab", 1);
+ CCtrlTabButton *tabB = dynamic_cast(CLuaIHM::getUIOnStack(ls, 1));
+ if (tabB)
+ {
+ // don't use addTab to avoid selection of new tab
+ addCtrl(tabB);
+
+ _Setuped = false;
+ updateCoords();
+
+ if(_HideOutTabs && !_AHOnChange.empty())
+ CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
+
+ }
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupTab::luaAddTabWithOrder(CLuaState &ls)
+ {
+ const char *funcName = "addTabWithOrder";
+ CLuaIHM::checkArgCount(ls, funcName, 2);
+ CLuaIHM::checkArgType(ls, funcName, 2, LUA_TNUMBER);
+
+ CCtrlTabButton *tabB = dynamic_cast(CLuaIHM::getUIOnStack(ls, 1));
+ if (tabB)
+ {
+ // don't use addTab to avoid selection of new tab
+ addTab(tabB, (sint) ls.toNumber(2));
+ }
+ return 0;
+ }
+
+ // ***************************************************************************
+ void CGroupTab::removeTab(sint index)
+ {
+ if(!(index>=0 && index<(sint)_Buttons.size()))
+ return;
+
+ vector buttons = _Buttons;
+
+ for(sint i=0;i<(sint)_Buttons.size();i++)
+ {
+ bool deleteElt = (i!=index);
+ CViewText* tabVT = _Buttons[i]->getViewText();
+ if(tabVT && !deleteElt)
+ delView(tabVT, deleteElt);
+
+ delCtrl(_Buttons[i], deleteElt);
+
+ if(!deleteElt)
+ (_Groups[i]->getParent())->delGroup(_Groups[i], deleteElt);
+ }
+ _Setuped = false;
+ updateCoords();
+
+ uint count=0;
+ CCtrlTabButton* lastTab = NULL;
+ for(sint i=0;i<(sint)buttons.size();i++)
+ {
+ if(i!=index)
+ {
+ buttons[i]->setId("tab"+NLMISC::toString(count));
+ buttons[i]->setParentPos(lastTab);
+ if((i==0) || (index==0 && i==1))
+ buttons[i]->setParentPosRef(Hotspot_TL);
+ else
+ _Buttons[i]->setParentPosRef(Hotspot_TR);
+
+ buttons[i]->setPosRef(Hotspot_TL);
+
+ lastTab = buttons[i];
+ addCtrl(buttons[i]);
+ count++;
+ }
+ }
+
+ _Setuped = false;
+ updateCoords();
+
+ // we have removed the first button which is the only one to own the reference
+ // then the new first button recovers the reference
+ if(index==0)
+ {
+ CCtrlTabButton * tab0 = _Buttons[0];
+ for(uint i=0; i<_Buttons.size(); ++i)
+ _Buttons[i]->initRBRefFromRadioButton(tab0);
+
+ select(_Selection);
+ }
+
+ if(_HideOutTabs)
+ {
+ select(_FirstTabIndex);
+
+ if(!_AHOnChange.empty())
+ CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
+ }
+ }
+
+ // ***************************************************************************
+
+ int CGroupTab::luaRemoveTab(CLuaState &ls)
+ {
+ const char *funcName = "removeTab";
+ CLuaIHM::checkArgCount(ls, funcName, 1);
+ CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
+ removeTab((uint) ls.toNumber(1));
+ return 0;
+ }
+
+ // ***************************************************************************
+ void CGroupTab::removeAll()
+ {
+ for(sint i=0;i<(sint)_Buttons.size();i++)
+ {
+ CViewText* tabVT = _Buttons[i]->getViewText();
+ if(tabVT)
+ delView(tabVT, false);
+
+ delCtrl(_Buttons[i], false);
+ (_Groups[i]->getParent())->delGroup(_Groups[i], false);
+ }
+
+ _Setuped = false;
+ updateCoords();
+ }
+
+ // ***************************************************************************
+
+ int CGroupTab::luaRemoveAll(CLuaState &ls)
+ {
+ CLuaIHM::checkArgCount(ls, "CGroupTab::removeAll", 0);
+ removeAll();
+ return 0;
+ }
+
+ // ***************************************************************************
+ CCtrlTabButton* CGroupTab::getTabButton(sint index)
+ {
+ if(index>=0 && index<(sint)_Buttons.size())
+ {
+ return _Buttons[index];
+ }
+ return NULL;
+ }
+
+ // ***************************************************************************
+ int CGroupTab::luaGetTabButton(CLuaState &ls)
+ {
+ const char *funcName = "getTabButton";
+ CLuaIHM::checkArgCount(ls, funcName, 1);
+ CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
+ CCtrlTabButton* tab = getTabButton((uint) ls.toNumber(1));
+ if(tab != NULL)
+ {
+ CLuaIHM::pushUIOnStack(ls, tab);
+ return 1;
+ }
+ return 0;
+ }
+
+ // ***************************************************************************
+ void CGroupTab::updateFirstTabButton()
+ {
+ if(!_HideOutTabs || (_Selection<0) || (_Buttons.size()==0) || (_Parent->getWReal()<0)
+ || _FirstTabIndex>=(sint)_Buttons.size())
+ return;
+
+ sint oldFirstTabIndex = _FirstTabIndex;
+ sint oldLastTabIndex = _LastTabIndex;
+
+ if(_FirstTabIndex<0)
+ {
+ for(uint i=0; i<_Buttons.size(); i++)
+ {
+ CCtrlTabButton * tab = _Buttons[i];
+ if(tab->getActive())
+ {
+ _FirstTabIndex = i;
+ break;
+ }
+ }
+ }
+
+ sint selection = _Selection;
+ if(selection>=(sint)_Buttons.size())
+ selection = _FirstTabIndex;
+
+ if(selection < _FirstTabIndex)
+ _FirstTabIndex = selection;
+
+ sint32 maxWidth = _Parent->getWReal();
+ sint32 buttonsWidth = 0;
+ _LastTabIndex = 0;
+
+ // desactive first tabs
+ for(uint i=0; i<(uint)_FirstTabIndex; i++)
+ {
+ CCtrlTabButton * tab = _Buttons[i];
+ if(tab->getActive())
+ tab->setActive(false);
+ }
+
+
+ // active tabs from _FirstTabIndex and search for last showed tab
+ for(uint i=_FirstTabIndex; i<_Buttons.size(); i++)
+ {
+ CCtrlTabButton * tab = _Buttons[i];
+ sint32 tabWidth = tab->getWMax();
+ if(buttonsWidth+tabWidth <= maxWidth)
+ {
+ buttonsWidth += tabWidth;
+ if(!tab->getActive())
+ tab->setActive(true);
+ _LastTabIndex = i;
+ }
+ else
+ break;
+ }
+
+ // check if selected tab is in showed tabs
+ if(_LastTabIndex < selection)
+ {
+ for(uint i=_LastTabIndex+1; i<=(uint)selection; i++)
+ {
+ CCtrlTabButton * tab = _Buttons[i];
+ buttonsWidth += tab->getWMax();
+ if(!tab->getActive())
+ tab->setActive(true);
+ }
+
+ while(buttonsWidth>maxWidth)
+ {
+ CCtrlTabButton * tab = _Buttons[_FirstTabIndex];
+ buttonsWidth -= tab->getWMax();
+ _FirstTabIndex++;
+ if(tab->getActive())
+ tab->setActive(false);
+ }
+ }
+
+ // add tabs before the "_FirstTabIndex" one if it remains place
+ while(buttonsWidth0)
+ {
+ CCtrlTabButton * tab = _Buttons[_FirstTabIndex-1];
+ buttonsWidth += tab->getWMax();
+ if(buttonsWidth<=maxWidth)
+ {
+ _FirstTabIndex--;
+ if(!tab->getActive())
+ tab->setActive(true);
+ }
+ }
+
+ // desactive last tabs
+ for(uint i=_LastTabIndex+1; i<_Buttons.size(); i++)
+ {
+ CCtrlTabButton * tab = _Buttons[i];
+ if(tab->getActive())
+ tab->setActive(false);
+ }
+
+ if(!_AHOnChange.empty() && ((oldFirstTabIndex!=_FirstTabIndex) || (oldLastTabIndex!=_LastTabIndex)))
+ CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
+
+ }
+
+ // ***************************************************************************
+ int CGroupTab::luaShowTabButton(CLuaState &ls)
+ {
+ const char *funcName = "showTabButton";
+ CLuaIHM::checkArgCount(ls, funcName, 1);
+ CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
+ sint showTab = (sint)ls.toNumber(1);
+
+ if(showTab>=0 && showTab<(sint)_Buttons.size())
+ {
+ sint32 maxWidth = _Parent->getWReal();
+ sint32 buttonsWidth = 0;
+
+ if(showTab<_FirstTabIndex)
+ {
+ _FirstTabIndex = showTab;
+ sint lastTabIndex = _FirstTabIndex;
+ for(uint i=_FirstTabIndex; i<_Buttons.size(); i++)
+ {
+ CCtrlTabButton * tab = _Buttons[i];
+ sint32 tabWidth = tab->getWMax();
+ if(buttonsWidth+tabWidth <= maxWidth)
+ {
+ buttonsWidth += tabWidth;
+ if(!tab->getActive())
+ tab->setActive(true);
+ lastTabIndex = i;
+ }
+ else
+ break;
+ }
+
+ if(lastTabIndex <_Selection)
+ select(lastTabIndex);
+ else
+ updateFirstTabButton();
+ }
+ else if(showTab>_LastTabIndex)
+ {
+ for(uint i=_FirstTabIndex; i<=(uint)showTab; i++)
+ buttonsWidth += _Buttons[i]->getWMax();
+
+ while(buttonsWidth>maxWidth)
+ {
+ buttonsWidth -= _Buttons[_FirstTabIndex]->getWMax();
+ _FirstTabIndex++;
+ }
+
+ if(_Selection<_FirstTabIndex)
+ select(_FirstTabIndex);
+ else
+ updateFirstTabButton();
+ }
+ }
+
+ return 0;
+ }
+
+ // ***************************************************************************
+ void CGroupTab::updateCoords ()
+ {
+ if(!_Setuped)
+ setup();
+
+ // special for groupTab. Because the ctrl may overlap each other from left to right, they are inserted in reverse
+ // order. BUT, for correct TR/TL coord handling, must updtae in the reverse sens too!
+
+ // **** just basis
+ CInterfaceGroup::doUpdateCoords();
+
+ // **** update in reverse order
+ _XReal += _OffsetX;
+ _YReal += _OffsetY;
+ vector::reverse_iterator ite;
+ for (ite = _EltOrder.rbegin() ; ite != _EltOrder.rend(); ite++)
+ {
+ CViewBase *pIE = *ite;
+ pIE->updateCoords();
+ }
+ _XReal -= _OffsetX;
+ _YReal -= _OffsetY;
+
+ // **** complete with child resize
+ CInterfaceGroup::updateCoords();
+
+ updateFirstTabButton();
+ }
+
+ // ***************************************************************************
+ void CGroupTab::select(sint index)
+ {
+ if(index<0)
+ index= -1;
+
+ if(index<(sint)_Buttons.size())
+ {
+ sint i;
+
+ // validate this radio button.
+ if(index>=0)
+ _Buttons[index]->setPushed(true);
+ else
+ for(i=0;i<(sint)_Buttons.size();i++)
+ _Buttons[i]->setPushed(false);
+
+ _NextSelection = index;
+
+ // set all render layer to their correct state
+ for(i=0;i<(sint)_Buttons.size();i++)
+ {
+ // set the selected one +1, so it will be over
+ _Buttons[i]->setRenderLayer(_BaseRenderLayer + (i==index?1:0) );
+ if (i==index)
+ {
+ _Buttons[i]->setBlink(false);
+ if (_Buttons[i]->_AHOnLeftClick2 != NULL)
+ // call like if press on it
+ _Buttons[i]->_AHOnLeftClick2->execute(_Buttons[i], _Buttons[i]->getParamsOnLeftClick());
+ }
+ }
+
+ // show/hide all the associated groups
+ for(i=0;i<(sint)_Groups.size();i++)
+ {
+ if(_Groups[i])
+ _Groups[i]->setActive(i==index);
+ }
+
+ // ok!
+ _Selection= index;
+
+ updateFirstTabButton();
+ }
+ }
+
+ // ***************************************************************************
+ void CGroupTab::selectFromCtrl(CCtrlTabButton *button)
+ {
+ // search in all buttons
+ for(uint i=0;i<_Buttons.size();i++)
+ {
+ // found?
+ if(_Buttons[i]==button)
+ {
+ select(i);
+ return;
+ }
+ }
+ }
+
+ // ***************************************************************************
+ void CGroupTab::selectDefault(CCtrlTabButton *ifSelectionIs)
+ {
+ if(!_HideOutTabs && _Selection>=0 && _Selection<(sint)_Buttons.size() && _Buttons[_Selection]==ifSelectionIs)
+ {
+ // parse all active button
+ for(uint i=0;i<_Buttons.size();i++)
+ {
+ if(_Buttons[i]->getActive())
+ {
+ select(i);
+ return;
+ }
+ }
+
+ // default: unselect
+ select(-1);
+ }
+ }
+
+ // ***************************************************************************
+ void CGroupTab::selectDefaultIfCurrentHid()
+ {
+ if(_Selection>=0 && _Selection<(sint)_Buttons.size() &&
+ _Buttons[_Selection]!=NULL && _Buttons[_Selection]->getActive()==false)
+ {
+ selectDefault(_Buttons[_Selection]);
+ }
+ }
+
+ // ***************************************************************************
+ sint CGroupTab::getSelection() const
+ {
+ return _Selection;
+ }
+
+ NLMISC_REGISTER_OBJECT(CViewBase, CCtrlTabButton, std::string, "tab_button");
+
+ // ***************************************************************************
+ std::string CGroupTab::getAssociatedGroupSelection() const
+ {
+ if(_Selection>=0 && _Selection<(sint)_Buttons.size())
+ {
+ return _Buttons[_Selection]->_AssociatedGroup;
+ }
+ return "";
+ }
+
+ // ***************************************************************************
+ CInterfaceGroup* CGroupTab::getGroup(sint index)
+ {
+ if(index>=0 && index<(sint)_Groups.size())
+ {
+ return _Groups[index];
+ }
+ return NULL;
+ }
+
+ // ***************************************************************************
+ int CGroupTab::luaGetGroup(CLuaState &ls)
+ {
+ const char *funcName = "getGroup";
+ CLuaIHM::checkArgCount(ls, funcName, 1);
+ CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
+ CInterfaceGroup* group = getGroup((uint) ls.toNumber(1));
+ if(group != NULL)
+ {
+ CLuaIHM::pushUIOnStack(ls, group);
+ return 1;
+ }
+ return 0;
+ }
+
+ // ***************************************************************************
+ CCtrlTabButton::CCtrlTabButton(const TCtorParam ¶m)
+ : CCtrlTextButton(param)
+ {
+ _DefaultX= 0;
+ _AHOnLeftClick2 = NULL;
+ _BlinkDate = 0;
+ _Blinking = false;
+ _BlinkState = false;
+ }
+
+ // ***************************************************************************
+ bool CCtrlTabButton::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
+ {
+ if(!CCtrlTextButton::parse(cur, parentGroup))
+ return false;
+
+ // if left click not setuped, set default
+ _AHOnLeftClick2 = _AHOnLeftClick;
+ string dummy;
+ _AHOnLeftClick= CAHManager::getInstance()->getAH("tab_select", dummy);
+
+ // read the associated group to show/hide
+ CXMLAutoPtr prop;
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"group" );
+ if(prop) _AssociatedGroup= (const char*)prop;
+
+ // backup the x
+ _DefaultX= _X;
+
+ return true;
+ }
+
+ // ***************************************************************************
+ void CCtrlTabButton::setActive(bool state)
+ {
+ if(state!=getActive())
+ {
+ CCtrlTextButton::setActive(state);
+
+ // special for correct display of textbuttons. reset to 0 when the button is hid
+ if(state)
+ setX(_DefaultX);
+ else
+ setX(0);
+
+ // if hide, and I was the selected tab, select a default active one
+ if(state==false)
+ {
+ CGroupTab *parent= dynamic_cast(getParent());
+ if(parent)
+ parent->selectDefault(this);
+ }
+ }
+ }
+
+ // ***************************************************************************
+ bool CCtrlTabButton::handleEvent (const NLGUI::CEventDescriptor &event)
+ {
+ if (event.getType() == NLGUI::CEventDescriptor::system)
+ {
+ const NLGUI::CEventDescriptorSystem &systemEvent = (const NLGUI::CEventDescriptorSystem &) event;
+ if (systemEvent.getEventTypeExtended() == NLGUI::CEventDescriptorSystem::clocktick)
+ if (_Blinking)
+ {
+ uint dbclickDelay = CWidgetManager::getInstance()->getUserDblClickDelay();
+ const CWidgetManager::SInterfaceTimes × = CWidgetManager::getInstance()->getInterfaceTimes();
+
+ if (( times.thisFrameMs - _BlinkDate) > dbclickDelay)
+ {
+ if (_BlinkState)
+ {
+ setTextColorNormal(CRGBA::White);
+ setTextModulateGlobalColorNormal(false);
+ }
+ else
+ {
+ setTextColorNormal(_TextColorNormalBlink);
+ setTextModulateGlobalColorNormal(_TextModulateGlobalColorNormalBlink);
+ }
+ _BlinkState = !_BlinkState;
+ _BlinkDate = times.thisFrameMs;
+ }
+ }
+ }
+ return CCtrlTextButton::handleEvent(event);
+ }
+
+ // ***************************************************************************
+ void CCtrlTabButton::setBlink (bool b)
+ {
+ if (b)
+ {
+ if (!_Blinking)
+ {
+ _TextColorNormalBlink = getTextColorNormal();
+ _TextModulateGlobalColorNormalBlink = getTextModulateGlobalColorNormal();
+ CWidgetManager::getInstance()->registerClockMsgTarget(this);
+ }
+ _Blinking = true;
+ }
+ else
+ {
+ if (_Blinking)
+ {
+ CWidgetManager::getInstance()->unregisterClockMsgTarget(this);
+ setTextColorNormal(_TextColorNormalBlink);
+ setTextModulateGlobalColorNormal(_TextModulateGlobalColorNormalBlink);
+ }
+ _Blinking = false;
+ }
+ }
+
+ // ***************************************************************************
+ // Action handler for Tab selection
+ class CHandlerTabSelect : public IActionHandler
+ {
+ public:
+ virtual void execute (CCtrlBase *pCaller, const string &/* Params */)
+ {
+ CCtrlTabButton *but= dynamic_cast(pCaller);
+
+ // get the parent TabGroup
+ CGroupTab *parent= dynamic_cast(but->getParent());
+ if(parent)
+ parent->selectFromCtrl(but);
+ }
+ };
+ REGISTER_ACTION_HANDLER(CHandlerTabSelect, "tab_select" );
+
+}
+
diff --git a/code/ryzom/client/src/client_chat_manager.cpp b/code/ryzom/client/src/client_chat_manager.cpp
index bbb52e524..8f12a17a6 100644
--- a/code/ryzom/client/src/client_chat_manager.cpp
+++ b/code/ryzom/client/src/client_chat_manager.cpp
@@ -34,7 +34,7 @@
#include "permanent_ban.h"
#include "global.h"
#include "nel/gui/ctrl_text_button.h"
-#include "interface_v3/group_tab.h"
+#include "nel/gui/group_tab.h"
#include "string_manager_client.h"
#include "game_share/generic_xml_msg_mngr.h"
diff --git a/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp b/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp
index d329d8f04..af540da96 100644
--- a/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp
+++ b/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp
@@ -35,7 +35,7 @@
#include "bot_chat_manager.h"
#include "dbctrl_sheet.h"
#include "nel/gui/group_editbox.h"
-#include "group_tab.h"
+#include "nel/gui/group_tab.h"
#include "nel/gui/group_container.h"
#include "action_handler_help.h"
#include "../string_manager_client.h"
diff --git a/code/ryzom/client/src/interface_v3/chat_window.cpp b/code/ryzom/client/src/interface_v3/chat_window.cpp
index fe5d12cf4..9ecbbd630 100644
--- a/code/ryzom/client/src/interface_v3/chat_window.cpp
+++ b/code/ryzom/client/src/interface_v3/chat_window.cpp
@@ -32,7 +32,7 @@
//
#include "nel/gui/group_container.h"
#include "nel/gui/group_editbox.h"
-#include "group_tab.h"
+#include "nel/gui/group_tab.h"
#include "interface_manager.h"
#include "nel/gui/action_handler.h"
#include "../client_chat_manager.h"
diff --git a/code/ryzom/client/src/interface_v3/chat_window.h b/code/ryzom/client/src/interface_v3/chat_window.h
index add950b54..ee8aafce3 100644
--- a/code/ryzom/client/src/interface_v3/chat_window.h
+++ b/code/ryzom/client/src/interface_v3/chat_window.h
@@ -32,6 +32,7 @@ namespace NLGUI
class CGroupList;
class CGroupEditBox;
class CGroupContainer;
+ class CCtrlTabButton;
}
class CChatWindow;
@@ -207,7 +208,7 @@ protected:
std::vector _FreeTellers;
- void getAssociatedSubWindow(CChatGroup::TGroupType gt, uint32 dynamicChatDbIndex, NLGUI::CGroupList *&gl, class CCtrlTabButton *&tab);
+ void getAssociatedSubWindow(CChatGroup::TGroupType gt, uint32 dynamicChatDbIndex, NLGUI::CGroupList *&gl, NLGUI::CCtrlTabButton *&tab);
void updateFreeTellerHeader(NLGUI::CGroupContainer &ft);
private:
diff --git a/code/ryzom/client/src/interface_v3/group_tab.cpp b/code/ryzom/client/src/interface_v3/group_tab.cpp
deleted file mode 100644
index c91b2f217..000000000
--- a/code/ryzom/client/src/interface_v3/group_tab.cpp
+++ /dev/null
@@ -1,847 +0,0 @@
-// Ryzom - MMORPG Framework
-// Copyright (C) 2010 Winch Gate Property Limited
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-#include "group_tab.h"
-#include "nel/misc/xml_auto_ptr.h"
-#include "nel/gui/lua_ihm.h"
-#include "nel/gui/widget_manager.h"
-#include "nel/gui/interface_group.h"
-#include "nel/gui/view_text.h"
-
-using namespace std;
-using namespace NLMISC;
-
-NLMISC_REGISTER_OBJECT(CViewBase, CGroupTab, std::string, "tab");
-
-// ***************************************************************************
-CGroupTab::CGroupTab(const TCtorParam ¶m)
- : CInterfaceGroup(param)
-{
- _Selection= -1;
- _NextSelection = -1;
- _BaseRenderLayer= 0;
- _Setuped= false;
- _HideOutTabs = false;
- _FirstTabIndex = -1;
- _LastTabIndex = -1;
-}
-
-
-// ***************************************************************************
-bool CGroupTab::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
-{
- if( !CInterfaceGroup::parse(cur, parentGroup) )
- return false;
-
- CXMLAutoPtr prop((const char*)xmlGetProp(cur, (xmlChar*)"hide_out_tabs"));
- if (prop)
- {
- _HideOutTabs = convertBool(prop);
- }
-
- prop = (char*) xmlGetProp( cur, (xmlChar*)"onchange" );
- if (prop) _AHOnChange = (const char *) prop;
- prop = (char*) xmlGetProp( cur, (xmlChar*)"onchange_params" );
- if (prop) _ParamsOnChange = (const char *) prop;
-
- return true;
-}
-
-// ***************************************************************************
-void CGroupTab::setup()
-{
- if(_Setuped)
- return;
- _Setuped= true;
-
- _Buttons.clear();
- _Groups.clear();
-
- /* Buttons must be named tab0,tab1,tab2...
- and tab_array0_0, tab_array0_1 .... (for vector of tab)
- Only 10 tab array are allowed
- */
- for(sint tabArrayIndex= -1;tabArrayIndex<10;tabArrayIndex++)
- {
- // prefix according to array or not
- string prefix;
- if(tabArrayIndex==-1)
- prefix= "tab";
- else
- prefix= toString("tab_array%d_", tabArrayIndex);
-
- // for all tab of this type (standard tab or array of tab), find the Buttons and groups.
- uint tabIndex=0;
- for(;;)
- {
- // find the ctrl named "tab0"
- CCtrlTabButton *but= dynamic_cast(getCtrl(toString("%s%d", prefix.c_str(), tabIndex)));
- if(!but)
- break;
-
- // find the associated group
- CInterfaceGroup *pGroup = NULL;
- CInterfaceGroup *pFather = this;
-
- while ((pGroup == NULL) && (pFather != NULL))
- {
- pGroup = pFather->getGroup(but->_AssociatedGroup);
- pFather = pFather->getParent();
- }
-
- // add to the button and group list
- _Buttons.push_back(but);
- _Groups.push_back(pGroup);
-
- // try next
- tabIndex++;
- }
- }
-
- // at the first setup, select by default the 1st
- if(_Selection<0)
- select(0);
-}
-
-// ***************************************************************************
-void CGroupTab::addTab(CCtrlTabButton * tabB)
-{
- addCtrl(tabB);
- _Setuped = false;
- updateCoords();
- selectFromCtrl(tabB);
-
- if(_HideOutTabs && !_AHOnChange.empty())
- CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
-
-}
-
-// ***************************************************************************
-void CGroupTab::addTab(CCtrlTabButton * tabB, sint index)
-{
- if(index<(sint)_Buttons.size() && index>=0)
- {
- vector buttons = _Buttons;
-
- for(sint i=0;i<(sint)_Buttons.size();i++)
- delCtrl(_Buttons[i], true);
-
- _Setuped = false;
- updateCoords();
-
- uint count=0;
- CCtrlTabButton* lastTab=NULL;
- for(sint i=0;i<(sint)buttons.size();i++)
- {
- if(i==index)
- {
- tabB->setId("tab" + NLMISC::toString(count));
- tabB->setParentPos(lastTab);
- if(i==0)
- tabB->setParentPosRef(Hotspot_TL);
- else
- tabB->setParentPosRef(Hotspot_TR);
- tabB->setPosRef(Hotspot_TL);
-
- addCtrl(tabB);
- lastTab = tabB;
- count++;
- }
-
- buttons[i]->setId("tab" + NLMISC::toString(count));
- buttons[i]->setParentPos(lastTab);
- if(i==0 && index!=0)
- buttons[i]->setParentPosRef(Hotspot_TL);
- else
- buttons[i]->setParentPosRef(Hotspot_TR);
- buttons[i]->setPosRef(Hotspot_TL);
-
- addCtrl(buttons[i]);
-
- lastTab = buttons[i];
- count++;
- }
-
- _Setuped = false;
- updateCoords();
-
- // we have added a new button in first position
- // then it must recover the reference
- if(index==0)
- {
- CCtrlTabButton * tab0 = _Buttons[0];
- for(uint i=0; i<_Buttons.size(); ++i)
- _Buttons[i]->initRBRefFromRadioButton(tab0);
-
- select(_Selection);
- }
- else
- {
- CCtrlTabButton * tab0 = _Buttons[0];
- _Buttons[index]->initRBRefFromRadioButton(tab0);
- }
- }
- else
- {
- tabB->setId(string("tab") + NLMISC::toString(_Buttons.size()));
-
- if(_Buttons.size()==0)
- {
- tabB->setParentPos(NULL);
- tabB->setParentPosRef(Hotspot_TL);
- }
- else
- {
- tabB->setParentPos(_Buttons[_Buttons.size()-1]);
- tabB->setParentPosRef(Hotspot_TR);
- }
- tabB->setPosRef(Hotspot_TL);
-
- addCtrl(tabB);
- }
-
- _Setuped = false;
- updateCoords();
-
- if(_HideOutTabs && !_AHOnChange.empty())
- CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
-
-}
-
-// ***************************************************************************
-int CGroupTab::luaAddTab(CLuaState &ls)
-{
- CLuaIHM::checkArgCount(ls, "CGroupTab::addTab", 1);
- CCtrlTabButton *tabB = dynamic_cast(CLuaIHM::getUIOnStack(ls, 1));
- if (tabB)
- {
- // don't use addTab to avoid selection of new tab
- addCtrl(tabB);
-
- _Setuped = false;
- updateCoords();
-
- if(_HideOutTabs && !_AHOnChange.empty())
- CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
-
- }
- return 0;
-}
-
-// ***************************************************************************
-int CGroupTab::luaAddTabWithOrder(CLuaState &ls)
-{
- const char *funcName = "addTabWithOrder";
- CLuaIHM::checkArgCount(ls, funcName, 2);
- CLuaIHM::checkArgType(ls, funcName, 2, LUA_TNUMBER);
-
- CCtrlTabButton *tabB = dynamic_cast(CLuaIHM::getUIOnStack(ls, 1));
- if (tabB)
- {
- // don't use addTab to avoid selection of new tab
- addTab(tabB, (sint) ls.toNumber(2));
- }
- return 0;
-}
-
-// ***************************************************************************
-void CGroupTab::removeTab(sint index)
-{
- if(!(index>=0 && index<(sint)_Buttons.size()))
- return;
-
- vector buttons = _Buttons;
-
- for(sint i=0;i<(sint)_Buttons.size();i++)
- {
- bool deleteElt = (i!=index);
- CViewText* tabVT = _Buttons[i]->getViewText();
- if(tabVT && !deleteElt)
- delView(tabVT, deleteElt);
-
- delCtrl(_Buttons[i], deleteElt);
-
- if(!deleteElt)
- (_Groups[i]->getParent())->delGroup(_Groups[i], deleteElt);
- }
- _Setuped = false;
- updateCoords();
-
- uint count=0;
- CCtrlTabButton* lastTab = NULL;
- for(sint i=0;i<(sint)buttons.size();i++)
- {
- if(i!=index)
- {
- buttons[i]->setId("tab"+NLMISC::toString(count));
- buttons[i]->setParentPos(lastTab);
- if((i==0) || (index==0 && i==1))
- buttons[i]->setParentPosRef(Hotspot_TL);
- else
- _Buttons[i]->setParentPosRef(Hotspot_TR);
-
- buttons[i]->setPosRef(Hotspot_TL);
-
- lastTab = buttons[i];
- addCtrl(buttons[i]);
- count++;
- }
- }
-
- _Setuped = false;
- updateCoords();
-
- // we have removed the first button which is the only one to own the reference
- // then the new first button recovers the reference
- if(index==0)
- {
- CCtrlTabButton * tab0 = _Buttons[0];
- for(uint i=0; i<_Buttons.size(); ++i)
- _Buttons[i]->initRBRefFromRadioButton(tab0);
-
- select(_Selection);
- }
-
- if(_HideOutTabs)
- {
- select(_FirstTabIndex);
-
- if(!_AHOnChange.empty())
- CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
- }
-}
-
-// ***************************************************************************
-
-int CGroupTab::luaRemoveTab(CLuaState &ls)
-{
- const char *funcName = "removeTab";
- CLuaIHM::checkArgCount(ls, funcName, 1);
- CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
- removeTab((uint) ls.toNumber(1));
- return 0;
-}
-
-// ***************************************************************************
-void CGroupTab::removeAll()
-{
- for(sint i=0;i<(sint)_Buttons.size();i++)
- {
- CViewText* tabVT = _Buttons[i]->getViewText();
- if(tabVT)
- delView(tabVT, false);
-
- delCtrl(_Buttons[i], false);
- (_Groups[i]->getParent())->delGroup(_Groups[i], false);
- }
-
- _Setuped = false;
- updateCoords();
-}
-
-// ***************************************************************************
-
-int CGroupTab::luaRemoveAll(CLuaState &ls)
-{
- CLuaIHM::checkArgCount(ls, "CGroupTab::removeAll", 0);
- removeAll();
- return 0;
-}
-
-// ***************************************************************************
-CCtrlTabButton* CGroupTab::getTabButton(sint index)
-{
- if(index>=0 && index<(sint)_Buttons.size())
- {
- return _Buttons[index];
- }
- return NULL;
-}
-
-// ***************************************************************************
-int CGroupTab::luaGetTabButton(CLuaState &ls)
-{
- const char *funcName = "getTabButton";
- CLuaIHM::checkArgCount(ls, funcName, 1);
- CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
- CCtrlTabButton* tab = getTabButton((uint) ls.toNumber(1));
- if(tab != NULL)
- {
- CLuaIHM::pushUIOnStack(ls, tab);
- return 1;
- }
- return 0;
-}
-
-// ***************************************************************************
-void CGroupTab::updateFirstTabButton()
-{
- if(!_HideOutTabs || (_Selection<0) || (_Buttons.size()==0) || (_Parent->getWReal()<0)
- || _FirstTabIndex>=(sint)_Buttons.size())
- return;
-
- sint oldFirstTabIndex = _FirstTabIndex;
- sint oldLastTabIndex = _LastTabIndex;
-
- if(_FirstTabIndex<0)
- {
- for(uint i=0; i<_Buttons.size(); i++)
- {
- CCtrlTabButton * tab = _Buttons[i];
- if(tab->getActive())
- {
- _FirstTabIndex = i;
- break;
- }
- }
- }
-
- sint selection = _Selection;
- if(selection>=(sint)_Buttons.size())
- selection = _FirstTabIndex;
-
- if(selection < _FirstTabIndex)
- _FirstTabIndex = selection;
-
- sint32 maxWidth = _Parent->getWReal();
- sint32 buttonsWidth = 0;
- _LastTabIndex = 0;
-
- // desactive first tabs
- for(uint i=0; i<(uint)_FirstTabIndex; i++)
- {
- CCtrlTabButton * tab = _Buttons[i];
- if(tab->getActive())
- tab->setActive(false);
- }
-
-
- // active tabs from _FirstTabIndex and search for last showed tab
- for(uint i=_FirstTabIndex; i<_Buttons.size(); i++)
- {
- CCtrlTabButton * tab = _Buttons[i];
- sint32 tabWidth = tab->getWMax();
- if(buttonsWidth+tabWidth <= maxWidth)
- {
- buttonsWidth += tabWidth;
- if(!tab->getActive())
- tab->setActive(true);
- _LastTabIndex = i;
- }
- else
- break;
- }
-
- // check if selected tab is in showed tabs
- if(_LastTabIndex < selection)
- {
- for(uint i=_LastTabIndex+1; i<=(uint)selection; i++)
- {
- CCtrlTabButton * tab = _Buttons[i];
- buttonsWidth += tab->getWMax();
- if(!tab->getActive())
- tab->setActive(true);
- }
-
- while(buttonsWidth>maxWidth)
- {
- CCtrlTabButton * tab = _Buttons[_FirstTabIndex];
- buttonsWidth -= tab->getWMax();
- _FirstTabIndex++;
- if(tab->getActive())
- tab->setActive(false);
- }
- }
-
- // add tabs before the "_FirstTabIndex" one if it remains place
- while(buttonsWidth0)
- {
- CCtrlTabButton * tab = _Buttons[_FirstTabIndex-1];
- buttonsWidth += tab->getWMax();
- if(buttonsWidth<=maxWidth)
- {
- _FirstTabIndex--;
- if(!tab->getActive())
- tab->setActive(true);
- }
- }
-
- // desactive last tabs
- for(uint i=_LastTabIndex+1; i<_Buttons.size(); i++)
- {
- CCtrlTabButton * tab = _Buttons[i];
- if(tab->getActive())
- tab->setActive(false);
- }
-
- if(!_AHOnChange.empty() && ((oldFirstTabIndex!=_FirstTabIndex) || (oldLastTabIndex!=_LastTabIndex)))
- CAHManager::getInstance()->runActionHandler(_AHOnChange, this, _ParamsOnChange);
-
-}
-
-// ***************************************************************************
-int CGroupTab::luaShowTabButton(CLuaState &ls)
-{
- const char *funcName = "showTabButton";
- CLuaIHM::checkArgCount(ls, funcName, 1);
- CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
- sint showTab = (sint)ls.toNumber(1);
-
- if(showTab>=0 && showTab<(sint)_Buttons.size())
- {
- sint32 maxWidth = _Parent->getWReal();
- sint32 buttonsWidth = 0;
-
- if(showTab<_FirstTabIndex)
- {
- _FirstTabIndex = showTab;
- sint lastTabIndex = _FirstTabIndex;
- for(uint i=_FirstTabIndex; i<_Buttons.size(); i++)
- {
- CCtrlTabButton * tab = _Buttons[i];
- sint32 tabWidth = tab->getWMax();
- if(buttonsWidth+tabWidth <= maxWidth)
- {
- buttonsWidth += tabWidth;
- if(!tab->getActive())
- tab->setActive(true);
- lastTabIndex = i;
- }
- else
- break;
- }
-
- if(lastTabIndex <_Selection)
- select(lastTabIndex);
- else
- updateFirstTabButton();
- }
- else if(showTab>_LastTabIndex)
- {
- for(uint i=_FirstTabIndex; i<=(uint)showTab; i++)
- buttonsWidth += _Buttons[i]->getWMax();
-
- while(buttonsWidth>maxWidth)
- {
- buttonsWidth -= _Buttons[_FirstTabIndex]->getWMax();
- _FirstTabIndex++;
- }
-
- if(_Selection<_FirstTabIndex)
- select(_FirstTabIndex);
- else
- updateFirstTabButton();
- }
- }
-
- return 0;
-}
-
-// ***************************************************************************
-void CGroupTab::updateCoords ()
-{
- if(!_Setuped)
- setup();
-
- // special for groupTab. Because the ctrl may overlap each other from left to right, they are inserted in reverse
- // order. BUT, for correct TR/TL coord handling, must updtae in the reverse sens too!
-
- // **** just basis
- CInterfaceGroup::doUpdateCoords();
-
- // **** update in reverse order
- _XReal += _OffsetX;
- _YReal += _OffsetY;
- vector::reverse_iterator ite;
- for (ite = _EltOrder.rbegin() ; ite != _EltOrder.rend(); ite++)
- {
- CViewBase *pIE = *ite;
- pIE->updateCoords();
- }
- _XReal -= _OffsetX;
- _YReal -= _OffsetY;
-
- // **** complete with child resize
- CInterfaceGroup::updateCoords();
-
- updateFirstTabButton();
-}
-
-// ***************************************************************************
-void CGroupTab::select(sint index)
-{
- if(index<0)
- index= -1;
-
- if(index<(sint)_Buttons.size())
- {
- sint i;
-
- // validate this radio button.
- if(index>=0)
- _Buttons[index]->setPushed(true);
- else
- for(i=0;i<(sint)_Buttons.size();i++)
- _Buttons[i]->setPushed(false);
-
- _NextSelection = index;
-
- // set all render layer to their correct state
- for(i=0;i<(sint)_Buttons.size();i++)
- {
- // set the selected one +1, so it will be over
- _Buttons[i]->setRenderLayer(_BaseRenderLayer + (i==index?1:0) );
- if (i==index)
- {
- _Buttons[i]->setBlink(false);
- if (_Buttons[i]->_AHOnLeftClick2 != NULL)
- // call like if press on it
- _Buttons[i]->_AHOnLeftClick2->execute(_Buttons[i], _Buttons[i]->getParamsOnLeftClick());
- }
- }
-
- // show/hide all the associated groups
- for(i=0;i<(sint)_Groups.size();i++)
- {
- if(_Groups[i])
- _Groups[i]->setActive(i==index);
- }
-
- // ok!
- _Selection= index;
-
- updateFirstTabButton();
- }
-}
-
-// ***************************************************************************
-void CGroupTab::selectFromCtrl(CCtrlTabButton *button)
-{
- // search in all buttons
- for(uint i=0;i<_Buttons.size();i++)
- {
- // found?
- if(_Buttons[i]==button)
- {
- select(i);
- return;
- }
- }
-}
-
-// ***************************************************************************
-void CGroupTab::selectDefault(CCtrlTabButton *ifSelectionIs)
-{
- if(!_HideOutTabs && _Selection>=0 && _Selection<(sint)_Buttons.size() && _Buttons[_Selection]==ifSelectionIs)
- {
- // parse all active button
- for(uint i=0;i<_Buttons.size();i++)
- {
- if(_Buttons[i]->getActive())
- {
- select(i);
- return;
- }
- }
-
- // default: unselect
- select(-1);
- }
-}
-
-// ***************************************************************************
-void CGroupTab::selectDefaultIfCurrentHid()
-{
- if(_Selection>=0 && _Selection<(sint)_Buttons.size() &&
- _Buttons[_Selection]!=NULL && _Buttons[_Selection]->getActive()==false)
- {
- selectDefault(_Buttons[_Selection]);
- }
-}
-
-// ***************************************************************************
-sint CGroupTab::getSelection() const
-{
- return _Selection;
-}
-
-NLMISC_REGISTER_OBJECT(CViewBase, CCtrlTabButton, std::string, "tab_button");
-
-// ***************************************************************************
-std::string CGroupTab::getAssociatedGroupSelection() const
-{
- if(_Selection>=0 && _Selection<(sint)_Buttons.size())
- {
- return _Buttons[_Selection]->_AssociatedGroup;
- }
- return "";
-}
-
-// ***************************************************************************
-CInterfaceGroup* CGroupTab::getGroup(sint index)
-{
- if(index>=0 && index<(sint)_Groups.size())
- {
- return _Groups[index];
- }
- return NULL;
-}
-
-// ***************************************************************************
-int CGroupTab::luaGetGroup(CLuaState &ls)
-{
- const char *funcName = "getGroup";
- CLuaIHM::checkArgCount(ls, funcName, 1);
- CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
- CInterfaceGroup* group = getGroup((uint) ls.toNumber(1));
- if(group != NULL)
- {
- CLuaIHM::pushUIOnStack(ls, group);
- return 1;
- }
- return 0;
-}
-
-// ***************************************************************************
-CCtrlTabButton::CCtrlTabButton(const TCtorParam ¶m)
-: CCtrlTextButton(param)
-{
- _DefaultX= 0;
- _AHOnLeftClick2 = NULL;
- _BlinkDate = 0;
- _Blinking = false;
- _BlinkState = false;
-}
-
-// ***************************************************************************
-bool CCtrlTabButton::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
-{
- if(!CCtrlTextButton::parse(cur, parentGroup))
- return false;
-
- // if left click not setuped, set default
- _AHOnLeftClick2 = _AHOnLeftClick;
- string dummy;
- _AHOnLeftClick= CAHManager::getInstance()->getAH("tab_select", dummy);
-
- // read the associated group to show/hide
- CXMLAutoPtr prop;
- prop = (char*) xmlGetProp( cur, (xmlChar*)"group" );
- if(prop) _AssociatedGroup= (const char*)prop;
-
- // backup the x
- _DefaultX= _X;
-
- return true;
-}
-
-// ***************************************************************************
-void CCtrlTabButton::setActive(bool state)
-{
- if(state!=getActive())
- {
- CCtrlTextButton::setActive(state);
-
- // special for correct display of textbuttons. reset to 0 when the button is hid
- if(state)
- setX(_DefaultX);
- else
- setX(0);
-
- // if hide, and I was the selected tab, select a default active one
- if(state==false)
- {
- CGroupTab *parent= dynamic_cast(getParent());
- if(parent)
- parent->selectDefault(this);
- }
- }
-}
-
-// ***************************************************************************
-bool CCtrlTabButton::handleEvent (const NLGUI::CEventDescriptor &event)
-{
- if (event.getType() == NLGUI::CEventDescriptor::system)
- {
- const NLGUI::CEventDescriptorSystem &systemEvent = (const NLGUI::CEventDescriptorSystem &) event;
- if (systemEvent.getEventTypeExtended() == NLGUI::CEventDescriptorSystem::clocktick)
- if (_Blinking)
- {
- uint dbclickDelay = CWidgetManager::getInstance()->getUserDblClickDelay();
- const CWidgetManager::SInterfaceTimes × = CWidgetManager::getInstance()->getInterfaceTimes();
-
- if (( times.thisFrameMs - _BlinkDate) > dbclickDelay)
- {
- if (_BlinkState)
- {
- setTextColorNormal(CRGBA::White);
- setTextModulateGlobalColorNormal(false);
- }
- else
- {
- setTextColorNormal(_TextColorNormalBlink);
- setTextModulateGlobalColorNormal(_TextModulateGlobalColorNormalBlink);
- }
- _BlinkState = !_BlinkState;
- _BlinkDate = times.thisFrameMs;
- }
- }
- }
- return CCtrlTextButton::handleEvent(event);
-}
-
-// ***************************************************************************
-void CCtrlTabButton::setBlink (bool b)
-{
- if (b)
- {
- if (!_Blinking)
- {
- _TextColorNormalBlink = getTextColorNormal();
- _TextModulateGlobalColorNormalBlink = getTextModulateGlobalColorNormal();
- CWidgetManager::getInstance()->registerClockMsgTarget(this);
- }
- _Blinking = true;
- }
- else
- {
- if (_Blinking)
- {
- CWidgetManager::getInstance()->unregisterClockMsgTarget(this);
- setTextColorNormal(_TextColorNormalBlink);
- setTextModulateGlobalColorNormal(_TextModulateGlobalColorNormalBlink);
- }
- _Blinking = false;
- }
-}
-
-// ***************************************************************************
-// Action handler for Tab selection
-class CHandlerTabSelect : public IActionHandler
-{
-public:
- virtual void execute (CCtrlBase *pCaller, const string &/* Params */)
- {
- CCtrlTabButton *but= dynamic_cast(pCaller);
-
- // get the parent TabGroup
- CGroupTab *parent= dynamic_cast(but->getParent());
- if(parent)
- parent->selectFromCtrl(but);
- }
-};
-REGISTER_ACTION_HANDLER(CHandlerTabSelect, "tab_select" );
-
diff --git a/code/ryzom/client/src/interface_v3/group_tab.h b/code/ryzom/client/src/interface_v3/group_tab.h
deleted file mode 100644
index 46cc241ab..000000000
--- a/code/ryzom/client/src/interface_v3/group_tab.h
+++ /dev/null
@@ -1,177 +0,0 @@
-// Ryzom - MMORPG Framework
-// Copyright (C) 2010 Winch Gate Property Limited
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-
-
-#ifndef NL_GROUP_TAB_H
-#define NL_GROUP_TAB_H
-
-#include "nel/misc/types_nl.h"
-#include "nel/gui/interface_group.h"
-#include "nel/gui/ctrl_text_button.h"
-
-
-// ***************************************************************************
-class CCtrlTabButton;
-
-
-// ***************************************************************************
-/**
- * Group handling Ctrl Tab, to easily simulate Tab ctrl.
- * NB: controlled groups doesn't have to be child of the GroupTab, they are searched in order:
- * - in this group
- * - in the parent group
- * - in global
- * \author Lionel Berenguier
- * \author Nevrax France
- * \date 2003
- */
-class CGroupTab : public CInterfaceGroup
-{
-public:
-
- /// Constructor
- CGroupTab(const TCtorParam ¶m);
-
- virtual bool parse (xmlNodePtr cur, CInterfaceGroup *parentGroup);
- virtual void updateCoords ();
-
- // select the ctrl tab. -1 will invalidate all.
- void select(sint index);
- sint getSelection() const;
-
- // select with a CCtrlTabButton ptr
- void selectFromCtrl(CCtrlTabButton *button);
-
- // select a default activated tab, if the current is a special ctrlTab
- void selectDefault(CCtrlTabButton *ifSelectionIs);
-
- // select a default activated tab, if the current is hid
- void selectDefaultIfCurrentHid();
-
- // add new tab
- void addTab(CCtrlTabButton *tabB);
- void addTab(CCtrlTabButton *tabB, sint index);
- int luaAddTab(CLuaState &ls);
- int luaAddTabWithOrder(CLuaState &ls);
-
- // remove selected tab
- void removeTab(sint index);
- int luaRemoveTab(CLuaState &ls);
-
- // remove all tabs
- void removeAll();
- int luaRemoveAll(CLuaState &ls);
-
- // tab number
- void setTabButtonNb(sint32 /* val */){}
- sint32 getTabButtonNb() const {return (sint32)_Buttons.size();}
-
- // selection index
- void setIndexSelection(sint32 val){select((sint)val);}
- sint32 getIndexSelection() const {return (sint32)_NextSelection;}
-
- // selection index
- void setAssociatedGroupSelection(const std::string & /* assG */){}
- std::string getAssociatedGroupSelection() const;
-
- // get group from index
- CInterfaceGroup* getGroup(sint index);
- int luaGetGroup(CLuaState &ls);
-
- // get tab from index
- CCtrlTabButton* getTabButton(sint index);
- int luaGetTabButton(CLuaState &ls);
-
- // first showed tab button
- sint32 getFirstTabButton() const {return (sint32)_FirstTabIndex;}
-
- // last showed tab button
- sint32 getLastTabButton() const {return (sint32)_LastTabIndex;}
-
- // update showed tab buttons on function of GroupTab width
- void updateFirstTabButton();
- int luaShowTabButton(CLuaState &ls);
-
- void dummySet(sint32 /* value */){}
-
- REFLECT_EXPORT_START(CGroupTab, CInterfaceGroup)
- REFLECT_LUA_METHOD("addTab", luaAddTab)
- REFLECT_LUA_METHOD("addTabWithOrder", luaAddTabWithOrder)
- REFLECT_LUA_METHOD("removeTab", luaRemoveTab)
- REFLECT_LUA_METHOD("removeAll", luaRemoveAll)
- REFLECT_LUA_METHOD("getGroup", luaGetGroup)
- REFLECT_LUA_METHOD("getTabButton", luaGetTabButton)
- REFLECT_LUA_METHOD("showTabButton", luaShowTabButton)
- REFLECT_SINT32 ("tabButtonNb", getTabButtonNb, setTabButtonNb)
- REFLECT_SINT32 ("selection", getIndexSelection, setIndexSelection)
- REFLECT_SINT32 ("firstTabButton", getFirstTabButton, dummySet)
- REFLECT_SINT32 ("lastTabButton", getLastTabButton, dummySet)
- REFLECT_STRING ("associatedGroupSelection", getAssociatedGroupSelection, setAssociatedGroupSelection)
- REFLECT_EXPORT_END
-
-private:
-
- std::vector _Buttons; // can't be NULL.
- std::vector _Groups; // may be NULL
- sint _Selection;
- sint _NextSelection;
- sint _BaseRenderLayer;
- bool _Setuped;
- bool _HideOutTabs;
- sint _FirstTabIndex;
- sint _LastTabIndex;
-
- std::string _AHOnChange;
- std::string _ParamsOnChange;
-
- void setup();
-};
-
-// ***************************************************************************
-/**
- * Used with CGroupTab
- */
-class CCtrlTabButton : public CCtrlTextButton
-{
-public:
-
- CCtrlTabButton(const TCtorParam ¶m);
-
- virtual bool parse (xmlNodePtr cur, CInterfaceGroup *parentGroup);
-
- virtual void setActive(bool state);
-
- virtual bool handleEvent (const NLGUI::CEventDescriptor &event);
-
- void setBlink (bool b);
-
- std::string _AssociatedGroup;
- IActionHandler *_AHOnLeftClick2;
-
-private:
-
- sint32 _DefaultX;
- bool _Blinking;
- NLMISC::CRGBA _TextColorNormalBlink;
- bool _TextModulateGlobalColorNormalBlink;
- sint64 _BlinkDate;
- bool _BlinkState;
-};
-
-#endif // NL_GROUP_TAB_H
-
-/* End of group_tab.h */
diff --git a/code/ryzom/client/src/interface_v3/interface_parser.cpp b/code/ryzom/client/src/interface_v3/interface_parser.cpp
index be160de5d..5f27cf92e 100644
--- a/code/ryzom/client/src/interface_v3/interface_parser.cpp
+++ b/code/ryzom/client/src/interface_v3/interface_parser.cpp
@@ -82,7 +82,7 @@
#include "group_in_scene_user_info.h"
#include "group_in_scene_bubble.h"
#include "group_phrase_skill_filter.h"
-#include "group_tab.h"
+#include "nel/gui/group_tab.h"
#include "group_table.h"
// DBGroup
#include "dbgroup_select_number.h"
diff --git a/code/ryzom/client/src/interface_v3/people_interraction.cpp b/code/ryzom/client/src/interface_v3/people_interraction.cpp
index c682ee824..1efed593b 100644
--- a/code/ryzom/client/src/interface_v3/people_interraction.cpp
+++ b/code/ryzom/client/src/interface_v3/people_interraction.cpp
@@ -39,7 +39,7 @@
#include "../entities.h"
#include "../net_manager.h"
#include "../connection.h"
-#include "group_tab.h"
+#include "nel/gui/group_tab.h"
#include "guild_manager.h"
// Game share
#include "game_share/entity_types.h"
diff --git a/code/ryzom/client/src/interface_v3/register_interface_elements.cpp b/code/ryzom/client/src/interface_v3/register_interface_elements.cpp
index b2c526b6b..a8c8b35e4 100644
--- a/code/ryzom/client/src/interface_v3/register_interface_elements.cpp
+++ b/code/ryzom/client/src/interface_v3/register_interface_elements.cpp
@@ -48,7 +48,7 @@
#include "nel/gui/ctrl_scroll_base.h"
#include "nel/gui/ctrl_scroll.h"
#include "dbgroup_combo_box.h"
-#include "group_tab.h"
+#include "nel/gui/group_tab.h"
#include "group_html.h"
#include "group_header.h"
#include "sphrase_manager.h"