Beispiel #1
0
        private void FillOurTreeView()
        {
            #region Old way

            //TreeViewNode t1 = new TreeViewNode("test1");
            //treeViewControl1.Root.Children.Add(t1);

            //TreeViewNode t11 = new TreeViewNode("subtest11");
            //t1.VMembers.Children.Add(t11);

            //TreeViewNode t12 = new TreeViewNode("subtest12");
            //t1.VMembers.Children.Add(t12);

            //TreeViewNode t2 = new TreeViewNode("test2");
            //treeViewControl1.Root.Children.Add(t2);
            //t2.MyNodeControl.TreeLineStyle = RedLineStyle;

            //TreeViewNode t21 = new TreeViewNode("subtest21");
            //t2.VMembers.Children.Add(t21);

            //TreeViewNode t22 = new TreeViewNode("subtest22");
            //t2.VMembers.Children.Add(t22);
            ////t21.VMembers.Children.Add(new SampleRootBlock());

            //TreeViewNode t211 = new TreeViewNode("subtest211");
            //t21.VMembers.Children.Add(t211);
            //// t21.HMembers.Children.Add(new ButtonBlock("Hello"));

            #endregion

            #region New way

            TreeViewNode t1   = treeViewControl1.AddNode("test1");
            TreeViewNode t11  = t1.AddNode("subtest11");
            TreeViewNode t12  = t1.AddNode("subtest12");
            TreeViewNode t2   = treeViewControl1.AddNode("test2");
            TreeViewNode t21  = t2.AddNode("subtest21");
            TreeViewNode t211 = t21.AddNode("subtest211");
            TreeViewNode t22  = t2.AddNode("subtest22");

            #endregion

            NodeRelationship r = new NodeRelationship();
            r.Sender    = t11;
            r.Receivers = new List <Block>();
            r.Receivers.Add(t22);
            r.Receivers.Add(t21);

            treeViewControl1.Root.Relationship = r;
        }
 private static bool IsAllowedToHaveRelationDefault(TreeNode parent, TreeNode child, NodeRelationship relation)
 {
     return true;
 }
        private void PaintDragDestinationGraphics(NodeRelationship _prevDNL = NodeRelationship.Null, TreeNode _prevDN = null)
        {
            if ((_prevDN == null || _prevDNL == NodeRelationship.Null) && (_dropNode == null || _dropNodeLocation == NodeRelationship.Null))
                return;

            Color DrawColor;
            Color SelectColor;
            TreeNode node;
            NodeRelationship location;
            bool removal;
            if (_prevDN != null & _prevDNL != NodeRelationship.Null)
            {
                DrawColor = SystemColors.Window;
                SelectColor = SystemColors.Window;
                node = _prevDN;
                location = _prevDNL;
                removal = true;
            }
            else
            {
                DrawColor = SystemColors.WindowText;
                SelectColor = SystemColors.MenuHighlight;
                node = _dropNode;
                location = _dropNodeLocation;
                removal=false;
            }

            Graphics g = CreateGraphics();

            int dropNodeImageWidth = ImageList.Images[node.ImageIndex == -1 ? 0 : node.ImageIndex].Size.Width + 2;
            // Once again, we are not dragging to node over, draw the placeholder using the ParentDragDrop bounds
            int LeftPos, RightPos, VertPos = 0;
            LeftPos = node.Bounds.Left - dropNodeImageWidth;
            RightPos = Width;

            switch (location)
            {
                case NodeRelationship.ChildGoesAbove:
                    VertPos = node.Bounds.Top;
                    break;
                case NodeRelationship.ChildGoesInside:
                    VertPos = node.Bounds.Bottom - node.Bounds.Height / 2;
                    LeftPos = node.Bounds.Right + 6;
                    if (removal)
                    {
                        using (Brush brush = new System.Drawing.SolidBrush(SelectColor))
                            g.FillRectangle(brush, new Rectangle(node.Bounds.Location, node.Bounds.Size));
                        if (node.TreeView != null)
                            OnDrawNode(new DrawTreeNodeEventArgs(g, node, Helper.MakeDrawNodeRectangle(node.Bounds), TreeNodeStates.Default));
                    }
                    else
                    {
                        using (Brush brush = new System.Drawing.SolidBrush(Color.FromArgb(64, SelectColor)))
                            g.FillRectangle(brush, new Rectangle(node.Bounds.Location, node.Bounds.Size));
                    }
                    using (Pen pen = new System.Drawing.Pen(DrawColor, 1))
                        g.DrawRectangle(pen, new Rectangle(node.Bounds.Location, node.Bounds.Size));
                    Point[] triangle = new Point[4] { new Point(LeftPos, VertPos-1), new Point(LeftPos, VertPos), new Point(LeftPos + 11, VertPos + 4), new Point(LeftPos + 11, VertPos - 5) };
                    using (Brush brush = new System.Drawing.SolidBrush(DrawColor))
                        g.FillPolygon(brush, triangle);
                    break;
                case NodeRelationship.ChildGoesUnder:
                    VertPos = node.Bounds.Bottom;
                    break;
            }
            using (Pen pen = new System.Drawing.Pen(DrawColor, 2))
                g.DrawLine(pen, new Point(LeftPos, VertPos), new Point(RightPos, VertPos));
        }
        public void MoveNode(TreeNode what, TreeNode where, NodeRelationship relation, NodeRelationship subRelation = NodeRelationship.Null, bool suspendUpdate = false)
        {
            if (!IsAllowedToHaveRelation(where,what,relation))
                return;

            if (subRelation == NodeRelationship.Null)
                subRelation = Settings.Current.DragIntoFolderToLastPosition ? NodeRelationship.ChildGoesUnder : NodeRelationship.ChildGoesAbove;

            TreeNode result = null;

            if (!suspendUpdate)
                BeginUpdate();

            if (where == null)
            {
                what.Remove();
                Nodes.Add(what);
            }
            else
            {
                if (what != where)
                    switch (relation)
                    {
                        case NodeRelationship.ChildGoesAbove:
                            what.Remove();
                            if (where.Parent != null)
                                where.Parent.Nodes.Insert(where.Index, what);
                            else
                                Nodes.Insert(where.Index, what);
                            result = what;
                            break;
                        case NodeRelationship.ChildGoesInside:
                            what.Remove();
                            if (subRelation == NodeRelationship.ChildGoesUnder)
                                where.Nodes.Add(what);
                            if (subRelation == NodeRelationship.ChildGoesAbove)
                                where.Nodes.Insert(0, what);
                            result = what;
                            break;
                        case NodeRelationship.ChildGoesUnder:
                            what.Remove();
                            if (where.Parent != null)
                                where.Parent.Nodes.Insert(where.Index + 1, what);
                            else
                                Nodes.Insert(where.Index + 1, what);
                            result = what;
                            break;
                    }
            }

            if (result!=null)
                SelectedNode = result;

            if (!suspendUpdate)
                EndUpdate();

            OnNodeMoved(result, suspendUpdate);
        }
        protected override void OnDragOver(DragEventArgs drgevent)
        {
            if (!DraggingInProgress)
            {
                drgevent.Effect = DragDropEffects.None;
                return;
            }

            drgevent.Effect = DragDropEffects.Move;

            TreeNode prevDN = _dropNode;
            NodeRelationship prevDNL = _dropNodeLocation;

            // Get actual drop node
            _dropNode = GetNodeAt(PointToClient(new Point(drgevent.X, drgevent.Y)));
            if (_dropNode != null)
            {

                int OffsetY = PointToClient(Cursor.Position).Y - _dropNode.Bounds.Top;

                if (IsFolder(_dropNode))
                {
                    if (OffsetY < (_dropNode.Bounds.Height / 3))
                        _dropNodeLocation = NodeRelationship.ChildGoesAbove;
                    else if (OffsetY > (_dropNode.Bounds.Height * 2 / 3))
                        _dropNodeLocation = NodeRelationship.ChildGoesUnder;
                    else
                        _dropNodeLocation = NodeRelationship.ChildGoesInside;
                }
                else
                {
                    if (OffsetY < (_dropNode.Bounds.Height / 2))
                        _dropNodeLocation = NodeRelationship.ChildGoesAbove;
                    else
                        _dropNodeLocation = NodeRelationship.ChildGoesUnder;
                }

                //Check if we are allowed to put this into that
                if (!IsAllowedToHaveRelation(_dropNode, _dragNode, _dropNodeLocation))
                {
                    drgevent.Effect = DragDropEffects.None;
                    _dropNodeLocation = NodeRelationship.Null;
                }

                if (_dropNode == _dragNode && _dropNodeLocation == NodeRelationship.ChildGoesInside)
                {
                    drgevent.Effect = DragDropEffects.None;
                    _dropNodeLocation = NodeRelationship.Null;
                }

                // Avoid that drop node is child of drag node
                TreeNode tmpNode = _dropNode;
                while (tmpNode.Parent != null)
                {
                    if (tmpNode.Parent == this._dragNode)
                    {
                        drgevent.Effect = DragDropEffects.None;
                        _dropNodeLocation = NodeRelationship.Null;
                    }
                    tmpNode = tmpNode.Parent;
                }

            }

            //Mechanism to scroll when reaching the end
            if (_dropNode != null)
            {
                //Always ensure that the node we are dropping over/in/under is visible
                _dropNode.EnsureVisible();
                //Highlight previous node if it exists and...
                if (_dropNode.PrevNode != null)
                {
                    //If previous node has no nodes or isnt expanded then this node is a single node and should be visible
                    if (_dropNode.PrevNode.Nodes.Count == 0 || !_dropNode.PrevNode.IsExpanded)
                        _dropNode.PrevNode.EnsureVisible();
                    //If previous node has nodes and is expanded then its last visible child should be made visible
                    else
                    {
                        //Find last visible child recursively
                        TreeNode lastChild = _dropNode.PrevNode.Nodes[_dropNode.PrevNode.Nodes.Count - 1];
                        while (lastChild.Nodes.Count > 0 && lastChild.IsExpanded)
                            lastChild = lastChild.Nodes[lastChild.Nodes.Count - 1];
                        lastChild.EnsureVisible();
                    }
                }
                //Highlight parent node if previous node doesnt exist (meaning node above this node is its parent)
                else
                {
                    if (_dropNode.Parent != null)
                        _dropNode.Parent.EnsureVisible();
                }
                //Highlight next node if it exists and...
                if (_dropNode.NextNode != null)
                {
                    //If this node has no nodes or isnt expanded then it is single, and next node should be visible
                    if (_dropNode.Nodes.Count == 0 || !_dropNode.IsExpanded)
                        _dropNode.NextNode.EnsureVisible();
                    //If this node has nodes and is expanded then we should select its first child
                    else
                        _dropNode.Nodes[0].EnsureVisible();
                }
                //Highlight next node after parent node if there is no next node
                else
                {
                    if (_dropNode.Nodes.Count == 0 || !_dropNode.IsExpanded)
                        if (_dropNode.Parent != null && _dropNode.Parent.NextNode != null)
                            _dropNode.Parent.NextNode.EnsureVisible();
                }
            }

            if (prevDNL != _dropNodeLocation || prevDN != _dropNode)
            {
                PaintDragDestinationGraphics(prevDNL, prevDN);
                PaintDragDestinationGraphics();
            }

            base.OnDragOver(drgevent);
        }
