Example #1
0
        /// <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
        }
Example #2
0
        private void onNodeCreated(object sender, SystemNotificationAnimEventArgs e)
        {
#if DEBUG
            MaxListener.PrintToListener("onNodeCreated");
#endif
            try
            {
                ListView.BeginUpdate();

                List <BaseTreeNode> refreshNodes = new List <BaseTreeNode>();
                foreach (UIntPtr handle in e.Handles)
                {
                    IAnimatable anim = MaxAnimatable.GetAnimByHandle(handle);
                    if (anim == null)
                    {
                        return;
                    }

                    IINode  node        = anim as IINode;
                    IILayer layer       = MaxLayers.GetLayer(node);
                    UIntPtr layerHandle = MaxAnimatable.GetHandleByAnim(layer);
                    ObjectTreeNode.ObjectClass objectClass = MaxNodes.GetObjectClass(node);

                    List <BaseTreeNode> layerTreeNodes = NodeControl.HandleMap.GetTreeNodesByHandle(layerHandle);
                    foreach (BaseTreeNode layerTreeNode in layerTreeNodes)
                    {
                        ObjectTreeNode objectTreeNode = new ObjectTreeNode(objectClass, handle, NodeControl.HandleMap);
                        NodeControl.Parent.AddChild(objectTreeNode, layerTreeNode, false);

                        if (!refreshNodes.Contains(layerTreeNode))
                        {
                            refreshNodes.Add(layerTreeNode);
                        }
                    }
                }
                MaxListener.PrintToListener(refreshNodes.Count.ToString());
                ListView.RefreshObjects(refreshNodes);
                ListView.Sort(ListView.NlmColumns.NameColumn, SortOrder.Ascending);
            }
            catch
            {
                throw new Exception();
            }
            finally
            {
                ListView.EndUpdate();
            }
        }
Example #3
0
        public static void onCreateFolderAddSelection(Object sender, ClickEventArgs e)
        {
            NlmTreeListView            listView  = e.ListView;
            IEnumerable <BaseTreeNode> selection = listView.SelectedObjects.Cast <BaseTreeNode>();

            onCreateFolder(sender, e);

            FolderTreeNode folderTreeNode = listView.SelectedObject as FolderTreeNode;

            if (folderTreeNode != null)
            {
                IEnumerable <BaseTreeNode> layerFolderSelection = selection
                                                                  .Where(x => x is LayerTreeNode || x is FolderTreeNode)
                                                                  .Where(x => !folderTreeNode.IsAncestor(x));
                IEnumerable <BaseTreeNode> refreshNodes = layerFolderSelection
                                                          .Where(x => x.Parent != null)
                                                          .Select(x => x.Parent);

                listView.NodeControl.Parent.MoveTreeNodes(layerFolderSelection, folderTreeNode);
                listView.RefreshObjects(refreshNodes.ToList());
                listView.RefreshObject(folderTreeNode);
            }
        }
