Exemplo n.º 1
0
        public override void OnProcess(Event e)
        {
            if (m_menu != null)
            {
                m_menu.ShowAsContext();
                m_menu = null;
            }


            if (e.IsMouseDown(MouseButton.Right) && e.IsMouseInsideRect(canvas.unscaledRect))
            {
                for (int i = 0; i < canvas.nodes.Length; i++)
                {
                    Node             currentNode = canvas.nodes[i];
                    ConnectionPort[] nodePorts   = currentNode.ports;

                    for (int j = 0; j < nodePorts.Length; j++)
                    {
                        ConnectionPort currentPort = nodePorts[j];

                        if (!currentNode.isHidden && currentPort.rect.Contains(canvas.mousePosition))
                        {
                            m_menu = new GenericMenu();

                            // save values.
                            ConnectionPort   portToDisconnect = currentPort;
                            ConnectionPort[] oldConnections   = portToDisconnect.connectedPorts;
                            string           itemName         = currentPort.connectionCount > 1 ? "Remove Connections" : "Remove Connection";
                            string           recordTitle      = "All Connections of the port: [" + currentPort.name + "] of the node: [" + currentPort.node.name + "] were removed";


                            if (currentPort.hasConnections)
                            {
                                m_menu.AddItem(new GUIContent(itemName), false, () => {
                                    GraphUndo.RecordAndPerform(recordTitle,
                                                               () => { Serializer.DisconnectAllPorts(portToDisconnect); },
                                                               () => {
                                        for (int p = 0; p < oldConnections.Length; p++)
                                        {
                                            Serializer.ConnectPorts(portToDisconnect, oldConnections[p]);
                                        }
                                    });
                                });
                            }
                            else
                            {
                                m_menu.AddDisabledItem(new GUIContent(itemName), false);
                            }

                            e.Use();
                            return;
                        }
                    }
                }
            }
        }
        void ShowCreateNodeMenu(Vector2 nodePosition)
        {
            Vector2 position = nodePosition;

            if (canvas.snapNodesOnGrid)
            {
                position = canvas.ConvertToSnapPosition(position);
            }

            m_nodeMenu = new GenericMenu();

            Type[] nodeTypesToAdd = ReflectionUtility.LoadClassTypes <Node, CreateNodeMenu> ();

            for (int i = 0; i < nodeTypesToAdd.Length; i++)
            {
                Type nodeTypeToAdd = nodeTypesToAdd[i];

                CreateNodeMenu createNodeMenu = nodeTypeToAdd.GetAttribute <CreateNodeMenu> ();

                // Normally this cannot happen.
                if (createNodeMenu == null)
                {
                    Debug.LogWarning("The node [" + nodeTypeToAdd.FullName + "] has no CreateNodeMenuAttribute");
                }
                else
                {
                    m_nodeMenu.AddItem(new GUIContent(createNodeMenu.path), false, () => {
                        AIController controller = graph.controller;
                        Node node     = createNodeMenu.CreateNew(nodeTypeToAdd);
                        node.position = position;
                        Serializer.AddNewNodeToController(controller, node);
                        graph.Repaint();

                        GraphUndo.Record("Add new node [" + node.name + "]",
                                         () => {
                            Serializer.RemoveNodeFromController(controller, node, false);
                            graph.Repaint();
                        },
                                         () => {
                            Serializer.RestoreNodeToController(controller, node, null);
                            graph.Repaint();
                        });
                    });
                }
            }
        }
        void DrawToolbarGUI(float width)
        {
            Rect rect               = new Rect(0, 0, width, Styles.toolbarHeight);
            Rect toggleRect         = new Rect(0, 0, 90, rect.height);
            Rect clearGraphUndoRect = new Rect(toggleRect.xMax + 1, 0, 45, rect.height);
            Rect clearAllUndoRect   = new Rect(clearGraphUndoRect.xMax - 1, 0, 60, rect.height);
            Rect plusRect           = new Rect(rect.width - 20 - Styles.scrollbarWidth, 0, 20, rect.height);
            Rect minusRect          = new Rect(plusRect.x - 20 - 1, 0, 20, rect.height);

            EditorGUI.Toolbar(rect, false, true, false, true);

            m_showUnityRecords = EditorGUI.Toggle(toggleRect, m_showUnityRecords, "Unity Records");

            GUI.enabled = GraphUndo.hasUndo || GraphUndo.hasRedo;
            if (EditorGUI.Button(clearGraphUndoRect, "Clear"))
            {
                GraphUndo.Clear();
            }

            GUI.enabled = GraphUndo.hasUnityUndo || GraphUndo.hasUnityRedo;
            if (EditorGUI.Button(clearAllUndoRect, "Clear All", Styles.clearAllButtonHoverColor))
            {
                if (EditorUtility.DisplayDialog(clearUnityHistoryTitle, clearUnityHistoryMessage, "Clear", "Don't Clear"))
                {
                    GraphUndo.ClearAll();
                }
            }

            GUI.enabled = GraphUndo.hasUnityUndo;
            if (EditorGUI.Button(minusRect, "<"))
            {
                UnityEditor.Undo.PerformUndo();
            }

            GUI.enabled = GraphUndo.hasUnityRedo;
            if (EditorGUI.Button(plusRect, ">"))
            {
                UnityEditor.Undo.PerformRedo();
            }

            GUI.enabled = true;
        }
        public override void OnProcess(Event e)
        {
            if (m_menu != null)
            {
                m_menu.ShowAsContext();
                m_menu = null;
            }

            if (m_port1 != null && m_port2 != null)
            {
                ConnectionPort port1 = m_port1;
                ConnectionPort port2 = m_port2;
                m_port1 = null;
                m_port2 = null;

                m_menu = new GenericMenu();
                m_menu.AddItem(new GUIContent("Delete Transition"), false, () => {
                    string recordTitle = "Connection removed: [" + port1.node.name + " : " + port1.name + "] -> [" + port2.node.name + " : " + port2.name + "]";
                    GraphUndo.RecordAndPerform(recordTitle,
                                               () => { Serializer.DisconnectPorts(port1, port2); },
                                               () => { Serializer.ConnectPorts(port1, port2); });
                });
            }
        }
