private void onFilePreSave(Object sender, SystemNotificationObjectEventArgs e) { #if DEBUG MaxListener.PrintToListener("onFilePreSave"); #endif MaxIO.SaveData(ListView, NodeControl); }
public void BuildLayerAndObjectNodes(List <BaseTreeNode> treeNodeList, IEnumerable <IILayer> layers, Hashtable folderNodeIdMap) { foreach (IILayer layer in layers) { UIntPtr handle = MaxAnimatable.GetHandleByAnim(layer); LayerData layerNodeData = MaxIO.LoadLayerData(layer); // If layer has node data, create treeNode based on that. // If not, create a new treeNode and append to root. LayerTreeNode layerTreeNode; if (layerNodeData == null) { layerTreeNode = new LayerTreeNode(handle, HandleMap); BuildChildObjects(layerTreeNode, layer); treeNodeList.Add(layerTreeNode); } else { List <Guid> layerTreeNodeParentIDs = layerNodeData.ParentIDs; foreach (Guid layerTreeNodeParentID in layerTreeNodeParentIDs) { // If the handle already exists it is an instance. // Populate the instance properties on all layers with that handle. if (HandleMap.ContainsHandle(handle)) { layerTreeNode = new LayerTreeNode(layerNodeData, handle, HandleMap); } else { layerTreeNode = new LayerTreeNode(layerNodeData, handle, HandleMap); } // If folderNodeData does not have a parent ID, // it should be appended as a root node. if (layerTreeNodeParentID == Guid.Empty) { treeNodeList.Add(layerTreeNode); } // If not, it should be parented to an existing treeNode, // as long as it exists. else { FolderTreeNode parent = folderNodeIdMap[layerTreeNodeParentID] as FolderTreeNode; if (parent == null) { treeNodeList.Add(layerTreeNode); } else { layerTreeNode.Parent = parent; parent.Children.Add(layerTreeNode); } } // Add objects to layer. BuildChildObjects(layerTreeNode, layer); } } } }
// Dispose of all classes that require disposing. protected override void Dispose(bool disposing) { MaxIO.SaveData(this, NodeControl); NlmColumns.Dispose(); NodeControl.Dispose(); //TODO: // Look through all properties that need disposing and dispose them. base.Dispose(disposing); }
public NlmTreeListView() { DisabledHandles = new List <UIntPtr>(); Margin = new Padding(0); Dock = DockStyle.Fill; // Apply look from 3ds Max colour scheme and set ImageList. MaxLook.ApplyLook(this); NodeClassImageList.Apply(this); // Set properties. AllowDrop = true; IsSimpleDragSource = true; IsSimpleDropSink = true; FullRowSelect = true; UseAlternatingBackColors = true; RowHeight = 20; UseCustomSelectionColors = true; HideSelection = false; CellEditActivation = ObjectListView.CellEditActivateMode.DoubleClick; UseFiltering = true; BorderStyle = BorderStyle.FixedSingle; View = View.Details; OwnerDrawnHeader = true; RevealAfterExpand = false; // After expanding, the expand node moves to the top of the listview. It's kinda jarring so turn it off. CanUseApplicationIdle = false; // 3ds Max appears to completley suppress application idle events. DisabledItemStyle = new DisabledNodeStyle(this); SelectColumnsOnRightClick = true; SelectColumnsOnRightClickBehaviour = ColumnSelectBehaviour.InlineMenu; ShowCommandMenuOnRightClick = false; ShowFilterMenuOnRightClick = false; // Instance feature expansion classes. TreeColumnRenderer = new NlmTreeColumnRenderer(); ColumnHeaderRenderer = new ColumnHeaderRenderer(this); NlmColumns = new NlmColumnCollection(this); CellEditValidator = new CellEditValidator(this); MouseLeftClick = new MouseLeftClick(this); ModelFilter = new NlmTreeNodeFilterEngine(this); NodeControl = new NodeController(this); ContextMenu = new NlmContextMenu(this); // Load saved state if it exists MaxIO.LoadNlmData(this); this.CellEditStarting += new CellEditEventHandler(onBeforeLabelEdit); }
public void BuildSceneTree() { // Create list of tree nodes to append to control. // Create folder node hashtable and use ID as key. // The hashtable is used to reparent nodes using stored parent ID's. List <BaseTreeNode> treeNodeList = new List <BaseTreeNode>(); Hashtable folderNodeIdMap = new Hashtable(); List <FolderData> folderNodeDataList = MaxIO.LoadFolderRootNodeData(); // These methods add the nodes to the tree node list. if (folderNodeDataList != null) { // We only add folder nodes if the data list obtained is not null. BuildFolderNodes(treeNodeList, folderNodeDataList, folderNodeIdMap); } BuildLayerAndObjectNodes(treeNodeList, MaxLayers.Layers, folderNodeIdMap); // Finally, add the list to the listview. ListView.Roots = treeNodeList; ListView.NodeControl.CollapseExpand.ExpandWasExpanded(treeNodeList); // And now sort :) ListView.Sort(ListView.NlmColumns.NameColumn, SortOrder.Ascending); }
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(); } }