/// <summary> /// Retrieve a connection between the two connectors. /// Returns null if there is no connection between the connectors. /// </summary> public ConnectionViewModel FindConnection(ConnectorViewModel connector1, ConnectorViewModel connector2) { Trace.Assert(connector1.Type != connector2.Type); // // Figure out which one is the source connector and which one is the // destination connector based on their connector types. // var sourceConnector = connector1.Type == ConnectorType.Output ? connector1 : connector2; var destConnector = connector1.Type == ConnectorType.Output ? connector2 : connector1; // // Now we can just iterate attached connections of the source // and see if it each one is attached to the destination connector. // foreach (var connection in sourceConnector.AttachedConnections) { if (connection.DestConnector == destConnector) { // // Found a connection that is outgoing from the source connector // and incoming to the destination connector. // return connection; } } return null; }
/// <summary> /// Called to query the application for feedback while the user is dragging the connection. /// </summary> public void QueryConnnectionFeedback(ConnectorViewModel draggedOutConnector, ConnectorViewModel draggedOverConnector, out object feedbackIndicator, out bool connectionOk) { if (draggedOutConnector == draggedOverConnector) { // // Can't connect to self! // Provide feedback to indicate that this connection is not valid! // feedbackIndicator = new ConnectionBadIndicator(); connectionOk = false; } else { var sourceConnector = draggedOutConnector; var destConnector = draggedOverConnector; // // Only allow connections from output connector to input connector (ie each // connector must have a different type). // Also only allocation from one node to another, never one node back to the same node. // connectionOk = sourceConnector.ParentNode != destConnector.ParentNode && sourceConnector.Type != destConnector.Type && destConnector.AttachedConnections.Count == 0; if (connectionOk) { // // Yay, this is a valid connection! // Provide feedback to indicate that this connection is ok! // feedbackIndicator = new ConnectionOkIndicator(); } else { // // Connectors with the same connector type (eg input & input, or output & output) // can't be connected. // Only connectors with separate connector type (eg input & output). // Provide feedback to indicate that this connection is not valid! // feedbackIndicator = new ConnectionBadIndicator(); } } }
/// <summary> /// Called when the user has finished dragging out the new connection. /// </summary> public void ConnectionDragCompleted(ConnectionViewModel newConnection, ConnectorViewModel connectorDraggedOut, ConnectorViewModel connectorDraggedOver) { if (connectorDraggedOver == null) { // // The connection was unsuccessful. // Maybe the user dragged it out and dropped it in empty space. // this.Network.Connections.Remove(newConnection); return; } // // Only allow connections from output connector to input connector (ie each // connector must have a different type). // Also only allocation from one node to another, never one node back to the same node. // bool connectionOk = connectorDraggedOut.ParentNode != connectorDraggedOver.ParentNode && connectorDraggedOut.Type != connectorDraggedOver.Type && connectorDraggedOver.AttachedConnections.Count == 0; if (!connectionOk) { // // Connections between connectors that have the same type, // eg input -> input or output -> output, are not allowed, // Remove the connection. // this.Network.Connections.Remove(newConnection); return; } // // The user has dragged the connection on top of another valid connector. // // // Remove any existing connection between the same two connectors. // var existingConnection = FindConnection(connectorDraggedOut, connectorDraggedOver); if (existingConnection != null) { this.Network.Connections.Remove(existingConnection); } // // Finalize the connection by attaching it to the connector // that the user dragged the mouse over. // if (newConnection.DestConnector == null) { newConnection.DestConnector = connectorDraggedOver; } else { newConnection.SourceConnector = connectorDraggedOver; } if (newConnection.DestConnector != null && newConnection.SourceConnector != null) { LibnoiseNode sourceNode = newConnection.SourceConnector.ParentNode.Module; LibnoiseNode destinationNode = newConnection.DestConnector.ParentNode.Module; ModuleBase sourceModule = newConnection.SourceConnector.ParentNode.Module.LibnoiseModule; ModuleBase destinationModule = newConnection.DestConnector.ParentNode.Module.LibnoiseModule; // get destination type, connector name, assign to correct module if(newConnection.DestConnector.Name.Equals("Input")) { destinationModule.Modules[0] = sourceModule; destinationNode.Inputs[0] = sourceNode; } else if(newConnection.DestConnector.Name.Equals("Left")) { destinationModule.Modules[0] = sourceModule; destinationNode.Inputs[0] = sourceNode; } else if(newConnection.DestConnector.Name.Equals("Right")) { destinationModule.Modules[1] = sourceModule; destinationNode.Inputs[1] = sourceNode; } else if(newConnection.DestConnector.Name.Equals("Operator")) { destinationModule.Modules[2] = sourceModule; destinationNode.Inputs[2] = sourceNode; } else if(newConnection.DestConnector.Name.Equals("Primary")) { destinationModule.Modules[0] = sourceModule; destinationNode.Inputs[0] = sourceNode; } else if(newConnection.DestConnector.Name.Equals("Secondary")) { destinationModule.Modules[1] = sourceModule; destinationNode.Inputs[1] = sourceNode; } else if(newConnection.DestConnector.Name.Equals("Controller")) { destinationModule.Modules[2] = sourceModule; destinationNode.Inputs[2] = sourceNode; } else if(newConnection.DestConnector.Name.Equals("X")) { destinationModule.Modules[1] = sourceModule; destinationNode.Inputs[1] = sourceNode; } else if(newConnection.DestConnector.Name.Equals("Y")) { destinationModule.Modules[2] = sourceModule; destinationNode.Inputs[2] = sourceNode; } else if(newConnection.DestConnector.Name.Equals("Z")) { destinationModule.Modules[3] = sourceModule; destinationNode.Inputs[3] = sourceNode; } } }
/// <summary> /// Called when the user has started to drag out a connector, thus creating a new connection. /// </summary> public ConnectionViewModel ConnectionDragStarted(ConnectorViewModel draggedOutConnector, Point curDragPoint) { // // Create a new connection to add to the view-model. // var connection = new ConnectionViewModel(); if (draggedOutConnector.Type == ConnectorType.Output) { // // The user is dragging out a source connector (an output) and will connect it to a destination connector (an input). // connection.SourceConnector = draggedOutConnector; connection.DestConnectorHotspot = curDragPoint; } else { // // The user is dragging out a destination connector (an input) and will connect it to a source connector (an output). // connection.DestConnector = draggedOutConnector; connection.SourceConnectorHotspot = curDragPoint; } // // Add the new connection to the view-model. // this.Network.Connections.Add(connection); return connection; }
/// <summary> /// Recursive Solve single node calculation /// </summary> /// <param name="node"></param> /// <returns>Is success solved</returns> private bool UnitSolve(AbstractNodeViewModel node,ConnectorViewModel invokerConnector = null) { { bool isSuccessed = true; if (node.InputConnectors.Count != 0) { foreach (var connector in node.InputConnectors) { // Exist input connectors, so check whether this attached to any node if (connector.AttachedConnections.Count != 0) { // Attached input // Attached num check if (connector.AttachedConnections.Count > 1) { // Usually not reached point throw new NotImplementedException("now input connection must has single attached."); } //So call the self recursively in terms of get this node's destination of the node foreach (var connection in connector.AttachedConnections) { AbstractNodeViewModel outputNode = null; if (connection.DestConnector.Type == ConnectorType.Output) outputNode = connection.DestConnector.ParentNode; else outputNode = connection.SourceConnector.ParentNode; isSuccessed = UnitSolve(outputNode, connector); } } } } /// If could not solved of just before node, cancel solve //if (!isSuccessed) return false; } /// Execute Calculation node.Calculate(); /// Check node is be able to solve of static //if(node.SolverType != NodeCalculationType.Dynamic) //{ // return false; //} /// Propagate data to invoker foreach(var connector in node.OutputConnectors) { foreach(var connection in connector.AttachedConnections) { ConnectorViewModel outputConnector = null; ConnectorViewModel inputConnector = null; if (connection.DestConnector.Type == ConnectorType.Output) { outputConnector = connection.DestConnector; inputConnector = connection.SourceConnector; } else { outputConnector = connection.SourceConnector; inputConnector = connection.DestConnector; } if (inputConnector == invokerConnector && connection.DestConnector.DataType == invokerConnector.DataType) { invokerConnector.NoRaiseEntity = outputConnector.Entity; } } } return true; }
/// <summary> /// /// </summary> public CreateConnectionUndoCommand(FlowGraphControlViewModel fgvm_, ConnectionViewModel connectionVM_) { m_FlowGraphVM = fgvm_; //m_ConnectionVM = connectionVM_.Copy(); m_DestConnector = connectionVM_.DestConnector; m_DestConnectorHotspot = connectionVM_.DestConnectorHotspot; m_Points = connectionVM_.Points; m_SourceConnector = connectionVM_.SourceConnector; m_SourceConnectorHotspot = connectionVM_.SourceConnectorHotspot; }
/// <summary> /// Called to query the application for feedback while the user is dragging the connection. /// </summary> public void QueryConnnectionFeedback(ConnectorViewModel draggedOutConnector, ConnectorViewModel draggedOverConnector, out object feedbackIndicator, out bool connectionOk) { if (draggedOutConnector == draggedOverConnector) { // // Can't connect to self! // Provide feedback to indicate that this connection is not valid! // feedbackIndicator = new ConnectionBadIndicator("Can't connect to self"); connectionOk = false; } else { string message = string.Empty; var sourceConnector = draggedOutConnector; var destConnector = draggedOverConnector; // // Only allow connections from output connector to input connector (ie each // connector must have a different type). // Also only allocation from one node to another, never one node back to the same node. // connectionOk = IsValidConnection(sourceConnector, draggedOverConnector, ref message); if (connectionOk) { feedbackIndicator = new ConnectionOkIndicator(); } else { // // Connectors with the same connector type (eg input & input, or output & output) // can't be connected. // Only connectors with separate connector type (eg input & output). // Provide feedback to indicate that this connection is not valid! // feedbackIndicator = new ConnectionBadIndicator(message); } } }
/// <summary> /// Called when the user has finished dragging out the new connection. /// </summary> public void ConnectionDragCompleted( ConnectionViewModel newConnection, ConnectorViewModel connectorDraggedOut, ConnectorViewModel connectorDraggedOver) { if (connectorDraggedOver == null) { // // The connection was unsuccessful. // Maybe the user dragged it out and dropped it in empty space. // this.Network.Connections.Remove(newConnection); // m_connectorDraggedOut = connectorDraggedOut; // m_ConnectorDraggedOver = connectorDraggedOver; // // //Open contextMenu // if (ContextMenuOpened != null) // { // ContextMenuOpened(this, null); // } return; } // // Only allow connections from output connector to input connector (ie each // connector must have a different type). // Also only allocation from one node to another, never one node back to the same node. // string dummy = string.Empty; bool connectionOk = IsValidConnection(connectorDraggedOut, connectorDraggedOver, ref dummy); if (!connectionOk) { // // Connections between connectors that have the same type, // eg input -> input or output -> output, are not allowed, // Remove the connection. // this.Network.Connections.Remove(newConnection); return; } // // The user has dragged the connection on top of another valid connector. // // // Remove any existing connection between the same two connectors. // var existingConnection = FindConnection(connectorDraggedOut, connectorDraggedOver); if (existingConnection != null) { this.Network.Connections.Remove(existingConnection); } // Finalize the connection by reordering the source & destination // if necessary if (newConnection.DestConnector == null) { if (connectorDraggedOver.SourceSlot.ConnectionType == SlotType.VarInOut) { if (newConnection.SourceConnector.SourceSlot.ConnectionType == SlotType.VarIn) { ConnectorViewModel dest = newConnection.SourceConnector; newConnection.SourceConnector = connectorDraggedOver; newConnection.DestConnector = dest; } else { newConnection.DestConnector = connectorDraggedOver; } } else if (connectorDraggedOver.SourceSlot.ConnectionType == SlotType.NodeIn || connectorDraggedOver.SourceSlot.ConnectionType == SlotType.VarIn) { newConnection.DestConnector = connectorDraggedOver; } else { ConnectorViewModel dest = newConnection.SourceConnector; newConnection.SourceConnector = connectorDraggedOver; newConnection.DestConnector = dest; } } else // connector source is null { if (connectorDraggedOver.SourceSlot.ConnectionType == SlotType.VarInOut) { if (newConnection.DestConnector.SourceSlot.ConnectionType == SlotType.VarIn) { newConnection.SourceConnector = connectorDraggedOver; } else { ConnectorViewModel dest = newConnection.DestConnector; newConnection.DestConnector = connectorDraggedOver; newConnection.SourceConnector = dest; } } else if (connectorDraggedOver.SourceSlot.ConnectionType == SlotType.NodeIn || connectorDraggedOver.SourceSlot.ConnectionType == SlotType.VarIn) { newConnection.SourceConnector = connectorDraggedOver; } else { ConnectorViewModel dest = newConnection.DestConnector; newConnection.SourceConnector = connectorDraggedOver; newConnection.DestConnector = dest; } } //special case variable from 2 SequenceNode directly connected if (newConnection.SourceConnector.SourceSlot is NodeSlotVar && newConnection.DestConnector.SourceSlot is NodeSlotVar) { ConnectorViewModel src = newConnection.SourceConnector; newConnection.SourceConnector = newConnection.DestConnector; newConnection.DestConnector = src; } m_UndoManager.Add(new CreateConnectionUndoCommand(this, newConnection)); }
/// <summary> /// Check if the 2 slot can be connected /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <param name="message_"></param> /// <returns></returns> private bool IsValidConnection(ConnectorViewModel a, ConnectorViewModel b, ref string message_) { bool connectionOk = a.ParentNode != b.ParentNode && a.Type != b.Type; if (connectionOk == true) { //case Variable Input Output if (a.Type == ConnectorType.VariableInputOutput) { connectionOk = b.Type == ConnectorType.VariableInput || b.Type == ConnectorType.VariableOutput; } else if (b.Type == ConnectorType.VariableInputOutput) { connectionOk = a.Type == ConnectorType.VariableInput || a.Type == ConnectorType.VariableOutput; } //case node/variable if (a.Type == ConnectorType.Input || a.Type == ConnectorType.Output) { connectionOk = b.Type == ConnectorType.Input || b.Type == ConnectorType.Output; } else if (b.Type == ConnectorType.Input || b.Type == ConnectorType.Output) { connectionOk = a.Type == ConnectorType.Input || a.Type == ConnectorType.Output; } //TODO : test connection object type //case Variable Output/Variable if (a.Type == ConnectorType.VariableOutput) { return b.Type == ConnectorType.VariableInputOutput || b.Type == ConnectorType.VariableInput; } else if (b.Type == ConnectorType.VariableOutput) { return a.Type == ConnectorType.VariableInputOutput || a.Type == ConnectorType.VariableInput; } //case Variable Input/Variable if (a.Type == ConnectorType.VariableInput/* || a.Type == ConnectorType.VariableOutput*/) { //a.AttachedConnections.Count == 1 because the destination connector is already connected connectionOk = b.Type == ConnectorType.VariableInputOutput && a.AttachedConnections.Count == 1; if (connectionOk == false) { message_ = "You can connect only one node into this slot"; } } else if (b.Type == ConnectorType.VariableInput/* || b.Type == ConnectorType.VariableOutput*/) { connectionOk = a.Type == ConnectorType.VariableInputOutput && b.AttachedConnections.Count == 0; if (connectionOk == false) { message_ = "You can connect only one node into this slot"; } } } // TODO : check if obsolete with direct connection ?? // check for variable node connection if (connectionOk == true && ( (a.Type == ConnectorType.VariableInput || a.Type == ConnectorType.VariableOutput || a.Type == ConnectorType.VariableInputOutput) && (b.Type == ConnectorType.VariableInput || b.Type == ConnectorType.VariableOutput || b.Type == ConnectorType.VariableInputOutput) )) { connectionOk = VariableTypeInspector.CheckCompatibilityType(a.SourceSlot.VariableType, b.SourceSlot.VariableType); if (connectionOk == false) { message_ = "You can not connect because the type is different"; } } return connectionOk; }
/// <summary> /// Called when the user has finished dragging out the new connection. /// </summary> public void ConnectionDragCompleted(ConnectionViewModel newConnection, ConnectorViewModel connectorDraggedOut, ConnectorViewModel connectorDraggedOver) { if (connectorDraggedOver == null) { // // The connection was unsuccessful. // Maybe the user dragged it out and dropped it in empty space. // this.Network.Connections.Remove(newConnection); return; } // // The user has dragged the connection on top of another valid connector. // var existingConnections = connectorDraggedOver.AttachedConnections; if (existingConnections != null) { // // There is already a connection attached to the connector that was dragged over. // Remove the existing connection from the view-model. // this.Network.Connections.RemoveRange(existingConnections as IEnumerable); } // // Finalize the connection by attaching it to the connector // that the user dropped the connection on. // newConnection.DestConnector = connectorDraggedOver; }
/// <summary> /// Called when the user has started to drag out a connector, thus creating a new connection. /// </summary> public ConnectionViewModel ConnectionDragStarted(ConnectorViewModel draggedOutConnector, Point curDragPoint) { if (draggedOutConnector.AttachedConnections.Any()) { // // There is an existing connection attached to the connector that has been dragged out. // Remove the existing connection from the view-model. // this.Network.Connections.RemoveRange(draggedOutConnector.AttachedConnections as IEnumerable); } // // Create a new connection to add to the view-model. // var connection = new ConnectionViewModel(); // // Link the source connector to the connector that was dragged out. // connection.SourceConnector = draggedOutConnector; // // Set the position of destination connector to the current position of the mouse cursor. // connection.DestConnectorHotspot = curDragPoint; // // Add the new connection to the view-model. // this.Network.Connections.Add(connection); return connection; }