Exemple #1
0
        private void treeviewDragFinishingHandler(object sender, DragFinishingEventArgs e)
        {
            // we want to finish off the drag ourselves, and not have the treeview control move the nodes around.
            // (In fact, in a lame attempt at 'data binding', we're going to completely redraw the tree after
            // making all the required changes from this drag-drop.) So set the flag to indicate that.
            e.FinishDrag = false;

            // first determine the node that they will be moved to. This will depend on if we are dragging onto a node
            // directly, or above/below one to reorder.
            ElementNode newParentNode = null;       // the ElementNode that the selected items will move to
            TreeNode    expandNode    = null;       // if we need to expand a node once we've moved everything
            int         index         = -1;

            if (e.DragBetweenNodes == DragBetweenNodes.DragOnTargetNode)
            {
                newParentNode = e.TargetNode.Tag as ElementNode;
                expandNode    = e.TargetNode;
            }
            else if (e.DragBetweenNodes == DragBetweenNodes.DragBelowTargetNode && e.TargetNode.IsExpanded)
            {
                newParentNode = e.TargetNode.Tag as ElementNode;
                expandNode    = e.TargetNode;
                index         = 0;
            }
            else
            {
                if (e.TargetNode.Parent == null)
                {
                    newParentNode = null;                     // needs to go at the root level
                }
                else
                {
                    newParentNode = e.TargetNode.Parent.Tag as ElementNode;
                }

                if (e.DragBetweenNodes == DragBetweenNodes.DragAboveTargetNode)
                {
                    index = e.TargetNode.Index;
                }
                else
                {
                    index = e.TargetNode.Index + 1;
                }
            }

            // Check to see if the new parent node would be 'losing' the Element (ie. becoming a
            // group instead of a leaf node with a element/patches). Prompt the user first.
            if (CheckAndPromptIfNodeWillLosePatches(newParentNode))
            {
                return;
            }

            // If moving element nodes, we need to iterate through all selected treenodes, and remove them from
            // the parent in which they are selected (which we can determine from the treenode parent), and add them
            // to the target node. If copying, we need to just add them to the new parent node.
            foreach (TreeNode treeNode in e.SourceNodes)
            {
                ElementNode sourceNode    = treeNode.Tag as ElementNode;
                ElementNode oldParentNode = (treeNode.Parent != null) ? treeNode.Parent.Tag as ElementNode : null;
                int         currentIndex  = treeNode.Index;
                if (e.DragMode == DragDropEffects.Move)
                {
                    if (index >= 0)
                    {
                        VixenSystem.Nodes.MoveNode(sourceNode, newParentNode, oldParentNode, index);

                        // if we're moving nodes within the same group, but earlier in the group, then increment the target position each time.
                        // This is because when the target is AFTER the current position, the shuffling offsets the nodes so that the target
                        // index can stay the same. This isn't the case for the reverse case.
                        if ((newParentNode != oldParentNode) ||
                            (newParentNode == oldParentNode && index < currentIndex))
                        {
                            index++;
                        }
                    }
                    else
                    {
                        VixenSystem.Nodes.MoveNode(sourceNode, newParentNode, oldParentNode);
                    }
                }
                else if (e.DragMode == DragDropEffects.Copy)
                {
                    if (index >= 0)
                    {
                        // increment the index after every move, so the items are inserted in the correct order (if not, they would be reversed)
                        VixenSystem.Nodes.AddChildToParent(sourceNode, newParentNode, index++);
                    }
                    else
                    {
                        VixenSystem.Nodes.AddChildToParent(sourceNode, newParentNode);
                    }
                }
                else
                {
                    Logging.Warn("ConfigElements: Trying to deal with a drag that is an unknown type!");
                }
            }

            if (expandNode != null)
            {
                expandNode.Expand();
            }

            PopulateNodeTree();
            OnDragFinished();
        }