Example #4
0
        private void onSystemPostMerge(Object sender, SystemNotificationObjectEventArgs e)
        {
#if DEBUG
            MaxListener.PrintToListener("onSystemPostMerge");
#endif
            try
            {
                ListView.BeginUpdate();

                // Collect existing layer and folder nodes.
                IEnumerable <FolderTreeNode> existingFolderNodes = NodeControl.Query.FolderNodes;
                IEnumerable <LayerTreeNode>  existingLayerNodes  = NodeControl.Query.LayerNodes;

                // Unfortunately no event is fired for nodes that are added to layers that already exist.
                // For this reason we need to refresh the children in every layer.
                NodeControl.Create.AddMissingChildObjects(existingLayerNodes);
                ListView.RefreshObjects(existingLayerNodes.ToList());

                // After merge, get all new layers that need to be added to NLM.
                // Old layers are collected because no notification happens for nodes added to existing layers :/
                List <IILayer> newLayers = new List <IILayer>();
                foreach (IILayer layer in MaxLayers.Layers)
                {
                    UIntPtr handle = MaxAnimatable.GetHandleByAnim(layer as IAnimatable);
                    if (!NodeControl.HandleMap.ContainsHandle(handle))
                    {
                        newLayers.Add(layer);
                    }
                }

                // Check each new layer for any folder data saved on the attribute.
                // If any data exists, append it ot folderDataList.
                List <BaseTreeNode> treeNodeList   = new List <BaseTreeNode>();
                List <FolderData>   folderDataList = new List <FolderData>();
                foreach (IILayer layer in newLayers)
                {
                    List <FolderData> parentFolders = MaxIO.LoadParentFolderData(layer as IAnimatable, ListView);
                    if (parentFolders != null)
                    {
                        foreach (FolderData folderData in parentFolders)
                        {
                            if (!folderDataList.Contains(folderData))
                            {
                                folderDataList.Add(folderData);
                            }
                        }
                    }
                }

                // We only add new folders, so build a hashtable of already existing folder nodes.
                // This hashtable is passed to the Build methods, which checks before creating a new node.
                Hashtable folderNodeIdMap = new Hashtable();
                foreach (FolderTreeNode folderNode in existingFolderNodes)
                {
                    folderNodeIdMap.Add(folderNode.ID, folderNode);
                }

                // Build new folder and layer nodes, and append them to the treeNodeList.
                NodeControl.Create.BuildFolderNodes(treeNodeList, folderDataList, folderNodeIdMap);
                NodeControl.Create.BuildLayerAndObjectNodes(treeNodeList, newLayers, folderNodeIdMap);

                // Finally, add the new objects.
                ListView.AddObjects(treeNodeList);
            }
            catch
            {
                throw new Exception();
            }
            finally
            {
                ListView.EndUpdate();
            }
        }
Example #5
0
        public Boolean Click(OlvListViewHitTestInfo hti)
        {
            if (hti.ColumnIndex > 0)
            {
                if (hti.Column == ListView.NlmColumns.ColorColumn)
                {
                    // Should the check states be changed on the selection, or on an item outside of selection.
                    // If inside selection, suppress change in selection by returning true.
                    // If outside selection, change the single item and return false.
                    if (hti.Item.Selected)
                    {
                        NlmMaxColorPicker colorPicker = new NlmMaxColorPicker(hti, true, ListView);
                        colorPicker.ShowModeless();
                        return(true);
                    }
                    else
                    {
                        NlmMaxColorPicker colorPicker = new NlmMaxColorPicker(hti, false, ListView);
                        colorPicker.ShowModeless();
                        // Returning false annoyingly pushes the window to the back.
                        // TODO: Somehow make this dialog modal, or at least parented to 3ds Max, and sort out the focus issue.
                        return(true);
                    }
                }
                if (hti.Column == ListView.NlmColumns.CurrentColumn)
                {
                    BaseTreeNode treeNode = hti.RowObject as BaseTreeNode;
                    if (treeNode is LayerTreeNode)
                    {
                        ListView.BeginUpdate();
                        hti.Column.PutValue(treeNode, true);
                        ListView.EndUpdate();
                    }
                    return(hti.Item.Selected);
                }
                else
                {
                    Boolean    htiItemSelected = hti.Item.Selected;
                    INLMColumn column          = hti.Column as INLMColumn;

                    // Should the check states be changed on the selection, or on an item outside of selection.
                    // If inside selection, suppress change in selection by returning true.
                    // If outside selection, change the single item and return false.
                    if (htiItemSelected)
                    {
                        column.AspectEngine.ToggleCheckStates(hti.RowObject);
                        ListView.RefreshObjects(ListView.SelectedObjects);
                    }
                    else
                    {
                        column.AspectEngine.ToggleCheckState(hti.RowObject);
                        ListView.RefreshObject(hti.RowObject);
                    }

                    MaxUI.RedrawViewportsNow();
                    return(htiItemSelected);
                }
            }
            return(false);
            // Returning true means selection does not change, returning false means it does.
        }