Exemplo n.º 5
0
        void EditorApplicationOnPlayModeStateChanged(PlayModeStateChange state)
        {
            switch (state)
            {
            case PlayModeStateChange.EnteredEditMode:
                    #if GRAPH_DEBUG
                Debug.Log("[AI Graph]: Enter edit mode");
                    #endif

                // If the graph enters edit mode.
                // Try to load the current selected controller
                // Load the controller before the edit mode was exited.
                // Set the last toggle index if it was node parameter or exposed parameter,
                // and the current isn't for the history.
                if (!TryLoadSelectedController())
                {
                    LoadController(controllerBeforeEditModeExited, aiBehaviourBeforeEditModeExited, true);
                }

                if (m_leftPanelSelectedToggleIndexBeforeEditModeExited == 0 || m_leftPanelSelectedToggleIndexBeforeEditModeExited == 1 && m_leftPanelSelectedToggleIndex != 2)
                {
                    m_leftPanelSelectedToggleIndex = m_leftPanelSelectedToggleIndexBeforeEditModeExited;
                }

                break;

            case PlayModeStateChange.ExitingEditMode:
                    #if GRAPH_DEBUG
                Debug.Log("[AI Graph]: Exit edit mode: Save current controller");
                    #endif

                // If the graph wants to exiting the edit mode,
                // save the current controller and left panel toggle index.
                controllerBeforeEditModeExited  = controller;
                aiBehaviourBeforeEditModeExited = aiBehaviour;
                m_leftPanelSelectedToggleIndexBeforeEditModeExited = m_leftPanelSelectedToggleIndex;

                // We need to clear the undo list because of unity's serialization,
                // we are not able to serialize the anonymous action delegates.
                GraphUndo.Clear();

                // Save and cleanup all modified controllers.
                // Same problem of serialization. We cannot go back to a further point.
                Serializer.CleanupAll();

                break;

            case PlayModeStateChange.EnteredPlayMode:
                    #if GRAPH_DEBUG
                Debug.Log("[AI Graph]: Enter play mode");
                    #endif

                // If the graph entered play mode,
                // try to load the current selected controller.
                // If no controller is selected check if the loaded
                // ai has a runtimeController and load that.
                // Else load the loaded controller or null if no one is loaded.
                if (!TryLoadSelectedController())
                {
                    if (aiBehaviour != null)
                    {
                        if (aiBehaviour.runtimeController != null)
                        {
                            LoadController(aiBehaviour.runtimeController, aiBehaviour, true);
                        }
                    }
                    else
                    {
                        LoadController(controller, null, true);
                    }
                }

                break;

            case PlayModeStateChange.ExitingPlayMode:
                    #if GRAPH_DEBUG
                Debug.Log("[AI Graph]: Exit play mode");
                    #endif

                // If we modified runtimeController,
                // clear the undo-list because they are not persistent and we cannot go back.
                GraphUndo.Clear();
                break;
            }
        }
        public override void OnProcess(Event e)
        {
            // select port
            if (e.IsMouseDown(MouseButton.Left) && m_selectedPort == null && e.IsMouseInsideRect(canvas.unscaledRect))
            {
                for (int i = 0; i < canvas.nodes.Length; i++)
                {
                    Node currentNode = canvas.nodes[i];

                    if (currentNode.isHidden)
                    {
                        continue;
                    }

                    ConnectionPort[] currentNodePorts = currentNode.ports;

                    for (int j = 0; j < currentNodePorts.Length; j++)
                    {
                        ConnectionPort currentNodePort = currentNodePorts[j];

                        if (!currentNodePort.isHidden && currentNodePort.rect.Contains(canvas.mousePosition))
                        {
                            m_selectedPort      = currentNodePort;
                            canvas.selectedPort = currentNodePort;

                            break;
                        }
                    }

                    if (m_selectedPort != null)
                    {
                        e.Use();
                        break;
                    }
                }
            }


            // drag port
            if (e.IsMouseDrag(MouseButton.Left) && m_selectedPort != null)
            {
                graph.Repaint();
                e.Use();
            }

            // connect
            if (e.IsMouseUp(MouseButton.Left) && m_selectedPort != null)
            {
                bool connectionExecuted = false;

                for (int i = 0; i < canvas.nodes.Length; i++)
                {
                    Node currentNode = canvas.nodes[i];

                    if (currentNode.isHidden)
                    {
                        continue;
                    }

                    ConnectionPort[] currentNodePorts = currentNode.ports;

                    for (int j = 0; j < currentNodePorts.Length; j++)
                    {
                        ConnectionPort currentNodePort = currentNodePorts[j];

                        if (!currentNodePort.isHidden && currentNodePort.rect.Contains(canvas.mousePosition))
                        {
                            ConnectionPort fromPort = m_selectedPort;
                            ConnectionPort toPort   = currentNodePort;

                            bool connectionSuccess = Serializer.ConnectPorts(fromPort, toPort);

                            if (connectionSuccess)
                            {
                                GraphUndo.Record(fromPort.node.name + " connected to " + toPort.node.name,
                                                 () => { Serializer.DisconnectPorts(fromPort, toPort); },
                                                 () => { Serializer.ConnectPorts(fromPort, toPort); });
                            }

                            connectionExecuted = true;
                            break;
                        }
                    }

                    if (connectionExecuted)
                    {
                        break;
                    }
                }

                m_selectedPort      = null;
                canvas.selectedPort = null;
                e.Use();
            }
        }
