Exemple #1
0
        public override NodeViewData CreateNodeViewData(NodeViewData parent, BehaviorNode rootBehavior)
        {
            NodeViewData nvd = base.CreateNodeViewData(parent, rootBehavior);
            nvd.ChangeShape(NodeShape.Ellipse);

            return nvd;
        }
Exemple #2
0
        public override NodeViewData CreateNodeViewData(NodeViewData parent, BehaviorNode rootBehavior)
        {
            NodeViewData nvd = base.CreateNodeViewData(parent, rootBehavior);
            nvd.ChangeShape(this.IsEndState ? NodeShape.RoundedRectangle : NodeShape.Rectangle);

            return nvd;
        }
Exemple #3
0
        public override NodeViewData CreateNodeViewData(NodeViewData parent, Behaviac.Design.Nodes.BehaviorNode rootBehavior)
        {
            NodeViewData nvd = base.CreateNodeViewData(parent, rootBehavior);
            nvd.ChangeShape(NodeShape.Rectangle);

            return nvd;
        }
Exemple #4
0
        public override NodeViewData CreateNodeViewData(NodeViewData parent, Behaviac.Design.Nodes.BehaviorNode rootBehavior)
        {
            NodeViewDataStyled nvd = new NodeViewDataStyled(parent, rootBehavior, this, null, __defaultBackgroundBrush, _label, _description);

            nvd.ChangeShape(NodeShape.Rectangle);

            return nvd;
        }
 /// <summary>
 /// Creates a new NodeLayoutManager.
 /// </summary>
 /// <param name="edgePen">The pen which is used to draw the edges connecting the nodes.</param>
 /// <param name="edgePenSubReferenced">The pen which is used to draw the edges connecting sub-referenced nodes.</param>
 /// <param name="skipLabels">Defines if labels are drawn or not.</param>
 /// <param name="rootNode">The root of the nodes shown in the view.</param>
 internal NodeLayoutManager(NodeViewData rootNode, Pen edgePen, Pen edgePenHighlight, Pen edgePenUpdate, Pen edgePenSubReferenced, bool skipLabels)
 {
     _rootNodeLayout = rootNode;
     _edgePen = edgePen;
     _edgePenHighLight = edgePenHighlight;
     _edgePenUpdate = edgePenUpdate;
     _edgePenReadOnly = edgePenSubReferenced;
     _skipLabels = skipLabels;
 }
            public override void Draw(Graphics graphics, NodeViewData nvd, RectangleF boundingBox) {
                Attach evnt = (Attach)_attachment;

                //// use a different brush depending on if the event is reacted to or blocked.
                //_labelBrush= evnt.BlockEvent ? Brushes.Orange : Brushes.White;
                _labelBrush = Brushes.White;

                base.Draw(graphics, nvd, boundingBox);
            }
 public NodeViewDataStyled(NodeViewData parent, BehaviorNode rootBehavior, Node node, Pen borderPen, Brush backgroundBrush, Brush draggedBackgroundBrush, string label, string description, int minWidth = 120, int minHeight = 35) :
     base(parent, rootBehavior, node,
          NodeShape.RoundedRectangle,
          new Style(backgroundBrush, null, Brushes.White),
          new Style(null, DefaultCurrentBorderPen, null),
          new Style(null, __defaultSelectedBorderPen, null),
          new Style(draggedBackgroundBrush, null, null),
          new Style(null, __highlightedBorderPen, null),
          new Style(null, __updatedBorderPen, null),
          new Style(null, __prefabBorderPen, null),
          label, __defaultLabelFont, __profileLabelFont, __profileLabelBoldFont, minWidth, minHeight, description) {
 }
Exemple #8
0
        /// <summary>
        /// Handles when dropping a tree node on the view.
        /// </summary>
        private void BehaviorTreeView_DragDrop(object sender, DragEventArgs e) {
            // make sure the view is focused
            Focus();

            // drag the property or method into the node
            string dragItem = (string)e.Data.GetData(DataFormats.Text);

            if (!string.IsNullOrEmpty(dragItem) && _dragTargetNode != null && _dragTargetNode.Node != null) {
                if (_dragTargetNode.Node.SetDefaultPropertyByDragAndDrop(dragItem)) {
                    if (ClickNode != null) {
                        ClickNode(_dragTargetNode);
                    }

                    UndoManager.Save(this.RootNode);

                    LayoutChanged();
                }

                return;
            }

            // get source node
            TreeNode sourceNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");

            if (sourceNode == null) {
                return;
            }

            NodeTag sourceNodeTag = (NodeTag)sourceNode.Tag;

            // keep the current node position
            //KeepNodePosition(_dragTargetNode);

            bool bDragBTOverNode = !((Node)this.RootNode).IsFSM && sourceNodeTag.Type == NodeTagType.Behavior && _dragTargetNode is Behaviac.Design.NodeViewData;

            // check if we are dropping an attach
            // or if we are dropping a bt to a node and the indicator is not left/right/up/bottom/center
            if (_dragAttachMode == NodeAttachMode.Attachment ||
                (bDragBTOverNode && (_dragAttachMode == NodeAttachMode.None || _dragAttachMode == NodeAttachMode.Attachment))) {
                Attachments.Attachment attach = null;

                // when we attach a behaviour we must create a special referenced behaviour node
                if (bDragBTOverNode) {
                    //drag an event(a bt) to a node
                    if (!File.Exists(sourceNodeTag.Filename))
                    {
                        MainWindow.Instance.SaveBehavior(sourceNodeTag.Defaults as Nodes.BehaviorNode, false);
                    }

                    if (File.Exists(sourceNodeTag.Filename)) {
                        // get the behavior we want to reference
                        BehaviorNode behavior = _behaviorTreeList.LoadBehavior(sourceNodeTag.Filename);
                        Behavior rootB = _rootNodeView.RootBehavior as Behavior;
                        Behavior b = behavior as Behavior;

                        if (!b.CanBeAttached || !IsCompatibleAgentType(rootB, b))
                            return;

                        attach = Behaviac.Design.Attachments.Attachment.Create(typeof(Behaviac.Design.Attachments.Event), _dragTargetNode.Node);
                        Behaviac.Design.Attachments.Event evt = (Behaviac.Design.Attachments.Event)attach;
                        evt.ReferencedBehavior = behavior;
                    }

                } else if (_dragTargetNode != null) {
                    Debug.Check(_dragAttachMode == NodeAttachMode.Attachment);

                    // add the attach to the target node
                    attach = Behaviac.Design.Attachments.Attachment.Create(sourceNodeTag.NodeType, _dragTargetNode.Node);
                }

                if (_dragTargetNode != null && attach != null && _dragTargetNode.Node.AcceptsAttachment(attach))
                {
                    attach.OnPropertyValueChanged(false);

                    attach.ResetId();
                    _dragTargetNode.Node.AddAttachment(attach);

                    NodeViewData.SubItemAttachment sub = attach.CreateSubItem();
                    _dragTargetNode.AddSubItem(sub);

                    SelectedNode = _dragTargetNode;
                    SelectedNode.SelectedSubItem = sub;

                    // call the ClickEvent event handler
                    if (ClickEvent != null) {
                        ClickEvent(SelectedNode);
                    }

                    UndoManager.Save(this.RootNode);

                    LayoutChanged();
                }
            }

            //else if (_dragAttachMode != NodeAttachMode.None)
            else {
                // attach a new node to the target node
                InsertNewNode(_dragTargetNode, _dragAttachMode, sourceNodeTag, this.PointToClient(new Point(e.X, e.Y)));
            }

            // reset drag stuff
            _dragTargetNode = null;
            _dragNodeDefaults = null;
            _dragAttachMode = NodeAttachMode.None;

            Invalidate();
        }
Exemple #9
0
        /// <summary>
        /// Centres the given node in the view.
        /// </summary>
        /// <param name="node">The node which will be centred.</param>
        internal void CenterNode(NodeViewData node) {
            _maintainNodePosition = node;

            // we use the existing maintain position stuff for that
            RectangleF bbox = node.IsFSM ? node.GetTotalBoundingBox() : node.BoundingBox;

            float width = bbox.Width <= 0.0f ? node.MinWidth : bbox.Width;
            float height = bbox.Height <= 0.0f ? node.MinHeight : bbox.Height;

            // Scale the whole graph to the suitable size in the view.
            float viewWidth = ClientSize.Width - 30;
            float viewHeight = ClientSize.Height - 30;
            bool isWidthScale = false;

            if (viewWidth > 0 && viewHeight > 0) {
                SizeF totalSize = node.GetTotalSize(_nodeLayoutManager.Padding.Width, int.MaxValue);
                float scale = 1.0f;

                if (totalSize.Width / totalSize.Height < viewWidth / viewHeight) {
                    scale = viewHeight / totalSize.Height;
                    isWidthScale = false;
                }

                else {
                    scale = viewWidth / totalSize.Width;
                    isWidthScale = true;
                }

                const float MinScale = 0.1f;
                const float MaxScale = 2.0f;

                if (scale < MinScale) {
                    _nodeLayoutManager.Scale = MinScale;
                }

                else if (scale > MaxScale) {
                    _nodeLayoutManager.Scale = MaxScale;
                }

                else {
                    _nodeLayoutManager.Scale = scale;
                }
            }

            if (node.IsFSM)
            {
                if (isWidthScale)
                    _graphOrigin = new PointF(0.0f, ClientSize.Height * 0.5f - height * 0.5f * _nodeLayoutManager.Scale);
                else
                    _graphOrigin = new PointF(ClientSize.Width * 0.5f - width * 0.5f * _nodeLayoutManager.Scale, 0.0f);
            }
            else
            {
                _graphOrigin = new PointF(20.0f, ClientSize.Height * 0.5f - height * 0.5f);
            }

            Invalidate();
        }
