Exemplo n.º 1
0
        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;
            }
        }
Exemplo n.º 2
0
        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;
            }
        }