private void NodePin_Loaded(object sender, RoutedEventArgs e) { NodePinViewModel viewModel = ((NodePinViewModel)DataContext); this.pinColourCache = viewModel.PinColour; viewModel.Pin = this; }
public static List <ConnectionViewModel> GetPinConnections(NodePinViewModel pin, GraphEditorViewModel graph) { List <ConnectionViewModel> pinConnections = new List <ConnectionViewModel>(); foreach (var connection in graph.Connections) { NodePinViewModel inputPin = connection.InputPin; NodePinViewModel outputPin = connection.OutputPin; if (pin == inputPin || pin == outputPin) { pinConnections.Add(connection); } } return(pinConnections); }
private void Editor_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // If we are creating a connection... if (IsCreatingConnection) { ConnectionBuilderViewModel connectionBuilder = (ConnectionBuilderViewModel)NewConnectionLine.DataContext; NodePinViewModel connectionRootPin = (NodePinViewModel)connectionBuilder.OutputPin.DataContext; // Check if we are clicking from an input pin // If we are, try to automatically place a constant node connecting to the input pin if (connectionRootPin.IsOutputPin == false && connectionRootPin.IsExecutionPin == false) { GraphEditorViewModel viewModel = (GraphEditorViewModel)this.DataContext; VisualConstantNodeViewModel autoConstantNode = new VisualConstantNodeViewModel(connectionRootPin.DataType) { X = viewModel.MousePoint.X, Y = viewModel.MousePoint.Y }; viewModel.VisualNodes.Add(autoConstantNode); // Generates the view for the NodePin in the constant node before we add it Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle, null); viewModel.Connections.Add(new ConnectionViewModel(autoConstantNode.OutputPin.Pin, connectionRootPin.Pin)); } IsCreatingConnection = false; return; } // If we aren't creating a connection just deselect any nodes foreach (VisualGraphComponentViewModel node in ((GraphEditorViewModel)DataContext).VisualNodes) { node.IsSelected = false; } }
private void NodePin_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { DependencyObject parentObject = VisualTreeHelper.GetParent(this); // Find the visual editor while (!(parentObject is VisualEditor)) { parentObject = VisualTreeHelper.GetParent(parentObject); if (parentObject == null) { return; } } VisualEditor visualEditor = parentObject as VisualEditor; // Determine how to handle the click if (visualEditor.IsCreatingConnection) { // If we are creating a new connection then we have to validate and add a new one GraphEditorViewModel graph = ((GraphEditorViewModel)visualEditor.DataContext); ConnectionBuilderViewModel connectionBuilder = ((ConnectionBuilderViewModel)visualEditor.NewConnectionLine.DataContext); NodePinViewModel rootPin = (NodePinViewModel)connectionBuilder.OutputPin.DataContext; NodePinViewModel targetPin = (NodePinViewModel)this.DataContext; // Validate the output and input pins // Reverse them if needed // TODO: More extensive validation. ie. Check for output -> output or input -> input connections. // Ensure datatypes are the same between pins if (rootPin.DataType != targetPin.DataType) { // If the data types do not match try and add in an auto-conversion foreach (var rule in graph.ConversionRules) { if (rule.Item1 == rootPin.DataType && rule.Item2 == targetPin.DataType) { // Conversion rule found! // Add the conversion node at the midpoint between pins Point rootPoint = rootPin.Pin.Centre; Point targetPoint = targetPin.Pin.Centre; Point midPoint = new Point( ((rootPoint.X + targetPoint.X) / 2), (rootPoint.Y + targetPoint.Y) / 2); VisualNodeViewModel conversionNode = new VisualNodeViewModel(rule.Item3) { X = midPoint.X, Y = midPoint.Y }; graph.VisualNodes.Add(conversionNode); // Generate the conversion node's view so we can access its pins Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle, null); // Add the new connections, but ensure it is an OutputPin -> InputPin connection // Otherwise, we need to correct for that here if (((NodePinViewModel)connectionBuilder.OutputPin.DataContext).IsOutputPin == false) { // Connections need flipping graph.Connections.Add(new ConnectionViewModel(targetPin.Pin, conversionNode.Inputs[0].Pin)); graph.Connections.Add(new ConnectionViewModel(conversionNode.Outputs[0].Pin, rootPin.Pin)); } else { // Connection is correct graph.Connections.Add(new ConnectionViewModel(rootPin.Pin, conversionNode.Inputs[0].Pin)); graph.Connections.Add(new ConnectionViewModel(conversionNode.Outputs[0].Pin, targetPin.Pin)); } } } } // If datatypes are the same, we can just create a connection between the pins // Make sure the connection is added in an OutputPin -> InputPin order else { if (((NodePinViewModel)connectionBuilder.OutputPin.DataContext).IsOutputPin == false) { graph.Connections.Add(new ConnectionViewModel(this, connectionBuilder.OutputPin)); } else { graph.Connections.Add(new ConnectionViewModel(connectionBuilder.OutputPin, this)); } } visualEditor.IsCreatingConnection = false; } else { // We need to initialise the 'create a connection' mode visualEditor.IsCreatingConnection = true; // And set the root pin ConnectionBuilderViewModel newConnection = ((ConnectionBuilderViewModel)visualEditor.NewConnectionLine.DataContext); newConnection.OutputPin = this; } }