Beispiel #6
0
        /// <summary>
        /// Get the sum of the branch lengths from this node to the specified node.
        /// </summary>
        /// <param name="otherNode">The node that should be reached</param>
        /// <param name="nodeRelationship">A value indicating how this node is related to <paramref name="otherNode"/>.</param>
        /// <returns>The sum of the branch lengths from this node to the specified node.</returns>
        public double PathLengthTo(TreeNode otherNode, NodeRelationship nodeRelationship = NodeRelationship.Unknown)
        {
            Contract.Requires(otherNode != null);

            TreeNode LCA = null;

            if (this == otherNode)
            {
                return(0);
            }

            if (nodeRelationship == NodeRelationship.Unknown)
            {
                List <TreeNode> myChildren = this.GetChildrenRecursive();
                if (myChildren.Contains(otherNode))
                {
                    nodeRelationship = NodeRelationship.Ancestor;
                }
                else
                {
                    List <TreeNode> otherChildren = otherNode.GetChildrenRecursive();
                    if (otherChildren.Contains(this))
                    {
                        nodeRelationship = NodeRelationship.Descendant;
                    }
                    else
                    {
                        LCA = GetLastCommonAncestor(new TreeNode[] { this, otherNode });

                        if (LCA != null)
                        {
                            nodeRelationship = NodeRelationship.Relatives;
                        }
                        else
                        {
                            throw new InvalidOperationException("The two nodes do not belong to the same tree!");
                        }
                    }
                }
            }

            switch (nodeRelationship)
            {
            case NodeRelationship.Relatives:
                return(LCA.PathLengthTo(this, NodeRelationship.Ancestor) + LCA.PathLengthTo(otherNode, NodeRelationship.Ancestor));

            case NodeRelationship.Ancestor:
                for (int i = 0; i < this.Children.Count; i++)
                {
                    if (this.Children[i] == otherNode)
                    {
                        return(this.Children[i].Length);
                    }
                    else if (this.Children[i].GetChildrenRecursive().Contains(otherNode))
                    {
                        return(this.Children[i].Length + this.Children[i].PathLengthTo(otherNode, NodeRelationship.Ancestor));
                    }
                }
                throw new InvalidOperationException("Unexpected code path!");

            case NodeRelationship.Descendant:
                return(otherNode.PathLengthTo(this, NodeRelationship.Ancestor));

            default:
                throw new InvalidOperationException("The two nodes do not belong to the same tree!");
            }
        }
