From e131c0f837ff75e600ee42a0c4bac4921d02c684 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 22 Jun 2012 05:37:55 +0200 Subject: [PATCH] CHANGED: #1471 CGroupTree is now part of NELGUI library, and is under NLGUI namespace. --- code/nel/include/nel/gui/group_tree.h | 376 ++++ code/nel/src/gui/group_tree.cpp | 1638 +++++++++++++++++ .../src/interface_v3/action_handler_game.cpp | 2 +- .../interface_v3/action_handler_phrase.cpp | 2 +- .../src/interface_v3/encyclopedia_manager.cpp | 2 +- .../client/src/interface_v3/group_html.h | 2 +- .../interface_v3/group_phrase_skill_filter.h | 2 +- .../client/src/interface_v3/group_skills.h | 2 +- .../client/src/interface_v3/group_tree.cpp | 1635 ---------------- .../client/src/interface_v3/group_tree.h | 375 ---- .../src/interface_v3/interface_parser.cpp | 2 +- .../client/src/interface_v3/lua_ihm_ryzom.cpp | 2 +- .../register_interface_elements.cpp | 2 +- code/ryzom/client/src/r2/editor.cpp | 4 +- code/ryzom/client/src/r2/editor.h | 5 +- code/ryzom/client/src/r2/palette_node.h | 2 +- code/ryzom/client/src/r2/tool_choose_pos.cpp | 2 +- 17 files changed, 2031 insertions(+), 2024 deletions(-) create mode 100644 code/nel/include/nel/gui/group_tree.h create mode 100644 code/nel/src/gui/group_tree.cpp delete mode 100644 code/ryzom/client/src/interface_v3/group_tree.cpp delete mode 100644 code/ryzom/client/src/interface_v3/group_tree.h 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" //