public override Object GetAspect(Object rowObject) { LayerTreeNode layerTreeNode = rowObject as LayerTreeNode; if (layerTreeNode != null) { IILayer layer = MaxAnimatable.GetAnimByHandle(layerTreeNode.Handle) as IILayer; if (layer != null) { IILayerProperties layerProps = MaxLayers.GetLayerProperties(layer); return(layerProps.Current); } } FolderTreeNode folderTreeNode = rowObject as FolderTreeNode; if (folderTreeNode != null) { // Default behaviour of getFolderCheckState returns true. // Only get folder check state if necessary as it is // more expensive than returning false. if (folderTreeNode.Children.Count > 0) { Boolean?checkState = getFolderCheckState(folderTreeNode); if (checkState == true || checkState == null) { return(null); } } } return(false); }
public override Object GetMaxValue(BaseTreeNode treeNode) { ObjectTreeNode objectTreeNode = treeNode as ObjectTreeNode; if (objectTreeNode != null) { IINode maxNode = MaxAnimatable.GetAnimByHandle(objectTreeNode.Handle) as IINode; if (maxNode != null) { return(maxNode.BoxMode_ < 0); } } LayerTreeNode layerTreeNode = treeNode as LayerTreeNode; if (layerTreeNode != null) { IILayer maxLayer = MaxAnimatable.GetAnimByHandle(layerTreeNode.Handle) as IILayer; #if Max2013 || Max2014 if (maxLayer != null) { return(!maxLayer.BoxMode); } #endif #if Max2015 if (maxLayer != null) { return(!maxLayer.BoxMode_); } #endif } return(false); }
public override void PutMaxValue(BaseTreeNode treeNode, Object newValue) { LayerTreeNode layerTreeNode = treeNode as LayerTreeNode; if (layerTreeNode != null) { IILayer maxLayer = MaxAnimatable.GetAnimByHandle(layerTreeNode.Handle) as IILayer; #if Max2013 || Max2014 if (maxLayer != null) { maxLayer.BoxMode = !(Boolean)newValue; } #endif #if Max2015 if (maxLayer != null) { maxLayer.BoxMode(!(Boolean)newValue, false); } #endif return; } ObjectTreeNode objectTreeNode = treeNode as ObjectTreeNode; if (objectTreeNode != null) { IINode maxNode = MaxAnimatable.GetAnimByHandle(objectTreeNode.Handle) as IINode; if (maxNode != null) { maxNode.BoxMode(!(Boolean)newValue); } return; } }
public override Object GetAspect(Object rowObject) { FolderTreeNode folderTreeNode = rowObject as FolderTreeNode; if (folderTreeNode != null) { return(folderTreeNode.Name); } LayerTreeNode layerTreeNode = rowObject as LayerTreeNode; if (layerTreeNode != null) { IILayer layer = MaxAnimatable.GetAnimByHandle(layerTreeNode.Handle) as IILayer; if (layer != null) { return(layer.Name); } } ObjectTreeNode objectTreeNode = rowObject as ObjectTreeNode; if (objectTreeNode != null) { IINode maxNode = MaxAnimatable.GetAnimByHandle(objectTreeNode.Handle) as IINode; if (maxNode != null) { return(maxNode.Name); } } return(null); }
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); } } } }
private static void onCreateLayer(Object sender, ClickEventArgs e, Boolean addSelection) { NlmTreeListView listView = e.ListView; listView.NodeControl.MaxEvents.LayerEvents.LayerCreated.UnregisterNotification(); IILayer layer = MaxLayers.CreateLayer(true, addSelection); UIntPtr handle = MaxAnimatable.GetHandleByAnim(layer); LayerTreeNode layerTreeNode = new LayerTreeNode(handle, listView.NodeControl.HandleMap); // Get parent node. BaseTreeNode parentTreeNode = null; if (listView.SelectedObjects.Count > 0) { BaseTreeNode treeNode = listView.SelectedObjects[0] as BaseTreeNode; if (treeNode is FolderTreeNode) { parentTreeNode = treeNode; } if (treeNode is LayerTreeNode) { parentTreeNode = treeNode.Parent; } } // Add folder to listview, ensure is visible by expanding parents. listView.AddObject(layerTreeNode, parentTreeNode); if (parentTreeNode != null) { listView.Expand(parentTreeNode); } // Scroll to new item. Int32 parentIndex = listView.IndexOf(layerTreeNode); if (parentIndex != -1) { listView.EnsureVisible(parentIndex); } // Sort, select listView.Sort(listView.NlmColumns.NameColumn, SortOrder.Ascending); listView.SelectedObjects = new List <Object> { layerTreeNode }; // Focus on the listview to ensure text entry goes to the edit box, and begin edit. listView.Focus(); listView.EditModel(layerTreeNode); // Register notification. listView.NodeControl.MaxEvents.LayerEvents.LayerCreated.RegisterNotification(); }
private void BuildChildObjects(LayerTreeNode layerTreeNode, IILayer maxLayer) { IEnumerable <IINode> layerNodes = MaxLayers.GetChildNodes(maxLayer); foreach (IINode maxNode in layerNodes) { UIntPtr iNodeHandle = MaxAnimatable.GetHandleByAnim(maxNode); ObjectTreeNode objectTreeNode = new ObjectTreeNode(MaxNodes.GetObjectClass(maxNode), iNodeHandle, HandleMap); ListView.NodeControl.Parent.AddChild(objectTreeNode, layerTreeNode, false); } }
// If the cell being edited is layer 0, cancel the cell edit. private void onBeforeLabelEdit(Object sender, CellEditEventArgs e) { if (e.RowObject is LayerTreeNode) { IILayer layer = MaxLayers.GetLayer(0); UIntPtr handle = MaxAnimatable.GetHandleByAnim(layer); if ((e.RowObject as LayerTreeNode).Handle == handle) { e.Cancel = true; } } }
private void SystemNotification(IntPtr Obj, IntPtr info) { Timer.Stop(); INotifyInfo notifyInfo = GlobalInterface.Instance.NotifyInfo.Marshal(info); IAnimatable anim = notifyInfo.CallParam as IAnimatable; UIntPtr handle = MaxAnimatable.GetHandleByAnim(anim); if (handle != null) { Handles.Add(handle); } Timer.Start(); }
public override void PutAspect(Object rowObject, Object newValue) { LayerTreeNode layerTreeNode = rowObject as LayerTreeNode; if (layerTreeNode != null) { IILayer layer = MaxAnimatable.GetAnimByHandle(layerTreeNode.Handle) as IILayer; if (layer != null) { IILayerProperties layerProps = MaxLayers.GetLayerProperties(layer); layerProps.Current = (Boolean)newValue; } } }
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(); } }
public static void onAddSelectedObjectsToLayer(Object sender, ClickEventArgs e) { // TODO: // This is quite slow compared to the NodeEventCallback LayerChanged. Look at that for tips. // Do we really need BeginUpdate and EndUpdate? Calculate which objects to refresh. // Also fix crappy bug where adding children to an expanded layer does not redraw properly. NlmTreeListView listView = e.ListView; try { listView.BeginUpdate(); IList selection = listView.SelectedObjects; if (selection.Count == 1) { LayerTreeNode layerTreeNode = selection[0] as LayerTreeNode; if (layerTreeNode != null) { List <BaseTreeNode> moveTreeNodes = new List <BaseTreeNode>(); IAnimatable layerAnim = MaxAnimatable.GetAnimByHandle(layerTreeNode.Handle); foreach (IINode maxNode in MaxNodes.SelectedNodes) { UIntPtr maxNodeHandle = MaxAnimatable.GetHandleByAnim(maxNode as IAnimatable); List <BaseTreeNode> treeNodes = listView.NodeControl.HandleMap.GetTreeNodesByHandle(maxNodeHandle); foreach (BaseTreeNode treeNode in treeNodes) { moveTreeNodes.Add(treeNode); } MaxNodes.MoveNodeToLayer(maxNode, layerAnim as IILayer); } listView.NodeControl.Parent.MoveTreeNodes(moveTreeNodes, layerTreeNode); } } listView.Sort(listView.NlmColumns.NameColumn, SortOrder.Ascending); } catch { throw new Exception(); } finally { e.ListView.EndUpdate(); } }
public override void LayerChanged(ITab <UIntPtr> nodes) { #if DEBUG MaxListener.PrintToListener("NodeEventCallback > LayerChanged"); #endif List <BaseTreeNode> deleteNodes = new List <BaseTreeNode>(); List <Tuple <BaseTreeNode, BaseTreeNode> > addNodes = new List <Tuple <BaseTreeNode, BaseTreeNode> >(); for (int i = 0; i < nodes.Count; i++) { UIntPtr maxNodeHandle = nodes[(IntPtr)i]; IINode maxNode = MaxAnimatable.GetAnimByHandle(maxNodeHandle) as IINode; IILayer maxLayer = MaxLayers.GetLayer(maxNode); UIntPtr layerHandle = MaxAnimatable.GetHandleByAnim(maxLayer); // We need to handle the following scenarios: // An object being moved to another layer. // Objects on instances layers moving to uninstanced layers. // Objects on uninstanced layers moving to instanced layers. // The easiest way to do this is to remove old object nodes and create new ones. // This should be pretty fast, and this event should fire relatively rarely, // but it may have to be rethought if it's too slow. // First we remove the old nodes. List <BaseTreeNode> objectTreeNodes = NodeControl.HandleMap.GetTreeNodesByHandle(maxNodeHandle); deleteNodes.AddRange(objectTreeNodes); // Then we add the object node to the new layer. List <BaseTreeNode> layerTreeNodes = NodeControl.HandleMap.GetTreeNodesByHandle(layerHandle); foreach (BaseTreeNode layerTreeNode in layerTreeNodes) { ObjectTreeNode newObjectTreeNode = new ObjectTreeNode(MaxNodes.GetObjectClass(maxNode), maxNodeHandle, NodeControl.HandleMap); addNodes.Add(new Tuple <BaseTreeNode, BaseTreeNode> (newObjectTreeNode, layerTreeNode)); } } // And finally we actually do the update all at once. NodeControl.Destroy.DeleteTreeNodes(deleteNodes); foreach (Tuple <BaseTreeNode, BaseTreeNode> tuple in addNodes) { NodeControl.Parent.AddChild(tuple.Item1, tuple.Item2, false); } // And sort :) ListView.Sort(ListView.NlmColumns.NameColumn, SortOrder.Ascending); }
public static void SaveLayerData(IEnumerable <LayerTreeNode> treeNodes, NlmTreeListView owner, HandleMap handleMap) { foreach (LayerTreeNode treeNode in treeNodes) { // Saving layer data is comprised of two sections. IAnimatable layerAnim = MaxAnimatable.GetAnimByHandle(treeNode.Handle); if (layerAnim != null) { // 1. Saving the layer data itself LayerData layerData = new LayerData(treeNode, owner, handleMap); SetAppData(layerAnim, DataAddress.LayerData, layerData); // 2. Saving all folder parents of the layer, in case it is merged and the data is needed. SaveParentFolderData(treeNode, layerAnim, owner); } } }
public void AddMissingChildObjects(IEnumerable <LayerTreeNode> layerNodes) { foreach (LayerTreeNode layerNode in layerNodes) { IILayer layer = MaxAnimatable.GetAnimByHandle(layerNode.Handle) as IILayer; IEnumerable <IINode> maxNodes = MaxLayers.GetChildNodes(layer); foreach (IINode maxNode in maxNodes) { UIntPtr iNodeHandle = MaxAnimatable.GetHandleByAnim(maxNode); // TODO: This needs to work with instanced layers. if (!HandleMap.ContainsHandle(iNodeHandle)) { ObjectTreeNode objectTreeNode = new ObjectTreeNode(MaxNodes.GetObjectClass(maxNode), iNodeHandle, HandleMap); objectTreeNode.Parent = layerNode; layerNode.Children.Add(objectTreeNode); } } } }
public override void PutAspect(Object rowObject, Object newValue) { FolderTreeNode folderTreeNode = rowObject as FolderTreeNode; if (folderTreeNode != null) { folderTreeNode.Name = newValue as String; return; } LayerTreeNode layerTreeNode = rowObject as LayerTreeNode; if (layerTreeNode != null) { IILayer maxLayer = MaxAnimatable.GetAnimByHandle(layerTreeNode.Handle) as IILayer; #if Max2013 || Max2014 String newString = newValue as String; if (maxLayer != null) { maxLayer.SetName(ref newString); } #endif #if Max2015 if (maxLayer != null) { maxLayer.Name = (newValue as String); } #endif return; } ObjectTreeNode objectTreeNode = rowObject as ObjectTreeNode; if (objectTreeNode != null) { IINode maxNode = MaxAnimatable.GetAnimByHandle(objectTreeNode.Handle) as IINode; if (maxNode != null) { maxNode.Name = newValue as String; } return; } }
public static void onSelectLayersFromSelectedObjects(Object sender, ClickEventArgs e) { NlmTreeListView listView = e.ListView; List <BaseTreeNode> newSelection = new List <BaseTreeNode>(); foreach (IINode maxNode in MaxNodes.SelectedNodes) { UIntPtr maxNodeHandle = MaxAnimatable.GetHandleByAnim(maxNode as IAnimatable); List <BaseTreeNode> objectTreeNodes = listView.NodeControl.HandleMap.GetTreeNodesByHandle(maxNodeHandle); foreach (BaseTreeNode objectTreeNode in objectTreeNodes) { BaseTreeNode layerTreeNode = objectTreeNode.Parent; if (!newSelection.Contains(layerTreeNode)) { newSelection.Add(layerTreeNode); } listView.NodeControl.CollapseExpand.ExpandAllParents(layerTreeNode); } } listView.SelectedObjects = newSelection; }
public override Object GetMaxValue(BaseTreeNode treeNode) { ObjectTreeNode objectTreeNode = treeNode as ObjectTreeNode; if (objectTreeNode != null) { IINode maxNode = MaxAnimatable.GetAnimByHandle(objectTreeNode.Handle) as IINode; if (maxNode != null) { return(maxNode.Renderable > 0); } } LayerTreeNode layerTreeNode = treeNode as LayerTreeNode; if (layerTreeNode != null) { IILayer maxLayer = MaxAnimatable.GetAnimByHandle(layerTreeNode.Handle) as IILayer; if (maxLayer != null) { return(maxLayer.Renderable); } } return(false); }
public override Object GetAspect(Object rowObject) { LayerTreeNode layerTreeNode = rowObject as LayerTreeNode; if (layerTreeNode != null) { IILayer maxLayer = MaxAnimatable.GetAnimByHandle(layerTreeNode.Handle) as IILayer; if (maxLayer != null) { // Erm, looks like max has BGR, not RGB. // Because of this, swap B and R to display properly in renderer. Color bgr = maxLayer.WireColor; return(Color.FromArgb(bgr.B, bgr.G, bgr.R)); } } ObjectTreeNode objectTreeNode = rowObject as ObjectTreeNode; if (objectTreeNode != null) { IINode maxNode = MaxAnimatable.GetAnimByHandle(objectTreeNode.Handle) as IINode; if (maxNode != null) { // Erm, looks like max has BGR, not RGB. // Because of this, swap B and R to display properly in renderer. Color bgr = maxNode.WireColor; return(Color.FromArgb(bgr.B, bgr.G, bgr.R)); } } FolderTreeNode folderTreeNode = rowObject as FolderTreeNode; if (folderTreeNode != null) { return(folderTreeNode.Color); } return(null); }
public override void PutAspect(Object rowObject, Object newValue) { FolderTreeNode folderTreeNode = rowObject as FolderTreeNode; if (folderTreeNode != null) { folderTreeNode.Color = (Color)newValue; return; } LayerTreeNode layerTreeNode = rowObject as LayerTreeNode; if (layerTreeNode != null) { IILayer maxLayer = MaxAnimatable.GetAnimByHandle(layerTreeNode.Handle) as IILayer; if (maxLayer != null) { #if Max2013 || Max2014 maxLayer.WireColor = (Color)newValue; #endif #if Max2015 maxLayer.SetWireColor((Color)newValue, false); #endif } return; } ObjectTreeNode objectTreeNode = rowObject as ObjectTreeNode; if (objectTreeNode != null) { IINode maxNode = MaxAnimatable.GetAnimByHandle(objectTreeNode.Handle) as IINode; if (maxNode != null) { maxNode.WireColor = (Color)newValue; } return; } }
public override Object GetMaxValue(BaseTreeNode treeNode) { LayerTreeNode layerTreeNode = treeNode as LayerTreeNode; if (layerTreeNode != null) { IILayer layer = MaxAnimatable.GetAnimByHandle(layerTreeNode.Handle) as IILayer; if (layer != null) { return(!layer.IsHidden); } } ObjectTreeNode objectTreeNode = treeNode as ObjectTreeNode; if (objectTreeNode != null) { IINode maxNode = MaxAnimatable.GetAnimByHandle(objectTreeNode.Handle) as IINode; if (maxNode != null) { return(!maxNode.IsObjectHidden); } } return(false); }
public override void PutAspect(Object rowObject, Object newValue) { BaseTreeNode treeNode = rowObject as BaseTreeNode; if (ListView.SmartFolderMode) { // If turning on, the parent folders need to be turned on too. if ((Boolean)newValue) { putValueAllParents(treeNode, true); } ObjectTreeNode objectTreeNode = treeNode as ObjectTreeNode; if (objectTreeNode != null) { IAnimatable anim = MaxAnimatable.GetAnimByHandle(objectTreeNode.Handle); // Set nodeValue and maxValue to new value. PutMaxValue(treeNode, newValue); PutTreeNodeValue(treeNode, newValue); // Avoid unnecessary casting by returning. return; } // Update max state with NLM state, if max node, set new value and update tree node value. LayerTreeNode layerTreeNode = treeNode as LayerTreeNode; if (layerTreeNode != null) { IAnimatable anim = MaxAnimatable.GetAnimByHandle(layerTreeNode.Handle); // Set nodeValue and maxValue to new value. PutMaxValue(treeNode, newValue); PutTreeNodeValue(treeNode, newValue); // Avoid unnecessary casting by returning. return; } // If folder, set tree node visiblity, and change layer value to match. if (treeNode is FolderTreeNode) { PutTreeNodeValue(treeNode, newValue); PutLayerChildrenMaxValue(treeNode, (Boolean)newValue); // Avoid unnecessary casting by returning. return; } } else // Hierarchy folder mode. { // If folder, set tree node visiblity, and change all child layer values to match. if (treeNode is FolderTreeNode) { // Set nodeValue to new value, and recursivly set all children to new value. PutTreeNodeValue(treeNode, newValue); SetFolderCheckState(treeNode, (Boolean)newValue); // Avoid unnecessary casting by returning. return; } // Update max state with NLM state, if max node, set new value and update tree node value. if (treeNode is LayerTreeNode || treeNode is ObjectTreeNode) { // Set maxValue to new value. PutMaxValue(treeNode, newValue); // Avoid unnecessary casting by returning. return; } } }
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(); } }
//TODO: // Perhaps move this to a new class / node control. It's pretty huge. // Use MaxLayers static class to manipulate max objects instead of in code here. /// <summary> /// Isolate selected TreeNodes in Nested Layer Manager. /// Any TreeNode that is not isolated is disabled, and the respective node hidden in Max. /// </summary> /// <param name="sender">An NLMCheckButton that contains a checked property.</param> /// <param name="e">NLM Button Event Args, that contain a pointer to the listview.</param> public static void onIsolateSelection(Object sender, ClickEventArgs e) { // If the sender is not an NLMCheckButton, the request has come from somewhere else (right click or shortcut). // For this reason, change the check state of the button UI which will raise this event again. if (!(sender is NlmCheckButton)) { e.ListView.ButtonPanelLeft.IsolateSelectedButton.Checked = !e.ListView.ButtonPanelLeft.IsolateSelectedButton.Checked; return; } NlmTreeListView listView = e.ListView; NlmCheckButton button = sender as NlmCheckButton; // Pause UI from refreshing. try { listView.BeginUpdate(); // Isolate selected if button checked. if (button.Checked) { // This method has some serious processing going on, so hashsets are used to maximise performance. // Calculate all enabled nodes and disabled nodes. HashSet <BaseTreeNode> enabledNodes = new HashSet <BaseTreeNode>(listView.NodeControl.Query.SelectionAndAllChildNodes); HashSet <BaseTreeNode> disabledNodes = new HashSet <BaseTreeNode>(listView.NodeControl.Query.AllNodes.Where(x => !enabledNodes.Contains(x))); // Disable disabled nodes. listView.DisableObjects(disabledNodes); // Now we need to work out what maxNodes and layers to temporarily hide. // Firstly, get the highest selected objects. IEnumerable <ObjectTreeNode> selectedNodes = listView.NodeControl.Query.SelectedAncestors .Where(x => (x is ObjectTreeNode)).Cast <ObjectTreeNode>(); HashSet <IILayer> onLayers = new HashSet <IILayer>(); // If objects are selected, we need to ensure that the layer is not hidden. // If any objects are selected, append the layer to the onLayers hashset. foreach (ObjectTreeNode objectTreeNode in selectedNodes) { IINode maxNode = MaxAnimatable.GetAnimByHandle(objectTreeNode.Handle) as IINode; if (maxNode == null) { continue; } IILayer layer = MaxLayers.GetLayer(maxNode); if (!onLayers.Contains(layer)) { onLayers.Add(layer); } } // Ensure that the layer is on so that objects are visible. // The layer is only turned on if an object is selected, and no ancestor is selected. // For any object that is not selected, the object needs to be hidden. foreach (IILayer layer in onLayers) { if (layer.IsHidden) { #if Max2013 || Max2014 layer.IsHidden = false; #endif #if Max2015 layer.Hide(false, false); #endif } foreach (IINode maxNode in MaxLayers.GetChildNodes(layer)) { UIntPtr maxNodeHandle = MaxAnimatable.GetHandleByAnim(maxNode); if (!selectedNodes.Any(x => (x).Handle == maxNodeHandle) && !maxNode.IsObjectHidden) { listView.DisabledHandles.Add(maxNodeHandle); maxNode.Hide(true); } } } // Loop through all layers that should be turned off. // If the layer should be hidden (because it is not in onLayers or in enabledLayers), hide it. IEnumerable <LayerTreeNode> enabledLayers = enabledNodes.Where(x => (x is LayerTreeNode)).Cast <LayerTreeNode>(); IEnumerable <IILayer> offLayers = MaxLayers.Layers.Where(x => !onLayers.Contains(x)); foreach (IILayer layer in offLayers) { UIntPtr layerHandle = MaxAnimatable.GetHandleByAnim(layer); if (!layer.IsHidden && !enabledLayers.Any(x => (x).Handle == layerHandle)) { #if Max2013 || Max2014 layer.IsHidden = true; #endif #if Max2015 layer.Hide(true, false); #endif listView.DisabledHandles.Add(layerHandle); } } } // Remove isolation and restore state if unchecked. else { // Enable all objects. listView.EnableObjects(listView.DisabledObjects); // Turn on all handles that were turned off. foreach (UIntPtr handle in listView.DisabledHandles) { IAnimatable maxAnim = MaxAnimatable.GetAnimByHandle(handle); IILayer maxLayer = maxAnim as IILayer; if (maxLayer != null) { #if Max2013 || Max2014 maxLayer.IsHidden = false; #endif #if Max2015 maxLayer.Hide(false, false); #endif continue; } IINode maxNode = maxAnim as IINode; if (maxNode != null) { maxNode.Hide(false); continue; } } // Clear list of handles. listView.DisabledHandles.Clear(); } } catch { throw new Exception(); } finally { listView.EndUpdate(); } MaxUI.RedrawViewportsNow(); }
// Move nodes to new parent after a drag drop operation. private void DragDropMoveNodes(BaseTreeNode target, IList dragNodes) { IList selection = ListView.SelectedObjects; ListView.BeginUpdate(); MaxEvents.NodeEvents.Unregister(); IEnumerable <BaseTreeNode> dragNodesEnum = dragNodes.Cast <BaseTreeNode>(); // Are layers or folders being dropped on layers? // If so, make the target the parent of the target. if (dragNodesEnum.All(x => x is LayerTreeNode) && target is LayerTreeNode || dragNodesEnum.All(x => x is FolderTreeNode) && target is LayerTreeNode) { target = target.Parent; } // Are objects being dropped on objects? // If so, make the target the parent of the target. if (dragNodesEnum.All(x => x is ObjectTreeNode) && target is ObjectTreeNode) { target = target.Parent; } // Do we move to the root or move under a treeNode? // If the target is null, we have to move to root. if (target != null && target is LayerTreeNode) { // Move the treenodes in the listView. NodeParentEngine.MoveTreeNodes(dragNodes.Cast <BaseTreeNode>().ToList(), target); //TODO: //IEnumerable<UIntPtr> handles = dragNodes.Cast<IEnumerable<BaseTreeNode>>() // .Where(x => x is ObjectTreeNode) // .Cast<ObjectTreeNode>() // .Select(x => x.Handle); // Move nodes to new layer in max. List <UIntPtr> handles = new List <UIntPtr>(); foreach (BaseTreeNode child in dragNodes) { ObjectTreeNode objectChild = child as ObjectTreeNode; if (objectChild != null) { handles.Add(objectChild.Handle); } } IILayer layer = MaxAnimatable.GetAnimByHandle(((LayerTreeNode)target).Handle) as IILayer; if (layer != null) { MaxNodes.MoveNodesToLayer(handles, layer); } } else { NodeParentEngine.MoveTreeNodes(dragNodes.Cast <BaseTreeNode>().ToList(), target); } MaxEvents.NodeEvents.Register(); // Default after drop behaviour tries to select nodes based on itemIndex. As nodes have moved this does not work. // Instead, return saved selection to SelectedObjects property, and make sure dropped Objects are visible. if (!ListView.IsExpanded(target)) { ListView.Expand(target); } ListView.Sort(ListView.NlmColumns.NameColumn, SortOrder.Ascending); ListView.SelectedObjects = selection; ListView.EndUpdate(); }
/// <summary> /// Deletes the selected treenodes, including associated max nodes. /// All children of selection are also deleted. /// Max nodes will not be deleted if not all instanced nodes are selected. /// If every layer 0 instance is selected, nothing will happen. /// </summary> public void DeleteSelection() { #if DEBUG System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); #endif ListView.NodeControl.MaxEvents.NodeEvents.Unregister(); ListView.NodeControl.MaxEvents.LayerEvents.LayerDeleted.UnregisterNotification(); // Don't do anything if every single layer 0 is selected. IILayer layer0 = MaxLayers.GetLayer(0); UIntPtr layer0handle = MaxAnimatable.GetHandleByAnim(layer0); List <BaseTreeNode> layerTreeNodes = HandleMap.GetTreeNodesByHandle(layer0handle); if (layerTreeNodes.All(x => NodeQuery.SelectionAndAllChildNodes.Contains(x))) { return; } // Collect the selection IEnumerables to use. HashSet <BaseTreeNode> selectionAndAllChildren = new HashSet <BaseTreeNode> (NodeQuery.SelectionAndAllChildNodes); // Calculate layer and object handles. IEnumerable <UIntPtr> objectHandles = selectionAndAllChildren.Where (x => x is ObjectTreeNode).Cast <ObjectTreeNode>().Select(x => x.Handle); IEnumerable <UIntPtr> layerHandles = selectionAndAllChildren.Where (x => x is LayerTreeNode).Cast <LayerTreeNode>().Select(x => x.Handle); // Delete handles from max. foreach (UIntPtr handle in objectHandles) { List <BaseTreeNode> instances = HandleMap.GetTreeNodesByHandle(handle); if (instances.Count() > 1) { if (!instances.All(x => selectionAndAllChildren.Contains(x))) { continue; } } MaxNodes.DeleteNode(handle); } foreach (UIntPtr handle in layerHandles) { List <BaseTreeNode> instances = HandleMap.GetTreeNodesByHandle(handle); if (instances.Count() > 1) { if (!instances.All(x => selectionAndAllChildren.Contains(x))) { continue; } } MaxLayers.DeleteLayer(handle); } // And now to delete the tree nodes now there are no max nodes. DeleteTreeNodes(selectionAndAllChildren); // The default behaviour of the listview is to maintain selection based on item index. // This is not very desirable, as the selection should be nothing. ListView.SelectedObjects = new Object[] {}; ListView.NodeControl.MaxEvents.LayerEvents.LayerDeleted.RegisterNotification(); ListView.NodeControl.MaxEvents.NodeEvents.Register(); #if DEBUG stopwatch.Stop(); MaxListener.PrintToListener("DeleteSelection completed in: " + stopwatch.ElapsedMilliseconds); #endif }