Beispiel #7
0
        private string traverse_tree(XElement node, string parent_id, NodeRelationship relationship)
        {
            // get this nodes infko
            string tagname = node.Name.LocalName;

            if (tagname == "math")
            {
                traverse_tree(node.FirstNode as XElement, parent_id, NodeRelationship.Right);
                return("");
            }

            string my_id = node.Attribute(ns + "id") == null ? null : (string)(node.Attribute(ns + "id").Value);

            // relationsip
            if (my_id != null)
            {
                //Console.WriteLine(my_id + " is " + relationship + " of " + parent_id);
                edge_list.Add(new Tuple <string, NodeRelationship, string>(my_id, relationship, parent_id));
            }

            // handle children
            switch (tagname)
            {
            case "mfrac":
                traverse_tree(node.FirstNode as XElement, my_id, NodeRelationship.Above);
                traverse_tree(node.LastNode as XElement, my_id, NodeRelationship.Below);
                return(my_id);

            case "mrow":
                string left_id = traverse_tree(node.FirstNode as XElement, parent_id, relationship);
                traverse_tree(node.LastNode as XElement, left_id, NodeRelationship.Right);
                return(left_id);

            case "msup":
                string super_base_id = traverse_tree(node.FirstNode as XElement, parent_id, relationship);
                traverse_tree(node.LastNode as XElement, super_base_id, NodeRelationship.SuperScript);
                return(super_base_id);

            case "msub":
                string sub_base_id = traverse_tree(node.FirstNode as XElement, parent_id, relationship);
                traverse_tree(node.LastNode as XElement, sub_base_id, NodeRelationship.SubScript);
                return(sub_base_id);

            case "msqrt":
                string first_under = traverse_tree(node.FirstNode as XElement, my_id, NodeRelationship.Under);
                if (node.LastNode != node.FirstNode)
                {
                    traverse_tree(node.FirstNode.NextNode as XElement, first_under, NodeRelationship.Right);
                }
                return(my_id);

            case "msubsup":
                var    child           = node.FirstNode;
                string sub_sup_base_id = traverse_tree(child as XElement, parent_id, relationship);
                traverse_tree(child.NextNode as XElement, sub_sup_base_id, NodeRelationship.Below);
                traverse_tree(child.NextNode.NextNode as XElement, sub_sup_base_id, NodeRelationship.Above);
                return(sub_sup_base_id);

            case "munderover":
                child = node.FirstNode;
                string under_over_base_id = traverse_tree(child as XElement, parent_id, relationship);
                traverse_tree(child.NextNode as XElement, under_over_base_id, NodeRelationship.Below);
                traverse_tree(child.NextNode.NextNode as XElement, under_over_base_id, NodeRelationship.Above);
                return(under_over_base_id);

            case "munder":
                string top_base_id = traverse_tree(node.FirstNode as XElement, parent_id, relationship);
                traverse_tree(node.LastNode as XElement, top_base_id, NodeRelationship.Below);
                return(top_base_id);
            }
            // everything esle
            return(my_id);
        }
        /// <summary>
        /// In this method we check wether a node can get placed near another node. 
        /// </summary>
        /// <param name="parent">Node being the receiver</param>
        /// <param name="child">Node that is trying to get attached</param>
        /// <example>
        /// You are not allowed to place Event above Start, so any relation which makes it so will be denied.
        /// </example>
        private bool TreeViewNodes_IsAllowedToHaveRelation(TreeNode parent, TreeNode child, NodeRelationship relation)
        {
            if (child.Tag == null)
                throw new ArgumentException("child", "Moving a TreeNode without a Tag, WTF?");
            if (parent.Tag == null)
                throw new ArgumentException("parent", "Moving a TreeNode without a Tag, WTF?");

            if (relation == NodeRelationship.ChildGoesInside && !TreeViewNodes.IsFolder(parent))
                return false;

            //Everything except comments cant go above Start (which can only occur in root)
            //Therefore, for each node that isnt a comment, and is trying to fit on one level with something that is in root...
            if (relation != NodeRelationship.ChildGoesInside && parent.Parent == null && !(child.Tag.GetType() == typeof(MissionNode_Comment) || child.Tag.GetType() == typeof(MissionNode_Start)))
            {
                //Check that we are not inserting directly above Start node...
                if (relation == NodeRelationship.ChildGoesAbove && parent.Tag.GetType() == typeof(MissionNode_Start))
                    return false;
                //...and check that we are not inserting near a node that is above Start node
                if (TreeViewNodes.Nodes.IndexOf(_startNode) > TreeViewNodes.Nodes.IndexOf(parent))
                    return false;
            }

            //Start, Comment and Unknown cannot go inside anything, start because it must stay on top and other two because they cant have Parent_ID attribute added to them
            if (child.Tag.GetType() == typeof(MissionNode_Start) || child.Tag.GetType() == typeof(MissionNode_Comment) || child.Tag.GetType() == typeof(MissionNode_Unknown))
            {
                //Refuse to go inside anything...
                if (relation == NodeRelationship.ChildGoesInside)
                    return false;
                //...or next to a node that is inside something...
                if (parent.Parent != null)
                    return false;
            }

            //Start additionally cannot go below anything that isnt a comment
            if (child.Tag.GetType() == typeof(MissionNode_Start))
            {
                //Never go under anything other than a comment or yourself
                if (relation == NodeRelationship.ChildGoesUnder && parent.Tag.GetType() != typeof(MissionNode_Comment) && parent != child)
                    return false;

                //Go through nodes until we meet the node we are becoming parented to
                //If we find anything except comment on the way, this means we are going below
                for (int i = 0; i < TreeViewNodes.Nodes.Count; i++)
                {
                    //When we found something other than a comment and the dragged node
                    if (TreeViewNodes.Nodes[i].Tag.GetType() != typeof(MissionNode_Comment) && TreeViewNodes.Nodes[i] != child)
                        //In case this is the node we are inserting above - allow it, otherwise deny it
                        if (relation == NodeRelationship.ChildGoesAbove && TreeViewNodes.Nodes[i] == parent)
                            break;
                        else
                            return false;

                    if (TreeViewNodes.Nodes[i] == parent)
                        break;
                }
            }

            return true;
        }
        /// <summary>
        /// In this method we check wether a statement can get placed near another statement. 
        /// </summary>
        /// <param name="parent">Node being the receiver</param>
        /// <param name="child">Node that is trying to get attached</param>
        /// <example>
        /// You are not allowed to place a Condition into Actions root.
        /// </example>
        private bool TreeViewStatements_IsAllowedToHaveRelation(TreeNode parent, TreeNode child, NodeRelationship relation)
        {
            if (child.Tag == null || parent.Tag == null) // This might be a comment or a folder
                return false;

            //You cannot go inside something that isnt a folder
            if (relation == NodeRelationship.ChildGoesInside && !TreeViewStatements.IsFolder(parent))
                return false;

            //Non-statements cannot move at all
            if (!(child.Tag is MissionStatement))
                return false;

            //If going inside, Conditions can only go inside codintion folder, actions can go inside actions folder, comment can go anywhere
            if (relation == NodeRelationship.ChildGoesInside && (((string)parent.Tag == "conditions" && ((MissionStatement)child.Tag).Kind == MissionStatementKind.Action) || ((string)parent.Tag == "actions" && ((MissionStatement)child.Tag).Kind == MissionStatementKind.Condition) || ((string)parent.Tag != "actions" && (string)parent.Tag != "conditions")))
                return false;

            //Comments cannot go inside conditions!
            if (relation == NodeRelationship.ChildGoesInside && ((string)parent.Tag == "conditions" && ((MissionStatement)child.Tag).Kind == MissionStatementKind.Commentary))
                return false;

            //If going adjacent to something
            //Conditions can only go adjacent to conditions or comments inside conditions folder
            //Actions can only go adjacent to actions or comments inside actions folder
            if (relation == NodeRelationship.ChildGoesAbove || relation == NodeRelationship.ChildGoesUnder)
            {
                if (!(parent.Tag is MissionStatement))
                    return false;

                if ((((MissionStatement)child.Tag).Kind == MissionStatementKind.Action) && ((string)parent.Parent.Tag != "actions"))
                    return false;

                if ((((MissionStatement)child.Tag).Kind == MissionStatementKind.Condition) && ((string)parent.Parent.Tag != "conditions"))
                    return false;
            }

            //Comments also cannot go under last condition
            if (relation == NodeRelationship.ChildGoesUnder && (((MissionStatement)child.Tag).Kind == MissionStatementKind.Commentary))
            {
                if (parent.Parent != null && parent.Parent.LastNode == parent && (string)parent.Parent.Tag == "conditions")
                    return false;
            }

            return true;
        }
        public Task Sort()
        {
            var nodes = this.nodes.ToDictionary
                        (
                kvp => kvp.Key,
                kvp => new NodeRelationship {
                Dependencies = kvp.Value.Dependencies.ToHashSet(actionComparer), Dependents = kvp.Value.Dependents.ToHashSet(actionComparer)
            },
                actionComparer
                        );

            var taskDictionary = this.nodes.ToDictionary
                                 (
                kvp => kvp.Key,
                kvp => new TaskRelationship(),
                actionComparer
                                 );

            var sortedNodeIds = new List <Node>();

            // Add root nodes
            sortedNodeIds.AddRange(this.nodes.Where(kvp => kvp.Value.Dependencies.Count == 0).Select(kvp => kvp.Key));

            var rootTasks = new List <Task>();

            foreach (Node nodeId in sortedNodeIds)
            {
                var task = new Task(nodeId.Action);
                taskDictionary[nodeId].Task = task;

                rootTasks.Add(task);
            }

            for (var index = 0; index < sortedNodeIds.Count; ++index)
            {
                Node nodeId = sortedNodeIds[index];
                Task task   = taskDictionary[nodeId].Task ?? Task.WhenAll(taskDictionary[nodeId].TaskDependencies).ContinueWith((Task t) => { nodeId.Action.Invoke(); });

                taskDictionary[nodeId].Task = task;

                HashSet <Node> dependentIds = nodes[nodeId].Dependents;
                foreach (Node dependentId in dependentIds)
                {
                    NodeRelationship dependent = nodes[dependentId];

                    taskDictionary[dependentId].TaskDependencies.Add(task);

                    dependent.Dependencies.Remove(sortedNodeIds[index]);
                    if (dependent.Dependencies.Count == 0)
                    {
                        sortedNodeIds.Add(dependentId);
                    }
                }
            }

            var cycledNodes = nodes.Where(kvp => kvp.Value.Dependencies.Count != 0).ToArray();

            if (cycledNodes.Length > 0)
            {
                return(Task.Run(() => Console.WriteLine("Failed to run. Cycle detected with the following nodes (" + string.Join(", ", cycledNodes.Select(kvp => kvp.Key.Name)) + ")")));
            }
            else
            {
                foreach (Task task in rootTasks)
                {
                    task.Start();
                }

                return(Task.WhenAll(taskDictionary.Values.Select(x => x.Task)).ContinueWith((Task t) => Console.WriteLine("")));
            }
        }