Exemplo n.º 7
0
        public override void OnProcess(Event e)
        {
            if (m_menu != null)
            {
                m_menu.ShowAsContext();
                m_menu = null;
            }

            if (e.IsMouseDown(MouseButton.Right) && e.IsMouseInsideRect(canvas.unscaledRect))
            {
                for (int i = 0; i < canvas.nodes.Length; i++)
                {
                    Node currentNode = canvas.nodes[i];

                    if (currentNode.isHidden)
                    {
                        continue;
                    }

                    if (currentNode.rect.Contains(canvas.mousePosition))
                    {
                        for (int j = 0; j < currentNode.ports.Length; j++)
                        {
                            if (currentNode.ports[j].rect.Contains(canvas.mousePosition))
                            {
                                return;
                            }
                        }

                        m_menu = new GenericMenu();

                        // save variables
                        Node            node        = currentNode;
                        AIController    controller  = graph.controller;
                        NodeRestoreData restoreData = Serializer.CreateNodeRestoreData(node);


                        // Add remove item if its not entry or any state.
                        // Else add disabled remove item.
                        if (node.IsEntryState() || node.IsAnyState())
                        {
                            m_menu.AddDisabledItem(new GUIContent("Delete"), false);
                        }
                        else
                        {
                            m_menu.AddItem(new GUIContent("Delete"), false, () => {
                                GraphUndo.RecordAndPerform("Delete node [" + node.name + "]",
                                                           () => { Serializer.RemoveNodeFromController(controller, node, false); },
                                                           () => { Serializer.RestoreNodeToController(controller, node, restoreData); });
                            });
                        }

                        // Add remove all connections item if the node has connections.
                        // Else add disabled remove all connections item.

                        // calculate connection count and save old connections.
                        int connectionsCount = 0;
                        Dictionary <ConnectionPort, ConnectionPort[]> oldConnections = new Dictionary <ConnectionPort, ConnectionPort[]> ();
                        foreach (ConnectionPort port in node.ports)
                        {
                            connectionsCount += port.connectionCount;
                            oldConnections.Add(port, port.connectedPorts);
                        }

                        string itemName = connectionsCount > 1 ? "Remove all connections" : "Remove connection";

                        if (connectionsCount == 0)
                        {
                            m_menu.AddDisabledItem(new GUIContent(itemName), false);
                        }
                        else
                        {
                            m_menu.AddItem(new GUIContent(itemName), false, () => {
                                GraphUndo.RecordAndPerform(itemName + " from node [" + node.name + "]",
                                                           () => { Serializer.DisconnectAllPorts(node); },
                                                           () => {
                                    foreach (ConnectionPort fromPort in oldConnections.Keys)
                                    {
                                        foreach (ConnectionPort toPort in oldConnections[fromPort])
                                        {
                                            Serializer.ConnectPorts(fromPort, toPort);
                                        }
                                    }
                                });
                            });
                        }

                        e.Use();
                    }
                }
            }
        }
