// 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 "group_frame.h" #include "nel/misc/smart_ptr.h" class CViewBitmap; class CViewText; // ---------------------------------------------------------------------------- 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; } 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 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 */