diff --git a/code/nel/include/nel/gui/group_tree.h b/code/nel/include/nel/gui/group_tree.h
new file mode 100644
index 000000000..b6000e779
--- /dev/null
+++ b/code/nel/include/nel/gui/group_tree.h
@@ -0,0 +1,376 @@
+// 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_TREE_H
+#define NL_GROUP_TREE_H
+
+#include "nel/misc/types_nl.h"
+#include "nel/gui/group_frame.h"
+#include "nel/misc/smart_ptr.h"
+
+namespace NLGUI
+{
+ class CViewText;
+ class CViewBitmap;
+
+ // ----------------------------------------------------------------------------
+ class CGroupTree : public CInterfaceGroup
+ {
+
+ public:
+
+ struct SNode;
+ // optional callback that is called when a node has been added
+ struct INodeAddedCallback
+ {
+ /** A node has just been added in the CGroupTree object
+ * \param node The logic node from which the ui node was built
+ * \param interfaceElement The ui node that was built
+ */
+ virtual void nodeAdded(SNode *node, CInterfaceElement *interfaceElement) = 0;
+ };
+
+ // Logic structure to initialize the group tree (root node is not displayed and is always opened)
+ struct SNode : public CReflectableRefPtrTarget
+ {
+ typedef NLMISC::CRefPtr TRefPtr;
+ // Common
+ std::string Id; // If not present auto-generated
+ bool Opened;
+ bool DisplayText; // If false instanciate a template
+ bool Show; // If false, the node is not displayed (true default, Root ignored)
+ sint32 YDecal;
+ // Text
+ ucstring Text; // Internationalized displayed text
+ sint32 FontSize; // If -1 (default), then take the groupTree one
+ NLMISC::CRGBA Color;
+ // Template
+ NLMISC::CSmartPtr Template;
+ // Actions Handlers (for left button)
+ std::string AHName;
+ std::string AHCond;
+ std::string AHParams;
+ // Actions Handlers (for right button)
+ std::string AHNameRight;
+ std::string AHParamsRight;
+ // Actions Handlers (close/open node)
+ std::string AHNameClose;
+ std::string AHParamsClose;
+ // bitmap at this level of hierarchy
+ std::string Bitmap; // additionnal bitmap
+ // Hierarchy
+ std::vector Children;
+ SNode *Father;
+ // updated at display
+ SNode *LastVisibleSon; // filled at build time, meaningfull only if son is shown and opened, undefined otherwise
+ // Node added callback
+ INodeAddedCallback *NodeAddedCallback;
+ //
+ CGroupTree *ParentTree;
+ // ----------------------------
+ SNode();
+ ~SNode();
+ void updateLastVisibleSon();
+ void detachChild(SNode *pNode);
+ void deleteChild(SNode *pNode);
+ void addChild (SNode *pNode);
+ bool isChild(SNode *pNode) const;
+ void addChildFront (SNode *pNode);
+ void addChildAtIndex (SNode *pNode, sint index);
+ void addChildSorted(SNode *pNode);
+ void addChildSortedByBitmap(SNode *pNode);
+ void setParentTree(CGroupTree *parent);
+ void setFather(SNode *father);
+ void closeAll();
+ void makeOrphan();
+ bool parse (xmlNodePtr cur, CGroupTree *parentGroup);
+ uint getNumBitmap() const { return Bitmap.empty() ? 0 : 1; }
+ SNode *getNodeFromId(const std::string &id);
+
+ // accessors
+ void setBitmap(const std::string &bitmap) { Bitmap = bitmap; }
+ std::string getBitmap() const { return Bitmap; }
+ void setOpened(bool opened) { Opened = opened; }
+ bool getOpened() const { return Opened; }
+ void setText(const ucstring &text) { Text = text; }
+ const ucstring& getText() const { return Text; }
+ sint32 getFontSize() const { return FontSize; }
+ void setFontSize(sint32 value) { FontSize = value; }
+ sint32 getYDecal() const { return YDecal; }
+ void setYDecal(sint32 value) { YDecal = value; }
+
+
+ std::string getId() const { return Id; }
+ void setId(const std::string &value) { Id = value; }
+ bool getShow() const { return Show; }
+ void setShow(bool value) { Show = value; }
+ std::string getAHName() const { return AHName; }
+ void setAHName(const std::string &value) { AHName = value; }
+ std::string getAHCond() const { return AHCond; }
+ void setAHCond(const std::string &value) { AHCond = value; }
+ std::string getAHParams() const { return AHParams; }
+ void setAHParams(const std::string &value) { AHParams = value; }
+ std::string getAHNameRight() const { return AHNameRight; }
+ void setAHNameRight(const std::string &value) { AHNameRight = value; }
+ std::string getAHParamsRight() const { return AHParamsRight; }
+ void setAHParamsRight(const std::string &value) { AHParamsRight = value; }
+ std::string getAHNameClose() const { return AHNameClose; }
+ void setAHNameClose(const std::string &value) { AHNameClose = value; }
+ std::string getAHParamsClose() const { return AHParamsClose; }
+ void setAHParamsClose(const std::string &value) { AHParamsClose = value; }
+ NLMISC::CRGBA getColor() const { return Color; }
+ void setColor(NLMISC::CRGBA color) { Color = color; }
+ // sort branch & sons alphabetically
+ void sort();
+ // sort branch & sons alphabetically & by bitmap name (blank bitmap being the first)
+ void sortByBitmap();
+
+ // lua bindings
+ int luaGetNumChildren(CLuaState &ls);
+ int luaGetChild(CLuaState &ls);
+ int luaDetachChild(CLuaState &ls);
+ int luaDeleteChild(CLuaState &ls);
+ int luaAddChild(CLuaState &ls);
+ int luaAddChildSorted(CLuaState &ls);
+ int luaAddChildSortedByBitmap(CLuaState &ls);
+ int luaIsChild(CLuaState &ls);
+ int luaAddChildFront (CLuaState &ls);
+ int luaAddChildAtIndex (CLuaState &ls);
+ int luaCloseAll(CLuaState &ls);
+ int luaGetFather(CLuaState &ls);
+ int luaSort(CLuaState &ls);
+ int luaSortByBitmap(CLuaState &ls);
+ int luaGetNodeFromId(CLuaState &ls);
+ int luaGetParentTree(CLuaState &ls);
+
+ // get node from first parameter on lua stack and throw necessary exception if not present
+ static SNode *luaGetNodeOnStack(CLuaState &ls, const char *funcName);
+
+ REFLECT_EXPORT_START(CGroupTree::SNode, CReflectable)
+ REFLECT_STRING("Id", getId, setId);
+ REFLECT_STRING("Bitmap", getBitmap, setBitmap);
+ REFLECT_SINT32("FontSize", getFontSize, setFontSize);
+ REFLECT_SINT32("YDecal", getYDecal, setYDecal);
+ REFLECT_STRING("AHName", getAHName, setAHName);
+ REFLECT_STRING("AHCond", getAHCond, setAHCond);
+ REFLECT_RGBA("Color", getColor, setColor);
+ REFLECT_STRING("AHParams", getAHParams, setAHParams);
+ REFLECT_STRING("AHNameRight", getAHNameRight, setAHNameRight);
+ REFLECT_STRING("AHParamsRight", getAHParamsRight, setAHParamsRight);
+ REFLECT_STRING("AHNameClose", getAHNameClose, setAHNameClose);
+ REFLECT_STRING("AHParamsClose", getAHParamsClose, setAHParamsClose);
+ REFLECT_BOOL("Opened", getOpened, setOpened);
+ REFLECT_BOOL("Show", getShow, setShow);
+ REFLECT_UCSTRING("Text", getText, setText);
+ // lua
+ REFLECT_LUA_METHOD("getNumChildren", luaGetNumChildren);
+ REFLECT_LUA_METHOD("getChild", luaGetChild);
+ REFLECT_LUA_METHOD("detachChild", luaDetachChild);
+ REFLECT_LUA_METHOD("deleteChild", luaDeleteChild);
+ REFLECT_LUA_METHOD("addChild", luaAddChild);
+ REFLECT_LUA_METHOD("addChildSorted", luaAddChildSorted);
+ REFLECT_LUA_METHOD("addChildSortedByBitmap", luaAddChildSortedByBitmap);
+ REFLECT_LUA_METHOD("addChildFront", luaAddChildFront);
+ REFLECT_LUA_METHOD("addChildAtIndex", luaAddChildAtIndex);
+ REFLECT_LUA_METHOD("isChild", luaIsChild);
+ REFLECT_LUA_METHOD("closeAll", luaCloseAll);
+ REFLECT_LUA_METHOD("getFather", luaGetFather);
+ REFLECT_LUA_METHOD("sort", luaSort);
+ REFLECT_LUA_METHOD("sortByBitmap", luaSortByBitmap);
+ REFLECT_LUA_METHOD("getNodeFromId", luaGetNodeFromId);
+ REFLECT_LUA_METHOD("getParentTree", luaGetParentTree);
+ REFLECT_EXPORT_END
+
+
+ };
+
+ public:
+
+ ///constructor
+ CGroupTree(const TCtorParam ¶m);
+
+ // dtor
+ virtual ~CGroupTree();
+
+ virtual bool parse (xmlNodePtr cur, CInterfaceGroup * parentGroup);
+
+ virtual void checkCoords();
+
+ virtual void updateCoords();
+
+ virtual void draw();
+
+ virtual bool handleEvent (const NLGUI::CEventDescriptor& eventDesc);
+
+ void reset();
+
+ // force rebuild the tree at next updateCoords()
+ void forceRebuild();
+
+ // For SNode
+ sint32 getIdNumber() { _IdGenerator++; return _IdGenerator; }
+ sint32 getFontSize() { return _FontSize; }
+ sint32 getYDecal() { return _YDecal; }
+
+ // Set root node and delete the last one the user must not delete all allocated sub node. Nb: selection is reseted
+ void setRootNode (SNode *);
+ // Remove all lines bitmaps and templates or texts
+ void removeAll();
+
+ // unselect current node in tree
+ void unselect();
+
+ // Select a node by its line index (depends on opened nodes). no-op if not possible (AH not here, line>size)
+ void selectLine(uint line, bool runAH = true);
+ // simulate right button click on the given line (this also select the line)
+ bool rightButton(uint line);
+
+ // Get the Selected Node Id. empty if none selected
+ const std::string &getSelectedNodeId() const;
+
+ // Select by the node Id. return false if not found (selection is not reseted)
+ // NB: if the node was already selected, no-op (no action handler launched)
+ bool selectNodeById(const std::string &nodeId, bool triggerAH = true);
+
+ // Get the root node (Opened State represent the current state)
+ SNode *getRootNode () const {return _RootNode;}
+
+ // get current SNode under the mouse (possibly NULL)
+ SNode *getNodeUnderMouse() const;
+
+ // Get/Change the NavigateOneBrnahc option. if false, then perform a reset before
+ bool getNavigateOneBranch() const {return _NavigateOneBranch;}
+ void changeNavigateOneBranch(bool newState);
+
+ // should be called by action handler when thy want to cancel the selection of the line that triggered them
+ void cancelNextSelectLine();
+
+ // Get selected node
+ SNode * getSelectedNode() { return _SelectedNode;}
+
+ // lua bindings
+ int luaGetRootNode(CLuaState &ls);
+ int luaSetRootNode(CLuaState &ls);
+ int luaForceRebuild(CLuaState &ls);
+ int luaSelectNodeById(CLuaState &ls);
+ int luaGetSelectedNodeId(CLuaState &ls);
+ int luaSelectLine(CLuaState &ls);
+ int luaUnselect(CLuaState &ls);
+ int luaGetNodeUnderMouse(CLuaState &ls);
+ int luaCancelNextSelectLine(CLuaState &ls);
+
+ // Reflection
+ REFLECT_EXPORT_START(CGroupTree, CInterfaceGroup)
+ REFLECT_BOOL ("navigate_one_branch", getNavigateOneBranch, changeNavigateOneBranch);
+ REFLECT_LUA_METHOD("getRootNode", luaGetRootNode);
+ REFLECT_LUA_METHOD("setRootNode", luaSetRootNode);
+ REFLECT_LUA_METHOD("forceRebuild", luaForceRebuild);
+ REFLECT_LUA_METHOD("getSelectedNodeId", luaGetSelectedNodeId);
+ REFLECT_LUA_METHOD("selectNodeById", luaSelectNodeById);
+ REFLECT_LUA_METHOD("selectLine", luaSelectLine);
+ REFLECT_LUA_METHOD("unselect", luaUnselect);
+ REFLECT_LUA_METHOD("getNodeUnderMouse", luaGetNodeUnderMouse);
+ REFLECT_LUA_METHOD("cancelNextSelectLine", luaCancelNextSelectLine);
+ REFLECT_EXPORT_END
+
+ private:
+
+ sint32 _BmpW, _BmpH, _FontSize, _YDecal;
+ sint32 _XExtend;
+
+ private:
+
+ // Display structure
+ struct SLine
+ {
+ CViewBase *TextOrTemplate;
+ std::vector Bmps;
+ SNode::TRefPtr Node;
+ uint8 Depth;
+
+ SLine()
+ {
+ TextOrTemplate = NULL;
+ }
+
+ ~SLine()
+ {
+ Bmps.clear();
+ }
+ uint getNumAdditionnalBitmap() const;
+ };
+
+ protected:
+
+ void rebuild();
+ void addTextLine (uint8 nDepth, SNode *pNode);
+ void addHierarchyBitmaps();
+
+ SNode *selectNodeByIdRecurse(SNode *pNode, const std::string &nodeId);
+
+ SNode *_RootNode;
+ sint32 _IdGenerator;
+ bool _MustRebuild;
+ std::vector _Lines;
+ sint32 _OverLine;
+ NLMISC::CRGBA _OverColor;
+ NLMISC::CRGBA _OverColorBack;
+ SNode *_SelectedNode;
+ sint32 _SelectedLine;
+ NLMISC::CRGBA _SelectedColor;
+
+ // If a node is closed and a son of this node was selected, then this option force the ancestor being the new selection
+ bool _SelectAncestorOnClose;
+ bool _NavigateOneBranch;
+ bool _AvoidSelectNodeByIdIR;
+
+ // when an action handler is run, it can call 'cancelSelectLine' if no selection should be done for real
+ bool _CancelNextSelectLine;
+
+
+ // Bitmap For arbo
+ std::string _ArboOpenFirst;
+ std::string _ArboCloseJustOne;
+ std::string _ArboSonWithoutSon;
+ std::string _ArboSonLast;
+ std::string _ArboSon;
+ std::string _ArboLevel;
+ std::string _ArboXExtend;
+
+ // Special rectangle
+ bool _RectangleOutlineMode;
+ sint32 _RectangleX, _RectangleY;
+ sint32 _RectangleW, _RectangleH;
+ sint32 _RectangleDeltaRL;
+
+ sint32 getHrcIconXStart(sint32 depth);
+ sint32 getHrcIconXEnd(sint32 depth);
+
+ void drawSelection(sint x, sint y, sint w, NLMISC::CRGBA col);
+
+ CViewBitmap *createViewBitmap(uint line, const std::string &idPrefix, const std::string &texture);
+ };
+
+}
+
+
+#endif // NL_GROUP_TREE_H
+
+/* End of group_tree.h */
+
+
diff --git a/code/nel/src/gui/group_tree.cpp b/code/nel/src/gui/group_tree.cpp
new file mode 100644
index 000000000..cb9372da6
--- /dev/null
+++ b/code/nel/src/gui/group_tree.cpp
@@ -0,0 +1,1638 @@
+// 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_tree.h"
+#include "nel/gui/interface_element.h"
+#include "nel/gui/view_bitmap.h"
+#include "nel/gui/view_text.h"
+#include "nel/gui/group_container_base.h"
+#include "nel/gui/action_handler.h"
+#include "nel/gui/lua_ihm.h"
+#include "nel/misc/i_xml.h"
+#include "nel/misc/i18n.h"
+#include "nel/misc/xml_auto_ptr.h"
+#include "nel/gui/widget_manager.h"
+#include "nel/gui/view_renderer.h"
+#include "nel/gui/view_pointer_base.h"
+
+using namespace std;
+using namespace NLMISC;
+
+namespace NLGUI
+{
+
+ // ----------------------------------------------------------------------------
+ // SNode
+ // ----------------------------------------------------------------------------
+ // TestYoyo
+ //uint SNodeCount= 0;
+ // ----------------------------------------------------------------------------
+ CGroupTree::SNode::SNode()
+ {
+ Opened = false;
+ Father = NULL;
+ FontSize = -1;
+ YDecal = 0;
+ DisplayText = true;
+ Template = NULL;
+ Show= true;
+ NodeAddedCallback = NULL;
+ Color = CRGBA::White;
+ ParentTree = NULL;
+ LastVisibleSon = NULL;
+ // TestYoyo
+ //nlinfo("SNode(): %8x, c%d", this, SNodeCount++);
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::SNode::updateLastVisibleSon()
+ {
+ LastVisibleSon = NULL;
+ if (!Show || !Opened) return;
+ for (sint sonIndex = (sint)Children.size() - 1; sonIndex >= 0; -- sonIndex)
+ {
+ if (Children[sonIndex]->Show)
+ {
+ LastVisibleSon = Children[sonIndex];
+ break;
+ }
+ }
+ for(uint k = 0; k < Children.size(); ++k)
+ {
+ Children[k]->updateLastVisibleSon();
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ CGroupTree::SNode::~SNode()
+ {
+ makeOrphan();
+ // IMPORTANT : must delete in reverse order because "makeOrphan" is called when deleting sons, thus changing vector size...
+ for (sint i = (sint)Children.size() - 1; i >= 0; --i)
+ delete Children[i];
+ Children.clear();
+ // TestYoyo
+ //nlinfo("~SNode(): %8x, c%d", this, --SNodeCount);
+ }
+
+ void CGroupTree::SNode::setParentTree(CGroupTree *parent)
+ {
+ ParentTree = parent;
+ for (uint k = 0; k < Children.size(); ++k)
+ {
+ Children[k]->setParentTree(parent);
+ }
+ }
+
+ void CGroupTree::SNode::setFather(SNode *father)
+ {
+ Father = father;
+ setParentTree(father ? father->ParentTree : NULL);
+ }
+
+
+ CGroupTree::SNode *CGroupTree::SNode::getNodeFromId(const std::string &id)
+ {
+ if (Id == id) return this;
+ // breadth first
+ for (uint k = 0; k < Children.size(); ++k)
+ {
+ if (Children[k]->Id == id)
+ {
+ return Children[k];
+ }
+ }
+ for (uint k = 0; k < Children.size(); ++k)
+ {
+ SNode *found = Children[k]->getNodeFromId(id);
+ if (found) return found;
+ }
+ return NULL;
+ }
+
+
+ void CGroupTree::SNode::makeOrphan()
+ {
+ if (ParentTree)
+ {
+ ParentTree->forceRebuild();
+ setParentTree(NULL);
+ }
+ //
+ if (Template != NULL)
+ {
+ if (Template->getParent())
+ {
+ // don't delete because may want to keep it. NB: deleted by smartptr at dtor
+ Template->getParent()->delGroup(Template, true);
+ }
+ }
+ //
+ if (Father)
+ {
+ Father->detachChild(this);
+ Father = NULL;
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ struct CNodeSorter
+ {
+ bool operator()(const CGroupTree::SNode *lhs, const CGroupTree::SNode *rhs) const
+ {
+ return lhs->Text < rhs->Text;
+ }
+ };
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::SNode::sort()
+ {
+ std::sort(Children.begin(), Children.end(), CNodeSorter());
+ for(uint k = 0; k < Children.size(); ++k)
+ {
+ Children[k]->sort();
+ }
+ }
+
+
+ // ----------------------------------------------------------------------------
+ struct CNodeSorterByBitmap
+ {
+ bool operator()(const CGroupTree::SNode *lhs, const CGroupTree::SNode *rhs) const
+ {
+ if (lhs->Bitmap != rhs->Bitmap) return lhs->Bitmap < rhs->Bitmap;
+ return lhs->Text < rhs->Text;
+ }
+ };
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::SNode::sortByBitmap()
+ {
+ std::sort(Children.begin(), Children.end(), CNodeSorterByBitmap());
+ for(uint k = 0; k < Children.size(); ++k)
+ {
+ Children[k]->sortByBitmap();
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::SNode::addChild (SNode *pNode)
+ {
+ if(!pNode) return;
+ pNode->makeOrphan();
+ Children.push_back(pNode);
+ pNode->setFather(this);
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::SNode::addChildSorted(SNode *pNode)
+ {
+ if (!pNode) return;
+ pNode->makeOrphan();
+ std::vector::iterator it = std::lower_bound(Children.begin(), Children.end(), pNode, CNodeSorter());
+ Children.insert(it, pNode);
+ pNode->setFather(this);
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::SNode::addChildSortedByBitmap(SNode *pNode)
+ {
+ if (!pNode) return;
+ pNode->makeOrphan();
+ std::vector::iterator it = std::lower_bound(Children.begin(), Children.end(), pNode, CNodeSorterByBitmap());
+ Children.insert(it, pNode);
+ pNode->setFather(this);
+ }
+
+ // ----------------------------------------------------------------------------
+ bool CGroupTree::SNode::isChild(SNode *pNode) const
+ {
+ return std::find(Children.begin(), Children.end(), pNode) != Children.end();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::SNode::detachChild(SNode *pNode)
+ {
+ nlassert(pNode);
+ nlassert(isChild(pNode));
+ Children.erase(std::remove(Children.begin(), Children.end(), pNode), Children.end());
+ pNode->setFather(NULL);
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::SNode::deleteChild(SNode *pNode)
+ {
+ delete pNode;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::SNode::addChildFront (SNode *pNode)
+ {
+ if(!pNode) return;
+ pNode->makeOrphan();
+ Children.insert(Children.begin(), pNode);
+ pNode->setFather(this);
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::SNode::addChildAtIndex(SNode *pNode, sint index)
+ {
+ if(!pNode) return;
+ if (index < 0 || index > (sint) Children.size())
+ {
+ nlwarning(" bad index %d (%d elements in the vector)", index, Children.size());
+ return;
+ }
+ pNode->makeOrphan();
+ if (pNode->Father)
+ {
+ pNode->Father->detachChild(pNode);
+ }
+ Children.insert(Children.begin() + index, pNode);
+ pNode->setFather(this);
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::SNode::closeAll()
+ {
+ Opened = false;
+ for (uint i = 0; i < Children.size(); ++i)
+ Children[i]->closeAll();
+ }
+
+ // ----------------------------------------------------------------------------
+ bool CGroupTree::SNode::parse (xmlNodePtr cur, CGroupTree * parentGroup)
+ {
+ if (stricmp((char*)cur->name, "node") == 0)
+ {
+ CXMLAutoPtr id((const char*) xmlGetProp (cur, (xmlChar*)"id"));
+ if (id)
+ Id = (const char*)id;
+ else
+ Id = toString(parentGroup->getIdNumber());
+
+ CXMLAutoPtr name((const char*) xmlGetProp (cur, (xmlChar*)"name"));
+
+ if (name)
+ {
+ const char *ptrName = (const char*)name;
+ Text = ucstring(ptrName);
+ if ((strlen(ptrName)>2) && (ptrName[0] == 'u') && (ptrName[1] == 'i'))
+ Text = CI18N::get (ptrName);
+ }
+
+ CXMLAutoPtr color((const char*) xmlGetProp (cur, (xmlChar*)"color"));
+ if (color)
+ {
+ Color = convertColor(color);
+ }
+
+ CXMLAutoPtr open((const char*) xmlGetProp (cur, (xmlChar*)"opened"));
+ if (open) Opened = convertBool(open);
+
+ CXMLAutoPtr show((const char*) xmlGetProp (cur, (xmlChar*)"show"));
+ if (open) Show = convertBool(show);
+
+ CXMLAutoPtr ah((const char*) xmlGetProp (cur, (xmlChar*)"handler"));
+ if (ah) AHName = (const char*)ah;
+ CXMLAutoPtr cond((const char*) xmlGetProp (cur, (xmlChar*)"cond"));
+ if (cond) AHCond = (const char*)cond;
+ CXMLAutoPtr params((const char*) xmlGetProp (cur, (xmlChar*)"params"));
+ if (params) AHParams = (const char*)params;
+
+ CXMLAutoPtr ahRight((const char*) xmlGetProp (cur, (xmlChar*)"handler_right"));
+ if (ahRight) AHNameRight = (const char*)ahRight;
+ CXMLAutoPtr paramsRight((const char*) xmlGetProp (cur, (xmlChar*)"params_right"));
+ if (paramsRight) AHParamsRight = (const char*)paramsRight;
+
+ CXMLAutoPtr bitmap((const char*) xmlGetProp (cur, (xmlChar*)"bitmap"));
+ if (bitmap) Bitmap = (const char*)bitmap;
+
+ FontSize = parentGroup->getFontSize();
+ CXMLAutoPtr fs((const char*) xmlGetProp (cur, (xmlChar*)"fontsize"));
+ if (fs) fromString((const char*)fs, FontSize);
+
+ YDecal = parentGroup->getYDecal();
+ CXMLAutoPtr yDecalPtr((const char*) xmlGetProp (cur, (xmlChar*)"y_decal"));
+ if (yDecalPtr) fromString((const char*)yDecalPtr, YDecal);
+
+
+ xmlNodePtr child = cur->children;
+
+ while (child != NULL)
+ {
+ SNode *pNode = new SNode;
+ pNode->parse (child, parentGroup);
+ addChild(pNode);
+ child = child->next;
+ }
+ }
+
+ return true;
+ }
+
+ // ----------------------------------------------------------------------------
+ // CGroupTree
+ // ----------------------------------------------------------------------------
+
+ NLMISC_REGISTER_OBJECT(CViewBase, CGroupTree, std::string, "tree");
+
+ // ----------------------------------------------------------------------------
+ CGroupTree::CGroupTree(const TCtorParam ¶m)
+ :CInterfaceGroup(param)
+ {
+ _IdGenerator = 0;
+ _XExtend= 0;
+ _BmpW = 14;
+ _BmpH = 14;
+ _FontSize = 12;
+ _YDecal = 0;
+ _MustRebuild = true;
+ _OverColor = CRGBA(255, 255, 255, 128);
+ _OverColorBack = CRGBA(64, 64, 64, 255);
+ _SelectedNode = NULL;
+ _SelectedLine = -1;
+ _SelectedColor = CRGBA(255, 128, 128, 128);
+ _RootNode = NULL;
+ _OverLine = -1;
+ _SelectAncestorOnClose= false;
+ _NavigateOneBranch= false;
+
+ _ArboOpenFirst= "arbo_open_first.tga";
+ _ArboCloseJustOne= "arbo_close_just_one.tga";
+ _ArboSonWithoutSon= "arbo_son_without_son.tga";
+ _ArboSonLast= "arbo_son_last.tga";
+ _ArboSon= "arbo_son.tga";
+ _ArboLevel= "arbo_level.tga";
+
+ _RectangleOutlineMode= false;
+ _RectangleX= 0;
+ _RectangleY= 0;
+ _RectangleW= 10;
+ _RectangleH= 10;
+ _RectangleDeltaRL= 0;
+
+ _AvoidSelectNodeByIdIR= false;
+ }
+
+ // ----------------------------------------------------------------------------
+ CGroupTree::~CGroupTree()
+ {
+ removeAll();
+ if (_RootNode != NULL) delete _RootNode;
+ }
+
+ // ----------------------------------------------------------------------------
+ bool CGroupTree::parse (xmlNodePtr cur, CInterfaceGroup * parentGroup)
+ {
+ if (!CInterfaceGroup::parse(cur, parentGroup))
+ return false;
+
+ CXMLAutoPtr ptr;
+
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"col_over");
+ if (ptr) _OverColor = convertColor(ptr);
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"col_select");
+ if (ptr) _SelectedColor = convertColor(ptr);
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"col_over_back");
+ if (ptr) _OverColorBack = convertColor(ptr);
+
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"fontsize");
+ if (ptr) fromString((const char*)ptr, _FontSize);
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"select_ancestor_on_close");
+ if (ptr) _SelectAncestorOnClose = convertBool(ptr);
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"navigate_one_branch");
+ if (ptr) _NavigateOneBranch = convertBool(ptr);
+
+ // read optional arbo bmps
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"arbo_open_first");
+ if (ptr) _ArboOpenFirst= (const char*)ptr;
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"arbo_close_just_one");
+ if (ptr) _ArboCloseJustOne= (const char*)ptr;
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"arbo_son_without_son");
+ if (ptr) _ArboSonWithoutSon= (const char*)ptr;
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"arbo_son_last");
+ if (ptr) _ArboSonLast= (const char*)ptr;
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"arbo_son");
+ if (ptr) _ArboSon= (const char*)ptr;
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"arbo_level");
+ if (ptr) _ArboLevel= (const char*)ptr;
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"arbo_x_extend");
+ if (ptr) _ArboXExtend= (const char*)ptr;
+
+ // Rectangle selection style
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"rectangle_outline");
+ if (ptr) _RectangleOutlineMode= convertBool(ptr);
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"rectangle_x");
+ if (ptr) fromString((const char*)ptr, _RectangleX);
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"rectangle_y");
+ if (ptr) fromString((const char*)ptr, _RectangleY);
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"rectangle_w");
+ if (ptr) fromString((const char*)ptr, _RectangleW);
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"rectangle_h");
+ if (ptr) fromString((const char*)ptr, _RectangleH);
+ ptr = (char*) xmlGetProp (cur, (xmlChar*)"rectangle_drl");
+ if (ptr) fromString((const char*)ptr, _RectangleDeltaRL);
+
+
+
+ _RootNode = new SNode;
+ // bool ok = true;
+ cur = cur->children;
+ while (cur)
+ {
+ // Check that this is a camera node
+ if ( stricmp((char*)cur->name, "node") == 0 )
+ {
+ SNode *pNode = new SNode;
+ if (!pNode->parse(cur, this))
+ {
+ delete pNode;
+ nlwarning("cannot parse node");
+ }
+ else
+ {
+ _RootNode->addChild(pNode);
+ }
+ }
+ cur = cur->next;
+ }
+ _RootNode->Opened = true;
+ _ResizeFromChildW = _ResizeFromChildH = true;
+
+ CViewRenderer &rVR = *CViewRenderer::getInstance();
+ sint32 id = rVR.getTextureIdFromName(_ArboOpenFirst);
+ if (id != -1)
+ rVR.getTextureSizeFromId(id, _BmpW, _BmpH);
+ sint32 dummy;
+ id = rVR.getTextureIdFromName(_ArboXExtend);
+ if (id != -1)
+ rVR.getTextureSizeFromId(id, _XExtend, dummy);
+ else
+ // if not found, reset, to avoid errors
+ _ArboXExtend= "";
+
+
+ return true;
+ }
+
+ // ----------------------------------------------------------------------------
+ sint32 CGroupTree::getHrcIconXStart(sint32 depth)
+ {
+ return depth*(_BmpW+_XExtend);
+ }
+
+ // ----------------------------------------------------------------------------
+ sint32 CGroupTree::getHrcIconXEnd(sint32 depth)
+ {
+ return depth*(_BmpW+_XExtend) + _BmpW;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::checkCoords()
+ {
+ CInterfaceGroup::checkCoords();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::updateCoords()
+ {
+ if (_MustRebuild)
+ rebuild();
+ CInterfaceGroup::updateCoords();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::drawSelection(sint x, sint y, sint w, CRGBA col)
+ {
+ CViewRenderer &rVR = *CViewRenderer::getInstance();
+
+ if(!_RectangleOutlineMode)
+ {
+ rVR.drawRotFlipBitmap (_RenderLayer, _XReal+_OffsetX+x, _YReal+_OffsetY+y,
+ w, _BmpH, 0, false, rVR.getBlankTextureId(),
+ col );
+ }
+ else
+ {
+ // draw the outline
+ x+= _XReal+_OffsetX+_RectangleX;
+ y+= _YReal+_OffsetY+_RectangleY;
+ w= _RectangleW;
+ sint32 h= _RectangleH;
+ sint32 rl= _RenderLayer + _RectangleDeltaRL;
+
+ rVR.drawRotFlipBitmap (rl, x, y, 1, h, 0, false, rVR.getBlankTextureId(), col );
+ rVR.drawRotFlipBitmap (rl, x+w-1, y, 1, h, 0, false, rVR.getBlankTextureId(), col );
+ rVR.drawRotFlipBitmap (rl, x, y, w, 1, 0, false, rVR.getBlankTextureId(), col );
+ rVR.drawRotFlipBitmap (rl, x, y+h-1, w, 1, 0, false, rVR.getBlankTextureId(), col );
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ CGroupTree::SNode *CGroupTree::getNodeUnderMouse() const
+ {
+ if (_OverLine == -1) return NULL;
+ return _Lines[_OverLine].Node;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::draw()
+ {
+ // get the clip area
+ sint32 clipx, clipy, clipw, cliph;
+ getClip(clipx, clipy, clipw, cliph);
+
+ // change the over
+ bool bDisplayOver = true;
+
+ if (!CWidgetManager::getInstance()->isMouseHandlingEnabled())
+ {
+ bDisplayOver = false;
+ }
+ else
+ if (CWidgetManager::getInstance()->getModalWindow() == NULL)
+ {
+ sint32 x = CWidgetManager::getInstance()->getPointer()->getX();
+ sint32 y = CWidgetManager::getInstance()->getPointer()->getY();
+
+ CInterfaceGroup *pIG = CWidgetManager::getInstance()->getWindowUnder(x, y);
+ CInterfaceGroup *pParent = this;
+ bool bFound = false;
+ while (pParent != NULL)
+ {
+ if (pParent == pIG)
+ {
+ bFound = true;
+ break;
+ }
+ pParent = pParent->getParent();
+ }
+
+ // if the mouse is not in the clipped area
+ if ((x < clipx) ||
+ (x > (clipx + clipw)) ||
+ (y < clipy) ||
+ (y > (clipy + cliph)) || !bFound)
+ {
+ _OverLine = -1;
+ }
+ else
+ {
+ x = x - _OffsetX;
+ y = y - _OffsetY;
+ for (sint32 i = 0; i < (sint32)_Lines.size(); ++i)
+ {
+ if ((y >= (_YReal+(sint32)(_Lines.size()-i-1)*_BmpH)) &&
+ (y < (_YReal+(sint32)(_Lines.size()-i)*_BmpH)))
+ {
+ _OverLine = i;
+ }
+ }
+ if (_OverLine != -1)
+ {
+ if (x < _XReal + getHrcIconXEnd(_Lines[_OverLine].Depth))
+ bDisplayOver = false;
+ }
+ }
+ }
+
+ // some over to display?
+ if ((_OverLine != -1) && bDisplayOver)
+ {
+ // Find the first container
+ CInterfaceGroup *pIG = _Parent;
+ CGroupContainerBase *pGC = dynamic_cast(pIG);
+ while (pIG != NULL)
+ {
+ pIG = pIG->getParent();
+ if (pIG == NULL) break;
+ if (dynamic_cast(pIG) != NULL)
+ pGC = dynamic_cast(pIG);
+ }
+
+ // avoid if window grayed
+ if (pGC != NULL)
+ {
+ if (pGC->isGrayed())
+ bDisplayOver = false;
+ }
+
+ // Has to display the over?
+ if (bDisplayOver)
+ {
+ // !NULL if the text over must displayed across all windows
+ CViewText *viewTextExtend= NULL;
+
+ // If the line is a simple Text line (not template)
+ if(_Lines[_OverLine].Node && _Lines[_OverLine].Node->DisplayText)
+ {
+ // Get the view text
+ viewTextExtend= safe_cast(_Lines[_OverLine].TextOrTemplate);
+ // If this viewText is not too big, no need
+ if(viewTextExtend->getXReal() + viewTextExtend->getWReal() <= (clipx+clipw) )
+ viewTextExtend= NULL;
+ }
+
+ // draw simple over
+ if(!viewTextExtend)
+ {
+ CRGBA col = _OverColor;
+ if(getModulateGlobalColor())
+ {
+ col.modulateFromColor (_OverColor, CWidgetManager::getInstance()->getGlobalColorForContent());
+ }
+ else
+ {
+ col= _OverColor;
+ col.A = (uint8)(((sint32)col.A*((sint32)CWidgetManager::getInstance()->getGlobalColorForContent().A+1))>>8);
+ }
+
+ drawSelection( getHrcIconXEnd(_Lines[_OverLine].Depth + _Lines[_OverLine].getNumAdditionnalBitmap()), ((sint)_Lines.size()-_OverLine-1)*_BmpH,
+ _WReal-getHrcIconXEnd(_Lines[_OverLine].Depth + _Lines[_OverLine].getNumAdditionnalBitmap()), col);
+ }
+ // Draw extended over
+ else
+ {
+ CRGBA col = _OverColorBack;
+ // must add the selection color
+ if(_SelectedLine == _OverLine)
+ {
+ // simulate alpha blend of the selection bitmap
+ CRGBA sel= _SelectedColor;
+ sel.A= (uint8)((sel.A*((sint32)CWidgetManager::getInstance()->getGlobalColorForContent().A+1))>>8);
+ col.blendFromuiRGBOnly(col, sel, sel.A);
+ }
+
+ // will be drawn over all the interface
+ CWidgetManager::getInstance()->setOverExtendViewText(viewTextExtend, col);
+ }
+ }
+ }
+
+ // some selection to display
+ if (_SelectedLine != -1)
+ {
+ CRGBA col = _SelectedColor;
+ if(getModulateGlobalColor())
+ {
+ col.modulateFromColor (_SelectedColor, CWidgetManager::getInstance()->getGlobalColorForContent());
+ }
+ else
+ {
+ col= _SelectedColor;
+ col.A = (uint8)(((sint32)col.A*((sint32)CWidgetManager::getInstance()->getGlobalColorForContent().A+1))>>8);
+ }
+
+ drawSelection( getHrcIconXEnd(_Lines[_SelectedLine].Depth + _Lines[_SelectedLine].getNumAdditionnalBitmap()), ((sint)_Lines.size()-_SelectedLine-1)*_BmpH,
+ _WReal-getHrcIconXEnd(_Lines[_SelectedLine].Depth + _Lines[_SelectedLine].getNumAdditionnalBitmap()), col );
+ }
+
+ CInterfaceGroup::draw();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::selectLine(uint line, bool runAH /*= true*/)
+ {
+ if(line>=_Lines.size())
+ return;
+
+ if (!_Lines[line].Node)
+ {
+ // just deleted : must wait next draw to know the new line under mouse
+ return;
+ }
+ if (!_Lines[line].Node->AHName.empty() && runAH)
+ {
+ _CancelNextSelectLine = false;
+ /*
+ CAHManager::getInstance()->runActionHandler ( _Lines[line].Node->AHName,
+ this,
+ _Lines[line].Node->AHParams );
+ */
+ if (!_CancelNextSelectLine)
+ {
+ _SelectedLine = line;
+ _SelectedNode = _Lines[line].Node;
+ }
+ CAHManager::getInstance()->runActionHandler ( _Lines[line].Node->AHName,
+ this,
+ _Lines[line].Node->AHParams );
+ _CancelNextSelectLine = false;
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ bool CGroupTree::rightButton(uint line)
+ {
+ if(line>=_Lines.size())
+ return false;
+
+ if (!_Lines[_OverLine].Node || _Lines[_OverLine].Node->AHNameRight.empty())
+ return false;
+
+ if (line != (uint) _SelectedLine) selectLine(line, false);
+
+ CAHManager::getInstance()->runActionHandler ( _Lines[line].Node->AHNameRight,
+ this,
+ _Lines[line].Node->AHParamsRight );
+ return true;
+ }
+
+
+
+ // ----------------------------------------------------------------------------
+ const std::string &CGroupTree::getSelectedNodeId() const
+ {
+ if(_SelectedLine>=0 && _SelectedLine<(sint)_Lines.size() && _Lines[_SelectedLine].Node)
+ {
+ return _Lines[_SelectedLine].Node->Id;
+ }
+ else
+ {
+ static string empty;
+ return empty;
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ bool CGroupTree::handleEvent (const NLGUI::CEventDescriptor& event)
+ {
+ if (!_Active) return false;
+ if (CInterfaceGroup::handleEvent(event)) return true;
+ // The line must be over (pre-selected)
+ if (event.getType() == NLGUI::CEventDescriptor::mouse && _OverLine>=0)
+ {
+ const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
+
+ if (!isIn(eventDesc.getX(), eventDesc.getY()))
+ return false;
+
+ sint32 x = eventDesc.getX() - _OffsetX;
+ // sint32 y = eventDesc.getY() - _OffsetY;
+ bool bText = false;
+ if (x >= (_XReal+getHrcIconXEnd(_Lines[_OverLine].Depth + _Lines[_OverLine].getNumAdditionnalBitmap())))
+ bText = true;
+ bool bIcon = false;
+ if ((x > (_XReal+getHrcIconXStart(_Lines[_OverLine].Depth)-_XExtend)) &&
+ (x < (_XReal+getHrcIconXEnd(_Lines[_OverLine].Depth + _Lines[_OverLine].getNumAdditionnalBitmap()))))
+ bIcon = true;
+
+ if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown)
+ {
+ if (bText)
+ {
+ return rightButton(_OverLine != -1 ? _OverLine : _SelectedLine);
+ }
+ }
+
+ if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown)
+ {
+ // line selection
+ if (bText)
+ {
+ selectLine(_OverLine);
+ }
+ // close of node
+ if (bIcon)
+ {
+ SNode *changedNode= _Lines[_OverLine].Node;
+
+ if (changedNode)
+ {
+ // if "SelectAncestorOnClose" feature wanted, if it was opened before, and if some node selected
+ if(_SelectAncestorOnClose && changedNode->Opened && _SelectedNode)
+ {
+ // check that the selected node is a son of the closing node
+ SNode *parent= _SelectedNode->Father;
+ while(parent)
+ {
+ if(parent==changedNode)
+ {
+ // Then change selection to this parent first
+ selectLine(_OverLine);
+ break;
+ }
+ parent= parent->Father;
+ }
+ }
+
+ // standard hrc
+ if(!_NavigateOneBranch)
+ {
+ // open/close the node
+ changedNode->Opened = !changedNode->Opened;
+ }
+ // else must close all necessary nodes.
+ else
+ {
+ if(changedNode->Opened)
+ changedNode->closeAll();
+ else
+ {
+ // must closeAll all his brothers first.
+ if(changedNode->Father)
+ {
+ changedNode->Father->closeAll();
+ changedNode->Father->Opened= true;
+ }
+ changedNode->Opened= true;
+ }
+ }
+
+ CAHManager::getInstance()->runActionHandler(changedNode->AHNameClose, this, changedNode->AHParamsClose);
+ }
+ forceRebuild();
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::unselect()
+ {
+ _SelectedLine = -1;
+ _SelectedNode = NULL;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::reset()
+ {
+ unselect();
+ if (_RootNode)
+ {
+ _RootNode->closeAll();
+ _RootNode->Opened = true;
+ }
+ forceRebuild();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::forceRebuild()
+ {
+ _MustRebuild = true;
+ invalidateCoords();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::rebuild()
+ {
+ // Remove all
+ removeAll();
+
+ if (_RootNode)
+ _RootNode->Opened = true;
+
+ // Rebuild all depending on the logic
+ if(_RootNode)
+ addTextLine (0, _RootNode);
+
+ // Reformating
+ sint32 sizeH = (sint32)_Lines.size()*_BmpH;
+ for (uint i = 0; i < _Lines.size(); ++i)
+ _Lines[i].TextOrTemplate->setY (_Lines[i].Node->YDecal + sizeH - ((1+_Lines[i].TextOrTemplate->getY())*_BmpH));
+ // Add the hierarchy bitmaps
+ addHierarchyBitmaps();
+ // Find if we can display selection
+ if (_SelectedNode != NULL)
+ {
+ _SelectedLine = -1;
+ for (uint i = 0; i < _Lines.size(); ++i)
+ if (_Lines[i].Node == _SelectedNode)
+ {
+ _SelectedLine = i;
+ break;
+ }
+ }
+
+ // Ok no more need to rebuild all this
+ _MustRebuild = false;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::setRootNode (SNode *pNewRoot)
+ {
+ // reset selection
+ _SelectedLine= -1;
+ _SelectedNode= NULL;
+
+ CRefPtr refPtrNewRoot = pNewRoot;
+ // clear old
+ delete _RootNode;
+
+ // If the node was deleted
+ if (pNewRoot && !refPtrNewRoot)
+ {
+ // NB nico : if anyone need that a day, please feel free to modify ...
+ nlwarning("Trying to set a node that is part of the tree as root node (not supported yet ...)");
+ }
+
+ // set new (may be NULL)
+ _RootNode = pNewRoot;
+ if(pNewRoot)
+ pNewRoot->setParentTree(this);
+ rebuild();
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::removeAll()
+ {
+ // Remove (but not delete) the groups template if any
+ for(uint i=0;i<_Lines.size();i++)
+ {
+ if (_Lines[i].Node)
+ {
+ if(_Lines[i].Node->Template)
+ {
+ delGroup(_Lines[i].Node->Template, true);
+ }
+ }
+ }
+
+ // Clear all lines, but don't delete templates
+ _Lines.clear();
+
+ // Delete all BmpViews and/or all text views
+ clearViews();
+ }
+
+
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::addTextLine (uint8 nDepth, CGroupTree::SNode *pNode)
+ {
+ pNode->setParentTree(this);
+ if (nDepth > 0)
+ {
+ SLine line;
+ line.Depth = nDepth-1;
+ line.Node = pNode;
+ if (pNode->DisplayText)
+ {
+ CViewText *pVT = new CViewText(TCtorParam());
+ line.TextOrTemplate = pVT;
+ pVT->setId("t"+toString(_Lines.size()));
+ pVT->setText(pNode->Text);
+ pVT->setColor(pNode->Color);
+ if(pNode->FontSize==-1)
+ pVT->setFontSize(_FontSize);
+ else
+ pVT->setFontSize(pNode->FontSize);
+ }
+ else
+ {
+ line.TextOrTemplate = pNode->Template;
+ }
+ line.TextOrTemplate->setPosRef (Hotspot_BL);
+ line.TextOrTemplate->setParentPosRef (Hotspot_BL);
+ line.TextOrTemplate->setParent (this);
+ line.TextOrTemplate->setParentPos (NULL);
+ line.TextOrTemplate->setX (getHrcIconXEnd(nDepth-1 + line.getNumAdditionnalBitmap()));
+ line.TextOrTemplate->setY ((sint32)_Lines.size());
+ line.TextOrTemplate->setModulateGlobalColor(this->getModulateGlobalColor());
+ if (pNode->DisplayText)
+ addView (line.TextOrTemplate);
+ else
+ addGroup ((CInterfaceGroup*)line.TextOrTemplate);
+ if (pNode->NodeAddedCallback)
+ {
+ pNode->NodeAddedCallback->nodeAdded(pNode, line.TextOrTemplate);
+ }
+ _Lines.push_back(line);
+ }
+
+ // recurs
+ if (pNode->Opened)
+ {
+ // **** standard hierarchy display, or if root
+ if(!_NavigateOneBranch || nDepth==0)
+ {
+ for (uint i = 0; i < pNode->Children.size(); ++i)
+ {
+ // add the branch only if want to show it
+ if(pNode->Children[i]->Show)
+ addTextLine (nDepth+1, pNode->Children[i]);
+ }
+ }
+ // **** display only the branch navigated
+ else
+ {
+ // find the first child opened
+ sint childOpen= -1;
+ for (uint i = 0; i < pNode->Children.size(); ++i)
+ {
+ // don't take hid ones
+ if(pNode->Children[i]->Show && pNode->Children[i]->Opened)
+ {
+ childOpen= i;
+ break;
+ }
+ }
+
+ // If some chidl opened, add just this line
+ if(childOpen>=0)
+ {
+ addTextLine (nDepth+1, pNode->Children[childOpen]);
+ }
+ // else add all closed, but showable lines
+ else
+ {
+ for (uint i = 0; i < pNode->Children.size(); ++i)
+ {
+ if(pNode->Children[i]->Show)
+ addTextLine (nDepth+1, pNode->Children[i]);
+ }
+ }
+ }
+ }
+ }
+
+ // ----------------------------------------------------------------------------
+ CViewBitmap *CGroupTree::createViewBitmap(uint line, const std::string &idPrefix, const std::string &texture)
+ {
+ CViewBitmap *pVB = new CViewBitmap(TCtorParam());
+ pVB->setId(idPrefix+toString(_Lines.size())+"_"+toString(_Lines[line].Bmps.size()));
+ pVB->setParent (this);
+ pVB->setParentPos (NULL);
+ pVB->setModulateGlobalColor(this->getModulateGlobalColor());
+ pVB->setTexture(texture);
+ return pVB;
+ }
+
+ // ----------------------------------------------------------------------------
+ void CGroupTree::addHierarchyBitmaps ()
+ {
+ if (_RootNode) _RootNode->updateLastVisibleSon();
+ for (uint nLayer = 0; nLayer < 256; nLayer++)
+ {
+ sint32 nCurRootLine = -1;
+ bool bCurRootLineLast = false;
+ bool bCurRootLineLastChild = false;
+ for (uint nLine = 0; nLine < _Lines.size(); nLine++)
+ if (nLayer <= _Lines[nLine].Depth)
+ {
+ // A Bitmap must be created
+ CViewBitmap *pVB = createViewBitmap(nLine, "t", "blank.tga");
+ pVB->setX (getHrcIconXStart(nLayer));
+ pVB->setY ((sint32)_Lines.size()*_BmpH - ((1+nLine)*_BmpH));
+
+ bool bAddBitmap = true;
+ bool bAddXExtendBitmap = false;
+ // Choose a bitmap
+ // Are we on the last depth in the line ?
+ if (_Lines[nLine].Depth == nLayer)
+ {
+ nCurRootLine = nLine;
+ if (_Lines[nLine].Node == _Lines[nCurRootLine].Node->Father->LastVisibleSon)
+ bCurRootLineLast = true;
+ else
+ bCurRootLineLast = false;
+ bCurRootLineLastChild = false;
+
+ // do i have some child shown?
+ bool haveSomeVisibleChild= false;
+ for(uint k=0;k<_Lines[nLine].Node->Children.size();k++)
+ {
+ if(_Lines[nLine].Node->Children[k]->Show)
+ {
+ haveSomeVisibleChild= true;
+ break;
+ }
+ }
+
+ // if so
+ if (haveSomeVisibleChild)
+ {
+ // Yes am I opened ?
+ if (_Lines[nLine].Node->Opened)
+ {
+ pVB->setTexture(_ArboOpenFirst);
+ }
+ else
+ {
+ // No I am closed
+ pVB->setTexture(_ArboCloseJustOne);
+ }
+ }
+ else
+ {
+ /*
+ // No child
+ // If there's a bitmap on this line , left an empty bitmap
+ if (!_Lines[nLine].Node->Bitmap.empty())
+ {
+ pVB->setTexture("blank.tga"); // create a transparent bitmap to have correct "child_resize_w"
+ pVB->setColor(CRGBA(0, 0, 0, 0));
+ }
+ else
+ {
+ pVB->setTexture(_ArboSonWithoutSon);
+ }
+ */
+ pVB->setTexture(_ArboSonWithoutSon);
+ }
+
+ // if not the root line, must add Extend Bitmap
+ if(nLayer)
+ bAddXExtendBitmap= true;
+ }
+ else
+ {
+ // No we are before the last depth, Do we have any current root ?
+ if (nCurRootLine != -1)
+ {
+ // Yes, do the current line is child of current root line ?
+ bool bFound = false;
+ for (uint i = 0; i < _Lines[nCurRootLine].Node->Children.size(); ++i)
+ if (_Lines[nLine].Node == _Lines[nCurRootLine].Node->Children[i])
+ {
+ bFound = true;
+ break;
+ }
+ if (bFound)
+ {
+ // is it the last child ?
+ bool lastSonDisplay= _Lines[nLine].Node == _Lines[nCurRootLine].Node->LastVisibleSon;
+
+
+ // Special for _NavigateOneBranch mode
+ if(_NavigateOneBranch)
+ {
+ // if node opened, then his brother are hid! => he behaves like a "last son"
+ if(_Lines[nLine].Node->Opened)
+ lastSonDisplay= true;
+ }
+
+ // if must display like last child
+ if (lastSonDisplay)
+ {
+ // Yes this is the last child
+ pVB->setTexture(_ArboSonLast);
+ bCurRootLineLastChild = true;
+ }
+ else
+ {
+ // No so we have brothers
+ pVB->setTexture(_ArboSon);
+ }
+ }
+ else
+ {
+ // Not found, display a line
+ pVB->setTexture(_ArboLevel);
+
+ // We have to not display a line if we have passed the last child of this root
+ // We never have to display a line also if we are in _NavigateOneBranch mode
+ if (bCurRootLineLastChild || _NavigateOneBranch)
+ bAddBitmap = false;
+ }
+ }
+ }
+
+ // Add the bitmap
+ if (bAddBitmap)
+ {
+ addView (pVB);
+ _Lines[nLine].Bmps.push_back(pVB);
+
+ // if must add the special extend bitmap, and if exist
+ if(bAddXExtendBitmap && !_ArboXExtend.empty())
+ {
+ CViewBitmap *pVB = createViewBitmap(nLine, "ext_t", _ArboXExtend);
+ pVB->setX (getHrcIconXStart(nLayer) - _XExtend);
+ pVB->setY ((sint32)_Lines.size()*_BmpH - ((1+nLine)*_BmpH));
+ addView (pVB);
+ _Lines[nLine].Bmps.push_back(pVB);
+ }
+ }
+ else
+ {
+ delete pVB;
+ }
+ }
+ }
+ // add additionnal bitmap for each line
+ for (uint nLine = 0; nLine < _Lines.size(); nLine++)
+ {
+ if (!_Lines[nLine].Node->Bitmap.empty())
+ {
+ CViewBitmap *pVB = createViewBitmap(nLine, "custom_bm", _Lines[nLine].Node->Bitmap);
+ pVB->setX (getHrcIconXStart(_Lines[nLine].Depth + 1));
+ pVB->setY ((sint32)_Lines.size()*_BmpH - ((1+nLine)*_BmpH));
+ _Lines[nLine].Bmps.push_back(pVB);
+ addView (pVB);
+ }
+ }
+ }
+
+ // ***************************************************************************
+ CGroupTree::SNode *CGroupTree::selectNodeByIdRecurse(SNode *pNode, const std::string &nodeId)
+ {
+ // select this node?
+ if(pNode!=_RootNode)
+ {
+ if(pNode->Id == nodeId)
+ return pNode;
+ }
+
+ // try with sons
+ for(uint i=0;iChildren.size();i++)
+ {
+ SNode *ret= selectNodeByIdRecurse(pNode->Children[i], nodeId);
+ if(ret)
+ return ret;
+ }
+
+ // not found => NULL
+ return NULL;
+ }
+
+ // ***************************************************************************
+ bool CGroupTree::selectNodeById(const std::string &nodeId, bool triggerAH)
+ {
+ SNode *selNode= NULL;
+
+ // Avoid infinite recurs
+ if(_AvoidSelectNodeByIdIR)
+ return true;
+
+ // first find in the hierarchy
+ selNode= selectNodeByIdRecurse(_RootNode, nodeId);
+
+ // if found
+ if(selNode)
+ {
+ // Opens the hierarchy
+ SNode *pFather = selNode->Father;
+ while(pFather != NULL)
+ {
+ pFather->Opened = true;
+ pFather = pFather->Father;
+ }
+
+ if (triggerAH)
+ {
+ // runAH may infinite recurs (HTML browse...)
+ _AvoidSelectNodeByIdIR= true;
+
+ // launch the action handler
+ CAHManager::getInstance()->runActionHandler ( selNode->AHName,
+ this,
+ selNode->AHParams );
+ }
+
+ // runAH may infinite recurs (HTML browse...)
+ _AvoidSelectNodeByIdIR= false;
+
+ // mark as selected
+ _SelectedNode = selNode;
+
+ forceRebuild();
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ // ***************************************************************************
+ class CHandlerTreeReset : public IActionHandler
+ {
+ public:
+ void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
+ {
+ CGroupTree *pTree = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(sParams));
+ if (pTree != NULL)
+ pTree->reset();
+ }
+ protected:
+ };
+ REGISTER_ACTION_HANDLER( CHandlerTreeReset, "tree_reset");
+
+ // ***************************************************************************
+ void CGroupTree::changeNavigateOneBranch(bool newState)
+ {
+ if(newState!=_NavigateOneBranch)
+ {
+ _NavigateOneBranch= newState;
+ // if new is true, then must reset both open state and selection
+ if(_NavigateOneBranch)
+ {
+ reset();
+ // reselect the first line
+ selectLine(0);
+ }
+ // else just rebuild
+ else
+ {
+ forceRebuild();
+ }
+ }
+ }
+
+ // ***************************************************************************
+ void CGroupTree::cancelNextSelectLine()
+ {
+ _CancelNextSelectLine = true;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::luaGetRootNode(CLuaState &ls)
+ {
+ CLuaIHM::checkArgCount(ls, "getRootNode", 0);
+ CLuaIHM::pushReflectableOnStack(ls, getRootNode());
+ return 1;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::luaSetRootNode(CLuaState &ls)
+ {
+ CLuaIHM::checkArgCount(ls, "setRootNode", 1);
+ if (ls.isNil())
+ {
+ setRootNode(NULL);
+ return 0;
+ }
+ setRootNode(SNode::luaGetNodeOnStack(ls, "CGroupTree::setRootNode"));
+ return 0;
+ }
+
+
+ // ***************************************************************************
+ int CGroupTree::luaForceRebuild(CLuaState &ls)
+ {
+ CLuaIHM::checkArgCount(ls, "forceRebuild", 0);
+ forceRebuild();
+ return 0;
+ }
+
+ // ***************************************************************************
+ CGroupTree::SNode *CGroupTree::SNode::luaGetNodeOnStack(CLuaState &ls, const char * /* funcName */)
+ {
+ SNode *node = dynamic_cast(CLuaIHM::getReflectableOnStack(ls, 1));
+ CLuaIHM::check(ls, node != NULL, "SNode expected");
+ return node;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaDetachChild(CLuaState &ls)
+ {
+ const char *funcName = "CGroupTree::SNode::luaDetachChild";
+ CLuaIHM::checkArgCount(ls, funcName, 1);
+ detachChild(luaGetNodeOnStack(ls, funcName));
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaSort(CLuaState &ls)
+ {
+ const char *funcName = "CGroupTree::SNode::luaSort";
+ CLuaIHM::checkArgCount(ls, funcName, 0);
+ sort();
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaSortByBitmap(CLuaState &ls)
+ {
+ const char *funcName = "CGroupTree::SNode::luaSort";
+ CLuaIHM::checkArgCount(ls, funcName, 0);
+ sortByBitmap();
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaDeleteChild(CLuaState &ls)
+ {
+ const char *funcName = "CGroupTree::SNode::luaDeleteChild";
+ CLuaIHM::checkArgCount(ls, funcName, 1);
+ deleteChild(luaGetNodeOnStack(ls, funcName));
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaAddChild(CLuaState &ls)
+ {
+ const char *funcName = "CGroupTree::SNode::luaAddChild";
+ CLuaIHM::checkArgCount(ls, funcName, 1);
+ addChild(luaGetNodeOnStack(ls, funcName));
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaAddChildSorted(CLuaState &ls)
+ {
+ const char *funcName = "CGroupTree::SNode::luaAddChildSorted";
+ CLuaIHM::checkArgCount(ls, funcName, 1);
+ addChildSorted(luaGetNodeOnStack(ls, funcName));
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaAddChildSortedByBitmap(CLuaState &ls)
+ {
+ const char *funcName = "CGroupTree::SNode::luaAddChildSortedByBitmap";
+ CLuaIHM::checkArgCount(ls, funcName, 1);
+ addChildSorted(luaGetNodeOnStack(ls, funcName));
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaGetNodeFromId(CLuaState &ls)
+ {
+ const char *funcName = "CGroupTree::SNode::luaGetNodeFromId";
+ CLuaIHM::checkArgCount(ls, funcName, 1);
+ CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING);
+ SNode *result = getNodeFromId(ls.toString(1));
+ if (result)
+ {
+ CLuaIHM::pushReflectableOnStack(ls, result);
+ }
+ else
+ {
+ ls.pushNil();
+ }
+ return 1;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaGetParentTree(CLuaState &ls)
+ {
+ CLuaIHM::checkArgCount(ls, "getParentTree", 0);
+ if (ParentTree)
+ {
+ CLuaIHM::pushUIOnStack(ls, ParentTree);
+ }
+ else
+ {
+ ls.pushNil();
+ }
+ return 1;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::luaGetNodeUnderMouse(CLuaState &ls)
+ {
+ CLuaIHM::checkArgCount(ls, "getNodeUnderMouse", 0);
+ SNode *node = getNodeUnderMouse();
+ if (node)
+ {
+ CLuaIHM::pushReflectableOnStack(ls, node);
+ }
+ else
+ {
+ ls.pushNil();
+ }
+ return 1;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::luaCancelNextSelectLine(CLuaState &ls)
+ {
+ CLuaIHM::checkArgCount(ls, "cancelNextSelectLine", 0);
+ cancelNextSelectLine();
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaAddChildFront(CLuaState &ls)
+ {
+ const char *funcName = "CGroupTree::SNode::luaAddChildFront";
+ CLuaIHM::checkArgCount(ls, funcName, 1);
+ addChild(luaGetNodeOnStack(ls, funcName));
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaIsChild(CLuaState &ls)
+ {
+ const char *funcName = "CGroupTree::SNode::luaIsChild";
+ CLuaIHM::checkArgCount(ls, funcName, 1);
+ ls.push(isChild(luaGetNodeOnStack(ls, funcName)));
+ return 1;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaAddChildAtIndex(CLuaState &ls)
+ {
+ const char *funcName = "CGroupTree::SNode::luaAddChildAtIndex";
+ CLuaIHM::checkArgCount(ls, funcName, 2);
+ CLuaIHM::checkArgType(ls, funcName, 2, LUA_TNUMBER);
+ addChildAtIndex(luaGetNodeOnStack(ls, funcName), (sint) ls.toNumber(2));
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaGetFather(CLuaState &ls)
+ {
+ const char *funcName = "CGroupTree::SNode::luaGetFather";
+ CLuaIHM::checkArgCount(ls, funcName, 0);
+ if(Father)
+ CLuaIHM::pushReflectableOnStack(ls, Father);
+ else
+ ls.pushNil();
+ return 1;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaGetNumChildren(CLuaState &ls)
+ {
+ const char *funcName = "CGroupTree::SNode::luaGetNumChildren";
+ CLuaIHM::checkArgCount(ls, funcName, 0);
+ ls.push((double) Children.size());
+ return 1;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaGetChild(CLuaState &ls)
+ {
+ const char *funcName = "CGroupTree::SNode::luaGetChild";
+ CLuaIHM::checkArgCount(ls, funcName, 1);
+ CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
+ //
+ sint index = (sint) ls.toNumber(1);
+ if (index < 0 || index >= (sint) Children.size())
+ {
+ std::string range = Children.empty() ? "" : toString("[0, %d]", Children.size() - 1);
+ CLuaIHM::fails(ls, "Bad index of tree node child : %d, range is %s", (int) index, range.c_str());
+ }
+ CLuaIHM::pushReflectableOnStack(ls, Children[index]);
+ return 1;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::SNode::luaCloseAll(CLuaState &ls)
+ {
+ const char *funcName = "CGroupTree::SNode::luaGetFather";
+ CLuaIHM::checkArgCount(ls, funcName, 0);
+ closeAll();
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::luaSelectNodeById(CLuaState &ls)
+ {
+ const char *funcName = "selectNodeById";
+ CLuaIHM::checkArgCount(ls, funcName, 2);
+ CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING);
+ CLuaIHM::checkArgType(ls, funcName, 2, LUA_TBOOLEAN);
+ selectNodeById(ls.toString(1), ls.toBoolean(2));
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::luaGetSelectedNodeId(CLuaState &ls)
+ {
+ CLuaIHM::checkArgCount(ls, "getSelectedNodeId", 0);
+ ls.push(getSelectedNodeId());
+ return 1;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::luaSelectLine(CLuaState &ls)
+ {
+ CLuaIHM::checkArgType(ls, "CGroupTree::selectLine", 1, LUA_TNUMBER);
+ CLuaIHM::checkArgType(ls, "CGroupTree::selectLine", 2, LUA_TBOOLEAN);
+ selectLine((uint) ls.toNumber(1), ls.toBoolean(2));
+ return 0;
+ }
+
+ // ***************************************************************************
+ int CGroupTree::luaUnselect(CLuaState &ls)
+ {
+ CLuaIHM::checkArgCount(ls, "unselect", 0);
+ unselect();
+ return 0;
+ }
+
+
+ // ***************************************************************************
+ uint CGroupTree::SLine::getNumAdditionnalBitmap() const
+ {
+ if (!Node) return 0;
+ return Node->getNumBitmap();
+ }
+
+}
+
+
diff --git a/code/ryzom/client/src/interface_v3/action_handler_game.cpp b/code/ryzom/client/src/interface_v3/action_handler_game.cpp
index 486f9b70f..d764ea90e 100644
--- a/code/ryzom/client/src/interface_v3/action_handler_game.cpp
+++ b/code/ryzom/client/src/interface_v3/action_handler_game.cpp
@@ -44,7 +44,7 @@
#include "guild_manager.h"
#include "../net_manager.h"
#include "interface_ddx.h"
-#include "group_tree.h"
+#include "nel/gui/group_tree.h"
#include "group_map.h"
#include "nel/gui/view_bitmap.h"
#include "action_handler_tools.h"
diff --git a/code/ryzom/client/src/interface_v3/action_handler_phrase.cpp b/code/ryzom/client/src/interface_v3/action_handler_phrase.cpp
index 8c60170b2..9a1466479 100644
--- a/code/ryzom/client/src/interface_v3/action_handler_phrase.cpp
+++ b/code/ryzom/client/src/interface_v3/action_handler_phrase.cpp
@@ -46,7 +46,7 @@
#include "../entities.h"
#include "macrocmd_manager.h"
#include "group_menu.h"
-#include "group_tree.h"
+#include "nel/gui/group_tree.h"
extern CSheetManager SheetMngr;
diff --git a/code/ryzom/client/src/interface_v3/encyclopedia_manager.cpp b/code/ryzom/client/src/interface_v3/encyclopedia_manager.cpp
index b3f2abad2..10f96d306 100644
--- a/code/ryzom/client/src/interface_v3/encyclopedia_manager.cpp
+++ b/code/ryzom/client/src/interface_v3/encyclopedia_manager.cpp
@@ -19,7 +19,7 @@
#include "stdpch.h"
#include "encyclopedia_manager.h"
#include "interface_manager.h"
-#include "group_tree.h"
+#include "nel/gui/group_tree.h"
#include "nel/gui/view_text_id.h"
#include "nel/gui/view_bitmap.h"
#include "action_handler_misc.h"
diff --git a/code/ryzom/client/src/interface_v3/group_html.h b/code/ryzom/client/src/interface_v3/group_html.h
index beca17afd..963c0f07f 100644
--- a/code/ryzom/client/src/interface_v3/group_html.h
+++ b/code/ryzom/client/src/interface_v3/group_html.h
@@ -26,7 +26,7 @@
#include "nel/misc/types_nl.h"
#include "nel/gui/interface_group.h"
#include "group_scrolltext.h"
-#include "group_tree.h"
+#include "nel/gui/group_tree.h"
#include "nel/gui/ctrl_button.h"
#include "group_table.h"
diff --git a/code/ryzom/client/src/interface_v3/group_phrase_skill_filter.h b/code/ryzom/client/src/interface_v3/group_phrase_skill_filter.h
index 8da02ee10..db18813f6 100644
--- a/code/ryzom/client/src/interface_v3/group_phrase_skill_filter.h
+++ b/code/ryzom/client/src/interface_v3/group_phrase_skill_filter.h
@@ -23,7 +23,7 @@
#include "game_share/brick_families.h"
#include "game_share/skills.h"
#include "nel/gui/interface_group.h"
-#include "group_tree.h"
+#include "nel/gui/group_tree.h"
// ***************************************************************************
diff --git a/code/ryzom/client/src/interface_v3/group_skills.h b/code/ryzom/client/src/interface_v3/group_skills.h
index a29af8a03..329734025 100644
--- a/code/ryzom/client/src/interface_v3/group_skills.h
+++ b/code/ryzom/client/src/interface_v3/group_skills.h
@@ -21,7 +21,7 @@
#include "nel/misc/types_nl.h"
#include "nel/gui/interface_group.h"
-#include "group_tree.h"
+#include "nel/gui/group_tree.h"
// ***************************************************************************
/** A Group that display all skills by category in a job
diff --git a/code/ryzom/client/src/interface_v3/group_tree.cpp b/code/ryzom/client/src/interface_v3/group_tree.cpp
deleted file mode 100644
index 735f28421..000000000
--- a/code/ryzom/client/src/interface_v3/group_tree.cpp
+++ /dev/null
@@ -1,1635 +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_tree.h"
-#include "nel/gui/interface_element.h"
-#include "nel/gui/view_bitmap.h"
-#include "nel/gui/view_text.h"
-#include "nel/gui/group_container_base.h"
-#include "nel/gui/action_handler.h"
-#include "nel/gui/lua_ihm.h"
-#include "nel/misc/i_xml.h"
-#include "nel/misc/i18n.h"
-#include "nel/misc/xml_auto_ptr.h"
-#include "nel/gui/widget_manager.h"
-#include "nel/gui/view_renderer.h"
-#include "nel/gui/view_pointer_base.h"
-
-using namespace std;
-using namespace NLMISC;
-
-// ----------------------------------------------------------------------------
-// SNode
-// ----------------------------------------------------------------------------
-// TestYoyo
-//uint SNodeCount= 0;
-// ----------------------------------------------------------------------------
-CGroupTree::SNode::SNode()
-{
- Opened = false;
- Father = NULL;
- FontSize = -1;
- YDecal = 0;
- DisplayText = true;
- Template = NULL;
- Show= true;
- NodeAddedCallback = NULL;
- Color = CRGBA::White;
- ParentTree = NULL;
- LastVisibleSon = NULL;
- // TestYoyo
- //nlinfo("SNode(): %8x, c%d", this, SNodeCount++);
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::SNode::updateLastVisibleSon()
-{
- LastVisibleSon = NULL;
- if (!Show || !Opened) return;
- for (sint sonIndex = (sint)Children.size() - 1; sonIndex >= 0; -- sonIndex)
- {
- if (Children[sonIndex]->Show)
- {
- LastVisibleSon = Children[sonIndex];
- break;
- }
- }
- for(uint k = 0; k < Children.size(); ++k)
- {
- Children[k]->updateLastVisibleSon();
- }
-}
-
-// ----------------------------------------------------------------------------
-CGroupTree::SNode::~SNode()
-{
- makeOrphan();
- // IMPORTANT : must delete in reverse order because "makeOrphan" is called when deleting sons, thus changing vector size...
- for (sint i = (sint)Children.size() - 1; i >= 0; --i)
- delete Children[i];
- Children.clear();
- // TestYoyo
- //nlinfo("~SNode(): %8x, c%d", this, --SNodeCount);
-}
-
-void CGroupTree::SNode::setParentTree(CGroupTree *parent)
-{
- ParentTree = parent;
- for (uint k = 0; k < Children.size(); ++k)
- {
- Children[k]->setParentTree(parent);
- }
-}
-
-void CGroupTree::SNode::setFather(SNode *father)
-{
- Father = father;
- setParentTree(father ? father->ParentTree : NULL);
-}
-
-
-CGroupTree::SNode *CGroupTree::SNode::getNodeFromId(const std::string &id)
-{
- if (Id == id) return this;
- // breadth first
- for (uint k = 0; k < Children.size(); ++k)
- {
- if (Children[k]->Id == id)
- {
- return Children[k];
- }
- }
- for (uint k = 0; k < Children.size(); ++k)
- {
- SNode *found = Children[k]->getNodeFromId(id);
- if (found) return found;
- }
- return NULL;
-}
-
-
-void CGroupTree::SNode::makeOrphan()
-{
- if (ParentTree)
- {
- ParentTree->forceRebuild();
- setParentTree(NULL);
- }
- //
- if (Template != NULL)
- {
- if (Template->getParent())
- {
- // don't delete because may want to keep it. NB: deleted by smartptr at dtor
- Template->getParent()->delGroup(Template, true);
- }
- }
- //
- if (Father)
- {
- Father->detachChild(this);
- Father = NULL;
- }
-}
-
-// ----------------------------------------------------------------------------
-struct CNodeSorter
-{
- bool operator()(const CGroupTree::SNode *lhs, const CGroupTree::SNode *rhs) const
- {
- return lhs->Text < rhs->Text;
- }
-};
-
-// ----------------------------------------------------------------------------
-void CGroupTree::SNode::sort()
-{
- std::sort(Children.begin(), Children.end(), CNodeSorter());
- for(uint k = 0; k < Children.size(); ++k)
- {
- Children[k]->sort();
- }
-}
-
-
-// ----------------------------------------------------------------------------
-struct CNodeSorterByBitmap
-{
- bool operator()(const CGroupTree::SNode *lhs, const CGroupTree::SNode *rhs) const
- {
- if (lhs->Bitmap != rhs->Bitmap) return lhs->Bitmap < rhs->Bitmap;
- return lhs->Text < rhs->Text;
- }
-};
-
-// ----------------------------------------------------------------------------
-void CGroupTree::SNode::sortByBitmap()
-{
- std::sort(Children.begin(), Children.end(), CNodeSorterByBitmap());
- for(uint k = 0; k < Children.size(); ++k)
- {
- Children[k]->sortByBitmap();
- }
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::SNode::addChild (SNode *pNode)
-{
- if(!pNode) return;
- pNode->makeOrphan();
- Children.push_back(pNode);
- pNode->setFather(this);
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::SNode::addChildSorted(SNode *pNode)
-{
- if (!pNode) return;
- pNode->makeOrphan();
- std::vector::iterator it = std::lower_bound(Children.begin(), Children.end(), pNode, CNodeSorter());
- Children.insert(it, pNode);
- pNode->setFather(this);
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::SNode::addChildSortedByBitmap(SNode *pNode)
-{
- if (!pNode) return;
- pNode->makeOrphan();
- std::vector::iterator it = std::lower_bound(Children.begin(), Children.end(), pNode, CNodeSorterByBitmap());
- Children.insert(it, pNode);
- pNode->setFather(this);
-}
-
-// ----------------------------------------------------------------------------
-bool CGroupTree::SNode::isChild(SNode *pNode) const
-{
- return std::find(Children.begin(), Children.end(), pNode) != Children.end();
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::SNode::detachChild(SNode *pNode)
-{
- nlassert(pNode);
- nlassert(isChild(pNode));
- Children.erase(std::remove(Children.begin(), Children.end(), pNode), Children.end());
- pNode->setFather(NULL);
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::SNode::deleteChild(SNode *pNode)
-{
- delete pNode;
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::SNode::addChildFront (SNode *pNode)
-{
- if(!pNode) return;
- pNode->makeOrphan();
- Children.insert(Children.begin(), pNode);
- pNode->setFather(this);
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::SNode::addChildAtIndex(SNode *pNode, sint index)
-{
- if(!pNode) return;
- if (index < 0 || index > (sint) Children.size())
- {
- nlwarning(" bad index %d (%d elements in the vector)", index, Children.size());
- return;
- }
- pNode->makeOrphan();
- if (pNode->Father)
- {
- pNode->Father->detachChild(pNode);
- }
- Children.insert(Children.begin() + index, pNode);
- pNode->setFather(this);
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::SNode::closeAll()
-{
- Opened = false;
- for (uint i = 0; i < Children.size(); ++i)
- Children[i]->closeAll();
-}
-
-// ----------------------------------------------------------------------------
-bool CGroupTree::SNode::parse (xmlNodePtr cur, CGroupTree * parentGroup)
-{
- if (stricmp((char*)cur->name, "node") == 0)
- {
- CXMLAutoPtr id((const char*) xmlGetProp (cur, (xmlChar*)"id"));
- if (id)
- Id = (const char*)id;
- else
- Id = toString(parentGroup->getIdNumber());
-
- CXMLAutoPtr name((const char*) xmlGetProp (cur, (xmlChar*)"name"));
-
- if (name)
- {
- const char *ptrName = (const char*)name;
- Text = ucstring(ptrName);
- if ((strlen(ptrName)>2) && (ptrName[0] == 'u') && (ptrName[1] == 'i'))
- Text = CI18N::get (ptrName);
- }
-
- CXMLAutoPtr color((const char*) xmlGetProp (cur, (xmlChar*)"color"));
- if (color)
- {
- Color = convertColor(color);
- }
-
- CXMLAutoPtr open((const char*) xmlGetProp (cur, (xmlChar*)"opened"));
- if (open) Opened = convertBool(open);
-
- CXMLAutoPtr show((const char*) xmlGetProp (cur, (xmlChar*)"show"));
- if (open) Show = convertBool(show);
-
- CXMLAutoPtr ah((const char*) xmlGetProp (cur, (xmlChar*)"handler"));
- if (ah) AHName = (const char*)ah;
- CXMLAutoPtr cond((const char*) xmlGetProp (cur, (xmlChar*)"cond"));
- if (cond) AHCond = (const char*)cond;
- CXMLAutoPtr params((const char*) xmlGetProp (cur, (xmlChar*)"params"));
- if (params) AHParams = (const char*)params;
-
- CXMLAutoPtr ahRight((const char*) xmlGetProp (cur, (xmlChar*)"handler_right"));
- if (ahRight) AHNameRight = (const char*)ahRight;
- CXMLAutoPtr paramsRight((const char*) xmlGetProp (cur, (xmlChar*)"params_right"));
- if (paramsRight) AHParamsRight = (const char*)paramsRight;
-
- CXMLAutoPtr bitmap((const char*) xmlGetProp (cur, (xmlChar*)"bitmap"));
- if (bitmap) Bitmap = (const char*)bitmap;
-
- FontSize = parentGroup->getFontSize();
- CXMLAutoPtr fs((const char*) xmlGetProp (cur, (xmlChar*)"fontsize"));
- if (fs) fromString((const char*)fs, FontSize);
-
- YDecal = parentGroup->getYDecal();
- CXMLAutoPtr yDecalPtr((const char*) xmlGetProp (cur, (xmlChar*)"y_decal"));
- if (yDecalPtr) fromString((const char*)yDecalPtr, YDecal);
-
-
- xmlNodePtr child = cur->children;
-
- while (child != NULL)
- {
- SNode *pNode = new SNode;
- pNode->parse (child, parentGroup);
- addChild(pNode);
- child = child->next;
- }
- }
-
- return true;
-}
-
-// ----------------------------------------------------------------------------
-// CGroupTree
-// ----------------------------------------------------------------------------
-
-NLMISC_REGISTER_OBJECT(CViewBase, CGroupTree, std::string, "tree");
-
-// ----------------------------------------------------------------------------
-CGroupTree::CGroupTree(const TCtorParam ¶m)
-:CInterfaceGroup(param)
-{
- _IdGenerator = 0;
- _XExtend= 0;
- _BmpW = 14;
- _BmpH = 14;
- _FontSize = 12;
- _YDecal = 0;
- _MustRebuild = true;
- _OverColor = CRGBA(255, 255, 255, 128);
- _OverColorBack = CRGBA(64, 64, 64, 255);
- _SelectedNode = NULL;
- _SelectedLine = -1;
- _SelectedColor = CRGBA(255, 128, 128, 128);
- _RootNode = NULL;
- _OverLine = -1;
- _SelectAncestorOnClose= false;
- _NavigateOneBranch= false;
-
- _ArboOpenFirst= "arbo_open_first.tga";
- _ArboCloseJustOne= "arbo_close_just_one.tga";
- _ArboSonWithoutSon= "arbo_son_without_son.tga";
- _ArboSonLast= "arbo_son_last.tga";
- _ArboSon= "arbo_son.tga";
- _ArboLevel= "arbo_level.tga";
-
- _RectangleOutlineMode= false;
- _RectangleX= 0;
- _RectangleY= 0;
- _RectangleW= 10;
- _RectangleH= 10;
- _RectangleDeltaRL= 0;
-
- _AvoidSelectNodeByIdIR= false;
-}
-
-// ----------------------------------------------------------------------------
-CGroupTree::~CGroupTree()
-{
- removeAll();
- if (_RootNode != NULL) delete _RootNode;
-}
-
-// ----------------------------------------------------------------------------
-bool CGroupTree::parse (xmlNodePtr cur, CInterfaceGroup * parentGroup)
-{
- if (!CInterfaceGroup::parse(cur, parentGroup))
- return false;
-
- CXMLAutoPtr ptr;
-
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"col_over");
- if (ptr) _OverColor = convertColor(ptr);
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"col_select");
- if (ptr) _SelectedColor = convertColor(ptr);
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"col_over_back");
- if (ptr) _OverColorBack = convertColor(ptr);
-
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"fontsize");
- if (ptr) fromString((const char*)ptr, _FontSize);
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"select_ancestor_on_close");
- if (ptr) _SelectAncestorOnClose = convertBool(ptr);
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"navigate_one_branch");
- if (ptr) _NavigateOneBranch = convertBool(ptr);
-
- // read optional arbo bmps
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"arbo_open_first");
- if (ptr) _ArboOpenFirst= (const char*)ptr;
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"arbo_close_just_one");
- if (ptr) _ArboCloseJustOne= (const char*)ptr;
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"arbo_son_without_son");
- if (ptr) _ArboSonWithoutSon= (const char*)ptr;
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"arbo_son_last");
- if (ptr) _ArboSonLast= (const char*)ptr;
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"arbo_son");
- if (ptr) _ArboSon= (const char*)ptr;
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"arbo_level");
- if (ptr) _ArboLevel= (const char*)ptr;
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"arbo_x_extend");
- if (ptr) _ArboXExtend= (const char*)ptr;
-
- // Rectangle selection style
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"rectangle_outline");
- if (ptr) _RectangleOutlineMode= convertBool(ptr);
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"rectangle_x");
- if (ptr) fromString((const char*)ptr, _RectangleX);
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"rectangle_y");
- if (ptr) fromString((const char*)ptr, _RectangleY);
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"rectangle_w");
- if (ptr) fromString((const char*)ptr, _RectangleW);
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"rectangle_h");
- if (ptr) fromString((const char*)ptr, _RectangleH);
- ptr = (char*) xmlGetProp (cur, (xmlChar*)"rectangle_drl");
- if (ptr) fromString((const char*)ptr, _RectangleDeltaRL);
-
-
-
- _RootNode = new SNode;
-// bool ok = true;
- cur = cur->children;
- while (cur)
- {
- // Check that this is a camera node
- if ( stricmp((char*)cur->name, "node") == 0 )
- {
- SNode *pNode = new SNode;
- if (!pNode->parse(cur, this))
- {
- delete pNode;
- nlwarning("cannot parse node");
- }
- else
- {
- _RootNode->addChild(pNode);
- }
- }
- cur = cur->next;
- }
- _RootNode->Opened = true;
- _ResizeFromChildW = _ResizeFromChildH = true;
-
- CViewRenderer &rVR = *CViewRenderer::getInstance();
- sint32 id = rVR.getTextureIdFromName(_ArboOpenFirst);
- if (id != -1)
- rVR.getTextureSizeFromId(id, _BmpW, _BmpH);
- sint32 dummy;
- id = rVR.getTextureIdFromName(_ArboXExtend);
- if (id != -1)
- rVR.getTextureSizeFromId(id, _XExtend, dummy);
- else
- // if not found, reset, to avoid errors
- _ArboXExtend= "";
-
-
- return true;
-}
-
-// ----------------------------------------------------------------------------
-sint32 CGroupTree::getHrcIconXStart(sint32 depth)
-{
- return depth*(_BmpW+_XExtend);
-}
-
-// ----------------------------------------------------------------------------
-sint32 CGroupTree::getHrcIconXEnd(sint32 depth)
-{
- return depth*(_BmpW+_XExtend) + _BmpW;
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::checkCoords()
-{
- CInterfaceGroup::checkCoords();
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::updateCoords()
-{
- if (_MustRebuild)
- rebuild();
- CInterfaceGroup::updateCoords();
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::drawSelection(sint x, sint y, sint w, CRGBA col)
-{
- CViewRenderer &rVR = *CViewRenderer::getInstance();
-
- if(!_RectangleOutlineMode)
- {
- rVR.drawRotFlipBitmap (_RenderLayer, _XReal+_OffsetX+x, _YReal+_OffsetY+y,
- w, _BmpH, 0, false, rVR.getBlankTextureId(),
- col );
- }
- else
- {
- // draw the outline
- x+= _XReal+_OffsetX+_RectangleX;
- y+= _YReal+_OffsetY+_RectangleY;
- w= _RectangleW;
- sint32 h= _RectangleH;
- sint32 rl= _RenderLayer + _RectangleDeltaRL;
-
- rVR.drawRotFlipBitmap (rl, x, y, 1, h, 0, false, rVR.getBlankTextureId(), col );
- rVR.drawRotFlipBitmap (rl, x+w-1, y, 1, h, 0, false, rVR.getBlankTextureId(), col );
- rVR.drawRotFlipBitmap (rl, x, y, w, 1, 0, false, rVR.getBlankTextureId(), col );
- rVR.drawRotFlipBitmap (rl, x, y+h-1, w, 1, 0, false, rVR.getBlankTextureId(), col );
- }
-}
-
-// ----------------------------------------------------------------------------
-CGroupTree::SNode *CGroupTree::getNodeUnderMouse() const
-{
- if (_OverLine == -1) return NULL;
- return _Lines[_OverLine].Node;
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::draw()
-{
- // get the clip area
- sint32 clipx, clipy, clipw, cliph;
- getClip(clipx, clipy, clipw, cliph);
-
- // change the over
- bool bDisplayOver = true;
-
- if (!CWidgetManager::getInstance()->isMouseHandlingEnabled())
- {
- bDisplayOver = false;
- }
- else
- if (CWidgetManager::getInstance()->getModalWindow() == NULL)
- {
- sint32 x = CWidgetManager::getInstance()->getPointer()->getX();
- sint32 y = CWidgetManager::getInstance()->getPointer()->getY();
-
- CInterfaceGroup *pIG = CWidgetManager::getInstance()->getWindowUnder(x, y);
- CInterfaceGroup *pParent = this;
- bool bFound = false;
- while (pParent != NULL)
- {
- if (pParent == pIG)
- {
- bFound = true;
- break;
- }
- pParent = pParent->getParent();
- }
-
- // if the mouse is not in the clipped area
- if ((x < clipx) ||
- (x > (clipx + clipw)) ||
- (y < clipy) ||
- (y > (clipy + cliph)) || !bFound)
- {
- _OverLine = -1;
- }
- else
- {
- x = x - _OffsetX;
- y = y - _OffsetY;
- for (sint32 i = 0; i < (sint32)_Lines.size(); ++i)
- {
- if ((y >= (_YReal+(sint32)(_Lines.size()-i-1)*_BmpH)) &&
- (y < (_YReal+(sint32)(_Lines.size()-i)*_BmpH)))
- {
- _OverLine = i;
- }
- }
- if (_OverLine != -1)
- {
- if (x < _XReal + getHrcIconXEnd(_Lines[_OverLine].Depth))
- bDisplayOver = false;
- }
- }
- }
-
- // some over to display?
- if ((_OverLine != -1) && bDisplayOver)
- {
- // Find the first container
- CInterfaceGroup *pIG = _Parent;
- CGroupContainerBase *pGC = dynamic_cast(pIG);
- while (pIG != NULL)
- {
- pIG = pIG->getParent();
- if (pIG == NULL) break;
- if (dynamic_cast(pIG) != NULL)
- pGC = dynamic_cast(pIG);
- }
-
- // avoid if window grayed
- if (pGC != NULL)
- {
- if (pGC->isGrayed())
- bDisplayOver = false;
- }
-
- // Has to display the over?
- if (bDisplayOver)
- {
- // !NULL if the text over must displayed across all windows
- CViewText *viewTextExtend= NULL;
-
- // If the line is a simple Text line (not template)
- if(_Lines[_OverLine].Node && _Lines[_OverLine].Node->DisplayText)
- {
- // Get the view text
- viewTextExtend= safe_cast(_Lines[_OverLine].TextOrTemplate);
- // If this viewText is not too big, no need
- if(viewTextExtend->getXReal() + viewTextExtend->getWReal() <= (clipx+clipw) )
- viewTextExtend= NULL;
- }
-
- // draw simple over
- if(!viewTextExtend)
- {
- CRGBA col = _OverColor;
- if(getModulateGlobalColor())
- {
- col.modulateFromColor (_OverColor, CWidgetManager::getInstance()->getGlobalColorForContent());
- }
- else
- {
- col= _OverColor;
- col.A = (uint8)(((sint32)col.A*((sint32)CWidgetManager::getInstance()->getGlobalColorForContent().A+1))>>8);
- }
-
- drawSelection( getHrcIconXEnd(_Lines[_OverLine].Depth + _Lines[_OverLine].getNumAdditionnalBitmap()), ((sint)_Lines.size()-_OverLine-1)*_BmpH,
- _WReal-getHrcIconXEnd(_Lines[_OverLine].Depth + _Lines[_OverLine].getNumAdditionnalBitmap()), col);
- }
- // Draw extended over
- else
- {
- CRGBA col = _OverColorBack;
- // must add the selection color
- if(_SelectedLine == _OverLine)
- {
- // simulate alpha blend of the selection bitmap
- CRGBA sel= _SelectedColor;
- sel.A= (uint8)((sel.A*((sint32)CWidgetManager::getInstance()->getGlobalColorForContent().A+1))>>8);
- col.blendFromuiRGBOnly(col, sel, sel.A);
- }
-
- // will be drawn over all the interface
- CWidgetManager::getInstance()->setOverExtendViewText(viewTextExtend, col);
- }
- }
- }
-
- // some selection to display
- if (_SelectedLine != -1)
- {
- CRGBA col = _SelectedColor;
- if(getModulateGlobalColor())
- {
- col.modulateFromColor (_SelectedColor, CWidgetManager::getInstance()->getGlobalColorForContent());
- }
- else
- {
- col= _SelectedColor;
- col.A = (uint8)(((sint32)col.A*((sint32)CWidgetManager::getInstance()->getGlobalColorForContent().A+1))>>8);
- }
-
- drawSelection( getHrcIconXEnd(_Lines[_SelectedLine].Depth + _Lines[_SelectedLine].getNumAdditionnalBitmap()), ((sint)_Lines.size()-_SelectedLine-1)*_BmpH,
- _WReal-getHrcIconXEnd(_Lines[_SelectedLine].Depth + _Lines[_SelectedLine].getNumAdditionnalBitmap()), col );
- }
-
- CInterfaceGroup::draw();
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::selectLine(uint line, bool runAH /*= true*/)
-{
- if(line>=_Lines.size())
- return;
-
- if (!_Lines[line].Node)
- {
- // just deleted : must wait next draw to know the new line under mouse
- return;
- }
- if (!_Lines[line].Node->AHName.empty() && runAH)
- {
- _CancelNextSelectLine = false;
- /*
- CAHManager::getInstance()->runActionHandler ( _Lines[line].Node->AHName,
- this,
- _Lines[line].Node->AHParams );
- */
- if (!_CancelNextSelectLine)
- {
- _SelectedLine = line;
- _SelectedNode = _Lines[line].Node;
- }
- CAHManager::getInstance()->runActionHandler ( _Lines[line].Node->AHName,
- this,
- _Lines[line].Node->AHParams );
- _CancelNextSelectLine = false;
- }
-}
-
-// ----------------------------------------------------------------------------
-bool CGroupTree::rightButton(uint line)
-{
- if(line>=_Lines.size())
- return false;
-
- if (!_Lines[_OverLine].Node || _Lines[_OverLine].Node->AHNameRight.empty())
- return false;
-
- if (line != (uint) _SelectedLine) selectLine(line, false);
-
- CAHManager::getInstance()->runActionHandler ( _Lines[line].Node->AHNameRight,
- this,
- _Lines[line].Node->AHParamsRight );
- return true;
-}
-
-
-
-// ----------------------------------------------------------------------------
-const std::string &CGroupTree::getSelectedNodeId() const
-{
- if(_SelectedLine>=0 && _SelectedLine<(sint)_Lines.size() && _Lines[_SelectedLine].Node)
- {
- return _Lines[_SelectedLine].Node->Id;
- }
- else
- {
- static string empty;
- return empty;
- }
-}
-
-// ----------------------------------------------------------------------------
-bool CGroupTree::handleEvent (const NLGUI::CEventDescriptor& event)
-{
- if (!_Active) return false;
- if (CInterfaceGroup::handleEvent(event)) return true;
- // The line must be over (pre-selected)
- if (event.getType() == NLGUI::CEventDescriptor::mouse && _OverLine>=0)
- {
- const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
-
- if (!isIn(eventDesc.getX(), eventDesc.getY()))
- return false;
-
- sint32 x = eventDesc.getX() - _OffsetX;
-// sint32 y = eventDesc.getY() - _OffsetY;
- bool bText = false;
- if (x >= (_XReal+getHrcIconXEnd(_Lines[_OverLine].Depth + _Lines[_OverLine].getNumAdditionnalBitmap())))
- bText = true;
- bool bIcon = false;
- if ((x > (_XReal+getHrcIconXStart(_Lines[_OverLine].Depth)-_XExtend)) &&
- (x < (_XReal+getHrcIconXEnd(_Lines[_OverLine].Depth + _Lines[_OverLine].getNumAdditionnalBitmap()))))
- bIcon = true;
-
- if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown)
- {
- if (bText)
- {
- return rightButton(_OverLine != -1 ? _OverLine : _SelectedLine);
- }
- }
-
- if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown)
- {
- // line selection
- if (bText)
- {
- selectLine(_OverLine);
- }
- // close of node
- if (bIcon)
- {
- SNode *changedNode= _Lines[_OverLine].Node;
-
- if (changedNode)
- {
- // if "SelectAncestorOnClose" feature wanted, if it was opened before, and if some node selected
- if(_SelectAncestorOnClose && changedNode->Opened && _SelectedNode)
- {
- // check that the selected node is a son of the closing node
- SNode *parent= _SelectedNode->Father;
- while(parent)
- {
- if(parent==changedNode)
- {
- // Then change selection to this parent first
- selectLine(_OverLine);
- break;
- }
- parent= parent->Father;
- }
- }
-
- // standard hrc
- if(!_NavigateOneBranch)
- {
- // open/close the node
- changedNode->Opened = !changedNode->Opened;
- }
- // else must close all necessary nodes.
- else
- {
- if(changedNode->Opened)
- changedNode->closeAll();
- else
- {
- // must closeAll all his brothers first.
- if(changedNode->Father)
- {
- changedNode->Father->closeAll();
- changedNode->Father->Opened= true;
- }
- changedNode->Opened= true;
- }
- }
-
- CAHManager::getInstance()->runActionHandler(changedNode->AHNameClose, this, changedNode->AHParamsClose);
- }
- forceRebuild();
- }
- return true;
- }
- }
- return false;
-}
-
-
-// ----------------------------------------------------------------------------
-void CGroupTree::unselect()
-{
- _SelectedLine = -1;
- _SelectedNode = NULL;
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::reset()
-{
- unselect();
- if (_RootNode)
- {
- _RootNode->closeAll();
- _RootNode->Opened = true;
- }
- forceRebuild();
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::forceRebuild()
-{
- _MustRebuild = true;
- invalidateCoords();
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::rebuild()
-{
- // Remove all
- removeAll();
-
- if (_RootNode)
- _RootNode->Opened = true;
-
- // Rebuild all depending on the logic
- if(_RootNode)
- addTextLine (0, _RootNode);
-
- // Reformating
- sint32 sizeH = (sint32)_Lines.size()*_BmpH;
- for (uint i = 0; i < _Lines.size(); ++i)
- _Lines[i].TextOrTemplate->setY (_Lines[i].Node->YDecal + sizeH - ((1+_Lines[i].TextOrTemplate->getY())*_BmpH));
- // Add the hierarchy bitmaps
- addHierarchyBitmaps();
- // Find if we can display selection
- if (_SelectedNode != NULL)
- {
- _SelectedLine = -1;
- for (uint i = 0; i < _Lines.size(); ++i)
- if (_Lines[i].Node == _SelectedNode)
- {
- _SelectedLine = i;
- break;
- }
- }
-
- // Ok no more need to rebuild all this
- _MustRebuild = false;
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::setRootNode (SNode *pNewRoot)
-{
- // reset selection
- _SelectedLine= -1;
- _SelectedNode= NULL;
-
- CRefPtr refPtrNewRoot = pNewRoot;
- // clear old
- delete _RootNode;
-
- // If the node was deleted
- if (pNewRoot && !refPtrNewRoot)
- {
- // NB nico : if anyone need that a day, please feel free to modify ...
- nlwarning("Trying to set a node that is part of the tree as root node (not supported yet ...)");
- }
-
- // set new (may be NULL)
- _RootNode = pNewRoot;
- if(pNewRoot)
- pNewRoot->setParentTree(this);
- rebuild();
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::removeAll()
-{
- // Remove (but not delete) the groups template if any
- for(uint i=0;i<_Lines.size();i++)
- {
- if (_Lines[i].Node)
- {
- if(_Lines[i].Node->Template)
- {
- delGroup(_Lines[i].Node->Template, true);
- }
- }
- }
-
- // Clear all lines, but don't delete templates
- _Lines.clear();
-
- // Delete all BmpViews and/or all text views
- clearViews();
-}
-
-
-
-// ----------------------------------------------------------------------------
-void CGroupTree::addTextLine (uint8 nDepth, CGroupTree::SNode *pNode)
-{
- pNode->setParentTree(this);
- if (nDepth > 0)
- {
- SLine line;
- line.Depth = nDepth-1;
- line.Node = pNode;
- if (pNode->DisplayText)
- {
- CViewText *pVT = new CViewText(TCtorParam());
- line.TextOrTemplate = pVT;
- pVT->setId("t"+toString(_Lines.size()));
- pVT->setText(pNode->Text);
- pVT->setColor(pNode->Color);
- if(pNode->FontSize==-1)
- pVT->setFontSize(_FontSize);
- else
- pVT->setFontSize(pNode->FontSize);
- }
- else
- {
- line.TextOrTemplate = pNode->Template;
- }
- line.TextOrTemplate->setPosRef (Hotspot_BL);
- line.TextOrTemplate->setParentPosRef (Hotspot_BL);
- line.TextOrTemplate->setParent (this);
- line.TextOrTemplate->setParentPos (NULL);
- line.TextOrTemplate->setX (getHrcIconXEnd(nDepth-1 + line.getNumAdditionnalBitmap()));
- line.TextOrTemplate->setY ((sint32)_Lines.size());
- line.TextOrTemplate->setModulateGlobalColor(this->getModulateGlobalColor());
- if (pNode->DisplayText)
- addView (line.TextOrTemplate);
- else
- addGroup ((CInterfaceGroup*)line.TextOrTemplate);
- if (pNode->NodeAddedCallback)
- {
- pNode->NodeAddedCallback->nodeAdded(pNode, line.TextOrTemplate);
- }
- _Lines.push_back(line);
- }
-
- // recurs
- if (pNode->Opened)
- {
- // **** standard hierarchy display, or if root
- if(!_NavigateOneBranch || nDepth==0)
- {
- for (uint i = 0; i < pNode->Children.size(); ++i)
- {
- // add the branch only if want to show it
- if(pNode->Children[i]->Show)
- addTextLine (nDepth+1, pNode->Children[i]);
- }
- }
- // **** display only the branch navigated
- else
- {
- // find the first child opened
- sint childOpen= -1;
- for (uint i = 0; i < pNode->Children.size(); ++i)
- {
- // don't take hid ones
- if(pNode->Children[i]->Show && pNode->Children[i]->Opened)
- {
- childOpen= i;
- break;
- }
- }
-
- // If some chidl opened, add just this line
- if(childOpen>=0)
- {
- addTextLine (nDepth+1, pNode->Children[childOpen]);
- }
- // else add all closed, but showable lines
- else
- {
- for (uint i = 0; i < pNode->Children.size(); ++i)
- {
- if(pNode->Children[i]->Show)
- addTextLine (nDepth+1, pNode->Children[i]);
- }
- }
- }
- }
-}
-
-// ----------------------------------------------------------------------------
-CViewBitmap *CGroupTree::createViewBitmap(uint line, const std::string &idPrefix, const std::string &texture)
-{
- CViewBitmap *pVB = new CViewBitmap(TCtorParam());
- pVB->setId(idPrefix+toString(_Lines.size())+"_"+toString(_Lines[line].Bmps.size()));
- pVB->setParent (this);
- pVB->setParentPos (NULL);
- pVB->setModulateGlobalColor(this->getModulateGlobalColor());
- pVB->setTexture(texture);
- return pVB;
-}
-
-// ----------------------------------------------------------------------------
-void CGroupTree::addHierarchyBitmaps ()
-{
- if (_RootNode) _RootNode->updateLastVisibleSon();
- for (uint nLayer = 0; nLayer < 256; nLayer++)
- {
- sint32 nCurRootLine = -1;
- bool bCurRootLineLast = false;
- bool bCurRootLineLastChild = false;
- for (uint nLine = 0; nLine < _Lines.size(); nLine++)
- if (nLayer <= _Lines[nLine].Depth)
- {
- // A Bitmap must be created
- CViewBitmap *pVB = createViewBitmap(nLine, "t", "blank.tga");
- pVB->setX (getHrcIconXStart(nLayer));
- pVB->setY ((sint32)_Lines.size()*_BmpH - ((1+nLine)*_BmpH));
-
- bool bAddBitmap = true;
- bool bAddXExtendBitmap = false;
- // Choose a bitmap
- // Are we on the last depth in the line ?
- if (_Lines[nLine].Depth == nLayer)
- {
- nCurRootLine = nLine;
- if (_Lines[nLine].Node == _Lines[nCurRootLine].Node->Father->LastVisibleSon)
- bCurRootLineLast = true;
- else
- bCurRootLineLast = false;
- bCurRootLineLastChild = false;
-
- // do i have some child shown?
- bool haveSomeVisibleChild= false;
- for(uint k=0;k<_Lines[nLine].Node->Children.size();k++)
- {
- if(_Lines[nLine].Node->Children[k]->Show)
- {
- haveSomeVisibleChild= true;
- break;
- }
- }
-
- // if so
- if (haveSomeVisibleChild)
- {
- // Yes am I opened ?
- if (_Lines[nLine].Node->Opened)
- {
- pVB->setTexture(_ArboOpenFirst);
- }
- else
- {
- // No I am closed
- pVB->setTexture(_ArboCloseJustOne);
- }
- }
- else
- {
- /*
- // No child
- // If there's a bitmap on this line , left an empty bitmap
- if (!_Lines[nLine].Node->Bitmap.empty())
- {
- pVB->setTexture("blank.tga"); // create a transparent bitmap to have correct "child_resize_w"
- pVB->setColor(CRGBA(0, 0, 0, 0));
- }
- else
- {
- pVB->setTexture(_ArboSonWithoutSon);
- }
- */
- pVB->setTexture(_ArboSonWithoutSon);
- }
-
- // if not the root line, must add Extend Bitmap
- if(nLayer)
- bAddXExtendBitmap= true;
- }
- else
- {
- // No we are before the last depth, Do we have any current root ?
- if (nCurRootLine != -1)
- {
- // Yes, do the current line is child of current root line ?
- bool bFound = false;
- for (uint i = 0; i < _Lines[nCurRootLine].Node->Children.size(); ++i)
- if (_Lines[nLine].Node == _Lines[nCurRootLine].Node->Children[i])
- {
- bFound = true;
- break;
- }
- if (bFound)
- {
- // is it the last child ?
- bool lastSonDisplay= _Lines[nLine].Node == _Lines[nCurRootLine].Node->LastVisibleSon;
-
-
- // Special for _NavigateOneBranch mode
- if(_NavigateOneBranch)
- {
- // if node opened, then his brother are hid! => he behaves like a "last son"
- if(_Lines[nLine].Node->Opened)
- lastSonDisplay= true;
- }
-
- // if must display like last child
- if (lastSonDisplay)
- {
- // Yes this is the last child
- pVB->setTexture(_ArboSonLast);
- bCurRootLineLastChild = true;
- }
- else
- {
- // No so we have brothers
- pVB->setTexture(_ArboSon);
- }
- }
- else
- {
- // Not found, display a line
- pVB->setTexture(_ArboLevel);
-
- // We have to not display a line if we have passed the last child of this root
- // We never have to display a line also if we are in _NavigateOneBranch mode
- if (bCurRootLineLastChild || _NavigateOneBranch)
- bAddBitmap = false;
- }
- }
- }
-
- // Add the bitmap
- if (bAddBitmap)
- {
- addView (pVB);
- _Lines[nLine].Bmps.push_back(pVB);
-
- // if must add the special extend bitmap, and if exist
- if(bAddXExtendBitmap && !_ArboXExtend.empty())
- {
- CViewBitmap *pVB = createViewBitmap(nLine, "ext_t", _ArboXExtend);
- pVB->setX (getHrcIconXStart(nLayer) - _XExtend);
- pVB->setY ((sint32)_Lines.size()*_BmpH - ((1+nLine)*_BmpH));
- addView (pVB);
- _Lines[nLine].Bmps.push_back(pVB);
- }
- }
- else
- {
- delete pVB;
- }
- }
- }
- // add additionnal bitmap for each line
- for (uint nLine = 0; nLine < _Lines.size(); nLine++)
- {
- if (!_Lines[nLine].Node->Bitmap.empty())
- {
- CViewBitmap *pVB = createViewBitmap(nLine, "custom_bm", _Lines[nLine].Node->Bitmap);
- pVB->setX (getHrcIconXStart(_Lines[nLine].Depth + 1));
- pVB->setY ((sint32)_Lines.size()*_BmpH - ((1+nLine)*_BmpH));
- _Lines[nLine].Bmps.push_back(pVB);
- addView (pVB);
- }
- }
-}
-
-// ***************************************************************************
-CGroupTree::SNode *CGroupTree::selectNodeByIdRecurse(SNode *pNode, const std::string &nodeId)
-{
- // select this node?
- if(pNode!=_RootNode)
- {
- if(pNode->Id == nodeId)
- return pNode;
- }
-
- // try with sons
- for(uint i=0;iChildren.size();i++)
- {
- SNode *ret= selectNodeByIdRecurse(pNode->Children[i], nodeId);
- if(ret)
- return ret;
- }
-
- // not found => NULL
- return NULL;
-}
-
-// ***************************************************************************
-bool CGroupTree::selectNodeById(const std::string &nodeId, bool triggerAH)
-{
- SNode *selNode= NULL;
-
- // Avoid infinite recurs
- if(_AvoidSelectNodeByIdIR)
- return true;
-
- // first find in the hierarchy
- selNode= selectNodeByIdRecurse(_RootNode, nodeId);
-
- // if found
- if(selNode)
- {
- // Opens the hierarchy
- SNode *pFather = selNode->Father;
- while(pFather != NULL)
- {
- pFather->Opened = true;
- pFather = pFather->Father;
- }
-
- if (triggerAH)
- {
- // runAH may infinite recurs (HTML browse...)
- _AvoidSelectNodeByIdIR= true;
-
- // launch the action handler
- CAHManager::getInstance()->runActionHandler ( selNode->AHName,
- this,
- selNode->AHParams );
- }
-
- // runAH may infinite recurs (HTML browse...)
- _AvoidSelectNodeByIdIR= false;
-
- // mark as selected
- _SelectedNode = selNode;
-
- forceRebuild();
-
- return true;
- }
- else
- {
- return false;
- }
-}
-
-// ***************************************************************************
-class CHandlerTreeReset : public IActionHandler
-{
-public:
- void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
- {
- CGroupTree *pTree = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(sParams));
- if (pTree != NULL)
- pTree->reset();
- }
-protected:
-};
-REGISTER_ACTION_HANDLER( CHandlerTreeReset, "tree_reset");
-
-// ***************************************************************************
-void CGroupTree::changeNavigateOneBranch(bool newState)
-{
- if(newState!=_NavigateOneBranch)
- {
- _NavigateOneBranch= newState;
- // if new is true, then must reset both open state and selection
- if(_NavigateOneBranch)
- {
- reset();
- // reselect the first line
- selectLine(0);
- }
- // else just rebuild
- else
- {
- forceRebuild();
- }
- }
-}
-
-// ***************************************************************************
-void CGroupTree::cancelNextSelectLine()
-{
- _CancelNextSelectLine = true;
-}
-
-// ***************************************************************************
-int CGroupTree::luaGetRootNode(CLuaState &ls)
-{
- CLuaIHM::checkArgCount(ls, "getRootNode", 0);
- CLuaIHM::pushReflectableOnStack(ls, getRootNode());
- return 1;
-}
-
-// ***************************************************************************
-int CGroupTree::luaSetRootNode(CLuaState &ls)
-{
- CLuaIHM::checkArgCount(ls, "setRootNode", 1);
- if (ls.isNil())
- {
- setRootNode(NULL);
- return 0;
- }
- setRootNode(SNode::luaGetNodeOnStack(ls, "CGroupTree::setRootNode"));
- return 0;
-}
-
-
-// ***************************************************************************
-int CGroupTree::luaForceRebuild(CLuaState &ls)
-{
- CLuaIHM::checkArgCount(ls, "forceRebuild", 0);
- forceRebuild();
- return 0;
-}
-
-// ***************************************************************************
-CGroupTree::SNode *CGroupTree::SNode::luaGetNodeOnStack(CLuaState &ls, const char * /* funcName */)
-{
- SNode *node = dynamic_cast(CLuaIHM::getReflectableOnStack(ls, 1));
- CLuaIHM::check(ls, node != NULL, "SNode expected");
- return node;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaDetachChild(CLuaState &ls)
-{
- const char *funcName = "CGroupTree::SNode::luaDetachChild";
- CLuaIHM::checkArgCount(ls, funcName, 1);
- detachChild(luaGetNodeOnStack(ls, funcName));
- return 0;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaSort(CLuaState &ls)
-{
- const char *funcName = "CGroupTree::SNode::luaSort";
- CLuaIHM::checkArgCount(ls, funcName, 0);
- sort();
- return 0;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaSortByBitmap(CLuaState &ls)
-{
- const char *funcName = "CGroupTree::SNode::luaSort";
- CLuaIHM::checkArgCount(ls, funcName, 0);
- sortByBitmap();
- return 0;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaDeleteChild(CLuaState &ls)
-{
- const char *funcName = "CGroupTree::SNode::luaDeleteChild";
- CLuaIHM::checkArgCount(ls, funcName, 1);
- deleteChild(luaGetNodeOnStack(ls, funcName));
- return 0;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaAddChild(CLuaState &ls)
-{
- const char *funcName = "CGroupTree::SNode::luaAddChild";
- CLuaIHM::checkArgCount(ls, funcName, 1);
- addChild(luaGetNodeOnStack(ls, funcName));
- return 0;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaAddChildSorted(CLuaState &ls)
-{
- const char *funcName = "CGroupTree::SNode::luaAddChildSorted";
- CLuaIHM::checkArgCount(ls, funcName, 1);
- addChildSorted(luaGetNodeOnStack(ls, funcName));
- return 0;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaAddChildSortedByBitmap(CLuaState &ls)
-{
- const char *funcName = "CGroupTree::SNode::luaAddChildSortedByBitmap";
- CLuaIHM::checkArgCount(ls, funcName, 1);
- addChildSorted(luaGetNodeOnStack(ls, funcName));
- return 0;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaGetNodeFromId(CLuaState &ls)
-{
- const char *funcName = "CGroupTree::SNode::luaGetNodeFromId";
- CLuaIHM::checkArgCount(ls, funcName, 1);
- CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING);
- SNode *result = getNodeFromId(ls.toString(1));
- if (result)
- {
- CLuaIHM::pushReflectableOnStack(ls, result);
- }
- else
- {
- ls.pushNil();
- }
- return 1;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaGetParentTree(CLuaState &ls)
-{
- CLuaIHM::checkArgCount(ls, "getParentTree", 0);
- if (ParentTree)
- {
- CLuaIHM::pushUIOnStack(ls, ParentTree);
- }
- else
- {
- ls.pushNil();
- }
- return 1;
-}
-
-// ***************************************************************************
-int CGroupTree::luaGetNodeUnderMouse(CLuaState &ls)
-{
- CLuaIHM::checkArgCount(ls, "getNodeUnderMouse", 0);
- SNode *node = getNodeUnderMouse();
- if (node)
- {
- CLuaIHM::pushReflectableOnStack(ls, node);
- }
- else
- {
- ls.pushNil();
- }
- return 1;
-}
-
-// ***************************************************************************
-int CGroupTree::luaCancelNextSelectLine(CLuaState &ls)
-{
- CLuaIHM::checkArgCount(ls, "cancelNextSelectLine", 0);
- cancelNextSelectLine();
- return 0;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaAddChildFront(CLuaState &ls)
-{
- const char *funcName = "CGroupTree::SNode::luaAddChildFront";
- CLuaIHM::checkArgCount(ls, funcName, 1);
- addChild(luaGetNodeOnStack(ls, funcName));
- return 0;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaIsChild(CLuaState &ls)
-{
- const char *funcName = "CGroupTree::SNode::luaIsChild";
- CLuaIHM::checkArgCount(ls, funcName, 1);
- ls.push(isChild(luaGetNodeOnStack(ls, funcName)));
- return 1;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaAddChildAtIndex(CLuaState &ls)
-{
- const char *funcName = "CGroupTree::SNode::luaAddChildAtIndex";
- CLuaIHM::checkArgCount(ls, funcName, 2);
- CLuaIHM::checkArgType(ls, funcName, 2, LUA_TNUMBER);
- addChildAtIndex(luaGetNodeOnStack(ls, funcName), (sint) ls.toNumber(2));
- return 0;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaGetFather(CLuaState &ls)
-{
- const char *funcName = "CGroupTree::SNode::luaGetFather";
- CLuaIHM::checkArgCount(ls, funcName, 0);
- if(Father)
- CLuaIHM::pushReflectableOnStack(ls, Father);
- else
- ls.pushNil();
- return 1;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaGetNumChildren(CLuaState &ls)
-{
- const char *funcName = "CGroupTree::SNode::luaGetNumChildren";
- CLuaIHM::checkArgCount(ls, funcName, 0);
- ls.push((double) Children.size());
- return 1;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaGetChild(CLuaState &ls)
-{
- const char *funcName = "CGroupTree::SNode::luaGetChild";
- CLuaIHM::checkArgCount(ls, funcName, 1);
- CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
- //
- sint index = (sint) ls.toNumber(1);
- if (index < 0 || index >= (sint) Children.size())
- {
- std::string range = Children.empty() ? "" : toString("[0, %d]", Children.size() - 1);
- CLuaIHM::fails(ls, "Bad index of tree node child : %d, range is %s", (int) index, range.c_str());
- }
- CLuaIHM::pushReflectableOnStack(ls, Children[index]);
- return 1;
-}
-
-// ***************************************************************************
-int CGroupTree::SNode::luaCloseAll(CLuaState &ls)
-{
- const char *funcName = "CGroupTree::SNode::luaGetFather";
- CLuaIHM::checkArgCount(ls, funcName, 0);
- closeAll();
- return 0;
-}
-
-// ***************************************************************************
-int CGroupTree::luaSelectNodeById(CLuaState &ls)
-{
- const char *funcName = "selectNodeById";
- CLuaIHM::checkArgCount(ls, funcName, 2);
- CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING);
- CLuaIHM::checkArgType(ls, funcName, 2, LUA_TBOOLEAN);
- selectNodeById(ls.toString(1), ls.toBoolean(2));
- return 0;
-}
-
-// ***************************************************************************
-int CGroupTree::luaGetSelectedNodeId(CLuaState &ls)
-{
- CLuaIHM::checkArgCount(ls, "getSelectedNodeId", 0);
- ls.push(getSelectedNodeId());
- return 1;
-}
-
-// ***************************************************************************
-int CGroupTree::luaSelectLine(CLuaState &ls)
-{
- CLuaIHM::checkArgType(ls, "CGroupTree::selectLine", 1, LUA_TNUMBER);
- CLuaIHM::checkArgType(ls, "CGroupTree::selectLine", 2, LUA_TBOOLEAN);
- selectLine((uint) ls.toNumber(1), ls.toBoolean(2));
- return 0;
-}
-
-// ***************************************************************************
-int CGroupTree::luaUnselect(CLuaState &ls)
-{
- CLuaIHM::checkArgCount(ls, "unselect", 0);
- unselect();
- return 0;
-}
-
-
-// ***************************************************************************
-uint CGroupTree::SLine::getNumAdditionnalBitmap() const
-{
- if (!Node) return 0;
- return Node->getNumBitmap();
-}
-
-
-
-
diff --git a/code/ryzom/client/src/interface_v3/group_tree.h b/code/ryzom/client/src/interface_v3/group_tree.h
deleted file mode 100644
index fcc321a2b..000000000
--- a/code/ryzom/client/src/interface_v3/group_tree.h
+++ /dev/null
@@ -1,375 +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_TREE_H
-#define NL_GROUP_TREE_H
-
-#include "nel/misc/types_nl.h"
-#include "nel/gui/group_frame.h"
-#include "nel/misc/smart_ptr.h"
-
-namespace NLGUI
-{
- class CViewText;
- class CViewBitmap;
-}
-
-// ----------------------------------------------------------------------------
-class CGroupTree : public CInterfaceGroup
-{
-
-public:
-
- struct SNode;
- // optional callback that is called when a node has been added
- struct INodeAddedCallback
- {
- /** A node has just been added in the CGroupTree object
- * \param node The logic node from which the ui node was built
- * \param interfaceElement The ui node that was built
- */
- virtual void nodeAdded(SNode *node, CInterfaceElement *interfaceElement) = 0;
- };
-
- // Logic structure to initialize the group tree (root node is not displayed and is always opened)
- struct SNode : public CReflectableRefPtrTarget
- {
- typedef NLMISC::CRefPtr TRefPtr;
- // Common
- std::string Id; // If not present auto-generated
- bool Opened;
- bool DisplayText; // If false instanciate a template
- bool Show; // If false, the node is not displayed (true default, Root ignored)
- sint32 YDecal;
- // Text
- ucstring Text; // Internationalized displayed text
- sint32 FontSize; // If -1 (default), then take the groupTree one
- NLMISC::CRGBA Color;
- // Template
- NLMISC::CSmartPtr Template;
- // Actions Handlers (for left button)
- std::string AHName;
- std::string AHCond;
- std::string AHParams;
- // Actions Handlers (for right button)
- std::string AHNameRight;
- std::string AHParamsRight;
- // Actions Handlers (close/open node)
- std::string AHNameClose;
- std::string AHParamsClose;
- // bitmap at this level of hierarchy
- std::string Bitmap; // additionnal bitmap
- // Hierarchy
- std::vector Children;
- SNode *Father;
- // updated at display
- SNode *LastVisibleSon; // filled at build time, meaningfull only if son is shown and opened, undefined otherwise
- // Node added callback
- INodeAddedCallback *NodeAddedCallback;
- //
- CGroupTree *ParentTree;
- // ----------------------------
- SNode();
- ~SNode();
- void updateLastVisibleSon();
- void detachChild(SNode *pNode);
- void deleteChild(SNode *pNode);
- void addChild (SNode *pNode);
- bool isChild(SNode *pNode) const;
- void addChildFront (SNode *pNode);
- void addChildAtIndex (SNode *pNode, sint index);
- void addChildSorted(SNode *pNode);
- void addChildSortedByBitmap(SNode *pNode);
- void setParentTree(CGroupTree *parent);
- void setFather(SNode *father);
- void closeAll();
- void makeOrphan();
- bool parse (xmlNodePtr cur, CGroupTree *parentGroup);
- uint getNumBitmap() const { return Bitmap.empty() ? 0 : 1; }
- SNode *getNodeFromId(const std::string &id);
-
- // accessors
- void setBitmap(const std::string &bitmap) { Bitmap = bitmap; }
- std::string getBitmap() const { return Bitmap; }
- void setOpened(bool opened) { Opened = opened; }
- bool getOpened() const { return Opened; }
- void setText(const ucstring &text) { Text = text; }
- const ucstring& getText() const { return Text; }
- sint32 getFontSize() const { return FontSize; }
- void setFontSize(sint32 value) { FontSize = value; }
- sint32 getYDecal() const { return YDecal; }
- void setYDecal(sint32 value) { YDecal = value; }
-
-
- std::string getId() const { return Id; }
- void setId(const std::string &value) { Id = value; }
- bool getShow() const { return Show; }
- void setShow(bool value) { Show = value; }
- std::string getAHName() const { return AHName; }
- void setAHName(const std::string &value) { AHName = value; }
- std::string getAHCond() const { return AHCond; }
- void setAHCond(const std::string &value) { AHCond = value; }
- std::string getAHParams() const { return AHParams; }
- void setAHParams(const std::string &value) { AHParams = value; }
- std::string getAHNameRight() const { return AHNameRight; }
- void setAHNameRight(const std::string &value) { AHNameRight = value; }
- std::string getAHParamsRight() const { return AHParamsRight; }
- void setAHParamsRight(const std::string &value) { AHParamsRight = value; }
- std::string getAHNameClose() const { return AHNameClose; }
- void setAHNameClose(const std::string &value) { AHNameClose = value; }
- std::string getAHParamsClose() const { return AHParamsClose; }
- void setAHParamsClose(const std::string &value) { AHParamsClose = value; }
- NLMISC::CRGBA getColor() const { return Color; }
- void setColor(NLMISC::CRGBA color) { Color = color; }
- // sort branch & sons alphabetically
- void sort();
- // sort branch & sons alphabetically & by bitmap name (blank bitmap being the first)
- void sortByBitmap();
-
- // lua bindings
- int luaGetNumChildren(CLuaState &ls);
- int luaGetChild(CLuaState &ls);
- int luaDetachChild(CLuaState &ls);
- int luaDeleteChild(CLuaState &ls);
- int luaAddChild(CLuaState &ls);
- int luaAddChildSorted(CLuaState &ls);
- int luaAddChildSortedByBitmap(CLuaState &ls);
- int luaIsChild(CLuaState &ls);
- int luaAddChildFront (CLuaState &ls);
- int luaAddChildAtIndex (CLuaState &ls);
- int luaCloseAll(CLuaState &ls);
- int luaGetFather(CLuaState &ls);
- int luaSort(CLuaState &ls);
- int luaSortByBitmap(CLuaState &ls);
- int luaGetNodeFromId(CLuaState &ls);
- int luaGetParentTree(CLuaState &ls);
-
- // get node from first parameter on lua stack and throw necessary exception if not present
- static SNode *luaGetNodeOnStack(CLuaState &ls, const char *funcName);
-
- REFLECT_EXPORT_START(CGroupTree::SNode, CReflectable)
- REFLECT_STRING("Id", getId, setId);
- REFLECT_STRING("Bitmap", getBitmap, setBitmap);
- REFLECT_SINT32("FontSize", getFontSize, setFontSize);
- REFLECT_SINT32("YDecal", getYDecal, setYDecal);
- REFLECT_STRING("AHName", getAHName, setAHName);
- REFLECT_STRING("AHCond", getAHCond, setAHCond);
- REFLECT_RGBA("Color", getColor, setColor);
- REFLECT_STRING("AHParams", getAHParams, setAHParams);
- REFLECT_STRING("AHNameRight", getAHNameRight, setAHNameRight);
- REFLECT_STRING("AHParamsRight", getAHParamsRight, setAHParamsRight);
- REFLECT_STRING("AHNameClose", getAHNameClose, setAHNameClose);
- REFLECT_STRING("AHParamsClose", getAHParamsClose, setAHParamsClose);
- REFLECT_BOOL("Opened", getOpened, setOpened);
- REFLECT_BOOL("Show", getShow, setShow);
- REFLECT_UCSTRING("Text", getText, setText);
- // lua
- REFLECT_LUA_METHOD("getNumChildren", luaGetNumChildren);
- REFLECT_LUA_METHOD("getChild", luaGetChild);
- REFLECT_LUA_METHOD("detachChild", luaDetachChild);
- REFLECT_LUA_METHOD("deleteChild", luaDeleteChild);
- REFLECT_LUA_METHOD("addChild", luaAddChild);
- REFLECT_LUA_METHOD("addChildSorted", luaAddChildSorted);
- REFLECT_LUA_METHOD("addChildSortedByBitmap", luaAddChildSortedByBitmap);
- REFLECT_LUA_METHOD("addChildFront", luaAddChildFront);
- REFLECT_LUA_METHOD("addChildAtIndex", luaAddChildAtIndex);
- REFLECT_LUA_METHOD("isChild", luaIsChild);
- REFLECT_LUA_METHOD("closeAll", luaCloseAll);
- REFLECT_LUA_METHOD("getFather", luaGetFather);
- REFLECT_LUA_METHOD("sort", luaSort);
- REFLECT_LUA_METHOD("sortByBitmap", luaSortByBitmap);
- REFLECT_LUA_METHOD("getNodeFromId", luaGetNodeFromId);
- REFLECT_LUA_METHOD("getParentTree", luaGetParentTree);
- REFLECT_EXPORT_END
-
-
- };
-
-public:
-
- ///constructor
- CGroupTree(const TCtorParam ¶m);
-
- // dtor
- virtual ~CGroupTree();
-
- virtual bool parse (xmlNodePtr cur, CInterfaceGroup * parentGroup);
-
- virtual void checkCoords();
-
- virtual void updateCoords();
-
- virtual void draw();
-
- virtual bool handleEvent (const NLGUI::CEventDescriptor& eventDesc);
-
- void reset();
-
- // force rebuild the tree at next updateCoords()
- void forceRebuild();
-
- // For SNode
- sint32 getIdNumber() { _IdGenerator++; return _IdGenerator; }
- sint32 getFontSize() { return _FontSize; }
- sint32 getYDecal() { return _YDecal; }
-
- // Set root node and delete the last one the user must not delete all allocated sub node. Nb: selection is reseted
- void setRootNode (SNode *);
- // Remove all lines bitmaps and templates or texts
- void removeAll();
-
- // unselect current node in tree
- void unselect();
-
- // Select a node by its line index (depends on opened nodes). no-op if not possible (AH not here, line>size)
- void selectLine(uint line, bool runAH = true);
- // simulate right button click on the given line (this also select the line)
- bool rightButton(uint line);
-
- // Get the Selected Node Id. empty if none selected
- const std::string &getSelectedNodeId() const;
-
- // Select by the node Id. return false if not found (selection is not reseted)
- // NB: if the node was already selected, no-op (no action handler launched)
- bool selectNodeById(const std::string &nodeId, bool triggerAH = true);
-
- // Get the root node (Opened State represent the current state)
- SNode *getRootNode () const {return _RootNode;}
-
- // get current SNode under the mouse (possibly NULL)
- SNode *getNodeUnderMouse() const;
-
- // Get/Change the NavigateOneBrnahc option. if false, then perform a reset before
- bool getNavigateOneBranch() const {return _NavigateOneBranch;}
- void changeNavigateOneBranch(bool newState);
-
- // should be called by action handler when thy want to cancel the selection of the line that triggered them
- void cancelNextSelectLine();
-
- // Get selected node
- SNode * getSelectedNode() { return _SelectedNode;}
-
- // lua bindings
- int luaGetRootNode(CLuaState &ls);
- int luaSetRootNode(CLuaState &ls);
- int luaForceRebuild(CLuaState &ls);
- int luaSelectNodeById(CLuaState &ls);
- int luaGetSelectedNodeId(CLuaState &ls);
- int luaSelectLine(CLuaState &ls);
- int luaUnselect(CLuaState &ls);
- int luaGetNodeUnderMouse(CLuaState &ls);
- int luaCancelNextSelectLine(CLuaState &ls);
-
- // Reflection
- REFLECT_EXPORT_START(CGroupTree, CInterfaceGroup)
- REFLECT_BOOL ("navigate_one_branch", getNavigateOneBranch, changeNavigateOneBranch);
- REFLECT_LUA_METHOD("getRootNode", luaGetRootNode);
- REFLECT_LUA_METHOD("setRootNode", luaSetRootNode);
- REFLECT_LUA_METHOD("forceRebuild", luaForceRebuild);
- REFLECT_LUA_METHOD("getSelectedNodeId", luaGetSelectedNodeId);
- REFLECT_LUA_METHOD("selectNodeById", luaSelectNodeById);
- REFLECT_LUA_METHOD("selectLine", luaSelectLine);
- REFLECT_LUA_METHOD("unselect", luaUnselect);
- REFLECT_LUA_METHOD("getNodeUnderMouse", luaGetNodeUnderMouse);
- REFLECT_LUA_METHOD("cancelNextSelectLine", luaCancelNextSelectLine);
- REFLECT_EXPORT_END
-
-private:
-
- sint32 _BmpW, _BmpH, _FontSize, _YDecal;
- sint32 _XExtend;
-
-private:
-
- // Display structure
- struct SLine
- {
- CViewBase *TextOrTemplate;
- std::vector Bmps;
- SNode::TRefPtr Node;
- uint8 Depth;
-
- SLine()
- {
- TextOrTemplate = NULL;
- }
-
- ~SLine()
- {
- Bmps.clear();
- }
- uint getNumAdditionnalBitmap() const;
- };
-
-protected:
-
- void rebuild();
- void addTextLine (uint8 nDepth, SNode *pNode);
- void addHierarchyBitmaps();
-
- SNode *selectNodeByIdRecurse(SNode *pNode, const std::string &nodeId);
-
- SNode *_RootNode;
- sint32 _IdGenerator;
- bool _MustRebuild;
- std::vector _Lines;
- sint32 _OverLine;
- NLMISC::CRGBA _OverColor;
- NLMISC::CRGBA _OverColorBack;
- SNode *_SelectedNode;
- sint32 _SelectedLine;
- NLMISC::CRGBA _SelectedColor;
-
- // If a node is closed and a son of this node was selected, then this option force the ancestor being the new selection
- bool _SelectAncestorOnClose;
- bool _NavigateOneBranch;
- bool _AvoidSelectNodeByIdIR;
-
- // when an action handler is run, it can call 'cancelSelectLine' if no selection should be done for real
- bool _CancelNextSelectLine;
-
-
- // Bitmap For arbo
- std::string _ArboOpenFirst;
- std::string _ArboCloseJustOne;
- std::string _ArboSonWithoutSon;
- std::string _ArboSonLast;
- std::string _ArboSon;
- std::string _ArboLevel;
- std::string _ArboXExtend;
-
- // Special rectangle
- bool _RectangleOutlineMode;
- sint32 _RectangleX, _RectangleY;
- sint32 _RectangleW, _RectangleH;
- sint32 _RectangleDeltaRL;
-
- sint32 getHrcIconXStart(sint32 depth);
- sint32 getHrcIconXEnd(sint32 depth);
-
- void drawSelection(sint x, sint y, sint w, NLMISC::CRGBA col);
-
- CViewBitmap *createViewBitmap(uint line, const std::string &idPrefix, const std::string &texture);
-};
-
-
-#endif // NL_GROUP_TREE_H
-
-/* End of group_tree.h */
-
-
diff --git a/code/ryzom/client/src/interface_v3/interface_parser.cpp b/code/ryzom/client/src/interface_v3/interface_parser.cpp
index 1203d66b4..35df296c3 100644
--- a/code/ryzom/client/src/interface_v3/interface_parser.cpp
+++ b/code/ryzom/client/src/interface_v3/interface_parser.cpp
@@ -66,7 +66,7 @@
#include "nel/gui/group_modal.h"
#include "group_modal_get_key.h"
#include "group_list.h"
-#include "group_tree.h"
+#include "nel/gui/group_tree.h"
#include "group_menu.h"
#include "group_container.h"
#include "group_scrolltext.h"
diff --git a/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp b/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp
index 3f363258c..cf1a1c2a8 100644
--- a/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp
+++ b/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp
@@ -51,7 +51,7 @@
#include "nel/gui/interface_group.h"
#include "nel/gui/view_text.h"
#include "game_share/people_pd.h"
-#include "group_tree.h"
+#include "nel/gui/group_tree.h"
#include "nel/gui/interface_link.h"
#include "nel/gui/interface_expr.h"
#include "people_interraction.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 ca2681bdd..bdde30aa9 100644
--- a/code/ryzom/client/src/interface_v3/register_interface_elements.cpp
+++ b/code/ryzom/client/src/interface_v3/register_interface_elements.cpp
@@ -41,7 +41,7 @@
#include "dbgroup_list_sheet.h"
#include "nel/gui/group_editbox_base.h"
#include "group_editbox.h"
-#include "group_tree.h"
+#include "nel/gui/group_tree.h"
#include "nel/gui/reflect.h"
#include "dbview_bar.h"
#include "dbview_bar3.h"
diff --git a/code/ryzom/client/src/r2/editor.cpp b/code/ryzom/client/src/r2/editor.cpp
index 7ce61fd08..29300c975 100644
--- a/code/ryzom/client/src/r2/editor.cpp
+++ b/code/ryzom/client/src/r2/editor.cpp
@@ -48,7 +48,7 @@
//
#include "nel/gui/lua_helper.h"
using namespace NLGUI;
-#include "../interface_v3/group_tree.h"
+#include "nel/gui/group_tree.h"
#include "../interface_v3/interface_manager.h"
#include "../contextual_cursor.h"
#include "../cursor_functions.h"
@@ -56,7 +56,7 @@ using namespace NLGUI;
#include "../events_listener.h"
#include "../interface_v3/group_list.h"
#include "nel/gui/event_descriptor.h"
-#include "../interface_v3/group_tree.h"
+#include "nel/gui/group_tree.h"
#include "../client_cfg.h"
#include "nel/gui/lua_ihm.h"
#include "../interface_v3/lua_ihm_ryzom.h"
diff --git a/code/ryzom/client/src/r2/editor.h b/code/ryzom/client/src/r2/editor.h
index 6219715b2..69711091c 100644
--- a/code/ryzom/client/src/r2/editor.h
+++ b/code/ryzom/client/src/r2/editor.h
@@ -41,8 +41,11 @@
+namespace NLGUI
+{
+ class CGroupTree;
+}
-class CGroupTree;
class CEntityCL;
namespace NL3D
diff --git a/code/ryzom/client/src/r2/palette_node.h b/code/ryzom/client/src/r2/palette_node.h
index c4e41fb2e..60c4b143b 100644
--- a/code/ryzom/client/src/r2/palette_node.h
+++ b/code/ryzom/client/src/r2/palette_node.h
@@ -20,7 +20,7 @@
#if 0
//#include "interface_user_data.h"
-#include "group_tree.h"
+#include "nel/gui/group_tree.h"
#include "nel/gui/lua_object.h"
//
#include "nel/misc/smart_ptr.h"
diff --git a/code/ryzom/client/src/r2/tool_choose_pos.cpp b/code/ryzom/client/src/r2/tool_choose_pos.cpp
index 966b54d5a..4d11d0423 100644
--- a/code/ryzom/client/src/r2/tool_choose_pos.cpp
+++ b/code/ryzom/client/src/r2/tool_choose_pos.cpp
@@ -20,7 +20,7 @@
#include "tool_choose_pos.h"
#include "../interface_v3/interface_manager.h"
#include "../global.h"
-#include "../interface_v3/group_tree.h"
+#include "nel/gui/group_tree.h"
#include "../interface_v3/group_map.h"
#include "../landscape_poly_drawer.h"
//