diff --git a/Scripts/Editor/NodeEditorAction.cs b/Scripts/Editor/NodeEditorAction.cs
index 1caecd9..827b3de 100644
--- a/Scripts/Editor/NodeEditorAction.cs
+++ b/Scripts/Editor/NodeEditorAction.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
-using XNodeEditor.Internal;
namespace XNodeEditor {
public partial class NodeEditorWindow {
@@ -12,8 +11,6 @@ namespace XNodeEditor {
public static bool isPanning { get; private set; }
public static Vector2[] dragOffset;
- public static XNode.Node[] copyBuffer = null;
-
private bool IsDraggingPort { get { return draggedOutput != null; } }
private bool IsHoveringPort { get { return hoveredPort != null; } }
private bool IsHoveringNode { get { return hoveredNode != null; } }
@@ -30,23 +27,32 @@ namespace XNodeEditor {
private RerouteReference[] preBoxSelectionReroute;
private Rect selectionBox;
private bool isDoubleClick = false;
- private Vector2 lastMousePosition;
+ private bool stoppedDraggingPort = true;
+ private XNode.NodePort draggedPort;
+
+
+ private struct RerouteReference {
+ public XNode.NodePort port;
+ public int connectionIndex;
+ public int pointIndex;
+
+ public RerouteReference(XNode.NodePort port, int connectionIndex, int pointIndex) {
+ this.port = port;
+ this.connectionIndex = connectionIndex;
+ this.pointIndex = pointIndex;
+ }
+
+ public void InsertPoint(Vector2 pos) { port.GetReroutePoints(connectionIndex).Insert(pointIndex, pos); }
+ public void SetPoint(Vector2 pos) { port.GetReroutePoints(connectionIndex) [pointIndex] = pos; }
+ public void RemovePoint() { port.GetReroutePoints(connectionIndex).RemoveAt(pointIndex); }
+ public Vector2 GetPoint() { return port.GetReroutePoints(connectionIndex) [pointIndex]; }
+ }
public void Controls() {
wantsMouseMove = true;
Event e = Event.current;
switch (e.type) {
- case EventType.DragUpdated:
- case EventType.DragPerform:
- DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
- if (e.type == EventType.DragPerform) {
- DragAndDrop.AcceptDrag();
- graphEditor.OnDropObjects(DragAndDrop.objectReferences);
- }
- break;
case EventType.MouseMove:
- //Keyboard commands will not get correct mouse position from Event
- lastMousePosition = e.mousePosition;
break;
case EventType.ScrollWheel:
float oldZoom = zoom;
@@ -283,7 +289,7 @@ namespace XNodeEditor {
case EventType.KeyDown:
if (EditorGUIUtility.editingTextField) break;
else if (e.keyCode == KeyCode.F) Home();
- if (NodeEditorUtilities.IsMac()) {
+ if (IsMac()) {
if (e.keyCode == KeyCode.Return) RenameSelectedNode();
} else {
if (e.keyCode == KeyCode.F2) RenameSelectedNode();
@@ -294,18 +300,12 @@ namespace XNodeEditor {
if (e.commandName == "SoftDelete") {
if (e.type == EventType.ExecuteCommand) RemoveSelectedNodes();
e.Use();
- } else if (NodeEditorUtilities.IsMac() && e.commandName == "Delete") {
+ } else if (IsMac() && e.commandName == "Delete") {
if (e.type == EventType.ExecuteCommand) RemoveSelectedNodes();
e.Use();
} else if (e.commandName == "Duplicate") {
if (e.type == EventType.ExecuteCommand) DuplicateSelectedNodes();
e.Use();
- } else if (e.commandName == "Copy") {
- if (e.type == EventType.ExecuteCommand) CopySelectedNodes();
- e.Use();
- } else if (e.commandName == "Paste") {
- if (e.type == EventType.ExecuteCommand) PasteNodes(WindowToGridPosition(lastMousePosition));
- e.Use();
}
Repaint();
break;
@@ -319,6 +319,14 @@ namespace XNodeEditor {
}
}
+ public bool IsMac() {
+ #if UNITY_2017_1_OR_NEWER
+ return SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX;
+ #else
+ return SystemInfo.operatingSystem.StartsWith("Mac");
+ #endif
+ }
+
private void RecalculateDragOffsets(Event current) {
dragOffset = new Vector2[Selection.objects.Length + selectedReroutes.Count];
// Selected nodes
@@ -335,17 +343,10 @@ namespace XNodeEditor {
}
}
- /// Puts all selected nodes in focus. If no nodes are present, resets view and zoom to to origin
+ /// Puts all nodes in focus. If no nodes are present, resets view to
public void Home() {
- var nodes = Selection.objects.Where(o => o is XNode.Node).Cast().ToList();
- if (nodes.Count > 0) {
- Vector2 minPos = nodes.Select(x => x.position).Aggregate((x, y) => new Vector2(Mathf.Min(x.x, y.x), Mathf.Min(x.y, y.y)));
- Vector2 maxPos = nodes.Select(x => x.position + (nodeSizes.ContainsKey(x) ? nodeSizes[x] : Vector2.zero)).Aggregate((x, y) => new Vector2(Mathf.Max(x.x, y.x), Mathf.Max(x.y, y.y)));
- panOffset = -(minPos + (maxPos - minPos) / 2f);
- } else {
- zoom = 2;
- panOffset = Vector2.zero;
- }
+ zoom = 2;
+ panOffset = Vector2.zero;
}
/// Remove nodes in the graph in Selection.objects
@@ -388,60 +389,41 @@ namespace XNodeEditor {
/// Duplicate selected nodes and select the duplicates
public void DuplicateSelectedNodes() {
- // Get selected nodes which are part of this graph
- XNode.Node[] selectedNodes = Selection.objects.Select(x => x as XNode.Node).Where(x => x != null && x.graph == graph).ToArray();
- // Get top left node position
- Vector2 topLeftNode = selectedNodes.Select(x => x.position).Aggregate((x, y) => new Vector2(Mathf.Min(x.x, y.x), Mathf.Min(x.y, y.y)));
- InsertDuplicateNodes(selectedNodes, topLeftNode + new Vector2(30, 30));
- }
-
- public void CopySelectedNodes() {
- copyBuffer = Selection.objects.Select(x => x as XNode.Node).Where(x => x != null && x.graph == graph).ToArray();
- }
-
- public void PasteNodes(Vector2 pos) {
- InsertDuplicateNodes(copyBuffer, pos);
- }
-
- private void InsertDuplicateNodes(XNode.Node[] nodes, Vector2 topLeft) {
- if (nodes == null || nodes.Length == 0) return;
-
- // Get top-left node
- Vector2 topLeftNode = nodes.Select(x => x.position).Aggregate((x, y) => new Vector2(Mathf.Min(x.x, y.x), Mathf.Min(x.y, y.y)));
- Vector2 offset = topLeft - topLeftNode;
-
- UnityEngine.Object[] newNodes = new UnityEngine.Object[nodes.Length];
+ UnityEngine.Object[] newNodes = new UnityEngine.Object[Selection.objects.Length];
Dictionary substitutes = new Dictionary();
- for (int i = 0; i < nodes.Length; i++) {
- XNode.Node srcNode = nodes[i];
- if (srcNode == null) continue;
- XNode.Node newNode = graphEditor.CopyNode(srcNode);
- substitutes.Add(srcNode, newNode);
- newNode.position = srcNode.position + offset;
- newNodes[i] = newNode;
+ for (int i = 0; i < Selection.objects.Length; i++) {
+ if (Selection.objects[i] is XNode.Node) {
+ XNode.Node srcNode = Selection.objects[i] as XNode.Node;
+ if (srcNode.graph != graph) continue; // ignore nodes selected in another graph
+ XNode.Node newNode = graphEditor.CopyNode(srcNode);
+ substitutes.Add(srcNode, newNode);
+ newNode.position = srcNode.position + new Vector2(30, 30);
+ newNodes[i] = newNode;
+ }
}
// Walk through the selected nodes again, recreate connections, using the new nodes
- for (int i = 0; i < nodes.Length; i++) {
- XNode.Node srcNode = nodes[i];
- if (srcNode == null) continue;
- foreach (XNode.NodePort port in srcNode.Ports) {
- for (int c = 0; c < port.ConnectionCount; c++) {
- XNode.NodePort inputPort = port.direction == XNode.NodePort.IO.Input ? port : port.GetConnection(c);
- XNode.NodePort outputPort = port.direction == XNode.NodePort.IO.Output ? port : port.GetConnection(c);
+ for (int i = 0; i < Selection.objects.Length; i++) {
+ if (Selection.objects[i] is XNode.Node) {
+ XNode.Node srcNode = Selection.objects[i] as XNode.Node;
+ if (srcNode.graph != graph) continue; // ignore nodes selected in another graph
+ foreach (XNode.NodePort port in srcNode.Ports) {
+ for (int c = 0; c < port.ConnectionCount; c++) {
+ XNode.NodePort inputPort = port.direction == XNode.NodePort.IO.Input ? port : port.GetConnection(c);
+ XNode.NodePort outputPort = port.direction == XNode.NodePort.IO.Output ? port : port.GetConnection(c);
- XNode.Node newNodeIn, newNodeOut;
- if (substitutes.TryGetValue(inputPort.node, out newNodeIn) && substitutes.TryGetValue(outputPort.node, out newNodeOut)) {
- newNodeIn.UpdateStaticPorts();
- newNodeOut.UpdateStaticPorts();
- inputPort = newNodeIn.GetInputPort(inputPort.fieldName);
- outputPort = newNodeOut.GetOutputPort(outputPort.fieldName);
+ XNode.Node newNodeIn, newNodeOut;
+ if (substitutes.TryGetValue(inputPort.node, out newNodeIn) && substitutes.TryGetValue(outputPort.node, out newNodeOut)) {
+ newNodeIn.UpdateStaticPorts();
+ newNodeOut.UpdateStaticPorts();
+ inputPort = newNodeIn.GetInputPort(inputPort.fieldName);
+ outputPort = newNodeOut.GetOutputPort(outputPort.fieldName);
+ }
+ if (!inputPort.IsConnectedTo(outputPort)) inputPort.Connect(outputPort);
}
- if (!inputPort.IsConnectedTo(outputPort)) inputPort.Connect(outputPort);
}
}
}
- // Select the new nodes
Selection.objects = newNodes;
}
@@ -477,7 +459,27 @@ namespace XNodeEditor {
NodeEditorGUILayout.DrawPortHandle(rect, bgcol, frcol);
}
+ stoppedDraggingPort = true;
}
+ else
+ {
+ if(stoppedDraggingPort)
+ {
+ if(draggedPort != null && draggedPort.IsOutput)
+ {
+ GenericMenu menu = new GenericMenu();
+ graphEditor.AddContextMenuItems(menu, ConnectOnCreate);
+ menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
+ }
+ stoppedDraggingPort = false;
+ }
+ }
+ if (hoveredPort != null)
+ draggedPort = hoveredPort;
+ else if(draggedOutputTarget != null)
+ draggedPort = draggedOutputTarget;
+
+ Repaint();
}
bool IsHoveringTitle(XNode.Node node) {
@@ -491,5 +493,20 @@ namespace XNodeEditor {
Rect windowRect = new Rect(nodePos, new Vector2(width / zoom, 30 / zoom));
return windowRect.Contains(mousePos);
}
+ private void ConnectOnCreate(object obj = default(object))
+ {
+ if(graph.nodes.Last().Ports.Where(r => r.IsInput == true).Any(r => r.ValueType == draggedPort.ValueType))
+ draggedPort.Connect(graph.nodes.Last().Ports.Where(r => r.IsInput == true).Where(r => r.ValueType == draggedPort.ValueType).ToArray()[0]);
+ else
+ draggedPort.Connect(graph.nodes.Last().Ports.Where(r => r.IsInput == true).ToArray()[0]);
+ }
+ private bool SomeNodesSelected()
+ {
+ foreach(UnityEngine.Object obj in Selection.objects)
+ {
+ return graph.nodes.Any(r => r.Equals((XNode.Node)obj));
+ }
+ return false;
+ }
}
-}
\ No newline at end of file
+}