Exemple #2
0
        protected override void OnDragDrop(DragEventArgs e)
        {
            // Check it's a list of nodes being dragged

            if (e.Data.GetDataPresent(typeof(List <TreeNode>)))
            {
                List <TreeNode> dragNodes = (List <TreeNode>)e.Data.GetData(typeof(List <TreeNode>));

                // if there was no target, don't do anything
                if (_dragDestinationNode == null)
                {
                    CleanupDragVisuals();
                    return;
                }

                // if we're dragging onto one of the selected nodes, then don't do anything
                if (dragNodes.Contains(_dragDestinationNode))
                {
                    CleanupDragVisuals();
                    return;
                }

                // if we're dragging onto one of our children, then don't do anything
                foreach (TreeNode node in dragNodes)
                {
                    // there seems to be a weird bug where we can get multiple nodes as drag data; sometimes
                    // 2 copies of the same node, except that one is part of the treeview, and one is not!
                    // (I suspect it is if the client treeview may completely repopulate itself while dragging).
                    // So, make sure the dragged nodes are part of this treeview first.
                    if (node.TreeView != this)
                    {
                        continue;
                    }

                    if (_dragDestinationNode.FullPath.StartsWith(node.FullPath))
                    {
                        CleanupDragVisuals();
                        return;
                    }
                }

                // before we actually do the dragging of nodes, raise the 'finishing' event. If the
                // handler wants us to stop, then don't complete the drag.
                if (DragFinishing != null)
                {
                    DragFinishingEventArgs ea = new DragFinishingEventArgs();
                    ea.SourceNodes      = dragNodes;
                    ea.TargetNode       = _dragDestinationNode;
                    ea.DragBetweenNodes = _dragBetweenState;
                    ea.DragMode         = e.Effect;
                    DragFinishing(this, ea);
                    if (!ea.FinishDrag)
                    {
                        CleanupDragVisuals();
                        return;
                    }
                }

                if (e.Effect == DragDropEffects.Move)
                {
                    foreach (TreeNode node in dragNodes)
                    {
                        node.Remove();
                    }
                }

                // this is pretty freakin' horrible. Needs to be refactored.
                int i;
                TreeNodeCollection target;
                switch (_dragBetweenState)
                {
                case DragBetweenNodes.DragAboveTargetNode:
                    if (_dragDestinationNode.Parent == null)
                    {
                        target = Nodes;
                    }
                    else
                    {
                        target = _dragDestinationNode.Parent.Nodes;
                    }

                    i = _dragDestinationNode.Index;
                    foreach (TreeNode node in dragNodes)
                    {
                        target.Insert(i++, node);
                    }
                    break;

                case DragBetweenNodes.DragBelowTargetNode:
                    // if it's expanded, drop the items into the start of the node's nodes.
                    if (_dragDestinationNode.IsExpanded)
                    {
                        i = 0;
                        foreach (TreeNode node in dragNodes)
                        {
                            _dragDestinationNode.Nodes.Insert(i++, node);
                        }
                        _dragDestinationNode.Expand();
                    }
                    else
                    {
                        if (_dragDestinationNode.Parent == null)
                        {
                            target = Nodes;
                        }
                        else
                        {
                            target = _dragDestinationNode.Parent.Nodes;
                        }

                        i = _dragDestinationNode.Index + 1;
                        foreach (TreeNode node in dragNodes)
                        {
                            target.Insert(i++, node);
                        }
                    }
                    break;

                case DragBetweenNodes.DragOnTargetNode:
                    _dragDestinationNode.Nodes.AddRange(dragNodes.ToArray());
                    _dragDestinationNode.Expand();
                    break;
                }

                // Call drag complete event
                if (DragComplete != null)
                {
                    DragSourceDestinationEventArgs ea = new DragSourceDestinationEventArgs();
                    ea.SourceNodes = dragNodes;
                    ea.TargetNode  = _dragDestinationNode;
                    DragComplete(this, ea);
                }
            }

            CleanupDragVisuals();
        }