/// <summary> /// Recalculates the layout if necessary. /// </summary> /// <param name="graphics">The graphics object which is used to measure the strings.</param> internal void UpdateLayout(Graphics graphics, bool bForce = false) { if (_layoutChanged) { _layoutChanged = false; _rootNodeLayout.SetBackgroundBrush(); // synchronize layout ProcessedBehaviors processedBehaviors = new ProcessedBehaviors(); _rootNodeLayout.SynchronizeWithNode(processedBehaviors, bForce); // calculate the size of each node _rootNodeLayout.UpdateFinalSize(graphics, _rootNodeLayout.RootBehavior); _rootNodeLayout.UpdateExtent(); // calculate the total size of the branches _rootNodeLayout.CalculateLayoutSize(_padding); // align the branches _rootNodeLayout.Layout(_padding); // align the parents at the centre of their children _rootNodeLayout.UpdateLocation(); } }
public override void DoSynchronizeWithNode(ProcessedBehaviors processedBehaviors) { // make all connectors changable for (int i = 0; i < _children.Connectors.Count; ++i) { _children.Connectors[i].IsReadOnly = false; } base.DoSynchronizeWithNode(processedBehaviors); }
public override void DoSynchronizeWithNode(ProcessedBehaviors processedBehaviors) { // make all connectors changable for (int i = 0; i < _children.Connectors.Count; ++i) { _children.Connectors[i].IsReadOnly = false; } base.DoSynchronizeWithNode(processedBehaviors); }
/// <summary> /// This function adapts the children of the view that they represent the children of the node this view is for. /// Children are added and removed. /// </summary> /// <param name="processedBehaviors">A list of previously processed behaviours to deal with circular references.</param> public override void SynchronizeWithNode(ProcessedBehaviors processedBehaviors, bool bForce = false) { // if we have a circular reference, we must skip it if (!processedBehaviors.MayProcessCheckOnly(_node)) { _children.ClearChildren(); return; } base.SynchronizeWithNode(processedBehaviors, bForce); }
/// <summary> /// Registers referenced behaviours so when a referenced behaviour changes, this view gets updated, as the root node will not change. /// </summary> /// <param name="processedBehaviors">A list of processed behaviours to avoid circular references.</param> /// <param name="node">The node we want to register on and its children.</param> private void RegisterReferencedBehaviors(ProcessedBehaviors processedBehaviors, Node node) { if (!processedBehaviors.MayProcess(node)) { return; } // check the children foreach(Node child in node.Children) RegisterReferencedBehaviors(processedBehaviors.Branch(child), child); }
/// <summary> /// Adds nodes to the referenced behaviour which represent sub-referenced behaviours. /// </summary> /// <param name="processedBehaviors">A list of processed behaviours to handle circular references.</param> /// <param name="parent">The node the sub-referenced behaviours will be added to.</param> /// <param name="node">The current node we are checking.</param> protected void GenerateReferencedBehaviorsTree(ProcessedBehaviors processedBehaviors, NodeViewData parent, Node node) { if (!processedBehaviors.MayProcess(node)) { return; } // check if this is a referenced behaviour if (node is ReferencedBehaviorNode) { // create the dummy node and add it without marking the behaviour as being modified as these are no REAL nodes. NodeViewData rb = node.CreateNodeViewData(parent, _rootBehavior); #if DEBUG rb.IsSubreferencedGraphNode(); #endif rb.DoSynchronizeWithNode(processedBehaviors); Connector conn = parent.GetConnector("GenericChildren"); Debug.Check(conn != null); Connector rbconn = parent.GetConnector("GenericChildren"); Debug.Check(rbconn != null); bool parentReadOnly = conn.IsReadOnly; conn.IsReadOnly = false; parent.AddChildNotModified(conn, rb); conn.IsReadOnly = parentReadOnly; // we have a circular reference here. Skip the children if (((ReferencedBehaviorNode)node).Reference == _rootBehavior) { rbconn.IsReadOnly = true; return; } // do the same for all the children foreach (Node child in node.Children) { GenerateReferencedBehaviorsTree(processedBehaviors.Branch(child), rb, child); } rbconn.IsReadOnly = true; } else if (node is Impulse) { // create the dummy node and add it without marking the behaviour as being modified as these are no REAL nodes. NodeViewData ip = node.CreateNodeViewData(parent, _rootBehavior); ip.DoSynchronizeWithNode(processedBehaviors); // do the same for all the children foreach (Node child in node.Children) { GenerateReferencedBehaviorsTree(processedBehaviors.Branch(child), ip, child); } if (ip.Children.Count > 0) { Connector conn = parent.GetConnector("GenericChildren"); Debug.Check(conn != null); Connector ipconn = ip.GetConnector("GenericChildren"); Debug.Check(ipconn != null); parent.AddChildNotModified(conn, ip); ipconn.IsReadOnly = true; } } else { // do the same for all the children foreach (Node child in node.Children) { GenerateReferencedBehaviorsTree(processedBehaviors.Branch(child), parent, child); } } }
/// <summary> /// Registers referenced behaviours so when a referenced behaviour changes, this view gets updated, as the root node will not change. /// </summary> /// <param name="processedBehaviors">A list of processed behaviours to avoid circular references.</param> /// <param name="node">The node we want to register on and its children.</param> private void RegisterReferencedBehaviors(ProcessedBehaviors processedBehaviors, Node node) { if (!processedBehaviors.MayProcess(node)) { return; } // check if this is a referenced behaviour. If so register the view on the ReferencedBehaviorWasModified event. if (node is ReferencedBehaviorNode) { ReferencedBehaviorNode refnode = (ReferencedBehaviorNode)node; refnode.ReferencedBehaviorWasModified += new ReferencedBehavior.ReferencedBehaviorWasModifiedEventDelegate(refnode_ReferencedBehaviorWasModified); } // check the children foreach(Node child in node.Children) RegisterReferencedBehaviors(processedBehaviors.Branch(child), child); }
/// <summary> /// Used to branch a new list for its children. /// </summary> /// <param name="previous">The list of processed behaviours the parent used.</param> protected ProcessedBehaviors(ProcessedBehaviors previous) { _processedBehaviors.AddRange(previous._processedBehaviors); }
/// <summary> /// Used to branch a new list for its children. /// </summary> /// <param name="previous">The list of processed behaviours the parent used.</param> protected ProcessedBehaviors(ProcessedBehaviors previous) { _processedBehaviors.AddRange(previous._processedBehaviors); }
/// <summary> /// Recalculates the layout if necessary. /// </summary> /// <param name="graphics">The graphics object which is used to measure the strings.</param> internal void UpdateLayout(Graphics graphics, bool bForce = false) { if(_layoutChanged) { _layoutChanged= false; _rootNodeLayout.SetBackgroundBrush(); // synchronize layout ProcessedBehaviors processedBehaviors= new ProcessedBehaviors(); _rootNodeLayout.SynchronizeWithNode(processedBehaviors, bForce); // calculate the size of each node _rootNodeLayout.UpdateFinalSize(graphics, _rootNodeLayout.RootBehavior); _rootNodeLayout.UpdateExtent(); // calculate the total size of the branches _rootNodeLayout.CalculateLayoutSize(_padding); // align the branches _rootNodeLayout.Layout(_padding); // align the parents at the centre of their children _rootNodeLayout.UpdateLocation(); } }
/// <summary> /// Creates the view data for a node. /// </summary> /// <param name="processedBehaviors">The list of processed behaviours to handle circular references.</param> public virtual void DoSynchronizeWithNode(ProcessedBehaviors processedBehaviors) { _children.ClearConnectors(); RemoveAllConnectorSubItems(); // create subitems. setSubItems(_node); foreach(Connector connector in _node.Connectors) connector.Clone(_children); foreach(Connector connector in _children.Connectors) { Connector nodeConnector = _node.GetConnector(connector.Identifier); Debug.Check(nodeConnector != null); for (int i = 0; i < nodeConnector.ChildCount; ++i) { Node node = (Node)nodeConnector.GetChild(i); NodeViewData nvd = node.CreateNodeViewData(this, _rootBehavior); Debug.Verify(AddChildNotModified(connector, nvd)); } } // create FSM nodes this.FSMNodes.Clear(); if (_node.FSMNodes.Count > 0) { foreach(Node node in _node.FSMNodes) { NodeViewData nvd = node.CreateNodeViewData(this, _rootBehavior); this.AddFSMNode(nvd); } } }
/// <summary> /// This function adapts the children of the view that they represent the children of the node this view is for. /// Children are added and removed. /// </summary> /// <param name="processedBehaviors">A list of previously processed behaviours to deal with circular references.</param> public virtual void SynchronizeWithNode(ProcessedBehaviors processedBehaviors, bool bForce = false) { if (processedBehaviors.MayProcess(_node)) { // check if we must rebuild the child list if (bForce || NeedsToSynchronizeWithNode()) { DoSynchronizeWithNode(processedBehaviors); } GenerateNewLabel(); // synchronise the children as well foreach(NodeViewData child in this.GetChildNodes()) { Debug.Check(child.RootBehavior == _rootBehavior); child.SynchronizeWithNode(processedBehaviors.Branch(child._node), bForce); } } }
/// <summary> /// This function adapts the children of the view that they represent the children of the node this view is for. /// Children are added and removed. /// </summary> /// <param name="processedBehaviors">A list of previously processed behaviours to deal with circular references.</param> public override void SynchronizeWithNode(ProcessedBehaviors processedBehaviors, bool bForce = false) { // if we have a circular reference, we must skip it if (!processedBehaviors.MayProcessCheckOnly(_node)) { _children.ClearChildren(); return; } base.SynchronizeWithNode(processedBehaviors, bForce); }
/// <summary> /// Adds nodes to the referenced behaviour which represent sub-referenced behaviours. /// </summary> /// <param name="processedBehaviors">A list of processed behaviours to handle circular references.</param> /// <param name="parent">The node the sub-referenced behaviours will be added to.</param> /// <param name="node">The current node we are checking.</param> protected void GenerateReferencedBehaviorsTree(ProcessedBehaviors processedBehaviors, NodeViewData parent, Node node) { if (!processedBehaviors.MayProcess(node)) { return; } // check if this is a referenced behaviour if (node is ReferencedBehaviorNode) { // create the dummy node and add it without marking the behaviour as being modified as these are no REAL nodes. NodeViewData rb = node.CreateNodeViewData(parent, _rootBehavior); #if DEBUG rb.IsSubreferencedGraphNode(); #endif rb.DoSynchronizeWithNode(processedBehaviors); Connector conn = parent.GetConnector(Connector.kGeneric); Debug.Check(conn != null); Connector rbconn = parent.GetConnector(Connector.kGeneric); Debug.Check(rbconn != null); bool parentReadOnly = conn.IsReadOnly; conn.IsReadOnly = false; parent.AddChildNotModified(conn, rb); conn.IsReadOnly = parentReadOnly; // we have a circular reference here. Skip the children if (((ReferencedBehaviorNode)node).Reference == _rootBehavior) { rbconn.IsReadOnly = true; return; } // do the same for all the children foreach(Node child in node.Children) GenerateReferencedBehaviorsTree(processedBehaviors.Branch(child), rb, child); rbconn.IsReadOnly = true; } else if (node is Impulse) { // create the dummy node and add it without marking the behaviour as being modified as these are no REAL nodes. NodeViewData ip = node.CreateNodeViewData(parent, _rootBehavior); ip.DoSynchronizeWithNode(processedBehaviors); // do the same for all the children foreach(Node child in node.Children) GenerateReferencedBehaviorsTree(processedBehaviors.Branch(child), ip, child); if (ip.Children.Count > 0) { Connector conn = parent.GetConnector(Connector.kGeneric); Debug.Check(conn != null); Connector ipconn = ip.GetConnector(Connector.kGeneric); Debug.Check(ipconn != null); parent.AddChildNotModified(conn, ip); ipconn.IsReadOnly = true; } } else { // do the same for all the children foreach(Node child in node.Children) GenerateReferencedBehaviorsTree(processedBehaviors.Branch(child), parent, child); } }
/// <summary> /// This function adapts the children of the view that they represent the children of the node this view is for. /// Children are added and removed. /// </summary> /// <param name="processedBehaviors">A list of previously processed behaviours to deal with circular references.</param> public virtual void SynchronizeWithNode(ProcessedBehaviors processedBehaviors, bool bForce = false) { if (processedBehaviors.MayProcess(_node)) { // allow the node to add some final children or remove some _node.PreLayoutUpdate(this); // check if we must rebuild the child list if (bForce || NeedsToSynchronizeWithNode()) DoSynchronizeWithNode(processedBehaviors); GenerateNewLabel(); // synchronise the children as well foreach (NodeViewData child in _children) { Debug.Check(child.RootBehavior == _rootBehavior); child.SynchronizeWithNode(processedBehaviors.Branch(child._node), bForce); } } }