Beispiel #11
0
        public void MoveNode(TreeNode what, TreeNode where, NodeRelationship relation, NodeRelationship subRelation = NodeRelationship.Null, bool suspendUpdate = false)
        {
            if (!IsAllowedToHaveRelation(where, what, relation))
            {
                return;
            }

            if (subRelation == NodeRelationship.Null)
            {
                subRelation = Settings.Current.DragIntoFolderToLastPosition ? NodeRelationship.ChildGoesUnder : NodeRelationship.ChildGoesAbove;
            }

            TreeNode result = null;

            if (!suspendUpdate)
            {
                BeginUpdate();
            }

            if (where == null)
            {
                what.Remove();
                Nodes.Add(what);
            }
            else
            {
                if (what != where)
                {
                    switch (relation)
                    {
                    case NodeRelationship.ChildGoesAbove:
                        what.Remove();
                        if (where.Parent != null)
                        {
                            where.Parent.Nodes.Insert(where.Index, what);
                        }
                        else
                        {
                            Nodes.Insert(where.Index, what);
                        }
                        result = what;
                        break;

                    case NodeRelationship.ChildGoesInside:
                        what.Remove();
                        if (subRelation == NodeRelationship.ChildGoesUnder)
                        {
                            where.Nodes.Add(what);
                        }
                        if (subRelation == NodeRelationship.ChildGoesAbove)
                        {
                            where.Nodes.Insert(0, what);
                        }
                        result = what;
                        break;

                    case NodeRelationship.ChildGoesUnder:
                        what.Remove();
                        if (where.Parent != null)
                        {
                            where.Parent.Nodes.Insert(where.Index + 1, what);
                        }
                        else
                        {
                            Nodes.Insert(where.Index + 1, what);
                        }
                        result = what;
                        break;
                    }
                }
            }

            if (result != null)
            {
                SelectedNode = result;
            }

            if (!suspendUpdate)
            {
                EndUpdate();
            }

            OnNodeMoved(result, new NodeMovedEventArgs(suspendUpdate));
        }
