// ---------------------------------------------------------------------- static iCS_EditorObject CreateAttachedMethod(iCS_EditorObject port, iCS_IStorage iStorage, Vector2 globalPos, LibraryObject libraryObject) { iCS_EditorObject newNodeParent = iStorage.GetNodeAt(globalPos); if (newNodeParent == null) { return(null); } if (!newNodeParent.IsKindOfPackage || newNodeParent.IsBehaviour) { return(null); } // FIXME: Animation & force layout sometime conflict. // Open a transaction for multi-operations iCS_UserCommands.OpenTransaction(iStorage); iCS_EditorObject method = null; iStorage.AnimateGraph(null, _ => { if (newNodeParent.IsInstanceNode) { method = iCS_UserCommands.CreatePropertiesWizardElement(newNodeParent, libraryObject); } else { method = iCS_UserCommands.CreateFunctionCallNode(newNodeParent, globalPos, libraryObject); } // Inverse effective data flow if new node is inside port parent. bool isConsumerPort = port.IsInputPort; var portParent = port.ParentNode; if (portParent.IsParentOf(method)) { isConsumerPort = !isConsumerPort; } iCS_EditorObject attachedPort = null; iCS_EditorObject providerPort = null; iCS_EditorObject consumerPort = null; if (isConsumerPort) { iCS_EditorObject[] outputPorts = Prelude.filter(x => iCS_Types.IsA(port.RuntimeType, x.RuntimeType), iStorage.GetChildOutputDataPorts(method)); // Connect if only one possibility. if (outputPorts.Length == 1) { attachedPort = outputPorts[0]; consumerPort = port; providerPort = attachedPort; } else { var bestPort = GetClosestMatch(port, outputPorts); if (bestPort != null) { attachedPort = bestPort; consumerPort = port; providerPort = bestPort; } } } else { iCS_EditorObject[] inputPorts = Prelude.filter(x => iCS_Types.IsA(x.RuntimeType, port.RuntimeType), iStorage.GetChildInputDataPorts(method)); // Connect if only one posiibility if (inputPorts.Length == 1) { attachedPort = inputPorts[0]; consumerPort = attachedPort; providerPort = port; } // Multiple choices exist so try the one with the closest name. else { var bestPort = GetClosestMatch(port, inputPorts); if (bestPort != null) { attachedPort = bestPort; consumerPort = bestPort; providerPort = port; } } } // Position attached port and layout binding. if (attachedPort != null && consumerPort != null && providerPort != null) { iStorage.AutoLayoutPort(attachedPort, port.GlobalPosition, attachedPort.ParentNode.GlobalPosition); iStorage.SetAndAutoLayoutNewDataConnection(consumerPort, providerPort); } iStorage.ForcedRelayoutOfTree(); } ); iCS_UserCommands.CloseTransaction(iStorage, "Create => " + libraryObject.nodeName); return(method); }