private void TransferInformationFromMethodToProperty(VisualNode sourceNode, VisualNode destinationNode)
        {
            if (sourceNode == null)
                throw new ArgumentNullException("sourceNode");
            if (sourceNode == null)
                throw new ArgumentNullException("destinationNode");

            destinationNode.Text = sourceNode.Text;

            Slot destinationInputSlot = this.GetSlot(destinationNode.GetInputSlot(0)) as Slot;
            Slot sourceInputSlot = this.GetSlot(sourceNode.GetInputSlot(0)) as Slot;
            if (sourceInputSlot.ConnectingSlots != null)
            {
                Slot outputSlot = this.GetSlot(sourceInputSlot.ConnectingSlots[0]) as Slot;
                this.edgeController.CreateLinkingEdge(outputSlot, destinationInputSlot);
            }

            Slot destinationOutputSlot = this.GetSlot(destinationNode.GetOutputSlot(0)) as Slot;
            Slot sourceOutputSlot = this.GetSlot(sourceNode.GetOutputSlot(0)) as Slot;
            if (sourceOutputSlot.ConnectingSlots != null)
            {
                foreach (uint slotId in sourceOutputSlot.ConnectingSlots)
                {
                    Slot inputSlot = this.GetSlot(slotId) as Slot;
                    this.edgeController.CreateLinkingEdge(destinationOutputSlot, inputSlot);
                }
            }

            List<string> defined = sourceNode.GetDefinedVariables(false);
            graphProperties.RuntimeStates.TransferVariableDefinitionMapping(
                defined, sourceNode.NodeId, destinationNode.NodeId);
        }
        private bool HandleSelectedMenuItem(GraphCommand command)
        {
            int         menuItemId   = (int)command.GetArgument(0);
            double      mouseX       = ((double)command.GetArgument(1));
            double      mouseY       = ((double)command.GetArgument(2));
            uint        nodeId       = (uint)command.GetArgument(3);
            NodePart    part         = ((NodePart)command.GetArgument(4));
            LibraryItem selectedItem = new LibraryItem();

            VisualNode node = this.GetVisualNode(nodeId);

            if (itemsProvider != null)
            {
                selectedItem = this.itemsProvider.GetItem(menuItemId);
            }

            if (selectedItem == null) //No match in the library
            {
                if (part == NodePart.NorthWest)
                {
                    this.HandleTopLeftSelectedItem(menuItemId, nodeId);
                }
                else if (menuItemId == Configurations.ConvertNodeToCode)
                {
                    HandleConvertSelectionToCode();
                    return(true);
                }
                else if (menuItemId < Configurations.PropertyBase)
                {
                    // @TODO(Joy): Use switch-case for "menuItemId".
                    ProcessPreviewMenuItems(menuItemId, nodeId);
                    UpdateDirtyNodes();
                    return(true);
                }
            }
            else //Item found in library
            {
                if (selectedItem.Children != null && selectedItem.Children.Count > 0)
                {
                    selectedItem = selectedItem.Children[0];
                }

                LibraryItem.MemberType itemType   = this.GetItemType(menuItemId);
                DeltaNodes             deltaNodes = new DeltaNodes();
                VisualNode             newNode    = null;

                if (part == NodePart.NorthEast)
                {
                    if (selectedItem.Type == LibraryItem.MemberType.InstanceProperty)
                    {
                        if (selectedItem.ItemType == NodeType.Function)
                        {
                            newNode = this.CreateMethodNode(mouseX, mouseY, selectedItem.Assembly, selectedItem.QualifiedName, selectedItem.ArgumentTypes);
                        }
                        else
                        {
                            newNode = this.CreatePropertyNode(mouseX, mouseY, selectedItem.Assembly, selectedItem.QualifiedName, selectedItem.ArgumentTypes);
                        }

                        deltaNodes.AppendToAddedNodes(newNode);
                    }
                    else if (selectedItem.Type == LibraryItem.MemberType.InstanceMethod)
                    {
                        newNode = this.CreateMethodNode(mouseX, mouseY, selectedItem.Assembly, selectedItem.QualifiedName, selectedItem.ArgumentTypes);
                        deltaNodes.AppendToAddedNodes(newNode);
                    }

                    if (newNode != null && (null != deltaNodes.AddedNodes) && deltaNodes.AddedNodes.Count > 0)
                    {
                        // @keyu: If we are acessing its member function or
                        // property, there is no reason to mark this node as
                        // dirty. Comment it out to avoid to recreate object.
                        //
                        // deltaNodes.AppendToModifiedNodes(node);

                        Slot inputSlot  = this.GetSlot(newNode.GetInputSlot(0)) as Slot;
                        Slot outputSlot = this.GetSlot(node.GetOutputSlot(0)) as Slot;

                        this.undoRedoRecorder.BeginGroup();
                        this.undoRedoRecorder.RecordRuntimeStatesForUndo(this.graphProperties.RuntimeStates);
                        this.undoRedoRecorder.RecordNodeModificationForUndo(deltaNodes.ModifiedNodes);
                        this.graphProperties.RuntimeStates.AddVariablesDefinedInNode(newNode, false);
                        this.edgeController.CreateLinkingEdge(outputSlot, inputSlot);
                        this.undoRedoRecorder.RecordNodeCreationForUndo(deltaNodes.AddedNodes);
                        this.undoRedoRecorder.EndGroup();

                        //After EstablishLinkingConnection() is executed, the nodes in the nodeToModify would already be modified
                        this.SynchronizeToLiveRunner(deltaNodes);
                    }
                }
                else if (part == NodePart.North)
                {
                    if (itemType == LibraryItem.MemberType.Constructor)
                    {
                        deltaNodes.AppendToModifiedNodes(node);
                        deltaNodes.AppendToModifiedNodes(FindAssociatedNodesFromNodes(deltaNodes.ModifiedNodes));

                        this.undoRedoRecorder.BeginGroup();
                        this.undoRedoRecorder.RecordNodeModificationForUndo(deltaNodes.ModifiedNodes);
                        //this.undoRedoRecorder.RecordEdgeModificationForUndo(edgeController.FindEdgeConnectTo(node));
                        ((FunctionNode)node).ChangeConstructor(selectedItem.QualifiedName, selectedItem.ArgumentTypes, selectedItem.ArgumentNames);
                        this.undoRedoRecorder.EndGroup();
                        //After ChangeConstructor() is executed, the nodes in the nodeToModify would already be modified
                        this.SynchronizeToLiveRunner(deltaNodes);
                    }
                    else if (itemType == LibraryItem.MemberType.InstanceProperty)
                    {
                        deltaNodes.AppendToRemovedNodes(node);
                        deltaNodes.AppendToModifiedNodes(this.FindAssociatedNodesFromNodes(deltaNodes.RemovedNodes));

                        newNode = this.CreatePropertyNode(mouseX, mouseY, selectedItem.Assembly, selectedItem.QualifiedName, selectedItem.ArgumentTypes);
                        deltaNodes.AppendToAddedNodes(newNode);

                        this.undoRedoRecorder.BeginGroup();
                        this.undoRedoRecorder.RecordRuntimeStatesForUndo(this.graphProperties.RuntimeStates);
                        this.undoRedoRecorder.RecordNodeDeletionForUndo(deltaNodes.RemovedNodes);
                        this.undoRedoRecorder.RecordNodeModificationForUndo(deltaNodes.ModifiedNodes);
                        this.TransferInformationFromMethodToProperty(node, newNode);
                        this.undoRedoRecorder.RecordNodeCreationForUndo(deltaNodes.AddedNodes);
                        this.DeleteNodes(deltaNodes.RemovedNodes);
                        this.undoRedoRecorder.EndGroup();

                        //After DeleteNodes() is executed, the nodes in the nodeToModify would already be modified
                        this.SynchronizeToLiveRunner(deltaNodes);
                    }
                    else if (itemType == LibraryItem.MemberType.InstanceMethod)
                    {
                        deltaNodes.AppendToModifiedNodes(node);
                        deltaNodes.AppendToModifiedNodes(FindAssociatedNodesFromNodes(deltaNodes.ModifiedNodes));

                        this.undoRedoRecorder.BeginGroup();
                        this.undoRedoRecorder.RecordNodeModificationForUndo(deltaNodes.ModifiedNodes);
                        ((FunctionNode)node).ChangeMethod(selectedItem.QualifiedName, selectedItem.ArgumentTypes);
                        this.undoRedoRecorder.EndGroup();

                        //After ChangeConstructor() is executed, the nodes in the nodeToModify would already be modified
                        this.SynchronizeToLiveRunner(deltaNodes);
                    }
                }
            }

            this.UpdateDirtyNodes();
            edgeController.UpdateEdgeConnectTo(node);
            return(true);
        }