Exemple #10
0
        private void saveAsReferencedTree() {
            if (SelectedNode == null ||
                SelectedNode == _rootNodeView ||
                _rootNodeView.RootBehavior.FileManager == null) {
                return;
            }

            string folder = _rootNodeView.RootBehavior.Folder;

            if (string.IsNullOrEmpty(folder)) {
                folder = Path.GetDirectoryName(_rootNodeView.RootBehavior.FileManager.Filename);
            }

            string ext = Path.GetExtension(_rootNodeView.RootBehavior.FileManager.Filename);
            string filename = Path.Combine(folder, "rf_" + SelectedNode.Node.ExportClass);
            filename = Path.ChangeExtension(filename, ext);

            using(SaveAsDialog saveAsDialog = new SaveAsDialog(true)) {
                saveAsDialog.Text = Resources.SaveAsReference;
                saveAsDialog.FileName = _behaviorTreeList.GetUniqueFileName(filename);

                if (saveAsDialog.ShowDialog() == DialogResult.OK) {
                    filename = saveAsDialog.FileName;

                    // Remove the selected node.
                    Node parentNode = SelectedNode.Node.Parent as Node;
                    BaseNode.Connector parentConnector = SelectedNode.Node.ParentConnector;
                    int index = parentConnector.GetChildIndex(SelectedNode.Node);
                    parentNode.RemoveChild(parentConnector, SelectedNode.Node);

                    // Create a new behavior node.
                    BehaviorNode behaviorNode = Node.CreateBehaviorNode(SelectedNode.Node.ExportClass);
                    ((Node)behaviorNode).AddChild(behaviorNode.GenericChildren, SelectedNode.Node);
                    ((Behavior)behaviorNode).AgentType = ((Behavior)_rootNodeView.RootBehavior).AgentType;

                    // Copy the used Pars from the current behavior to the new one.
                    foreach(ParInfo par in((Behavior)_rootNodeView.RootBehavior).LocalVars) {
                        List<Node.ErrorCheck> result = new List<Node.ErrorCheck>();
                        Plugin.CheckPar(SelectedNode.Node, par, ref result);

                        if (result.Count > 0) {
                            ((Behavior)behaviorNode).LocalVars.Add(par);
                        }
                    }

                    // Save the new behavior node.
                    behaviorNode.FileManager = _behaviorTreeList.GetFileManagers()[0].Create(filename, behaviorNode);
                    behaviorNode.FileManager.Save();

                    _behaviorTreeList.RebuildBehaviorList();

                    // get the behavior we want to reference
                    behaviorNode = _behaviorTreeList.LoadBehavior(filename);

                    // Create a referenced node to hold the new behavior node.
                    ReferencedBehavior refNode = Node.CreateReferencedBehaviorNode(_rootNodeView.RootBehavior, behaviorNode);

                    // Add the new referenced node.
                    Node newNode = refNode as Node;
                    parentNode.AddChild(parentConnector, newNode, index);

                    // Select the new node automatically.
                    _selectedNodePending = newNode;
                    _selectedNodePendingParent = SelectedNode.Parent;

                    newNode.ResetId(true);
                    UndoManager.Save(this.RootNode);

                    LayoutChanged();
                }
            }
        }
Exemple #11
0
        /// <summary>
        /// Handles when a tree node is dragged on the view.
        /// </summary>
        private void BehaviorTreeView_DragOver(object sender, DragEventArgs e) {
            // get the node we are dragging over
            Point pt = PointToClient(new Point(e.X, e.Y));
            NodeViewData nodeFound = _rootNodeView.GetInsideNode(new PointF(pt.X, pt.Y));

            // update last know mouse position
            _lastMousePosition = new PointF(pt.X, pt.Y);

            // update the current node
            if (nodeFound != _currentNode) {
                _currentNode = nodeFound;
                Invalidate();
            }

            // when we are moving on a node we must keep drawing as the ttach ode might change but not the node
            else if (nodeFound != null) {
                Invalidate();
            }

            // store the target node
            _dragTargetNode = _currentNode;

            // deny drop by default
            e.Effect = DragDropEffects.None;

            // process dragging the property and method string value from the Meta Browser
            string dragItem = (string)e.Data.GetData(DataFormats.Text);

            if (!string.IsNullOrEmpty(dragItem) &&
                _dragTargetNode != null && _dragTargetNode.Node != null &&
                _dragTargetNode.Node.AcceptDefaultPropertyByDragAndDrop()) {
                e.Effect = DragDropEffects.Move;

                _dragAttachMode = NodeAttachMode.None;

                return;
            }

            // make sure the correct drag attach mode is set
            if (_dragTargetNode != null) {
                if (_dragNodeDefaults is Nodes.Node && _dragAttachMode == NodeAttachMode.Attachment) {
                    _dragAttachMode = NodeAttachMode.None;

                } else if (_dragNodeDefaults is Attachments.Attachment && _dragAttachMode != NodeAttachMode.Attachment) {
                    _dragAttachMode = NodeAttachMode.Attachment;
                }
            }

            // check if we are trying to drop a node on another one
            if (_dragTargetNode != null && (e.KeyState & 1/*left mouse button*/) > 0) {
                if (_dragNodeDefaults != null &&
                    (_dragNodeDefaults is Nodes.Node && (_dragAttachMode != NodeAttachMode.None || !(_dragNodeDefaults is Nodes.BehaviorNode) || !(_dragTargetNode.Node is Nodes.BehaviorNode)) ||
                     _dragNodeDefaults is Attachments.Attachment && _dragTargetNode.Node.AcceptsAttachment(_dragNodeDefaults))) {
                    e.Effect = DragDropEffects.Move;
                }
            }

            // If this is an empty node, no effect for it.
            if (_dragTargetNode == null || _dragTargetNode.Node == null || _dragNodeDefaults == null ||
                _dragAttachMode == NodeAttachMode.None && !_dragTargetNode.Node.AcceptsAttachment(_dragNodeDefaults))
            {
                e.Effect = DragDropEffects.None;
            }

            if (_rootNodeView.IsFSM || _rootNodeView.Children.Count == 0) { // fsm or empty behavior
                if (_dragNodeDefaults != null) {
                    if (_dragNodeDefaults is Node) {
                        Node dragNode = _dragNodeDefaults as Node;

                        if (dragNode.IsFSM || dragNode is Behavior) {
                            if (_dragTargetNode == null) {
                                e.Effect = DragDropEffects.Move;
                            }
                            //else if (_dragNodeDefaults is Nodes.BehaviorNode) {
                            //    e.Effect = DragDropEffects.None;
                            //}
                        }

                    } else if (_dragNodeDefaults is Attachments.Attachment) {
                        Attachments.Attachment dragAttachment = _dragNodeDefaults as Attachments.Attachment;

                        if (dragAttachment.IsFSM) {
                            if (_dragTargetNode != null && !(_dragTargetNode.Node is Nodes.BehaviorNode) &&
                                _dragTargetNode.Node.AcceptsAttachment(dragAttachment)) {
                                e.Effect = DragDropEffects.Move;
                            }

                            else {
                                e.Effect = DragDropEffects.None;
                            }
                        }
                    }
                }
            }
        }
            public override void Draw(Graphics graphics, NodeViewData nvd, RectangleF boundingBox) {
                // render background
                DrawBackground(graphics, nvd, this.BackgroundBrush);

                // render the label
                PointF center = new PointF(boundingBox.Left + boundingBox.Width * 0.5f, boundingBox.Top + boundingBox.Height * 0.5f);

                SizeF labelSize = MeasureDisplayStringWidth(graphics, this.DisplayLabel, _labelFont);

                // draw text
                switch (_alignment) {
                    case (Alignment.Left):
                        graphics.DrawString(this.DisplayLabel, _labelFont, _labelBrush, boundingBox.Left + 6.0f, center.Y - labelSize.Height * 0.5f);
                        break;

                    case (Alignment.Center):
                        graphics.DrawString(this.DisplayLabel, _labelFont, _labelBrush, center.X - labelSize.Width * 0.5f, center.Y - labelSize.Height * 0.5f);
                        break;

                    case (Alignment.Right):
                        graphics.DrawString(this.DisplayLabel, _labelFont, _labelBrush, boundingBox.Right - labelSize.Width - 6.0f, center.Y - labelSize.Height * 0.5f);
                        break;
                }
            }
Exemple #13
0
        private bool MoveSubItem(NodeViewData sourceNvd, NodeViewData targetNvd, NodeViewData.SubItemAttachment sourceAttachment, NodeViewData.SubItemAttachment targetAttachment, bool insertPreviously, bool isCopied) {
            if (sourceNvd != null && targetNvd != null && sourceAttachment != null &&
                sourceNvd.SetSubItem(targetNvd, sourceAttachment, targetAttachment, insertPreviously, isCopied)) {
                // set the prefab dirty for the node
                if (!string.IsNullOrEmpty(sourceNvd.Node.PrefabName)) {
                    sourceNvd.Node.HasOwnPrefabData = true;
                }

                if (!string.IsNullOrEmpty(targetNvd.Node.PrefabName)) {
                    targetNvd.Node.HasOwnPrefabData = true;
                }

                SelectedNode = targetNvd;

                // call the ClickEvent event handler
                if (ClickEvent != null) {
                    ClickEvent(SelectedNode);
                }

                UndoManager.Save(this.RootNode);

                LayoutChanged();

                return true;
            }

            return false;
        }
Exemple #14
0
        private void control_ClickEvent(NodeViewData node)
        {
            if (node == null)
                return;

            // if there is no subitem selected, use the properties of the node
            if (node.SelectedSubItem == null || node.SelectedSubItem.SelectableObject == null)
            {
                PropertiesDock.InspectObject(node.RootBehavior, node.Node);
            }
            // publish the properties of the subitem's selection object
            else
            {
                PropertiesDock.InspectObject(node.RootBehavior, node.SelectedSubItem.SelectableObject);
            }
        }
