private static void WriteLinks(XmlGraphData <TUIRawData, TEditorData> conversation, XElement root) { HashSet <UnorderedTuple2 <Tuple <Id <TConnector>, IConversationNodeData> > > links = new HashSet <UnorderedTuple2 <Tuple <Id <TConnector>, IConversationNodeData> > >(); foreach (var n in conversation.Nodes) { foreach (var c in n.GraphData.Connectors) { foreach (var cc in c.Connections) { var pair1 = Tuple.Create(c.Id, n.GraphData); var pair2 = Tuple.Create(cc.Id, cc.Parent); links.Add(UnorderedTuple.Make(pair1, pair2)); } } } foreach (var link in links) { var node1 = new XAttribute("node1", link.Item1.Item2.NodeId.Serialized()); var connector1 = new XAttribute("connector1", link.Item1.Item1.Serialized()); var node2 = new XAttribute("node2", link.Item2.Item2.NodeId.Serialized()); var connector2 = new XAttribute("connector2", link.Item2.Item1.Serialized()); root.Add(new XElement("Link", node1, connector1, node2, connector2)); } }
private IEnumerable <Usage> ConnectionDefinitionUsages(IConversationNodeData data) { Id <TConnectorDefinition> connector1 = Id <TConnectorDefinition> .FromGuid(data.Parameters.Where(p => p.Id == DomainIDs.ConnectionDefinitionConnector1).OfType <IEnumParameter>().Single().Value); Id <TConnectorDefinition> connector2 = Id <TConnectorDefinition> .FromGuid(data.Parameters.Where(p => p.Id == DomainIDs.ConnectionDefinitionConnector2).OfType <IEnumParameter>().Single().Value); var reference = UnorderedTuple.Make(connector1, connector2); foreach (var conversationFile in m_project.Conversations) { HashSet <UnorderedTuple2 <Output> > connections = new HashSet <UnorderedTuple2 <Output> >(); foreach (var node in conversationFile.Nodes) { foreach (var connector in node.Data.Connectors) { if (connector.Definition.Id == connector1 || connector.Definition.Id == connector2) { foreach (var connection in connector.Connections) { var c = UnorderedTuple.Make(connector.Definition.Id, connection.Definition.Id); if (c == reference) { connections.Add(UnorderedTuple.Make(connector, connection)); } yield return(new Usage(node, conversationFile, "Node connection using connector definition")); } } } } } }
public static void TestUnorderedTuple() { var a = UnorderedTuple.Make(0, 1); var A = UnorderedTuple.Make(1, 0); var b = UnorderedTuple.Make(0, 2); Assert.That(a.Equals(A)); Assert.That(A.Equals(a)); Assert.That(!a.Equals(b)); }
private void StoreConnections(TNode node, bool register) { if (!register) { if (m_connectionDeregisterActions.ContainsKey(node)) { foreach (var deregister in m_connectionDeregisterActions[node]) { deregister(); } } return; } foreach (var connector in node.Data.Connectors) { var connectorTemp = connector; Action <Output, bool> connected = (connection, mustExist) => { ConnectionUpdate(connection, connectorTemp, mustExist); }; connectorTemp.Connected += c => connected(c, true); connectorTemp.Disconnected += connection => { DisconnectionUpdate(connection, connectorTemp, UIInfo(connection).Area.Value); }; foreach (var connection in connectorTemp.Connections) { connected(connection, false); } Action deregister = UIInfo(connectorTemp).Area.Changed.Register(change => { foreach (var connection in connectorTemp.Connections) { var other = UIInfo(connection); //The nature of the bezier splines means they will never reach outside the bounding rectangle which includes their endpoints RectangleF fromBounds = RectangleF.Union(change.From, other.Area.Value); var pair = UnorderedTuple.Make(connectorTemp, connection); SpatiallyOrderedConnections.Remove(Tuple.Create(pair, fromBounds)); RectangleF toBounds = RectangleF.Union(change.To, other.Area.Value); SpatiallyOrderedConnections.Add(Tuple.Create(pair, toBounds), toBounds); } }); if (!m_connectionDeregisterActions.ContainsKey(node)) { m_connectionDeregisterActions[node] = new List <Action>(); } m_connectionDeregisterActions[node].Add(deregister); } }
private void DisconnectionUpdate(Output connection, Output connectorTemp, RectangleF connectorPosition) { var ui1 = UIInfo(connectorTemp); //The nature of the bezier splines means they will never reach outside the bounding rectangle which includes their endpoints RectangleF bounds = RectangleF.Union(ui1.Area.Value, connectorPosition); var pair = UnorderedTuple.Make(connectorTemp, connection); bool exists = SpatiallyOrderedConnections.FindTouchingRegion(bounds).Contains(Tuple.Create(pair, bounds)); if (exists) { SpatiallyOrderedConnections.Remove(Tuple.Create(pair, bounds)); } }
public bool CanConnect(Id <TConnectorDefinition> a, Id <TConnectorDefinition> b) { var test = UnorderedTuple.Make(a, b); var alwaysAllowed = UnorderedTuple.Make(SpecialConnectors.Input.Id, SpecialConnectors.Output.Id); if (test.Equals(alwaysAllowed)) { return(true); } if (m_allowed.Contains(test)) { return(true); } return(false); }
public override IEnumerable <ConversationError <T> > Check(IEnumerable <T> nodes, IErrorCheckerUtilities <T> utils) { HashSet <UnorderedTuple2 <T> > results = new HashSet <UnorderedTuple2 <T> >(); foreach (var node in nodes) { foreach (var c in node.Data.Connectors) { foreach (var connection in c.Connections) { if (!c.Rules.CanConnect(c.Definition.Id, connection.Definition.Id)) { results.Add(UnorderedTuple.Make(node, utils.ReverseLookup(connection.Parent))); } } } } return(results.Select(r => new InvalidConnectionError(r))); }
private static HashSet <UnorderedTuple2 <Tuple <Id <TConnector>, Id <NodeTemp> > > > ReadLinks(IEnumerable <Id <NodeTemp> > filteredNodes, XElement root) { HashSet <UnorderedTuple2 <Tuple <Id <TConnector>, Id <NodeTemp> > > > result = new HashSet <UnorderedTuple2 <Tuple <Id <TConnector>, Id <NodeTemp> > > >(); foreach (var link in root.Elements("Link")) { Id <NodeTemp> node1 = Id <NodeTemp> .Parse(link.Attribute("node1").Value); Id <TConnector> connector1 = Id <TConnector> .Parse(link.Attribute("connector1").Value); Id <NodeTemp> node2 = Id <NodeTemp> .Parse(link.Attribute("node2").Value); Id <TConnector> connector2 = Id <TConnector> .Parse(link.Attribute("connector2").Value); if (filteredNodes.Any(n => n.Equals(node1) || n.Equals(node2))) { result.Add(UnorderedTuple.Make(Tuple.Create(connector1, node1), Tuple.Create(connector2, node2))); } } return(result); }
private void ConnectionUpdate(Output connection, Output connectorTemp, bool mustExist) { var ui1 = UIInfo(connectorTemp, false); var ui2 = UIInfo(connection, !mustExist); if (ui2 != null) { //The nature of the bezier splines means they will never reach outside the bounding rectangle which includes their endpoints RectangleF bounds = RectangleF.Union(ui1.Area.Value, ui2.Area.Value); var pair = UnorderedTuple.Make(connectorTemp, connection); bool exists = SpatiallyOrderedConnections.FindTouchingRegion(bounds).Contains(Tuple.Create(pair, bounds)); if (!exists) { SpatiallyOrderedConnections.Add(Tuple.Create(pair, bounds), bounds); } else { } } }
private void paintDrawWindow(object sender, PaintEventArgs e) { Graphics g = e.Graphics; Matrix transform = GetTransform(); var tl = transform.Inverse().TransformPoint(new PointF(0, 0)); var br = transform.Inverse().TransformPoint(new PointF(Width, Height)); RectangleF bounds = RectangleF.FromLTRB(tl.X, tl.Y, br.X, br.Y); using (g.Clip = new Region(new RectangleF(0, 0, DocumentSize.Width * GraphScale, DocumentSize.Height * GraphScale))) { var originalState = g.Save(); DrawGrid(e); g.Transform = transform; if (CurrentFile != null) { //var orderedUnselectedNodes = CurrentFile.Nodes.Reverse().Where(n => !m_mouseController.Selected.Nodes.Contains(n.Data.NodeId)); //var orderedSelectedNodes = CurrentFile.Nodes.Reverse().Where(n => m_mouseController.Selected.Nodes.Contains(n.Data.NodeId)); var tree = new ZOrderedQuadTree <TNode>(SpatiallyOrderedNodes, CurrentFile.RelativePosition); var nodes = tree.FindTouchingRegion(bounds).Reverse(); var orderedUnselectedNodes = nodes.Where(n => !m_mouseController.Selected.Nodes.Contains(n.Data.NodeId)); var orderedSelectedNodes = nodes.Where(n => m_mouseController.Selected.Nodes.Contains(n.Data.NodeId)); //Make sure the nodes are the right size so the connectors end up in the right place foreach (var node in CurrentFile.Nodes) { node.Renderer.UpdateArea(); } HashSet <UnorderedTuple2 <PointF> > unselectedNodeConnections = new HashSet <UnorderedTuple2 <PointF> >(); HashSet <UnorderedTuple2 <PointF> > selectedNodeConnections = new HashSet <UnorderedTuple2 <PointF> >(); HashSet <UnorderedTuple2 <PointF> > selectedConnections = new HashSet <UnorderedTuple2 <PointF> >(); foreach (var node in orderedUnselectedNodes) { foreach (var t in node.Data.Connectors) { foreach (var connection in t.Connections) { PointF p1 = UIInfo(t).Area.Value.Center(); PointF p2 = UIInfo(connection).Area.Value.Center(); var pair = UnorderedTuple.Make(p1, p2); bool selected = m_mouseController.IsSelected(connection) || m_mouseController.IsSelected(t); if (selected) { unselectedNodeConnections.Remove(pair); if (!m_mouseController.DraggingLinks) //If we're dragging this connection around then let the mouse controller render it { selectedConnections.Add(pair); } } else { unselectedNodeConnections.Add(pair); } } } } foreach (var node in orderedSelectedNodes) { foreach (var t in node.Data.Connectors) { foreach (var connection in t.Connections) { PointF p1 = UIInfo(t).Area.Value.Center(); PointF p2 = UIInfo(connection).Area.Value.Center(); var pair = UnorderedTuple.Make(p1, p2); bool selected = m_mouseController.IsSelected(connection) || m_mouseController.IsSelected(t); unselectedNodeConnections.Remove(pair); if (selected) { selectedNodeConnections.Remove(pair); if (!m_mouseController.DraggingLinks) //If we're dragging this connection around then let the mouse controller render it { selectedConnections.Add(pair); } } else { selectedNodeConnections.Add(pair); } } } } //Draw all the groups foreach (NodeGroup group in CurrentFile.Groups.Reverse()) { group.Renderer.Draw(g, m_mouseController.Selected.Groups.Contains(group), m_colorScheme); } //Draw all the connections for unselected nodes using (ConnectionDrawer connections = new ConnectionDrawer(this.Colors)) { foreach (var connection in unselectedNodeConnections) { connections.Add(connection.Item1, connection.Item2, false); } connections.Draw(g); } //Draw all the unselected nodes foreach (TNode node in orderedUnselectedNodes) { node.Renderer.Draw(g, m_mouseController.Selected.Nodes.Contains(node.Data.NodeId), m_colorScheme); foreach (var t in node.Data.Connectors) { bool selected = m_mouseController.IsSelected(t); UIInfo(t).Draw(g, selected ? Colors.Foreground : Colors.Connectors); } } //Draw all the connections for selected nodes using (ConnectionDrawer connections = new ConnectionDrawer(this.Colors)) { foreach (var connection in selectedNodeConnections) { connections.Add(connection.Item1, connection.Item2, false); } connections.Draw(g); } //Draw all the selected nodes foreach (TNode node in orderedSelectedNodes) { node.Renderer.Draw(g, m_mouseController.Selected.Nodes.Contains(node.Data.NodeId), m_colorScheme); foreach (var t in node.Data.Connectors) { bool selected = m_mouseController.IsSelected(t); UIInfo(t).Draw(g, selected ? Colors.Foreground : Colors.Connectors); } } //Draw all the selected connections using (ConnectionDrawer connections = new ConnectionDrawer(this.Colors)) { foreach (var connection in selectedConnections) { connections.Add(connection.Item1, connection.Item2, true); } connections.Draw(g); } //Draw any dynamic connections, etc if (m_mouseController != null) { using (var connections = new ConnectionDrawer(this.Colors)) { m_mouseController.Draw(g, connections); connections.Draw(g); } } } g.DrawRectangle(Colors.ControlBorder, RectangleF.FromLTRB(0, 0, DocumentSize.Width - 1, DocumentSize.Height - 1)); g.Restore(originalState); g.DrawRectangle(Colors.ControlBorder, Rectangle.FromLTRB(0, 0, drawWindow.Width - 1, drawWindow.Height - 1)); } }
public void Allow(Id <TConnectorDefinition> a, Id <TConnectorDefinition> b) { m_rules.Add(UnorderedTuple.Make(a, b)); }
public bool CanConnect(Id <TConnectorDefinition> a, Id <TConnectorDefinition> b) { return(m_rules.Contains(UnorderedTuple.Make(a, b))); }
public bool CanConnect(Id <TConnectorDefinition> a, Id <TConnectorDefinition> b) { return(acceptablePairings.Contains(UnorderedTuple.Make(a, b))); }