Example #1
0
        public static void onSelectObjectsFromHighlight(Object sender, ClickEventArgs e)
        {
            NlmTreeListView listView = e.ListView;

            MaxNodes.ClearNodeSelection();

            IEnumerable <UIntPtr> handles = listView.NodeControl.Query.SelectionAndAllChildObjectHandles;

            MaxNodes.SelectNodes(handles);
        }
Example #2
0
        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);
            }
        }
Example #3
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 #4
0
        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);
        }
Example #5
0
        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();
            }
        }
Example #6
0
 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);
             }
         }
     }
 }
Example #7
0
        /// <summary>
        /// Returns the message to be displayed when a node publishing limit has been reached
        /// </summary>
        /// <returns></returns>
        public string GetMessage()
        {
            //Custom message overrides everything
            if (!string.IsNullOrEmpty(CustomMessage))
            {
                return(CustomMessage);
            }

            //Return a standard message if this rule is created on the fly based on a special document property value
            if (FromProperty)
            {
                return(string.Format("Node saved but not published. Max allowed child nodes for this specific node: {0}.", MaxNodes.ToString()));
            }

            //This is the message that is returned when a rule is in the config file, and no custom message has been defined.
            return(string.Format(
                       "Node saved but not published. Max allowed nodes {1} directly under {2}: {0}."
                       , MaxNodes.ToString()
                       , ChildDocType.Equals("*") ? "of any type" : string.Format("of type \"{0}\"", ChildDocType)
                       , ParentDocType.Equals("*") ? "any node" : string.Format("nodes of type \"{0}\"", ParentDocType)
                       ));
        }
Example #8
0
        /// <summary>
        /// Returns the warning message to be displayed on publishing a node when a rule is in effect but the limit has not been reached.
        /// </summary>
        /// <param name="currentNodeCount"></param>
        /// <returns></returns>
        public string GetWarningMessage(int currentNodeCount)
        {
            //Custom message overrides everything
            if (!string.IsNullOrEmpty(CustomWarningMessage))
            {
                return(CustomWarningMessage);
            }

            //Return a standard message if this rule is created on the fly based on a special document property value
            if (FromProperty)
            {
                return(string.Format("Restrictions for this node are in place. You have published {0} out {1} allowed child nodes.", (currentNodeCount + 1).ToString(), MaxNodes.ToString()));
            }

            //This is the message that is returned when a rule is in the config file, and no custom message has been defined.
            return(string.Format(
                       "Restrictions in place. {3} directly under {2}: {1} of {0} allowed."
                       , MaxNodes.ToString()
                       , (currentNodeCount + 1).ToString()
                       , ParentDocType.Equals("*") ? "any node" : string.Format("nodes of type \"{0}\"", ParentDocType)
                       , ChildDocType.Equals("*") ? "Any node" : string.Format("Nodes of type \"{0}\"", ChildDocType)
                       ));
        }
Example #9
0
        // 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();
        }
Example #10
0
        /// <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
        }