Beispiel #12
0
        protected override void OnDragOver(DragEventArgs drgevent)
        {
            if (!DraggingInProgress)
            {
                drgevent.Effect = DragDropEffects.None;
                return;
            }

            drgevent.Effect = DragDropEffects.Move;

            TreeNode         prevDN  = _dropNode;
            NodeRelationship prevDNL = _dropNodeLocation;

            // Get actual drop node
            _dropNode = GetNodeAt(PointToClient(new Point(drgevent.X, drgevent.Y)));
            if (_dropNode != null)
            {
                int OffsetY = PointToClient(Cursor.Position).Y - _dropNode.Bounds.Top;

                if (IsFolder(_dropNode))
                {
                    if (OffsetY < (_dropNode.Bounds.Height / 3))
                    {
                        _dropNodeLocation = NodeRelationship.ChildGoesAbove;
                    }
                    else if (OffsetY > (_dropNode.Bounds.Height * 2 / 3))
                    {
                        _dropNodeLocation = NodeRelationship.ChildGoesUnder;
                    }
                    else
                    {
                        _dropNodeLocation = NodeRelationship.ChildGoesInside;
                    }
                }
                else
                {
                    if (OffsetY < (_dropNode.Bounds.Height / 2))
                    {
                        _dropNodeLocation = NodeRelationship.ChildGoesAbove;
                    }
                    else
                    {
                        _dropNodeLocation = NodeRelationship.ChildGoesUnder;
                    }
                }

                //Check if we are allowed to put this into that
                if (!IsAllowedToHaveRelation(_dropNode, _dragNode, _dropNodeLocation))
                {
                    drgevent.Effect   = DragDropEffects.None;
                    _dropNodeLocation = NodeRelationship.Null;
                }

                if (_dropNode == _dragNode && _dropNodeLocation == NodeRelationship.ChildGoesInside)
                {
                    drgevent.Effect   = DragDropEffects.None;
                    _dropNodeLocation = NodeRelationship.Null;
                }

                // Avoid that drop node is child of drag node
                TreeNode tmpNode = _dropNode;
                while (tmpNode.Parent != null)
                {
                    if (tmpNode.Parent == this._dragNode)
                    {
                        drgevent.Effect   = DragDropEffects.None;
                        _dropNodeLocation = NodeRelationship.Null;
                    }
                    tmpNode = tmpNode.Parent;
                }
            }

            //Mechanism to scroll when reaching the end
            if (_dropNode != null)
            {
                //Always ensure that the node we are dropping over/in/under is visible
                _dropNode.EnsureVisible();
                //Highlight previous node if it exists and...
                if (_dropNode.PrevNode != null)
                {
                    //If previous node has no nodes or isn't expanded then this node is a single node and should be visible
                    if (_dropNode.PrevNode.Nodes.Count == 0 || !_dropNode.PrevNode.IsExpanded)
                    {
                        _dropNode.PrevNode.EnsureVisible();
                    }
                    //If previous node has nodes and is expanded then its last visible child should be made visible
                    else
                    {
                        //Find last visible child recursively
                        TreeNode lastChild = _dropNode.PrevNode.Nodes[_dropNode.PrevNode.Nodes.Count - 1];
                        while (lastChild.Nodes.Count > 0 && lastChild.IsExpanded)
                        {
                            lastChild = lastChild.Nodes[lastChild.Nodes.Count - 1];
                        }
                        lastChild.EnsureVisible();
                    }
                }
                //Highlight parent node if previous node doesnt exist (meaning node above this node is its parent)
                else
                {
                    if (_dropNode.Parent != null)
                    {
                        _dropNode.Parent.EnsureVisible();
                    }
                }
                //Highlight next node if it exists and...
                if (_dropNode.NextNode != null)
                {
                    //If this node has no nodes or isn't expanded then it is single, and next node should be visible
                    if (_dropNode.Nodes.Count == 0 || !_dropNode.IsExpanded)
                    {
                        _dropNode.NextNode.EnsureVisible();
                    }
                    //If this node has nodes and is expanded then we should select its first child
                    else
                    {
                        _dropNode.Nodes[0].EnsureVisible();
                    }
                }
                //Highlight next node after parent node if there is no next node
                else
                {
                    if (_dropNode.Nodes.Count == 0 || !_dropNode.IsExpanded)
                    {
                        if (_dropNode.Parent != null && _dropNode.Parent.NextNode != null)
                        {
                            _dropNode.Parent.NextNode.EnsureVisible();
                        }
                    }
                }
            }

            if (prevDNL != _dropNodeLocation || prevDN != _dropNode)
            {
                PaintDragDestinationGraphics(prevDNL, prevDN);
                PaintDragDestinationGraphics();
            }

            base.OnDragOver(drgevent);
        }
