public override void Deleted(ITab <UIntPtr> nodes) { #if DEBUG MaxListener.PrintToListener("NodeEventCallback > Deleted"); #endif List <BaseTreeNode> deletedNodes = new List <BaseTreeNode>(); for (int i = 0; i < nodes.Count; i++) { UIntPtr nodeHandle = nodes[(IntPtr)i]; List <BaseTreeNode> baseTreeNodes = NodeControl.HandleMap.GetTreeNodesByHandle(nodeHandle); foreach (BaseTreeNode baseTreeNode in baseTreeNodes) { if (baseTreeNode != null) { deletedNodes.Add(baseTreeNode); } } } try { ListView.BeginUpdate(); NodeControl.Destroy.DeleteTreeNodes(deletedNodes); } catch { throw new Exception(); } finally { ListView.EndUpdate(); } }
private void onSystemPostReset(Object sender, SystemNotificationObjectEventArgs e) { #if DEBUG MaxListener.PrintToListener("onSystemPostReset"); #endif try { ListView.BeginUpdate(); NodeControl.Create.BuildSceneTree(); } catch { throw new Exception(); } finally { ListView.EndUpdate(); } }
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 onInstanceSelectedLayers(Object sender, ClickEventArgs e) { NlmTreeListView listView = e.ListView; // Multiple items are being added, so let's use BeginUpdate. try { listView.BeginUpdate(); foreach (BaseTreeNode treeNode in listView.SelectedObjects) { LayerTreeNode layerTreeNode = treeNode as LayerTreeNode; if (layerTreeNode != null) { LayerTreeNode newLayerTreeNode = new LayerTreeNode(layerTreeNode.Handle, listView.NodeControl.HandleMap); foreach (ObjectTreeNode objectTreeNode in treeNode.Children) { ObjectTreeNode newObjectTreeNode = new ObjectTreeNode(objectTreeNode.Class, objectTreeNode.Handle, listView.NodeControl.HandleMap); newObjectTreeNode.Parent = newLayerTreeNode; newLayerTreeNode.Children.Add(newObjectTreeNode); } //foreach (LayerTreeNode instanceNode in layerTreeNode.Instances) //{ // instanceNode.Instances.Add(newLayerTreeNode); // newLayerTreeNode.Instances.Add(instanceNode); //} //layerTreeNode.Instances.Add(newLayerTreeNode); //newLayerTreeNode.Instances.Add(layerTreeNode); listView.AddObject(newLayerTreeNode, treeNode.Parent); } } listView.Sort(listView.NlmColumns.NameColumn, SortOrder.Ascending); } catch { throw new Exception(); } finally { listView.EndUpdate(); } }
// 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(); }
//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(); }
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. }