Exemple #15
0
        /// <summary>
        /// Handles the drawing and updating of the graph.
        /// </summary>
        protected override void OnPaint(PaintEventArgs e) {
            base.OnPaint(e);

            // calculate the mouse position in the graph
            PointF graphMousePos = _nodeLayoutManager.ViewToGraph(_lastMousePosition);

            // when the layout was changed it needs to be recalculated
            bool layoutChanged = _nodeLayoutManager.LayoutChanged;

            if (layoutChanged) {
                _nodeLayoutManager.UpdateLayout(e.Graphics, _forceChangeLayout);
                _forceChangeLayout = false;
            }

            // center the root behaviour if requested
            if (_pendingCenterBehavior) {
                _pendingCenterBehavior = false;
                CenterNode(_rootNodeView);
            }

            // select the pending node
            if (_selectedNodePending != null) {
                if (_selectedNodePendingParent != null) {
                    if (_selectedNodePendingParent.CanBeExpanded() && !_selectedNodePendingParent.IsExpanded) {
                        _selectedNodePendingParent.IsExpanded = true;
                        LayoutChanged();
                    }

                    SelectedNode = _selectedNodePendingParent.GetChild(_selectedNodePending);

                } else {
                    SelectedNode = RootNodeView.FindNodeViewData(_selectedNodePending);
                }

                if (SelectedNode != null) {
                    if (SelectedNode.CanBeExpanded() && !SelectedNode.IsExpanded) {
                        SelectedNode.IsExpanded = true;
                        LayoutChanged();
                    }

                    SelectedNode.SelectedSubItem = SelectedNode.GetSubItem(_selectedAttachmentPending);
                    ShowNode(SelectedNode);
                }

                _selectedNodePending = null;
                _selectedNodePendingParent = null;
                _selectedAttachmentPending = null;

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

            // check if we must keep the original position of the mouse
            if (_maintainMousePosition) {
                _maintainMousePosition = false;

                // move the graph so that _graphOrigin is at the same position in the view as it was before
                float mouseX = (graphMousePos.X - _graphOrigin.X) * _nodeLayoutManager.Scale + _nodeLayoutManager.Offset.X;
                float mouseY = (graphMousePos.Y - _graphOrigin.Y) * _nodeLayoutManager.Scale + _nodeLayoutManager.Offset.Y;

                _nodeLayoutManager.Offset = new PointF(mouseX, mouseY);
            }

            // check if we must keep the original position of _maintainNodePosition
            else if (_maintainNodePosition != null) {
                // move the graph so that _graphOrigin is at the same position in the view as it was before
                RectangleF bbox = _maintainNodePosition.IsFSM ? _maintainNodePosition.GetTotalBoundingBox() : _maintainNodePosition.BoundingBox;
                PointF viewpos = new PointF(bbox.X * _nodeLayoutManager.Scale, bbox.Y * _nodeLayoutManager.Scale);

                _nodeLayoutManager.Offset = new PointF(_graphOrigin.X - viewpos.X, _graphOrigin.Y - viewpos.Y);
            }

            // reset the node whose position we want to keep
            _maintainNodePosition = null;

            // draw the graph to the view
            _nodeLayoutManager.DrawGraph(e.Graphics, graphMousePos, _currentNode, SelectedNode, _highlightedNodeIds, _updatedNodeIds, _highlightedTransitionIds, _highlightBreakPoint, _profileInfos);

            // check if we are currently dragging a node and we must draw additional data
            if (_dragTargetNode != null && _dragAttachment == null && (KeyCtrlIsDown && _movedNode != null || _dragTargetNode.Node != _movedNode)) {
                if (_dragAttachMode == NodeAttachMode.Attachment) {
                    // we could draw some stuff for attachements here
                } else {
                    // draw the arrows for the attach modes

                    // get the bounding box of the node
                    RectangleF bbox = _dragTargetNode.BoundingBox;

                    // get the bounding box of the connector
                    _dragTargetConnector = null;

                    // the depth of the area for the mouse
                    const float offset = 12.0f;

                    // the distance of the arrow from the border and its height
                    const float innerOffset = 2.0f;

                    // the horizintal middle of the node
                    float centerX = bbox.Left + bbox.Width * 0.5f;
                    float centerY = bbox.Top + bbox.Height * 0.5f;
                    float centerBoxX = bbox.X + bbox.Width * 0.4f;
                    float centerBoxWidth = bbox.Width * 0.2f;

                    // the half width of the arrow depending of the node's height
                    float arrowHalfWidth = (bbox.Height - innerOffset - innerOffset) * 0.5f;

                    // calculate the mouse areas for the different attach modes
                    RectangleF top    = new RectangleF(centerBoxX, bbox.Top, centerBoxWidth, offset);
                    RectangleF bottom = new RectangleF(centerBoxX, bbox.Bottom - offset, centerBoxWidth, offset);
                    RectangleF center = new RectangleF(centerBoxX, centerY - offset * 0.5f, centerBoxWidth, offset);
                    RectangleF left   = new RectangleF(bbox.X, bbox.Y, offset, bbox.Height);

                    // update for dragging in a new node
                    BehaviorNode behavior = _dragNodeDefaults as BehaviorNode;

                    if (behavior != null && behavior.FileManager == null) {
                        behavior = null;
                    }

                    // the node that is currently dragged
                    Node draggedNode = (_movedNode != null) ? _movedNode : (_dragNodeDefaults as Node);

                    if (draggedNode == null) {
                        return;
                    }

                    Node.Connector parentConnector = _dragTargetNode.Node.ParentConnector;
                    bool canBeAdoptedByParent = parentConnector != null && (!parentConnector.IsAsChild || AdoptNodeByAncestor(_dragTargetNode.Node.Parent, draggedNode));
                    //bool targetCanBeAdoptedByParent = (_movedNode == null) || (_movedNode.ParentConnector != null) && _movedNode.ParentConnector.AcceptsChild(_dragTargetNode.Node);
                    bool hasParentBehavior = _dragTargetNode.HasParentBehavior(behavior);
                    bool parentHasParentBehavior = (_dragTargetNode.Parent == null);

                    bool isFSM = _rootNodeView.IsFSM || (_rootNodeView.Children.Count == 0);

                    bool mayTop = !isFSM && canBeAdoptedByParent /*&& targetCanBeAdoptedByParent*/ && !parentHasParentBehavior &&
                                  parentConnector != null && parentConnector.AcceptsChild(draggedNode);

                    bool mayBottom = mayTop;

                    bool mayCenter = !parentHasParentBehavior && (_rootNodeView.IsFSM && draggedNode.IsFSM || canBeAdoptedByParent && 
                                     draggedNode.GetType() != _dragTargetNode.Node.GetType() &&
                                     parentConnector != null && !parentConnector.IsReadOnly && parentConnector.AcceptsChild(draggedNode, true) &&
                                     draggedNode.CanAdoptChildren(_dragTargetNode.Node));

                    bool mayLeft = !isFSM && (_dragTargetNode.Node.Parent != _movedNode) &&
                                   canBeAdoptedByParent && !parentHasParentBehavior && !hasParentBehavior &&
                                   parentConnector != null && !parentConnector.IsReadOnly && parentConnector.AcceptsChild(draggedNode, true) &&
                                   !(draggedNode is BehaviorNode) && draggedNode.CanAdoptNode(_dragTargetNode.Node);

                    // update for moving an existing node
                    bool dragTargetHasParentMovedNode = false;

                    if (_movedNode != null) {
                        mayCenter = false;
                        dragTargetHasParentMovedNode = KeyShiftIsDown && _dragTargetNode.Node.HasParent(_movedNode);

                        // a node may not dragged on itself and may not dragged on one of its own children
                        if (_dragTargetNode.Node == _movedNode || dragTargetHasParentMovedNode) {
                            //mayTop = KeyCtrlIsDown;
                            mayTop &= KeyCtrlIsDown && (_dragTargetNode.Node.ParentConnector != null) && _dragTargetNode.Node.ParentConnector.AcceptsChild(_movedNode);
                            mayBottom = mayTop;
                            mayLeft = false;

                        } else {
                            // a dragged node cannot be placed in the same position again
                            mayTop &= (KeyCtrlIsDown || _dragTargetNode.Node.PreviousNode != _movedNode);
                            mayBottom &= (KeyCtrlIsDown || _dragTargetNode.Node.NextNode != _movedNode);
                            mayLeft &= _movedNode.CanAdoptChildren(_dragTargetNode.Node) && (!KeyShiftIsDown || _movedNode.Children.Count == 0);
                        }
                    }

                    if (_copiedNode != null) {
                        mayCenter = false;
                        mayLeft &= _copiedNode.CanAdoptChildren(_dragTargetNode.Node) && (!KeyShiftIsDown || _copiedNode.Children.Count == 0);
                        mayTop &= (_dragTargetNode.Node.ParentConnector != null) && _dragTargetNode.Node.ParentConnector.AcceptsChild(_copiedNode);
                        mayBottom = mayTop;

                    } else if (_clipboardPasteMode) {
                        mayCenter = false;
                        mayLeft &= !KeyShiftIsDown;
                    }

                    // reset the attach mode
                    _dragAttachMode = NodeAttachMode.None;

                    // the vertices needed to draw the arrows
                    PointF[] vertices = new PointF[3];

                    // draw the top arrow if this action is allowed
                    if (mayTop) {
                        vertices[0] = new PointF(centerX - arrowHalfWidth, top.Bottom - innerOffset);
                        vertices[1] = new PointF(centerX, top.Top + innerOffset);
                        vertices[2] = new PointF(centerX + arrowHalfWidth, top.Bottom - innerOffset);

                        if (top.Contains(graphMousePos)) {
                            _dragAttachMode = NodeAttachMode.Top;
                            e.Graphics.FillPolygon(Brushes.White, vertices);

                        } else {
                            e.Graphics.FillPolygon(Brushes.Black, vertices);
                        }
                    }

                    // draw the bottom arrow if this action is allowed
                    if (mayBottom) {
                        vertices[0] = new PointF(centerX - arrowHalfWidth, bottom.Top + innerOffset);
                        vertices[1] = new PointF(centerX + arrowHalfWidth, bottom.Top + innerOffset);
                        vertices[2] = new PointF(centerX, bottom.Bottom - innerOffset);

                        if (_dragAttachMode == NodeAttachMode.None && bottom.Contains(graphMousePos)) {
                            _dragAttachMode = NodeAttachMode.Bottom;
                            e.Graphics.FillPolygon(Brushes.White, vertices);

                        } else {
                            e.Graphics.FillPolygon(Brushes.Black, vertices);
                        }
                    }

                    // draw the center rectangle if this action is allowed
                    if (mayCenter) {
                        if (center.Contains(graphMousePos)) {
                            _dragAttachMode = NodeAttachMode.Center;
                            e.Graphics.FillRectangle(Brushes.White, centerX - arrowHalfWidth * 0.5f, centerY - innerOffset * 2.0f, arrowHalfWidth, innerOffset * 4.0f);

                        } else {
                            e.Graphics.FillRectangle(Brushes.Black, centerX - arrowHalfWidth * 0.5f, centerY - innerOffset * 2.0f, arrowHalfWidth, innerOffset * 4.0f);
                        }
                    }

                    // draw the left arrow if this action is allowed
                    if (mayLeft) {
                        vertices[0] = new PointF(left.Right - innerOffset, left.Top + innerOffset);
                        vertices[1] = new PointF(left.Right - innerOffset, left.Bottom - innerOffset);
                        vertices[2] = new PointF(left.Left + innerOffset, left.Top + left.Height * 0.5f);

                        if (_dragAttachMode == NodeAttachMode.None && left.Contains(graphMousePos)) {
                            _dragAttachMode = NodeAttachMode.Left;
                            e.Graphics.FillPolygon(Brushes.White, vertices);

                        } else {
                            e.Graphics.FillPolygon(Brushes.Black, vertices);
                        }
                    }

                    // draw the right arrow if this action is allowed
                    foreach(Node.Connector connector in _dragTargetNode.Connectors) {
                        RectangleF bboxConnector = _dragTargetNode.GetConnectorBoundingBox(bbox, connector);
                        RectangleF right = new RectangleF(bboxConnector.Right - offset, bboxConnector.Y, offset, bboxConnector.Height);

                        bool mayRight = !_rootNodeView.IsFSM && !dragTargetHasParentMovedNode &&
                                        !hasParentBehavior &&
                                        !connector.IsReadOnly &&
                                        connector.AcceptsChild(draggedNode) &&
                                        (!connector.IsAsChild || AdoptNodeByAncestor(_dragTargetNode.Node, draggedNode));

                        if (mayRight && draggedNode != null && connector == draggedNode.ParentConnector) {
                            mayRight = false;
                        }

                        if (mayRight) {
                            float inOffset = bboxConnector.Height > innerOffset * 4.0f ? innerOffset : 3.0f;

                            vertices[0] = new PointF(right.Left + inOffset, right.Top + inOffset);
                            vertices[1] = new PointF(right.Right - inOffset, right.Top + right.Height * 0.5f);
                            vertices[2] = new PointF(right.Left + inOffset, right.Bottom - inOffset);

                            if (_dragAttachMode == NodeAttachMode.None && right.Contains(graphMousePos)) {
                                _dragTargetConnector = _dragTargetNode.Node.GetConnector(connector.Identifier);
                                _dragAttachMode = NodeAttachMode.Right;
                                e.Graphics.FillPolygon(Brushes.White, vertices);

                            } else {
                                e.Graphics.FillPolygon(Brushes.Black, vertices);
                            }
                        }
                    }
                }
            }

            // draw last mouse pos
            //e.Graphics.DrawRectangle(Pens.Red, graphMousePos.X -1.0f, graphMousePos.Y -1.0f, 2.0f, 2.0f);

            //when we are dragging an existing node we draw a small graph representing it
            if (_movedNodeGraph != null) {
                // update the layout for the graph. This happens only once inside the function.
                _movedNodeGraph.UpdateLayout(e.Graphics);

                // offset the graph to the mouse position
                _movedNodeGraph.Offset = new PointF(_nodeLayoutManager.Offset.X + graphMousePos.X * _nodeLayoutManager.Scale,
                                                    _nodeLayoutManager.Offset.Y + graphMousePos.Y * _nodeLayoutManager.Scale - _movedNodeGraph.RootNodeLayout.LayoutRectangle.Height * 0.5f * _movedNodeGraph.Scale);

                // draw the graph
                _movedNodeGraph.DrawGraph(e.Graphics, graphMousePos);
            }

            // attachment
            if (_currentNode != null && _dragTargetNode != null &&
                _dragAttachment != null && _dragTargetAttachment != null && _dragAttachment != _dragTargetAttachment &&
                _dragTargetNode.Node.AcceptsAttachment(_dragAttachment.Attachment)) {
                _dragAttachMode = NodeAttachMode.None;

                Attachments.Attachment sourceAttach = _dragAttachment.SelectableObject as Attachments.Attachment;
                Attachments.Attachment targetAttach = _dragTargetAttachment.SelectableObject as Attachments.Attachment;

                if (sourceAttach != null && targetAttach != null &&
                    sourceAttach.IsPrecondition == targetAttach.IsPrecondition &&
                    sourceAttach.IsTransition == targetAttach.IsTransition &&
                    sourceAttach.IsEffector == targetAttach.IsEffector)
                {
                    SubItemRegin regin = _dragTargetNode.GetSubItemRegin(graphMousePos);
                    int itemIndex = _currentNode.GetSubItemIndex(_dragAttachment);
                    int targetItemIndex = _dragTargetNode.GetSubItemIndex(_dragTargetAttachment);

                    if (regin != SubItemRegin.Out && itemIndex >= 0 && targetItemIndex >= 0) {
                        RectangleF bbox = _dragTargetNode.GetSubItemBoundingBox(graphMousePos);

                        const float offset = 8.0f;
                        const float innerOffset = 2.0f;

                        float centerX = bbox.Left + bbox.Width * 0.5f;
                        float centerY = bbox.Top + bbox.Height * 0.5f;
                        float centerBoxX = bbox.X + bbox.Width * 0.4f;
                        float arrowHalfWidth = bbox.Width * 0.12f;

                        RectangleF top = new RectangleF(centerX - arrowHalfWidth, bbox.Top, arrowHalfWidth * 2.0f, offset);
                        RectangleF bottom = new RectangleF(centerX - arrowHalfWidth, bbox.Bottom - offset, arrowHalfWidth * 2.0f, offset);

                        PointF[] vertices = new PointF[3];

                        switch (regin) {
                            case SubItemRegin.Top:
                                if (KeyCtrlIsDown || _currentNode != _dragTargetNode || itemIndex != targetItemIndex - 1) {
                                    vertices[0] = new PointF(centerX - arrowHalfWidth, top.Bottom - innerOffset);
                                    vertices[1] = new PointF(centerX, top.Top + innerOffset);
                                    vertices[2] = new PointF(centerX + arrowHalfWidth, top.Bottom - innerOffset);

                                    if (top.Contains(graphMousePos)) {
                                        _dragAttachMode = NodeAttachMode.Top;
                                        e.Graphics.FillPolygon(Brushes.White, vertices);

                                    } else {
                                        e.Graphics.FillPolygon(Brushes.Black, vertices);
                                    }
                                }

                                break;

                            case SubItemRegin.Bottom:
                                if (KeyCtrlIsDown || _currentNode != _dragTargetNode || itemIndex != targetItemIndex + 1) {
                                    vertices[0] = new PointF(centerX - arrowHalfWidth, bottom.Top + innerOffset);
                                    vertices[1] = new PointF(centerX + arrowHalfWidth, bottom.Top + innerOffset);
                                    vertices[2] = new PointF(centerX, bottom.Bottom - innerOffset);

                                    if (bottom.Contains(graphMousePos)) {
                                        _dragAttachMode = NodeAttachMode.Bottom;
                                        e.Graphics.FillPolygon(Brushes.White, vertices);

                                    } else {
                                        e.Graphics.FillPolygon(Brushes.Black, vertices);
                                    }
                                }

                                break;
                        }
                    }
                }
            }

            if (_movedSubItem != null) {
                NodeViewData.SubItemText subitem = _movedSubItem as NodeViewData.SubItemText;

                if (subitem != null) {
                    RectangleF boundingBox = new RectangleF(graphMousePos, new SizeF(50, 12));
                    e.Graphics.FillRectangle(subitem.BackgroundBrush, boundingBox);
                }
            }

            // draw FSM related
            DrawFSMArrow(e, graphMousePos);
            DrawFSMDragCurve(e, graphMousePos);

            //the first time of paint, to collapse plan failed branch by default
            Behavior b = this.RootNode as Behavior;

            if (b.PlanIsCollapseFailedBranch > 0) {
                if (b.PlanIsCollapseFailedBranch == Behavior.kPlanIsCollapseFailedBranch) {
                    NodeViewData root = (NodeViewData)this.RootNodeView.Children[0];
                    CollapseFailedBrach(root);
                }

                b.PlanIsCollapseFailedBranch--;

                this.CenterNode(this._rootNodeView);
                this.LayoutChanged();
            }
        }
Exemple #16
0
        /// <summary>
        /// Handles when a key is released.
        /// </summary>
        protected override void OnKeyUp(KeyEventArgs e) {
            switch (e.KeyCode) {
                case (Keys.Enter):
                    if (SelectedNode != null) {
                        if (KeyCtrlIsDown) {
                            SelectedNode.ExpandAll(!SelectedNode.IsExpanded);
                        }

                        else {
                            SelectedNode.IsExpanded = !SelectedNode.IsExpanded;
                        }

                        LayoutChanged();

                        e.Handled = true;
                    }

                    break;

                    // store when the shift key is released
                case (Keys.ShiftKey):

                    // update the drawn graph for dragging and duplicating
                    if (_movedNodeGraph != null) {
                        _movedNodeGraph.RenderDepth = 0;
                        Invalidate();
                    }

                    break;

                    // paste from clipboard
                case (Keys.V):
                    PasteSelectedNode();

                    _clipboardPasteMode = false;

                    // reset all the drag data
                    _copiedNode = null;
                    _movedNode = null;
                    _dragTargetNode = null;
                    _dragNodeDefaults = null;
                    _movedNodeGraph = null;

                    // redraw the graph
                    Invalidate();
                    break;

                case (Keys.Left):
                case (Keys.Right):
                case (Keys.Up):
                case (Keys.Down):
                    if (e.Control)
                    {
                        break;
                    }

                    if (SelectedNode == null) {
                        SelectedNode = this.RootNodeView;

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

                        LayoutChanged();
                        break;
                    }

                    switch (e.KeyCode) {
                        case (Keys.Left):
                            if (SelectedNode != null && SelectedNode.Parent != null) {
                                SelectedNode = SelectedNode.Parent;

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

                                LayoutChanged();
                            }

                            break;

                        case (Keys.Right):
                            if (SelectedNode != null && SelectedNode.Children.Count > 0) {
                                SelectedNode = SelectedNode.Children[0] as NodeViewData;

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

                                LayoutChanged();
                            }

                            break;

                        case (Keys.Up):
                            if (SelectedNode != null) {
                                if (!KeyShiftIsDown || !SwitchSelection()) {
                                    // Node
                                    if (SelectedNode.SelectedSubItem == null) {
                                        if (SelectedNode.PreviousNode != null) {
                                            if (KeyCtrlIsDown) { // Move
                                                MoveNode(true);

                                            } else { // Select
                                                SelectedNode = SelectedNode.PreviousNode as NodeViewData;

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

                                    // Attachment
                                    else {
                                        NodeViewData.SubItem previousItem = SelectedNode.PreviousSelectedSubItem;

                                        if (previousItem != null) {
                                            if (KeyCtrlIsDown) { // Move
                                                NodeViewData.SubItemAttachment sourceItem = SelectedNode.SelectedSubItem as NodeViewData.SubItemAttachment;
                                                NodeViewData.SubItemAttachment targetItem = previousItem as NodeViewData.SubItemAttachment;
                                                MoveSubItem(SelectedNode, SelectedNode, sourceItem, targetItem, true, false);
                                                SelectedNode.SelectedSubItem = sourceItem;

                                            } else { // Select
                                                SelectedNode.SelectedSubItem = previousItem;

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

                                LayoutChanged();
                            }

                            break;

                        case (Keys.Down):
                            if (SelectedNode != null) {
                                if (!KeyShiftIsDown || !SwitchSelection()) {
                                    // Node
                                    if (SelectedNode.SelectedSubItem == null) {
                                        if (SelectedNode.NextNode != null) {
                                            if (KeyCtrlIsDown) { // Move
                                                MoveNode(false);

                                            } else { // Select
                                                SelectedNode = SelectedNode.NextNode as NodeViewData;

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

                                    // Attachment
                                    else {
                                        NodeViewData.SubItem nextItem = SelectedNode.NextSelectedSubItem;

                                        if (nextItem != null) {
                                            if (KeyCtrlIsDown) { // Move
                                                NodeViewData.SubItemAttachment sourceItem = SelectedNode.SelectedSubItem as NodeViewData.SubItemAttachment;
                                                NodeViewData.SubItemAttachment targetItem = nextItem as NodeViewData.SubItemAttachment;
                                                MoveSubItem(SelectedNode, SelectedNode, sourceItem, targetItem, false, false);
                                                SelectedNode.SelectedSubItem = sourceItem;

                                            } else { // Select
                                                SelectedNode.SelectedSubItem = nextItem;

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

                                LayoutChanged();
                            }

                            break;
                    }

                    break;

                default:
                    base.OnKeyUp(e);
                    break;
            }
        }
Exemple #17
0
 private void KeepNodePosition(NodeViewData nvd) {
     // keep the position of the current node
     if (nvd != null && !nvd.IsFSM)
     {
         _maintainNodePosition = nvd;
         _graphOrigin = _maintainNodePosition.DisplayBoundingBox.Location;
     }
 }
Exemple #18
0
        private void MoveNode(bool insertPreviously) {
            if (SelectedNode != null) {
                Node node = SelectedNode.Node as Node;
                Node parent = node.Parent as Node;
                BaseNode.Connector connector = node.ParentConnector;

                if (parent != null && connector != null) {
                    int n = connector.GetChildIndex(node);
                    Debug.Check(n >= 0 && n < connector.ChildCount);

                    if (insertPreviously) {
                        Debug.Check(n > 0);

                        parent.RemoveChild(connector, node);
                        parent.AddChild(connector, node, n - 1);

                    } else {
                        Debug.Check(n < connector.ChildCount - 1);

                        parent.RemoveChild(connector, node);
                        parent.AddChild(connector, node, n + 1);
                    }

                    _selectedNodePending = node;
                    _selectedNodePendingParent = SelectedNode.Parent;

                    // set the prefab dirty for the current node
                    if (!string.IsNullOrEmpty(node.PrefabName)) {
                        node.HasOwnPrefabData = true;
                    }

                    UndoManager.Save(this.RootNode);
                }
            }
        }
Exemple #19
0
        /// <summary>
        /// Handles when a mouse button was pressed.
        /// </summary>
        protected override void OnMouseDown(MouseEventArgs e) {
            // the graph has not yet been dragged
            _startMousePosition = e.Location;
            _lastMousePosition = e.Location;
            _objectDragType = ObjectDragTypes.kNone;
            _dragAttachment = null;
            _dragTargetAttachment = null;
            _movedSubItem = null;
            _fsmDragMode = FSMDragModes.kNone;

            if (!_clipboardPasteMode) {
                _currentNode = _rootNodeView.GetInsideNode(_lastMousePosition);
                _dragTargetNode = null;
                _movedNodeGraph = null;
                _movedNode = null;

                if (_currentNode != null) {
                    if (KeyCtrlIsDown || _currentNode.IsFSM || _currentNode.CanBeDragged() &&
                        (KeyShiftIsDown || _currentNode.Node.ParentCanAdoptChildren)) {
                        _objectDragType = ObjectDragTypes.kNode;
                    }
                }

            } else {
                if (_currentNode == null) {
                    _currentNode = _rootNodeView.GetInsideNode(_lastMousePosition);
                }

                if (_dragTargetNode == null) {
                    _dragTargetNode = _currentNode;
                }
            }

            if (e.Button == MouseButtons.Left && _currentNode != null) {
                Debug.Check(_nodeLayoutManager != null);
                NodeViewData.SubItem subItem = _currentNode.GetSubItem(_currentNode, _nodeLayoutManager.ViewToGraph(e.Location));
                NodeViewData.SubItemAttachment attach = subItem as NodeViewData.SubItemAttachment;

                if (attach != null && attach.IsSelected) {
                    _objectDragType = ObjectDragTypes.kAttachment;
                }

                PointF graphMousePos = _nodeLayoutManager.ViewToGraph(_lastMousePosition);
                NodeViewData.RangeType rangeType = _currentNode.CheckFSMArrowRange(graphMousePos, out _fsmSubItem, out _fsmItemBoundingBox);

                if (rangeType != NodeViewData.RangeType.kNode) {
                    _objectDragType = ObjectDragTypes.kNone;

                    if (Plugin.EditMode == EditModes.Design)
                    {
                        if (rangeType == NodeViewData.RangeType.kFSMLeftArrow)
                        {
                            _fsmDragMode = FSMDragModes.kLeft;
                        }

                        else if (rangeType == NodeViewData.RangeType.kFSMRightArrow)
                        {
                            _fsmDragMode = FSMDragModes.kRight;
                        }
                    }
                }
            }

            if (_currentNode == null) {
                _objectDragType = ObjectDragTypes.kGraph;
            }

            // focus the view if not focused
            if (!Focused) {
                // we focus twice to avoid an issue with focusing the view
                Parent.Focus();

                //OnMouseDown will cal OnGotFocus as well
                //Focus();
            }

            base.OnMouseDown(e);
        }
Exemple #20
0
        /// <summary>
        /// Handles when a mouse button is let go of.
        /// </summary>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            _movedSubItem = null;

            // check if we were dragging a transition for the FSM.
            if (e.Button == MouseButtons.Left && _currentNode != null && ((_objectDragType == ObjectDragTypes.kNode) && _currentNode.IsFSM || _fsmSubItem != null && _fsmDragMode != FSMDragModes.kNone)) {
                if (Plugin.EditMode == EditModes.Design && _startMousePosition != e.Location) {
                    // drag and move the fsm node
                    if ((_objectDragType == ObjectDragTypes.kNode) && _currentNode.IsFSM) {
                        UndoManager.Save(this.RootNode);

                        LayoutChanged();
                    }

                    // drag and connector the target node
                    else {
                        NodeViewData targetNvd = _rootNodeView.GetInsideNode(e.Location);

                        if (targetNvd != null && targetNvd.IsFSM && (targetNvd.Parent != null) && _fsmSubItem is NodeViewData.SubItemAttachment) {
                            NodeViewData.SubItemAttachment subItemAttachment = _fsmSubItem as NodeViewData.SubItemAttachment;

                            if (subItemAttachment.Attachment != null && subItemAttachment.Attachment.TargetFSMNodeId != targetNvd.Node.Id) {
                                subItemAttachment.Attachment.TargetFSMNodeId = targetNvd.Node.Id;

                                UndoManager.Save(this.RootNode);

                                LayoutChanged();
                            }
                        }
                    }
                }
            }

            // check if we were dragging an existing sub item.
            else if (e.Button == MouseButtons.Left && _currentNode != null && _dragTargetNode != null && _dragAttachment != null) {
                NodeViewData.SubItem targetSubItem = _dragTargetNode.GetSubItem(_dragTargetNode, _nodeLayoutManager.ViewToGraph(e.Location));

                if (KeyCtrlIsDown || targetSubItem != _dragAttachment) {
                    NodeViewData.SubItemAttachment targetAttachment = targetSubItem as NodeViewData.SubItemAttachment;

                    if ((_currentNode != _dragTargetNode || targetAttachment != null) &&
                        this.MoveSubItem(_currentNode, _dragTargetNode, _dragAttachment, targetAttachment, _dragAttachMode == NodeAttachMode.Top, KeyCtrlIsDown)) {
                        _currentNode.ClickEvent(_currentNode, _nodeLayoutManager.ViewToGraph(e.Location));

                        LayoutChanged();
                    }
                }

                _dragAttachment = null;
                _dragTargetAttachment = null;
                _dragAttachMode = NodeAttachMode.None;
            }

            // check if we were dragging or copying an existing node.
            else if (e.Button == MouseButtons.Left && (_movedNode != null || _copiedNode != null || _clipboardPasteMode)) {
                // if we have a valid target node continue
                if (_dragTargetNode != null) {
                    Node sourceNode = null;

                    if (_copiedNode != null) {
                        bool cloneBranch = !(_copiedNode is ReferencedBehavior);
                        sourceNode = (KeyShiftIsDown && cloneBranch) ? (Nodes.Node)_copiedNode.CloneBranch() : (Nodes.Node)_copiedNode.Clone();

                    } else if (_clipboardPasteMode) {
                        bool cloneBranch = !(_clipboardNode is ReferencedBehavior);
                        sourceNode = (/*KeyShiftIsDown && */cloneBranch) ? (Nodes.Node)_clipboardNode.CloneBranch() : (Nodes.Node)_clipboardNode.Clone();

                    } else if (_movedNode != null) {
                        sourceNode = _movedNode;
                    }

                    Debug.Check(sourceNode != null);
                    Node sourceParent = (Node)sourceNode.Parent;
                    BehaviorNode sourceBehavior = sourceNode.Behavior;

                    if (_dragTargetNode.Node == sourceNode) {
                        _dragAttachMode = NodeAttachMode.None;
                    }

                    if (_dragAttachMode == NodeAttachMode.Top ||
                        _dragAttachMode == NodeAttachMode.Bottom ||
                        _dragAttachMode == NodeAttachMode.Left ||
                        _dragAttachMode == NodeAttachMode.Right ||
                        _dragAttachMode == NodeAttachMode.Center) {
                        // set the prefab dirty for its previous parent
                        if (sourceParent != null && !string.IsNullOrEmpty(sourceParent.PrefabName)) {
                            sourceParent.HasOwnPrefabData = true;
                        }

                        if (KeyShiftIsDown) {
                            if (sourceParent != null) {
                                sourceParent.RemoveChild(sourceNode.ParentConnector, sourceNode);
                            }

                        } else {
                            sourceNode.ExtractNode();
                        }
                    }

                    // move the dragged node to the target node, according to the attach mode
                    switch (_dragAttachMode) {
                            // the node will be placed above the target node
                        case (NodeAttachMode.Top):
                            int n = _dragTargetNode.Node.ParentConnector.GetChildIndex(_dragTargetNode.Node);
                            ((Node)_dragTargetNode.Node.Parent).AddChild(_dragTargetNode.Node.ParentConnector, sourceNode, n);

                            _selectedNodePending = sourceNode;
                            _selectedNodePendingParent = _dragTargetNode.Parent;

                            LayoutChanged();
                            break;

                            // the node will be placed below the target node
                        case (NodeAttachMode.Bottom):
                            int m = _dragTargetNode.Node.ParentConnector.GetChildIndex(_dragTargetNode.Node);
                            ((Node)_dragTargetNode.Node.Parent).AddChild(_dragTargetNode.Node.ParentConnector, sourceNode, m + 1);

                            _selectedNodePending = sourceNode;
                            _selectedNodePendingParent = _dragTargetNode.Parent;

                            LayoutChanged();
                            break;

                            // the node will be placed in front of the target node
                        case (NodeAttachMode.Left):
                            Node parent = (Node)_dragTargetNode.Node.Parent;
                            Node.Connector conn = _dragTargetNode.Node.ParentConnector;

                            int o = conn.GetChildIndex(_dragTargetNode.Node);

                            parent.RemoveChild(conn, _dragTargetNode.Node);
                            parent.AddChild(conn, sourceNode, o);

                            BaseNode.Connector sourceConn = sourceNode.GetConnector(conn.Identifier);
                            Debug.Check(sourceConn != null);

                            sourceNode.AddChild(sourceConn, _dragTargetNode.Node);

                            _selectedNodePending = sourceNode;
                            _selectedNodePendingParent = _dragTargetNode.Parent;

                            LayoutChanged();
                            break;

                            // the node will simply attached to the target node
                        case (NodeAttachMode.Right):
                            _dragTargetNode.Node.AddChild(_dragTargetConnector, sourceNode);

                            _selectedNodePending = sourceNode;
                            _selectedNodePendingParent = _dragTargetNode;

                            LayoutChanged();
                            break;

                            // the node will replace the target node
                        case (NodeAttachMode.Center):
                            if (replaceNode(_dragTargetNode.Node, sourceNode)) {
                                LayoutChanged();
                            }

                            break;
                    }

                    if (_dragAttachMode != NodeAttachMode.None) {
                        // If cloning a node, its Id should be reset.
                        if (_copiedNode != null || _clipboardPasteMode) {
                            // Cross two different behavior files
                            if (_clipboardPasteMode && _clipboardRootNode != this.RootNodeView) {
                                try {
                                    // Copy the used Pars from the current behavior to the new one.
                                    if (_clipboardNode != null && _clipboardRootNode != null && _clipboardRootNode.Node is Behavior) {
                                        foreach(ParInfo par in((Behavior)(_clipboardRootNode.Node)).LocalVars) {
                                            List<Node.ErrorCheck> result = new List<Node.ErrorCheck>();
                                            Plugin.CheckPar(_clipboardNode, par, ref result);

                                            if (result.Count > 0) {
                                                bool bExist = false;
                                                foreach(ParInfo p in((Behavior)this.RootNode).LocalVars) {
                                                    if (p.Name == par.Name) {
                                                        bExist = true;
                                                        break;
                                                    }
                                                }

                                                if (!bExist) {
                                                    ((Behavior)this.RootNode).LocalVars.Add(par);
                                                }
                                            }
                                        }
                                    }

                                    // reset its properties and methods
                                    sourceNode.ResetMembers(false, this.RootNode.AgentType, true);

                                } catch {
                                }
                            }

                            // reset its Id
                            sourceNode.ResetId(true);
                        }

                        // update the node's label
                        sourceNode.OnPropertyValueChanged(false);

                        // set the prefab dirty for its current parent
                        if (sourceNode.Parent != null) {
                            Node parent = (Node)sourceNode.Parent;

                            if (!string.IsNullOrEmpty(parent.PrefabName)) {
                                parent.HasOwnPrefabData = true;
                                sourceNode.SetPrefab(parent.PrefabName, true);
                            }
                        }

                        UndoManager.Save(this.RootNode);
                    }
                }

                // reset all the drag data
                if (!_clipboardPasteMode) {
                    _copiedNode = null;
                    _movedNode = null;
                    _dragTargetNode = null;
                    _dragNodeDefaults = null;
                    _movedNodeGraph = null;
                }

                // redraw the graph
                Invalidate();
            }

            // popup the menu for the current hit node
            else if (e.Button == MouseButtons.Right && !KeyAltIsDown && !KeyCtrlIsDown && !KeyShiftIsDown) {
                bool itemEnabled = (SelectedNode != null && SelectedNode.Node.Parent != null);
                itemEnabled &= (Plugin.EditMode == EditModes.Design);

                deleteMenuItem.ShortcutKeys = Keys.Delete;
                deleteTreeMenuItem.ShortcutKeys = Keys.Shift | Keys.Delete;

                cutMenuItem.Enabled = SelectedNodeCanBeCut();
                cutTreeMenuItem.Enabled = (SelectedNode != null) && !SelectedNode.IsFSM && SelectedTreeCanBeCut();
                copyMenuItem.Enabled = itemEnabled;
                copySubtreeMenuItem.Enabled = (SelectedNode != null) && !SelectedNode.IsFSM;
                pasteMenuItem.Enabled = SelectedNodeCanBePasted();
                deleteMenuItem.Enabled = SelectedNodeCanBeDeleted();
                deleteTreeMenuItem.Enabled = (SelectedNode != null) && !SelectedNode.IsFSM && SelectedTreeCanBeDeleted();

                bool isReferencedBehavior = SelectedNode != null && SelectedNode.Node is ReferencedBehavior;
                bool isEvent = SelectedNode != null && SelectedNode.SelectedSubItem != null && SelectedNode.SelectedSubItem.SelectableObject is Attachments.Event;
                referenceMenuItem.Enabled = itemEnabled || isReferencedBehavior || isEvent;
                referenceMenuItem.Text = (isReferencedBehavior || isEvent) ? Resources.OpenReference : Resources.SaveReference;

                disableMenuItem.Enabled = false;
                if (itemEnabled)
                {
                    if (SelectedNode.SelectedSubItem != null && SelectedNode.SelectedSubItem.SelectableObject is Attachments.Attachment)
                    {
                        Attachments.Attachment attach = SelectedNode.SelectedSubItem.SelectableObject as Attachments.Attachment;
                        disableMenuItem.Enabled = attach.CanBeDisabled();
                        disableMenuItem.Text = attach.Enable ? Resources.DisableNode : Resources.EnableNode;
                    }
                    else
                    {
                        disableMenuItem.Enabled = SelectedNode.Node.CanBeDisabled();
                        disableMenuItem.Text = SelectedNode.Node.Enable ? Resources.DisableNode : Resources.EnableNode;
                    }
                }

                expandMenuItem.Enabled = (SelectedNode != null && SelectedNode.CanBeExpanded());
                collapseMenuItem.Enabled = expandMenuItem.Enabled;
                expandAllMenuItem.Enabled = expandMenuItem.Enabled;
                collapseAllMenuItem.Enabled = expandMenuItem.Enabled;

                bool isPrefabInstance = SelectedNode != null && !string.IsNullOrEmpty(SelectedNode.Node.PrefabName);
                breakPrefabMenuItem.Enabled = itemEnabled && isPrefabInstance;

                if (isPrefabInstance) {
                    string fullpath = FileManagers.FileManager.GetFullPath(SelectedNode.Node.PrefabName);
                    isPrefabInstance = File.Exists(fullpath);
                }

                savePrefabMenuItem.Enabled = itemEnabled;
                savePrefabMenuItem.Text = isPrefabInstance ? Resources.OpenPrefab : Resources.SavePrefab;

                if (SelectedNode != null) {
                    Node prefabRoot = SelectedNode.Node.GetPrefabRoot();
                    string relativeFilename = FileManagers.FileManager.GetRelativePath(this.RootNode.Filename);
                    applyMenuItem.Enabled = itemEnabled && isPrefabInstance && SelectedNode.Node.PrefabName != relativeFilename && prefabRoot.IsPrefabDataDirty();
                }

                breakpointMenuItem.Enabled = SelectedNode != null && SelectedNode.Parent != null;

                if (SelectedNode != null) {
                    enterBreakpointMenuItem.Text = SelectedNode.GetBreakpointOperation(HighlightBreakPoint.kEnter);
                    exitBreakpointMenuItem.Text = SelectedNode.GetBreakpointOperation(HighlightBreakPoint.kExit);

                    this.beakpointPlanning.Visible = false;

                    if (SelectedNode.Node is Task) {
                        this.beakpointPlanning.Visible = true;
                        beakpointPlanning.Text = SelectedNode.GetBreakpointOperation(HighlightBreakPoint.kPlanning);
                    }
                }

                contextMenu.Show(this, new Point(e.X, e.Y));
            }

            Cursor = Cursors.Default;
            _fsmDragMode = FSMDragModes.kNone;

            // redraw the graph
            Invalidate();

            base.OnMouseUp(e);
        }
Exemple #21
0
        /// <summary>
        /// Shows the given node in the view.
        /// </summary>
        /// <param name="node">The node which will be centred.</param>
        internal void ShowNode(NodeViewData node) {
            // Expand all of its parents.
            bool layoutChanged = false;
            NodeViewData parent = node.Parent;

            while (parent != null) {
                if (!parent.IsExpanded) {
                    parent.IsExpanded = true;
                    layoutChanged = true;
                }

                parent = parent.Parent;
            }

            if (layoutChanged) {
                LayoutChanged();
            }

            // we use the existing maintain position stuff for that
            RectangleF bbox = node.BoundingBox;

            // If the node was not yet shown there is no bounding box,
            // so we simply use the min width and height for that.
            float width = bbox.Width <= 0.0f ? node.MinWidth : bbox.Width;
            float height = bbox.Height <= 0.0f ? node.MinHeight : bbox.Height;

            RectangleF displayBox = node.DisplayBoundingBox;

            // If this display bounding box is in the view, the node need not be moved.
            if (displayBox.X >= 0 && displayBox.X <= ClientSize.Width - width &&
                displayBox.Y >= 0 && displayBox.Y <= ClientSize.Height - height) {
                return;
            }

            _maintainNodePosition = node;

            _graphOrigin = new PointF(ClientSize.Width * 0.5f - width * 0.5f, ClientSize.Height * 0.5f - height * 0.5f);

            Invalidate();
        }
Exemple #22
0
        private void CollapseFailedBrach(NodeViewData nv) {
            Behavior b = nv.Node.Behavior as Behavior;

            if (b.PlanningProcess != null) {
                FrameStatePool.PlanningState nodeState = b.PlanningProcess.GetNode(nv.FullId);

                if (nodeState != null) {
                    //if (!nodeState._bOk || nodeState._bPreFailed)
                    if (nodeState._bPreFailed) {
                        nv.IsExpanded = false;
                        return;
                    }

                } else {
                    nv.IsExpanded = false;
                    return;
                }
            }

            if (nv.Children.Count > 0) {
                nv.IsExpanded = true;

                foreach(NodeViewData c in nv.Children) {
                    CollapseFailedBrach(c);
                }
            }
        }
Exemple #23
0
        /// <summary>
        /// Attaches a dragged node from the node explorer to an existing node.
        /// </summary>
        /// <param name="nvd">The node the new node will be attached to.</param>
        /// <param name="mode">The way the new node will be attached.</param>
        /// <param name="nodetag">The tag of the you want to create.</param>
        /// <param name="label">The label of the new node.</param>
        private void InsertNewNode(NodeViewData nvd, NodeAttachMode mode, NodeTag nodetag, PointF mousePos) {
            if (nodetag.Type != NodeTagType.Behavior && nodetag.Type != NodeTagType.Prefab && nodetag.Type != NodeTagType.Node) {
                throw new Exception("Only behaviours, prefabs and nodes can be attached to a behaviour tree");
            }

            Node newnode = null;
            bool isPrefabInstance = false;

            // when we attach a behaviour we must create a special referenced behaviour node
            if (nodetag.Type == NodeTagType.Behavior || nodetag.Type == NodeTagType.Prefab) {
                if (!File.Exists(nodetag.Filename)) {
                    if (!SaveBehavior(nodetag.Filename)) {
                        return;
                    }
                }

                // get the behavior we want to reference
                BehaviorNode behavior = _behaviorTreeList.LoadBehavior(nodetag.Filename);

                // a behaviour reference itself
                if (nvd != null && nvd.IsBehaviorReferenced(behavior)) {
                    if (DialogResult.Cancel == MessageBox.Show(Resources.CircularReferencedInfo, Resources.Warning, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning)) {
                        return;
                    }
                }

                if (nodetag.Type == NodeTagType.Prefab) {
                    behavior = (BehaviorNode)behavior.Clone();
                }

                Behavior rootB = _rootNodeView.RootBehavior as Behavior;
                Behavior b = behavior as Behavior;

                if (rootB.AgentType == null) {
                    rootB.AgentType = b.AgentType;

                } else if (!IsCompatibleAgentType(rootB, b)) {
                    return;
                }

                // behavior
                if (nodetag.Type == NodeTagType.Behavior) {
                    // create the referenced behaviour node for the behaviour
                    ReferencedBehavior refnode = Node.CreateReferencedBehaviorNode(_rootNodeView.RootBehavior, behavior, mode == NodeAttachMode.None || ((Node)this.RootNode).IsFSM);

                    newnode = (Node)refnode;
                    //the comment seems too long to overlap the node
                    //newnode.CommentText = Resources.ThisIsReferenceTree;
                    newnode.CommentBackground = Node.CommentColor.Gray;
                }

                // prefab
                else {
                    // Copy all Pars from the prefab file into the current behavior node.
                    List<ParInfo> pars = new List<ParInfo>();
                    foreach(ParInfo par in b.LocalVars) {
                        bool found = false;
                        foreach(ParInfo rootPar in rootB.LocalVars) {
                            if (par.Name == rootPar.Name) {
                                if (par.Type != rootPar.Type) {
                                    string errorMsg = string.Format(Resources.ParErrorInfo, par.Name, b.Label, rootB.Label);
                                    MessageBox.Show(errorMsg, Resources.LoadError, MessageBoxButtons.OK);
                                    return;
                                }

                                found = true;
                                break;
                            }
                        }

                        if (!found) {
                            pars.Add(par);
                        }
                    }

                    rootB.LocalVars.AddRange(pars);

                    // The first child should be the root node of the prefab tree.
                    Node behaviorNode = (Node)behavior;

                    if (behaviorNode.Children.Count > 0) {
                        newnode = (Node)behaviorNode.Children[0];

                        string prefab = Path.GetFileNameWithoutExtension(behavior.Filename);
                        newnode.CommentText = string.Format("Prefab[{0}]", prefab);

                        isPrefabInstance = true;
                        string prefabName = FileManagers.FileManager.GetRelativePath(behavior.Filename);
                        newnode.SetPrefab(prefabName);
                    }
                }

            } else {
                // simply create the node which is supposed to be created.
                newnode = Node.Create(nodetag.NodeType);

                if (newnode != null)
                    newnode.PostCreatedByEditor();
            }

            if (newnode == null) {
                return;
            }

            // update label
            newnode.OnPropertyValueChanged(false);

            Node node = (nvd != null) ? nvd.Node : null;

            if (node == null) {
                mode = NodeAttachMode.None;
            }

            Attachments.Attachment startCondition = null;

            // attach the new node with the correct mode
            switch (mode) {
                    // the new node is inserted in front of the target node
                case NodeAttachMode.Left:
                    if (node != null) {
                        Node parent = (Node)node.Parent;

                        int k = node.ParentConnector.GetChildIndex(node);

                        Node.Connector conn = node.ParentConnector;
                        Debug.Check(conn != null);

                        parent.RemoveChild(conn, node);
                        parent.AddChild(conn, newnode, k);

                        Node.Connector newconn = newnode.GetConnector(conn.Identifier);
                        Debug.Check(newconn != null);
                        newnode.AddChild(newconn, node);

                        // automatically select the new node
                        _selectedNodePending = newnode;
                        _selectedNodePendingParent = nvd.Parent;
                    }

                    break;

                    // the new node is simply added to the target node's children
                case NodeAttachMode.Right:
                    if (newnode != null && newnode.IsFSM) {
                        startCondition = this.addFSMNode(newnode, mousePos);

                        newnode.ScreenLocation = new PointF(_rootNodeView.BoundingBox.Left + _rootNodeView.BoundingBox.Width * 1.5f, _rootNodeView.BoundingBox.Top);

                    } else if (node != null) {
                        node.AddChild(_dragTargetConnector, newnode);

                        _dragTargetConnector.IsExpanded = true;

                        // automatically select the new node
                        _selectedNodePending = newnode;
                        _selectedNodePendingParent = nvd;
                    }

                    break;

                    // the new node is placed above the target node
                case NodeAttachMode.Top:
                    if (node != null) {
                        int n = _dragTargetNode.Node.ParentConnector.GetChildIndex(node);
                        ((Node)node.Parent).AddChild(_dragTargetNode.Node.ParentConnector, newnode, n);

                        // automatically select the new node
                        _selectedNodePending = newnode;
                        _selectedNodePendingParent = nvd.Parent;
                    }

                    break;

                    // the new node is placed below the target node
                case NodeAttachMode.Bottom:
                    if (node != null) {
                        int m = _dragTargetNode.Node.ParentConnector.GetChildIndex(node);
                        ((Node)node.Parent).AddChild(_dragTargetNode.Node.ParentConnector, newnode, m + 1);

                        // automatically select the new node
                        _selectedNodePending = newnode;
                        _selectedNodePendingParent = nvd.Parent;
                    }

                    break;

                    // the node will replace the target node
                case NodeAttachMode.Center:
                    if (node != null && replaceNode(node, newnode)) {
                        // automatically select the new node
                        _selectedNodePending = newnode;
                        _selectedNodePendingParent = nvd.Parent;

                        this.Redraw();
                    }

                    break;

                case NodeAttachMode.None:
                    if (newnode != null && newnode.IsFSM) {
                        startCondition = this.addFSMNode(newnode, mousePos);

                        // automatically select the new node
                        _selectedNodePending = newnode;
                        _selectedNodePendingParent = this.RootNodeView;
                    }

                    break;
            }

            // After being created, its Id should be reset.
            if (newnode != null) {
                newnode.ResetId(true);

                // set the prefab dirty for the current parent
                if (newnode.Parent != null) {
                    Node parent = (Node)newnode.Parent;

                    if (!string.IsNullOrEmpty(parent.PrefabName)) {
                        parent.HasOwnPrefabData = true;

                        if (!isPrefabInstance) {
                            newnode.SetPrefab(parent.PrefabName);
                            newnode.HasOwnPrefabData = true;
                        }
                    }
                }

                if (startCondition != null) {
                    startCondition.TargetFSMNodeId = newnode.Id;
                }

                UndoManager.Save(this.RootNode);
            }

            // the layout needs to be recalculated
            LayoutChanged();
        }
Exemple #24
0
        public void DeleteSelectedNode(bool deleteSubTree = false) {
            if (SelectedNode == null || Plugin.EditMode != EditModes.Design) {
                return;
            }

            deleteSubTree &= SelectedNode.CanBeDeleted(true);

            // when we have a node selected which is not the root node, continue
            if (SelectedNode != null && (SelectedNode.SelectedSubItem != null || SelectedNode.Node.Parent != null)) {
                BehaviorNode sourceBehavior = SelectedNode.Node.Behavior;

                // check whether we have to delete an event or a node
                if (SelectedNode.SelectedSubItem == null) {
                    if (deleteSubTree || SelectedNode.CanBeDeleted()) {
                        // store the selected node
                        Node node = SelectedNode.Node;

                        if (node.Parent != null) {
                            Node parent = (Node)node.Parent;

                            if (!string.IsNullOrEmpty(parent.PrefabName)) {
                                parent.HasOwnPrefabData = true;
                            }
                        }

                        // select the next node automatically
                        if (node.NextNode != null) {
                            _selectedNodePending = node.NextNode as Node;
                            _selectedNodePendingParent = SelectedNode.Parent;

                        } else if (node.PreviousNode != null) {
                            _selectedNodePending = node.PreviousNode as Node;
                            _selectedNodePendingParent = SelectedNode.Parent;

                        } else if (node.Parent != null) {
                            _selectedNodePending = node.Parent as Node;
                            _selectedNodePendingParent = SelectedNode.Parent != null ? SelectedNode.Parent.Parent : null;

                        } else {
                            _selectedNodePending = null;
                            _selectedNodePendingParent = null;
                        }

                        bool isDeleted = false;

                        if (deleteSubTree) {
                            if (node.Parent != null) {
                                ((Node)node.Parent).RemoveChild(node.ParentConnector, node);

                                // keep the root node in the view
                                KeepNodePosition(RootNodeView);

                                // remove all breakpoints
                                removeBreakpoints(SelectedNode, true);

                                isDeleted = true;
                            }

                        } else if (node.IsFSM) {
                            if (node.Parent != null && node.Parent.RemoveFSMNode(node)) {
                                // remove its breakpoints
                                removeBreakpoints(SelectedNode, false);

                                isDeleted = true;
                            }

                        } else if (node.ExtractNode()) {
                            // remove its breakpoints
                            removeBreakpoints(SelectedNode, false);

                            isDeleted = true;

                        } else {
                            _selectedNodePending = null;
                            _selectedNodePendingParent = null;
                        }

                        if (isDeleted)
                        {
                            Node root = (Node)this.RootNode;
                            if (root.FSMNodes.Count == 0)
                            {
                                // remove the Start condition for the FSM root node
                                for (int i = 0; i < root.Attachments.Count; ++i)
                                {
                                    if (root.Attachments[i].IsStartCondition)
                                    {
                                        root.Attachments.RemoveAt(i);
                                        break;
                                    }
                                }
                            }

                            UndoManager.Save(this.RootNode);
                        }

                        SelectedNode = null;
                        _currentNode = null;
                    }

                } else {
                    NodeViewData.SubItem nextItem = SelectedNode.NextSelectedSubItem;

                    if (nextItem == null) {
                        nextItem = SelectedNode.PreviousSelectedSubItem;
                    }

                    // just let the node delete the selected subitem
                    if (SelectedNode.RemoveSelectedSubItem()) {
                        Node node = SelectedNode.Node;

                        if (!string.IsNullOrEmpty(node.PrefabName)) {
                            node.HasOwnPrefabData = true;
                        }

                        UndoManager.Save(this.RootNode);

                        // select the next subitem automatically
                        if (nextItem != null) {
                            SelectedNode.SelectedSubItem = nextItem;

                            // update all labels of its subitems
                            foreach(NodeViewData.SubItem subItem in SelectedNode.SubItems) {
                                NodeViewData.SubItemAttachment attach = subItem as NodeViewData.SubItemAttachment;

                                if (attach != null && attach.Attachment != null) {
                                    attach.Attachment.OnPropertyValueChanged(false);
                                }
                            }

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

                        } else {
                            if (ClickNode != null) {
                                ClickNode(SelectedNode);
                            }
                        }
                    }
                }

                // the layout needs to be recalculated
                LayoutChanged();
            }
        }
Exemple #25
0
 private void control_ClickNode(NodeViewData nvd)
 {
     OnNodeClicked(nvd);
 }
Exemple #26
0
        public void SetHighlights(List<string> highlightedTransitionIds, List<string> highlightedNodeIds, List<string> updatedNodeIds, HighlightBreakPoint highlightBreakPoint, Dictionary<string, FrameStatePool.NodeProfileInfos.ProfileInfo> profileInfos)
        {
            bool shouldRefresh = (_highlightBreakPoint != highlightBreakPoint);

            if (shouldRefresh && highlightBreakPoint != null) {
                SelectedNode = RootNodeView.FindNodeViewData(highlightBreakPoint.NodeId);

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

            if (!shouldRefresh) {
                shouldRefresh = !compareTwoLists(_highlightedTransitionIds, highlightedTransitionIds);
            }

            if (!shouldRefresh) {
                shouldRefresh = !compareTwoLists(_updatedNodeIds, updatedNodeIds);
            }

            if (!shouldRefresh) {
                shouldRefresh = !compareTwoLists(_highlightedNodeIds, highlightedNodeIds);
            }

            if (!shouldRefresh) {
                shouldRefresh = !compareTwoDicts(_profileInfos, profileInfos);
            }

            _highlightedTransitionIds = highlightedTransitionIds;
            _highlightBreakPoint = highlightBreakPoint;
            _highlightedNodeIds = highlightedNodeIds;
            _updatedNodeIds = updatedNodeIds;
            _profileInfos = profileInfos;

            if (shouldRefresh) {
                List<string> allExpandedIds = new List<string>();

                if (_highlightedNodeIds != null) {
                    allExpandedIds.AddRange(_highlightedNodeIds);
                }

                if (_updatedNodeIds != null) {
                    foreach(string id in _updatedNodeIds) {
                        if (!allExpandedIds.Contains(id)) {
                            allExpandedIds.Add(id);
                        }
                    }
                }

                bool layoutChanged = false;
                foreach(string id in allExpandedIds) {
                    NodeViewData nvd = RootNodeView.FindNodeViewData(id);

                    if (nvd != null && !nvd.CheckAllParentsExpanded())
                    {
                        nvd.SetAllParentsExpanded();
                        this._pendingCenterBehavior = true;
                        layoutChanged = true;
                    }
                }

                if (layoutChanged) {
                    LayoutChanged();
                }

                Refresh();
            }
        }
Exemple #27
0
        public void CopySelectedNode(bool copySubTree = false) {
            if (SelectedNode == null || Plugin.EditMode != EditModes.Design) {
                return;
            }

            _clipboardRootNode = this.RootNodeView;
            _clipboardNode = null;
            _clipboardSubItem = null;

            if (SelectedNode.SelectedSubItem == null) {
                if (SelectedNode.Node is ReferencedBehavior) {
                    _clipboardNode = (Node)SelectedNode.Node;
                }

                else {
                    _clipboardNode = copySubTree ? (Node)SelectedNode.Node.CloneBranch() : (Node)SelectedNode.Node.Clone();
                }

            } else {
                _clipboardSubItem = SelectedNode.SelectedSubItem;
            }
        }
Exemple #28
0
        /// <summary>
        /// Handles when the mouse is moved.
        /// </summary>
        protected override void OnMouseMove(MouseEventArgs e) {
            if (_lostFocus) {
                _lostFocus = false;

                // update the last ouse position
                _lastMousePosition = e.Location;

                base.OnMouseMove(e);

                return;
            }

            // returns the mouse under the mouse cursor
            NodeViewData nodeFound = _rootNodeView.GetInsideNode(e.Location);
            NodeViewData.SubItem subItemFound = null;

            if (nodeFound != null) {
                subItemFound = nodeFound.GetSubItem(nodeFound, _nodeLayoutManager.ViewToGraph(e.Location));

            } else {
                this.toolTip.Hide(this);
            }

            // clear previously stored node which can cause problems when dragging to another view
            //_dragTargetNode = null;

            if (nodeFound != null || _currentExpandNode != null || subItemFound != null) {
                if (_dragAttachment == null) {
                    _currentNode = nodeFound;
                }

                if (Settings.Default.ShowNodeToolTips) {
                    if (nodeFound != null) {
                        _nodeToolTip = (subItemFound != null) ? subItemFound.ToolTip : nodeFound.ToolTip;
                    }

                    if (!string.IsNullOrEmpty(_nodeToolTip)) {
                        this.toolTipTimer.Start();
                    }
                }

                Invalidate();
            }

            // check if we are currently dragging the graph
            if ((e.Button == MouseButtons.Middle || (e.Button == MouseButtons.Left && _objectDragType == ObjectDragTypes.kGraph)) && _lastMousePosition != e.Location && !this.contextMenu.Visible) {
                Cursor = Cursors.SizeAll;

                // move the graph according to the last mouse position
                _nodeLayoutManager.Offset = new PointF(_nodeLayoutManager.Offset.X - (_lastMousePosition.X - e.X), _nodeLayoutManager.Offset.Y - (_lastMousePosition.Y - e.Y));

                Invalidate();
            }

            // check if we start duplicating an existing node step 1
            else if (e.Button == MouseButtons.Left && KeyCtrlIsDown && _lastMousePosition != e.Location && _dragNodeDefaults == null && _copiedNode == null && _currentNode != null && !(_currentNode.Node is BehaviorNode)) {
                if (_objectDragType == ObjectDragTypes.kNode) { // node
                    _movedNode = null;
                    _copiedNode = _currentNode.Node;

                    // create the layout manager used to draw the graph
                    _movedNodeGraph = new NodeLayoutManager(_copiedNode.CloneBranch().CreateNodeViewData(null, _rootNodeView.RootBehavior), _nodeLayoutManager.EdgePen, _nodeLayoutManager.EdgePenSelected, _nodeLayoutManager.EdgePenHighlighted, _nodeLayoutManager.EdgePenUpdate, _nodeLayoutManager.EdgePenReadOnly, true);
                    _movedNodeGraph.Scale = 0.3f;
                    _movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0;

                    // use the existing node as the node defaults
                    _dragNodeDefaults = _copiedNode;

                } else if (_objectDragType == ObjectDragTypes.kAttachment) { // attachment
                    if (_dragAttachment == null) {
                        NodeViewData.SubItem subItem = _currentNode.GetSubItem(_currentNode, _nodeLayoutManager.ViewToGraph(e.Location));
                        _dragAttachment = subItem as NodeViewData.SubItemAttachment;
                    }
                }

                Invalidate();
            }

            // check if we are duplicating an existing node step 2
            else if (e.Button == MouseButtons.Left && KeyCtrlIsDown && (_copiedNode != null || _dragAttachment != null)) {
                if (_objectDragType == ObjectDragTypes.kNode) { // node
                    _movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0;

                    _dragTargetNode = _currentNode;

                    Cursor = _currentNode == null ? Cursors.No : Cursors.Default;

                    //Point movedGraphGraphPos= new Point(e.Location.X + _movedNodeGraph.Offset.X, e.Location.Y + _movedNodeGraph.Offset.Y /-2);
                    //_movedNodeGraph.Location= movedGraphGraphPos;

                } else if (_objectDragType == ObjectDragTypes.kAttachment) { // attachment
                    _dragTargetNode = nodeFound;

                    if (_dragTargetNode != null) {
                        NodeViewData.SubItem subItem = _dragTargetNode.GetSubItem(_dragTargetNode, _nodeLayoutManager.ViewToGraph(e.Location));
                        _dragTargetAttachment = subItem as NodeViewData.SubItemAttachment;
                    }
                }

                Invalidate();
            }

            // check if we start dragging an existing node step 1
            else if (e.Button == MouseButtons.Left && _lastMousePosition != e.Location && !KeyCtrlIsDown && _movedNode == null && _currentNode != null) {
                if (_objectDragType == ObjectDragTypes.kNode) { // node
                    if (_currentNode.CanBeDragged())
                    {
                        if (_currentNode.IsFSM)
                        {
                            PointF currentGraphMousePos = _nodeLayoutManager.ViewToGraph(e.Location);
                            PointF lastGraphMousePos = _nodeLayoutManager.ViewToGraph(_lastMousePosition);

                            _currentNode.ScreenLocation = new PointF(_currentNode.ScreenLocation.X + currentGraphMousePos.X - lastGraphMousePos.X,
                                                                     _currentNode.ScreenLocation.Y + currentGraphMousePos.Y - lastGraphMousePos.Y);

                            LayoutChanged();

                        }
                        else if ((KeyShiftIsDown || _currentNode.Node.ParentCanAdoptChildren))
                        {
                            _movedNode = _currentNode.Node;

                            // create the layout manager used to draw the graph
                            if (_movedNodeGraph == null)
                            {
                                _movedNodeGraph = new NodeLayoutManager(_movedNode.CloneBranch().CreateNodeViewData(null, _rootNodeView.RootBehavior), _nodeLayoutManager.EdgePen, _nodeLayoutManager.EdgePenSelected, _nodeLayoutManager.EdgePenHighlighted, _nodeLayoutManager.EdgePenUpdate, _nodeLayoutManager.EdgePenReadOnly, true);
                            }

                            _movedNodeGraph.Scale = 0.3f;
                            //_movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0;
                            _movedNodeGraph.RenderDepth = int.MaxValue;
                        }
                    }

                } else if (_objectDragType == ObjectDragTypes.kAttachment) { // attachment
                    if (_fsmDragMode == FSMDragModes.kNone && Plugin.EditMode == EditModes.Design) {
                        _movedNodeGraph = null;
                        _dragTargetNode = nodeFound;

                        if (_dragAttachment == null) {
                            NodeViewData.SubItem subItem = _currentNode.GetSubItem(_currentNode, _nodeLayoutManager.ViewToGraph(e.Location));
                            _dragAttachment = subItem as NodeViewData.SubItemAttachment;

                            if (_dragAttachment != null) {
                                _movedSubItem = _dragAttachment.Clone(_currentNode.Node);
                            }

                        } else if (_dragTargetNode != null) {
                            NodeViewData.SubItem subItem = _dragTargetNode.GetSubItem(_dragTargetNode, _nodeLayoutManager.ViewToGraph(e.Location));
                            _dragTargetAttachment = subItem as NodeViewData.SubItemAttachment;
                        }
                    }
                }

                Invalidate();
            }

            // check if we start dragging an existing node step 2
            else if (e.Button == MouseButtons.Left && _movedNode != null && !_clipboardPasteMode) {
                // create the layout manager used to draw the graph
                if (_movedNodeGraph == null) {
                    _movedNodeGraph = new NodeLayoutManager(_movedNode.CloneBranch().CreateNodeViewData(null, _rootNodeView.RootBehavior), _nodeLayoutManager.EdgePen, _nodeLayoutManager.EdgePenSelected, _nodeLayoutManager.EdgePenHighlighted, _nodeLayoutManager.EdgePenUpdate, _nodeLayoutManager.EdgePenReadOnly, true);
                }

                _movedNodeGraph.Scale = 0.3f;
                _movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0;

                _dragNodeDefaults = _movedNode;
                _dragTargetNode = _currentNode;

                Cursor = _currentNode == null ? Cursors.No : Cursors.Default;

                Invalidate();

            } else if (_clipboardPasteMode) {
                if (_movedNodeGraph != null) {
                    //_movedNodeGraph.RenderDepth = KeyShiftIsDown ? int.MaxValue : 0;
                    _movedNodeGraph.RenderDepth = int.MaxValue;
                }

                _dragTargetNode = _currentNode;

                Cursor = _currentNode == null ? Cursors.No : Cursors.Default;

                Invalidate();

            } else if (_currentNode != null && _dragAttachment == null) {
                // Highlight the expand/collapse flag
                PointF graphMousePos = _nodeLayoutManager.ViewToGraph(e.Location);
                bool isInExandRange = _currentNode.IsInExpandRange(graphMousePos);
                bool isInExandConnectorRange = _currentNode.IsInExpandConnectorRange(graphMousePos);

                if (isInExandRange || isInExandConnectorRange) {
                    _currentExpandNode = _currentNode;
                    _nodeToolTip = isInExandRange ? Resources.ExpandAllInfo : Resources.ExpandConnectorInfo;
                    Invalidate();

                } else if (_currentExpandNode != null) {
                    _currentExpandNode = null;
                    Invalidate();
                }
            }

            // update the last ouse position
            _lastMousePosition = e.Location;

            base.OnMouseMove(e);
        }
Exemple #29
0
        private void control_ClickNode(NodeViewData nvd)
        {
            _clickedNVD = nvd;

            Thread backgroundThread = new Thread(AsyncUpdateProperties);
            backgroundThread.SetApartmentState(ApartmentState.STA);
            backgroundThread.Start();
            while (backgroundThread.IsAlive)
            {
                Application.DoEvents();
            }

            _clickedNVD = null;
        }
Exemple #30
0
        private void removeBreakpoints(NodeViewData nvd, bool removeChildren) {
            if (nvd == null || RootNode == null || string.IsNullOrEmpty(RootNode.Filename)) {
                return;
            }

            string behaviorFilename = RootNode.MakeRelative(RootNode.Filename);

            if (string.IsNullOrEmpty(behaviorFilename)) {
                return;
            }

            string[] actionNames = { HighlightBreakPoint.kEnter, HighlightBreakPoint.kExit };
            string fullId = nvd.FullId;

            foreach(string actionName in actionNames) {
                DebugDataPool.BreakPoint breakPoint = DebugDataPool.FindBreakPoint(behaviorFilename, fullId, actionName);

                if (breakPoint != null) {
                    DebugDataPool.Action action = breakPoint.FindAction(actionName);
                    Debug.Check(action != null);

                    DebugDataPool.RemoveBreakPoint(behaviorFilename, fullId, action);
                }
            }

            if (removeChildren) {
                foreach(BaseNode child in nvd.Children) {
                    NodeViewData childNvd = child as NodeViewData;

                    if (childNvd != null) {
                        removeBreakpoints(childNvd, removeChildren);
                    }
                }
            }
        }