Beispiel #13
0
        private void PaintDragDestinationGraphics(NodeRelationship _prevDNL = NodeRelationship.Null, TreeNode _prevDN = null)
        {
            if ((_prevDN == null || _prevDNL == NodeRelationship.Null) && (_dropNode == null || _dropNodeLocation == NodeRelationship.Null))
            {
                return;
            }

            Color            DrawColor;
            Color            SelectColor;
            TreeNode         node;
            NodeRelationship location;
            bool             removal;

            if (_prevDN != null & _prevDNL != NodeRelationship.Null)
            {
                DrawColor   = SystemColors.Window;
                SelectColor = SystemColors.Window;
                node        = _prevDN;
                location    = _prevDNL;
                removal     = true;
            }
            else
            {
                DrawColor   = SystemColors.WindowText;
                SelectColor = SystemColors.MenuHighlight;
                node        = _dropNode;
                location    = _dropNodeLocation;
                removal     = false;
            }

            Graphics g = CreateGraphics();

            int dropNodeImageWidth = ImageList.Images[node.ImageIndex == -1 ? 0 : node.ImageIndex].Size.Width + 2;
            // Once again, we are not dragging to node over, draw the placeholder using the ParentDragDrop bounds
            int LeftPos, RightPos, VertPos = 0;

            LeftPos  = node.Bounds.Left - dropNodeImageWidth;
            RightPos = Width;

            switch (location)
            {
            case NodeRelationship.ChildGoesAbove:
                VertPos = node.Bounds.Top;
                break;

            case NodeRelationship.ChildGoesInside:
                VertPos = node.Bounds.Bottom - node.Bounds.Height / 2;
                LeftPos = node.Bounds.Right + 6;
                if (removal)
                {
                    using (Brush brush = new System.Drawing.SolidBrush(SelectColor))
                        g.FillRectangle(brush, new Rectangle(node.Bounds.Location, node.Bounds.Size));
                    if (node.TreeView != null)
                    {
                        OnDrawNode(new DrawTreeNodeEventArgs(g, node, Helper.MakeDrawNodeRectangle(node.Bounds), TreeNodeStates.Default));
                    }
                }
                else
                {
                    using (Brush brush = new System.Drawing.SolidBrush(Color.FromArgb(64, SelectColor)))
                        g.FillRectangle(brush, new Rectangle(node.Bounds.Location, node.Bounds.Size));
                }
                using (Pen pen = new System.Drawing.Pen(DrawColor, 1))
                    g.DrawRectangle(pen, new Rectangle(node.Bounds.Location, node.Bounds.Size));
                Point[] triangle = new Point[4] {
                    new Point(LeftPos, VertPos - 1), new Point(LeftPos, VertPos), new Point(LeftPos + 11, VertPos + 4), new Point(LeftPos + 11, VertPos - 5)
                };
                using (Brush brush = new System.Drawing.SolidBrush(DrawColor))
                    g.FillPolygon(brush, triangle);
                break;

            case NodeRelationship.ChildGoesUnder:
                VertPos = node.Bounds.Bottom;
                break;
            }
            using (Pen pen = new System.Drawing.Pen(DrawColor, 2))
                g.DrawLine(pen, new Point(LeftPos, VertPos), new Point(RightPos, VertPos));
        }
Beispiel #14
0
 private static bool IsAllowedToHaveRelationDefault(TreeNode parent, TreeNode child, NodeRelationship relation)
 {
     return(true);
 }