diff --git a/code/nel/include/nel/gui/group_header.h b/code/nel/include/nel/gui/group_header.h
new file mode 100644
index 000000000..81d5d20be
--- /dev/null
+++ b/code/nel/include/nel/gui/group_header.h
@@ -0,0 +1,86 @@
+// 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 CL_GROUP_HEADER_H
+#define CL_GROUP_HEADER_H
+
+#include "nel/gui/group_list.h"
+
+namespace NLGUI
+{
+
+ class CGroupHeaderEntry;
+
+ // *****************************************************************************************************************
+ /** Display a header with movable entries.
+ * Usually used with a table to change the size of each column (much like the windows file explorer in 'details' mode)
+ *
+ * \author Nicolas Vizerie
+ * \author Nevrax France
+ * \date 2006
+ */
+ class CGroupHeader : public CGroupList
+ {
+ public:
+ REFLECT_EXPORT_START(CGroupHeader, CGroupList)
+ REFLECT_LUA_METHOD("enlargeColumns", luaEnlargeColumns);
+ REFLECT_LUA_METHOD("resizeColumnsAndContainer", luaResizeColumnsAndContainer);
+ REFLECT_EXPORT_END
+
+ CGroupHeader(const TCtorParam ¶m);
+ // from CInterfaceGroup
+ virtual bool parse(xmlNodePtr cur, CInterfaceGroup * parentGroup);
+ sint32 getHeaderMaxSize() const { return _HeaderMaxSize; }
+ // get the entries in this header
+ void getEntries(std::vector &dest);
+ // ensure that max. content of columns is visible (without the total width becoming more than 'getHeaderMaxSize()'
+ void enlargeColumns(sint32 margin);
+ // ensure that content of each column is visible
+ void resizeColumnsAndContainer(sint32 margin);
+ private:
+ sint32 _HeaderMaxSize;
+ int luaEnlargeColumns(CLuaState &ls);
+ int luaResizeColumnsAndContainer(CLuaState &ls);
+ };
+
+ // *****************************************************************************************************************
+ // an entry in a header, includes a "mover control" to move it inside its parent header
+ // NOTE : when not used inside a CGroupHeader, will work, but there will be no 'max_size'
+ class CGroupHeaderEntry : public CInterfaceGroup
+ {
+ public:
+ CGroupHeaderEntry(const TCtorParam ¶m);
+ // from CInterfaceGroup
+ virtual bool parse(xmlNodePtr cur, CInterfaceGroup * parentGroup);
+ sint32 getMinSize() const { return _MinSize; }
+ virtual void updateCoords();
+ CInterfaceGroup *getTargetColumn() const;
+
+ const std::string &getAHOnResize() const { return _AHOnResize; }
+ const std::string &getAHOnResizeParams() const { return _AHOnResizeParams; }
+
+ private:
+ sint32 _MinSize;
+ std::string _TargetColumnId;
+ std::string _AHOnResize;
+ std::string _AHOnResizeParams;
+ };
+
+
+}
+
+#endif
+
diff --git a/code/nel/src/gui/group_header.cpp b/code/nel/src/gui/group_header.cpp
new file mode 100644
index 000000000..48ae85776
--- /dev/null
+++ b/code/nel/src/gui/group_header.cpp
@@ -0,0 +1,441 @@
+// 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_container.h"
+#include "nel/gui/group_header.h"
+#include "nel/gui/lua_ihm.h"
+#include "nel/gui/widget_manager.h"
+
+
+using namespace NLMISC;
+
+namespace NLGUI
+{
+
+ //////////////////
+ // CGroupHeader //
+ //////////////////
+
+ // *****************************************************************************************************************
+ CGroupHeader::CGroupHeader(const TCtorParam ¶m) : CGroupList(param), _HeaderMaxSize(32767)
+ {
+ }
+
+ // *****************************************************************************************************************
+ void CGroupHeader::enlargeColumns(sint32 margin)
+ {
+ std::vector entries;
+ getEntries(entries);
+ sint32 totalWidth = 0;
+ for (uint k = 0; k < entries.size(); ++k)
+ {
+ CInterfaceGroup *colEnclosing = entries[k]->getTargetColumn();
+ if (colEnclosing && !colEnclosing->getGroups().empty())
+ {
+ CInterfaceGroup *col = colEnclosing->getGroups()[0];
+ if (col)
+ {
+ // enlarge to the max to be able to measure the sub text (they may clamp themselves based
+ // on their first non-"child resizing" parent (see CViewText::updateCoords)
+ colEnclosing->setW(16384);
+ colEnclosing->invalidateCoords();
+ colEnclosing->updateCoords();
+
+ // assume that first child is resizing from its children width (either 'child_resize_w=true' or a CGroupList)
+ entries[k]->setW(std::max(entries[k]->getMinSize(), col->getW() + margin));
+ entries[k]->invalidateCoords();
+ totalWidth += entries[k]->getW();
+ }
+ }
+ }
+ // if total width bigger than allowed, reduce proportionnally
+ if (totalWidth > _HeaderMaxSize)
+ {
+ while (totalWidth > _HeaderMaxSize)
+ {
+ bool adjusted = false;
+ // stupid algo here, but ponctual ...
+ for (uint k = 0; k < entries.size() && totalWidth > _HeaderMaxSize; ++k)
+ {
+ if (entries[k]->getW() > entries[k]->getMinSize())
+ {
+ entries[k]->setW(entries[k]->getW() - 1);
+ entries[k]->invalidateCoords();
+ --totalWidth;
+ adjusted = true;
+ }
+ }
+ // if all at min size, just exit ...
+ if (!adjusted) break;
+ }
+ }
+ else
+ {
+ // search first parent that limit size, if it is larger then enlarge to fit size
+ CInterfaceGroup *limitingParent = getParent();
+ while (limitingParent && (limitingParent->getResizeFromChildW() || dynamic_cast(limitingParent)))
+ {
+ // NB nico : the dynamic_cast for CGroupList is bad!!
+ // can't avoid it for now, because, CGroupList implicitly does a "resize from child" in its update coords
+ // ...
+ limitingParent = limitingParent->getParent();
+ }
+ if (limitingParent && limitingParent->getWReal() > totalWidth)
+ {
+ while (limitingParent->getWReal() > totalWidth && totalWidth < _HeaderMaxSize)
+ {
+ // enlarge to matche parent size
+ // stupid algo here, but ponctual ...
+ for (uint k = 0; k < entries.size(); ++k)
+ {
+ entries[k]->setW(entries[k]->getW() + 1);
+ entries[k]->invalidateCoords();
+ ++totalWidth;
+ if (limitingParent->getWReal() <= totalWidth || totalWidth >= _HeaderMaxSize) break;
+ }
+ }
+ }
+ }
+ invalidateCoords();
+ }
+
+ // *****************************************************************************************************************
+ void CGroupHeader::resizeColumnsAndContainer(sint32 margin)
+ {
+ std::vector entries;
+ getEntries(entries);
+ sint32 totalWidth = 0;
+ for (uint k = 0; k < entries.size(); ++k)
+ {
+ CInterfaceGroup *colEnclosing = entries[k]->getTargetColumn();
+ if (colEnclosing && !colEnclosing->getGroups().empty())
+ {
+ CInterfaceGroup *col = colEnclosing->getGroups()[0];
+ if (col)
+ {
+ // enlarge to the max to be able to measure the sub text (they may clamp themselves based
+ // on their first non-"child resizing" parent (see CViewText::updateCoords)
+ colEnclosing->setW(16384);
+ colEnclosing->invalidateCoords();
+ colEnclosing->updateCoords();
+
+ // assume that first child is resizing from its children width (either 'child_resize_w=true' or a CGroupList)
+ entries[k]->setW(std::max(entries[k]->getMinSize(), col->getW() + margin));
+ entries[k]->invalidateCoords();
+ totalWidth += entries[k]->getW();
+ }
+ }
+ }
+
+ // resize W
+ if (totalWidth <= _HeaderMaxSize)
+ {
+ // search first parent that limit size, if it is larger then enlarge to fit size
+ CInterfaceGroup *limitingParent = getParent();
+ while (limitingParent && (limitingParent->getResizeFromChildW() || dynamic_cast(limitingParent)))
+ {
+ // NB nico : the dynamic_cast for CGroupList is bad!!
+ // can't avoid it for now, because, CGroupList implicitly does a "resize from child" in its update coords
+ // ...
+ limitingParent = limitingParent->getParent();
+ }
+
+ getParentContainer()->setW(totalWidth + getParentContainer()->getWReal() - limitingParent->getWReal());
+ }
+
+ // resize H
+ if(entries.size()>0)
+ {
+ CInterfaceGroup *colEnclosing = entries[0]->getTargetColumn();
+ if (colEnclosing && !colEnclosing->getGroups().empty())
+ {
+ CInterfaceGroup *col = colEnclosing->getGroups()[0];
+ if (col)
+ {
+ // search first parent that limit size, if it is larger then enlarge to fit size
+ CInterfaceGroup *limitingParent = colEnclosing->getParent();
+ while (limitingParent && (limitingParent->getResizeFromChildH() || dynamic_cast(limitingParent)))
+ limitingParent = limitingParent->getParent();
+
+ getParentContainer()->setH(col->getH() + getParentContainer()->getHReal() - limitingParent->getHReal());
+ }
+ }
+ }
+
+
+ invalidateCoords();
+ }
+
+ // *****************************************************************************************************************
+ void CGroupHeader::getEntries(std::vector &dest)
+ {
+ dest.clear();
+ const std::vector &groups = getGroups();
+ for (uint k = 0; k < groups.size(); ++k)
+ {
+ CGroupHeaderEntry *entry = dynamic_cast(groups[k]);
+ if (entry)
+ {
+ dest.push_back(entry);
+ }
+ }
+ }
+
+ // *****************************************************************************************************************
+ int CGroupHeader::luaEnlargeColumns(CLuaState &ls)
+ {
+ const char *funcName = "enlargeColumns";
+ CLuaIHM::checkArgCount(ls, funcName, 1);
+ CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
+ enlargeColumns((sint32) ls.toNumber(1));
+ return 0;
+ }
+
+ // *****************************************************************************************************************
+ int CGroupHeader::luaResizeColumnsAndContainer(CLuaState &ls)
+ {
+ const char *funcName = "resizeColumnsAndContainer";
+ CLuaIHM::checkArgCount(ls, funcName, 1);
+ CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
+ resizeColumnsAndContainer((sint32) ls.toNumber(1));
+ return 0;
+ }
+
+ // *****************************************************************************************************************
+ bool CGroupHeader::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
+ {
+ if(!CGroupList::parse(cur, parentGroup)) return false;
+ CXMLAutoPtr prop((const char*) xmlGetProp( cur, (xmlChar*)"header_max_size" ));
+ if (prop) fromString((const char*)prop, _HeaderMaxSize);
+ return true;
+ }
+
+ /////////////////////////
+ // CHeaderEntryResizer //
+ /////////////////////////
+
+ class CHeaderEntryResizer : public CCtrlBase
+ {
+ public:
+ CHeaderEntryResizer(bool rightSide, sint32 wMin) : CCtrlBase(TCtorParam()),
+ _RightSide(rightSide),
+ _Moving(false),
+ _StartX(0),
+ _OffsetX(0),
+ _WMin(wMin)
+ {}
+ void release()
+ {
+ if (CWidgetManager::getInstance()->getCapturePointerLeft() == this)
+ {
+ _Moving = false;
+ CWidgetManager::getInstance()->setCapturePointerLeft(NULL);
+ }
+ }
+ virtual uint getDeltaDepth() const { return 100; }
+ CInterfaceGroup *getTargetGroup()
+ {
+ if (_RightSide) return _Parent;
+
+ if (getParent()->getParent() == _Parent->getParentPos()) return NULL; // leftmost header
+ return dynamic_cast(getParent()->getParentPos());
+ }
+ bool handleEvent (const NLGUI::CEventDescriptor &event)
+ {
+ if (_Parent)
+ {
+ if (event.getType() == NLGUI::CEventDescriptor::system)
+ {
+ const NLGUI::CEventDescriptorSystem &eds = (const NLGUI::CEventDescriptorSystem &) event;
+ if (eds.getEventTypeExtended() == NLGUI::CEventDescriptorSystem::setfocus)
+ {
+ const NLGUI::CEventDescriptorSetFocus &edsf = (const NLGUI::CEventDescriptorSetFocus &) eds;
+ if (edsf.hasFocus() == false)
+ {
+ release();
+ return CCtrlBase::handleEvent(event);
+ }
+ }
+ }
+ if (event.getType() == NLGUI::CEventDescriptor::mouse)
+ {
+ const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
+ if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown)
+ {
+ if (!this->isIn(eventDesc.getX(), eventDesc.getY())) return false;
+ _TargetGroup = getTargetGroup();
+ if (!_TargetGroup) return false;
+ CWidgetManager::getInstance()->setCapturePointerLeft(this);
+ _Moving = true;
+ _OffsetX = _TargetGroup->getW() - eventDesc.getX();
+ return true;
+ }
+ if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup)
+ {
+ release();
+ }
+ if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousemove)
+ {
+ if (_Moving && CWidgetManager::getInstance()->getCapturePointerLeft() == this)
+ {
+ if (!_TargetGroup)
+ {
+ release();
+ return false;
+ }
+ sint32 newW = eventDesc.getX() + _OffsetX;
+ // compute width of all header entries but this one
+ CGroupHeader *header = dynamic_cast(getParent()->getParent());
+ if (header)
+ {
+ sint32 w = 0;
+ for (uint k = 0; k < header->getNumChildren(); ++k)
+ {
+ if (header->getChild(k) != _TargetGroup)
+ {
+ w += header->getChild(k)->getW();
+ }
+ }
+ sint32 excess = w + newW - header->getHeaderMaxSize();
+ if (excess)
+ {
+ // try to diminish the size of all headers starting from the last
+ for (sint k = header->getNumChildren() - 1; k >= 0 && excess > 0; --k)
+ {
+ if (header->getChild(k) == _TargetGroup) break;
+ CGroupHeaderEntry *ghe = dynamic_cast(header->getChild(k));
+ sint32 wGain = std::min(excess, std::max((sint32) 0, ghe->getW() - ghe->getMinSize()));
+ if (wGain > 0)
+ {
+ ghe->setW(ghe->getW() - wGain);
+ ghe->invalidateCoords();
+ excess -= wGain;
+ }
+ }
+ }
+ newW -= std::max((sint32) 0, excess);
+ }
+ _TargetGroup->setW(std::max(_WMin, newW));
+ _TargetGroup->invalidateCoords();
+ CGroupHeaderEntry *ghe = dynamic_cast((CInterfaceGroup *) _TargetGroup);
+ if (ghe)
+ {
+ ghe->setW(_TargetGroup->getW());
+ ghe->invalidateCoords();
+ CAHManager::getInstance()->runActionHandler(ghe->getAHOnResize(), ghe, ghe->getAHOnResizeParams());
+ }
+ return true;
+ }
+ _Moving = false;
+ }
+ }
+ }
+ return CCtrlBase::handleEvent(event);
+ }
+ virtual void draw ()
+ {
+ // no-op
+ }
+ virtual bool getMouseOverShape(std::string &texName, uint8 &rot, NLMISC::CRGBA &col)
+ {
+
+ if (!getTargetGroup()) return false;
+ texName = "curs_resize_LR.tga";
+ rot = 0;
+ col = CRGBA::White;
+ return true;
+ }
+
+ private:
+ NLMISC::CRefPtr _TargetGroup; // group for which w is modified
+ bool _RightSide; // right or left side mover ?
+ bool _Moving;
+ sint32 _StartX; // value to add to mouse to get local x pos of target group
+ sint32 _OffsetX;
+ sint32 _WMin;
+ };
+
+ // *****************************************************************************************************************
+ CGroupHeaderEntry::CGroupHeaderEntry(const TCtorParam ¶m) : CInterfaceGroup(param)
+ {
+ _MinSize = 4;
+ }
+
+ // *****************************************************************************************************************
+ bool CGroupHeaderEntry::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
+ {
+ if (!CInterfaceGroup::parse(cur, parentGroup)) return false;
+ // left mover
+ CXMLAutoPtr prop((const char*) xmlGetProp( cur, (xmlChar*)"wmin" ));
+ if (prop) fromString((const char*)prop, _MinSize);
+ sint32 resizerSize = 4;
+ prop = (char*) xmlGetProp( cur, (xmlChar*)"resizer_size" );
+ if (prop) fromString((const char*)prop, resizerSize);
+ prop = (char*) xmlGetProp(cur, (xmlChar*) "target");
+ if (prop) _TargetColumnId = (const char *) prop;
+
+ prop = (char*) xmlGetProp(cur, (xmlChar*) "on_resize");
+ if (prop) _AHOnResize = (const char *) prop;
+ prop = (char*) xmlGetProp(cur, (xmlChar*) "on_resize_params");
+ if (prop) _AHOnResizeParams = (const char *) prop;
+
+ CHeaderEntryResizer *hm = new CHeaderEntryResizer(false, _MinSize);
+ addCtrl(hm);
+ hm->setW(resizerSize);
+ hm->setSizeRef(2);
+ hm->setParent(this);
+ hm->setParentPosRef(Hotspot_TL);
+ hm->setPosRef(Hotspot_TL);
+ // right mover
+ hm = new CHeaderEntryResizer(true, _MinSize);
+ addCtrl(hm);
+ hm->setW(resizerSize);
+ hm->setSizeRef(2);
+ hm->setParent(this);
+ hm->setParentPosRef(Hotspot_TR);
+ hm->setPosRef(Hotspot_TR);
+ //
+ return true;
+ }
+
+ // *****************************************************************************************************************
+ CInterfaceGroup *CGroupHeaderEntry::getTargetColumn() const
+ {
+ return dynamic_cast(CWidgetManager::getInstance()->getElementFromId(_TargetColumnId));
+ }
+
+ // *****************************************************************************************************************
+ void CGroupHeaderEntry::updateCoords()
+ {
+ CInterfaceGroup::updateCoords();
+ CInterfaceGroup *targetColumn = getTargetColumn();
+ if (targetColumn)
+ {
+ if (targetColumn->getW() != getW())
+ {
+ targetColumn->setW(getW());
+ targetColumn->invalidateCoords();
+ }
+ }
+ }
+
+
+ NLMISC_REGISTER_OBJECT(CViewBase, CGroupHeader, std::string, "header");
+ NLMISC_REGISTER_OBJECT(CViewBase, CGroupHeaderEntry, std::string, "header_entry");
+
+}
+
diff --git a/code/ryzom/client/src/interface_v3/group_header.cpp b/code/ryzom/client/src/interface_v3/group_header.cpp
deleted file mode 100644
index b907595a5..000000000
--- a/code/ryzom/client/src/interface_v3/group_header.cpp
+++ /dev/null
@@ -1,435 +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 "nel/gui/group_container.h"
-#include "group_header.h"
-#include "nel/gui/lua_ihm.h"
-#include "nel/gui/widget_manager.h"
-
-
-using namespace NLMISC;
-
-//////////////////
-// CGroupHeader //
-//////////////////
-
-// *****************************************************************************************************************
-CGroupHeader::CGroupHeader(const TCtorParam ¶m) : CGroupList(param), _HeaderMaxSize(32767)
-{
-}
-
-// *****************************************************************************************************************
-void CGroupHeader::enlargeColumns(sint32 margin)
-{
- std::vector entries;
- getEntries(entries);
- sint32 totalWidth = 0;
- for (uint k = 0; k < entries.size(); ++k)
- {
- CInterfaceGroup *colEnclosing = entries[k]->getTargetColumn();
- if (colEnclosing && !colEnclosing->getGroups().empty())
- {
- CInterfaceGroup *col = colEnclosing->getGroups()[0];
- if (col)
- {
- // enlarge to the max to be able to measure the sub text (they may clamp themselves based
- // on their first non-"child resizing" parent (see CViewText::updateCoords)
- colEnclosing->setW(16384);
- colEnclosing->invalidateCoords();
- colEnclosing->updateCoords();
-
- // assume that first child is resizing from its children width (either 'child_resize_w=true' or a CGroupList)
- entries[k]->setW(std::max(entries[k]->getMinSize(), col->getW() + margin));
- entries[k]->invalidateCoords();
- totalWidth += entries[k]->getW();
- }
- }
- }
- // if total width bigger than allowed, reduce proportionnally
- if (totalWidth > _HeaderMaxSize)
- {
- while (totalWidth > _HeaderMaxSize)
- {
- bool adjusted = false;
- // stupid algo here, but ponctual ...
- for (uint k = 0; k < entries.size() && totalWidth > _HeaderMaxSize; ++k)
- {
- if (entries[k]->getW() > entries[k]->getMinSize())
- {
- entries[k]->setW(entries[k]->getW() - 1);
- entries[k]->invalidateCoords();
- --totalWidth;
- adjusted = true;
- }
- }
- // if all at min size, just exit ...
- if (!adjusted) break;
- }
- }
- else
- {
- // search first parent that limit size, if it is larger then enlarge to fit size
- CInterfaceGroup *limitingParent = getParent();
- while (limitingParent && (limitingParent->getResizeFromChildW() || dynamic_cast(limitingParent)))
- {
- // NB nico : the dynamic_cast for CGroupList is bad!!
- // can't avoid it for now, because, CGroupList implicitly does a "resize from child" in its update coords
- // ...
- limitingParent = limitingParent->getParent();
- }
- if (limitingParent && limitingParent->getWReal() > totalWidth)
- {
- while (limitingParent->getWReal() > totalWidth && totalWidth < _HeaderMaxSize)
- {
- // enlarge to matche parent size
- // stupid algo here, but ponctual ...
- for (uint k = 0; k < entries.size(); ++k)
- {
- entries[k]->setW(entries[k]->getW() + 1);
- entries[k]->invalidateCoords();
- ++totalWidth;
- if (limitingParent->getWReal() <= totalWidth || totalWidth >= _HeaderMaxSize) break;
- }
- }
- }
- }
- invalidateCoords();
-}
-
-// *****************************************************************************************************************
-void CGroupHeader::resizeColumnsAndContainer(sint32 margin)
-{
- std::vector entries;
- getEntries(entries);
- sint32 totalWidth = 0;
- for (uint k = 0; k < entries.size(); ++k)
- {
- CInterfaceGroup *colEnclosing = entries[k]->getTargetColumn();
- if (colEnclosing && !colEnclosing->getGroups().empty())
- {
- CInterfaceGroup *col = colEnclosing->getGroups()[0];
- if (col)
- {
- // enlarge to the max to be able to measure the sub text (they may clamp themselves based
- // on their first non-"child resizing" parent (see CViewText::updateCoords)
- colEnclosing->setW(16384);
- colEnclosing->invalidateCoords();
- colEnclosing->updateCoords();
-
- // assume that first child is resizing from its children width (either 'child_resize_w=true' or a CGroupList)
- entries[k]->setW(std::max(entries[k]->getMinSize(), col->getW() + margin));
- entries[k]->invalidateCoords();
- totalWidth += entries[k]->getW();
- }
- }
- }
-
- // resize W
- if (totalWidth <= _HeaderMaxSize)
- {
- // search first parent that limit size, if it is larger then enlarge to fit size
- CInterfaceGroup *limitingParent = getParent();
- while (limitingParent && (limitingParent->getResizeFromChildW() || dynamic_cast(limitingParent)))
- {
- // NB nico : the dynamic_cast for CGroupList is bad!!
- // can't avoid it for now, because, CGroupList implicitly does a "resize from child" in its update coords
- // ...
- limitingParent = limitingParent->getParent();
- }
-
- getParentContainer()->setW(totalWidth + getParentContainer()->getWReal() - limitingParent->getWReal());
- }
-
- // resize H
- if(entries.size()>0)
- {
- CInterfaceGroup *colEnclosing = entries[0]->getTargetColumn();
- if (colEnclosing && !colEnclosing->getGroups().empty())
- {
- CInterfaceGroup *col = colEnclosing->getGroups()[0];
- if (col)
- {
- // search first parent that limit size, if it is larger then enlarge to fit size
- CInterfaceGroup *limitingParent = colEnclosing->getParent();
- while (limitingParent && (limitingParent->getResizeFromChildH() || dynamic_cast(limitingParent)))
- limitingParent = limitingParent->getParent();
-
- getParentContainer()->setH(col->getH() + getParentContainer()->getHReal() - limitingParent->getHReal());
- }
- }
- }
-
-
- invalidateCoords();
-}
-
-// *****************************************************************************************************************
-void CGroupHeader::getEntries(std::vector &dest)
-{
- dest.clear();
- const std::vector &groups = getGroups();
- for (uint k = 0; k < groups.size(); ++k)
- {
- CGroupHeaderEntry *entry = dynamic_cast(groups[k]);
- if (entry)
- {
- dest.push_back(entry);
- }
- }
-}
-
-// *****************************************************************************************************************
-int CGroupHeader::luaEnlargeColumns(CLuaState &ls)
-{
- const char *funcName = "enlargeColumns";
- CLuaIHM::checkArgCount(ls, funcName, 1);
- CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
- enlargeColumns((sint32) ls.toNumber(1));
- return 0;
-}
-
-// *****************************************************************************************************************
-int CGroupHeader::luaResizeColumnsAndContainer(CLuaState &ls)
-{
- const char *funcName = "resizeColumnsAndContainer";
- CLuaIHM::checkArgCount(ls, funcName, 1);
- CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
- resizeColumnsAndContainer((sint32) ls.toNumber(1));
- return 0;
-}
-
-// *****************************************************************************************************************
-bool CGroupHeader::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
-{
- if(!CGroupList::parse(cur, parentGroup)) return false;
- CXMLAutoPtr prop((const char*) xmlGetProp( cur, (xmlChar*)"header_max_size" ));
- if (prop) fromString((const char*)prop, _HeaderMaxSize);
- return true;
-}
-
-/////////////////////////
-// CHeaderEntryResizer //
-/////////////////////////
-
-class CHeaderEntryResizer : public CCtrlBase
-{
-public:
- CHeaderEntryResizer(bool rightSide, sint32 wMin) : CCtrlBase(TCtorParam()),
- _RightSide(rightSide),
- _Moving(false),
- _StartX(0),
- _OffsetX(0),
- _WMin(wMin)
- {}
- void release()
- {
- if (CWidgetManager::getInstance()->getCapturePointerLeft() == this)
- {
- _Moving = false;
- CWidgetManager::getInstance()->setCapturePointerLeft(NULL);
- }
- }
- virtual uint getDeltaDepth() const { return 100; }
- CInterfaceGroup *getTargetGroup()
- {
- if (_RightSide) return _Parent;
-
- if (getParent()->getParent() == _Parent->getParentPos()) return NULL; // leftmost header
- return dynamic_cast(getParent()->getParentPos());
- }
- bool handleEvent (const NLGUI::CEventDescriptor &event)
- {
- if (_Parent)
- {
- if (event.getType() == NLGUI::CEventDescriptor::system)
- {
- const NLGUI::CEventDescriptorSystem &eds = (const NLGUI::CEventDescriptorSystem &) event;
- if (eds.getEventTypeExtended() == NLGUI::CEventDescriptorSystem::setfocus)
- {
- const NLGUI::CEventDescriptorSetFocus &edsf = (const NLGUI::CEventDescriptorSetFocus &) eds;
- if (edsf.hasFocus() == false)
- {
- release();
- return CCtrlBase::handleEvent(event);
- }
- }
- }
- if (event.getType() == NLGUI::CEventDescriptor::mouse)
- {
- const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
- if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown)
- {
- if (!this->isIn(eventDesc.getX(), eventDesc.getY())) return false;
- _TargetGroup = getTargetGroup();
- if (!_TargetGroup) return false;
- CWidgetManager::getInstance()->setCapturePointerLeft(this);
- _Moving = true;
- _OffsetX = _TargetGroup->getW() - eventDesc.getX();
- return true;
- }
- if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup)
- {
- release();
- }
- if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousemove)
- {
- if (_Moving && CWidgetManager::getInstance()->getCapturePointerLeft() == this)
- {
- if (!_TargetGroup)
- {
- release();
- return false;
- }
- sint32 newW = eventDesc.getX() + _OffsetX;
- // compute width of all header entries but this one
- CGroupHeader *header = dynamic_cast(getParent()->getParent());
- if (header)
- {
- sint32 w = 0;
- for (uint k = 0; k < header->getNumChildren(); ++k)
- {
- if (header->getChild(k) != _TargetGroup)
- {
- w += header->getChild(k)->getW();
- }
- }
- sint32 excess = w + newW - header->getHeaderMaxSize();
- if (excess)
- {
- // try to diminish the size of all headers starting from the last
- for (sint k = header->getNumChildren() - 1; k >= 0 && excess > 0; --k)
- {
- if (header->getChild(k) == _TargetGroup) break;
- CGroupHeaderEntry *ghe = dynamic_cast(header->getChild(k));
- sint32 wGain = std::min(excess, std::max((sint32) 0, ghe->getW() - ghe->getMinSize()));
- if (wGain > 0)
- {
- ghe->setW(ghe->getW() - wGain);
- ghe->invalidateCoords();
- excess -= wGain;
- }
- }
- }
- newW -= std::max((sint32) 0, excess);
- }
- _TargetGroup->setW(std::max(_WMin, newW));
- _TargetGroup->invalidateCoords();
- CGroupHeaderEntry *ghe = dynamic_cast((CInterfaceGroup *) _TargetGroup);
- if (ghe)
- {
- ghe->setW(_TargetGroup->getW());
- ghe->invalidateCoords();
- CAHManager::getInstance()->runActionHandler(ghe->getAHOnResize(), ghe, ghe->getAHOnResizeParams());
- }
- return true;
- }
- _Moving = false;
- }
- }
- }
- return CCtrlBase::handleEvent(event);
- }
- virtual void draw ()
- {
- // no-op
- }
- virtual bool getMouseOverShape(std::string &texName, uint8 &rot, NLMISC::CRGBA &col)
- {
-
- if (!getTargetGroup()) return false;
- texName = "curs_resize_LR.tga";
- rot = 0;
- col = CRGBA::White;
- return true;
- }
-
-private:
- NLMISC::CRefPtr _TargetGroup; // group for which w is modified
- bool _RightSide; // right or left side mover ?
- bool _Moving;
- sint32 _StartX; // value to add to mouse to get local x pos of target group
- sint32 _OffsetX;
- sint32 _WMin;
-};
-
-// *****************************************************************************************************************
-CGroupHeaderEntry::CGroupHeaderEntry(const TCtorParam ¶m) : CInterfaceGroup(param)
-{
- _MinSize = 4;
-}
-
-// *****************************************************************************************************************
-bool CGroupHeaderEntry::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
-{
- if (!CInterfaceGroup::parse(cur, parentGroup)) return false;
- // left mover
- CXMLAutoPtr prop((const char*) xmlGetProp( cur, (xmlChar*)"wmin" ));
- if (prop) fromString((const char*)prop, _MinSize);
- sint32 resizerSize = 4;
- prop = (char*) xmlGetProp( cur, (xmlChar*)"resizer_size" );
- if (prop) fromString((const char*)prop, resizerSize);
- prop = (char*) xmlGetProp(cur, (xmlChar*) "target");
- if (prop) _TargetColumnId = (const char *) prop;
-
- prop = (char*) xmlGetProp(cur, (xmlChar*) "on_resize");
- if (prop) _AHOnResize = (const char *) prop;
- prop = (char*) xmlGetProp(cur, (xmlChar*) "on_resize_params");
- if (prop) _AHOnResizeParams = (const char *) prop;
-
- CHeaderEntryResizer *hm = new CHeaderEntryResizer(false, _MinSize);
- addCtrl(hm);
- hm->setW(resizerSize);
- hm->setSizeRef(2);
- hm->setParent(this);
- hm->setParentPosRef(Hotspot_TL);
- hm->setPosRef(Hotspot_TL);
- // right mover
- hm = new CHeaderEntryResizer(true, _MinSize);
- addCtrl(hm);
- hm->setW(resizerSize);
- hm->setSizeRef(2);
- hm->setParent(this);
- hm->setParentPosRef(Hotspot_TR);
- hm->setPosRef(Hotspot_TR);
- //
- return true;
-}
-
-// *****************************************************************************************************************
-CInterfaceGroup *CGroupHeaderEntry::getTargetColumn() const
-{
- return dynamic_cast(CWidgetManager::getInstance()->getElementFromId(_TargetColumnId));
-}
-
-// *****************************************************************************************************************
-void CGroupHeaderEntry::updateCoords()
-{
- CInterfaceGroup::updateCoords();
- CInterfaceGroup *targetColumn = getTargetColumn();
- if (targetColumn)
- {
- if (targetColumn->getW() != getW())
- {
- targetColumn->setW(getW());
- targetColumn->invalidateCoords();
- }
- }
-}
-
-
-NLMISC_REGISTER_OBJECT(CViewBase, CGroupHeader, std::string, "header");
-NLMISC_REGISTER_OBJECT(CViewBase, CGroupHeaderEntry, std::string, "header_entry");
diff --git a/code/ryzom/client/src/interface_v3/group_header.h b/code/ryzom/client/src/interface_v3/group_header.h
deleted file mode 100644
index 113130d1d..000000000
--- a/code/ryzom/client/src/interface_v3/group_header.h
+++ /dev/null
@@ -1,85 +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 CL_GROUP_HEADER_H
-#define CL_GROUP_HEADER_H
-
-
-#include "nel/gui/group_list.h"
-
-
-class CGroupHeaderEntry;
-
-// *****************************************************************************************************************
-/** Display a header with movable entries.
- * Usually used with a table to change the size of each column (much like the windows file explorer in 'details' mode)
- *
- * \author Nicolas Vizerie
- * \author Nevrax France
- * \date 2006
- */
-class CGroupHeader : public CGroupList
-{
-public:
- REFLECT_EXPORT_START(CGroupHeader, CGroupList)
- REFLECT_LUA_METHOD("enlargeColumns", luaEnlargeColumns);
- REFLECT_LUA_METHOD("resizeColumnsAndContainer", luaResizeColumnsAndContainer);
- REFLECT_EXPORT_END
- CGroupHeader(const TCtorParam ¶m);
- // from CInterfaceGroup
- virtual bool parse(xmlNodePtr cur, CInterfaceGroup * parentGroup);
- sint32 getHeaderMaxSize() const { return _HeaderMaxSize; }
- // get the entries in this header
- void getEntries(std::vector &dest);
- // ensure that max. content of columns is visible (without the total width becoming more than 'getHeaderMaxSize()'
- void enlargeColumns(sint32 margin);
- // ensure that content of each column is visible
- void resizeColumnsAndContainer(sint32 margin);
-private:
- sint32 _HeaderMaxSize;
- int luaEnlargeColumns(CLuaState &ls);
- int luaResizeColumnsAndContainer(CLuaState &ls);
-};
-
-// *****************************************************************************************************************
-// an entry in a header, includes a "mover control" to move it inside its parent header
-// NOTE : when not used inside a CGroupHeader, will work, but there will be no 'max_size'
-class CGroupHeaderEntry : public CInterfaceGroup
-{
-public:
- CGroupHeaderEntry(const TCtorParam ¶m);
- // from CInterfaceGroup
- virtual bool parse(xmlNodePtr cur, CInterfaceGroup * parentGroup);
- sint32 getMinSize() const { return _MinSize; }
- virtual void updateCoords();
- CInterfaceGroup *getTargetColumn() const;
-
- const std::string &getAHOnResize() const { return _AHOnResize; }
- const std::string &getAHOnResizeParams() const { return _AHOnResizeParams; }
-
-private:
- sint32 _MinSize;
- std::string _TargetColumnId;
-
- std::string _AHOnResize;
- std::string _AHOnResizeParams;
-};
-
-
-
-
-#endif
-
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 a8c8b35e4..f71ccb5a2 100644
--- a/code/ryzom/client/src/interface_v3/register_interface_elements.cpp
+++ b/code/ryzom/client/src/interface_v3/register_interface_elements.cpp
@@ -50,7 +50,7 @@
#include "dbgroup_combo_box.h"
#include "nel/gui/group_tab.h"
#include "group_html.h"
-#include "group_header.h"
+#include "nel/gui/group_header.h"
#include "sphrase_manager.h"
//
#include "../r2/displayer_visual.h"