Beispiel #3
0
        internal EdgeConnectionFlag AttemptConnectEdge(VisualNode node, NodePart nodePart, int index, out List<IVisualNode> nodeToModify)
        {
            nodeToModify = new List<IVisualNode>();

            connectNodeId = uint.MaxValue;
            connectSlotId = uint.MaxValue;
            connectSlotType = SlotType.None;
            SlotType startSlotType = SlotType.None;

            if (node != null)
            {
                connectNodeId = node.NodeId;

                if (graphController.CurrentDragState == DragState.CurveDrawing)
                {
                    if (currentlySelectedNodeId == connectNodeId)
                        return EdgeConnectionFlag.None;

                    startSlotType = currentlySelectedSlotType;
                }
                else
                {
                    foreach (uint slotId in reconnectingSlots)   //try to connect any of the reconnecting node
                    {
                        if (connectNodeId == graphController.GetSlot(slotId).Owners.Last())
                            return EdgeConnectionFlag.None;
                    }

                    if (graphController.GetSlot(lastConnectedSlotId).SlotType == SlotType.Output)
                        startSlotType = SlotType.Input;
                    else
                        startSlotType = SlotType.Output;
                }

                if (nodePart == NodePart.InputSlot || nodePart == NodePart.InputLabel || nodePart == NodePart.ReplicationGuide)
                {
                    connectSlotType = SlotType.Input;
                    connectSlotId = node.GetInputSlot(index);
                }
                else if (nodePart == NodePart.OutputSlot || (nodePart == NodePart.Text && node.VisualType != NodeType.CodeBlock)) // user can only connect to the output slot of the CBN
                {
                    connectSlotType = SlotType.Output;
                    connectSlotId = node.GetOutputSlot(index);
                }
                else if (node.VisualType == NodeType.Identifier && nodePart == NodePart.Caption)
                {
                    if (startSlotType == SlotType.Output)
                    {
                        connectSlotType = SlotType.Input;
                        connectSlotId = node.GetInputSlot(0);
                    }
                    else if (startSlotType == SlotType.Input)
                    {
                        connectSlotType = SlotType.Output;
                        connectSlotId = node.GetOutputSlot(0);
                    }
                }
            }

            if (graphController.CurrentDragState == DragState.CurveDrawing)
            {
                if (connectSlotId == 0 || connectSlotId == uint.MaxValue)
                    return EdgeConnectionFlag.None;
                if (currentlySelectedSlotType == connectSlotType)
                    return EdgeConnectionFlag.Illegal;

                // Check if these is a edge between the two slots already
                if (startSlotType == SlotType.Input)
                {
                    this.inputSlotId = currentlySelectedSlotId;
                    this.outputSlotId = connectSlotId;
                }
                else
                {
                    this.inputSlotId = connectSlotId;
                    this.outputSlotId = currentlySelectedSlotId;
                }

                var entry = edgeCollection.FirstOrDefault(x => IsAdded(x.Value));
                if ((edgeCollection.Count() != 0) && (entry.Value != null))
                    return EdgeConnectionFlag.None;

                nodeToModify.Add(graphController.GetVisualNode(currentlySelectedNodeId));
                nodeToModify.Add(node);

                //check if it is a edge replace(the input slot is connect to other node already)
                if (FindEdgeToBeReplaced(out edgeToBeReplaced))
                {
                    nodeToModify.Add(graphController.GetVisualNode
                                            (graphController.GetSlot(edgeToBeReplaced.StartSlotId).Owners.Last()));
                    nodeToModify.Add(graphController.GetVisualNode
                                            (graphController.GetSlot(edgeToBeReplaced.EndSlotId).Owners.Last()));
                }
                return EdgeConnectionFlag.NewEdge;
            }
            else
            {
                nodeToModify.Add(graphController.GetVisualNode
                                            (graphController.GetSlot(lastConnectedSlotId).Owners.Last()));
                foreach (uint slotId in reconnectingSlots)
                {
                    nodeToModify.Add(graphController.GetVisualNode
                                        (graphController.GetSlot(slotId).Owners.Last()));
                }

                if (connectSlotId == 0 || connectSlotId == uint.MaxValue)
                    return EdgeConnectionFlag.None;
                if (connectSlotType != graphController.GetSlot(lastConnectedSlotId).SlotType)
                    return EdgeConnectionFlag.Illegal;

                if (lastConnectedSlotId == connectSlotId) // node modification is needed only when the it reconnect to different slot
                {
                    nodeToModify = new List<IVisualNode>();
                }
                else
                {
                    nodeToModify.Add(node);

                    //check if it is a edge replace(the input slot is connect to other node already)
                    if (FindEdgeToBeReplaced(reconnectingSlots[0], out edgeToBeReplaced))
                    {
                        if (!reconnectingEdges.Contains(edgeToBeReplaced.EdgeId))
                        {
                            nodeToModify.Add(graphController.GetVisualNode
                                                    (graphController.GetSlot(edgeToBeReplaced.StartSlotId).Owners.Last()));
                            nodeToModify.Add(graphController.GetVisualNode
                                                    (graphController.GetSlot(edgeToBeReplaced.EndSlotId).Owners.Last()));
                        }
                    }
                }

                return EdgeConnectionFlag.ReconnectEdge;
            }
        }