Exemplo n.º 8
0
        public override void OnProcess(Event e)
        {
            // Hover, select and drag start can only start if the mouse is in the canvas and drag and multi selection is not started.
            if (e.IsMouseInsideRect(canvas.unscaledRect) && !m_dragStarted && !m_multiSelectionStarted)
            {
                bool nodeSelected = false;
                bool nodeHovered  = false;

                // if left mouse button is down, save the selection position,
                // all current selected nodes in the canvas and clear the current selected nodes.
                if (e.IsMouseDown(MouseButton.Left))
                {
                    m_selectionStartPosition     = canvas.mousePosition;
                    m_currentSelectedCanvasNodes = canvas.GetSelectedNodes();
                    m_selectedNodes.Clear();
                }

                for (int i = 0; i < canvas.nodes.Length; i++)
                {
                    Node node = canvas.nodes[i];

                    if (node.isHidden)
                    {
                        continue;
                    }

                    if (!nodeHovered && node.rect.Contains(canvas.mousePosition))
                    {
                        // set the node under the mouse to the hover state.
                        // But only if the shift key is not clicked. Or the control key is clicked.
                        if (e.control || !e.shift)
                        {
                            canvas.SetHoveredNode(node);
                            nodeHovered = true;
                        }

                        if (e.IsMouseDown(MouseButton.Left))
                        {
                            // check if a port is under the mouse.
                            ConnectionPort[] nodePorts = node.ports;
                            for (int j = 0; j < nodePorts.Length; j++)
                            {
                                if (nodePorts[j].rect.Contains(canvas.mousePosition))
                                {
                                    // node drag cannot start.
                                    // select the current node and return.
                                    canvas.SetSelectedNode(node);
                                    return;
                                }
                            }

                            // a node is selected.
                            nodeSelected          = true;
                            m_currentSelectedNode = node;

                            if (e.control)
                            {
                                // if the control key is down add all current selected nodes in the canvas
                                // and add the current selected node if its not in the current selected node list.
                                m_selectionWithControlKey = true;
                                m_selectedNodes.AddRange(m_currentSelectedCanvasNodes);
                                if (!m_selectedNodes.Contains(node))
                                {
                                    m_selectedNodes.Add(node);
                                }
                            }
                            else if (e.shift)
                            {
                                // If the shift key is down add all current selected nodes in the canvas
                                // and remove the current selected if it's in the list.
                                m_selectionWithShiftKey = true;
                                m_selectedNodes.AddRange(m_currentSelectedCanvasNodes);
                                if (m_selectedNodes.Contains(node))
                                {
                                    m_selectedNodes.Remove(node);
                                }
                            }
                            else
                            {
                                // If no other control key is down, two different
                                // modes can be performed. If the current selected node
                                // is already selected, the user want to drag all current selected canvas nodes
                                // or if he don't drag the current selected node, he only want to select this node.
                                //
                                // If the current selected node is not on the canvas selected, the user want to
                                // select and maybe drag only the current selected node.
                                if (m_currentSelectedCanvasNodes.Contains(node))
                                {
                                    m_selectedNodes.AddRange(m_currentSelectedCanvasNodes);
                                }
                                else
                                {
                                    m_selectedNodes.Add(node);
                                }
                            }

                            // set all drag start positions of the current selected nodes.
                            m_nodeDragStartPositions = new Vector2[m_selectedNodes.Count];
                            for (int j = 0; j < m_nodeDragStartPositions.Length; j++)
                            {
                                m_nodeDragStartPositions[j] = m_selectedNodes[j].position;
                            }

                            // select nodes visually.
                            canvas.SetSelectedNodes(m_selectedNodes.ToArray());

                            // start drag if currently more than one node is selected.
                            m_dragStarted = m_selectedNodes.Count > 0;

                            GUI.SetNextControlName("");
                            GUI.FocusControl("");

                            e.Use();
                            break;
                        }
                        else if (e.IsMouseDown(MouseButton.Right))
                        {
                            // select node for the context selection.
                            canvas.SetSelectedNode(node);
                            graph.Repaint();
                            return;
                        }
                    }
                }

                // If no node was selected, the user want to start a multi selection.
                // Or deselect all nodes.
                if (!nodeSelected && e.IsMouseDown(MouseButton.Left))
                {
                    m_multiSelectionStarted = true;

                    if (e.control)
                    {
                        m_selectionWithControlKey = true;
                    }
                    else if (e.shift)
                    {
                        m_selectionWithShiftKey = true;
                    }

                    // remove hot controls
                    GUI.SetNextControlName("");
                    GUI.FocusControl("");
                    e.Use();
                }
            }

            // handle node drag.
            if (m_dragStarted)
            {
                // drag starts only if the user moves the mouse a short distance, while the mouse is down.
                if (!m_dragPerformed && Vector2.Distance(m_selectionStartPosition, canvas.mousePosition) > 5)
                {
                    m_dragPerformed = true;
                }

                if (e.IsMouseDrag(MouseButton.Left) && m_dragPerformed)
                {
                    m_dragPerformed = true;
                    m_dragDelta     = canvas.mousePosition - m_selectionStartPosition;

                    if (canvas.snapNodesOnGrid)
                    {
                        m_dragDelta = canvas.ConvertToSnapPosition(m_dragDelta);
                    }

                    for (int i = 0; i < m_selectedNodes.Count; i++)
                    {
                        m_selectedNodes[i].position = m_nodeDragStartPositions[i] + m_dragDelta;
                    }

                    e.Use();
                }
            }

            // handle node multi selection.
            if (m_multiSelectionStarted)
            {
                Vector2 currentCanvasPosition = canvas.mousePosition;

                // rearrange the min and max position.
                float xMinCanvas = Mathf.Min(m_selectionStartPosition.x, currentCanvasPosition.x);
                float yMinCanvas = Mathf.Min(m_selectionStartPosition.y, currentCanvasPosition.y);
                float xMaxCanvas = Mathf.Max(m_selectionStartPosition.x, currentCanvasPosition.x);
                float yMaxCanvas = Mathf.Max(m_selectionStartPosition.y, currentCanvasPosition.y);

                // create the current selection rect in canvas space.
                m_multiSelectionCanvasRect = Rect.MinMaxRect(xMinCanvas, yMinCanvas, xMaxCanvas, yMaxCanvas);

                // create a selection rect in screen space (for rendering) i dont want to scale the border of this rect.
                Vector2 min = canvas.CanvasToScreenPoint(new Vector2(xMinCanvas, yMinCanvas));
                Vector2 max = canvas.CanvasToScreenPoint(new Vector2(xMaxCanvas, yMaxCanvas));
                m_multiSelectionScreenRect = Rect.MinMaxRect(min.x, min.y, max.x, max.y);


                m_selectedNodes.Clear();

                // If the user starts with control key down.
                // He want to add all nodes in the rect.
                if (m_selectionWithControlKey)
                {
                    m_selectedNodes.AddRange(m_currentSelectedCanvasNodes);

                    for (int i = 0; i < canvas.nodes.Length; i++)
                    {
                        Node node = canvas.nodes[i];
                        if (m_multiSelectionCanvasRect.Overlaps(node.rect))
                        {
                            if (!m_selectedNodes.Contains(node))
                            {
                                m_selectedNodes.Add(node);
                            }
                        }
                    }
                }

                // If the user starts with shift key down.
                // he want to remove all nodes in the rect.
                else if (m_selectionWithShiftKey)
                {
                    m_selectedNodes.AddRange(m_currentSelectedCanvasNodes);

                    for (int i = 0; i < canvas.nodes.Length; i++)
                    {
                        Node node = canvas.nodes[i];
                        if (m_multiSelectionCanvasRect.Overlaps(node.rect))
                        {
                            if (m_selectedNodes.Contains(node))
                            {
                                m_selectedNodes.Remove(node);
                            }
                        }
                    }
                }

                // The user want only select nodes in the rect.
                else
                {
                    for (int i = 0; i < canvas.nodes.Length; i++)
                    {
                        Node node = canvas.nodes[i];
                        if (m_multiSelectionCanvasRect.Overlaps(node.rect))
                        {
                            if (!m_selectedNodes.Contains(node))
                            {
                                m_selectedNodes.Add(node);
                            }
                        }
                    }
                }

                canvas.SetHoveredNodes(m_selectedNodes.ToArray());

                if (e.IsMouseDrag(MouseButton.Left))
                {
                    e.Use();
                }
            }

            if (e.IsMouseUp(MouseButton.Left, true))
            {
                // remove hot controls
//                GUI.SetNextControlName ("");
//                GUI.FocusControl ("");

                if (m_dragStarted)
                {
                    // Check if drag was performed.
                    // If drag was performed, create a record for all dragged nodes.
                    if (m_dragPerformed)
                    {
                        Node[]    finalNodesToDrag            = m_selectedNodes.ToArray();
                        Vector2[] finalNodeDragStartPositions = m_nodeDragStartPositions;
                        Vector2   finalDragDelta = m_dragDelta;

                        string undoName = finalNodesToDrag.Length > 1 ? "Move [" + finalNodesToDrag.Length + "] nodes" : "Move node [" + finalNodesToDrag[0].name + "]";

                        GraphUndo.Record(undoName,
                                         () => {
                            for (int i = 0; i < finalNodesToDrag.Length; i++)
                            {
                                finalNodesToDrag[i].position = finalNodeDragStartPositions[i];
                            }
                        },
                                         () => {
                            for (int i = 0; i < finalNodesToDrag.Length; i++)
                            {
                                finalNodesToDrag[i].position = finalNodeDragStartPositions[i] + finalDragDelta;
                            }
                        });

                        graph.controller.isDirty = true;
                        e.Use();
                    }

                    // If no drag was performed, check if a node was selected.
                    // If no node was selected, clear the selected nodes.
                    // Else check if the current selected node was selected and select only this.
                    // Or select all current selected nodes.
                    else
                    {
                        if (m_selectionWithControlKey || m_selectionWithShiftKey)
                        {
                            canvas.SetSelectedNodes(m_selectedNodes.ToArray());
                        }
                        else if (m_currentSelectedNode != null)
                        {
                            bool nodeWasNodeAlreadySelected = m_currentSelectedCanvasNodes.Contains(m_currentSelectedNode);

                            if (nodeWasNodeAlreadySelected)
                            {
                                canvas.SetSelectedNode(m_currentSelectedNode);
                            }
                            else
                            {
                                canvas.SetSelectedNodes(m_selectedNodes.ToArray());
                            }
                        }
                        else
                        {
                            canvas.ClearSelectedNodes();
                        }

                        e.Use();
                    }
                }
                else if (m_multiSelectionStarted)
                {
                    // If no node is in the multi selection rect, the user clicked in the canvas and will deselect all current selected nodes.
                    // Otherwise select all nodes, that are in the selection rect.
                    if (m_selectedNodes.Count > 0)
                    {
                        canvas.SetSelectedNodes(m_selectedNodes.ToArray());
                    }
                    else
                    {
                        canvas.ClearSelectedNodes();
                    }

                    e.Use();
                }

                // Reset all fields.
                m_currentSelectedNode     = null;
                m_dragStarted             = false;
                m_dragPerformed           = false;
                m_multiSelectionStarted   = false;
                m_selectionWithControlKey = false;
                m_selectionWithShiftKey   = false;
            }
        }