/// <summary> /// Deletes the selected treenodes, but does not delete associated max nodes. /// All children need to be provided, otherwise the child nodes will not be removed from the HandleMap. /// </summary> /// <param name="treeNodes"></param> public void DeleteTreeNodes(IEnumerable <BaseTreeNode> treeNodes) { #if DEBUG System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); #endif List <BaseTreeNode> rootNodes = new List <BaseTreeNode>(); HashSet <BaseTreeNode> refreshNodes = new HashSet <BaseTreeNode>(); // Delete nodes in NLM foreach (BaseTreeNode treeNode in treeNodes) { // Instead of removing each branch node independently, append to array. // We can then remove them all at the same time, which is way quicker. if (treeNode.Parent == null) { rootNodes.Add(treeNode); } else { treeNode.Parent.Children.Remove(treeNode); // Instead of refreshing each node independently, append to array. // We can then refresh all objects at the same time which is way quicker. if (!refreshNodes.Contains(treeNode.Parent) && !treeNodes.Any(x => treeNode.IsAncestor(x))) { refreshNodes.Add(treeNode.Parent); } treeNode.Parent = null; } // Remove anim handle / treenode link from map. // Note: // Using if (x is y) is creating a cast, which is doubling the casting. // Instead, casting once and checking for null is used. // Continue is used to avoid unnecessary casting. ObjectTreeNode objectTreeNode = treeNode as ObjectTreeNode; if (objectTreeNode != null) { HandleMap.RemoveTreeNodeFromHandle(objectTreeNode, objectTreeNode.Handle); continue; } LayerTreeNode layerTreeNode = treeNode as LayerTreeNode; if (layerTreeNode != null) { HandleMap.RemoveTreeNodeFromHandle(layerTreeNode, layerTreeNode.Handle); continue; } } // Work through the appended arrays and remove / refresh. ListView.RemoveObjects(rootNodes); ListView.RefreshObjects(refreshNodes.ToList()); #if DEBUG stopwatch.Stop(); MaxListener.PrintToListener("DeleteTreeNodes completed in: " + stopwatch.ElapsedMilliseconds); #endif }
// TODO: Change List to IEnumerable public void MoveTreeNodes(IEnumerable <BaseTreeNode> children, BaseTreeNode newParent) { // Removing root nodes is expensive. // In order to speed things up, build an array of root nodes to delete. List <BaseTreeNode> rootRemoveNodes = new List <BaseTreeNode>(); List <BaseTreeNode> rootAddNodes = new List <BaseTreeNode>(); foreach (BaseTreeNode child in children) { if (!(child.Parent == null && newParent == null)) { // If the parent is null it's a root node. // If there is a parent, remove it from children. if (child.Parent == null) { rootRemoveNodes.Add(child); } else { child.Parent.Children.Remove(child); } // Set the child to the new parent. child.Parent = newParent; // If the new parent is null, it should become a root node. // If newParent is not null, add it to the children. if (newParent == null) { rootAddNodes.Add(child); } else { newParent.Children.Add(child); } } } // Finally, add all new root nodes to the listview and refresh nodes. if (rootRemoveNodes.Count > 0) { ListView.RemoveObjects(rootRemoveNodes); } if (rootAddNodes.Count > 0) { ListView.AddObjects(rootAddNodes); } }