guiTreeViewCtrl.cpp
Engine/source/gui/controls/guiTreeViewCtrl.cpp
Public Functions
ConsoleDocClass(GuiTreeViewCtrl , "@brief Hierarchical list of text items with optional <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">icons.\n\n</a>" "Can also be used <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> inspect <a href="/coding/class/classsimobject/">SimObject</a> hierarchies, primarily within <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">editors.\n\n</a>" "GuiTreeViewCtrls can either display arbitrary user-defined trees or can be used <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> display <a href="/coding/class/classsimobject/">SimObject</a> hierarchies where " "each parent node in the tree is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classsimset/">SimSet</a> or <a href="/coding/class/classsimgroup/">SimGroup</a> and each leaf node is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SimObject.\n\n</a>" "Each item in the tree has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> text and <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> value. For trees that display <a href="/coding/class/classsimobject/">SimObject</a> hierarchies, the text <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> each item " "is automatically derived from objects <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a0e48c1f64b558d03d870367324920354">while</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> each item is the ID of the respective SimObject. For trees " "that are not tied <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> SimObjects, both text and <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> of each item are set by the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">user.\n\n</a>" " Additionally, items in the tree can have <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">icons.\n\n</a>" "Each item in the tree has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> distinct numeric ID that is unique within its tree. The ID of the root item, which is always " "present on <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> tree, is 0.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classguitreeviewctrl/">GuiTreeViewCtrl</a>(DatablockEditorTree)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " tabSize=\"16\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " textOffset = \"2\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " fullRowSelect = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " itemHeight = \"21\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " destroyTreeOnSleep = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " MouseDragging = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " MultipleSelections = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " DeleteObjectAllowed = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " DragToItemAllowed = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " ClearAllOnSingleSelection = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " showRoot = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " internalNamesOnly = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " objectNamesOnly = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " compareToObjectID = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " Profile = \"GuiTreeViewProfile\";\n" " tooltipprofile = \"GuiToolTipProfile\";\n" " hovertime = \"1000\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiContainers\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , addChildSelectionByValue , void , (S32 parentId, const char *value) , "Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child selection by it's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n\n</a>" "@param parentId Parent <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">TreeItemId.\n</a>" "@param <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/document_8h/#document_8h_1a071cf97155ba72ac9a1fc4ad7e63d481">Value</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> search <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">for.\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , addSelection , void , (S32 id, bool isLastSelection) , (true) , "Add an item/object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the current <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">selection.\n\n</a>" "@param <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> ID of item/object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> add <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">selection.\n</a>" "@param isLastSelection Whether there are more pending items/objects <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be added <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the selection. If false, " "the <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> will defer refreshing the tree and wait until addSelection() is called with this parameter set " "<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> true." )
DefineEngineMethod(GuiTreeViewCtrl , buildIconTable , bool , (const char *icons) , "Builds an icon <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">table.\n\n</a>" "@param icons Name of icons <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> build, Icons should be designated by the bitmap/png <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> names(minus the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> extensions)" "and separated by colons(:). This list should be synchronized with the Icons <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enum\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , buildVisibleTree , void , (bool forceFullUpdate) , (false) , "Build the visible <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param forceFullUpdate True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> force <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> full update of the tree, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> only update the <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stuff.\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , cancelRename , void , () , "Cancel renaming an item (For internal use)." )
DefineEngineMethod(GuiTreeViewCtrl , clear , void , () , "Empty the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , clearFilterText , void , () , "Clear the current item filtering <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pattern.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">setFilterText\n</a>" "@see getFilterText" )
DefineEngineMethod(GuiTreeViewCtrl , clearHiddenItems , void , () , "Set the pattern by which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> filter items in the tree. Only items in the tree whose text " "matches this pattern are <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">displayed.\n\n</a>" "@param pattern New pattern based on which visible items in the tree should be filtered. If empty, all items become <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">visible.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getFilterText\n</a>" " @see clearFilterText" )
DefineEngineMethod(GuiTreeViewCtrl , clearSelection , void , () , "Unselect all currently selected items." )
DefineEngineMethod(GuiTreeViewCtrl , deleteSelection , void , () , "Delete all items/objects in the current selection." )
DefineEngineMethod(GuiTreeViewCtrl , editItem , bool , (S32 itemId, const char *newText, const char *newValue) , "Edits the text and <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> given tree <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemId TreeItemID <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">edit.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , expandItem , bool , (S32 itemID, bool expand) , (true) , "Expand/contract item, item 's sub-<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" " @param itemID TreeItemId of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> expand or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">contract.\n</a>" " @param expand True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> expand the item, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> contract <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">it.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , findChildItemByName , S32 , (S32 parentId, const char *childName) , "Get the child item of the given parent item whose text matches @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">childName.\n\n</a>" "@param parentId <a href="/coding/class/classitem/">Item</a> ID of the parent in which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> look <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">child.\n</a>" "@param childName Text of the child item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">find.\n</a>" "@return ID of the child item or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> no child in @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parentId has the given text @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">childName.\n\n</a>" "@note This method does not recurse, i.e. it only looks <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> direct children." )
DefineEngineMethod(GuiTreeViewCtrl , findItemByName , S32 , (const char *text) , "Get the ID of the item whose text matches the given @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">text.\n\n</a>" "@param text <a href="/coding/class/classitem/">Item</a> text <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">match.\n</a>" "@return ID of the item or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> no item matches the given text." )
DefineEngineMethod(GuiTreeViewCtrl , findItemByObjectId , S32 , (S32 objectId) , "Find an item by its object <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> and returns the Tree <a href="/coding/class/classitem/">Item</a> ID <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">it.\n\n</a>" "@param objectId <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a5df911aaca43421a25e32c3002befbc4">Object</a> <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> you want the item <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> for." "@return Tree <a href="/coding/class/classitem/">Item</a> Id <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the given object ID." )
DefineEngineMethod(GuiTreeViewCtrl , findItemByValue , S32 , (const char *value) , "Get the ID of the item whose <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> matches @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n\n</a>" "@param <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/document_8h/#document_8h_1a071cf97155ba72ac9a1fc4ad7e63d481">Value</a> text <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">match.\n</a>" "@return ID of the item or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> no item has the given value." )
DefineEngineMethod(GuiTreeViewCtrl , getChild , S32 , (S32 itemId) , "Get the child of the parent with the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">id.\n\n</a>" "@param itemId TreeItemID of item that <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child we should <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">get.\n</a>" "@return Id of child of given item." )
DefineEngineMethod(GuiTreeViewCtrl , getFilterText , const char * , () , "Get the current filter expression. Only tree items whose text matches this expression " "are displayed. By default, the expression is empty and all items are <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">shown.\n\n</a>" " @return The current filter pattern or an empty string <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> no filter pattern is currently <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">active.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">setFilterText\n</a>" " @see clearFilterText" )
DefineEngineMethod(GuiTreeViewCtrl , getFirstRootItem , S32 , () , "Get <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> root <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n</a>" "@return Id <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> root item." )
DefineEngineMethod(GuiTreeViewCtrl , getItemAtPosition , S32 , (Point2I position) , (Point2I::Zero) , "Get the tree item at the passed in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">position.\n\n</a>" "@param position The position <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> check <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> what item is below <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">it.\n</a>" "@return The <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> of the item under the position." )
DefineEngineMethod(GuiTreeViewCtrl , getItemCount , S32 , () , "Get the total number of items in the tree or item <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">count.\n\n</a>" "@return total number of items in the tree." )
DefineEngineMethod(GuiTreeViewCtrl , getItemObject , S32 , (S32 itemId) , "Gets the object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> particular <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemId <a href="/coding/class/classitem/">Item</a> <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> you want the object <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> for." "@return <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a5df911aaca43421a25e32c3002befbc4">Object</a> Id <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the given tree item ID." )
DefineEngineMethod(GuiTreeViewCtrl , getItemText , const char * , (S32 itemId) , "Gets the text <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemId TreeItemID <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> get text <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">of.\n</a>" "@return Text <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> given item." )
DefineEngineMethod(GuiTreeViewCtrl , getItemValue , const char * , (S32 itemId) , "Gets the <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemId TreeItemID <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> get <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">of.\n</a>" "@return <a href="/coding/file/document_8h/#document_8h_1a071cf97155ba72ac9a1fc4ad7e63d481">Value</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> given item." )
DefineEngineMethod(GuiTreeViewCtrl , getNextSibling , S32 , (S32 itemId) , "Get the next sibling of the given item <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param itemId TreeItemID of item that we want the next sibling <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">of.\n</a>" "@return Id of next sibling of the given item." )
DefineEngineMethod(GuiTreeViewCtrl , getParentItem , S32 , (S32 itemId) , "Get the parent of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> given <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param itemId TreeItemID of item that has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parent we should <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">get.\n</a>" "@return Id of parent of given item." )
DefineEngineMethod(GuiTreeViewCtrl , getPrevSibling , S32 , (S32 itemId) , "Get the previous sibling of the given item <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param itemId TreeItemID of item that we want the previous sibling <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">of.\n</a>" "@return Id of previous sibling of the given item." )
DefineEngineMethod(GuiTreeViewCtrl , getSelectedItem , S32 , (S32 index) , (0) , "Return the selected item at the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">index.\n\n</a>" "@param index Given index <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> look <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> selected item." "@return selected item at the given index." )
DefineEngineMethod(GuiTreeViewCtrl , getSelectedItemList , const char * , () , "Returns <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> space separated list <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> ids of all selected <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">items.\n\n</a>" "@return space separated list of selected item ids." )
DefineEngineMethod(GuiTreeViewCtrl , getSelectedItemsCount , S32 , () , "Get the selected number of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">items.\n\n</a>" "@return number of selected items." )
DefineEngineMethod(GuiTreeViewCtrl , getSelectedObject , S32 , (S32 index) , (0) , "Return the currently selected <a href="/coding/class/classsimobject/">SimObject</a> at the given index in inspector <a href="/coding/file/zipobject_8cpp/#zipobject_8cpp_1ac6c3dfb4c3a68f849f32cbfb21da4e77">mode</a> or -1.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@param index Given index <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> look <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> selected object." "@return currently selected <a href="/coding/class/classsimobject/">SimObject</a> at the given index in inspector <a href="/coding/file/zipobject_8cpp/#zipobject_8cpp_1ac6c3dfb4c3a68f849f32cbfb21da4e77">mode</a> or -1." )
DefineEngineMethod(GuiTreeViewCtrl , getSelectedObjectList , const char * , () , "Returns <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> space separated list of all selected object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ids.\n\n</a>" "@return space separated list of all selected object ids." )
DefineEngineMethod(GuiTreeViewCtrl , getTabLevel , S32 , (S32 itemId) , (0) , "Get the tree item at the passed in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">position.\n\n</a>" "@param position The position <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> check <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> what item is below <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">it.\n</a>" "@return The <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> of the item under the position." )
DefineEngineMethod(GuiTreeViewCtrl , getTextToRoot , const char * , (S32 itemId, const char *delimiter) , ("") , "Gets the text from the current node <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the root, concatenating at each branch upward, with <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> specified delimiter <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">optionally.\n\n</a>" " @param itemId TreeItemId of node <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> start at." " @param delimiter(Optional) delimiter <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> use between each branch concatenation." " @return text from the current node <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the root." )
DefineEngineMethod(GuiTreeViewCtrl , hideSelection , void , (bool state) , (true) , "Call <a href="/coding/class/classsimobject/#classsimobject_1a68c9d8dc400ba765c987d9c917e7880f">SimObject::setHidden</a>( @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> state ) on all objects in the current <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">selection.\n\n</a>" "@param state Visibility state <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set objects in selection to." )
DefineEngineMethod(GuiTreeViewCtrl , insertItem , S32 , (S32 parentId, const char *text, const char *value, const char *icon, S32 normalImage, S32 expandedImage) , ("", "", 0, 0) , "Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param parentId <a href="/coding/class/classitem/">Item</a> ID of parent <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> add the item as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child. 0 is root <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n</a>" "@param text Text <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> display on the item in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n</a>" "@param <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> Behind-the-scenes <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n</a>" "@param <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">icon\n</a>" "@param <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">normalImage\n</a>" "@param <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">expandedImage\n</a>" "@return The ID of the newly added item." )
DefineEngineMethod(GuiTreeViewCtrl , insertObject , S32 , (S32 parentId, SimObject *obj, bool OKToEdit) , (false) , "Inserts object as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the given parent." )
DefineEngineMethod(GuiTreeViewCtrl , isItemSelected , bool , (S32 id) , "Check whether the given item is currently selected in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> <a href="/coding/class/classitem/">Item</a>/object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ID.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the given item/object is currently selected in the tree." )
DefineEngineMethod(GuiTreeViewCtrl , isParentItem , bool , (S32 itemId) , "Returns true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the given item contains child <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">items.\n\n</a>" "@param itemId TreeItemID <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> check <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">children.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the given item contains child items, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , lockSelection , void , (bool lock) , (true) , "Set whether the current selection can be changed by the user or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">not.\n\n</a>" "@param lock If true, the current selection is frozen and cannot be changed. If false, " "the selection may be modified." )
DefineEngineMethod(GuiTreeViewCtrl , markItem , bool , (S32 itemID, bool mark) , (true) , "Mark/unmark <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemID TreeItemId of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> Mark or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">unmark.\n</a>" "@param mark True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> Mark the item, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> unmark <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">it.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , moveItemDown , void , (S32 itemId) , "Move the specified item down in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param itemId TreeItemId of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> move down in the tree." )
DefineEngineMethod(GuiTreeViewCtrl , moveItemUp , void , (S32 itemId) , "Move the specified item up in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param itemId TreeItemId of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> move up in the tree." )
DefineEngineMethod(GuiTreeViewCtrl , onRenameValidate , void , () , "Validate the <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> name <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> an object (For internal use)." )
DefineEngineMethod(GuiTreeViewCtrl , open , void , (const char *objName, bool okToEdit) , (true) , "Set the root of the tree view <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the specified object, or <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the root <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n\n</a>" " @param objName Name or <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> of <a href="/coding/class/classsimset/">SimSet</a> or object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set the tree root equal <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to.\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , removeAllChildren , void , (S32 itemId) , "Remove all children of an item from the tree with the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">id.\n\n</a>" "@param itemId TreeItemID of item that has children we should <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">remove.\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , removeChildSelectionByValue , void , (S32 parentId, const char *value) , "Deselect <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child item or remove it from the selection based on its parent and its <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n\n</a>" "@param parentId Parent <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">TreeItemId.\n</a>" "@param <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/document_8h/#document_8h_1a071cf97155ba72ac9a1fc4ad7e63d481">Value</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> search <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">for.\n</a>" "@param performCallback True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/gamefunctions_8cpp/#gamefunctions_8cpp_1aa17ef8ef4f36199ef68ab2859f9fbda4">notify</a> script of the change, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">not.\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , removeItem , bool , (S32 itemId, bool deleteObjects) , (0, true) , "Remove an item from the tree with the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">id.\n\n</a>" "@param itemId TreeItemID of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">remove.\n</a>" "@param deleteObjects Whether the object on the item is deleted when the item <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">is.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , removeSelection , void , (S32 itemId) , "Deselect an item or remove it from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">selection.\n\n</a>" "@param itemId <a href="/coding/class/classitem/">Item</a> Id <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">deselect.\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , reparentItem , void , (S32 itemId, S32 parentId) , (0, 0) , "Check whether the given item is currently selected in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> <a href="/coding/class/classitem/">Item</a>/object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ID.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the given item/object is currently selected in the tree." )
DefineEngineMethod(GuiTreeViewCtrl , scrollVisible , bool , (S32 itemID) , "Make the given item <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">visible.\n\n</a>" "@param itemID TreeItemId of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> scroll <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a>/make <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">visible.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , scrollVisibleByObjectId , S32 , (S32 objectId) , "Show item by object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">id.\n\n</a>" "@param objectId <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a5df911aaca43421a25e32c3002befbc4">Object</a> <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> you want <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> scroll to." "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , selectItem , bool , (S32 itemID, bool select) , (true) , "Select or deselect and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemID TreeItemId of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> select or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">deselect.\n</a>" "@param select True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> select the item, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> deselect <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">it.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , setDebug , void , (bool value) , (true) , "Enable/disable debug output." "@param <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> enable debug output, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> disable it." )
DefineEngineMethod(GuiTreeViewCtrl , setFilterChildren , void , (bool doFilterChildren) , (true) , "Set the pattern by which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> filter items in the tree. Only items in the tree whose text " "matches this pattern are <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">displayed.\n\n</a>" "@param pattern New pattern based on which visible items in the tree should be filtered. If empty, all items become <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">visible.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getFilterText\n</a>" " @see clearFilterText" )
DefineEngineMethod(GuiTreeViewCtrl , setFilterText , void , (const char *pattern) , "Set the pattern by which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> filter items in the tree. Only items in the tree whose text " "matches this pattern are <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">displayed.\n\n</a>" "@param pattern New pattern based on which visible items in the tree should be filtered. If empty, all items become <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">visible.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getFilterText\n</a>" " @see clearFilterText" )
DefineEngineMethod(GuiTreeViewCtrl , setItemFilterException , void , (U32 item, bool isExempt) , (0, true) , "Set the pattern by which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> filter items in the tree. Only items in the tree whose text " "matches this pattern are <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">displayed.\n\n</a>" "@param pattern New pattern based on which visible items in the tree should be filtered. If empty, all items become <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">visible.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getFilterText\n</a>" " @see clearFilterText" )
DefineEngineMethod(GuiTreeViewCtrl , setItemHidden , void , (U32 item, bool hidden) , (0, true) , "Set the pattern by which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> filter items in the tree. Only items in the tree whose text " "matches this pattern are <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">displayed.\n\n</a>" "@param pattern New pattern based on which visible items in the tree should be filtered. If empty, all items become <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">visible.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getFilterText\n</a>" " @see clearFilterText" )
DefineEngineMethod(GuiTreeViewCtrl , setItemImages , void , (S32 itemId, S8 normalImage, S8 expandedImage) , "Sets the normal and expanded images <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> show <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemId TreeItemID of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set images <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">for.\n</a>" "@param normalImage Normal image <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the given item." "@param expandedImage Expanded image <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the given item." )
DefineEngineMethod(GuiTreeViewCtrl , setItemTooltip , bool , (S32 itemId, const char *tooltip) , "Set the tooltip <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> show <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemId TreeItemID of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set the tooltip <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">for.\n</a>" "@param tooltip <a href="/coding/class/classstring/">String</a> tooltip <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the item." "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> successfully found the item, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not" )
DefineEngineMethod(GuiTreeViewCtrl , showItemRenameCtrl , void , (S32 itemId) , "Show the rename text field <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the given item (only one at <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> time)." "@param itemId TreeItemId of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> show rename text field for." )
DefineEngineMethod(GuiTreeViewCtrl , sort , void , (S32 parentId, bool traverseHierarchy, bool parentsFirst, bool caseSensitive) , (0, false, false, true) , "Sorts all items of the given parent (or root). With 'hierarchy' , traverses hierarchy." " @param parentId TreeItemID of parent/root <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> sort all the items under. Use 0 <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> sort the entire tree." " @param traverseHierarchy True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> traverse the hierarchy, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> not." " @param parentsFirst True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> sort the parents first." " @param caseSensitive True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> pay attention <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> case, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> ignore it." )
DefineEngineMethod(GuiTreeViewCtrl , toggleHideSelection , void , () , "Toggle the hidden state of all objects in the current selection." )
DefineEngineMethod(GuiTreeViewCtrl , toggleLockSelection , void , () , "Toggle the locked state of all objects in the current selection." )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , canRenameObject , bool , (SimObject *object) , (object) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , handleRenameObject , bool , (const char *newName, SimObject *object) , (newName, object) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , isValidDragTarget , bool , (S32 id, const char *value) , (id, value) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onAddGroupSelected , void , (SimGroup *group) , (group) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onAddMultipleSelectionBegin , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onAddMultipleSelectionEnd , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onAddSelection , void , (S32 itemOrObjectId, bool isLastSelection) , (itemOrObjectId, isLastSelection) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onBeginReparenting , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onClearSelection , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onDefineIcons , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onDeleteObject , bool , (SimObject *object) , (object) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onDeleteSelection , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onDragDropped , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onEndReparenting , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onInspect , void , (S32 itemOrObjectId) , (itemOrObjectId) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onKeyDown , void , (S32 modifier, S32 keyCode) , (modifier, keyCode) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onMouseDragged , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onMouseUp , void , (S32 hitItemId, S32 mouseClickCount) , (hitItemId, mouseClickCount) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onObjectDeleteCompleted , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onRemoveSelection , void , (S32 itemOrObjectId) , (itemOrObjectId) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onReparent , void , (S32 itemOrObjectId, S32 oldParentItemOrObjectId, S32 newParentItemOrObjectId) , (itemOrObjectId, oldParentItemOrObjectId, newParentItemOrObjectId) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onRightMouseDown , void , (S32 itemId, const Point2I &mousePos, SimObject *object) , (itemId, mousePos, object) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onRightMouseUp , void , (S32 itemId, const Point2I &mousePos, SimObject *object) , (itemId, mousePos, object) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onSelect , void , (S32 itemOrObjectId) , (itemOrObjectId) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onUnselect , void , (S32 itemOrObjectId) , (itemOrObjectId) , "" )
itemCompareCaseInsensitive(const void * a, const void * b)
itemCompareCaseSensitive(const void * a, const void * b)
itemSortList(GuiTreeViewCtrl::Item *& firstChild, bool caseSensitive, bool traverseHierarchy, bool parentsFirst)
Detailed Description
Public Functions
ConsoleDocClass(GuiTreeViewCtrl , "@brief Hierarchical list of text items with optional <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">icons.\n\n</a>" "Can also be used <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> inspect <a href="/coding/class/classsimobject/">SimObject</a> hierarchies, primarily within <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">editors.\n\n</a>" "GuiTreeViewCtrls can either display arbitrary user-defined trees or can be used <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> display <a href="/coding/class/classsimobject/">SimObject</a> hierarchies where " "each parent node in the tree is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classsimset/">SimSet</a> or <a href="/coding/class/classsimgroup/">SimGroup</a> and each leaf node is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SimObject.\n\n</a>" "Each item in the tree has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> text and <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> value. For trees that display <a href="/coding/class/classsimobject/">SimObject</a> hierarchies, the text <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> each item " "is automatically derived from objects <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a0e48c1f64b558d03d870367324920354">while</a> the <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> each item is the ID of the respective SimObject. For trees " "that are not tied <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> SimObjects, both text and <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> of each item are set by the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">user.\n\n</a>" " Additionally, items in the tree can have <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">icons.\n\n</a>" "Each item in the tree has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> distinct numeric ID that is unique within its tree. The ID of the root item, which is always " "present on <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> tree, is 0.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classguitreeviewctrl/">GuiTreeViewCtrl</a>(DatablockEditorTree)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " tabSize=\"16\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " textOffset = \"2\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " fullRowSelect = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " itemHeight = \"21\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " destroyTreeOnSleep = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " MouseDragging = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " MultipleSelections = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " DeleteObjectAllowed = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " DragToItemAllowed = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " ClearAllOnSingleSelection = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " showRoot = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " internalNamesOnly = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " objectNamesOnly = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " compareToObjectID = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " Profile = \"GuiTreeViewProfile\";\n" " tooltipprofile = \"GuiToolTipProfile\";\n" " hovertime = \"1000\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiContainers\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , addChildSelectionByValue , void , (S32 parentId, const char *value) , "Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child selection by it's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n\n</a>" "@param parentId Parent <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">TreeItemId.\n</a>" "@param <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/document_8h/#document_8h_1a071cf97155ba72ac9a1fc4ad7e63d481">Value</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> search <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">for.\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , addSelection , void , (S32 id, bool isLastSelection) , (true) , "Add an item/object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the current <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">selection.\n\n</a>" "@param <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> ID of item/object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> add <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">selection.\n</a>" "@param isLastSelection Whether there are more pending items/objects <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be added <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the selection. If false, " "the <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> will defer refreshing the tree and wait until addSelection() is called with this parameter set " "<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> true." )
DefineEngineMethod(GuiTreeViewCtrl , buildIconTable , bool , (const char *icons) , "Builds an icon <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">table.\n\n</a>" "@param icons Name of icons <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> build, Icons should be designated by the bitmap/png <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> names(minus the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> extensions)" "and separated by colons(:). This list should be synchronized with the Icons <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enum\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , buildVisibleTree , void , (bool forceFullUpdate) , (false) , "Build the visible <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param forceFullUpdate True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> force <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> full update of the tree, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> only update the <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stuff.\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , cancelRename , void , () , "Cancel renaming an item (For internal use)." )
DefineEngineMethod(GuiTreeViewCtrl , clear , void , () , "Empty the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , clearFilterText , void , () , "Clear the current item filtering <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pattern.\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">setFilterText\n</a>" "@see getFilterText" )
DefineEngineMethod(GuiTreeViewCtrl , clearHiddenItems , void , () , "Set the pattern by which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> filter items in the tree. Only items in the tree whose text " "matches this pattern are <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">displayed.\n\n</a>" "@param pattern New pattern based on which visible items in the tree should be filtered. If empty, all items become <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">visible.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getFilterText\n</a>" " @see clearFilterText" )
DefineEngineMethod(GuiTreeViewCtrl , clearSelection , void , () , "Unselect all currently selected items." )
DefineEngineMethod(GuiTreeViewCtrl , deleteSelection , void , () , "Delete all items/objects in the current selection." )
DefineEngineMethod(GuiTreeViewCtrl , editItem , bool , (S32 itemId, const char *newText, const char *newValue) , "Edits the text and <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> given tree <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemId TreeItemID <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">edit.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , expandItem , bool , (S32 itemID, bool expand) , (true) , "Expand/contract item, item 's sub-<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" " @param itemID TreeItemId of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> expand or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">contract.\n</a>" " @param expand True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> expand the item, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> contract <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">it.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , findChildItemByName , S32 , (S32 parentId, const char *childName) , "Get the child item of the given parent item whose text matches @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">childName.\n\n</a>" "@param parentId <a href="/coding/class/classitem/">Item</a> ID of the parent in which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> look <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">child.\n</a>" "@param childName Text of the child item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">find.\n</a>" "@return ID of the child item or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> no child in @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parentId has the given text @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">childName.\n\n</a>" "@note This method does not recurse, i.e. it only looks <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> direct children." )
DefineEngineMethod(GuiTreeViewCtrl , findItemByName , S32 , (const char *text) , "Get the ID of the item whose text matches the given @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">text.\n\n</a>" "@param text <a href="/coding/class/classitem/">Item</a> text <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">match.\n</a>" "@return ID of the item or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> no item matches the given text." )
DefineEngineMethod(GuiTreeViewCtrl , findItemByObjectId , S32 , (S32 objectId) , "Find an item by its object <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> and returns the Tree <a href="/coding/class/classitem/">Item</a> ID <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">it.\n\n</a>" "@param objectId <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a5df911aaca43421a25e32c3002befbc4">Object</a> <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> you want the item <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> for." "@return Tree <a href="/coding/class/classitem/">Item</a> Id <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the given object ID." )
DefineEngineMethod(GuiTreeViewCtrl , findItemByValue , S32 , (const char *value) , "Get the ID of the item whose <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> matches @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n\n</a>" "@param <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/document_8h/#document_8h_1a071cf97155ba72ac9a1fc4ad7e63d481">Value</a> text <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">match.\n</a>" "@return ID of the item or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> no item has the given value." )
DefineEngineMethod(GuiTreeViewCtrl , getChild , S32 , (S32 itemId) , "Get the child of the parent with the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">id.\n\n</a>" "@param itemId TreeItemID of item that <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child we should <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">get.\n</a>" "@return Id of child of given item." )
DefineEngineMethod(GuiTreeViewCtrl , getFilterText , const char * , () , "Get the current filter expression. Only tree items whose text matches this expression " "are displayed. By default, the expression is empty and all items are <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">shown.\n\n</a>" " @return The current filter pattern or an empty string <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> no filter pattern is currently <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">active.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">setFilterText\n</a>" " @see clearFilterText" )
DefineEngineMethod(GuiTreeViewCtrl , getFirstRootItem , S32 , () , "Get <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> root <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n</a>" "@return Id <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> root item." )
DefineEngineMethod(GuiTreeViewCtrl , getItemAtPosition , S32 , (Point2I position) , (Point2I::Zero) , "Get the tree item at the passed in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">position.\n\n</a>" "@param position The position <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> check <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> what item is below <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">it.\n</a>" "@return The <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> of the item under the position." )
DefineEngineMethod(GuiTreeViewCtrl , getItemCount , S32 , () , "Get the total number of items in the tree or item <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">count.\n\n</a>" "@return total number of items in the tree." )
DefineEngineMethod(GuiTreeViewCtrl , getItemObject , S32 , (S32 itemId) , "Gets the object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> particular <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemId <a href="/coding/class/classitem/">Item</a> <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> you want the object <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> for." "@return <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a5df911aaca43421a25e32c3002befbc4">Object</a> Id <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the given tree item ID." )
DefineEngineMethod(GuiTreeViewCtrl , getItemText , const char * , (S32 itemId) , "Gets the text <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemId TreeItemID <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> get text <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">of.\n</a>" "@return Text <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> given item." )
DefineEngineMethod(GuiTreeViewCtrl , getItemValue , const char * , (S32 itemId) , "Gets the <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemId TreeItemID <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> get <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">of.\n</a>" "@return <a href="/coding/file/document_8h/#document_8h_1a071cf97155ba72ac9a1fc4ad7e63d481">Value</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> given item." )
DefineEngineMethod(GuiTreeViewCtrl , getNextSibling , S32 , (S32 itemId) , "Get the next sibling of the given item <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param itemId TreeItemID of item that we want the next sibling <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">of.\n</a>" "@return Id of next sibling of the given item." )
DefineEngineMethod(GuiTreeViewCtrl , getParentItem , S32 , (S32 itemId) , "Get the parent of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> given <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param itemId TreeItemID of item that has <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> parent we should <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">get.\n</a>" "@return Id of parent of given item." )
DefineEngineMethod(GuiTreeViewCtrl , getPrevSibling , S32 , (S32 itemId) , "Get the previous sibling of the given item <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param itemId TreeItemID of item that we want the previous sibling <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">of.\n</a>" "@return Id of previous sibling of the given item." )
DefineEngineMethod(GuiTreeViewCtrl , getSelectedItem , S32 , (S32 index) , (0) , "Return the selected item at the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">index.\n\n</a>" "@param index Given index <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> look <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> selected item." "@return selected item at the given index." )
DefineEngineMethod(GuiTreeViewCtrl , getSelectedItemList , const char * , () , "Returns <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> space separated list <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> ids of all selected <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">items.\n\n</a>" "@return space separated list of selected item ids." )
DefineEngineMethod(GuiTreeViewCtrl , getSelectedItemsCount , S32 , () , "Get the selected number of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">items.\n\n</a>" "@return number of selected items." )
DefineEngineMethod(GuiTreeViewCtrl , getSelectedObject , S32 , (S32 index) , (0) , "Return the currently selected <a href="/coding/class/classsimobject/">SimObject</a> at the given index in inspector <a href="/coding/file/zipobject_8cpp/#zipobject_8cpp_1ac6c3dfb4c3a68f849f32cbfb21da4e77">mode</a> or -1.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@param index Given index <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> look <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> selected object." "@return currently selected <a href="/coding/class/classsimobject/">SimObject</a> at the given index in inspector <a href="/coding/file/zipobject_8cpp/#zipobject_8cpp_1ac6c3dfb4c3a68f849f32cbfb21da4e77">mode</a> or -1." )
DefineEngineMethod(GuiTreeViewCtrl , getSelectedObjectList , const char * , () , "Returns <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> space separated list of all selected object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ids.\n\n</a>" "@return space separated list of all selected object ids." )
DefineEngineMethod(GuiTreeViewCtrl , getTabLevel , S32 , (S32 itemId) , (0) , "Get the tree item at the passed in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">position.\n\n</a>" "@param position The position <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> check <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> what item is below <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">it.\n</a>" "@return The <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> of the item under the position." )
DefineEngineMethod(GuiTreeViewCtrl , getTextToRoot , const char * , (S32 itemId, const char *delimiter) , ("") , "Gets the text from the current node <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the root, concatenating at each branch upward, with <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> specified delimiter <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">optionally.\n\n</a>" " @param itemId TreeItemId of node <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> start at." " @param delimiter(Optional) delimiter <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> use between each branch concatenation." " @return text from the current node <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the root." )
DefineEngineMethod(GuiTreeViewCtrl , hideSelection , void , (bool state) , (true) , "Call <a href="/coding/class/classsimobject/#classsimobject_1a68c9d8dc400ba765c987d9c917e7880f">SimObject::setHidden</a>( @<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> state ) on all objects in the current <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">selection.\n\n</a>" "@param state Visibility state <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set objects in selection to." )
DefineEngineMethod(GuiTreeViewCtrl , insertItem , S32 , (S32 parentId, const char *text, const char *value, const char *icon, S32 normalImage, S32 expandedImage) , ("", "", 0, 0) , "Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param parentId <a href="/coding/class/classitem/">Item</a> ID of parent <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> add the item as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child. 0 is root <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n</a>" "@param text Text <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> display on the item in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n</a>" "@param <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> Behind-the-scenes <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n</a>" "@param <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">icon\n</a>" "@param <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">normalImage\n</a>" "@param <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">expandedImage\n</a>" "@return The ID of the newly added item." )
DefineEngineMethod(GuiTreeViewCtrl , insertObject , S32 , (S32 parentId, SimObject *obj, bool OKToEdit) , (false) , "Inserts object as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the given parent." )
DefineEngineMethod(GuiTreeViewCtrl , isItemSelected , bool , (S32 id) , "Check whether the given item is currently selected in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> <a href="/coding/class/classitem/">Item</a>/object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ID.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the given item/object is currently selected in the tree." )
DefineEngineMethod(GuiTreeViewCtrl , isParentItem , bool , (S32 itemId) , "Returns true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the given item contains child <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">items.\n\n</a>" "@param itemId TreeItemID <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> check <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">children.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the given item contains child items, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , lockSelection , void , (bool lock) , (true) , "Set whether the current selection can be changed by the user or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">not.\n\n</a>" "@param lock If true, the current selection is frozen and cannot be changed. If false, " "the selection may be modified." )
DefineEngineMethod(GuiTreeViewCtrl , markItem , bool , (S32 itemID, bool mark) , (true) , "Mark/unmark <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemID TreeItemId of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> Mark or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">unmark.\n</a>" "@param mark True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> Mark the item, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> unmark <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">it.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , moveItemDown , void , (S32 itemId) , "Move the specified item down in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param itemId TreeItemId of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> move down in the tree." )
DefineEngineMethod(GuiTreeViewCtrl , moveItemUp , void , (S32 itemId) , "Move the specified item up in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param itemId TreeItemId of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> move up in the tree." )
DefineEngineMethod(GuiTreeViewCtrl , onRenameValidate , void , () , "Validate the <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> name <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> an object (For internal use)." )
DefineEngineMethod(GuiTreeViewCtrl , open , void , (const char *objName, bool okToEdit) , (true) , "Set the root of the tree view <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the specified object, or <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the root <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n\n</a>" " @param objName Name or <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> of <a href="/coding/class/classsimset/">SimSet</a> or object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set the tree root equal <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to.\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , removeAllChildren , void , (S32 itemId) , "Remove all children of an item from the tree with the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">id.\n\n</a>" "@param itemId TreeItemID of item that has children we should <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">remove.\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , removeChildSelectionByValue , void , (S32 parentId, const char *value) , "Deselect <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child item or remove it from the selection based on its parent and its <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n\n</a>" "@param parentId Parent <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">TreeItemId.\n</a>" "@param <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/document_8h/#document_8h_1a071cf97155ba72ac9a1fc4ad7e63d481">Value</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> search <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">for.\n</a>" "@param performCallback True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/gamefunctions_8cpp/#gamefunctions_8cpp_1aa17ef8ef4f36199ef68ab2859f9fbda4">notify</a> script of the change, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">not.\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , removeItem , bool , (S32 itemId, bool deleteObjects) , (0, true) , "Remove an item from the tree with the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">id.\n\n</a>" "@param itemId TreeItemID of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">remove.\n</a>" "@param deleteObjects Whether the object on the item is deleted when the item <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">is.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , removeSelection , void , (S32 itemId) , "Deselect an item or remove it from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">selection.\n\n</a>" "@param itemId <a href="/coding/class/classitem/">Item</a> Id <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">deselect.\n</a>" )
DefineEngineMethod(GuiTreeViewCtrl , reparentItem , void , (S32 itemId, S32 parentId) , (0, 0) , "Check whether the given item is currently selected in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tree.\n\n</a>" "@param <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> <a href="/coding/class/classitem/">Item</a>/object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ID.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the given item/object is currently selected in the tree." )
DefineEngineMethod(GuiTreeViewCtrl , scrollVisible , bool , (S32 itemID) , "Make the given item <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">visible.\n\n</a>" "@param itemID TreeItemId of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> scroll <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a>/make <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">visible.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , scrollVisibleByObjectId , S32 , (S32 objectId) , "Show item by object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">id.\n\n</a>" "@param objectId <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a5df911aaca43421a25e32c3002befbc4">Object</a> <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> you want <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> scroll to." "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , selectItem , bool , (S32 itemID, bool select) , (true) , "Select or deselect and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemID TreeItemId of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> select or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">deselect.\n</a>" "@param select True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> select the item, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> deselect <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">it.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not." )
DefineEngineMethod(GuiTreeViewCtrl , setDebug , void , (bool value) , (true) , "Enable/disable debug output." "@param <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> enable debug output, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> disable it." )
DefineEngineMethod(GuiTreeViewCtrl , setFilterChildren , void , (bool doFilterChildren) , (true) , "Set the pattern by which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> filter items in the tree. Only items in the tree whose text " "matches this pattern are <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">displayed.\n\n</a>" "@param pattern New pattern based on which visible items in the tree should be filtered. If empty, all items become <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">visible.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getFilterText\n</a>" " @see clearFilterText" )
DefineEngineMethod(GuiTreeViewCtrl , setFilterText , void , (const char *pattern) , "Set the pattern by which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> filter items in the tree. Only items in the tree whose text " "matches this pattern are <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">displayed.\n\n</a>" "@param pattern New pattern based on which visible items in the tree should be filtered. If empty, all items become <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">visible.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getFilterText\n</a>" " @see clearFilterText" )
DefineEngineMethod(GuiTreeViewCtrl , setItemFilterException , void , (U32 item, bool isExempt) , (0, true) , "Set the pattern by which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> filter items in the tree. Only items in the tree whose text " "matches this pattern are <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">displayed.\n\n</a>" "@param pattern New pattern based on which visible items in the tree should be filtered. If empty, all items become <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">visible.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getFilterText\n</a>" " @see clearFilterText" )
DefineEngineMethod(GuiTreeViewCtrl , setItemHidden , void , (U32 item, bool hidden) , (0, true) , "Set the pattern by which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> filter items in the tree. Only items in the tree whose text " "matches this pattern are <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">displayed.\n\n</a>" "@param pattern New pattern based on which visible items in the tree should be filtered. If empty, all items become <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">visible.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">getFilterText\n</a>" " @see clearFilterText" )
DefineEngineMethod(GuiTreeViewCtrl , setItemImages , void , (S32 itemId, S8 normalImage, S8 expandedImage) , "Sets the normal and expanded images <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> show <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemId TreeItemID of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set images <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">for.\n</a>" "@param normalImage Normal image <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the given item." "@param expandedImage Expanded image <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the given item." )
DefineEngineMethod(GuiTreeViewCtrl , setItemTooltip , bool , (S32 itemId, const char *tooltip) , "Set the tooltip <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> show <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">item.\n\n</a>" "@param itemId TreeItemID of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set the tooltip <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">for.\n</a>" "@param tooltip <a href="/coding/class/classstring/">String</a> tooltip <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> set <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the item." "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> successfully found the item, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not" )
DefineEngineMethod(GuiTreeViewCtrl , showItemRenameCtrl , void , (S32 itemId) , "Show the rename text field <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the given item (only one at <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> time)." "@param itemId TreeItemId of item <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> show rename text field for." )
DefineEngineMethod(GuiTreeViewCtrl , sort , void , (S32 parentId, bool traverseHierarchy, bool parentsFirst, bool caseSensitive) , (0, false, false, true) , "Sorts all items of the given parent (or root). With 'hierarchy' , traverses hierarchy." " @param parentId TreeItemID of parent/root <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> sort all the items under. Use 0 <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> sort the entire tree." " @param traverseHierarchy True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> traverse the hierarchy, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> not." " @param parentsFirst True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> sort the parents first." " @param caseSensitive True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> pay attention <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> case, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> ignore it." )
DefineEngineMethod(GuiTreeViewCtrl , toggleHideSelection , void , () , "Toggle the hidden state of all objects in the current selection." )
DefineEngineMethod(GuiTreeViewCtrl , toggleLockSelection , void , () , "Toggle the locked state of all objects in the current selection." )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , canRenameObject , bool , (SimObject *object) , (object) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , handleRenameObject , bool , (const char *newName, SimObject *object) , (newName, object) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , isValidDragTarget , bool , (S32 id, const char *value) , (id, value) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onAddGroupSelected , void , (SimGroup *group) , (group) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onAddMultipleSelectionBegin , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onAddMultipleSelectionEnd , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onAddSelection , void , (S32 itemOrObjectId, bool isLastSelection) , (itemOrObjectId, isLastSelection) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onBeginReparenting , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onClearSelection , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onDefineIcons , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onDeleteObject , bool , (SimObject *object) , (object) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onDeleteSelection , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onDragDropped , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onEndReparenting , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onInspect , void , (S32 itemOrObjectId) , (itemOrObjectId) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onKeyDown , void , (S32 modifier, S32 keyCode) , (modifier, keyCode) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onMouseDragged , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onMouseUp , void , (S32 hitItemId, S32 mouseClickCount) , (hitItemId, mouseClickCount) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onObjectDeleteCompleted , void , () , () , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onRemoveSelection , void , (S32 itemOrObjectId) , (itemOrObjectId) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onReparent , void , (S32 itemOrObjectId, S32 oldParentItemOrObjectId, S32 newParentItemOrObjectId) , (itemOrObjectId, oldParentItemOrObjectId, newParentItemOrObjectId) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onRightMouseDown , void , (S32 itemId, const Point2I &mousePos, SimObject *object) , (itemId, mousePos, object) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onRightMouseUp , void , (S32 itemId, const Point2I &mousePos, SimObject *object) , (itemId, mousePos, object) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onSelect , void , (S32 itemOrObjectId) , (itemOrObjectId) , "" )
IMPLEMENT_CALLBACK(GuiTreeViewCtrl , onUnselect , void , (S32 itemOrObjectId) , (itemOrObjectId) , "" )
IMPLEMENT_CONOBJECT(GuiTreeViewCtrl )
itemCompareCaseInsensitive(const void * a, const void * b)
itemCompareCaseSensitive(const void * a, const void * b)
itemSortList(GuiTreeViewCtrl::Item *& firstChild, bool caseSensitive, bool traverseHierarchy, bool parentsFirst)
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "gui/controls/guiTreeViewCtrl.h" 26 27#include "core/frameAllocator.h" 28#include "core/strings/findMatch.h" 29#include "gui/containers/guiScrollCtrl.h" 30#include "gui/worldEditor/editorIconRegistry.h" 31#include "console/consoleTypes.h" 32#include "console/console.h" 33#include "gui/core/guiTypes.h" 34#include "gfx/gfxDrawUtil.h" 35#include "gui/controls/guiTextEditCtrl.h" 36#ifdef TORQUE_TOOLS 37 #include "gui/editor/editorFunctions.h" 38#endif 39#include "console/engineAPI.h" 40 41IMPLEMENT_CONOBJECT(GuiTreeViewCtrl); 42 43ConsoleDocClass( GuiTreeViewCtrl, 44 "@brief Hierarchical list of text items with optional icons.\n\n" 45 46 "Can also be used to inspect SimObject hierarchies, primarily within editors.\n\n" 47 48 "GuiTreeViewCtrls can either display arbitrary user-defined trees or can be used to display SimObject hierarchies where " 49 "each parent node in the tree is a SimSet or SimGroup and each leaf node is a SimObject.\n\n" 50 51 "Each item in the tree has a text and a value. For trees that display SimObject hierarchies, the text for each item " 52 "is automatically derived from objects while the value for each item is the ID of the respective SimObject. For trees " 53 "that are not tied to SimObjects, both text and value of each item are set by the user.\n\n" 54 55 "Additionally, items in the tree can have icons.\n\n" 56 57 "Each item in the tree has a distinct numeric ID that is unique within its tree. The ID of the root item, which is always " 58 "present on a tree, is 0.\n\n" 59 60 "@tsexample\n" 61 "new GuiTreeViewCtrl(DatablockEditorTree)\n" 62 "{\n" 63 " tabSize = \"16\";\n" 64 " textOffset = \"2\";\n" 65 " fullRowSelect = \"0\";\n" 66 " itemHeight = \"21\";\n" 67 " destroyTreeOnSleep = \"0\";\n" 68 " MouseDragging = \"0\";\n" 69 " MultipleSelections = \"1\";\n" 70 " DeleteObjectAllowed = \"1\";\n" 71 " DragToItemAllowed = \"0\";\n" 72 " ClearAllOnSingleSelection = \"1\";\n" 73 " showRoot = \"1\";\n" 74 " internalNamesOnly = \"0\";\n" 75 " objectNamesOnly = \"0\";\n" 76 " compareToObjectID = \"0\";\n" 77 " Profile = \"GuiTreeViewProfile\";\n" 78 " tooltipprofile = \"GuiToolTipProfile\";\n" 79 " hovertime = \"1000\";\n" 80 "};\n" 81 "@endtsexample\n\n" 82 83 "@ingroup GuiContainers\n"); 84 85IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onDeleteObject, bool, ( SimObject* object ), ( object ), "" ); 86IMPLEMENT_CALLBACK( GuiTreeViewCtrl, isValidDragTarget, bool, ( S32 id, const char* value ), ( id, value ), "" ); 87IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onDefineIcons, void, (), (), "" ); 88IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onAddGroupSelected, void, ( SimGroup* group ), ( group ), "" ); 89IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onAddSelection, void, ( S32 itemOrObjectId, bool isLastSelection ), ( itemOrObjectId, isLastSelection ), "" ); 90IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onSelect, void, ( S32 itemOrObjectId ), ( itemOrObjectId ), "" ); 91IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onInspect, void, ( S32 itemOrObjectId ), ( itemOrObjectId ), "" ); 92IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onRemoveSelection, void, ( S32 itemOrObjectId ), ( itemOrObjectId ), "" ); 93IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onUnselect, void, ( S32 itemOrObjectId ), ( itemOrObjectId ), "" ); 94IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onDeleteSelection, void, (), (), "" ); 95IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onObjectDeleteCompleted, void, (), (), "" ); 96IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onKeyDown, void, ( S32 modifier, S32 keyCode ), ( modifier, keyCode ), "" ); 97IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onMouseUp, void, ( S32 hitItemId, S32 mouseClickCount ), ( hitItemId, mouseClickCount ), "" ); 98IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onMouseDragged, void, (), (), "" ); 99IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onRightMouseDown, void, ( S32 itemId, const Point2I& mousePos, SimObject* object ), ( itemId, mousePos, object ), "" ); 100IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onRightMouseUp, void, ( S32 itemId, const Point2I& mousePos, SimObject* object ), ( itemId, mousePos, object ), "" ); 101IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onBeginReparenting, void, (), (), "" ); 102IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onEndReparenting, void, (), (), "" ); 103IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onReparent, void, ( S32 itemOrObjectId, S32 oldParentItemOrObjectId, S32 newParentItemOrObjectId ), ( itemOrObjectId, oldParentItemOrObjectId, newParentItemOrObjectId ), "" ); 104IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onDragDropped, void, (), (), "" ); 105IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onAddMultipleSelectionBegin, void, (), (), "" ); 106IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onAddMultipleSelectionEnd, void, (), (), "" ); 107IMPLEMENT_CALLBACK( GuiTreeViewCtrl, canRenameObject, bool, ( SimObject* object ), ( object ), "" ); 108IMPLEMENT_CALLBACK( GuiTreeViewCtrl, handleRenameObject, bool, ( const char* newName, SimObject* object ), ( newName, object ), "" ); 109IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onClearSelection, void, (), (), "" ); 110 111 112static S32 QSORT_CALLBACK itemCompareCaseSensitive( const void *a, const void *b ) 113{ 114 GuiTreeViewCtrl::Item* itemA = *( ( GuiTreeViewCtrl::Item** ) a ); 115 GuiTreeViewCtrl::Item* itemB = *( ( GuiTreeViewCtrl::Item** ) b ); 116 117 char bufferA[ 1024 ]; 118 char bufferB[ 1024 ]; 119 120 itemA->getDisplayText( sizeof( bufferA ), bufferA ); 121 itemB->getDisplayText( sizeof( bufferB ), bufferB ); 122 123 return dStrnatcmp( bufferA, bufferB ); 124} 125 126static S32 QSORT_CALLBACK itemCompareCaseInsensitive( const void *a, const void *b ) 127{ 128 GuiTreeViewCtrl::Item* itemA = *( ( GuiTreeViewCtrl::Item** ) a ); 129 GuiTreeViewCtrl::Item* itemB = *( ( GuiTreeViewCtrl::Item** ) b ); 130 131 char bufferA[ 1024 ]; 132 char bufferB[ 1024 ]; 133 134 itemA->getDisplayText( sizeof( bufferA ), bufferA ); 135 itemB->getDisplayText( sizeof( bufferB ), bufferB ); 136 137 return dStrnatcasecmp( bufferA, bufferB ); 138} 139 140static void itemSortList( GuiTreeViewCtrl::Item*& firstChild, bool caseSensitive, bool traverseHierarchy, bool parentsFirst ) 141{ 142 // Sort the children. 143 // Do this in a separate scope, so we release the buffers before 144 // recursing. 145 146 { 147 Vector< GuiTreeViewCtrl::Item*> parents; 148 Vector< GuiTreeViewCtrl::Item*> items; 149 150 // Put all items into the two vectors. 151 152 for( GuiTreeViewCtrl::Item* item = firstChild; item != NULL; item = item->mNext ) 153 if( parentsFirst && item->isParent() ) 154 parents.push_back( item ); 155 else 156 items.push_back( item ); 157 158 // Sort both vectors. 159 160 dQsort( parents.address(), parents.size(), sizeof( GuiTreeViewCtrl::Item* ), caseSensitive ? itemCompareCaseSensitive : itemCompareCaseInsensitive ); 161 dQsort( items.address(), items.size(), sizeof( GuiTreeViewCtrl::Item* ), caseSensitive ? itemCompareCaseSensitive : itemCompareCaseInsensitive ); 162 163 // Wipe current child chain then reconstruct it in reverse 164 // as we prepend items. 165 166 firstChild = NULL; 167 168 // Add child items. 169 170 for( U32 i = items.size(); i > 0; -- i ) 171 { 172 GuiTreeViewCtrl::Item* child = items[ i - 1 ]; 173 174 child->mNext = firstChild; 175 if( firstChild ) 176 firstChild->mPrevious = child; 177 178 firstChild = child; 179 } 180 181 // Add parent child items, if requested. 182 183 for( U32 i = parents.size(); i > 0; -- i ) 184 { 185 GuiTreeViewCtrl::Item* child = parents[ i - 1 ]; 186 187 child->mNext = firstChild; 188 if( firstChild ) 189 firstChild->mPrevious = child; 190 191 firstChild = child; 192 } 193 194 firstChild->mPrevious = NULL; 195 } 196 197 // Traverse hierarchy, if requested. 198 199 if( traverseHierarchy ) 200 { 201 GuiTreeViewCtrl::Item* child = firstChild; 202 while( child ) 203 { 204 if( child->isParent() ) 205 child->sort( caseSensitive, traverseHierarchy, parentsFirst ); 206 207 child = child->mNext; 208 } 209 } 210} 211 212 213//============================================================================= 214// GuiTreeViewCtrl::Item. 215//============================================================================= 216// MARK: ---- GuiTreeViewCtrl::Item ---- 217 218//----------------------------------------------------------------------------- 219 220GuiTreeViewCtrl::Item::Item( GuiTreeViewCtrl* parent, GuiControlProfile *pProfile ) 221{ 222 AssertFatal( pProfile != NULL , "Cannot create a tree item without a valid tree and control profile!"); 223 mParentControl = parent; 224 mState = 0; 225 mId = -1; 226 mTabLevel = 0; 227 mIcon = 0; 228 mDataRenderWidth = 0; 229 mParent = NULL; 230 mChild = NULL; 231 mNext = NULL; 232 mPrevious = NULL; 233 mProfile = pProfile; 234 235 mScriptInfo.mNormalImage = BmpCon; 236 mScriptInfo.mExpandedImage = BmpExp; 237 mScriptInfo.mText = NULL; 238 mScriptInfo.mValue = NULL; 239} 240 241//----------------------------------------------------------------------------- 242 243GuiTreeViewCtrl::Item::~Item() 244{ 245 _disconnectMonitors(); 246} 247 248//----------------------------------------------------------------------------- 249 250void GuiTreeViewCtrl::Item::_connectMonitors() 251{ 252 if( mInspectorInfo.mObject != NULL ) 253 { 254 SimSet* set = dynamic_cast< SimSet* >( mInspectorInfo.mObject.getPointer() ); 255 if( set ) 256 set->getSetModificationSignal().notify( mParentControl, &GuiTreeViewCtrl::_onInspectorSetObjectModified ); 257 } 258} 259 260//----------------------------------------------------------------------------- 261 262void GuiTreeViewCtrl::Item::_disconnectMonitors() 263{ 264 if( mInspectorInfo.mObject != NULL ) 265 { 266 SimSet* set = dynamic_cast< SimSet* >( mInspectorInfo.mObject.getPointer() ); 267 if( set ) 268 set->getSetModificationSignal().remove( mParentControl, &GuiTreeViewCtrl::_onInspectorSetObjectModified ); 269 } 270} 271 272//----------------------------------------------------------------------------- 273 274void GuiTreeViewCtrl::Item::setNormalImage(S8 id) 275{ 276 if(mState.test(InspectorData)) 277 { 278 Con::errorf("Tried to set normal image %d for item %d, which is InspectorData!", id, mId); 279 return; 280 } 281 282 mScriptInfo.mNormalImage = id; 283} 284 285//----------------------------------------------------------------------------- 286 287void GuiTreeViewCtrl::Item::setExpandedImage(S8 id) 288{ 289 if(mState.test(InspectorData)) 290 { 291 Con::errorf("Tried to set expanded image %d for item %d, which is InspectorData!", id, mId); 292 return; 293 } 294 295 mScriptInfo.mExpandedImage = id; 296} 297 298//----------------------------------------------------------------------------- 299 300void GuiTreeViewCtrl::Item::setText(StringTableEntry txt) 301{ 302 if(mState.test(InspectorData)) 303 { 304 Con::errorf("Tried to set text for item %d, which is InspectorData!", mId); 305 return; 306 } 307 308 mScriptInfo.mText = txt; 309 310 311 // Update Render Data 312 if( !mProfile.isNull() ) 313 mDataRenderWidth = getDisplayTextWidth( mProfile->mFont ); 314 315} 316 317//----------------------------------------------------------------------------- 318 319void GuiTreeViewCtrl::Item::setValue(StringTableEntry val) 320{ 321 if(mState.test(InspectorData)) 322 { 323 Con::errorf("Tried to set value for item %d, which is InspectorData!", mId); 324 return; 325 } 326 327 mScriptInfo.mValue = const_cast<char*>(val); // mValue really ought to be a StringTableEntry 328 329 // Update Render Data 330 if( !mProfile.isNull() ) 331 mDataRenderWidth = getDisplayTextWidth( mProfile->mFont ); 332 333} 334 335//----------------------------------------------------------------------------- 336 337S8 GuiTreeViewCtrl::Item::getNormalImage() const 338{ 339 if(mState.test(InspectorData)) 340 { 341 Con::errorf("Tried to get the normal image for item %d, which is InspectorData!", mId); 342 return 0; // fail safe for width determinations 343 } 344 345 return mScriptInfo.mNormalImage; 346} 347 348//----------------------------------------------------------------------------- 349 350S8 GuiTreeViewCtrl::Item::getExpandedImage() const 351{ 352 if(mState.test(InspectorData)) 353 { 354 Con::errorf("Tried to get the expanded image for item %d, which is InspectorData!", mId); 355 return 0; // fail safe for width determinations 356 } 357 358 return mScriptInfo.mExpandedImage; 359} 360 361//----------------------------------------------------------------------------- 362 363StringTableEntry GuiTreeViewCtrl::Item::getText() 364{ 365 if(mState.test(InspectorData)) 366 { 367 Con::errorf("Tried to get the text for item %d, which is InspectorData!", mId); 368 return NULL; 369 } 370 371 return ( mScriptInfo.mText ) ? mScriptInfo.mText : StringTable->EmptyString(); 372} 373 374//----------------------------------------------------------------------------- 375 376StringTableEntry GuiTreeViewCtrl::Item::getValue() 377{ 378 if(mState.test(InspectorData)) 379 { 380 Con::errorf("Tried to get the value for item %d, which is InspectorData!", mId); 381 return NULL; 382 } 383 384 return ( mScriptInfo.mValue ) ? mScriptInfo.mValue : StringTable->EmptyString(); 385} 386 387//----------------------------------------------------------------------------- 388 389void GuiTreeViewCtrl::Item::setObject(SimObject *obj) 390{ 391 if(!mState.test(InspectorData)) 392 { 393 return; 394 } 395 396 _disconnectMonitors(); 397 mInspectorInfo.mObject = obj; 398 _connectMonitors(); 399 400 // Update Render Data 401 if( !mProfile.isNull() ) 402 mDataRenderWidth = getDisplayTextWidth( mProfile->mFont ); 403} 404 405//----------------------------------------------------------------------------- 406 407SimObject *GuiTreeViewCtrl::Item::getObject() 408{ 409 if(!mState.test(InspectorData)) 410 { 411 return NULL; 412 } 413 414 return mInspectorInfo.mObject; 415} 416 417//----------------------------------------------------------------------------- 418 419U32 GuiTreeViewCtrl::Item::getDisplayTextLength() 420{ 421 if( mState.test( InspectorData ) ) 422 { 423 SimObject *obj = getObject(); 424 if( !obj ) 425 return 0; 426 427 StringTableEntry name = obj->getName(); 428 StringTableEntry internalName = obj->getInternalName(); 429 StringTableEntry className = obj->getClassName(); 430 431 if( showInternalNameOnly() ) 432 { 433 if( internalName && internalName[ 0 ] ) 434 return dStrlen( internalName ); 435 else 436 return dStrlen( "(none)" ); 437 } 438 else if( showObjectNameOnly() ) 439 { 440 if( name && name[ 0 ] ) 441 return dStrlen( name ); 442 else if( mState.test( ShowClassNameForUnnamed ) ) 443 return dStrlen( className ); 444 else 445 return dStrlen( "(none)" ); 446 } 447 448 dsize_t len = 0; 449 if( mState.test( ShowObjectId ) ) 450 len += dStrlen( obj->getIdString() ) + 2; // '<id>: ' 451 if( mState.test( ShowClassName ) ) 452 { 453 if( name && name[ 0 ] ) 454 len += dStrlen( className ) + 3; // '<class> - ' 455 else 456 len += dStrlen( className ); 457 } 458 if( mState.test( ShowObjectName ) ) 459 { 460 if( name && name[ 0 ] ) 461 len += dStrlen( name ); 462 else if( mState.test( ShowClassNameForUnnamed ) ) 463 len += dStrlen( className ); 464 } 465 if( mState.test( ShowInternalName ) ) 466 { 467 if( internalName && internalName[ 0 ] ) 468 len += dStrlen( internalName ) + 3; // ' [<internalname>]' 469 } 470 471 return len; 472 } 473 474 StringTableEntry pText = getText(); 475 if( pText == NULL ) 476 return 0; 477 478 return dStrlen( pText ); 479} 480 481//----------------------------------------------------------------------------- 482 483void GuiTreeViewCtrl::Item::getDisplayText(U32 bufLen, char *buf) 484{ 485 FrameAllocatorMarker txtAlloc; 486 487 //if we're doing the special case of forcing the item text, just skip the rest of this junk 488 if (mState.test(ForceItemName)) 489 { 490 StringTableEntry text = (mScriptInfo.mText) ? mScriptInfo.mText : StringTable->EmptyString(); 491 dStrncpy(buf, text, bufLen); 492 return; 493 } 494 495 if( mState.test( InspectorData ) ) 496 { 497 SimObject *pObject = getObject(); 498 if( pObject ) 499 { 500 const char* pObjName = pObject->getName(); 501 const char* pInternalName = pObject->getInternalName(); 502 503 bool hasInternalName = pInternalName && pInternalName[0]; 504 bool hasObjectName = pObjName && pObjName[0]; 505 506 const char* pClassName = pObject->getClassName(); 507 508 if( showInternalNameOnly() ) 509 dSprintf( buf, bufLen, "%s", hasInternalName ? pInternalName : "(none)" ); 510 else if( showObjectNameOnly() ) 511 { 512 if( !hasObjectName && mState.test( ShowClassNameForUnnamed ) ) 513 dSprintf( buf, bufLen, "%s", pClassName ); 514 else 515 dSprintf( buf, bufLen, "%s", hasObjectName ? pObjName : "(none)" ); 516 } 517 else 518 { 519 char* ptr = buf; 520 int len = bufLen; 521 522 if( mState.test( ShowObjectId ) ) 523 { 524 S32 n = dSprintf( ptr, len, "%d: ", pObject->getId() ); 525 ptr += n; 526 len -= n; 527 } 528 529 if( mState.test( ShowClassName ) ) 530 { 531 S32 n; 532 if( hasObjectName && mState.test( ShowObjectName ) ) 533 n = dSprintf( ptr, len, "%s - ", pClassName ); 534 else 535 n = dSprintf( ptr, len, "%s", pClassName ); 536 537 ptr += n; 538 len -= n; 539 } 540 541 if( mState.test( ShowObjectName ) ) 542 { 543 S32 n = 0; 544 if (hasObjectName) 545 { 546 //If it's been marked, reflect that 547 if (mState.test(Item::Marked)) 548 n = dSprintf(ptr, len, "*%s", pObjName); 549 else 550 n = dSprintf(ptr, len, "%s", pObjName); 551 } 552 else if( mState.test( ShowClassNameForUnnamed ) ) 553 n = dSprintf( ptr, len, "%s", pClassName ); 554 555 ptr += n; 556 len -= n; 557 } 558 559 if (hasInternalName && mState.test(ShowInternalName)) 560 { 561 if (mState.test(Item::Marked)) 562 dSprintf(ptr, len, " *[%s]", pInternalName); 563 else 564 dSprintf(ptr, len, " [%s]", pInternalName); 565 } 566 } 567 } 568 else 569 buf[ 0 ] = '\0'; 570 } 571 else 572 { 573 // Script data! (copy it in) 574 dStrncpy(buf, getText(), bufLen); 575 } 576} 577 578//----------------------------------------------------------------------------- 579 580S32 GuiTreeViewCtrl::Item::getDisplayTextWidth(GFont *font) 581{ 582 if( !font ) 583 return 0; 584 585 FrameAllocatorMarker txtAlloc; 586 U32 bufLen = getDisplayTextLength(); 587 if( bufLen == 0 ) 588 return 0; 589 590 // Add space for the string terminator 591 bufLen++; 592 593 char *buf = (char*)txtAlloc.alloc(bufLen); 594 getDisplayText(bufLen, buf); 595 596 return font->getStrWidth(buf); 597} 598 599//----------------------------------------------------------------------------- 600 601bool GuiTreeViewCtrl::Item::hasObjectBasedTooltip() 602{ 603 if(mState.test(Item::InspectorData)) 604 { 605 SimObject *pObject = getObject(); 606 if(pObject) 607 { 608 const char* pClassName = pObject->getClassName(); 609 610 // Retrieve custom tooltip string 611 String method("GetTooltip"); 612 method += pClassName; 613 if(mParentControl->isMethod(method.c_str())) 614 { 615 return true; 616 } 617 } 618 } 619 620 return false; 621} 622 623//----------------------------------------------------------------------------- 624 625void GuiTreeViewCtrl::Item::getTooltipText(U32 bufLen, char *buf) 626{ 627 getDisplayText(bufLen, buf); 628 629 if(mState.test(Item::InspectorData)) 630 { 631 SimObject *pObject = getObject(); 632 if(pObject) 633 { 634 const char* pClassName = pObject->getClassName(); 635 636 // Retrieve custom tooltip string 637 String method("GetTooltip"); 638 method += pClassName; 639 if(mParentControl->isMethod(method.c_str())) 640 { 641 const char* tooltip = Con::executef( mParentControl, method.c_str(), pObject->getIdString() ); 642 dsize_t len = dStrlen(buf); 643 S32 newBufLen = bufLen-len; 644 if(dStrlen(tooltip) > 0 && newBufLen > 0) 645 { 646 dSprintf(buf+len, newBufLen, "\n%s", tooltip); 647 } 648 } 649 } 650 } 651} 652 653//----------------------------------------------------------------------------- 654 655bool GuiTreeViewCtrl::Item::isParent() const 656{ 657 if(mState.test(VirtualParent)) 658 { 659 if( !isInspectorData() ) 660 return true; 661 662 // Does our object have any children? 663 if(mInspectorInfo.mObject) 664 { 665 SimSet *pSimSet = dynamic_cast<SimSet*>( (SimObject*)mInspectorInfo.mObject); 666 if ( pSimSet != NULL && pSimSet->size() > 0) 667 return pSimSet->size(); 668 } 669 } 670 671 // Otherwise, just return whether the child list is populated. 672 return mChild; 673} 674 675//----------------------------------------------------------------------------- 676 677bool GuiTreeViewCtrl::Item::isExpanded() const 678{ 679 if(mState.test(InspectorData)) 680 return mInspectorInfo.mObject ? mInspectorInfo.mObject->isExpanded() : false; 681 else 682 return mState.test(Expanded); 683} 684 685//----------------------------------------------------------------------------- 686 687void GuiTreeViewCtrl::Item::setExpanded(bool f) 688{ 689 if( mState.test(InspectorData) ) 690 { 691 if( !mInspectorInfo.mObject.isNull() ) 692 mInspectorInfo.mObject->setExpanded(f); 693 } 694 else 695 mState.set(Expanded, f); 696} 697 698//----------------------------------------------------------------------------- 699 700void GuiTreeViewCtrl::Item::setVirtualParent( bool value ) 701{ 702 mState.set(VirtualParent, value); 703} 704 705//----------------------------------------------------------------------------- 706 707GuiTreeViewCtrl::Item* GuiTreeViewCtrl::Item::findChildByName( const char* name ) 708{ 709 Item* child = mChild; 710 while( child ) 711 { 712 if( dStricmp( child->mScriptInfo.mText, name ) == 0 ) 713 return child; 714 715 child = child->mNext; 716 } 717 718 return NULL; 719} 720 721//----------------------------------------------------------------------------- 722 723GuiTreeViewCtrl::Item *GuiTreeViewCtrl::Item::findChildByValue(const SimObject *obj) 724{ 725 // Iterate over our children and try to find the given 726 // SimObject 727 728 Item *pResultObj = mChild; 729 730 while(pResultObj) 731 { 732 // CodeReview this check may need to be removed 733 // if we want to use the tree for data that 734 // isn't related to SimObject based objects with 735 // arbitrary values associated with them [5/5/2007 justind] 736 737 // Skip non-inspector data stuff. 738 if(pResultObj->mState.test(InspectorData)) 739 { 740 if(pResultObj->getObject() == obj) 741 break; // Whoa. 742 } 743 pResultObj = pResultObj->mNext; 744 } 745 // If the loop terminated we are NULL, otherwise we have the result in res. 746 return pResultObj; 747} 748 749//----------------------------------------------------------------------------- 750 751GuiTreeViewCtrl::Item *GuiTreeViewCtrl::Item::findChildByValue( StringTableEntry Value ) 752{ 753 // Iterate over our children and try to find the given Value 754 // Note : This is a case-insensitive search 755 Item *pResultObj = mChild; 756 757 while(pResultObj) 758 { 759 760 // check the script value of the item against the specified value 761 if( pResultObj->mScriptInfo.mValue != NULL && dStricmp( pResultObj->mScriptInfo.mValue, Value ) == 0 ) 762 return pResultObj; 763 pResultObj = pResultObj->mNext; 764 } 765 // If the loop terminated we didn't find an item with the specified script value 766 return NULL; 767} 768 769//----------------------------------------------------------------------------- 770 771void GuiTreeViewCtrl::Item::sort( bool caseSensitive, bool traverseHierarchy, bool parentsFirst ) 772{ 773 itemSortList( mChild, caseSensitive, traverseHierarchy, parentsFirst ); 774} 775 776//============================================================================= 777// GuiTreeViewCtrl. 778//============================================================================= 779// MARK: ---- GuiTreeViewCtrl ---- 780 781//----------------------------------------------------------------------------- 782 783GuiTreeViewCtrl::GuiTreeViewCtrl() 784{ 785 VECTOR_SET_ASSOCIATION(mItems); 786 VECTOR_SET_ASSOCIATION(mVisibleItems); 787 VECTOR_SET_ASSOCIATION(mSelectedItems); 788 VECTOR_SET_ASSOCIATION(mSelected); 789 790 mItemFreeList = NULL; 791 mRoot = NULL; 792 mItemCount = 0; 793 mSelectedItem = 0; 794 mStart = 0; 795 mPossibleRenameItem = NULL; 796 mRenamingItem = NULL; 797 mTempItem = NULL; 798 mRenameCtrl = NULL; 799 800 mDraggedToItem = 0; 801 mCurrentDragCell = 0; 802 mPreviousDragCell = 0; 803 mDragMidPoint = NomDragMidPoint; 804 mMouseDragged = false; 805 mDebug = false; 806 807 // persist info.. 808 mTabSize = 16; 809 mTextOffset = 2; 810 mFullRowSelect = false; 811 mItemHeight = 20; 812 813 // 814 setSize(Point2I(1, 0)); 815 816 // Set up default state 817 mFlags.set(ShowTreeLines); 818 mFlags.set(IsEditable, false); 819 820 mDestroyOnSleep = true; 821 mSupportMouseDragging = true; 822 mMultipleSelections = true; 823 mDeleteObjectAllowed = true; 824 mDragToItemAllowed = true; 825 mShowRoot = true; 826 mUseInspectorTooltips = false; 827 mTooltipOnWidthOnly = false; 828 mCompareToObjectID = true; 829 mShowObjectIds = true; 830 mShowClassNames = true; 831 mShowObjectNames = true; 832 mShowInternalNames = true; 833 mShowClassNameForUnnamedObjects = false; 834 mFlags.set(RebuildVisible); 835 836 mCanRenameObjects = true; 837 mRenameInternal = false; 838 839 mClearAllOnSingleSelection = true; 840 841 mBitmapBase = StringTable->EmptyString(); 842 mTexRollover = NULL; 843 mTexSelected = NULL; 844 845 mRenderTooltipDelegate.bind( this, &GuiTreeViewCtrl::renderTooltip ); 846 847 mDoFilterChildren = true; 848} 849 850//----------------------------------------------------------------------------- 851 852GuiTreeViewCtrl::~GuiTreeViewCtrl() 853{ 854 _destroyTree(); 855} 856 857//------------------------------------------------------------------------------ 858 859void GuiTreeViewCtrl::initPersistFields() 860{ 861 addGroup( "TreeView" ); 862 863 addField( "tabSize", TypeS32, Offset(mTabSize, GuiTreeViewCtrl)); 864 addField( "textOffset", TypeS32, Offset(mTextOffset, GuiTreeViewCtrl)); 865 addField( "fullRowSelect", TypeBool, Offset(mFullRowSelect, GuiTreeViewCtrl)); 866 addField( "itemHeight", TypeS32, Offset(mItemHeight, GuiTreeViewCtrl)); 867 addField( "destroyTreeOnSleep", TypeBool, Offset(mDestroyOnSleep, GuiTreeViewCtrl), 868 "If true, the entire tree item hierarchy is deleted when the control goes to sleep." ); 869 addField( "mouseDragging", TypeBool, Offset(mSupportMouseDragging, GuiTreeViewCtrl)); 870 addField( "multipleSelections", TypeBool, Offset(mMultipleSelections, GuiTreeViewCtrl), 871 "If true, multiple items can be selected concurrently." ); 872 addField( "deleteObjectAllowed", TypeBool, Offset(mDeleteObjectAllowed, GuiTreeViewCtrl)); 873 addField( "dragToItemAllowed", TypeBool, Offset(mDragToItemAllowed, GuiTreeViewCtrl)); 874 addField( "clearAllOnSingleSelection", TypeBool, Offset(mClearAllOnSingleSelection, GuiTreeViewCtrl)); 875 addField( "showRoot", TypeBool, Offset(mShowRoot, GuiTreeViewCtrl), 876 "If true, the root item is shown in the tree." ); 877 addField( "useInspectorTooltips", TypeBool, Offset(mUseInspectorTooltips, GuiTreeViewCtrl)); 878 addField( "tooltipOnWidthOnly", TypeBool, Offset(mTooltipOnWidthOnly, GuiTreeViewCtrl)); 879 880 endGroup( "TreeView" ); 881 882 addGroup( "Inspector Trees" ); 883 884 addField( "showObjectIds", TypeBool, Offset( mShowObjectIds, GuiTreeViewCtrl ), 885 "If true, item text labels for objects will include object IDs." ); 886 addField( "showClassNames", TypeBool, Offset( mShowClassNames, GuiTreeViewCtrl ), 887 "If true, item text labels for objects will include class names." ); 888 addField( "showObjectNames", TypeBool, Offset( mShowObjectNames, GuiTreeViewCtrl ), 889 "If true, item text labels for objects will include object names." ); 890 addField( "showInternalNames", TypeBool, Offset( mShowInternalNames, GuiTreeViewCtrl ), 891 "If true, item text labels for obje ts will include internal names." ); 892 addField( "showClassNameForUnnamedObjects", TypeBool, Offset( mShowClassNameForUnnamedObjects, GuiTreeViewCtrl ), 893 "If true, class names will be used as object names for unnamed objects." ); 894 addField( "compareToObjectID", TypeBool, Offset(mCompareToObjectID, GuiTreeViewCtrl)); 895 addField( "canRenameObjects", TypeBool, Offset(mCanRenameObjects, GuiTreeViewCtrl), 896 "If true clicking on a selected item ( that is an object and not the root ) will allow you to rename it." ); 897 addField( "renameInternal", TypeBool, Offset(mRenameInternal, GuiTreeViewCtrl), 898 "If true then object renaming operates on the internalName rather than the object name." ); 899 900 endGroup( "Inspector Trees" ); 901 902 Parent::initPersistFields(); 903} 904 905//------------------------------------------------------------------------------ 906 907GuiTreeViewCtrl::Item * GuiTreeViewCtrl::getItem(S32 itemId) const 908{ 909 if ( itemId > 0 && itemId <= mItems.size() ) 910 return mItems[itemId-1]; 911 return NULL; 912} 913 914//------------------------------------------------------------------------------ 915 916GuiTreeViewCtrl::Item * GuiTreeViewCtrl::createItem(S32 icon) 917{ 918 Item * pNewItem = NULL; 919 920 // grab from the free list? 921 if( mItemFreeList ) 922 { 923 pNewItem = mItemFreeList; 924 mItemFreeList = pNewItem->mNext; 925 926 // re-add to vector 927 mItems[ pNewItem->mId - 1 ] = pNewItem; 928 } 929 else 930 { 931 pNewItem = new Item( this, mProfile ); 932 933 AssertFatal( pNewItem != NULL, "Fatal : unable to allocate tree item!"); 934 935 mItems.push_back( pNewItem ); 936 937 // set the id 938 pNewItem->mId = mItems.size(); 939 } 940 941 // reset 942 if (icon) 943 pNewItem->mIcon = icon; 944 else 945 pNewItem->mIcon = Default; //default icon to stick next to an item 946 947 pNewItem->mState = Item::ShowObjectId | Item::ShowClassName | Item::ShowObjectName | Item::ShowInternalName; 948 pNewItem->mTabLevel = 0; 949 950 // Null out item pointers 951 pNewItem->mNext = 0; 952 pNewItem->mPrevious = 0; 953 pNewItem->mChild = 0; 954 pNewItem->mParent = 0; 955 956 mItemCount++; 957 958 return pNewItem; 959} 960 961//------------------------------------------------------------------------------ 962 963void GuiTreeViewCtrl::_destroyChildren( Item* item, Item* parent, bool deleteObjects ) 964{ 965 if ( !item || item == parent || !mItems[item->mId-1] ) 966 return; 967 968 // destroy depth first, then siblings from last to first 969 if ( item->isParent() && item->mChild ) 970 _destroyChildren(item->mChild, item, deleteObjects); 971 if( item->mNext ) 972 _destroyChildren(item->mNext, parent, deleteObjects); 973 974 // destroy the item 975 _destroyItem( item, deleteObjects ); 976} 977 978//----------------------------------------------------------------------------- 979 980void GuiTreeViewCtrl::_destroyItem( Item* item, bool deleteObject ) 981{ 982 if(!item) 983 return; 984 985 if(item->isInspectorData()) 986 { 987 // make sure the SimObjectPtr is clean! 988 SimObject *pObject = item->getObject(); 989 if( pObject && pObject->isProperlyAdded() ) 990 { 991 bool skipDelete = !deleteObject; 992 993 if( !skipDelete && isMethod( "onDeleteObject" ) ) 994 skipDelete = onDeleteObject_callback( pObject ); 995 996 if ( !skipDelete ) 997 pObject->deleteObject(); 998 } 999 1000 item->setObject( NULL ); 1001 } 1002 1003 // Remove item from the selection 1004 if (mSelectedItem == item->mId) 1005 mSelectedItem = 0; 1006 for ( S32 i = 0; i < mSelectedItems.size(); i++ ) 1007 { 1008 if ( mSelectedItems[i] == item ) 1009 { 1010 mSelectedItems.erase( i ); 1011 break; 1012 } 1013 } 1014 item->mState.clear(); 1015 1016 // unlink 1017 if( item->mPrevious ) 1018 item->mPrevious->mNext = item->mNext; 1019 if( item->mNext ) 1020 item->mNext->mPrevious = item->mPrevious; 1021 if( item->mParent && ( item->mParent->mChild == item ) ) 1022 item->mParent->mChild = item->mNext; 1023 1024 // remove from vector 1025 mItems[item->mId-1] = 0; 1026 1027 // set as root free item 1028 item->mNext = mItemFreeList; 1029 mItemFreeList = item; 1030 mItemCount--; 1031} 1032 1033//------------------------------------------------------------------------------ 1034 1035void GuiTreeViewCtrl::_deleteItem(Item *item) 1036{ 1037 removeItem(item->mId); 1038} 1039 1040//------------------------------------------------------------------------------ 1041 1042void GuiTreeViewCtrl::_destroyTree() 1043{ 1044 // clear the item list 1045 for(U32 i = 0; i < mItems.size(); i++) 1046 { 1047 Item *pFreeItem = mItems[ i ]; 1048 if( pFreeItem != NULL ) 1049 delete pFreeItem; 1050 } 1051 1052 mItems.clear(); 1053 1054 // clear the free list 1055 while(mItemFreeList) 1056 { 1057 Item *next = mItemFreeList->mNext; 1058 delete mItemFreeList; 1059 mItemFreeList = next; 1060 } 1061 1062 mVisibleItems.clear(); 1063 mSelectedItems.clear(); 1064 1065 // 1066 mRoot = NULL; 1067 mItemFreeList = NULL; 1068 mItemCount = 0; 1069 mSelectedItem = 0; 1070 mDraggedToItem = 0; 1071 1072 mRenamingItem = NULL; 1073 mTempItem = NULL; 1074 mPossibleRenameItem = NULL; 1075} 1076 1077//------------------------------------------------------------------------------ 1078 1079void GuiTreeViewCtrl::_onInspectorSetObjectModified( SetModification modification, SimSet* set, SimObject* object ) 1080{ 1081 // Don't bother searching for the Item to see if it is actually visible and instead just 1082 // mark our tree state as dirty so we get a rebuild on the next render. 1083 1084 mFlags.set( RebuildVisible ); 1085} 1086 1087//------------------------------------------------------------------------------ 1088 1089GuiTreeViewCtrl::Item* GuiTreeViewCtrl::_findItemByAmbiguousId( S32 itemOrObjectId, bool buildVirtual ) 1090{ 1091 Item* item = getItem( itemOrObjectId ); 1092 if( item ) 1093 return item; 1094 1095 SimObject* object = Sim::findObject( itemOrObjectId ); 1096 if( object ) 1097 { 1098 // If we should expand virtual trees in order to find the item, 1099 // do so now. 1100 if( buildVirtual ) 1101 { 1102 if( mFlags.test( RebuildVisible ) ) 1103 buildVisibleTree(); 1104 1105 SimGroup* group = object->getGroup(); 1106 if( group ) 1107 _expandObjectHierarchy( group ); 1108 } 1109 1110 if( objectSearch( object, &item ) ) 1111 return item; 1112 } 1113 1114 return NULL; 1115} 1116 1117//------------------------------------------------------------------------------ 1118 1119void GuiTreeViewCtrl::_expandObjectHierarchy( SimGroup* group ) 1120{ 1121 SimGroup* parent = group->getGroup(); 1122 if( parent && !parent->isExpanded() ) 1123 _expandObjectHierarchy( parent ); 1124 1125 if( !group->isExpanded() ) 1126 { 1127 Item* item; 1128 if( objectSearch( group, &item ) ) 1129 { 1130 item->setExpanded(); 1131 onVirtualParentBuild( item, false ); 1132 } 1133 } 1134} 1135 1136//------------------------------------------------------------------------------ 1137 1138void GuiTreeViewCtrl::_buildItem( Item* item, U32 tabLevel, bool bForceFullUpdate, bool skipFlter ) 1139{ 1140 if (!item || !mActive || !isVisible() || !mProfile ) 1141 return; 1142 1143 // If it's inspector data, make sure we still have it, if not, kill it. 1144 if(item->isInspectorData() && !item->getObject() ) 1145 { 1146 removeItem(item->mId); 1147 return; 1148 } 1149 1150 // If it's a virtual parent, give a chance to update itself... 1151 if(item->mState.test( Item::VirtualParent) ) 1152 { 1153 // If it returns false the item has been removed. 1154 1155 if( !onVirtualParentBuild( item, bForceFullUpdate ) ) 1156 return; 1157 } 1158 1159 // If we have a filter pattern, sync the item's filtering status to it. 1160 1161 if( !getFilterText().isEmpty() && !skipFlter) 1162 { 1163 // Determine the filtering status by looking for the filter 1164 // text in the item's display text. 1165 1166 char displayText[ 2048 ]; 1167 item->getDisplayText( sizeof( displayText ), displayText ); 1168 if( !dStristr( displayText, mFilterText ) ) 1169 { 1170 //Last check, see if we special-exception this item 1171 if (!mItemFilterExceptionList.contains(item->mId)) 1172 item->mState.set(Item::Filtered); 1173 else 1174 item->mState.clear(Item::Filtered); 1175 1176 // If it's not a parent, we're done. Otherwise, there may be children 1177 // that are not filtered so we need to process them first. 1178 1179 if( !item->isParent() ) 1180 return; 1181 } 1182 else 1183 { 1184 item->mState.clear(Item::Filtered); 1185 } 1186 } 1187 else 1188 item->mState.clear( Item::Filtered ); 1189 1190 //If the item should be hidden from view, check now 1191 if (mHiddenItemsList.contains(item->mId)) 1192 item->mState.set(Item::Filtered); 1193 1194 // Is this the root item? 1195 const bool isRoot = item == mRoot; 1196 1197 // Add non-root items or the root if we're supposed to show it. 1198 1199 if( ( mShowRoot || !isRoot ) && 1200 !item->isFiltered() ) 1201 { 1202 item->mTabLevel = tabLevel; 1203 mVisibleItems.push_back( item ); 1204 1205 if( mProfile != NULL ) 1206 { 1207 mProfile->incLoadCount(); 1208 1209 S32 width = mTextOffset + ( mTabSize * item->mTabLevel ) + getInspectorItemIconsWidth( item ) + item->getDisplayTextWidth( mProfile->mFont ); 1210 1211 // check image 1212 S32 image = BmpChild; 1213 if ( item->isInspectorData() ) 1214 image = item->isExpanded() ? BmpExp : BmpCon; 1215 else 1216 image = item->isExpanded() ? item->getExpandedImage() : item->getNormalImage(); 1217 1218 if ( ( image >= 0 ) && ( image < mProfile->mBitmapArrayRects.size() ) ) 1219 width += mProfile->mBitmapArrayRects[image].extent.x; 1220 1221 if ( width > mMaxWidth ) 1222 mMaxWidth = width; 1223 1224 mProfile->decLoadCount(); 1225 } 1226 } 1227 1228 // If expanded or a hidden root, add all the 1229 // children items as well. 1230 1231 if ( item->isExpanded() || 1232 bForceFullUpdate || 1233 ( isRoot && !mShowRoot ) ) 1234 { 1235 Item* child = item->mChild; 1236 while ( child ) 1237 { 1238 // Bit of a hack so we can safely remove items as we 1239 // traverse. 1240 Item *pChildTemp = child; 1241 child = child->mNext; 1242 1243 if (!mItemFilterExceptionList.contains(item->mId) && !mDoFilterChildren && !item->isFiltered()) 1244 _buildItem( pChildTemp, tabLevel + 1, bForceFullUpdate, true ); 1245 else 1246 _buildItem(pChildTemp, tabLevel + 1, bForceFullUpdate, false); 1247 } 1248 } 1249} 1250 1251//------------------------------------------------------------------------------ 1252 1253void GuiTreeViewCtrl::buildVisibleTree(bool bForceFullUpdate) 1254{ 1255 // Recursion Prevention. 1256 if( mFlags.test( BuildingVisTree ) ) 1257 return; 1258 mFlags.set( BuildingVisTree, true ); 1259 1260 if( mDebug ) 1261 Con::printf( "Rebuilding visible tree" ); 1262 1263 mMaxWidth = 0; 1264 mVisibleItems.clear(); 1265 1266 // If we're filtering, force a full update. 1267 1268 if( !mFilterText.isEmpty() ) 1269 bForceFullUpdate = true; 1270 1271 // Update the flags. 1272 mFlags.clear(RebuildVisible); 1273 1274 // build the root items 1275 Item *traverse = mRoot; 1276 while(traverse) 1277 { 1278 _buildItem(traverse, 0, bForceFullUpdate); 1279 traverse = traverse->mNext; 1280 } 1281 1282 // adjust the GuiArrayCtrl 1283 mCellSize.set( mMaxWidth + mTextOffset, mItemHeight ); 1284 setSize(Point2I(1, mVisibleItems.size())); 1285 syncSelection(); 1286 1287 // Done Recursing. 1288 mFlags.clear( BuildingVisTree ); 1289} 1290 1291//------------------------------------------------------------------------------ 1292 1293bool GuiTreeViewCtrl::scrollVisible( S32 itemId ) 1294{ 1295 Item* item = getItem(itemId); 1296 if(item) 1297 return scrollVisible(item); 1298 1299 return false; 1300} 1301 1302//----------------------------------------------------------------------------- 1303 1304bool GuiTreeViewCtrl::scrollVisible( Item *item ) 1305{ 1306 // Now, make sure it's visible (ie, all parents expanded) 1307 Item *parent = item->mParent; 1308 1309 if( !item->isInspectorData() && item->mState.test(Item::VirtualParent) ) 1310 onVirtualParentExpand(item); 1311 1312 while(parent) 1313 { 1314 parent->setExpanded(true); 1315 1316 if( !parent->isInspectorData() && parent->mState.test(Item::VirtualParent) ) 1317 onVirtualParentExpand(parent); 1318 1319 parent = parent->mParent; 1320 } 1321 1322 // Get our scroll-pappy, if any. 1323 GuiScrollCtrl *pScrollParent = dynamic_cast<GuiScrollCtrl*>( getParent() ); 1324 1325 if ( !pScrollParent ) 1326 { 1327 Con::warnf("GuiTreeViewCtrl::scrollVisible - parent control is not a GuiScrollCtrl!"); 1328 return false; 1329 } 1330 1331 // And now, build the visible tree so we know where we have to scroll. 1332 if( mFlags.test( RebuildVisible ) ) 1333 buildVisibleTree(); 1334 1335 // All done, let's figure out where we have to scroll... 1336 for(S32 i=0; i<mVisibleItems.size(); i++) 1337 { 1338 if(mVisibleItems[i] == item) 1339 { 1340 // Fetch X Details. 1341 const S32 xPos = pScrollParent->getChildRelPos().x; 1342 const S32 xWidth = ( mMaxWidth - xPos ); 1343 1344 // Scroll to View the Item. 1345 // Note: Delta X should be 0 so that we maintain the X axis position. 1346 pScrollParent->scrollRectVisible( RectI( xPos, i * mItemHeight, xWidth, mItemHeight ) ); 1347 return true; 1348 } 1349 } 1350 1351 // If we got here, it's probably bad... 1352 Con::errorf("GuiTreeViewCtrl::scrollVisible - was unable to find specified item in visible list!"); 1353 return false; 1354} 1355 1356//------------------------------------------------------------------------------ 1357 1358S32 GuiTreeViewCtrl::insertItem(S32 parentId, const char * text, const char * value, const char * iconString, S16 normalImage, S16 expandedImage) 1359{ 1360 if( ( parentId < 0 ) || ( parentId > mItems.size() ) ) 1361 { 1362 Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::insertItem: invalid parent id!"); 1363 return 0; 1364 } 1365 1366 if((parentId != 0) && (mItems[parentId-1] == 0)) 1367 { 1368 Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::insertItem: parent item invalid!"); 1369 return 0; 1370 } 1371 1372 1373 const char * pItemText = ( text != NULL ) ? text : ""; 1374 const char * pItemValue = ( value != NULL ) ? value : ""; 1375 1376 S32 icon = getIcon(iconString); 1377 1378 // create an item (assigns id) 1379 Item * pNewItem = createItem(icon); 1380 if( pNewItem == NULL ) 1381 return 0; 1382 1383 pNewItem->setText( StringTable->insert( pItemText, true ) ); 1384 pNewItem->setValue( StringTable->insert( pItemValue, true ) ); 1385 1386 pNewItem->setNormalImage( normalImage ); 1387 pNewItem->setExpandedImage( expandedImage ); 1388 1389 // root level? 1390 if(parentId == 0) 1391 { 1392 // insert back 1393 if( mRoot != NULL ) 1394 { 1395 Item * pTreeTraverse = mRoot; 1396 while( pTreeTraverse != NULL && pTreeTraverse->mNext != NULL ) 1397 pTreeTraverse = pTreeTraverse->mNext; 1398 1399 pTreeTraverse->mNext = pNewItem; 1400 pNewItem->mPrevious = pTreeTraverse; 1401 } 1402 else 1403 mRoot = pNewItem; 1404 1405 mFlags.set(RebuildVisible); 1406 } 1407 else if( mItems.size() >= ( parentId - 1 ) ) 1408 { 1409 Item * pParentItem = mItems[parentId-1]; 1410 1411 // insert back 1412 if( pParentItem != NULL && pParentItem->mChild) 1413 { 1414 Item * pTreeTraverse = pParentItem->mChild; 1415 while( pTreeTraverse != NULL && pTreeTraverse->mNext != NULL ) 1416 pTreeTraverse = pTreeTraverse->mNext; 1417 1418 pTreeTraverse->mNext = pNewItem; 1419 pNewItem->mPrevious = pTreeTraverse; 1420 } 1421 else 1422 pParentItem->mChild = pNewItem; 1423 1424 pNewItem->mParent = pParentItem; 1425 1426 if( pParentItem->isExpanded() ) 1427 mFlags.set(RebuildVisible); 1428 } 1429 1430 return pNewItem->mId; 1431} 1432 1433//------------------------------------------------------------------------------ 1434 1435bool GuiTreeViewCtrl::removeItem( S32 itemId, bool deleteObjects ) 1436{ 1437 if( isSelected( itemId ) ) 1438 removeSelection( itemId ); 1439 1440 // tree? 1441 if(itemId == 0) 1442 { 1443 //RD: this does not delete objects and thus isn't coherent with the semantics of this method 1444 1445 _destroyTree(); 1446 return(true); 1447 } 1448 1449 Item * item = getItem(itemId); 1450 if(!item) 1451 { 1452 //Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::removeItem: invalid item id!"); 1453 return false; 1454 } 1455 1456 // root? 1457 if(item == mRoot) 1458 mRoot = item->mNext; 1459 1460 // Dispose of any children... 1461 if (item->mChild) 1462 _destroyChildren( item->mChild, item, deleteObjects ); 1463 1464 // Kill the item... 1465 _destroyItem( item, deleteObjects ); 1466 1467 // Update the rendered tree... 1468 mFlags.set(RebuildVisible); 1469 1470 return true; 1471} 1472 1473 1474//----------------------------------------------------------------------------- 1475 1476void GuiTreeViewCtrl::removeAllChildren(S32 itemId) 1477{ 1478 Item * item = getItem(itemId); 1479 if(item) 1480 { 1481 _destroyChildren(item->mChild, item); 1482 } 1483} 1484//------------------------------------------------------------------------------ 1485 1486const S32 GuiTreeViewCtrl::getFirstRootItem() const 1487{ 1488 return (mRoot ? mRoot->mId : 0); 1489} 1490 1491//------------------------------------------------------------------------------ 1492 1493S32 GuiTreeViewCtrl::getChildItem(S32 itemId) 1494{ 1495 Item * item = getItem(itemId); 1496 if(!item) 1497 { 1498 Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getChild: invalid item id!"); 1499 return(0); 1500 } 1501 1502 return(item->mChild ? item->mChild->mId : 0); 1503} 1504 1505//----------------------------------------------------------------------------- 1506 1507S32 GuiTreeViewCtrl::getParentItem(S32 itemId) 1508{ 1509 Item * item = getItem(itemId); 1510 if(!item) 1511 { 1512 Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getParent: invalid item id!"); 1513 return(0); 1514 } 1515 1516 return(item->mParent ? item->mParent->mId : 0); 1517} 1518 1519//----------------------------------------------------------------------------- 1520 1521S32 GuiTreeViewCtrl::getNextSiblingItem(S32 itemId) 1522{ 1523 Item * item = getItem(itemId); 1524 if(!item) 1525 { 1526 Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getNextSibling: invalid item id!"); 1527 return(0); 1528 } 1529 1530 return(item->mNext ? item->mNext->mId : 0); 1531} 1532 1533//----------------------------------------------------------------------------- 1534 1535S32 GuiTreeViewCtrl::getPrevSiblingItem(S32 itemId) 1536{ 1537 Item * item = getItem(itemId); 1538 if(!item) 1539 { 1540 Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getPrevSibling: invalid item id!"); 1541 return(0); 1542 } 1543 1544 return(item->mPrevious ? item->mPrevious->mId : 0); 1545} 1546 1547//------------------------------------------------------------------------------ 1548 1549bool GuiTreeViewCtrl::isValidDragTarget( Item* item ) 1550{ 1551 bool isValid = true; 1552 1553 // First, check if we're just going to override this from manually setting the ForceAllowDrag flag 1554 // If that's set, we're assuming special circumstances and will just let it go on it's way 1555 if (item->isDragTargetAllowed()) 1556 return true; 1557 1558 // If this is inspector data, first make sure the item accepts all 1559 // selected objects as children. This prevents bad surprises when 1560 // certain SimSet subclasses reject children and start shoving them 1561 // off to places of their own choosing. 1562 1563 if( item->isInspectorData() ) 1564 { 1565 if( mDebug ) 1566 Con::printf( "Checking %i:%s as drag-parent", 1567 item->getObject()->getId(), item->getObject()->getClassName() ); 1568 1569 SimSet* set = dynamic_cast< SimSet*>( item->getObject() ); 1570 if( set ) 1571 { 1572 for( U32 i = 0; i < mSelectedItems.size(); ++ i ) 1573 { 1574 Item* selectedItem = mSelectedItems[ i ]; 1575 1576 if( mDebug ) 1577 Con::printf( "Checking %i:%s as drag-object", 1578 selectedItem->getObject()->getId(), 1579 selectedItem->getObject()->getClassName() ); 1580 1581 if( selectedItem->isInspectorData() 1582 && !set->acceptsAsChild( selectedItem->getObject() ) ) 1583 return false; 1584 } 1585 } 1586 } 1587 1588 if( isMethod( "isValidDragTarget" ) ) 1589 { 1590 // We have a callback. Exclusively leave the decision whether 1591 // the item is a valid drag target to it. 1592 1593 isValid = isValidDragTarget_callback( item->mId, getItemValue( item->mId ) ); 1594 } 1595 else 1596 { 1597 // Make the item a valid drag target if it either already is 1598 // a parent (including VirtualParents) or if dragging to non-parent 1599 // items is explicitly allowed. 1600 1601 isValid = item->isParent() || mDragToItemAllowed; 1602 } 1603 1604 return isValid; 1605} 1606 1607//------------------------------------------------------------------------------ 1608 1609S32 GuiTreeViewCtrl::getItemCount() 1610{ 1611 return(mItemCount); 1612} 1613 1614//----------------------------------------------------------------------------- 1615 1616S32 GuiTreeViewCtrl::getSelectedItem() 1617{ 1618 return mSelectedItem; 1619} 1620 1621//------------------------------------------------------------------------------ 1622 1623void GuiTreeViewCtrl::moveItemUp( S32 itemId ) 1624{ 1625 GuiTreeViewCtrl::Item* pItem = getItem( itemId ); 1626 if ( !pItem ) 1627 { 1628 Con::errorf( ConsoleLogEntry::General, "GuiTreeViewCtrl::moveItemUp: invalid item id!"); 1629 return; 1630 } 1631 1632 Item * pParent = pItem->mParent; 1633 Item * pPrevItem = pItem->mPrevious; 1634 if ( pPrevItem == NULL || pParent == NULL ) 1635 { 1636 Con::errorf( ConsoleLogEntry::General, "GuiTreeViewCtrl::moveItemUp: Unable to move item up, bad data!"); 1637 return; 1638 } 1639 1640 // Diddle the linked list! 1641 if ( pPrevItem->mPrevious ) 1642 pPrevItem->mPrevious->mNext = pItem; 1643 else if ( pItem->mParent ) 1644 pItem->mParent->mChild = pItem; 1645 1646 if ( pItem->mNext ) 1647 pItem->mNext->mPrevious = pPrevItem; 1648 1649 pItem->mPrevious = pPrevItem->mPrevious; 1650 pPrevItem->mNext = pItem->mNext; 1651 pItem->mNext = pPrevItem; 1652 pPrevItem->mPrevious = pItem; 1653 1654 // Update SimObjects if Appropriate. 1655 SimObject * pSimObject = NULL; 1656 SimSet * pParentSet = NULL; 1657 1658 // Fetch Current Add Set 1659 if( pParent->isInspectorData() ) 1660 pParentSet = dynamic_cast<SimSet*>( pParent->getObject() ); 1661 else 1662 { 1663 // parent is probably script data so we search up the tree for a 1664 // set to put our object in 1665 Item * pTraverse = pItem->mParent; 1666 while ( pTraverse != NULL && !pTraverse->isInspectorData() ) 1667 pTraverse = pTraverse->mParent; 1668 1669 // found an ancestor who is an inspectorData? 1670 if (pTraverse != NULL) 1671 pParentSet = pTraverse->isInspectorData() ? dynamic_cast<SimSet*>( pTraverse->getObject() ) : NULL; 1672 } 1673 1674 // Reorder the item and make sure that the children of the item get updated 1675 // correctly prev item may be script... so find a prevItem if there is. 1676 // We only need to reorder if there you move it above an inspector item. 1677 if ( pSimObject != NULL && pParentSet != NULL ) 1678 { 1679 Item * pTraverse = pItem->mNext; 1680 1681 while(pTraverse) 1682 { 1683 if (pTraverse->isInspectorData()) 1684 break; 1685 pTraverse = pTraverse->mNext; 1686 } 1687 1688 if (pTraverse && pItem->getObject() && pTraverse->getObject()) 1689 pParentSet->reOrder(pItem->getObject(), pTraverse->getObject()); 1690 } 1691 1692 mFlags.set(RebuildVisible); 1693} 1694//----------------------------------------------------------------------------- 1695 1696void GuiTreeViewCtrl::moveItemDown( S32 itemId ) 1697{ 1698 GuiTreeViewCtrl::Item* item = getItem( itemId ); 1699 if ( !item ) 1700 { 1701 Con::errorf( ConsoleLogEntry::General, "GuiTreeViewCtrl::moveItemDown: invalid item id!"); 1702 return; 1703 } 1704 1705 Item* nextItem = item->mNext; 1706 if ( !nextItem ) 1707 { 1708 Con::errorf( ConsoleLogEntry::General, "GuiTreeViewCtrl::moveItemDown: no next sibling?"); 1709 return; 1710 } 1711 1712 // Diddle the linked list! 1713 if ( nextItem->mNext ) 1714 nextItem->mNext->mPrevious = item; 1715 1716 if ( item->mPrevious ) 1717 item->mPrevious->mNext = nextItem; 1718 else if ( item->mParent ) 1719 item->mParent->mChild = nextItem; 1720 1721 item->mNext = nextItem->mNext; 1722 nextItem->mPrevious = item->mPrevious; 1723 item->mPrevious = nextItem; 1724 nextItem->mNext = item; 1725 1726 // And update the simobjects if apppropriate... 1727 SimObject * simobj = NULL; 1728 if (item->isInspectorData()) 1729 simobj = item->getObject(); 1730 1731 SimSet *parentSet = NULL; 1732 1733 // grab the current parentSet if there is any... 1734 if(item->mParent->isInspectorData()) 1735 parentSet = dynamic_cast<SimSet*>(item->mParent->getObject()); 1736 else 1737 { 1738 // parent is probably script data so we search up the tree for a 1739 // set to put our object in 1740 Item * temp = item->mParent; 1741 while (temp && !temp->isInspectorData()) 1742 temp = temp->mParent; 1743 1744 // found an ancestor who is an inspectorData? 1745 parentSet = (temp && temp->isInspectorData()) ? dynamic_cast<SimSet*>(temp->getObject()) : NULL; 1746 } 1747 1748 // Reorder the item and make sure that the children of the item get updated 1749 // correctly prev item may be script... so find a prevItem if there is. 1750 // We only need to reorder if there you move it above an inspector item. 1751 if (simobj && parentSet) 1752 { 1753 Item * temp = item->mPrevious; 1754 1755 while(temp) 1756 { 1757 if (temp->isInspectorData()) 1758 break; 1759 temp = temp->mPrevious; 1760 } 1761 1762 if (temp && item->getObject() && temp->getObject()) 1763 parentSet->reOrder(temp->getObject(), item->getObject()); 1764 } 1765 1766 mFlags.set(RebuildVisible); 1767} 1768 1769//------------------------------------------------------------------------------ 1770 1771bool GuiTreeViewCtrl::onAdd() 1772{ 1773 if( !Parent::onAdd() ) 1774 return false; 1775 1776 // If we have dynamic fields, convert the "internalNamesOnly" and "objectNamesOnly" 1777 // legacy fields. 1778 1779 if( getFieldDictionary() ) 1780 { 1781 static StringTableEntry sInternalNamesOnly = StringTable->insert( "internalNamesOnly" ); 1782 static StringTableEntry sObjectNamesOnly = StringTable->insert( "objectNamesOnly" ); 1783 1784 const char* internalNamesOnly = getDataField( sInternalNamesOnly, NULL ); 1785 if( internalNamesOnly && internalNamesOnly[ 0 ] && dAtob( internalNamesOnly ) ) 1786 { 1787 mShowObjectIds = false; 1788 mShowClassNames = false; 1789 mShowObjectNames = false; 1790 mShowInternalNames = true; 1791 } 1792 1793 const char* objectNamesOnly = getDataField( sObjectNamesOnly, NULL ); 1794 if( objectNamesOnly && objectNamesOnly[ 0 ] && dAtob( objectNamesOnly ) ) 1795 { 1796 mShowObjectIds = false; 1797 mShowClassNames = false; 1798 mShowObjectNames = true; 1799 mShowInternalNames = false; 1800 } 1801 } 1802 1803 return true; 1804} 1805 1806//------------------------------------------------------------------------------ 1807 1808bool GuiTreeViewCtrl::onWake() 1809{ 1810 if(!Parent::onWake() || !mProfile->constructBitmapArray()) 1811 return false; 1812 1813 // If destroy on sleep, then we have to give things a chance to rebuild. 1814 if(mDestroyOnSleep) 1815 { 1816 onDefineIcons_callback(); 1817 } 1818 1819 // Update the row height, if appropriate. 1820 if(mProfile->mAutoSizeHeight) 1821 { 1822 // make sure it's big enough for both bitmap AND font... 1823 mItemHeight = getMax((S32)mFont->getHeight(), (S32)mProfile->mBitmapArrayRects[0].extent.y); 1824 } 1825 1826 mFlags.set(RebuildVisible); 1827 1828 return true; 1829} 1830 1831//----------------------------------------------------------------------------- 1832 1833void GuiTreeViewCtrl::onSleep() 1834{ 1835 Parent::onSleep(); 1836 1837 // If appropriate, blast the tree. (We probably rebuild it on wake.) 1838 if( mDestroyOnSleep ) 1839 _destroyTree(); 1840 1841 if ( mRenameCtrl ) 1842 { 1843 mRenameCtrl->deleteObject(); 1844 mRenameCtrl = NULL; 1845 } 1846} 1847 1848//----------------------------------------------------------------------------- 1849 1850bool GuiTreeViewCtrl::buildIconTable(const char * icons) 1851{ 1852 // Icons should be designated by the bitmap/png file names (minus the file extensions) 1853 // and separated by colons (:). This list should be synchronized with the Icons enum. 1854 1855 // Figure the size of the buffer we need... 1856 const char* temp = dStrchr( icons, '\t' ); 1857 U32 textLen = temp ? ( temp - icons ) : dStrlen( icons ); 1858 1859 // Allocate temporary space. 1860 FrameAllocatorMarker txtBuff; 1861 char* drawText = (char*)txtBuff.alloc(sizeof(char) * (textLen + 4)); 1862 dStrncpy( drawText, icons, textLen ); 1863 drawText[textLen] = '\0'; 1864 1865 U32 numIcons = 0; 1866 char buf[ 1024 ]; 1867 char* pos = drawText; 1868 1869 // Count the number of icons and store them. 1870 while( *pos && numIcons < MaxIcons ) 1871 { 1872 char* start = pos; 1873 while( *pos && *pos != ':' ) 1874 pos ++; 1875 1876 const U32 len = pos - start; 1877 if( len ) 1878 { 1879 dStrncpy( buf, start, getMin( sizeof( buf ) / sizeof( buf[ 0 ] ) - 1, len ) ); 1880 buf[ len ] = '\0'; 1881 1882 mIconTable[ numIcons ] = GFXTexHandle( buf, &GFXTexturePersistentProfile, avar( "%s() - mIconTable[%d] (line %d)", __FUNCTION__, numIcons, __LINE__ ) ); 1883 } 1884 else 1885 mIconTable[ numIcons ] = GFXTexHandle(); 1886 1887 numIcons ++; 1888 if( *pos ) 1889 pos ++; 1890 } 1891 1892 return true; 1893} 1894 1895//------------------------------------------------------------------------------ 1896 1897void GuiTreeViewCtrl::onPreRender() 1898{ 1899 Parent::onPreRender(); 1900 1901 S32 nRootItemId = getFirstRootItem(); 1902 if( nRootItemId == 0 ) 1903 return; 1904 1905 Item *pRootItem = getItem( nRootItemId ); 1906 if( pRootItem == NULL ) 1907 return; 1908 1909 // Update every render in case new objects are added 1910 if(mFlags.test(RebuildVisible)) 1911 { 1912 buildVisibleTree(); 1913 mFlags.clear(RebuildVisible); 1914 } 1915} 1916 1917//------------------------------------------------------------------------------ 1918 1919bool GuiTreeViewCtrl::_hitTest(const Point2I & pnt, Item* & item, BitSet32 & flags) 1920{ 1921 // Initialize some things. 1922 const Point2I pos = globalToLocalCoord(pnt); 1923 flags.clear(); 1924 item = 0; 1925 1926 // get the hit cell 1927 Point2I cell((pos.x < 0 ? -1 : pos.x / mCellSize.x), 1928 (pos.y < 0 ? -1 : pos.y / mCellSize.y)); 1929 1930 // valid? 1931 if((cell.x < 0 || cell.x >= mSize.x) || 1932 (cell.y < 0 || cell.y >= mSize.y)) 1933 return false; 1934 1935 flags.set(OnRow); 1936 1937 // Grab the cell. 1938 if (cell.y >= mVisibleItems.size()) 1939 return false; //Invalid cell, so don't do anything 1940 1941 item = mVisibleItems[cell.y]; 1942 1943 S32 min = mTabSize * item->mTabLevel; 1944 1945 // left of icon/text? 1946 if(pos.x < min) 1947 { 1948 flags.set(OnIndent); 1949 return true; 1950 } 1951 1952 // check image 1953 S32 image = BmpChild; 1954 1955 if(item->isInspectorData()) 1956 image = item->isExpanded() ? BmpExp : BmpCon; 1957 else 1958 image = item->isExpanded() ? item->getExpandedImage() : item->getNormalImage(); 1959 1960 if((image >= 0) && (image < mProfile->mBitmapArrayRects.size())) 1961 min += mProfile->mBitmapArrayRects[image].extent.x; 1962 1963 // Is it on the image? 1964 if(pos.x < min) 1965 { 1966 flags.set(OnImage); 1967 return(true); 1968 } 1969 1970 // Check the icon. 1971 min += getInspectorItemIconsWidth( item ); 1972 1973 if ( pos.x < min ) 1974 { 1975 flags.set(OnIcon); 1976 return true; 1977 } 1978 1979 // Check the text. 1980 1981 min += mProfile->mTextOffset.x; 1982 1983 FrameAllocatorMarker txtAlloc; 1984 U32 bufLen = item->getDisplayTextLength() + 1; 1985 char *buf = (char*)txtAlloc.alloc(bufLen); 1986 item->getDisplayText(bufLen, buf); 1987 1988 min += mProfile->mFont->getStrWidth(buf); 1989 if(pos.x < min) 1990 flags.set(OnText); 1991 1992 return true; 1993} 1994 1995//----------------------------------------------------------------------------- 1996 1997S32 GuiTreeViewCtrl::getInspectorItemIconsWidth(Item* & item) 1998{ 1999 S32 width = 0; 2000 2001 if( item->isInspectorData() ) 2002 { 2003 // Based on code in onRenderCell() 2004 2005 S32 icon = Lock1; 2006 S32 icon2 = Hidden; 2007 2008 if (item->getObject() && item->getObject()->isLocked()) 2009 { 2010 if (mIconTable[icon]) 2011 { 2012 width += mIconTable[icon].getWidth(); 2013 } 2014 } 2015 2016 if (item->getObject() && item->getObject()->isHidden()) 2017 { 2018 if (mIconTable[icon2]) 2019 { 2020 width += mIconTable[icon2].getWidth(); 2021 } 2022 } 2023 2024 GFXTexHandle iconHandle; 2025 if ( ( item->mIcon != -1 ) && mIconTable[item->mIcon] ) 2026 iconHandle = mIconTable[item->mIcon]; 2027 #ifdef TORQUE_TOOLS 2028 else 2029 iconHandle = gEditorIcons.findIcon( item->getObject() ); 2030 #endif 2031 2032 if ( iconHandle.isValid() ) 2033 { 2034 width += iconHandle.getWidth(); 2035 } 2036 } 2037 else 2038 { 2039 S32 icon = item->isExpanded() ? item->mScriptInfo.mExpandedImage : item->mScriptInfo.mNormalImage; 2040 if ( ( icon != -1 ) && mIconTable[icon] ) 2041 { 2042 width += mIconTable[icon].getWidth(); 2043 } 2044 } 2045 2046 return width; 2047} 2048 2049//----------------------------------------------------------------------------- 2050 2051bool GuiTreeViewCtrl::setAddGroup(SimObject * obj) 2052{ 2053 // make sure we're talking about a group. 2054 SimGroup * grp = dynamic_cast<SimGroup*>(obj); 2055 2056 if(grp) 2057 { 2058 onAddGroupSelected_callback( grp ); 2059 return true; 2060 } 2061 return false; 2062} 2063 2064//----------------------------------------------------------------------------- 2065 2066void GuiTreeViewCtrl::syncSelection() 2067{ 2068 // for each visible item check to see if it is on the mSelected list. 2069 // if it is then make sure that it is on the mSelectedItems list as well. 2070 for (S32 i = 0; i < mVisibleItems.size(); i++) 2071 { 2072 for (S32 j = 0; j < mSelected.size(); j++) 2073 { 2074 if (mVisibleItems[i]->mId == mSelected[j]) 2075 { 2076 // check to see if it is on the visible items list. 2077 bool addToSelectedItems = true; 2078 for (S32 k = 0; k < mSelectedItems.size(); k++) 2079 { 2080 if (mSelected[j] == mSelectedItems[k]->mId) 2081 { 2082 // don't add it 2083 addToSelectedItems = false; 2084 } 2085 } 2086 if (addToSelectedItems) 2087 { 2088 mVisibleItems[i]->mState.set(Item::Selected, true); 2089 mSelectedItems.push_front(mVisibleItems[i]); 2090 break; 2091 } 2092 } 2093 else if (mVisibleItems[i]->isInspectorData()) 2094 { 2095 if(mCompareToObjectID) 2096 { 2097 if (mVisibleItems[i]->getObject() && mVisibleItems[i]->getObject()->getId() == mSelected[j]) 2098 { 2099 // check to see if it is on the visible items list. 2100 bool addToSelectedItems = true; 2101 for (S32 k = 0; k < mSelectedItems.size(); k++) 2102 { 2103 if (mSelectedItems[k]->isInspectorData() && mSelectedItems[k]->getObject() ) 2104 { 2105 if (mSelected[j] == mSelectedItems[k]->getObject()->getId()) 2106 { 2107 // don't add it 2108 addToSelectedItems = false; 2109 } 2110 } 2111 else 2112 { 2113 if (mSelected[j] == mSelectedItems[k]->mId) 2114 { 2115 // don't add it 2116 addToSelectedItems = false; 2117 } 2118 } 2119 } 2120 if (addToSelectedItems) 2121 { 2122 mVisibleItems[i]->mState.set(Item::Selected, true); 2123 mSelectedItems.push_front(mVisibleItems[i]); 2124 break; 2125 } 2126 } 2127 } 2128 } 2129 2130 } 2131 2132 } 2133} 2134 2135//----------------------------------------------------------------------------- 2136 2137void GuiTreeViewCtrl::removeSelection( S32 itemOrObjectId ) 2138{ 2139 if (mDebug) 2140 Con::printf( "removeSelection %i", itemOrObjectId ); 2141 2142 Item* item = _findItemByAmbiguousId( itemOrObjectId, false ); 2143 if (!item) 2144 return; 2145 2146 // Make sure we have a true item ID even if we started with 2147 // an object ID. 2148 S32 itemId = item->getID(); 2149 2150 S32 objectId = -1; 2151 if ( item->isInspectorData() && item->getObject() ) 2152 objectId = item->getObject()->getId(); 2153 2154 // Remove from vector of selected object ids if it exists there 2155 if ( objectId != -1 ) 2156 { 2157 for ( S32 i = 0; i < mSelected.size(); i++ ) 2158 { 2159 if ( objectId == mSelected[i] || itemId == mSelected[i] ) 2160 { 2161 mSelected.erase( i ); 2162 break; 2163 } 2164 } 2165 } 2166 else 2167 { 2168 for ( S32 i = 0; i < mSelected.size(); i++ ) 2169 { 2170 if ( itemId == mSelected[i] ) 2171 { 2172 mSelected.erase( i ); 2173 break; 2174 } 2175 } 2176 } 2177 2178 item->mState.set(Item::Selected, false); 2179 2180 // Remove from vector of selected items if it exists there. 2181 for ( S32 i = 0; i < mSelectedItems.size(); i++ ) 2182 { 2183 if ( mSelectedItems[i] == item ) 2184 { 2185 mSelectedItems.erase( i ); 2186 break; 2187 } 2188 } 2189 2190 // Callback. 2191 onRemoveSelection( item ); 2192} 2193 2194//----------------------------------------------------------------------------- 2195 2196void GuiTreeViewCtrl::addSelection( S32 itemOrObjectId, bool update, bool isLastSelection ) 2197{ 2198 if (mDebug) 2199 Con::printf( "addSelection %i", itemOrObjectId ); 2200 2201 Item* item = _findItemByAmbiguousId( itemOrObjectId ); 2202 2203 // Add Item? 2204 if ( !item || isSelected( item ) || !canAddSelection( item ) ) 2205 { 2206 // Nope. 2207 return; 2208 } 2209 2210 const S32 itemId = item->getID(); 2211 2212 // Ok, we have an item to select which isn't already selected.... 2213 2214 // Do we want to allow more than one selected item? 2215 if( !mMultipleSelections ) 2216 clearSelection(); 2217 2218 // Add this object id to the vector of selected objectIds 2219 // if it is not already. 2220 bool foundMatch = false; 2221 for ( S32 i = 0; i < mSelected.size(); i++) 2222 { 2223 if ( mSelected[i] == itemId ) 2224 foundMatch = true; 2225 } 2226 2227 if ( !foundMatch ) 2228 mSelected.push_front(itemId); 2229 2230 item->mState.set(Item::Selected, true); 2231 2232 if( mSelected.size() == 1 ) 2233 { 2234 onItemSelected( item ); 2235 } 2236 2237 // Callback Start 2238 // Set and add the selection to the selected items group 2239 item->mState.set(Item::Selected, true); 2240 mSelectedItems.push_front(item); 2241 2242 if ( item->isInspectorData() && 2243 item->getObject() ) 2244 { 2245 SimObject *obj = item->getObject(); 2246 2247 onAddSelection_callback( obj->getId(), isLastSelection ); 2248 } 2249 else 2250 { 2251 onAddSelection_callback( item->mId, isLastSelection ); 2252 } 2253 // Callback end 2254 2255 mFlags.set( RebuildVisible ); 2256 if( update ) 2257 { 2258 // Also make it so we can see it if we didn't already. 2259 scrollVisible( item ); 2260 } 2261} 2262 2263 2264//----------------------------------------------------------------------------- 2265 2266void GuiTreeViewCtrl::onItemSelected( Item *item ) 2267{ 2268 mSelectedItem = item->getID(); 2269 2270 if (item->isInspectorData()) 2271 { 2272 SimObject* object = item->getObject(); 2273 if( object ) 2274 onSelect_callback( object->getId() ); 2275 if( !item->isParent() && object ) 2276 onInspect_callback( object->getId() ); 2277 } 2278 else 2279 { 2280 onSelect_callback( item->mId ); 2281 if( !item->isParent() ) 2282 onInspect_callback( item->mId ); 2283 } 2284} 2285 2286//----------------------------------------------------------------------------- 2287 2288void GuiTreeViewCtrl::onRemoveSelection( Item *item ) 2289{ 2290 S32 id = item->mId; 2291 2292 if( item->isInspectorData() && 2293 item->getObject() ) 2294 { 2295 SimObject* obj = item->getObject(); 2296 id = obj->getId(); 2297 //obj->setSelected( false ); 2298 } 2299 2300 if( isMethod( "onRemoveSelection" ) ) 2301 onRemoveSelection_callback( id ); 2302 else 2303 onUnselect_callback( id ); 2304} 2305 2306//----------------------------------------------------------------------------- 2307 2308bool GuiTreeViewCtrl::setItemSelected(S32 itemId, bool select) 2309{ 2310 Item * item = getItem(itemId); 2311 if( isSelected( item ) == select ) 2312 return true; 2313 2314 if (select) 2315 { 2316 if (mDebug) Con::printf("setItemSelected called true"); 2317 2318 mSelected.push_front(itemId); 2319 } 2320 else 2321 { 2322 if (mDebug) Con::printf("setItemSelected called false"); 2323 2324 // remove it from the mSelected list 2325 for (S32 j = 0; j <mSelected.size(); j++) 2326 { 2327 if (item) 2328 { 2329 if (item->isInspectorData()) 2330 { 2331 if (item->getObject()) 2332 { 2333 if(item->getObject()->getId() == mSelected[j]) 2334 { 2335 mSelected.erase(j); 2336 break; 2337 } 2338 } 2339 else 2340 { 2341 // Zombie, kill it! 2342 mSelected.erase(j); 2343 j--; 2344 break; 2345 } 2346 } 2347 } 2348 2349 if (mSelected[j] == itemId) 2350 { 2351 mSelected.erase(j); 2352 break; 2353 } 2354 } 2355 } 2356 2357 if(!item) 2358 { 2359 // maybe what we were passed wasn't an item id but an object id. 2360 for (S32 i = 0; i <mItems.size(); i++) 2361 { 2362 if (mItems[i] != 0) 2363 { 2364 if (mItems[i]->isInspectorData()) 2365 { 2366 if (mItems[i]->getObject()) 2367 { 2368 if(mItems[i]->getObject()->getId() == itemId) 2369 { 2370 item = mItems[i]; 2371 break; 2372 } 2373 } 2374 else 2375 { 2376 // It's a zombie, blast it. 2377 mItems.erase(i); 2378 i--; 2379 } 2380 } 2381 } 2382 } 2383 2384 if (!item) 2385 { 2386 //Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::setItemSelected: invalid item id! Perhaps it isn't visible yet."); 2387 return(false); 2388 } 2389 } 2390 2391 mFlags.set( RebuildVisible ); 2392 2393 if(select) 2394 { 2395 addSelection( item->mId ); 2396 onItemSelected( item ); 2397 } 2398 else 2399 { 2400 // deselect the item, if it's present. 2401 item->mState.set(Item::Selected, false); 2402 2403 if (item->isInspectorData() && item->getObject()) 2404 onUnselect_callback( item->getObject()->getId() ); 2405 else 2406 onUnselect_callback( item->mId ); 2407 2408 // remove it from the selected items list 2409 for (S32 i = 0; i < mSelectedItems.size(); i++) 2410 { 2411 if (mSelectedItems[i] == item) 2412 { 2413 mSelectedItems.erase(i); 2414 break; 2415 } 2416 } 2417 } 2418 2419 setUpdate(); 2420 return(true); 2421} 2422 2423//----------------------------------------------------------------------------- 2424 2425// Given an item's index in the selection list, return its itemId 2426S32 GuiTreeViewCtrl::getSelectedItem(S32 index) 2427{ 2428 if(index >= 0 && index < getSelectedItemsCount()) 2429 { 2430 return mSelectedItems[index]->mId; 2431 } 2432 2433 return -1; 2434} 2435 2436//----------------------------------------------------------------------------- 2437 2438bool GuiTreeViewCtrl::setItemExpanded(S32 itemId, bool expand) 2439{ 2440 Item * item = getItem(itemId); 2441 if(!item) 2442 { 2443 Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::setItemExpanded: invalid item id!"); 2444 return(false); 2445 } 2446 2447 if(item->isExpanded() == expand) 2448 return(true); 2449 2450 item->setExpanded(expand); 2451 2452 // expand parents 2453 if(expand) 2454 { 2455 while (item) 2456 { 2457 if (!item->isInspectorData() && item->mState.test(Item::VirtualParent)) 2458 onVirtualParentExpand(item); 2459 2460 scrollVisible(item); 2461 item = item->mParent; 2462 } 2463 } 2464 else 2465 { 2466 if(item->mState.test(Item::VirtualParent)) 2467 onVirtualParentCollapse(item); 2468 2469 item->setExpanded(false); 2470 } 2471 2472 //if (!item->isInspectorData() && item->mState.test(Item::VirtualParent)) 2473 // onVirtualParentExpand(item); 2474 2475 mFlags.set(RebuildVisible); 2476 2477 return(true); 2478} 2479 2480 2481//----------------------------------------------------------------------------- 2482 2483bool GuiTreeViewCtrl::setItemValue(S32 itemId, StringTableEntry Value) 2484{ 2485 Item * item = getItem(itemId); 2486 if(!item) 2487 { 2488 Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::setItemValue: invalid item id!"); 2489 return(false); 2490 } 2491 2492 item->setValue( ( Value ) ? Value : "" ); 2493 2494 return(true); 2495} 2496 2497//----------------------------------------------------------------------------- 2498 2499const char * GuiTreeViewCtrl::getItemText(S32 itemId) 2500{ 2501 Item * item = getItem(itemId); 2502 if(!item) 2503 { 2504 Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getItemText: invalid item id!"); 2505 return(""); 2506 } 2507 2508 return(item->getText() ? item->getText() : ""); 2509} 2510 2511//----------------------------------------------------------------------------- 2512 2513const char * GuiTreeViewCtrl::getItemValue(S32 itemId) 2514{ 2515 Item * item = getItem(itemId); 2516 if(!item) 2517 { 2518 Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getItemValue: invalid item id!"); 2519 return(""); 2520 } 2521 2522 if(item->mState.test(Item::InspectorData)) 2523 { 2524 // If it's InspectorData, we let people use this call to get an object reference. 2525 return item->mInspectorInfo.mObject->getIdString(); 2526 } 2527 else 2528 { 2529 // Just return the script value... 2530 return item->getValue(); 2531 } 2532} 2533 2534//----------------------------------------------------------------------------- 2535 2536S32 GuiTreeViewCtrl::getItemAtPosition(Point2I position) 2537{ 2538 BitSet32 hitFlags = 0; 2539 Item* item; 2540 2541 if (_hitTest(position, item, hitFlags)) 2542 return item->mId; 2543 else 2544 return -1; 2545} 2546 2547//----------------------------------------------------------------------------- 2548 2549bool GuiTreeViewCtrl::editItem( S32 itemId, const char* newText, const char* newValue ) 2550{ 2551 Item* item = getItem( itemId ); 2552 if ( !item ) 2553 { 2554 Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::editItem: invalid item id: %d!", itemId); 2555 return false; 2556 } 2557 2558 if ( item->mState.test(Item::InspectorData) ) 2559 { 2560 Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::editItem: item %d is inspector data and may not be modified!", itemId); 2561 return false; 2562 } 2563 2564 item->setText( StringTable->insert( newText, true ) ); 2565 item->setValue( StringTable->insert( newValue, true ) ); 2566 2567 // Update the widths and such: 2568 mFlags.set(RebuildVisible); 2569 return true; 2570} 2571 2572//----------------------------------------------------------------------------- 2573 2574bool GuiTreeViewCtrl::markItem( S32 itemId, bool mark ) 2575{ 2576 Item *item = getItem( itemId ); 2577 if ( !item ) 2578 { 2579 Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::markItem: invalid item id: %d!", itemId); 2580 return false; 2581 } 2582 2583 item->mState.set(Item::Marked, mark); 2584 return true; 2585} 2586 2587//----------------------------------------------------------------------------- 2588 2589bool GuiTreeViewCtrl::isItemSelected( S32 itemId ) 2590{ 2591 for( U32 i = 0, num = mSelectedItems.size(); i < num; ++ i ) 2592 if( mSelectedItems[ i ]->mId == itemId ) 2593 return true; 2594 2595 return false; 2596} 2597 2598//----------------------------------------------------------------------------- 2599 2600void GuiTreeViewCtrl::deleteSelection() 2601{ 2602 onDeleteSelection_callback(); 2603 2604 if (mSelectedItems.empty()) 2605 { 2606 for (S32 i = 0; i < mSelected.size(); i++) 2607 { 2608 S32 objectId = mSelected[i]; 2609 2610 // find the object 2611 SimObject* obj = Sim::findObject(objectId); 2612 if ( !obj ) 2613 continue; 2614 2615 bool skipDelete = onDeleteObject_callback( obj ); 2616 if ( !skipDelete ) 2617 obj->deleteObject(); 2618 } 2619 } 2620 else 2621 { 2622 Vector<Item*> delSelection; 2623 delSelection = mSelectedItems; 2624 mSelectedItems.clear(); 2625 while (!delSelection.empty()) 2626 { 2627 Item * item = delSelection.front(); 2628 setItemSelected(item->mId,false); 2629 if ( item->mParent ) 2630 _deleteItem( item ); 2631 2632 delSelection.pop_front(); 2633 } 2634 } 2635 2636 mSelected.clear(); 2637 mSelectedItems.clear(); 2638 mSelectedItem = 0; 2639 2640 onObjectDeleteCompleted_callback(); 2641} 2642 2643//------------------------------------------------------------------------------ 2644 2645// keyboard movement of items is restricted to just one item at a time 2646// if more than one item is selected then movement operations are not performed 2647bool GuiTreeViewCtrl::onKeyDown( const GuiEvent& event ) 2648{ 2649 if ( !mVisible || !mActive || !mAwake ) 2650 return false; 2651 2652 // All the keyboard functionality requires a selected item, so if none exists... 2653 2654 // Deal with enter and delete 2655 if ( event.modifier == 0 ) 2656 { 2657 if ( event.keyCode == KEY_RETURN ) 2658 { 2659 execAltConsoleCallback(); 2660 return true; 2661 } 2662 2663 if ( event.keyCode == KEY_DELETE && mDeleteObjectAllowed ) 2664 { 2665 // Don't delete the root! 2666 if (mSelectedItems.empty()) 2667 return true; 2668 2669 //this may be fighting with the world editor delete 2670 deleteSelection(); 2671 return true; 2672 } 2673 2674 //call a generic bit of script that will let the subclass know that a key was pressed 2675 onKeyDown_callback( event.modifier, event.keyCode ); 2676 } 2677 2678 // only do operations if only one item is selected 2679 if ( mSelectedItems.empty() || (mSelectedItems.size() > 1)) 2680 return false; 2681 2682 Item* item = mSelectedItems.first(); 2683 2684 if ( !item ) 2685 return false; 2686 2687 // The Alt key lets you move items around! 2688 if ( mFlags.test(IsEditable) && event.modifier & SI_ALT ) 2689 { 2690 switch ( event.keyCode ) 2691 { 2692 case KEY_UP: 2693 // Move us up. 2694 if ( item->mPrevious ) 2695 { 2696 moveItemUp( item->mId ); 2697 scrollVisible(item); 2698 } 2699 return true; 2700 2701 case KEY_DOWN: 2702 // Move the item under us up. 2703 if ( item->mNext ) 2704 { 2705 moveItemUp( item->mNext->mId ); 2706 scrollVisible(item); 2707 } 2708 return true; 2709 2710 case KEY_LEFT: 2711 if ( item->mParent ) 2712 { 2713 if ( item->mParent->mParent ) 2714 { 2715 // Ok, we have both an immediate parent, and a grandparent. 2716 2717 // The goal of left-arrow alt is to become the child of our 2718 // grandparent, ie, to become a sibling of our parent. 2719 2720 // First, unlink item from its siblings. 2721 if ( item->mPrevious ) 2722 item->mPrevious->mNext = item->mNext; 2723 else 2724 item->mParent->mChild = item->mNext; 2725 2726 if ( item->mNext ) 2727 item->mNext->mPrevious = item->mPrevious; 2728 2729 // Now, relink as the next sibling of our parent. 2730 item->mPrevious = item->mParent; 2731 item->mNext = item->mParent->mNext; 2732 2733 // If there was already a next sibling, deal with that case. 2734 if ( item->mNext ) 2735 item->mNext->mPrevious = item; 2736 item->mParent->mNext = item; 2737 2738 // Snag the current parent set if any... 2739 SimSet *parentSet = NULL; 2740 2741 if(item->mParent->isInspectorData()) 2742 parentSet = dynamic_cast<SimSet*>(item->mParent->getObject()); 2743 else 2744 { 2745 // parent is probably script data so we search up the tree for a 2746 // set to put our object in 2747 Item * temp = item->mParent; 2748 while (!temp->isInspectorData()) 2749 temp = temp->mParent; 2750 // found a ancestor who is an inspectorData 2751 if (temp->isInspectorData()) 2752 parentSet = dynamic_cast<SimSet*>(temp->getObject()); 2753 else parentSet = NULL; 2754 } 2755 2756 // Get our active SimObject if any 2757 SimObject *simObj = NULL; 2758 if(item->isInspectorData()) 2759 simObj = item->getObject(); 2760 2761 // Remove from the old parentset... 2762 if(simObj && parentSet) { 2763 if (parentSet->size()>0) 2764 { 2765 SimObject *lastObject = parentSet->last(); 2766 parentSet->removeObject(simObj); 2767 parentSet->reOrder(lastObject); 2768 } else 2769 parentSet->removeObject(simObj); 2770 } 2771 2772 // And finally, update our item 2773 item->mParent = item->mParent->mParent; 2774 2775 // Snag the newparent set if any... 2776 SimSet *newParentSet = NULL; 2777 2778 if(item->mParent->isInspectorData()) 2779 newParentSet = dynamic_cast<SimSet*>(item->mParent->getObject()); 2780 else 2781 { 2782 // parent is probably script data so we search up the tree for a 2783 // set to put our object in 2784 Item * temp = item->mParent; 2785 while (!temp->isInspectorData()) 2786 temp = temp->mParent; 2787 // found a ancestor who is an inspectorData 2788 if (temp->isInspectorData()) 2789 newParentSet = dynamic_cast<SimSet*>(temp->getObject()); 2790 else newParentSet = NULL; 2791 } 2792 if(simObj && newParentSet) 2793 { 2794 2795 newParentSet->addObject(simObj); 2796 Item * temp = item->mNext; 2797 // item->mNext may be script, so find an inspector item to reorder with if any 2798 2799 if (temp) { 2800 do { 2801 if (temp->isInspectorData()) 2802 break; 2803 temp = temp->mNext; 2804 } while (temp); 2805 if (temp && item->getObject() && temp->getObject()) //do we still have a item->mNext? If not then don't bother reordering 2806 newParentSet->reOrder(item->getObject(), temp->getObject()); 2807 } 2808 2809 } else if (!simObj&&newParentSet) { 2810 // our current item is script data. but it may have children who 2811 // is inspector data who need an updated set 2812 if (item->mChild) 2813 inspectorSearch(item->mChild, item, parentSet, newParentSet); 2814 2815 } 2816 2817 // And update everything hurrah. 2818 buildVisibleTree(); 2819 scrollVisible(item); 2820 } 2821 } 2822 return true; 2823 2824 case KEY_RIGHT: 2825 if ( item->mPrevious ) 2826 { 2827 // Make the item the last child of its previous sibling. 2828 2829 // First, unlink from the current position in the list 2830 item->mPrevious->mNext = item->mNext; 2831 2832 if ( item->mNext ) 2833 item->mNext->mPrevious = item->mPrevious; 2834 2835 // Get the object we're poking with. 2836 SimObject *simObj = NULL; 2837 SimSet *parentSet = NULL; 2838 if(item->isInspectorData()) 2839 simObj = item->getObject(); 2840 if(item->mParent->isInspectorData()) 2841 parentSet = dynamic_cast<SimSet*>(item->mParent->getObject()); 2842 else { 2843 // parent is probably script data so we search up the tree for a 2844 // set to put our object in 2845 Item * temp = item->mParent; 2846 while (!temp->isInspectorData()) 2847 temp = temp->mParent; 2848 // found an ancestor who is an inspectorData 2849 if (temp->isInspectorData()) 2850 parentSet = dynamic_cast<SimSet*>(temp->getObject()); 2851 } 2852 2853 // If appropriate, remove from the current SimSet. 2854 if(parentSet && simObj) { 2855 if (parentSet->size()>0) 2856 { 2857 SimObject *lastObject = parentSet->last(); 2858 parentSet->removeObject(simObj); 2859 parentSet->reOrder(lastObject); 2860 } else 2861 parentSet->removeObject(simObj); 2862 } 2863 2864 2865 // Now, make our previous sibling our parent... 2866 item->mParent = item->mPrevious; 2867 item->mNext = NULL; 2868 2869 // And sink us down to the end of its siblings, if appropriate. 2870 if ( item->mParent->mChild ) 2871 { 2872 Item* temp = item->mParent->mChild; 2873 while ( temp->mNext ) 2874 temp = temp->mNext; 2875 2876 temp->mNext = item; 2877 item->mPrevious = temp; 2878 } 2879 else 2880 { 2881 // only child...<sniff> 2882 item->mParent->mChild = item; 2883 item->mPrevious = NULL; 2884 } 2885 2886 // Make sure the new parent is expanded: 2887 if ( !item->mParent->mState.test( Item::Expanded ) ) 2888 setItemExpanded( item->mParent->mId, true ); 2889 2890 // Snag the new parent simset if any. 2891 SimSet *newParentSet = NULL; 2892 2893 // new parent might be script. so figure out what set we need to add it to. 2894 if(item->mParent->isInspectorData()) 2895 newParentSet = dynamic_cast<SimSet*>(item->mParent->getObject()); 2896 else 2897 { 2898 // parent is probably script data so we search up the tree for a 2899 // set to put our object in 2900 if (mDebug) Con::printf("oh nos my parent is script!"); 2901 Item * temp = item->mParent; 2902 while (!temp->isInspectorData()) 2903 temp = temp->mParent; 2904 // found a ancestor who is an inspectorData 2905 if (temp->isInspectorData()) 2906 newParentSet = dynamic_cast<SimSet*>(temp->getObject()); 2907 else newParentSet = NULL; 2908 } 2909 // Add the item's SimObject to the new parent simset, at the end. 2910 if(newParentSet && simObj) 2911 newParentSet->addObject(simObj); 2912 else if (!simObj&&newParentSet&&parentSet) { 2913 // our current item is script data. but it may have children who 2914 // is inspector data who need an updated set 2915 2916 if (item->mChild) { 2917 inspectorSearch(item->mChild, item, parentSet, newParentSet); 2918 } 2919 2920 } 2921 scrollVisible(item); 2922 } 2923 return true; 2924 2925 default: 2926 break; 2927 } 2928 } 2929 2930 // Explorer-esque navigation... 2931 switch( event.keyCode ) 2932 { 2933 case KEY_UP: 2934 // Select previous visible item: 2935 if ( item->mPrevious ) 2936 { 2937 item = item->mPrevious; 2938 while ( item->isParent() && item->isExpanded() ) 2939 { 2940 item = item->mChild; 2941 while ( item->mNext ) 2942 item = item->mNext; 2943 } 2944 clearSelection(); 2945 addSelection( item->mId ); 2946 return true; 2947 } 2948 2949 // or select parent: 2950 if ( item->mParent ) 2951 { 2952 clearSelection(); 2953 addSelection( item->mParent->mId ); 2954 return true; 2955 } 2956 2957 return false; 2958 break; 2959 2960 case KEY_DOWN: 2961 // Selected child if it is visible: 2962 if ( item->isParent() && item->isExpanded() ) 2963 { 2964 clearSelection(); 2965 addSelection( item->mChild->mId ); 2966 return true; 2967 } 2968 // or select next sibling (recursively): 2969 do 2970 { 2971 if ( item->mNext ) 2972 { 2973 clearSelection(); 2974 addSelection( item->mNext->mId ); 2975 return true; 2976 } 2977 2978 item = item->mParent; 2979 } while ( item ); 2980 2981 return false; 2982 break; 2983 2984 case KEY_LEFT: 2985 // Contract current menu: 2986 if ( item->isExpanded() ) 2987 { 2988 setItemExpanded( item->mId, false ); 2989 scrollVisible(item); 2990 return true; 2991 } 2992 // or select parent: 2993 if ( item->mParent ) 2994 { 2995 clearSelection(); 2996 addSelection( item->mParent->mId ); 2997 return true; 2998 } 2999 3000 return false; 3001 break; 3002 3003 case KEY_RIGHT: 3004 // Expand selected item: 3005 if ( item->isParent() ) 3006 { 3007 if ( !item->isExpanded() ) 3008 { 3009 setItemExpanded( item->mId, true ); 3010 scrollVisible(item); 3011 return true; 3012 } 3013 3014 // or select child: 3015 clearSelection(); 3016 addSelection( item->mChild->mId ); 3017 return true; 3018 } 3019 3020 return false; 3021 break; 3022 3023 default: 3024 break; 3025 } 3026 3027 // Not processed, so pass the event on: 3028 return Parent::onKeyDown( event ); 3029} 3030 3031//------------------------------------------------------------------------------ 3032 3033// on mouse up look at the current item and check to see if it is valid 3034// to move the selected item(s) to it. 3035void GuiTreeViewCtrl::onMouseUp(const GuiEvent &event) 3036{ 3037 if( !mActive || !mAwake || !mVisible ) 3038 return; 3039 3040 BitSet32 hitFlags = 0; 3041 if( isMethod("onMouseUp") ) 3042 { 3043 Item* item; 3044 3045 S32 hitItemId = -1; 3046 if( _hitTest( event.mousePoint, item, hitFlags ) ) 3047 hitItemId = item->mId; 3048 3049 onMouseUp_callback( hitItemId, event.mouseClickCount ); 3050 } 3051 3052 mouseUnlock(); 3053 3054 if ( mSelectedItems.empty()) 3055 { 3056 mDragMidPoint = NomDragMidPoint; 3057 return; 3058 } 3059 3060 hitFlags = 0; 3061 Item *hitItem; 3062 bool hitCheck = _hitTest( event.mousePoint, hitItem, hitFlags ); 3063 mRenamingItem = NULL; 3064 3065 if( hitCheck ) 3066 { 3067 if ( event.mouseClickCount == 1 && !mMouseDragged && mPossibleRenameItem != NULL ) 3068 { 3069 if (hitItem == mPossibleRenameItem ) 3070 showItemRenameCtrl(hitItem); 3071 } 3072 else // If mouseUp occurs on the same item as mouse down 3073 { 3074 bool wasSelected = isSelected(hitItem); 3075 bool multiSelect = getSelectedItemsCount() > 1; 3076 if( wasSelected && multiSelect && hitItem == mTempItem ) 3077 { 3078 clearSelection(); 3079 addSelection( hitItem->mId ); 3080 } 3081 } 3082 } 3083 3084 mPossibleRenameItem = NULL; 3085 3086 if (!mMouseDragged) 3087 return; 3088 3089 Item* newItem = NULL; 3090 Item* newItem2 = NULL; 3091 3092 if (mFlags.test(IsEditable)) 3093 { 3094 Parent::onMouseMove( event ); 3095 3096 hitFlags = 0; 3097 if( !_hitTest( event.mousePoint, newItem2, hitFlags ) ) 3098 { 3099 if( !mShowRoot ) 3100 newItem2 = mRoot; 3101 else 3102 { 3103 if( mDebug ) 3104 Con::printf( "Nothing hit" ); 3105 3106 mDragMidPoint = NomDragMidPoint; 3107 return; 3108 } 3109 } 3110 3111 newItem2->mState.clear(Item::MouseOverBmp | Item::MouseOverText ); 3112 3113 // If the hit item is the visible root, make sure 3114 // we don't allow dragging above. 3115 3116 if( newItem2 == mRoot && mDragMidPoint == AbovemDragMidPoint ) 3117 { 3118 if( mDebug ) 3119 Con::printf( "Rejecting to make child sibling of root" ); 3120 3121 mDragMidPoint = NomDragMidPoint; 3122 return; 3123 } 3124 3125 // if the newItem isn't in the mSelectedItemList then continue. 3126 3127 Vector<Item *>::iterator k; 3128 for(k = mSelectedItems.begin(); k != mSelectedItems.end(); k++) 3129 { 3130 newItem = newItem2; 3131 3132 if (*(k) == newItem) 3133 { 3134 mDragMidPoint = NomDragMidPoint; 3135 return; 3136 } 3137 3138 Item * temp = *(k); 3139 Item * grandpaTemp = newItem->mParent; 3140 3141 // grandpa check, kick out if an item would be its own ancestor 3142 while (grandpaTemp) 3143 { 3144 if (temp == grandpaTemp) 3145 { 3146 if (mDebug) 3147 { 3148 Con::printf("grandpa check"); 3149 3150 if (temp->isInspectorData()) 3151 Con::printf("temp's name: %s",temp->getObject()->getName()); 3152 3153 if (grandpaTemp->isInspectorData()) 3154 Con::printf("grandpa's name: %s",grandpaTemp->getObject()->getName()); 3155 } 3156 3157 mDragMidPoint = NomDragMidPoint; 3158 return; 3159 } 3160 3161 grandpaTemp = grandpaTemp->mParent; 3162 } 3163 } 3164 3165 // Notify script for undo. 3166 3167 onBeginReparenting_callback(); 3168 3169 // Reparent the items. 3170 3171 reparentItems(mSelectedItems, newItem2); 3172 3173 onEndReparenting_callback(); 3174 3175 // And update everything. 3176 scrollVisible(newItem); 3177 3178 onDragDropped_callback(); 3179 3180 buildVisibleTree(false); 3181 } 3182 3183 mDragMidPoint = NomDragMidPoint; 3184} 3185 3186//------------------------------------------------------------------------------ 3187 3188void GuiTreeViewCtrl::onMouseDragged(const GuiEvent &event) 3189{ 3190 if( mDragStartInSelection ) 3191 onMouseDragged_callback(); 3192 3193 if(!mSupportMouseDragging) 3194 return; 3195 3196 if( !mActive || !mAwake || !mVisible ) 3197 return; 3198 3199 if (mSelectedItems.size() == 0) 3200 return; 3201 3202 //Check through to make sure all attempted dragged items even allow it 3203 for (U32 i = 0; i < mSelectedItems.size(); i++) 3204 if (!mSelectedItems[i]->isDragAllowed()) 3205 return; 3206 3207 // Give us a little delta before we actually start a mouse drag so that 3208 // if the user moves the mouse a little while clicking, he/she does not 3209 // accidentally trigger a drag. 3210 3211 if( mFabs( ( mMouseDownPoint - event.mousePoint ).len() ) <= 4.f ) 3212 return; 3213 3214 Point2I pt = globalToLocalCoord(event.mousePoint); 3215 Parent::onMouseMove(event); 3216 mouseLock(); 3217 mMouseDragged = true; 3218 3219 // If the drag is outside of our visible area, 3220 // start scrolling. 3221 3222 GuiScrollCtrl* scrollCtrl = dynamic_cast< GuiScrollCtrl* >( getParent() ); 3223 if( scrollCtrl && !scrollCtrl->isPointVisible( pt ) ) 3224 { 3225 S32 widthDelta = 0; 3226 S32 heightDelta = 0; 3227 3228 if( pt.x < scrollCtrl->getChildRelPos().x ) 3229 widthDelta = pt.x - scrollCtrl->getChildRelPos().x; 3230 else if( pt.x > scrollCtrl->getChildRelPos().x + scrollCtrl->getContentExtent().x ) 3231 widthDelta = pt.x - scrollCtrl->getChildRelPos().x - scrollCtrl->getContentExtent().x; 3232 3233 if( pt.y < scrollCtrl->getChildRelPos().y ) 3234 heightDelta = pt.y - scrollCtrl->getChildRelPos().y; 3235 else if( pt.y > scrollCtrl->getChildRelPos().y + scrollCtrl->getContentExtent().y ) 3236 heightDelta = pt.y - scrollCtrl->getChildRelPos().y - scrollCtrl->getContentExtent().y; 3237 3238 const F32 SCROLL_RATIO = 0.5f; 3239 scrollCtrl->scrollDelta( S32( F32( widthDelta ) * SCROLL_RATIO ), S32( F32( heightDelta ) * SCROLL_RATIO ) ); 3240 } 3241 3242 // whats our mDragMidPoint? 3243 mCurrentDragCell = mMouseOverCell.y; 3244 S32 midpCell = mCurrentDragCell * mItemHeight + (mItemHeight/2); 3245 S32 currentY = pt.y; 3246 S32 yDiff = currentY-midpCell; 3247 S32 variance = (mItemHeight/5); 3248 if( mPreviousDragCell >= 0 && mPreviousDragCell < mVisibleItems.size() ) 3249 mVisibleItems[mPreviousDragCell]->mState.clear( Item::MouseOverBmp | Item::MouseOverText | Item::MouseOverIcon ); 3250 3251 bool hoverItem = false; 3252 3253 if (mAbs(yDiff) <= variance) 3254 { 3255 mDragMidPoint = NomDragMidPoint; 3256 // highlight the current item 3257 // hittest to detect whether we are on an item 3258 // ganked from onMouseMouse 3259 3260 // used for tracking what our last cell was so we can clear it. 3261 mPreviousDragCell = mCurrentDragCell; 3262 if (mCurrentDragCell >= 0) 3263 { 3264 3265 Item* item = NULL; 3266 BitSet32 hitFlags = 0; 3267 if ( !_hitTest( event.mousePoint, item, hitFlags ) ) 3268 return; 3269 3270 // If the item is a valid drag target, activate the item 3271 // highlighting. 3272 3273 if( isValidDragTarget( item ) ) 3274 { 3275 hoverItem = true; 3276 3277 if ( hitFlags.test( OnImage ) ) 3278 item->mState.set( Item::MouseOverBmp ); 3279 3280 if ( hitFlags.test( OnText ) ) 3281 item->mState.set( Item::MouseOverText ); 3282 3283 if ( hitFlags.test( OnIcon ) ) 3284 item->mState.set( Item::MouseOverIcon ); 3285 3286 // Always redraw the entire mouse over item, since we are distinguishing 3287 // between the bitmap and the text: 3288 setUpdateRegion( Point2I( mMouseOverCell.x * mCellSize.x, mMouseOverCell.y * mCellSize.y ), mCellSize ); 3289 } 3290 } 3291 } 3292 3293 if ( !hoverItem ) 3294 { 3295 //above or below an item? 3296 if (yDiff < 0) 3297 mDragMidPoint = AbovemDragMidPoint; 3298 else 3299 mDragMidPoint = BelowmDragMidPoint; 3300 } 3301} 3302 3303//----------------------------------------------------------------------------- 3304 3305void GuiTreeViewCtrl::onMiddleMouseDown(const GuiEvent & event) 3306{ 3307 //for debugging items 3308 if (mDebug) { 3309 Item* item; 3310 BitSet32 hitFlags = 0; 3311 _hitTest( event.mousePoint, item, hitFlags ); 3312 Con::printf("debugging %d", item->mId); 3313 Point2I pt = globalToLocalCoord(event.mousePoint); 3314 if (item->isInspectorData() && item->getObject()) { 3315 Con::printf("object data:"); 3316 Con::printf("name:%s",item->getObject()->getName()); 3317 Con::printf("className:%s",item->getObject()->getClassName()); 3318 } 3319 Con::printf("contents of mSelectedItems:"); 3320 for(S32 i = 0; i < mSelectedItems.size(); i++) { 3321 if (mSelectedItems[i]->isInspectorData()) { 3322 Con::printf("%d",mSelectedItems[i]->getObject()->getId()); 3323 } else 3324 Con::printf("wtf %d", mSelectedItems[i]); 3325 } 3326 Con::printf("contents of mSelected"); 3327 for (S32 j = 0; j < mSelected.size(); j++) { 3328 Con::printf("%d", mSelected[j]); 3329 } 3330 mCurrentDragCell = mMouseOverCell.y; 3331 S32 midpCell = (mCurrentDragCell) * mItemHeight + (mItemHeight/2); 3332 S32 currentY = pt.y; 3333 S32 yDiff = currentY-midpCell; 3334 Con::printf("cell info: (%d,%d) mCurrentDragCell=%d est=(%d,%d,%d) ydiff=%d",pt.x,pt.y,mCurrentDragCell,mCurrentDragCell*mItemHeight, midpCell, (mCurrentDragCell+1)*mItemHeight,yDiff); 3335 } 3336} 3337 3338//----------------------------------------------------------------------------- 3339 3340void GuiTreeViewCtrl::onMouseDown(const GuiEvent & event) 3341{ 3342 if( !mActive || !mAwake || !mVisible ) 3343 { 3344 Parent::onMouseDown(event); 3345 return; 3346 } 3347 if ( mProfile->mCanKeyFocus ) 3348 setFirstResponder(); 3349 3350 Item * item = 0; 3351 BitSet32 hitFlags; 3352 mDragMidPoint = NomDragMidPoint; 3353 3354 mMouseDragged = false; 3355 mMouseDownPoint = event.mousePoint; 3356 3357 // 3358 if(!_hitTest(event.mousePoint, item, hitFlags)) 3359 return; 3360 3361 mPossibleRenameItem = NULL; 3362 mRenamingItem = NULL; 3363 mTempItem = NULL; 3364 3365 // 3366 if( event.modifier & SI_MULTISELECT ) 3367 { 3368 bool selectFlag = item->mState.test(Item::Selected); 3369 if (selectFlag == true) 3370 { 3371 // already selected, so unselect it and remove it 3372 removeSelection(item->mId); 3373 } 3374 else 3375 { 3376 addSelection(item->mId); 3377 } 3378 } 3379 else if( event.modifier & SI_RANGESELECT && mMultipleSelections ) 3380 { 3381 // is something already selected? 3382 S32 firstSelectedIndex = 0; 3383 Item * firstItem = NULL; 3384 if (!mSelectedItems.empty()) 3385 { 3386 firstItem = mSelectedItems.front(); 3387 for (S32 i = 0; i < mVisibleItems.size();i++) 3388 { 3389 if (mVisibleItems[i] == mSelectedItems.front()) 3390 { 3391 firstSelectedIndex = i; 3392 break; 3393 } 3394 } 3395 mCurrentDragCell = mMouseOverCell.y; 3396 if (mVisibleItems[firstSelectedIndex] != firstItem ) 3397 { 3398 /* 3399 Con::printf("something isn't right..."); 3400 if (mVisibleItems[firstSelectedIndex]->isInspectorData()) 3401 Con::printf("visibleItem %s",mVisibleItems[firstSelectedIndex]->getObject()->getName()); 3402 if (firstItem->isInspectorData()) 3403 Con::printf("firstItem %s",firstItem->getObject()->getName()); 3404 */ 3405 } 3406 else 3407 { 3408 // select the cells 3409 onAddMultipleSelectionBegin_callback(); 3410 if ((mCurrentDragCell) < firstSelectedIndex) 3411 { 3412 //select up 3413 for (S32 j = (mCurrentDragCell); j < firstSelectedIndex; j++) 3414 { 3415 if( j != (firstSelectedIndex - 1) ) 3416 addSelection(mVisibleItems[j]->mId, false, false); 3417 else 3418 addSelection(mVisibleItems[j]->mId, false); 3419 } 3420 } 3421 else 3422 { 3423 // select down 3424 for (S32 j = firstSelectedIndex+1; j < (mCurrentDragCell+1); j++) 3425 { 3426 if( j != mCurrentDragCell ) 3427 addSelection(mVisibleItems[j]->mId, false, false); 3428 else 3429 addSelection(mVisibleItems[j]->mId, false); 3430 } 3431 } 3432 3433 // Scroll to view the last selected cell. 3434 scrollVisible( mVisibleItems[mCurrentDragCell] ); 3435 3436 onAddMultipleSelectionEnd_callback(); 3437 } 3438 } 3439 } 3440 else if ( event.modifier & SI_PRIMARY_ALT ) 3441 { 3442 if ( item->isInspectorData() && item->getObject() ) 3443 setAddGroup(item->getObject()); 3444 } 3445 else if ( !hitFlags.test(OnImage) ) 3446 { 3447 mTempItem = item; 3448 3449 bool wasSelected = isSelected( item ); 3450 bool multiSelect = getSelectedItemsCount() > 1; 3451 3452 if( !wasSelected || !multiSelect ) 3453 { 3454 if ( mClearAllOnSingleSelection ) 3455 clearSelection(); 3456 3457 if ( !wasSelected || mClearAllOnSingleSelection ) 3458 addSelection( item->mId ); 3459 3460 if ( wasSelected && 3461 !multiSelect && 3462 mCanRenameObjects && 3463 hitFlags.test(OnText) && 3464 mFlags.test(IsEditable) && 3465 item->isInspectorData() && 3466 item->getObject() && 3467 item->getObject()->isNameChangeAllowed() && 3468 item != mRoot && 3469 event.mouseClickCount == 1 ) 3470 { 3471 mPossibleRenameItem = item; 3472 3473 if ( isMethod( "canRenameObject" ) ) 3474 { 3475 if( canRenameObject_callback( item->getObject() ) ) 3476 mPossibleRenameItem = NULL; 3477 } 3478 } 3479 } 3480 3481 } 3482 3483 if ( ( hitFlags.test( OnText ) || hitFlags.test( OnIcon ) ) && 3484 event.mouseClickCount > 1 ) 3485 execAltConsoleCallback(); 3486 3487 // For dragging, note if hit is in selection. 3488 3489 mDragStartInSelection = isItemSelected( item->mId ); 3490 3491 if(!item->isParent()) 3492 return; 3493 3494 // 3495 if ( mFullRowSelect || hitFlags.test( OnImage ) ) 3496 { 3497 item->setExpanded(!item->isExpanded()); 3498 if( !item->isInspectorData() && item->mState.test(Item::VirtualParent) ) 3499 onVirtualParentExpand(item); 3500 3501 mFlags.set( RebuildVisible ); 3502 scrollVisible(item); 3503 } 3504} 3505 3506//------------------------------------------------------------------------------ 3507 3508void GuiTreeViewCtrl::onMouseMove( const GuiEvent &event ) 3509{ 3510 if ( mMouseOverCell.y >= 0 && mVisibleItems.size() > mMouseOverCell.y) 3511 mVisibleItems[mMouseOverCell.y]->mState.clear( Item::MouseOverBmp | Item::MouseOverText | Item::MouseOverIcon); 3512 3513 Parent::onMouseMove( event ); 3514 3515 if ( mMouseOverCell.y >= 0 ) 3516 { 3517 Item* item = NULL; 3518 BitSet32 hitFlags = 0; 3519 if ( !_hitTest( event.mousePoint, item, hitFlags ) ) 3520 return; 3521 3522 if ( hitFlags.test( OnImage ) ) 3523 item->mState.set( Item::MouseOverBmp ); 3524 3525 if ( hitFlags.test( OnText ) ) 3526 item->mState.set( Item::MouseOverText ); 3527 3528 if ( hitFlags.test( OnIcon ) ) 3529 item->mState.set( Item::MouseOverIcon ); 3530 3531 // Always redraw the entire mouse over item, since we are distinguishing 3532 // between the bitmap and the text: 3533 setUpdateRegion( Point2I( mMouseOverCell.x * mCellSize.x, mMouseOverCell.y * mCellSize.y ), mCellSize ); 3534 } 3535} 3536 3537//------------------------------------------------------------------------------ 3538 3539void GuiTreeViewCtrl::onMouseEnter( const GuiEvent &event ) 3540{ 3541 Parent::onMouseEnter( event ); 3542 onMouseMove( event ); 3543} 3544 3545//------------------------------------------------------------------------------ 3546 3547void GuiTreeViewCtrl::onMouseLeave( const GuiEvent &event ) 3548{ 3549 if ( mMouseOverCell.y >= 0 && mVisibleItems.size() > mMouseOverCell.y) 3550 mVisibleItems[mMouseOverCell.y]->mState.clear( Item::MouseOverBmp | Item::MouseOverText | Item::MouseOverIcon ); 3551 3552 Parent::onMouseLeave( event ); 3553} 3554 3555//------------------------------------------------------------------------------ 3556 3557void GuiTreeViewCtrl::onRightMouseDown(const GuiEvent & event) 3558{ 3559 if(!mActive) 3560 { 3561 Parent::onRightMouseDown(event); 3562 return; 3563 } 3564 3565 Item * item = NULL; 3566 BitSet32 hitFlags; 3567 3568 // 3569 if(!_hitTest(event.mousePoint, item, hitFlags)) 3570 return; 3571 3572 // 3573 3574 if (item->isInspectorData() && item->getObject()) 3575 onRightMouseDown_callback( item->mId, event.mousePoint, item->getObject() ); 3576 else 3577 onRightMouseDown_callback( item->mId, event.mousePoint ); 3578} 3579 3580//----------------------------------------------------------------------------- 3581 3582void GuiTreeViewCtrl::onRightMouseUp(const GuiEvent & event) 3583{ 3584 Item *item = NULL; 3585 BitSet32 hitFlags; 3586 3587 if ( !_hitTest( event.mousePoint, item, hitFlags ) ) 3588 return; 3589 3590 if ( hitFlags.test( OnText ) || hitFlags.test( OnIcon ) ) 3591 { 3592 if ( !isItemSelected( item->getID() ) ) 3593 { 3594 clearSelection(); 3595 addSelection( item->getID() ); 3596 } 3597 3598 if (item->isInspectorData() && item->getObject()) 3599 onRightMouseUp_callback( item->mId, event.mousePoint, item->getObject() ); 3600 else 3601 onRightMouseUp_callback( item->mId, event.mousePoint ); 3602 } 3603 else 3604 { 3605 clearSelection(); 3606 } 3607 3608 Parent::onRightMouseUp(event); 3609} 3610 3611//------------------------------------------------------------------------------ 3612 3613void GuiTreeViewCtrl::onRender(Point2I offset, const RectI &updateRect) 3614{ 3615 if ( !mRenamingItem && mRenameCtrl ) 3616 { 3617 mRenameCtrl->deleteObject(); 3618 mRenameCtrl = NULL; 3619 } 3620 3621 // Get all our contents drawn! 3622 Parent::onRender(offset,updateRect); 3623 3624 // Deal with drawing the drag & drop line, if any... 3625 GFX->setClipRect(updateRect); 3626 3627 // only do it if we have a mDragMidPoint 3628 if (mDragMidPoint == NomDragMidPoint || !mSupportMouseDragging ) 3629 return; 3630 3631 ColorI greyLine(128,128,128); 3632 Point2F squarePt; 3633 3634 // CodeReview: LineWidth is not supported in Direct3D. This is lame. [5/10/2007 Pat] 3635 // draw mDragMidPoint lines with a diamond 3636 if (mDragMidPoint == AbovemDragMidPoint) 3637 { 3638 S32 tempY = mItemHeight*mCurrentDragCell+offset.y ; 3639 squarePt.y = (F32)tempY; 3640 squarePt.x = 125.f+offset.x; 3641 GFX->getDrawUtil()->drawLine(0+offset.x, tempY, 250+offset.x, tempY,greyLine); 3642 GFX->getDrawUtil()->draw2DSquare(squarePt, 6, 90 ); 3643 3644 } 3645 if (mDragMidPoint == BelowmDragMidPoint) 3646 { 3647 S32 tempY2 = mItemHeight*(mCurrentDragCell+1) +offset.y; 3648 squarePt.y = (F32)tempY2; 3649 squarePt.x = 125.f+offset.x; 3650 GFX->getDrawUtil()->drawLine(0+offset.x, tempY2, 250+offset.x, tempY2,greyLine); 3651 GFX->getDrawUtil()->draw2DSquare(squarePt,6, 90 ); 3652 } 3653} 3654 3655//----------------------------------------------------------------------------- 3656 3657void GuiTreeViewCtrl::onRenderCell(Point2I offset, Point2I cell, bool, bool ) 3658{ 3659 if( !mVisibleItems.size() ) 3660 return; 3661 3662 // Do some sanity checking and data retrieval. 3663 AssertFatal(cell.y < mVisibleItems.size(), "GuiTreeViewCtrl::onRenderCell: invalid cell"); 3664 Item * item = mVisibleItems[cell.y]; 3665 3666 // If there's no object, deal with it. 3667 if(item->isInspectorData()) 3668 if(!item->getObject()) 3669 return; 3670 3671 RectI drawRect( offset, mCellSize ); 3672 GFXDrawUtil *drawer = GFX->getDrawUtil(); 3673 drawer->clearBitmapModulation(); 3674 3675 FrameAllocatorMarker txtBuff; 3676 3677 // Ok, we have the item. There are a few possibilities at this point: 3678 // - We need to draw inheritance lines and a treeview-chosen icon 3679 // OR 3680 // - We have to draw an item-dependent icon 3681 // - If we're mouseover, we have to highlight it. 3682 // 3683 // - We have to draw the text for the item 3684 // - Taking into account various mouseover states 3685 // - Taking into account the value (set or not) 3686 // - If it's an inspector data, we have to do some custom rendering 3687 // - ADDED: If it is being renamed, we also have custom rendering. 3688 3689 // Ok, first draw the tab and icon. 3690 3691 // Do we draw the tree lines? 3692 if( mFlags.test(ShowTreeLines) ) 3693 { 3694 drawRect.point.x += ( mTabSize * item->mTabLevel ); 3695 Item* parent = item->mParent; 3696 for ( S32 i = item->mTabLevel; ( parent && i > 0 ); i-- ) 3697 { 3698 drawRect.point.x -= mTabSize; 3699 if ( parent->mNext ) 3700 drawer->drawBitmapSR( mProfile->mTextureObject, drawRect.point, mProfile->mBitmapArrayRects[BmpLine] ); 3701 3702 parent = parent->mParent; 3703 } 3704 } 3705 3706 // Now, the icon... 3707 drawRect.point.x = offset.x + mTabSize * item->mTabLevel; 3708 3709 // First, draw the rollover glow, if it's an inner node. 3710 if ( item->isParent() && item->mState.test( Item::MouseOverBmp ) ) 3711 drawer->drawBitmapSR( mProfile->mTextureObject, drawRect.point, mProfile->mBitmapArrayRects[BmpGlow] ); 3712 3713 // Now, do we draw a treeview-selected item or an item dependent one? 3714 S32 newOffset = 0; // This is stored so we can render glow, then update render pos. 3715 3716 S32 bitmap = 0; 3717 3718 // Ok, draw the treeview lines as appropriate. 3719 3720 bool drawBitmap = true; 3721 if ( !item->isParent() ) 3722 { 3723 if( mFlags.test( ShowTreeLines ) ) 3724 { 3725 if( ( item->mNext && item->mPrevious ) 3726 || ( item->mNext && item->mParent && ( !_isRootLevelItem( item ) || mShowRoot ) ) ) 3727 bitmap = BmpChild; 3728 else if( item->mNext && ( !item->mParent || !mShowRoot ) ) 3729 bitmap = BmpFirstChild; 3730 else if( item->mPrevious || ( item->mParent && !_isRootLevelItem( item ) ) ) 3731 bitmap = BmpLastChild; 3732 else 3733 drawBitmap = false; 3734 } 3735 else 3736 drawBitmap = false; 3737 } 3738 else 3739 { 3740 bitmap = item->isExpanded() ? BmpExp : BmpCon; 3741 3742 if( mFlags.test( ShowTreeLines ) ) 3743 { 3744 // Shift indices to show versions with tree lines. 3745 3746 if ( item->mParent || item->mPrevious ) 3747 bitmap += ( item->mNext ? 3 : 2 ); 3748 else 3749 bitmap += ( item->mNext ? 1 : 0 ); 3750 } 3751 } 3752 3753 if( ( bitmap >= 0 ) && ( bitmap < mProfile->mBitmapArrayRects.size() ) ) 3754 { 3755 if( drawBitmap ) 3756 drawer->drawBitmapSR( mProfile->mTextureObject, drawRect.point, mProfile->mBitmapArrayRects[bitmap] ); 3757 newOffset = mProfile->mBitmapArrayRects[bitmap].extent.x; 3758 } 3759 3760 if(item->isInspectorData()) 3761 { 3762 // draw lock icon if need be 3763 S32 icon = Lock1; 3764 S32 icon2 = Hidden; 3765 3766 if (item->getObject() && item->getObject()->isLocked()) 3767 { 3768 if (mIconTable[icon]) 3769 { 3770 //drawRect.point.x = offset.x + mTabSize * item->mTabLevel + mIconTable[icon].getWidth(); 3771 drawRect.point.x += mIconTable[icon].getWidth(); 3772 drawer->drawBitmap( mIconTable[icon], drawRect.point ); 3773 } 3774 } 3775 3776 if (item->getObject() && item->getObject()->isHidden()) 3777 { 3778 if (mIconTable[icon2]) 3779 { 3780 //drawRect.point.x = offset.x + mTabSize * item->mTabLevel + mIconTable[icon].getWidth(); 3781 drawRect.point.x += mIconTable[icon2].getWidth(); 3782 drawer->drawBitmap( mIconTable[icon2], drawRect.point ); 3783 } 3784 } 3785 3786 SimObject * pObject = item->getObject(); 3787 SimGroup * pGroup = ( pObject == NULL ) ? NULL : dynamic_cast<SimGroup*>( pObject ); 3788 3789 // If this item is a VirtualParent we can use the generic SimGroup123 icons. 3790 // However if there is already an icon in the EditorIconRegistry for this 3791 // exact class (not counting parent class icons) we want to use that instead. 3792 bool hasClassIcon = false; 3793#ifdef TORQUE_TOOLS 3794 hasClassIcon = gEditorIcons.hasIconNoRecurse( pObject ); 3795#endif 3796 3797 // draw the icon associated with the item 3798 if ( !hasClassIcon && item->mState.test(Item::VirtualParent)) 3799 { 3800 if ( pGroup != NULL) 3801 { 3802 //Check if we're a SceneObject, and pick the default icon as appropriate 3803 3804 if (pObject->getClassName() != String("SimGroup")) 3805 { 3806 item->mIcon = Icon31; 3807 } 3808 else 3809 { 3810 //If we're purely a SimGroup, pick our icon. 3811 if (item->isExpanded()) 3812 item->mIcon = SimGroup1; 3813 else 3814 item->mIcon = SimGroup2; 3815 } 3816 } 3817 else 3818 item->mIcon = SimGroup2; 3819 } 3820 3821 if ( !hasClassIcon && item->mState.test(Item::Marked)) 3822 { 3823 if (item->isInspectorData()) 3824 { 3825 if ( pGroup != NULL ) 3826 { 3827 if (item->isExpanded()) 3828 item->mIcon = SimGroup3; 3829 else 3830 item->mIcon = SimGroup4; 3831 } 3832 } 3833 } 3834 3835 GFXTexHandle iconHandle; 3836 3837 if ( ( item->mIcon != -1 ) && mIconTable[item->mIcon] ) 3838 iconHandle = mIconTable[item->mIcon]; 3839#ifdef TORQUE_TOOLS 3840 else 3841 iconHandle = gEditorIcons.findIcon( item->getObject() ); 3842#endif 3843 3844 if ( iconHandle.isValid() ) 3845 { 3846 S32 iconHeight = (mItemHeight - iconHandle.getHeight()) / 2; 3847 S32 oldHeight = drawRect.point.y; 3848 if(iconHeight > 0) 3849 drawRect.point.y += iconHeight; 3850 drawRect.point.x += iconHandle.getWidth(); 3851 drawer->drawBitmap( iconHandle, drawRect.point ); 3852 drawRect.point.y = oldHeight; 3853 } 3854 } 3855 else 3856 { 3857 S32 icon = item->isExpanded() ? item->mScriptInfo.mExpandedImage : item->mScriptInfo.mNormalImage; 3858 if ( icon ) 3859 { 3860 if (mIconTable[icon]) 3861 { 3862 S32 iconHeight = (mItemHeight - mIconTable[icon].getHeight()) / 2; 3863 S32 oldHeight = drawRect.point.y; 3864 if(iconHeight > 0) 3865 drawRect.point.y += iconHeight; 3866 drawRect.point.x += mIconTable[icon].getWidth(); 3867 drawer->drawBitmap( mIconTable[icon], drawRect.point ); 3868 drawRect.point.y = oldHeight; 3869 } 3870 } 3871 } 3872 3873 // Ok, update offset so we can render some text! 3874 drawRect.point.x += newOffset; 3875 3876 // Ok, now we're off to rendering the actual data for the treeview item. 3877 3878 U32 bufLen = 1024; //item->mDataRenderWidth + 1; 3879 char *displayText = (char *)txtBuff.alloc(bufLen); 3880 displayText[bufLen-1] = 0; 3881 item->getDisplayText(bufLen, displayText); 3882 3883 // Draw the rollover/selected bitmap, if one was specified. 3884 drawRect.extent.x = mProfile->mFont->getStrWidth( displayText ) + ( 2 * mTextOffset ); 3885 if ( item->mState.test( Item::Selected ) && mTexSelected ) 3886 drawer->drawBitmapStretch( mTexSelected, drawRect ); 3887 else if ( item->mState.test( Item::MouseOverText ) && mTexRollover ) 3888 drawer->drawBitmapStretch( mTexRollover, drawRect ); 3889 3890 // Offset a bit so as to space text properly. 3891 drawRect.point.x += mTextOffset; 3892 3893 // Determine what color the font should be. 3894 ColorI fontColor; 3895 3896 fontColor = item->mState.test( Item::Selected ) ? mProfile->mFontColorSEL : 3897 ( item->mState.test( Item::MouseOverText ) ? mProfile->mFontColorHL : mProfile->mFontColor ); 3898 3899 if (item->mState.test(Item::Selected)) 3900 { 3901 drawer->drawRectFill(drawRect, mProfile->mFillColorSEL); 3902 } 3903 else if (item->mState.test(Item::MouseOverText)) 3904 { 3905 drawer->drawRectFill(drawRect, mProfile->mFillColorHL); 3906 } 3907 3908 if( item->mState.test(Item::MouseOverText) ) 3909 { 3910 fontColor = mProfile->mFontColorHL; 3911 } 3912 3913 drawer->setBitmapModulation( fontColor ); 3914 3915 // Center the text horizontally. 3916 S32 height = (mItemHeight - mProfile->mFont->getHeight()) / 2; 3917 3918 if(height > 0) 3919 drawRect.point.y += height; 3920 3921 // JDD - offset by two pixels or so to keep the text from rendering RIGHT ONTOP of the outline 3922 drawRect.point.x += 2; 3923 3924 drawer->drawText( mProfile->mFont, drawRect.point, displayText, mProfile->mFontColors ); 3925 3926 if ( mRenamingItem == item && mRenameCtrl ) 3927 { 3928 Point2I ctrPos = globalToLocalCoord( drawRect.point ); 3929 ctrPos.y -= height; 3930 ctrPos.x -= 2; 3931 3932 Point2I ctrExtent( getWidth() - ctrPos.x, drawRect.extent.y ); 3933 3934 mRenameCtrl->setPosition( ctrPos ); 3935 mRenameCtrl->setExtent( ctrExtent ); 3936 mRenameCtrl->setVisible( true ); 3937 } 3938} 3939 3940//------------------------------------------------------------------------------ 3941 3942bool GuiTreeViewCtrl::renderTooltip( const Point2I &hoverPos, const Point2I& cursorPos, const char* tipText ) 3943{ 3944 Item* item; 3945 BitSet32 flags = 0; 3946 if( _hitTest( cursorPos, item, flags ) && (!item->mTooltip.isEmpty() || mUseInspectorTooltips) ) 3947 { 3948 bool render = true; 3949 3950 if( mTooltipOnWidthOnly && !item->hasObjectBasedTooltip() ) 3951 { 3952 // Only render tooltip if the item's text is cut off with its 3953 // parent scroll control, unless there is custom object-based 3954 // tooltip information. 3955 GuiScrollCtrl *pScrollParent = dynamic_cast<GuiScrollCtrl*>( getParent() ); 3956 if ( pScrollParent ) 3957 { 3958 Point2I textStart; 3959 Point2I textExt; 3960 3961 const Point2I pos = globalToLocalCoord(cursorPos); 3962 textStart.y = pos.y / mCellSize.y; 3963 textStart.y *= mCellSize.y; 3964 3965 // The following is taken from _hitTest() 3966 textStart.x = mTabSize * item->mTabLevel; 3967 S32 image = BmpChild; 3968 if((image >= 0) && (image < mProfile->mBitmapArrayRects.size())) 3969 textStart.x += mProfile->mBitmapArrayRects[image].extent.x; 3970 textStart.x += mTextOffset; 3971 3972 textStart.x += getInspectorItemIconsWidth( item ); 3973 3974 FrameAllocatorMarker txtAlloc; 3975 U32 bufLen = item->getDisplayTextLength() + 1; 3976 char *buf = (char*)txtAlloc.alloc(bufLen); 3977 item->getDisplayText(bufLen, buf); 3978 textExt.x = mProfile->mFont->getStrWidth(buf); 3979 textExt.y = mProfile->mFont->getHeight(); 3980 3981 if( pScrollParent->isRectCompletelyVisible(RectI(textStart, textExt)) ) 3982 render = false; 3983 } 3984 } 3985 3986 if( render ) 3987 { 3988 if( mUseInspectorTooltips ) 3989 { 3990 char buf[2048]; 3991 item->getTooltipText( sizeof( buf ), buf ); 3992 tipText = buf; 3993 } 3994 else 3995 { 3996 tipText = item->mTooltip.c_str(); 3997 } 3998 } 3999 } 4000 4001 return defaultTooltipRender( cursorPos, cursorPos, tipText ); 4002} 4003 4004//------------------------------------------------------------------------------ 4005 4006void GuiTreeViewCtrl::clearSelection() 4007{ 4008 if( mDebug ) Con::printf( "clearSelection called" ); 4009 4010 while ( !mSelectedItems.empty() ) 4011 { 4012 removeSelection( mSelectedItems.last()->mId ); 4013 } 4014 4015 mSelectedItems.clear(); 4016 mSelected.clear(); 4017 4018 onClearSelection(); 4019 onClearSelection_callback(); 4020} 4021 4022//----------------------------------------------------------------------------- 4023 4024void GuiTreeViewCtrl::lockSelection(bool lock) 4025{ 4026 for(U32 i = 0; i < mSelectedItems.size(); i++) 4027 { 4028 if(mSelectedItems[i]->isInspectorData()) 4029 mSelectedItems[i]->getObject()->setLocked(lock); 4030 } 4031} 4032 4033//----------------------------------------------------------------------------- 4034 4035void GuiTreeViewCtrl::hideSelection(bool hide) 4036{ 4037 for(U32 i = 0; i < mSelectedItems.size(); i++) 4038 { 4039 if(mSelectedItems[i]->isInspectorData()) 4040 mSelectedItems[i]->getObject()->setHidden(hide); 4041 } 4042} 4043 4044//----------------------------------------------------------------------------- 4045 4046void GuiTreeViewCtrl::toggleLockSelection() 4047{ 4048 for(U32 i = 0; i < mSelectedItems.size(); i++) 4049 { 4050 if( mSelectedItems[i]->isInspectorData() ) 4051 { 4052 SimObject* object = mSelectedItems[ i ]->getObject(); 4053 object->setLocked( !object->isLocked() ); 4054 } 4055 } 4056} 4057 4058//----------------------------------------------------------------------------- 4059 4060void GuiTreeViewCtrl::toggleHideSelection() 4061{ 4062 for(U32 i = 0; i < mSelectedItems.size(); i++) 4063 { 4064 if( mSelectedItems[i]->isInspectorData() ) 4065 { 4066 SimObject* object = mSelectedItems[ i ]->getObject(); 4067 object->setHidden( !object->isHidden() ); 4068 } 4069 } 4070} 4071 4072//------------------------------------------------------------------------------ 4073 4074// handles icon assignments 4075S32 GuiTreeViewCtrl::getIcon(const char * iconString) 4076{ 4077 return -1; 4078} 4079 4080//----------------------------------------------------------------------------- 4081 4082GuiTreeViewCtrl::Item* GuiTreeViewCtrl::addInspectorDataItem(Item *parent, SimObject *obj) 4083{ 4084 S32 icon = getIcon(obj->getClassName()); 4085 Item *item = createItem(icon); 4086 item->mState.set(Item::InspectorData); 4087 4088 // Set the item text label flags. 4089 4090 if( !mShowObjectIds ) 4091 item->mState.clear( Item::ShowObjectId ); 4092 else 4093 item->mState.set( Item::ShowObjectId ); 4094 if( !mShowClassNames ) 4095 item->mState.clear( Item::ShowClassName ); 4096 else 4097 item->mState.set( Item::ShowClassName ); 4098 if( !mShowObjectNames ) 4099 item->mState.clear( Item::ShowObjectName ); 4100 else 4101 item->mState.set( Item::ShowObjectName ); 4102 if( !mShowInternalNames ) 4103 item->mState.clear( Item::ShowInternalName ); 4104 else 4105 item->mState.set( Item::ShowInternalName ); 4106 if( mShowClassNameForUnnamedObjects ) 4107 item->mState.set( Item::ShowClassNameForUnnamed ); 4108 4109 // Deal with child objects... 4110 if(dynamic_cast<SimSet*>(obj)) 4111 item->mState.set(Item::VirtualParent); 4112 4113 // Actually store the data! 4114 item->setObject(obj); 4115 4116 // Now add us to the data structure... 4117 if(parent) 4118 { 4119 // Add as child of parent. 4120 if(parent->mChild) 4121 { 4122 Item * traverse = parent->mChild; 4123 while(traverse->mNext) 4124 traverse = traverse->mNext; 4125 4126 traverse->mNext = item; 4127 item->mPrevious = traverse; 4128 } 4129 else 4130 parent->mChild = item; 4131 4132 item->mParent = parent; 4133 } 4134 else 4135 { 4136 // If no parent, add to root. 4137 item->mNext = mRoot; 4138 mRoot = item; 4139 item->mParent = NULL; 4140 } 4141 4142 mFlags.set(RebuildVisible); 4143 return item; 4144} 4145 4146//----------------------------------------------------------------------------- 4147 4148void GuiTreeViewCtrl::unlinkItem(Item * item) 4149{ 4150 if (item->mPrevious) 4151 item->mPrevious->mNext = item->mNext; 4152 4153 if (item->mNext) 4154 item->mNext->mPrevious = item->mPrevious; 4155} 4156 4157//----------------------------------------------------------------------------- 4158 4159bool GuiTreeViewCtrl::childSearch(Item * item, SimObject *obj, bool yourBaby) 4160{ 4161 Item * temp = item->mChild; 4162 while (temp) 4163 { 4164 //do you have my baby? 4165 if (temp->isInspectorData()) 4166 { 4167 if (temp->getObject() == obj) 4168 yourBaby = false; //probably a child of an inner script 4169 } 4170 yourBaby = childSearch(temp,obj, yourBaby); 4171 temp = temp->mNext; 4172 } 4173 return yourBaby; 4174} 4175 4176//----------------------------------------------------------------------------- 4177 4178void GuiTreeViewCtrl::inspectorSearch(Item * item, Item * parent, SimSet * parentSet, SimSet * newParentSet) 4179{ 4180 if (!parentSet||!newParentSet) 4181 return; 4182 4183 if (item == parent->mNext) 4184 return; 4185 4186 if (item) 4187 { 4188 if (item->isInspectorData()) 4189 { 4190 // remove the object from the parentSet and add it to the newParentSet 4191 SimObject* simObj = item->getObject(); 4192 4193 if (parentSet->size()) 4194 { 4195 SimObject *lastObject = parentSet->last(); 4196 parentSet->removeObject(simObj); 4197 parentSet->reOrder(lastObject); 4198 } 4199 else 4200 parentSet->removeObject(simObj); 4201 4202 newParentSet->addObject(simObj); 4203 4204 if (item->mNext) 4205 { 4206 inspectorSearch(item->mNext, parent, parentSet, newParentSet); 4207 return; 4208 } 4209 else 4210 { 4211 // end of children so backing up 4212 if (item->mParent == parent) 4213 return; 4214 else 4215 { 4216 inspectorSearch(item->mParent->mNext, parent, parentSet, newParentSet); 4217 return; 4218 } 4219 } 4220 } 4221 4222 if (item->mChild) 4223 { 4224 inspectorSearch(item->mChild, parent, parentSet, newParentSet); 4225 return; 4226 } 4227 4228 if (item->mNext) 4229 { 4230 inspectorSearch(item->mNext, parent, parentSet, newParentSet); 4231 return; 4232 } 4233 } 4234} 4235 4236//----------------------------------------------------------------------------- 4237 4238bool GuiTreeViewCtrl::objectSearch( const SimObject *object, Item **item ) 4239{ 4240 for ( U32 i = 0; i < mItems.size(); i++ ) 4241 { 4242 Item *pItem = mItems[i]; 4243 4244 if ( !pItem ) 4245 continue; 4246 4247 //A bit hackish, but we make a special exception here for items that are named 'Components', as they're merely 4248 //virtual parents to act as a container to an Entity's components 4249 if (pItem->mScriptInfo.mText == StringTable->insert("Components")) 4250 continue; 4251 4252 SimObject *pObj = pItem->getObject(); 4253 4254 if ( pObj && pObj == object ) 4255 { 4256 *item = pItem; 4257 return true; 4258 } 4259 } 4260 4261 return false; 4262} 4263 4264//----------------------------------------------------------------------------- 4265 4266bool GuiTreeViewCtrl::onVirtualParentBuild(Item *item, bool bForceFullUpdate) 4267{ 4268 if(!item->mState.test(Item::InspectorData)) 4269 return true; 4270 4271 // Blast an item if it doesn't have a corresponding SimObject... 4272 if(item->mInspectorInfo.mObject == NULL) 4273 { 4274 removeItem(item->mId); 4275 return false; 4276 } 4277 4278 // Skip the next stuff unless we're expanded... 4279 if(!item->isExpanded() && !bForceFullUpdate && !( item == mRoot && !mShowRoot ) ) 4280 return true; 4281 4282 // Verify that we have all the kids we should in here... 4283 SimSet *srcObj = dynamic_cast<SimSet*>(&(*item->mInspectorInfo.mObject)); 4284 4285 // If it's not a SimSet... WTF are we doing here? 4286 if(!srcObj) 4287 return true; 4288 4289 // This is slow but probably ok. 4290 for( SimSet::iterator i = srcObj->begin(); i != srcObj->end(); ++ i ) 4291 { 4292 SimObject *obj = *i; 4293 4294 // If we can't find it, add it. 4295 // unless it has a parent that is a child that is a script 4296 Item *res = item->findChildByValue(obj); 4297 4298 bool foundChild = true; 4299 4300 // search the children. if any of them are the parent of the object then don't add it. 4301 foundChild = childSearch(item,obj,foundChild); 4302 4303 if(!res && foundChild) 4304 { 4305 if (mDebug) Con::printf( "adding object %i to item %i", obj->getId(), item->mId ); 4306 res = addInspectorDataItem(item, obj); 4307 } 4308 4309 if( res ) 4310 res->mState.set( Item::RebuildVisited ); 4311 } 4312 4313 // Go through our items and purge those that have disappeared from 4314 // the set. 4315 for( Item* ptr = item->mChild; ptr != NULL; ) 4316 { 4317 Item* next = ptr->mNext; 4318 if( !ptr->mState.test( Item::RebuildVisited ) ) 4319 { 4320 if( mDebug ) Con::printf( "removing item %i for object %i that is no longer in the set", 4321 ptr->mId, ptr->getObject()->getId() ); 4322 4323 removeItem( ptr->mId, false ); 4324 } 4325 else 4326 ptr->mState.clear( Item::RebuildVisited ); 4327 4328 ptr = next; 4329 } 4330 4331 return true; 4332} 4333 4334//----------------------------------------------------------------------------- 4335 4336bool GuiTreeViewCtrl::onVirtualParentExpand(Item *item) 4337{ 4338 // Do nothing... 4339 return true; 4340} 4341 4342//----------------------------------------------------------------------------- 4343 4344bool GuiTreeViewCtrl::onVirtualParentCollapse(Item *item) 4345{ 4346 // Do nothing... 4347 return true; 4348} 4349 4350//----------------------------------------------------------------------------- 4351 4352void GuiTreeViewCtrl::inspectObject( SimObject* obj, bool okToEdit ) 4353{ 4354 _destroyTree(); 4355 4356 mFlags.set( IsEditable, okToEdit ); 4357 mFlags.set( IsInspector ); 4358 4359 onDefineIcons_callback(); 4360 4361 addInspectorDataItem( NULL, obj ); 4362} 4363 4364//----------------------------------------------------------------------------- 4365 4366S32 GuiTreeViewCtrl::insertObject( S32 parent, SimObject* obj, bool okToEdit ) 4367{ 4368 mFlags.set( IsEditable, okToEdit ); 4369 mFlags.set( IsInspector ); 4370 4371 //onDefineIcons_callback(); 4372 4373 GuiTreeViewCtrl::Item *item = addInspectorDataItem( getItem(parent), obj ); 4374 return item->getID(); 4375} 4376 4377//----------------------------------------------------------------------------- 4378 4379S32 GuiTreeViewCtrl::findItemByName(const char *name) 4380{ 4381 for (S32 i = 0; i < mItems.size(); i++) 4382 { 4383 if ( !mItems[i] ) 4384 continue; 4385 if( mItems[i]->mState.test( Item::InspectorData ) ) 4386 continue; 4387 if (mItems[i] && String::compare(mItems[i]->getText(),name) == 0) 4388 return mItems[i]->mId; 4389 } 4390 4391 return 0; 4392} 4393 4394//----------------------------------------------------------------------------- 4395 4396S32 GuiTreeViewCtrl::findItemByValue(const char *name) 4397{ 4398 for (S32 i = 0; i < mItems.size(); i++) 4399 { 4400 if (!mItems[i]) 4401 continue; 4402 if( mItems[i]->mState.test( Item::InspectorData ) ) 4403 continue; 4404 if (mItems[i] && String::compare(mItems[i]->getValue(),name) == 0) 4405 return mItems[i]->mId; 4406 } 4407 4408 return 0; 4409} 4410 4411//----------------------------------------------------------------------------- 4412 4413void GuiTreeViewCtrl::sortTree( bool caseSensitive, bool traverseHierarchy, bool parentsFirst ) 4414{ 4415 itemSortList( mRoot, caseSensitive, traverseHierarchy, parentsFirst ); 4416} 4417 4418//----------------------------------------------------------------------------- 4419 4420StringTableEntry GuiTreeViewCtrl::getTextToRoot( S32 itemId, const char * delimiter ) 4421{ 4422 Item * item = getItem(itemId); 4423 4424 if(!item) 4425 { 4426 Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getTextToRoot: invalid start item id!"); 4427 return StringTable->EmptyString(); 4428 } 4429 4430 if(item->isInspectorData()) 4431 { 4432 Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getTextToRoot: cannot get text to root of inspector data items"); 4433 return StringTable->EmptyString(); 4434 } 4435 4436 char bufferOne[1024]; 4437 char bufferTwo[1024]; 4438 char bufferNodeText[128]; 4439 4440 dMemset( bufferOne, 0, sizeof(bufferOne) ); 4441 dMemset( bufferTwo, 0, sizeof(bufferTwo) ); 4442 4443 dStrcpy( bufferOne, item->getText(), 1024 ); 4444 4445 Item *prevNode = item->mParent; 4446 while ( prevNode ) 4447 { 4448 dMemset( bufferNodeText, 0, sizeof(bufferNodeText) ); 4449 dStrcpy( bufferNodeText, prevNode->getText(), 128 ); 4450 dSprintf( bufferTwo, 1024, "%s%s%s",bufferNodeText, delimiter, bufferOne ); 4451 dStrcpy( bufferOne, bufferTwo, 1024 ); 4452 dMemset( bufferTwo, 0, sizeof(bufferTwo) ); 4453 prevNode = prevNode->mParent; 4454 } 4455 4456 // Return the result, StringTable-ized. 4457 return StringTable->insert( bufferOne, true ); 4458} 4459 4460//----------------------------------------------------------------------------- 4461 4462void GuiTreeViewCtrl::setFilterText( const String& text ) 4463{ 4464 mFilterText = text; 4465 4466 // Trigger rebuild. 4467 mFlags.set( RebuildVisible ); 4468} 4469 4470void GuiTreeViewCtrl::setItemFilterException(U32 item, bool isExempted) 4471{ 4472 if (isExempted) 4473 { 4474 mItemFilterExceptionList.push_back(item); 4475 } 4476 else 4477 { 4478 mItemFilterExceptionList.remove(item); 4479 } 4480} 4481 4482void GuiTreeViewCtrl::setItemHidden(U32 item, bool isHidden) 4483{ 4484 if (isHidden) 4485 { 4486 mHiddenItemsList.push_back(item); 4487 } 4488 else 4489 { 4490 mHiddenItemsList.remove(item); 4491 } 4492} 4493 4494void GuiTreeViewCtrl::reparentItems(Vector<Item*> selectedItems, Item* newParent) 4495{ 4496 for (S32 i = 0; i < selectedItems.size(); i++) 4497 { 4498 Item* item = selectedItems[i]; 4499 4500 if (mDebug) 4501 Con::printf("----------------------------"); 4502 4503 // clear old highlighting of the item 4504 item->mState.clear(Item::MouseOverBmp | Item::MouseOverText); 4505 4506 // move the selected item to the newParent 4507 Item * oldParent = item->mParent; 4508 // Snag the current parent set if any for future reference 4509 SimSet * parentSet = NULL; 4510 4511 if (oldParent != nullptr && oldParent->isInspectorData()) 4512 { 4513 parentSet = dynamic_cast<SimSet*>(oldParent->getObject()); 4514 } 4515 else 4516 { 4517 // parent is probably script data so we search up the tree for a 4518 // set to put our object in 4519 Item* temp = oldParent; 4520 while (temp) 4521 { 4522 if (temp->isInspectorData()) 4523 break; 4524 temp = temp->mParent; 4525 } 4526 // found an ancestor who is an inspectorData 4527 if (temp) 4528 { 4529 if (temp->isInspectorData()) 4530 parentSet = dynamic_cast<SimSet*>(temp->getObject()); 4531 } 4532 } 4533 4534 // unlink from the current position in the list 4535 unlinkItem(item); 4536 4537 // update the parent's children 4538 4539 // check if we an only child 4540 if (item->mParent && item->mParent->mChild == item) 4541 { 4542 if (item->mNext) 4543 item->mParent->mChild = item->mNext; 4544 else 4545 item->mParent->mChild = NULL; 4546 } 4547 4548 if (mDragMidPoint != NomDragMidPoint) 4549 { 4550 4551 //if it is below an expanded tree, place as last item in the tree 4552 //if it is below a parent who isn't expanded put below it 4553 4554 // position the item above or below another item 4555 if (mDragMidPoint == AbovemDragMidPoint) 4556 { 4557 // easier to treat everything as "Below the mDragMidPoint" so make some adjustments 4558 if (mDebug) 4559 Con::printf("adding item above mDragMidPoint"); 4560 4561 // above the mid point of an item, so grab either the parent 4562 // or the previous sibling 4563 4564 // does the item have a previous sibling? 4565 if (newParent->mPrevious) 4566 { 4567 newParent = newParent->mPrevious; 4568 4569 if (mDebug) 4570 Con::printf("treating as if below an item that isn't expanded"); 4571 4572 // otherwise add below that item as a sibling 4573 item->mParent = newParent->mParent; 4574 item->mPrevious = newParent; 4575 item->mNext = newParent->mNext; 4576 if (newParent->mNext) 4577 newParent->mNext->mPrevious = item; 4578 newParent->mNext = item; 4579 } 4580 else 4581 { 4582 if (mDebug) 4583 Con::printf("treating as if adding below the parent of the item"); 4584 4585 // instead we add as the first item below the newParent's parent 4586 item->mParent = newParent->mParent; 4587 item->mNext = newParent; 4588 item->mPrevious = NULL; 4589 newParent->mPrevious = item; 4590 item->mParent->mChild = item; 4591 } 4592 } 4593 else if (mDragMidPoint == BelowmDragMidPoint) 4594 { 4595 if ((newParent->isParent()) && (newParent->isExpanded())) 4596 { 4597 if (mDebug) 4598 Con::printf("adding item to an expanded parent below the mDragMidPoint"); 4599 4600 item->mParent = newParent; 4601 4602 // then add the new item as a child 4603 item->mNext = newParent->mChild; 4604 if (newParent->mChild) 4605 newParent->mChild->mPrevious = item; 4606 item->mParent->mChild = item; 4607 item->mPrevious = NULL; 4608 } 4609 else if ((!newParent->mNext) && (newParent->mParent) && (newParent->mParent->mParent)) 4610 { 4611 // add below it's parent. 4612 if (mDebug) 4613 Con::printf("adding below a tree"); 4614 4615 item->mParent = newParent->mParent->mParent; 4616 item->mNext = newParent->mParent->mNext; 4617 item->mPrevious = newParent->mParent; 4618 4619 if (newParent->mParent->mNext) 4620 newParent->mParent->mNext->mPrevious = item; 4621 4622 newParent->mParent->mNext = item; 4623 } 4624 else 4625 { 4626 // adding below item not as a child 4627 if (mDebug) 4628 Con::printf("adding item below the mDragMidPoint of an item"); 4629 4630 item->mParent = newParent->mParent; 4631 // otherwise the item is a sibling 4632 if (newParent->mNext) 4633 newParent->mNext->mPrevious = item; 4634 item->mNext = newParent->mNext; 4635 item->mPrevious = newParent; 4636 newParent->mNext = item; 4637 } 4638 } 4639 } 4640 // if we're not allowed to add to items, then try to add to the parent of the hit item. 4641 // if we are, just add to the item we hit. 4642 else 4643 { 4644 if (mDebug) 4645 { 4646 if (item->isInspectorData() && item->getObject()) 4647 Con::printf("Item: %i", item->getObject()->getId()); 4648 if (newParent->isInspectorData() && newParent->getObject()) 4649 Con::printf("Parent: %i", newParent->getObject()->getId()); 4650 Con::printf("dragged onto an item"); 4651 } 4652 4653 // If the hit item is not a valid drag target, 4654 // then try to add to the parent. 4655 4656 if (!isValidDragTarget(newParent)) 4657 { 4658 // add to the item's parent. 4659 if (!newParent->mParent || !newParent->mParent->isParent()) 4660 { 4661 if (mDebug) 4662 Con::printf("could not find the parent of that item. dragging to an item is not allowed, kicking out."); 4663 mDragMidPoint = NomDragMidPoint; 4664 continue; 4665 } 4666 newParent = newParent->mParent; 4667 } 4668 4669 // new parent is the item in the current cell 4670 item->mParent = newParent; 4671 4672 // adjust children if any 4673 if (newParent->mChild) 4674 { 4675 if (mDebug) Con::printf("not the first child"); 4676 4677 // put it at the top of the list (easier to find if there are many children) 4678 if (newParent->mChild) 4679 newParent->mChild->mPrevious = item; 4680 item->mNext = newParent->mChild; 4681 newParent->mChild = item; 4682 item->mPrevious = NULL; 4683 } 4684 else 4685 { 4686 if (mDebug) Con::printf("first child"); 4687 4688 // only child 4689 newParent->mChild = item; 4690 item->mNext = NULL; 4691 item->mPrevious = NULL; 4692 } 4693 } 4694 4695 // expand the item we added to, if it isn't expanded already 4696 if (!item->mParent->mState.test(Item::Expanded)) 4697 setItemExpanded(item->mParent->mId, true); 4698 4699 //---------------------------------------------------------------- 4700 // handle objects 4701 4702 // Get our active SimObject if any 4703 SimObject* simObj = NULL; 4704 if (item->isInspectorData()) 4705 { 4706 simObj = item->getObject(); 4707 } 4708 4709 // Remove from the old parentset 4710 if ((simObj && parentSet) && (oldParent != item->mParent)) 4711 { 4712 if (mDebug) 4713 Con::printf("removing item from old parentset"); 4714 4715 // hack to get around the way removeObject takes the last item of the set 4716 // and moves it into the place of the object we removed 4717 if (parentSet->size() > 0) 4718 { 4719 SimObject* lastObject = parentSet->last(); 4720 parentSet->removeObject(simObj); 4721 parentSet->reOrder(lastObject); 4722 } 4723 else 4724 { 4725 parentSet->removeObject(simObj); 4726 } 4727 } 4728 4729 // Snag the newparent set if any... 4730 SimSet* newParentSet = NULL; 4731 4732 if (item->mParent->isInspectorData()) 4733 { 4734 if (mDebug) 4735 Con::printf("getting a new parent set"); 4736 4737 SimObject* tmpObj = item->mParent->getObject(); 4738 newParentSet = dynamic_cast<SimSet*>(tmpObj); 4739 } 4740 else 4741 { 4742 // parent is probably script data so we search up the tree for a 4743 // set to put our object in 4744 if (mDebug) 4745 Con::printf("oh nos my parent is script!"); 4746 4747 Item* temp = item->mParent; 4748 while (temp) 4749 { 4750 if (temp->isInspectorData()) 4751 break; 4752 temp = temp->mParent; 4753 } 4754 4755 // found a ancestor who is an inspectorData 4756 if (temp) 4757 { 4758 if (temp->isInspectorData()) 4759 newParentSet = dynamic_cast<SimSet*>(temp->getObject()); 4760 } 4761 else 4762 { 4763 newParentSet = NULL; 4764 } 4765 } 4766 4767 if (simObj && newParentSet) 4768 { 4769 if (mDebug) 4770 Con::printf("simobj and new ParentSet"); 4771 4772 if (oldParent != item->mParent) 4773 newParentSet->addObject(simObj); 4774 4775 //order the objects in the simset according to their 4776 //order in the tree view control 4777 if (!item->mNext) 4778 { 4779 if (item->mPrevious) 4780 { 4781 //bring to the end of the set 4782 SimObject* prevObject = item->mPrevious->getObject(); 4783 if (prevObject && item->getObject()) 4784 { 4785 newParentSet->reOrder(item->getObject(), prevObject); 4786 } 4787 } 4788 } 4789 else 4790 { 4791 //reorder within the set 4792 SimObject* nextObject = item->mNext->getObject(); 4793 if (nextObject && item->getObject()) 4794 { 4795 newParentSet->reOrder(item->getObject(), nextObject); 4796 } 4797 } 4798 } 4799 else if (!simObj && newParentSet) 4800 { 4801 // our current item is script data. but it may have children who 4802 // is inspector data who need an updated set 4803 if (mDebug) 4804 Con::printf("no simobj but new parentSet"); 4805 if (item->mChild) 4806 inspectorSearch(item->mChild, item, parentSet, newParentSet); 4807 4808 } 4809 else if (simObj && !newParentSet) 4810 { 4811 if (mDebug) 4812 Con::printf("simobject and no new parent set"); 4813 } 4814 else 4815 if (mDebug) 4816 Con::printf("no simobject and no new parent set"); 4817 4818 // Notify script. 4819 4820 if (item->isInspectorData()) 4821 { 4822 if (item->getObject() && (oldParent && oldParent->getObject()) && item->mParent->getObject()) 4823 onReparent_callback( 4824 item->getObject()->getId(), 4825 oldParent->getObject()->getId(), 4826 item->mParent->getObject()->getId() 4827 ); 4828 } 4829 else 4830 { 4831 onReparent_callback( 4832 item->mId, 4833 oldParent->mId, 4834 item->mParent->mId 4835 ); 4836 } 4837 } 4838} 4839 4840S32 GuiTreeViewCtrl::getTabLevel(S32 itemId) 4841{ 4842 Item* item = getItem(itemId); 4843 if (item != nullptr) 4844 { 4845 return item->mTabLevel; 4846 } 4847 4848 return 0; 4849} 4850//============================================================================= 4851// Console Methods. 4852//============================================================================= 4853// MARK: ---- Console Methods ---- 4854 4855//----------------------------------------------------------------------------- 4856 4857DefineEngineMethod( GuiTreeViewCtrl, findItemByName, S32, ( const char* text ),, 4858 "Get the ID of the item whose text matches the given @a text.\n\n" 4859 "@param text Item text to match.\n" 4860 "@return ID of the item or -1 if no item matches the given text." ) 4861{ 4862 return object->findItemByName( text ); 4863} 4864 4865//----------------------------------------------------------------------------- 4866 4867DefineEngineMethod( GuiTreeViewCtrl, findItemByValue, S32, ( const char* value ),, 4868 "Get the ID of the item whose value matches @a value.\n\n" 4869 "@param value Value text to match.\n" 4870 "@return ID of the item or -1 if no item has the given value." ) 4871{ 4872 return object->findItemByValue( value ); 4873} 4874 4875//----------------------------------------------------------------------------- 4876 4877DefineEngineMethod( GuiTreeViewCtrl, findChildItemByName, S32, ( S32 parentId, const char* childName ),, 4878 "Get the child item of the given parent item whose text matches @a childName.\n\n" 4879 "@param parentId Item ID of the parent in which to look for the child.\n" 4880 "@param childName Text of the child item to find.\n" 4881 "@return ID of the child item or -1 if no child in @a parentId has the given text @a childName.\n\n" 4882 "@note This method does not recurse, i.e. it only looks for direct children." ) 4883{ 4884 if( parentId == 0 ) 4885 { 4886 if( !object->getRootItem() ) 4887 return 0; 4888 4889 GuiTreeViewCtrl::Item* root = object->getRootItem(); 4890 while( root ) 4891 { 4892 if( dStricmp( root->getText(), childName ) == 0 ) 4893 return root->getID(); 4894 4895 root = root->mNext; 4896 } 4897 4898 return 0; 4899 } 4900 else 4901 { 4902 GuiTreeViewCtrl::Item* item = object->getItem( parentId ); 4903 4904 if( !item ) 4905 { 4906 Con::errorf( "GuiTreeViewCtrl.findChildItemByName - invalid parent ID '%i'", parentId ); 4907 return 0; 4908 } 4909 4910 GuiTreeViewCtrl::Item* child = item->findChildByName( childName ); 4911 if( !child ) 4912 return 0; 4913 4914 return child->mId; 4915 } 4916} 4917 4918//----------------------------------------------------------------------------- 4919 4920DefineEngineMethod( GuiTreeViewCtrl, insertItem, S32, ( S32 parentId, const char* text, const char* value, const char* icon, S32 normalImage, S32 expandedImage ), ( "", "", 0, 0 ), 4921 "Add a new item to the tree.\n\n" 4922 "@param parentId Item ID of parent to which to add the item as a child. 0 is root item.\n" 4923 "@param text Text to display on the item in the tree.\n" 4924 "@param value Behind-the-scenes value of the item.\n" 4925 "@param icon\n" 4926 "@param normalImage\n" 4927 "@param expandedImage\n" 4928 "@return The ID of the newly added item." ) 4929{ 4930 return object->insertItem( parentId, text, value, icon, normalImage, expandedImage ); 4931} 4932 4933DefineEngineMethod( GuiTreeViewCtrl, insertObject, S32, ( S32 parentId, SimObject* obj, bool OKToEdit ), (false), "Inserts object as a child to the given parent." ) 4934{ 4935 return object->insertObject(parentId, obj, OKToEdit); 4936} 4937//----------------------------------------------------------------------------- 4938 4939DefineEngineMethod( GuiTreeViewCtrl, lockSelection, void, ( bool lock ), ( true ), 4940 "Set whether the current selection can be changed by the user or not.\n\n" 4941 "@param lock If true, the current selection is frozen and cannot be changed. If false, " 4942 "the selection may be modified." ) 4943{ 4944 object->lockSelection( lock ); 4945} 4946 4947//----------------------------------------------------------------------------- 4948 4949DefineEngineMethod( GuiTreeViewCtrl, hideSelection, void, ( bool state ), ( true ), 4950 "Call SimObject::setHidden( @a state ) on all objects in the current selection.\n\n" 4951 "@param state Visibility state to set objects in selection to." ) 4952{ 4953 object->hideSelection( state ); 4954} 4955 4956//----------------------------------------------------------------------------- 4957 4958DefineEngineMethod( GuiTreeViewCtrl, toggleLockSelection, void, (),, 4959 "Toggle the locked state of all objects in the current selection." ) 4960{ 4961 object->toggleLockSelection(); 4962 4963} 4964 4965//----------------------------------------------------------------------------- 4966 4967DefineEngineMethod( GuiTreeViewCtrl, toggleHideSelection, void, (),, 4968 "Toggle the hidden state of all objects in the current selection." ) 4969{ 4970 object->toggleHideSelection(); 4971} 4972 4973//----------------------------------------------------------------------------- 4974 4975DefineEngineMethod( GuiTreeViewCtrl, clearSelection, void, (),, 4976 "Unselect all currently selected items." ) 4977{ 4978 object->clearSelection(); 4979} 4980 4981//----------------------------------------------------------------------------- 4982 4983DefineEngineMethod( GuiTreeViewCtrl, deleteSelection, void, (),, 4984 "Delete all items/objects in the current selection." ) 4985{ 4986 object->deleteSelection(); 4987} 4988 4989//----------------------------------------------------------------------------- 4990 4991DefineEngineMethod( GuiTreeViewCtrl, addSelection, void, ( S32 id, bool isLastSelection ), ( true ), 4992 "Add an item/object to the current selection.\n\n" 4993 "@param id ID of item/object to add to the selection.\n" 4994 "@param isLastSelection Whether there are more pending items/objects to be added to the selection. If false, " 4995 "the control will defer refreshing the tree and wait until addSelection() is called with this parameter set " 4996 "to true." ) 4997{ 4998 object->addSelection( id, isLastSelection, isLastSelection ); 4999} 5000 5001DefineEngineMethod( GuiTreeViewCtrl, addChildSelectionByValue, void, ( S32 parentId, const char* value), , 5002 "Add a child selection by it's value.\n\n" 5003 "@param parentId Parent TreeItemId.\n" 5004 "@param value Value to search for.\n") 5005{ 5006 GuiTreeViewCtrl::Item* parentItem = object->getItem(parentId); 5007 GuiTreeViewCtrl::Item* child = parentItem->findChildByValue(value); 5008 object->addSelection(child->getID()); 5009} 5010 5011DefineEngineMethod( GuiTreeViewCtrl, removeSelection, void, ( S32 itemId), , 5012 "Deselect an item or remove it from the selection.\n\n" 5013 "@param itemId Item Id to deselect.\n") 5014{ 5015 object->removeSelection(itemId); 5016} 5017 5018DefineEngineMethod( GuiTreeViewCtrl, removeChildSelectionByValue, void, ( S32 parentId, const char* value), , 5019 "Deselect a child item or remove it from the selection based on its parent and its value.\n\n" 5020 "@param parentId Parent TreeItemId.\n" 5021 "@param value Value to search for.\n" 5022 "@param performCallback True to notify script of the change, false to not.\n") 5023{ 5024 GuiTreeViewCtrl::Item* parentItem = object->getItem(parentId); 5025 if(parentItem) 5026 { 5027 GuiTreeViewCtrl::Item* child = parentItem->findChildByValue(value); 5028 if(child) 5029 { 5030 object->removeSelection(child->getID()); 5031 } 5032 } 5033} 5034 5035DefineEngineMethod( GuiTreeViewCtrl, selectItem, bool, ( S32 itemID, bool select), (true) , 5036 "Select or deselect and item.\n\n" 5037 "@param itemID TreeItemId of item to select or deselect.\n" 5038 "@param select True to select the item, false to deselect it.\n" 5039 "@return True if it was successful, false if not.") 5040{ 5041 return object->setItemSelected(itemID, select); 5042} 5043 5044DefineEngineMethod( GuiTreeViewCtrl, expandItem, bool, ( S32 itemID, bool expand), (true) , 5045 "Expand/contract item, item's sub-tree.\n\n" 5046 "@param itemID TreeItemId of item to expand or contract.\n" 5047 "@param expand True to expand the item, false to contract it.\n" 5048 "@return True if it was successful, false if not.") 5049{ 5050 return(object->setItemExpanded(itemID, expand)); 5051} 5052 5053DefineEngineMethod( GuiTreeViewCtrl, markItem, bool, ( S32 itemID, bool mark), (true) , 5054 "Mark/unmark item.\n\n" 5055 "@param itemID TreeItemId of item to Mark or unmark.\n" 5056 "@param mark True to Mark the item, false to unmark it.\n" 5057 "@return True if it was successful, false if not.") 5058{ 5059 return object->markItem(itemID, mark); 5060} 5061 5062DefineEngineMethod( GuiTreeViewCtrl, scrollVisible, bool, ( S32 itemID), , 5063 "Make the given item visible.\n\n" 5064 "@param itemID TreeItemId of item to scroll to/make visible.\n" 5065 "@return True if it was successful, false if not.") 5066{ 5067 return object->scrollVisible(itemID); 5068} 5069 5070DefineEngineMethod( GuiTreeViewCtrl, buildIconTable, bool, ( const char* icons), , 5071 "Builds an icon table.\n\n" 5072 "@param icons Name of icons to build, Icons should be designated by the bitmap/png file names (minus the file extensions)" 5073 "and separated by colons (:). This list should be synchronized with the Icons enum\n" 5074 "@return True if it was successful, false if not.") 5075{ 5076 return object->buildIconTable(icons); 5077} 5078 5079DefineEngineMethod( GuiTreeViewCtrl, open, void, ( const char * objName, bool okToEdit), (true), 5080 "Set the root of the tree view to the specified object, or to the root set.\n\n" 5081 "@param objName Name or id of SimSet or object to set the tree root equal to.\n") 5082{ 5083 SimSet *treeRoot = NULL; 5084 SimObject* target = Sim::findObject(objName); 5085 5086 5087 if (target) 5088 treeRoot = dynamic_cast<SimSet*>(target); 5089 5090 if (! treeRoot) 5091 Sim::findObject(RootGroupId, treeRoot); 5092 5093 object->inspectObject(treeRoot,okToEdit); 5094} 5095 5096DefineEngineMethod( GuiTreeViewCtrl, setItemTooltip, bool, ( S32 itemId, const char* tooltip), , 5097 "Set the tooltip to show for the given item.\n\n" 5098 "@param itemId TreeItemID of item to set the tooltip for.\n" 5099 "@param tooltip String tooltip to set for the item." 5100 "@return True if successfully found the item, false if not") 5101{ 5102 GuiTreeViewCtrl::Item* item = object->getItem( itemId ); 5103 if( !item ) 5104 { 5105 Con::errorf( "GuiTreeViewCtrl::setTooltip() - invalid item id '%i'", itemId ); 5106 return false; 5107 } 5108 5109 item->mTooltip = tooltip; 5110 5111 return true; 5112} 5113 5114DefineEngineMethod( GuiTreeViewCtrl, setItemImages, void, ( S32 itemId, S8 normalImage, S8 expandedImage ), , 5115 "Sets the normal and expanded images to show for the given item.\n\n" 5116 "@param itemId TreeItemID of item to set images for.\n" 5117 "@param normalImage Normal image to set for the given item." 5118 "@param expandedImage Expanded image to set for the given item.") 5119{ 5120 5121 GuiTreeViewCtrl::Item* item = object->getItem( itemId ); 5122 if( !item ) 5123 { 5124 Con::errorf( "GuiTreeViewCtrl::setItemImages() - invalid item id '%i'", itemId ); 5125 return; 5126 } 5127 5128 item->setNormalImage(normalImage); 5129 item->setExpandedImage(expandedImage); 5130} 5131 5132DefineEngineMethod( GuiTreeViewCtrl, isParentItem, bool, ( S32 itemId ), , 5133 "Returns true if the given item contains child items.\n\n" 5134 "@param itemId TreeItemID to check for children.\n" 5135 "@return True if the given item contains child items, false if not.") 5136{ 5137 if( !itemId && object->getItemCount() ) 5138 return true; 5139 5140 GuiTreeViewCtrl::Item* item = object->getItem( itemId ); 5141 if( !item ) 5142 { 5143 Con::errorf( "GuiTreeViewCtrl::isParentItem - invalid item id '%i'", itemId ); 5144 return false; 5145 } 5146 5147 return item->isParent(); 5148} 5149 5150DefineEngineMethod( GuiTreeViewCtrl, getItemText, const char *, ( S32 itemId ), , 5151 "Gets the text for a given item.\n\n" 5152 "@param itemId TreeItemID to get text of.\n" 5153 "@return Text for a given item.") 5154{ 5155 return(object->getItemText(itemId)); 5156} 5157 5158DefineEngineMethod( GuiTreeViewCtrl, getItemValue, const char *, ( S32 itemId ), , 5159 "Gets the value for a given item.\n\n" 5160 "@param itemId TreeItemID to get value of.\n" 5161 "@return Value for a given item.") 5162{ 5163 return object->getItemValue(itemId); 5164} 5165 5166DefineEngineMethod( GuiTreeViewCtrl, editItem, bool, ( S32 itemId, const char* newText, const char* newValue ), , 5167 "Edits the text and value for a given tree item.\n\n" 5168 "@param itemId TreeItemID to edit.\n" 5169 "@return True if successful, false if not.") 5170{ 5171 return(object->editItem(itemId, newText, newValue)); 5172} 5173 5174DefineEngineMethod( GuiTreeViewCtrl, removeItem, bool, (S32 itemId, bool deleteObjects), (0, true), 5175 "Remove an item from the tree with the given id.\n\n" 5176 "@param itemId TreeItemID of item to remove.\n" 5177 "@param deleteObjects Whether the object on the item is deleted when the item is.\n" 5178 "@return True if successful, false if not.") 5179{ 5180 return(object->removeItem(itemId, deleteObjects)); 5181} 5182 5183DefineEngineMethod( GuiTreeViewCtrl, removeAllChildren, void, (S32 itemId), , 5184 "Remove all children of an item from the tree with the given id.\n\n" 5185 "@param itemId TreeItemID of item that has children we should remove.\n") 5186{ 5187 object->removeAllChildren(itemId); 5188} 5189 5190DefineEngineMethod( GuiTreeViewCtrl, clear, void, (), , 5191 "Empty the tree.\n") 5192{ 5193 object->removeItem(0); 5194} 5195 5196DefineEngineMethod( GuiTreeViewCtrl, getFirstRootItem, S32, (), , 5197 "Get id for root item.\n" 5198 "@return Id for root item.") 5199{ 5200 return(object->getFirstRootItem()); 5201} 5202 5203DefineEngineMethod( GuiTreeViewCtrl, getChild, S32, (S32 itemId), , 5204 "Get the child of the parent with the given id.\n\n" 5205 "@param itemId TreeItemID of item that a child we should get.\n" 5206 "@return Id of child of given item.") 5207{ 5208 return(object->getChildItem(itemId)); 5209} 5210 5211DefineEngineMethod( GuiTreeViewCtrl, buildVisibleTree, void, (bool forceFullUpdate), (false), 5212 "Build the visible tree.\n\n" 5213 "@param forceFullUpdate True to force a full update of the tree, false to only update the new stuff.\n") 5214{ 5215 object->buildVisibleTree( forceFullUpdate ); 5216} 5217 5218//FIXME: [rene 11/09/09 - This clashes with GuiControl.getParent(); bad thing; should be getParentItem] 5219DefineEngineMethod( GuiTreeViewCtrl, getParentItem, S32, (S32 itemId), , 5220 "Get the parent of a given id in the tree.\n\n" 5221 "@param itemId TreeItemID of item that has a parent we should get.\n" 5222 "@return Id of parent of given item.") 5223{ 5224 return(object->getParentItem(itemId)); 5225} 5226 5227DefineEngineMethod( GuiTreeViewCtrl, getNextSibling, S32, (S32 itemId), , 5228 "Get the next sibling of the given item id in the tree.\n\n" 5229 "@param itemId TreeItemID of item that we want the next sibling of.\n" 5230 "@return Id of next sibling of the given item.") 5231{ 5232 return(object->getNextSiblingItem(itemId)); 5233} 5234 5235DefineEngineMethod( GuiTreeViewCtrl, getPrevSibling, S32, (S32 itemId), , 5236 "Get the previous sibling of the given item id in the tree.\n\n" 5237 "@param itemId TreeItemID of item that we want the previous sibling of.\n" 5238 "@return Id of previous sibling of the given item.") 5239{ 5240 return(object->getPrevSiblingItem(itemId)); 5241} 5242 5243DefineEngineMethod( GuiTreeViewCtrl, getItemCount, S32, (), , 5244 "Get the total number of items in the tree or item count.\n\n" 5245 "@return total number of items in the tree.") 5246{ 5247 return(object->getItemCount()); 5248} 5249 5250DefineEngineMethod( GuiTreeViewCtrl, getSelectedItem, S32, (S32 index), (0), 5251 "Return the selected item at the given index.\n\n" 5252 "@param index Given index to look for selected item." 5253 "@return selected item at the given index.") 5254{ 5255 return ( object->getSelectedItem( index ) ); 5256} 5257 5258DefineEngineMethod( GuiTreeViewCtrl, getSelectedObject, S32, (S32 index), (0), 5259 "Return the currently selected SimObject at the given index in inspector mode or -1.\n\n" 5260 "@param index Given index to look for selected object." 5261 "@return currently selected SimObject at the given index in inspector mode or -1.") 5262{ 5263 GuiTreeViewCtrl::Item *item = object->getItem( object->getSelectedItem( index ) ); 5264 if( item != NULL && item->isInspectorData() ) 5265 { 5266 SimObject *obj = item->getObject(); 5267 if( obj != NULL ) 5268 return obj->getId(); 5269 } 5270 5271 return -1; 5272} 5273 5274const char* GuiTreeViewCtrl::getSelectedObjectList() 5275{ 5276 static const U32 bufSize = 1024; 5277 char* buff = Con::getReturnBuffer(bufSize); 5278 dSprintf(buff,bufSize,""); 5279 5280 5281 const Vector< GuiTreeViewCtrl::Item*> selectedItems = this->getSelectedItems(); 5282 for(S32 i = 0; i < selectedItems.size(); i++) 5283 { 5284 GuiTreeViewCtrl::Item *item = selectedItems[i]; 5285 5286 if ( item->isInspectorData() && item->getObject() ) 5287 { 5288 S32 id = item->getObject()->getId(); 5289 //get the current length of the buffer 5290 U32 len = dStrlen(buff); 5291 //the start of the buffer where we want to write 5292 char* buffPart = buff+len; 5293 //the size of the remaining buffer (-1 cause dStrlen doesn't count the \0) 5294 S32 size = bufSize-len-1; 5295 //write it: 5296 if(size < 1) 5297 { 5298 Con::errorf("GuiTreeViewCtrl::getSelectedItemList - Not enough room to return our object list"); 5299 return buff; 5300 } 5301 5302 dSprintf(buffPart,size,"%d ", id); 5303 } 5304 } 5305 5306 return buff; 5307} 5308 5309DefineEngineMethod( GuiTreeViewCtrl, getSelectedObjectList, const char*, (), , 5310 "Returns a space separated list of all selected object ids.\n\n" 5311 "@return space separated list of all selected object ids.") 5312{ 5313 return object->getSelectedObjectList(); 5314} 5315 5316DefineEngineMethod( GuiTreeViewCtrl, moveItemUp, void, (S32 itemId), , 5317 "Move the specified item up in the tree.\n\n" 5318 "@param itemId TreeItemId of item to move up in the tree.") 5319{ 5320 object->moveItemUp( itemId ); 5321} 5322 5323DefineEngineMethod( GuiTreeViewCtrl, getSelectedItemsCount, S32, (), , 5324 "Get the selected number of items.\n\n" 5325 "@return number of selected items.") 5326{ 5327 return ( object->getSelectedItemsCount() ); 5328} 5329 5330DefineEngineMethod( GuiTreeViewCtrl, moveItemDown, void, (S32 itemId), , 5331 "Move the specified item down in the tree.\n\n" 5332 "@param itemId TreeItemId of item to move down in the tree.") 5333{ 5334 object->moveItemDown( itemId ); 5335} 5336 5337//----------------------------------------------------------------------------- 5338 5339DefineEngineMethod( GuiTreeViewCtrl, getTextToRoot, const char*, (S32 itemId, const char* delimiter), (""), 5340 "Gets the text from the current node to the root, concatenating at each branch upward, with a specified delimiter optionally.\n\n" 5341 "@param itemId TreeItemId of node to start at." 5342 "@param delimiter (Optional) delimiter to use between each branch concatenation." 5343 "@return text from the current node to the root.") 5344{ 5345 if (!String::compare(delimiter, "" )) 5346 { 5347 Con::warnf("GuiTreeViewCtrl::getTextToRoot - Invalid number of arguments!"); 5348 return (""); 5349 } 5350 return object->getTextToRoot( itemId, delimiter ); 5351} 5352 5353DefineEngineMethod( GuiTreeViewCtrl, getSelectedItemList, const char*, (), , 5354 "Returns a space separated list if ids of all selected items.\n\n" 5355 "@return space separated list of selected item ids.") 5356{ 5357 const U32 bufSize = 1024; 5358 char* buff = Con::getReturnBuffer(bufSize); 5359 dSprintf(buff, bufSize, ""); 5360 5361 const Vector< S32>& selected = object->getSelected(); 5362 for(int i = 0; i < selected.size(); i++) 5363 { 5364 S32 id = selected[i]; 5365 //get the current length of the buffer 5366 U32 len = dStrlen(buff); 5367 //the start of the buffer where we want to write 5368 char* buffPart = buff+len; 5369 //the size of the remaining buffer (-1 cause dStrlen doesn't count the \0) 5370 S32 size = bufSize-len-1; 5371 //write it: 5372 if(size < 1) 5373 { 5374 Con::errorf("GuiTreeViewCtrl::getSelectedItemList - Not enough room to return our object list"); 5375 return buff; 5376 } 5377 5378 dSprintf(buffPart,size,"%d ", id); 5379 } 5380//mSelected 5381 5382 return buff; 5383} 5384 5385S32 GuiTreeViewCtrl::findItemByObjectId(S32 iObjId) 5386{ 5387 for (S32 i = 0; i < mItems.size(); i++) 5388 { 5389 if ( !mItems[i] ) 5390 continue; 5391 5392 SimObject* pObj = mItems[i]->getObject(); 5393 if( pObj && pObj->getId() == iObjId ) 5394 return mItems[i]->mId; 5395 } 5396 5397 return -1; 5398} 5399 5400//------------------------------------------------------------------------------ 5401DefineEngineMethod( GuiTreeViewCtrl, findItemByObjectId, S32, (S32 objectId), , 5402 "Find an item by its object id and returns the Tree Item ID for it.\n\n" 5403 "@param objectId Object id you want the item id for." 5404 "@return Tree Item Id for the given object ID.") 5405{ 5406 return(object->findItemByObjectId(objectId)); 5407} 5408 5409//------------------------------------------------------------------------------ 5410S32 GuiTreeViewCtrl::getItemObject(S32 itemId) 5411{ 5412 GuiTreeViewCtrl::Item* item = getItem(itemId); 5413 if (!item) 5414 { 5415 return 0; 5416 } 5417 5418 SimObject* pObj = item->getObject(); 5419 if (pObj) 5420 return pObj->getId(); 5421 5422 return 0; 5423} 5424 5425//------------------------------------------------------------------------------ 5426DefineEngineMethod(GuiTreeViewCtrl, getItemObject, S32, (S32 itemId), , 5427 "Gets the object for a particular item.\n\n" 5428 "@param itemId Item id you want the object id for." 5429 "@return Object Id for the given tree item ID.") 5430{ 5431 return(object->getItemObject(itemId)); 5432} 5433 5434//------------------------------------------------------------------------------ 5435bool GuiTreeViewCtrl::scrollVisibleByObjectId(S32 objID) 5436{ 5437 S32 itemID = findItemByObjectId(objID); 5438 5439 if(itemID == -1) 5440 { 5441 // we did not find the item in our current items 5442 // we should try to find and show the parent of the item. 5443 SimObject *obj = Sim::findObject(objID); 5444 if(!obj || !obj->getGroup()) 5445 return false; 5446 5447 // if we can't show the parent, we fail. 5448 if(! scrollVisibleByObjectId(obj->getGroup()->getId()) ) 5449 return false; 5450 5451 // get the parent. expand the parent. rebuild the tree. this ensures that 5452 // we'll be able to find the child item we're targeting. 5453 S32 parentID = findItemByObjectId(obj->getGroup()->getId()); 5454 AssertFatal(parentID != -1, "We were able to show the parent, but could not then find the parent. This should not happen."); 5455 Item *parentItem = getItem(parentID); 5456 parentItem->setExpanded(true); 5457 buildVisibleTree(); 5458 5459 // NOW we should be able to find the object. if not... something's wrong. 5460 itemID = findItemByObjectId(objID); 5461 AssertWarn(itemID != -1,"GuiTreeViewCtrl::scrollVisibleByObjectId() found the parent, but can't find it's immediate child. This should not happen."); 5462 if(itemID == -1) 5463 return false; 5464 } 5465 5466 // ok, item found. scroll to it. 5467 mFlags.set( RebuildVisible ); 5468 scrollVisible(itemID); 5469 5470 return true; 5471} 5472 5473//------------------------------------------------------------------------------ 5474DefineEngineMethod( GuiTreeViewCtrl, scrollVisibleByObjectId, S32, (S32 objectId), , 5475 "Show item by object id.\n\n" 5476 "@param objectId Object id you want to scroll to." 5477 "@return True if successful, false if not.") 5478{ 5479 return(object->scrollVisibleByObjectId(objectId)); 5480} 5481 5482//------------------------------------------------------------------------------ 5483 5484//FIXME: this clashes with SimSet.sort() 5485DefineEngineMethod( GuiTreeViewCtrl, sort, void, (S32 parentId, bool traverseHierarchy, bool parentsFirst, bool caseSensitive), (0, false, false, true), 5486 "Sorts all items of the given parent (or root). With 'hierarchy', traverses hierarchy." 5487 "@param parentId TreeItemID of parent/root to sort all the items under. Use 0 to sort the entire tree." 5488 "@param traverseHierarchy True to traverse the hierarchy, false to not." 5489 "@param parentsFirst True to sort the parents first." 5490 "@param caseSensitive True to pay attention to case, false to ignore it.") 5491{ 5492 5493 if( !parentId ) 5494 object->sortTree( caseSensitive, traverseHierarchy, parentsFirst ); 5495 else 5496 { 5497 GuiTreeViewCtrl::Item* item = object->getItem( parentId ); 5498 if( !item ) 5499 { 5500 Con::errorf( "GuiTreeViewCtrl::sort - no item '%i' in tree", parentId ); 5501 return; 5502 } 5503 5504 item->sort( caseSensitive, traverseHierarchy, parentsFirst ); 5505 } 5506} 5507 5508void GuiTreeViewCtrl::cancelRename() 5509{ 5510 if ( !mRenamingItem || !mRenameCtrl ) 5511 return; 5512 5513 mRenamingItem = NULL; 5514 5515 if ( mRenameCtrl ) 5516 mRenameCtrl->clearFirstResponder(); 5517} 5518 5519void GuiTreeViewCtrl::onRenameValidate() 5520{ 5521 if ( !mRenamingItem || !mRenameCtrl ) 5522 return; 5523 5524 char data[ GuiTextCtrl::MAX_STRING_LENGTH+1 ]; 5525 mRenameCtrl->getText( data ); 5526 5527 SimObject *obj = mRenamingItem->getObject(); 5528 5529 mRenamingItem = NULL; 5530 5531 // Object could have been deleted in the interum. 5532 if ( !obj ) 5533 return; 5534 5535 if( isMethod( "handleRenameObject" ) && handleRenameObject_callback( data, obj ) ) 5536 return; 5537 5538 if ( mRenameInternal ) 5539 obj->setInternalName( data ); 5540 else 5541#ifdef TORQUE_TOOLS 5542 if ( validateObjectName( data, obj ) ) 5543#endif 5544 obj->assignName( data ); 5545} 5546 5547void GuiTreeViewCtrl::showItemRenameCtrl( Item* item ) 5548{ 5549 SimObject *renameObj = item->getObject(); 5550 5551 mRenamingItem = item; 5552 5553 if ( !mRenameCtrl ) 5554 { 5555 mRenameCtrl = new GuiTextEditCtrl; 5556 mRenameCtrl->registerObject(); 5557 addObject( mRenameCtrl ); 5558 5559 if ( mRenameInternal ) 5560 mRenameCtrl->setText( renameObj->getInternalName() ); 5561 else 5562 mRenameCtrl->setText( renameObj->getName() ); 5563 5564 mRenameCtrl->setFirstResponder(); 5565 mRenameCtrl->setSinkAllKeys(true); 5566 mRenameCtrl->selectAllText(); 5567 mRenameCtrl->setCursorPos(0); 5568 5569 char cmd[256]; 5570 dSprintf( cmd, 256, "%i.onRenameValidate();", getId() ); 5571 mRenameCtrl->setField( "validate", cmd ); 5572 5573 dSprintf( cmd, 256, "%i.cancelRename();", getId() ); 5574 mRenameCtrl->setField( "escapeCommand", cmd ); 5575 } 5576} 5577 5578DefineEngineMethod( GuiTreeViewCtrl, cancelRename, void, (), , "Cancel renaming an item (For internal use).") 5579{ 5580 object->cancelRename(); 5581} 5582 5583DefineEngineMethod( GuiTreeViewCtrl, onRenameValidate, void, (), , "Validate the new name for an object (For internal use).") 5584{ 5585 object->onRenameValidate(); 5586} 5587 5588DefineEngineMethod( GuiTreeViewCtrl, showItemRenameCtrl, void, (S32 itemId), , 5589 "Show the rename text field for the given item (only one at a time)." 5590 "@param itemId TreeItemId of item to show rename text field for.") 5591{ 5592 GuiTreeViewCtrl::Item* item = object->getItem( itemId ); 5593 if( !item ) 5594 { 5595 Con::errorf( "GuiTreeViewCtrl::showItemRenameCtrl - invalid item id '%i'", itemId ); 5596 return; 5597 } 5598 5599 object->showItemRenameCtrl( item ); 5600} 5601 5602DefineEngineMethod( GuiTreeViewCtrl, setDebug, void, (bool value), (true), 5603 "Enable/disable debug output." 5604 "@param value True to enable debug output, false to disable it.") 5605{ 5606 5607 object->setDebug( value ); 5608} 5609 5610//----------------------------------------------------------------------------- 5611 5612DefineEngineMethod( GuiTreeViewCtrl, isItemSelected, bool, ( S32 id ),, 5613 "Check whether the given item is currently selected in the tree.\n\n" 5614 "@param id Item/object ID.\n" 5615 "@return True if the given item/object is currently selected in the tree." ) 5616{ 5617 const Vector< GuiTreeViewCtrl::Item*>& selectedItems = object->getSelectedItems(); 5618 for( S32 i = 0; i < selectedItems.size(); ++ i ) 5619 if( selectedItems[ i ]->mId == id ) 5620 return true; 5621 5622 return false; 5623} 5624 5625//----------------------------------------------------------------------------- 5626 5627DefineEngineMethod( GuiTreeViewCtrl, getFilterText, const char*, (),, 5628 "Get the current filter expression. Only tree items whose text matches this expression " 5629 "are displayed. By default, the expression is empty and all items are shown.\n\n" 5630 "@return The current filter pattern or an empty string if no filter pattern is currently active.\n\n" 5631 "@see setFilterText\n" 5632 "@see clearFilterText" ) 5633{ 5634 return object->getFilterText(); 5635} 5636 5637//----------------------------------------------------------------------------- 5638 5639DefineEngineMethod( GuiTreeViewCtrl, setFilterText, void, ( const char* pattern ),, 5640 "Set the pattern by which to filter items in the tree. Only items in the tree whose text " 5641 "matches this pattern are displayed.\n\n" 5642 "@param pattern New pattern based on which visible items in the tree should be filtered. If empty, all items become visible.\n\n" 5643 "@see getFilterText\n" 5644 "@see clearFilterText" ) 5645{ 5646 object->setFilterText( pattern ); 5647} 5648 5649DefineEngineMethod(GuiTreeViewCtrl, setFilterChildren, void, (bool doFilterChildren), (true), 5650 "Set the pattern by which to filter items in the tree. Only items in the tree whose text " 5651 "matches this pattern are displayed.\n\n" 5652 "@param pattern New pattern based on which visible items in the tree should be filtered. If empty, all items become visible.\n\n" 5653 "@see getFilterText\n" 5654 "@see clearFilterText") 5655{ 5656 object->setFilterChildren(doFilterChildren); 5657} 5658 5659DefineEngineMethod(GuiTreeViewCtrl, setItemFilterException, void, (U32 item, bool isExempt), (0, true), 5660 "Set the pattern by which to filter items in the tree. Only items in the tree whose text " 5661 "matches this pattern are displayed.\n\n" 5662 "@param pattern New pattern based on which visible items in the tree should be filtered. If empty, all items become visible.\n\n" 5663 "@see getFilterText\n" 5664 "@see clearFilterText") 5665{ 5666 object->setItemFilterException(item, isExempt); 5667} 5668 5669DefineEngineMethod(GuiTreeViewCtrl, setItemHidden, void, (U32 item, bool hidden), (0, true), 5670 "Set the pattern by which to filter items in the tree. Only items in the tree whose text " 5671 "matches this pattern are displayed.\n\n" 5672 "@param pattern New pattern based on which visible items in the tree should be filtered. If empty, all items become visible.\n\n" 5673 "@see getFilterText\n" 5674 "@see clearFilterText") 5675{ 5676 object->setItemHidden(item, hidden); 5677} 5678 5679DefineEngineMethod(GuiTreeViewCtrl, clearHiddenItems, void, (),, 5680 "Set the pattern by which to filter items in the tree. Only items in the tree whose text " 5681 "matches this pattern are displayed.\n\n" 5682 "@param pattern New pattern based on which visible items in the tree should be filtered. If empty, all items become visible.\n\n" 5683 "@see getFilterText\n" 5684 "@see clearFilterText") 5685{ 5686 object->clearHiddenItems(); 5687} 5688//----------------------------------------------------------------------------- 5689 5690DefineEngineMethod( GuiTreeViewCtrl, clearFilterText, void, (),, 5691 "Clear the current item filtering pattern.\n\n" 5692 "@see setFilterText\n" 5693 "@see getFilterText" ) 5694{ 5695 object->clearFilterText(); 5696} 5697 5698DefineEngineMethod(GuiTreeViewCtrl, getItemAtPosition, S32, (Point2I position), (Point2I::Zero), 5699 "Get the tree item at the passed in position.\n\n" 5700 "@param position The position to check for what item is below it.\n" 5701 "@return The id of the item under the position.") 5702{ 5703 return object->getItemAtPosition(position); 5704} 5705 5706DefineEngineMethod(GuiTreeViewCtrl, reparentItem, void, (S32 itemId, S32 parentId), (0, 0), 5707 "Check whether the given item is currently selected in the tree.\n\n" 5708 "@param id Item/object ID.\n" 5709 "@return True if the given item/object is currently selected in the tree.") 5710{ 5711 if (itemId == parentId || itemId < 0 || parentId < 0) 5712 return; 5713 5714 const Vector< GuiTreeViewCtrl::Item*> & selectedItems = object->getItems(); 5715 Vector<GuiTreeViewCtrl::Item*> items; 5716 GuiTreeViewCtrl::Item * parent = nullptr; 5717 5718 for (S32 i = 0; i < selectedItems.size(); ++i) 5719 { 5720 if (selectedItems[i]->mId == itemId) 5721 { 5722 items.push_back(selectedItems[i]); 5723 } 5724 5725 if (selectedItems[i]->mId == parentId) 5726 { 5727 parent = selectedItems[i]; 5728 } 5729 } 5730 5731 if (!items.empty() && parent != nullptr) 5732 { 5733 object->reparentItems(items, parent); 5734 } 5735} 5736 5737DefineEngineMethod(GuiTreeViewCtrl, getTabLevel, S32, (S32 itemId), (0), 5738 "Get the tree item at the passed in position.\n\n" 5739 "@param position The position to check for what item is below it.\n" 5740 "@return The id of the item under the position.") 5741{ 5742 return object->getTabLevel(itemId); 5743} 5744