From d871b7bec44aeea0e3f2e8b08a44a934ce4591b1 Mon Sep 17 00:00:00 2001 From: Thor Brigsted Date: Wed, 24 Jan 2018 12:23:12 +0100 Subject: [PATCH] Added node box selection --- Scripts/Editor/NodeEditorAction.cs | 50 +++++++++++++++++++----------- Scripts/Editor/NodeEditorGUI.cs | 28 +++++++++++++++++ 2 files changed, 60 insertions(+), 18 deletions(-) diff --git a/Scripts/Editor/NodeEditorAction.cs b/Scripts/Editor/NodeEditorAction.cs index e3499a9..6e5e035 100644 --- a/Scripts/Editor/NodeEditorAction.cs +++ b/Scripts/Editor/NodeEditorAction.cs @@ -4,23 +4,21 @@ using UnityEngine; namespace XNodeEditor { public partial class NodeEditorWindow { - + public enum NodeActivity { Idle, HoldHeader, DragHeader, HoldGrid, DragGrid } + public static NodeActivity currentActivity = NodeActivity.Idle; public static bool isPanning { get; private set; } public static Vector2[] dragOffset; - //private bool IsDraggingNode { get { return draggedNode != null; } } private bool IsDraggingPort { get { return draggedOutput != null; } } private bool IsHoveringPort { get { return hoveredPort != null; } } private bool IsHoveringNode { get { return hoveredNode != null; } } - public bool CanDragNodeHeader { get; private set; } - public bool DidDragNodeHeader { get; private set; } private XNode.Node hoveredNode = null; - - //[NonSerialized] private XNode.Node draggedNode = null; [NonSerialized] private XNode.NodePort hoveredPort = null; [NonSerialized] private XNode.NodePort draggedOutput = null; [NonSerialized] private XNode.NodePort draggedOutputTarget = null; private Rect nodeRects; + private Vector2 dragBoxStart; + private UnityEngine.Object[] preBoxSelection; public void Controls() { wantsMouseMove = true; @@ -43,7 +41,7 @@ namespace XNodeEditor { draggedOutputTarget = null; } Repaint(); - } else if (CanDragNodeHeader) { + } else if (currentActivity == NodeActivity.HoldHeader || currentActivity == NodeActivity.DragHeader) { for (int i = 0; i < Selection.objects.Length; i++) { if (Selection.objects[i] is XNode.Node) { XNode.Node node = Selection.objects[i] as XNode.Node; @@ -54,7 +52,17 @@ namespace XNodeEditor { } } } - DidDragNodeHeader = true; + currentActivity = NodeActivity.DragHeader; + Repaint(); + } else if (currentActivity == NodeActivity.HoldGrid) { + currentActivity = NodeActivity.DragGrid; + preBoxSelection = Selection.objects; + dragBoxStart = WindowToGridPosition(e.mousePosition); + Repaint(); + } else if (currentActivity == NodeActivity.DragGrid) { + foreach (XNode.Node node in graph.nodes) { + + } Repaint(); } } else if (e.button == 1 || e.button == 2) { @@ -90,8 +98,7 @@ namespace XNodeEditor { if (!Selection.Contains(hoveredNode)) SelectNode(hoveredNode, e.control || e.shift); else if (e.control || e.shift) DeselectNode(hoveredNode); e.Use(); - DidDragNodeHeader = false; - CanDragNodeHeader = true; + currentActivity = NodeActivity.HoldHeader; dragOffset = new Vector2[Selection.objects.Length]; for (int i = 0; i < dragOffset.Length; i++) { if (Selection.objects[i] is XNode.Node) { @@ -102,7 +109,8 @@ namespace XNodeEditor { } // If mousedown on grid background, deselect all else if (!IsHoveringNode) { - Selection.activeObject = null; + currentActivity = NodeActivity.HoldGrid; + if (!e.control && !e.shift) Selection.activeObject = null; } } break; @@ -121,10 +129,8 @@ namespace XNodeEditor { draggedOutput = null; draggedOutputTarget = null; EditorUtility.SetDirty(graph); - Repaint(); AssetDatabase.SaveAssets(); - } else if (CanDragNodeHeader) { - CanDragNodeHeader = false; + } else if (currentActivity == NodeActivity.DragHeader) { AssetDatabase.SaveAssets(); } else if (!IsHoveringNode) { // If click outside node, release field focus @@ -132,19 +138,20 @@ namespace XNodeEditor { GUIUtility.hotControl = 0; GUIUtility.keyboardControl = 0; } - Repaint(); AssetDatabase.SaveAssets(); } // If click node header, select single node. - if (IsHoveringNode && !DidDragNodeHeader && IsHoveringTitle(hoveredNode) && !(e.control || e.shift)) { + if (currentActivity == NodeActivity.HoldHeader && !(e.control || e.shift)) { SelectNode(hoveredNode, false); - Repaint(); } + + Repaint(); + currentActivity = NodeActivity.Idle; } else if (e.button == 1) { if (!isPanning) { if (IsHoveringNode && IsHoveringTitle(hoveredNode)) { - if (!Selection.Contains(hoveredNode)) SelectNode(hoveredNode,false); + if (!Selection.Contains(hoveredNode)) SelectNode(hoveredNode, false); ShowNodeContextMenu(); } else if (!IsHoveringNode) { ShowGraphContextMenu(); @@ -158,6 +165,13 @@ namespace XNodeEditor { else if (e.keyCode == KeyCode.D && e.control) DublicateSelectedNodes(); Repaint(); break; + case EventType.Ignore: + // If release mouse outside window + if (e.rawType == EventType.MouseUp && currentActivity == NodeActivity.DragGrid) { + Repaint(); + currentActivity = NodeActivity.Idle; + } + break; } } diff --git a/Scripts/Editor/NodeEditorGUI.cs b/Scripts/Editor/NodeEditorGUI.cs index 0153965..32232f0 100644 --- a/Scripts/Editor/NodeEditorGUI.cs +++ b/Scripts/Editor/NodeEditorGUI.cs @@ -21,6 +21,7 @@ namespace XNodeEditor { DrawConnections(); DrawDraggedConnection(); DrawNodes(); + DrawBox(); DrawTooltip(); GUI.matrix = m; @@ -71,6 +72,17 @@ namespace XNodeEditor { GUI.DrawTextureWithTexCoords(rect, crossTex, new Rect(tileOffset + new Vector2(0.5f, 0.5f), tileAmount)); } + public void DrawBox() { + if (currentActivity == NodeActivity.DragGrid) { + Vector2 curPos = WindowToGridPosition(Event.current.mousePosition); + Vector2 size = curPos - dragBoxStart; + Rect r = new Rect(dragBoxStart, size); + r.position = GridToWindowPosition(r.position); + r.size /= zoom; + Handles.DrawSolidRectangleWithOutline(r, new Color(0, 0, 0, 0.1f), new Color(1, 1, 1, 0.6f)); + } + } + public static bool DropdownButton(string name, float width) { return GUILayout.Button(name, EditorStyles.toolbarDropDown, GUILayout.Width(width)); } @@ -201,6 +213,8 @@ namespace XNodeEditor { hoveredPort = null; } + List preSelection = new List(preBoxSelection); + //Save guiColor so we can revert it Color guiColor = GUI.color; for (int n = 0; n < graph.nodes.Count; n++) { @@ -268,6 +282,19 @@ namespace XNodeEditor { Rect windowRect = new Rect(nodePos, nodeSize); if (windowRect.Contains(mousePos)) hoveredNode = node; + //If dragging a selection box, add nodes inside to selection + if (currentActivity == NodeActivity.DragGrid) { + Vector2 startPos = GridToWindowPosition(dragBoxStart); + Vector2 size = (mousePos - startPos) / zoom; + Rect r = new Rect(dragBoxStart, size); + Vector2 rpos = GridToWindowPosition(r.position); + if (size.x < 0) { rpos.x += size.x; size.x = Mathf.Abs(size.x); } + if (size.y < 0) { rpos.y += size.y; size.y = Mathf.Abs(size.y); } + r.position = rpos; + r.size = size; + if (windowRect.Overlaps(r)) preSelection.Add(node); + } + //Check if we are hovering any of this nodes ports //Check input ports foreach (XNode.NodePort input in node.Inputs) { @@ -288,6 +315,7 @@ namespace XNodeEditor { GUILayout.EndArea(); } + if (e.type != EventType.Layout && currentActivity == NodeActivity.DragGrid) Selection.objects = preSelection.ToArray(); EndZoomed(position, zoom); //If a change in hash is detected in the selected node, call OnValidate method.