Exemplo n.º 1
0
        public void AddToGraph(VisualPortGraphNode source, VisualPortGraphNode destination, Port sourcePort, Port destinationPort)
        {
            if (source == null)
            {
                return;
            }

            source.GetPort(sourcePort.Name, condition: p => !p.IsInputPort);

            if (destination != null && destinationPort == null)
            {
                // Select matching port on destination
                destinationPort = destination.GetPort(sourcePort.Type, byMatchingType: true, condition: p => p.IsInputPort) ??
                                  destination.Ports.FirstOrDefault(p => p.IsInputPort);
            }

            var sourcePositionHandler = new Action <string, Port, IPortConnection>((nodeId, port, connection) =>
            {
                var node = Graph.GetNode(nodeId);

                if (node != null)
                {
                    var portRender = node.PortRenders[port.Name];
                    var position   = portRender.TranslatePoint(new Point(0, 0), node.Render);

                    position.X += node.PositionX + portRender.ActualWidth;
                    position.Y +=
                        node.PositionY
                        + portRender.ActualHeight / 2
                        + connection.SourcePort.ConnectionIds.IndexOf(connection.Id) * 5
                        - connection.SourcePort.ConnectionIds.Count * 5;

                    connection.SourcePosition = position;
                }
            });

            var destinationPositionHandler = new Action <string, Port, IPortConnection>((nodeId, port, connection) =>
            {
                var node = Graph.GetNode(nodeId);

                if (node != null)
                {
                    FrameworkElement portRender;
                    if (node.PortRenders.ContainsKey(port.Name))
                    {
                        portRender = node.PortRenders[port.Name];
                    }
                    else
                    {
                        portRender = node.PortRenders.Values.First();
                    }

                    var position = portRender.TranslatePoint(new Point(0, 0), node.Render);

                    position.X += node.PositionX;
                    position.Y += node.PositionY + portRender.ActualHeight / 2;

                    connection.DestinationPosition = position;
                }
            });

            var newConnection = new PortGraphConnection()
            {
                Graph           = Graph,
                StateTransition = StateTransition,
                UndoHistory     = UndoHistory,
                SourceId        = source.Id,
                DestinationId   = destination?.Id ?? "",
                SourcePort      = sourcePort,
                DestinationPort = destinationPort ?? null
            };

            newConnection.InitialiseRender();

            newConnection.SourcePositionHandler      = sourcePositionHandler;
            newConnection.DestinationPositionHandler = destinationPositionHandler;

            newConnection.Validate();

            // The following should change to accomodate manually-set positions
            if (sourcePort != null && !sourcePort.ConnectionIds.Contains(newConnection.Id))
            {
                sourcePort.ConnectionIds.Add(newConnection.Id);
            }

            if (destinationPort != null && destinationPort.ConnectionIds.Contains(newConnection.Id))
            {
                destinationPort.ConnectionIds.Add(newConnection.Id);
            }

            if (source != null)
            {
                source.RefreshPortUI();
            }
            if (destination != null)
            {
                destination.RefreshPortUI();
            }

            // Add connection when wire is manually placed onto a new source or destination
            (source as VisualPortGraphNode).PortConnectionRequested += port =>
            {
                var conn = Graph.GetConnection(Graph.GetSelectedConnectionId());

                if (conn != null)
                {
                    if (port.IsInputPort)
                    {
                        conn.ChangeDestination(source.Id, port);
                    }
                    else
                    {
                        conn.ChangeSource(source.Id, port);
                    }
                }
            };

            if (destination != null)
            {
                (destination as VisualPortGraphNode).PortConnectionRequested += port =>
                {
                    var conn = Graph.GetConnection(Graph.GetSelectedConnectionId());

                    if (conn != null)
                    {
                        if (port.IsInputPort)
                        {
                            conn.ChangeDestination(destination.Id, port);
                        }
                        else
                        {
                            conn.ChangeSource(destination.Id, port);
                        }
                    }

                    StateTransition.Update(Enums.DiagramMode.Idle);
                };
            }

            Graph.AddConnection(newConnection);

            newConnection.Render.Loaded += (sender, args) => renderLoaded?.Execute();

            foreach (var transitionEventHandler in transitionEventHandlers)
            {
                transitionEventHandler.Sender = newConnection;
            }

            if (destination != null)
            {
                Graph.SelectNode(destination.Id);
            }

            if (connectionIdOutput != null)
            {
                connectionIdOutput.Data = newConnection.Id;
            }
        }