1
0
mirror of https://github.com/Siccity/xNode.git synced 2026-02-04 22:34:54 +08:00

Un-reverted changes made after 1.7

This commit is contained in:
Thor Brigsted 2019-09-04 15:45:39 +02:00
parent 935cc56602
commit 8c26042eef
2 changed files with 107 additions and 55 deletions

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using XNodeEditor.Internal;
namespace XNodeEditor { namespace XNodeEditor {
public partial class NodeEditorWindow { public partial class NodeEditorWindow {
@ -11,6 +12,8 @@ namespace XNodeEditor {
public static bool isPanning { get; private set; } public static bool isPanning { get; private set; }
public static Vector2[] dragOffset; public static Vector2[] dragOffset;
public static XNode.Node[] copyBuffer = null;
private bool IsDraggingPort { get { return draggedOutput != null; } } private bool IsDraggingPort { get { return draggedOutput != null; } }
private bool IsHoveringPort { get { return hoveredPort != null; } } private bool IsHoveringPort { get { return hoveredPort != null; } }
private bool IsHoveringNode { get { return hoveredNode != null; } } private bool IsHoveringNode { get { return hoveredNode != null; } }
@ -27,10 +30,10 @@ namespace XNodeEditor {
private RerouteReference[] preBoxSelectionReroute; private RerouteReference[] preBoxSelectionReroute;
private Rect selectionBox; private Rect selectionBox;
private bool isDoubleClick = false; private bool isDoubleClick = false;
private bool stoppedDraggingPort = true; private bool stoppedDraggingPort = true;
private XNode.NodePort draggedPort; private XNode.NodePort draggedPort;
private struct RerouteReference { private struct RerouteReference {
public XNode.NodePort port; public XNode.NodePort port;
public int connectionIndex; public int connectionIndex;
@ -48,11 +51,23 @@ namespace XNodeEditor {
public Vector2 GetPoint() { return port.GetReroutePoints(connectionIndex) [pointIndex]; } public Vector2 GetPoint() { return port.GetReroutePoints(connectionIndex) [pointIndex]; }
} }
private Vector2 lastMousePosition;
public void Controls() { public void Controls() {
wantsMouseMove = true; wantsMouseMove = true;
Event e = Event.current; Event e = Event.current;
switch (e.type) { 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: case EventType.MouseMove:
//Keyboard commands will not get correct mouse position from Event
lastMousePosition = e.mousePosition;
break; break;
case EventType.ScrollWheel: case EventType.ScrollWheel:
float oldZoom = zoom; float oldZoom = zoom;
@ -289,7 +304,7 @@ namespace XNodeEditor {
case EventType.KeyDown: case EventType.KeyDown:
if (EditorGUIUtility.editingTextField) break; if (EditorGUIUtility.editingTextField) break;
else if (e.keyCode == KeyCode.F) Home(); else if (e.keyCode == KeyCode.F) Home();
if (IsMac()) { if (NodeEditorUtilities.IsMac()) {
if (e.keyCode == KeyCode.Return) RenameSelectedNode(); if (e.keyCode == KeyCode.Return) RenameSelectedNode();
} else { } else {
if (e.keyCode == KeyCode.F2) RenameSelectedNode(); if (e.keyCode == KeyCode.F2) RenameSelectedNode();
@ -300,12 +315,18 @@ namespace XNodeEditor {
if (e.commandName == "SoftDelete") { if (e.commandName == "SoftDelete") {
if (e.type == EventType.ExecuteCommand) RemoveSelectedNodes(); if (e.type == EventType.ExecuteCommand) RemoveSelectedNodes();
e.Use(); e.Use();
} else if (IsMac() && e.commandName == "Delete") { } else if (NodeEditorUtilities.IsMac() && e.commandName == "Delete") {
if (e.type == EventType.ExecuteCommand) RemoveSelectedNodes(); if (e.type == EventType.ExecuteCommand) RemoveSelectedNodes();
e.Use(); e.Use();
} else if (e.commandName == "Duplicate") { } else if (e.commandName == "Duplicate") {
if (e.type == EventType.ExecuteCommand) DuplicateSelectedNodes(); if (e.type == EventType.ExecuteCommand) DuplicateSelectedNodes();
e.Use(); 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(); Repaint();
break; break;
@ -319,14 +340,6 @@ 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) { private void RecalculateDragOffsets(Event current) {
dragOffset = new Vector2[Selection.objects.Length + selectedReroutes.Count]; dragOffset = new Vector2[Selection.objects.Length + selectedReroutes.Count];
// Selected nodes // Selected nodes
@ -343,10 +356,17 @@ namespace XNodeEditor {
} }
} }
/// <summary> Puts all nodes in focus. If no nodes are present, resets view to </summary> /// <summary> Puts all selected nodes in focus. If no nodes are present, resets view and zoom to to origin </summary>
public void Home() { public void Home() {
zoom = 2; var nodes = Selection.objects.Where(o => o is XNode.Node).Cast<XNode.Node>().ToList();
panOffset = Vector2.zero; 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;
}
} }
/// <summary> Remove nodes in the graph in Selection.objects</summary> /// <summary> Remove nodes in the graph in Selection.objects</summary>
@ -389,41 +409,60 @@ namespace XNodeEditor {
/// <summary> Duplicate selected nodes and select the duplicates </summary> /// <summary> Duplicate selected nodes and select the duplicates </summary>
public void DuplicateSelectedNodes() { public void DuplicateSelectedNodes() {
UnityEngine.Object[] newNodes = new UnityEngine.Object[Selection.objects.Length]; // 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];
Dictionary<XNode.Node, XNode.Node> substitutes = new Dictionary<XNode.Node, XNode.Node>(); Dictionary<XNode.Node, XNode.Node> substitutes = new Dictionary<XNode.Node, XNode.Node>();
for (int i = 0; i < Selection.objects.Length; i++) { for (int i = 0; i < nodes.Length; i++) {
if (Selection.objects[i] is XNode.Node) { XNode.Node srcNode = nodes[i];
XNode.Node srcNode = Selection.objects[i] as XNode.Node; if (srcNode == null) continue;
if (srcNode.graph != graph) continue; // ignore nodes selected in another graph XNode.Node newNode = graphEditor.CopyNode(srcNode);
XNode.Node newNode = graphEditor.CopyNode(srcNode); substitutes.Add(srcNode, newNode);
substitutes.Add(srcNode, newNode); newNode.position = srcNode.position + offset;
newNode.position = srcNode.position + new Vector2(30, 30); newNodes[i] = newNode;
newNodes[i] = newNode;
}
} }
// Walk through the selected nodes again, recreate connections, using the new nodes // Walk through the selected nodes again, recreate connections, using the new nodes
for (int i = 0; i < Selection.objects.Length; i++) { for (int i = 0; i < nodes.Length; i++) {
if (Selection.objects[i] is XNode.Node) { XNode.Node srcNode = nodes[i];
XNode.Node srcNode = Selection.objects[i] as XNode.Node; if (srcNode == null) continue;
if (srcNode.graph != graph) continue; // ignore nodes selected in another graph foreach (XNode.NodePort port in srcNode.Ports) {
foreach (XNode.NodePort port in srcNode.Ports) { for (int c = 0; c < port.ConnectionCount; c++) {
for (int c = 0; c < port.ConnectionCount; c++) { XNode.NodePort inputPort = port.direction == XNode.NodePort.IO.Input ? port : port.GetConnection(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.NodePort outputPort = port.direction == XNode.NodePort.IO.Output ? port : port.GetConnection(c);
XNode.Node newNodeIn, newNodeOut; XNode.Node newNodeIn, newNodeOut;
if (substitutes.TryGetValue(inputPort.node, out newNodeIn) && substitutes.TryGetValue(outputPort.node, out newNodeOut)) { if (substitutes.TryGetValue(inputPort.node, out newNodeIn) && substitutes.TryGetValue(outputPort.node, out newNodeOut)) {
newNodeIn.UpdateStaticPorts(); newNodeIn.UpdateStaticPorts();
newNodeOut.UpdateStaticPorts(); newNodeOut.UpdateStaticPorts();
inputPort = newNodeIn.GetInputPort(inputPort.fieldName); inputPort = newNodeIn.GetInputPort(inputPort.fieldName);
outputPort = newNodeOut.GetOutputPort(outputPort.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; Selection.objects = newNodes;
} }
@ -501,4 +540,4 @@ namespace XNodeEditor {
draggedPort.Connect(graph.nodes.Last().Ports.Where(r => r.IsInput == true).ToArray()[0]); draggedPort.Connect(graph.nodes.Last().Ports.Where(r => r.IsInput == true).ToArray()[0]);
} }
} }
} }

View File

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEditor; using UnityEditor;
@ -38,14 +38,14 @@ namespace XNodeEditor {
if (NodeEditorUtilities.GetAttrib(type, out attrib)) // Return custom path if (NodeEditorUtilities.GetAttrib(type, out attrib)) // Return custom path
return attrib.menuName; return attrib.menuName;
else // Return generated path else // Return generated path
return ObjectNames.NicifyVariableName(type.ToString().Replace('.', '/')); return NodeEditorUtilities.NodeDefaultPath(type);
} }
/// <summary> Add items for the context menu when right-clicking this node. Override to add custom menu items. </summary> /// <summary> Add items for the context menu when right-clicking this node. Override to add custom menu items. </summary>
public virtual void AddContextMenuItems(GenericMenu menu, GenericMenu.MenuFunction2 call = default(GenericMenu.MenuFunction2)) { public virtual void AddContextMenuItems(GenericMenu menu, GenericMenu.MenuFunction2 call = default(GenericMenu.MenuFunction2)) {
Vector2 pos = NodeEditorWindow.current.WindowToGridPosition(Event.current.mousePosition); Vector2 pos = NodeEditorWindow.current.WindowToGridPosition(Event.current.mousePosition);
for (int i = 0; i < NodeEditorWindow.nodeTypes.Length; i++) { for (int i = 0; i < NodeEditorReflection.nodeTypes.Length; i++) {
Type type = NodeEditorWindow.nodeTypes[i]; Type type = NodeEditorReflection.nodeTypes[i];
//Get node context menu path //Get node context menu path
string path = GetNodeMenuName(type); string path = GetNodeMenuName(type);
@ -62,8 +62,10 @@ namespace XNodeEditor {
}); });
} }
menu.AddSeparator(""); menu.AddSeparator("");
menu.AddItem(new GUIContent("Preferences"), false, () => NodeEditorWindow.OpenPreferences()); if (NodeEditorWindow.copyBuffer != null && NodeEditorWindow.copyBuffer.Length > 0) menu.AddItem(new GUIContent("Paste"), false, () => NodeEditorWindow.current.PasteNodes(pos));
NodeEditorWindow.AddCustomContextMenuItems(menu, target); else menu.AddDisabledItem(new GUIContent("Paste"));
menu.AddItem(new GUIContent("Preferences"), false, () => NodeEditorReflection.OpenPreferences());
menu.AddCustomContextMenuItems(target);
} }
public virtual Color GetPortColor(XNode.NodePort port) { public virtual Color GetPortColor(XNode.NodePort port) {
@ -74,16 +76,27 @@ namespace XNodeEditor {
return NodeEditorPreferences.GetTypeColor(type); return NodeEditorPreferences.GetTypeColor(type);
} }
public virtual string GetPortTooltip(XNode.NodePort port) {
Type portType = port.ValueType;
string tooltip = "";
tooltip = portType.PrettyName();
if (port.IsOutput) {
object obj = port.node.GetValue(port);
tooltip += " = " + (obj != null ? obj.ToString() : "null");
}
return tooltip;
}
/// <summary> Deal with objects dropped into the graph through DragAndDrop </summary>
public virtual void OnDropObjects(UnityEngine.Object[] objects) {
Debug.Log("No OnDropItems override defined for " + GetType());
}
/// <summary> Create a node and save it in the graph asset </summary> /// <summary> Create a node and save it in the graph asset </summary>
public virtual void CreateNode(Type type, Vector2 position) { public virtual void CreateNode(Type type, Vector2 position) {
XNode.Node node = target.AddNode(type); XNode.Node node = target.AddNode(type);
node.position = position; node.position = position;
if (string.IsNullOrEmpty(node.name)) { if (node.name == null || node.name.Trim() == "") node.name = NodeEditorUtilities.NodeDefaultName(type);
// Automatically remove redundant 'Node' postfix
string typeName = type.Name;
if (typeName.EndsWith("Node")) typeName = typeName.Substring(0, typeName.LastIndexOf("Node"));
node.name = UnityEditor.ObjectNames.NicifyVariableName(typeName);
}
AssetDatabase.AddObjectToAsset(node, target); AssetDatabase.AddObjectToAsset(node, target);
if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
NodeEditorWindow.RepaintAll(); NodeEditorWindow.RepaintAll();
@ -107,7 +120,7 @@ namespace XNodeEditor {
[AttributeUsage(AttributeTargets.Class)] [AttributeUsage(AttributeTargets.Class)]
public class CustomNodeGraphEditorAttribute : Attribute, public class CustomNodeGraphEditorAttribute : Attribute,
XNodeEditor.Internal.NodeEditorBase<NodeGraphEditor, NodeGraphEditor.CustomNodeGraphEditorAttribute, XNode.NodeGraph>.INodeEditorAttrib { XNodeEditor.Internal.NodeEditorBase<NodeGraphEditor, NodeGraphEditor.CustomNodeGraphEditorAttribute, XNode.NodeGraph>.INodeEditorAttrib {
private Type inspectedType; private Type inspectedType;
public string editorPrefsKey; public string editorPrefsKey;
/// <summary> Tells a NodeGraphEditor which Graph type it is an editor for </summary> /// <summary> Tells a NodeGraphEditor which Graph type it is an editor for </summary>
@ -123,4 +136,4 @@ namespace XNodeEditor {
} }
} }
} }
} }