public override bool AddChildNotModified(Node.Connector connector, Node node) { Debug.Check(connector.Owner == this || connector.Owner == _referencedBehavior); if (connector.Owner == this) { return(base.AddChildNotModified(connector, node)); } if (((Node)_referencedBehavior).AddChildNotModified(connector, node)) { _children.RequiresRebuild(); RemoveSubItemsForConnector(); AddSubItemsForConnector(); return(true); } return(false); }
void OnGUI() { Handles.BeginGUI(); Color last = Handles.color; drawBackground(new Color(0.1f, 0.1f, 0.1f, 1f)); Handles.color = last; BeginWindows(); nodes.ForEach(n => { n.render(offset); }); EndWindows(); conns.ForEach(c => { c.render(offset); }); Handles.EndGUI(); Event e = Event.current; if (e.type == EventType.MouseDrag) { offset -= e.delta; Repaint(); } if (connectFromObj != null) { drawCurve(connectFromObj.Position - offset, e.mousePosition); Repaint(); } if (e.button == 1) { connectFromObj = null; } }
void connectionManagement(Node.Connector con) { var existing = parent.conns.Find(co => co.contains(con)); if (existing != null) { parent.connectFromObj = existing.a == con? existing.b: existing.a; existing.a.bound = false; existing.b.bound = false; parent.conns.Remove(existing); } else { if (parent.connectFromObj == null) { parent.connectFromObj = con; } else if (con.Parent != parent.connectFromObj.Parent) { if (con.type != parent.connectFromObj.type) { parent.conns.Add(new Node.Connection(parent.connectFromObj, con)); parent.connectFromObj = null; parent.RemoveNotification(); } else { parent.ShowNotification(new GUIContent("Cannot connect to same type of pin!")); } } else { parent.ShowNotification(new GUIContent("Cannot connect to same node!")); } } }
/// <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(); } }
/// <summary> /// Loads a node from a given XML node. /// </summary> /// <param name="getBehaviorNode">The callback used to return the behavior.</param> /// <param name="xml">The XML node we want to create the node from.</param> /// <param name="parent">The parent this node will be added to.</param> /// <param name="connector">The connector used to add this node to the parent.</param> /// <returns>Returns the created node.</returns> protected Node CreateNodeAndAdd(List <Nodes.Node.ErrorCheck> result, GetBehaviorNode getBehaviorNode, XmlNode xml, Node parent, Node.Connector connector) { try { // get the type of the node and create it string clss = GetAttribute(xml, "Class"); Type t = Plugin.GetType(clss); if (t == null) { string msg = string.Format(Resources.ExceptionUnknownNodeType, clss); string msgError = string.Format("{0}:\n{1}", this.Filename, msg); //throw new Exception(msg); MessageBox.Show(msgError, Resources.LoadError, MessageBoxButtons.OK); parent.Behavior.TriggerWasModified(parent); return(null); } Node node = Nodes.Node.Create(t); if (parent == null) { //if this._version == 0, it means there is no Version attribute in the file node.Behavior.Version = this._version; } // update the loaded behaviour member if (node is BehaviorNode) { ((BehaviorNode)node).FileManager = this; } // add the node to the parent if (parent != null) { if (connector != null) { parent.AddChildNotModified(connector, node); } else { parent.AddFSMNode(node); } } int version = 0; if (node.Behavior != null) { version = node.Behavior.Version; } else { Debug.Check(true); } SetEnterExitSlot(result, xml, node, version); // initialise the properties IList <DesignerPropertyInfo> properties = node.GetDesignerProperties(); foreach (DesignerPropertyInfo property in properties) { if (!property.Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave)) { InitProperty(result, xml, node, property); } } // return the created behaviour node if (node is BehaviorNode) { getBehaviorNode((BehaviorNode)node); } // maintain compatibility with version 1 if (node is ReferencedBehaviorNode) { ReferencedBehaviorNode refbehavior = (ReferencedBehaviorNode)node; if (refbehavior.ReferenceFilename == null) { refbehavior.ReferenceFilename = GetAttribute(xml, "Reference"); } } // update node with properties node.OnPropertyValueChanged(false); // load child objects foreach (XmlNode xnode in xml.ChildNodes) { if (xnode.NodeType == XmlNodeType.Element) { switch (xnode.Name) { // load parameters case ("Parameters"): if (node is Behavior || node is ReferencedBehavior) { LoadParameters(result, xnode, node, node.LocalVars); node.Behavior.PostLoadPars(); } break; case ("DescriptorRefs"): #if QUERY_EANBLED LoadDescriptorRefs(result, xnode, node.Behavior as Behavior); #endif//#if QUERY_EANBLED break; // maintain compatibility with version 1 case ("Node"): CreateNodeAndAdd(result, getBehaviorNode, xnode, node, node.GetConnector(BaseNode.Connector.kGeneric)); break; // maintain compatibility with version 2.1 case ("Event"): case ("Attachment"): { Attachments.Attachment a = CreateAttachment(result, node, xnode); if (a != null) { node.AddAttachment(a); a.PostCreate(result, version, node, xnode); } } break; case ("Comment"): // create a comment object node.CommentText = "temp"; // initialise the attributes properties = node.CommentObject.GetDesignerProperties(); foreach (DesignerPropertyInfo property in properties) { if (property.Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave)) { continue; } string value; if (GetAttribute(xnode, property.Property.Name, out value)) { property.SetValueFromString(result, node.CommentObject, value); } } break; case ("Connector"): string identifier = GetAttribute(xnode, "Identifier"); Nodes.Node.Connector conn = node.GetConnector(identifier); foreach (XmlNode connected in xnode.ChildNodes) { if (connected.NodeType == XmlNodeType.Element && connected.Name == "Node") { CreateNodeAndAdd(result, getBehaviorNode, connected, node, conn); } } break; case ("FSMNodes"): string locationX = GetAttribute(xnode, "ScreenLocationX"); string locationY = GetAttribute(xnode, "ScreenLocationY"); if (!string.IsNullOrEmpty(locationX) && !string.IsNullOrEmpty(locationY)) { try { float x = float.Parse(locationX); float y = float.Parse(locationY); node.ScreenLocation = new System.Drawing.PointF(x, y); } catch { } } foreach (XmlNode fsmNode in xnode.ChildNodes) { if (fsmNode.NodeType == XmlNodeType.Element && fsmNode.Name == "Node") { CreateNodeAndAdd(result, getBehaviorNode, fsmNode, node, null); } } break; } } } // update attachments with attributes foreach (Attachments.Attachment attach in node.Attachments) { attach.OnPropertyValueChanged(false); } // set the properties from its prefab bool isPrefabInstance = !string.IsNullOrEmpty(node.PrefabName) && !node.HasOwnPrefabData; if (isPrefabInstance) { Node prefabNode = Plugin.GetPrefabNode(node); if (prefabNode != null) { node.ResetByPrefab(node.PrefabName, prefabNode); Behavior b = node.Behavior as Behavior; b.AgentType.AddPars(b.LocalVars); } } node.PostCreate(result, version, xml); return(node); } catch (Exception e) { string idNode = xml.Attributes["Id"].Value; string msgError = string.Format("{0}:\r\nNode Id:{1}\r\n{2}", this.Filename, idNode, e.Message); //throw new Exception(msg); MessageBox.Show(msgError, Resources.LoadError, MessageBoxButtons.OK); } return(null); }
/// <summary> /// Loads a node from a given XML node. /// </summary> /// <param name="getBehaviorNode">The callback used to return the behavior.</param> /// <param name="xml">The XML node we want to create the node from.</param> /// <param name="parent">The parent this node will be added to.</param> /// <param name="connector">The connector used to add this node to the parent.</param> /// <returns>Returns the created node.</returns> protected Node CreateNodeAndAdd(GetBehaviorNode getBehaviorNode, XmlNode xml, Node parent, Node.Connector connector) { // get the type of the node and create it string clss = GetAttribute(xml, "Class"); Type t = Plugin.GetType(clss); if (t == null) { throw new Exception(string.Format(Resources.ExceptionUnknownNodeType, clss)); } Node node = Nodes.Node.Create(t); // update the loaded behaviour member if (node is BehaviorNode) { ((BehaviorNode)node).FileManager = this; } // add the node to the parent if (parent != null) { Debug.Check(connector != null); parent.AddChildNotModified(connector, node); } // initialise the properties IList <DesignerPropertyInfo> properties = node.GetDesignerProperties(); foreach (DesignerPropertyInfo property in properties) { if (property.Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave)) { continue; } InitProperty(xml, node, property); node.PostPropertyInit(property); } // return the created behaviour node if (node is BehaviorNode) { getBehaviorNode((BehaviorNode)node); } // maintain compatibility with version 1 if (node is ReferencedBehaviorNode) { ReferencedBehaviorNode refbehavior = (ReferencedBehaviorNode)node; if (refbehavior.ReferenceFilename == null) { refbehavior.ReferenceFilename = GetAttribute(xml, "Reference"); } } // update node with properties node.OnPropertyValueChanged(false); // load child objects foreach (XmlNode xnode in xml.ChildNodes) { if (xnode.NodeType == XmlNodeType.Element) { switch (xnode.Name.ToLowerInvariant()) { // maintain compatibility with version 1 case ("node"): CreateNodeAndAdd(getBehaviorNode, xnode, node, node.GetConnector("GenericChildren")); break; // maintain compatibility with version 2.1 case ("event"): case ("attachment"): node.AddAttachment(CreateAttachment(node, xnode)); break; case ("comment"): // create a comment object node.CommentText = "temp"; // initialise the attributes properties = node.CommentObject.GetDesignerProperties(); foreach (DesignerPropertyInfo property in properties) { if (property.Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave)) { continue; } string value; if (GetAttribute(xnode, property.Property.Name, out value)) { property.SetValueFromString(node.CommentObject, value); } } break; case ("connector"): string identifier = GetAttribute(xnode, "Identifier"); Nodes.Node.Connector conn = node.GetConnector(identifier); foreach (XmlNode connected in xnode.ChildNodes) { if (connected.NodeType == XmlNodeType.Element && connected.Name.ToLowerInvariant() == "node") { CreateNodeAndAdd(getBehaviorNode, connected, node, conn); } } break; } } } // update attachments with attributes foreach (Attachments.Attachment attach in node.Attachments) { attach.OnPropertyValueChanged(false); } return(node); }
/// <summary> /// Loads a node from a given XML node. /// </summary> /// <param name="getBehaviorNode">The callback used to return the behavior.</param> /// <param name="xml">The XML node we want to create the node from.</param> /// <param name="parent">The parent this node will be added to.</param> /// <param name="connector">The connector used to add this node to the parent.</param> /// <returns>Returns the created node.</returns> protected Node CreateNodeAndAdd(GetBehaviorNode getBehaviorNode, XmlNode xml, Node parent, Node.Connector connector) { try { // get the type of the node and create it string clss = GetAttribute(xml, "Class"); Type t = Plugin.GetType(clss); if (t == null) { string msg = string.Format(Resources.ExceptionUnknownNodeType, clss); string msgError = string.Format("{0}:\n{1}", this.Filename, msg); //throw new Exception(msg); MessageBox.Show(msgError, Resources.LoadError, MessageBoxButtons.OK); parent.Behavior.IsModified = true; return(null); } Node node = Nodes.Node.Create(t); // update the loaded behaviour member if (node is BehaviorNode) { ((BehaviorNode)node).FileManager = this; } // add the node to the parent if (parent != null) { Debug.Check(connector != null); parent.AddChildNotModified(connector, node); } // initialise the properties IList <DesignerPropertyInfo> properties = node.GetDesignerProperties(); foreach (DesignerPropertyInfo property in properties) { if (!property.Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave)) { InitProperty(xml, node, property); node.PostPropertyInit(property); } } // return the created behaviour node if (node is BehaviorNode) { getBehaviorNode((BehaviorNode)node); } // maintain compatibility with version 1 if (node is ReferencedBehaviorNode) { ReferencedBehaviorNode refbehavior = (ReferencedBehaviorNode)node; if (refbehavior.ReferenceFilename == null) { refbehavior.ReferenceFilename = GetAttribute(xml, "Reference"); } } // update node with properties node.OnPropertyValueChanged(false); // load child objects foreach (XmlNode xnode in xml.ChildNodes) { if (xnode.NodeType == XmlNodeType.Element) { switch (xnode.Name.ToLowerInvariant()) { // load parameters case ("parameters"): LoadParameters(xnode, node, node.Pars); break; case ("descriptorrefs"): #if QUERY_EANBLED LoadDescriptorRefs(xnode, node.Behavior as Behavior); #endif//#if QUERY_EANBLED break; // maintain compatibility with version 1 case ("node"): CreateNodeAndAdd(getBehaviorNode, xnode, node, node.GetConnector("GenericChildren")); break; // maintain compatibility with version 2.1 case ("event"): case ("attachment"): { Attachments.Attachment a = CreateAttachment(node, xnode); if (a != null) { node.AddAttachment(a); } } break; case ("comment"): // create a comment object node.CommentText = "temp"; // initialise the attributes properties = node.CommentObject.GetDesignerProperties(); foreach (DesignerPropertyInfo property in properties) { if (property.Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave)) { continue; } string value; if (GetAttribute(xnode, property.Property.Name, out value)) { property.SetValueFromString(node.CommentObject, value); } } break; case ("connector"): string identifier = GetAttribute(xnode, "Identifier"); Nodes.Node.Connector conn = node.GetConnector(identifier); foreach (XmlNode connected in xnode.ChildNodes) { if (connected.NodeType == XmlNodeType.Element && connected.Name.ToLowerInvariant() == "node") { CreateNodeAndAdd(getBehaviorNode, connected, node, conn); } } break; } } } // update attachments with attributes foreach (Attachments.Attachment attach in node.Attachments) { attach.OnPropertyValueChanged(false); } // set the properties from its prefab bool isPrefabInstance = !string.IsNullOrEmpty(node.PrefabName) && !node.HasOwnPrefabData; if (isPrefabInstance) { Node prefabNode = Plugin.GetPrefabNode(node); if (prefabNode != null) { node.ResetByPrefab(node.PrefabName, prefabNode); } } return(node); } catch (Exception e) { string idNode = xml.Attributes["Id"].Value; string msgError = string.Format("{0}:\r\nNode Id:{1}\r\n{2}", this.Filename, idNode, e.Message); //throw new Exception(msg); MessageBox.Show(msgError, Resources.LoadError, MessageBoxButtons.OK); } return(null); }