Guest User

Untitled

a guest
Jan 11th, 2026
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.20 KB | None | 0 0
  1. --//Rewrite of nodeTree which stores data by reference as opposed to by value
  2.  
  3. return function(plugin,pluginBase,dock)
  4.     ------------
  5.     --//VARS\\--
  6.     ------------
  7.  
  8.     --//constants
  9.     local UITemplates = pluginBase:WaitForChild("Storage"):WaitForChild("Templates"):WaitForChild("NodeTree2")
  10.     local pluginResource = pluginBase:WaitForChild("PluginCode"):WaitForChild("Core"):WaitForChild("Resource")
  11.     local button2 = require(pluginResource:WaitForChild("OOP"):WaitForChild("Button2"))(plugin,pluginBase)
  12.     local pluginConfig = require(pluginResource:WaitForChild("LocalSettings"))
  13.    
  14.     local contentObjects = {} --contentobjectName=contentobject
  15.     for _,v in script:WaitForChild("ContentTypes"):GetChildren() do --populate
  16.         contentObjects[v.Name] = require(v)(plugin,pluginBase,dock)
  17.     end
  18.    
  19.     -----------------
  20.     --//FUNCTIONS\\--
  21.     -----------------
  22.    
  23.     --//A lot of functions that are implemented in both tree and node are defined here, for consistency
  24.     local function getSubnode(self,subn)
  25.         if type(subn)=="number" then --subnode is index
  26.             return self.subnodes[subn]
  27.         elseif table.find(self.subnodes,subn) then --subnode is the actual node
  28.             return subn
  29.         else --subn may be nodes data
  30.             for _,v in self.subnodes do
  31.                 if v.data==subn then
  32.                     return v
  33.                 end
  34.             end
  35.         end
  36.     end
  37.    
  38.     local function removeNode(node,parentNode) --node to be removed, parentNode?.
  39.         --disconnect this branch from parent node
  40.         local subnodesTable = parentNode and parentNode.subnodes or node.parentNode.subnodes
  41.         table.remove(subnodesTable,table.find(subnodesTable,node))
  42.        
  43.         --clean node
  44.         node:SetState(false) --remove all connections of this
  45.         node:PrepareCleanup() --call :Delete on all add button objects
  46.         node.UIInstance:Destroy() --destroy UI
  47.         table.clear(node) --not strictly necessary, but helpful for debugging so if something is holding a stale reference to this node it will likley error.
  48.     end
  49.    
  50.     local function removeSubnode(self,subn)
  51.         local subn = getSubnode(self,subn)
  52.  
  53.         removeNode(subn,self)
  54.        
  55.         return subn
  56.     end
  57.    
  58.     -----------
  59.     --//OOP\\--
  60.     -----------
  61.    
  62.     --//OOP FOR NODE, NOT ROOT THOUGH.  SEE <TREE> BELOW FOR ROOT
  63.    
  64.     local node2 = {}
  65.     --nodeData is the data object this node corresponds to, implements __tostring if this is userdata
  66.     --parent node is the parent node data instance, or the root
  67.     --parent frame is where this node gets parented to
  68.     --contents table describes what UI elements we want in this node, array of {name,...} where ... is passed to the content object constructor
  69.     --add function is the function that gets called when the add button is clicked, or nil if we dont want an add button
  70.     function node2.new(nodeData,rootNode,parentNode,parentFrame,contentsTable,addFunction)
  71.         local self = setmetatable({},{__index=node2,
  72.             __iter = function(t)
  73.                 return next,t.subnodes
  74.             end
  75.         })
  76.  
  77.         self.data = nodeData --data object this node correlates to.  Should implement __tostring for display name
  78.  
  79.         self.rootNode = rootNode --points to root node instance
  80.         self.parentNode = parentNode --points to parent node
  81.         self.depth = parentNode.depth+1 --0 correspsonds to root node, each level down increases by 1.  this is the depth of THIS node
  82.         self.subnodes = {} --ordered array of subnodes
  83.  
  84.         self.contents = {} --Array of {contentObject}
  85.  
  86.         self.state = parentNode.state
  87.    
  88.         self.addFunction = addFunction
  89.         self.addButton = nil --defined as button object in the case we have an addFunction
  90.    
  91.         self.UIInstance = self:Construct(parentNode,parentFrame,contentsTable)
  92.  
  93.         return self
  94.     end
  95.  
  96.     function node2:Construct(parentNode,parentFrame,contentsTable) --constructs this node's UI
  97.         local node = UITemplates.Node:Clone()
  98.        
  99.         --Construct node contents
  100.         for _,contentData in ipairs(contentsTable) do
  101.             local contentObject = contentObjects[contentData[1]]
  102.             contentData = table.clone(contentData)
  103.             table.remove(contentData,1) --remove name, leaving constructor data
  104.             table.insert(self.contents,contentObject.new(self,node.Contents,unpack(contentData))) --provide content data to content object, after base data
  105.         end
  106.  
  107.         --Add add button under this node, if applicable
  108.         if self.addFunction then
  109.             node.ChildrenContainer.Visible = true --show drop bar
  110.            
  111.             local addContainer = UITemplates.AddContainer:Clone()
  112.            
  113.             local addButtonObject = button2.new(addContainer.AddButton,"TraditionalBlue")
  114.             addButtonObject.MouseButton1Click:Connect(function()
  115.                 self.addFunction(self)
  116.             end)
  117.            
  118.             self.addButton = addButtonObject
  119.            
  120.             addContainer.Parent = node.ChildrenContainer.ChildNodes
  121.         end
  122.  
  123.         node.LayoutOrder = #parentNode.subnodes
  124.         node.Parent = parentFrame
  125.        
  126.         return node
  127.     end
  128.  
  129.     --//Where nodeData is the data this node represents
  130.     --//Node contents are the elemets that display in this node, and their corresponding data
  131.     --//Add data is the function that is called when we add a subnode, or nil if we dont want the user to have that button
  132.     function node2:AddSubnode(nodeData,nodeContents,addData)
  133.         self.UIInstance.ChildrenContainer.Visible = true --make sure you can see children being added
  134.        
  135.         local new = node2.new(nodeData,self.rootNode,self,self.UIInstance.ChildrenContainer.ChildNodes,nodeContents)
  136.        
  137.         table.insert(self.subnodes,new)
  138.  
  139.         return new
  140.     end
  141.    
  142.     function node2:RemoveSubnode(subn) --Funds subnode subn from children nodes, and removes it with its descendants.  Subn can be an index, or value of subn's data, or subn itself
  143.         return removeSubnode(self,subn)
  144.     end
  145.  
  146.     function node2:Remove() --removes this node
  147.         return removeNode(self)
  148.     end
  149.  
  150.     function node2:GetSubnode(subn) --subnode can be an index, or value of node.data
  151.         return getSubnode(self,subn)
  152.     end
  153.  
  154.     function node2:PrepareCleanup() --removes all add buttons before :Destroy is called
  155.         for _,v in self.subnodes do
  156.             v:PrepareCleanup()
  157.         end
  158.        
  159.         if self.addButton then
  160.             self.addButton:Destroy()
  161.         end
  162.     end
  163.  
  164.     function node2:SetState(s)
  165.         self.state = s
  166.        
  167.         if self.addButton then --reset button on open and close
  168.             self.addButton:Unhighlight()
  169.         end
  170.        
  171.         for _,v in self.subnodes do
  172.             v:SetState(s)
  173.         end
  174.     end
  175.    
  176.     ----
  177.     --//OOP FOR TREE (AKA, THE ROOT)
  178.     ----
  179.    
  180.     local tree = {}
  181.  
  182.     --parentFrame is frame the tree will be parented to
  183.     --addFunction is nil if we do not want users to have an add button under this.
  184.     --Otherwise, its the functiont that will be called when a user clicks addNode
  185.     function tree.new(parentFrame,addFunction)
  186.         local self = setmetatable({},{__index=tree,
  187.             __iter = function(t)
  188.                 return next,t.subnodes
  189.             end
  190.         })
  191.        
  192.         self.depth = 0
  193.         self.subnodes = {}
  194.        
  195.         self.addFunction = addFunction
  196.         self.addButton = nil
  197.        
  198.         self.UIInstance = self:Construct(parentFrame)
  199.        
  200.         return self
  201.     end
  202.    
  203.     function tree:Construct(parentFrame)
  204.         local treeContainer = UITemplates.Tree:Clone()
  205.        
  206.         if self.addFunction then
  207.             local addContainer = UITemplates.AddContainer:Clone()
  208.  
  209.             local addButtonObject = button2.new(addContainer.AddButton,"TraditionalBlue")
  210.             addButtonObject.MouseButton1Click:Connect(function()
  211.                 self.addFunction(self)
  212.             end)
  213.  
  214.             self.addButton = addButtonObject
  215.  
  216.             addContainer.Parent = treeContainer
  217.         end
  218.        
  219.         treeContainer.Parent = parentFrame
  220.        
  221.         return treeContainer
  222.     end
  223.  
  224.     function tree:AddSubnode(nodeData,nodeContents,addFunction)
  225.         local new = node2.new(nodeData,self,self,self.UIInstance,nodeContents,addFunction)
  226.  
  227.         table.insert(self.subnodes,new)
  228.  
  229.         return new
  230.     end
  231.    
  232.     function tree:GetSubnode(subn) --subnode can be an index, or value of node.data
  233.         return getSubnode(self,subn)
  234.     end
  235.    
  236.     function tree:RemoveSubnode(subn)
  237.         return removeSubnode(self,subn)
  238.     end
  239.    
  240.     function tree:ClearAllData() --deletes all descending nodes, resetting the tree
  241.         while #self.subnodes>0 do
  242.             removeNode(self.subnodes[1],self) --eliminate overhead by directly calling removenode.  even better would be to just clean them all then clear the table.
  243.         end
  244.     end
  245.  
  246.     function tree:Destroy() --Deletes the entire tree, and all descending nodes, for cleanup
  247.         self:ClearAllData()
  248.  
  249.         self:SetState(false) --remove all connections
  250.         self.UIInstance:Destroy()
  251.     end
  252.    
  253.     function tree:SetState(s)
  254.         self.state = s
  255.        
  256.         for _,v in self.subnodes do
  257.             v:SetState(s)
  258.         end
  259.     end
  260.  
  261.     return tree
  262. end
Advertisement
Add Comment
Please, Sign In to add comment