mirror of
https://github.com/Siccity/xNode.git
synced 2026-03-26 22:49:02 +08:00
Fixed format
This commit is contained in:
parent
598c75fb3a
commit
882c5e2a1d
@ -4,10 +4,8 @@ using System.Linq;
|
|||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace XNodeEditor
|
namespace XNodeEditor {
|
||||||
{
|
public partial class NodeEditorWindow {
|
||||||
public partial class NodeEditorWindow
|
|
||||||
{
|
|
||||||
public enum NodeActivity { Idle, HoldNode, DragNode, HoldGrid, DragGrid }
|
public enum NodeActivity { Idle, HoldNode, DragNode, HoldGrid, DragGrid }
|
||||||
public static NodeActivity currentActivity = NodeActivity.Idle;
|
public static NodeActivity currentActivity = NodeActivity.Idle;
|
||||||
public static bool isPanning { get; private set; }
|
public static bool isPanning { get; private set; }
|
||||||
@ -30,45 +28,37 @@ namespace XNodeEditor
|
|||||||
private Rect selectionBox;
|
private Rect selectionBox;
|
||||||
private bool isDoubleClick = false;
|
private bool isDoubleClick = false;
|
||||||
|
|
||||||
private struct RerouteReference
|
private struct RerouteReference {
|
||||||
{
|
|
||||||
public XNode.NodePort port;
|
public XNode.NodePort port;
|
||||||
public int connectionIndex;
|
public int connectionIndex;
|
||||||
public int pointIndex;
|
public int pointIndex;
|
||||||
|
|
||||||
public RerouteReference(XNode.NodePort port, int connectionIndex, int pointIndex)
|
public RerouteReference(XNode.NodePort port, int connectionIndex, int pointIndex) {
|
||||||
{
|
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.connectionIndex = connectionIndex;
|
this.connectionIndex = connectionIndex;
|
||||||
this.pointIndex = pointIndex;
|
this.pointIndex = pointIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InsertPoint(Vector2 pos) { port.GetReroutePoints(connectionIndex).Insert(pointIndex, pos); }
|
public void InsertPoint(Vector2 pos) { port.GetReroutePoints(connectionIndex).Insert(pointIndex, pos); }
|
||||||
public void SetPoint(Vector2 pos) { port.GetReroutePoints(connectionIndex)[pointIndex] = pos; }
|
public void SetPoint(Vector2 pos) { port.GetReroutePoints(connectionIndex) [pointIndex] = pos; }
|
||||||
public void RemovePoint() { port.GetReroutePoints(connectionIndex).RemoveAt(pointIndex); }
|
public void RemovePoint() { port.GetReroutePoints(connectionIndex).RemoveAt(pointIndex); }
|
||||||
public Vector2 GetPoint() { return port.GetReroutePoints(connectionIndex)[pointIndex]; }
|
public Vector2 GetPoint() { return port.GetReroutePoints(connectionIndex) [pointIndex]; }
|
||||||
}
|
}
|
||||||
|
|
||||||
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.DragUpdated:
|
||||||
case EventType.DragPerform:
|
case EventType.DragPerform:
|
||||||
|
|
||||||
|
|
||||||
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
||||||
|
|
||||||
if (e.type == EventType.DragPerform)
|
if (e.type == EventType.DragPerform) {
|
||||||
{
|
|
||||||
DragAndDrop.AcceptDrag();
|
DragAndDrop.AcceptDrag();
|
||||||
|
|
||||||
foreach (object droppedItem in DragAndDrop.objectReferences)
|
foreach (object droppedItem in DragAndDrop.objectReferences) {
|
||||||
{
|
|
||||||
graphEditor.DropItem(droppedItem);
|
graphEditor.DropItem(droppedItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,69 +73,52 @@ namespace XNodeEditor
|
|||||||
if (NodeEditorPreferences.GetSettings().zoomToMouse) panOffset += (1 - oldZoom / zoom) * (WindowToGridPosition(e.mousePosition) + panOffset);
|
if (NodeEditorPreferences.GetSettings().zoomToMouse) panOffset += (1 - oldZoom / zoom) * (WindowToGridPosition(e.mousePosition) + panOffset);
|
||||||
break;
|
break;
|
||||||
case EventType.MouseDrag:
|
case EventType.MouseDrag:
|
||||||
if (e.button == 0)
|
if (e.button == 0) {
|
||||||
{
|
if (IsDraggingPort) {
|
||||||
if (IsDraggingPort)
|
if (IsHoveringPort && hoveredPort.IsInput && draggedOutput.CanConnectTo(hoveredPort)) {
|
||||||
{
|
if (!draggedOutput.IsConnectedTo(hoveredPort)) {
|
||||||
if (IsHoveringPort && hoveredPort.IsInput && draggedOutput.CanConnectTo(hoveredPort))
|
|
||||||
{
|
|
||||||
if (!draggedOutput.IsConnectedTo(hoveredPort))
|
|
||||||
{
|
|
||||||
draggedOutputTarget = hoveredPort;
|
draggedOutputTarget = hoveredPort;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
draggedOutputTarget = null;
|
draggedOutputTarget = null;
|
||||||
}
|
}
|
||||||
Repaint();
|
Repaint();
|
||||||
}
|
} else if (currentActivity == NodeActivity.HoldNode) {
|
||||||
else if (currentActivity == NodeActivity.HoldNode)
|
|
||||||
{
|
|
||||||
RecalculateDragOffsets(e);
|
RecalculateDragOffsets(e);
|
||||||
currentActivity = NodeActivity.DragNode;
|
currentActivity = NodeActivity.DragNode;
|
||||||
Repaint();
|
Repaint();
|
||||||
}
|
}
|
||||||
if (currentActivity == NodeActivity.DragNode)
|
if (currentActivity == NodeActivity.DragNode) {
|
||||||
{
|
|
||||||
// Holding ctrl inverts grid snap
|
// Holding ctrl inverts grid snap
|
||||||
bool gridSnap = NodeEditorPreferences.GetSettings().gridSnap;
|
bool gridSnap = NodeEditorPreferences.GetSettings().gridSnap;
|
||||||
if (e.control) gridSnap = !gridSnap;
|
if (e.control) gridSnap = !gridSnap;
|
||||||
|
|
||||||
Vector2 mousePos = WindowToGridPosition(e.mousePosition);
|
Vector2 mousePos = WindowToGridPosition(e.mousePosition);
|
||||||
// Move selected nodes with offset
|
// Move selected nodes with offset
|
||||||
for (int i = 0; i < Selection.objects.Length; i++)
|
for (int i = 0; i < Selection.objects.Length; i++) {
|
||||||
{
|
if (Selection.objects[i] is XNode.Node) {
|
||||||
if (Selection.objects[i] is XNode.Node)
|
|
||||||
{
|
|
||||||
XNode.Node node = Selection.objects[i] as XNode.Node;
|
XNode.Node node = Selection.objects[i] as XNode.Node;
|
||||||
Vector2 initial = node.position;
|
Vector2 initial = node.position;
|
||||||
node.position = mousePos + dragOffset[i];
|
node.position = mousePos + dragOffset[i];
|
||||||
if (gridSnap)
|
if (gridSnap) {
|
||||||
{
|
|
||||||
node.position.x = (Mathf.Round((node.position.x + 8) / 16) * 16) - 8;
|
node.position.x = (Mathf.Round((node.position.x + 8) / 16) * 16) - 8;
|
||||||
node.position.y = (Mathf.Round((node.position.y + 8) / 16) * 16) - 8;
|
node.position.y = (Mathf.Round((node.position.y + 8) / 16) * 16) - 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Offset portConnectionPoints instantly if a node is dragged so they aren't delayed by a frame.
|
// Offset portConnectionPoints instantly if a node is dragged so they aren't delayed by a frame.
|
||||||
Vector2 offset = node.position - initial;
|
Vector2 offset = node.position - initial;
|
||||||
if (offset.sqrMagnitude > 0)
|
if (offset.sqrMagnitude > 0) {
|
||||||
{
|
foreach (XNode.NodePort output in node.Outputs) {
|
||||||
foreach (XNode.NodePort output in node.Outputs)
|
|
||||||
{
|
|
||||||
Rect rect;
|
Rect rect;
|
||||||
if (portConnectionPoints.TryGetValue(output, out rect))
|
if (portConnectionPoints.TryGetValue(output, out rect)) {
|
||||||
{
|
|
||||||
rect.position += offset;
|
rect.position += offset;
|
||||||
portConnectionPoints[output] = rect;
|
portConnectionPoints[output] = rect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (XNode.NodePort input in node.Inputs)
|
foreach (XNode.NodePort input in node.Inputs) {
|
||||||
{
|
|
||||||
Rect rect;
|
Rect rect;
|
||||||
if (portConnectionPoints.TryGetValue(input, out rect))
|
if (portConnectionPoints.TryGetValue(input, out rect)) {
|
||||||
{
|
|
||||||
rect.position += offset;
|
rect.position += offset;
|
||||||
portConnectionPoints[input] = rect;
|
portConnectionPoints[input] = rect;
|
||||||
}
|
}
|
||||||
@ -154,28 +127,22 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Move selected reroutes with offset
|
// Move selected reroutes with offset
|
||||||
for (int i = 0; i < selectedReroutes.Count; i++)
|
for (int i = 0; i < selectedReroutes.Count; i++) {
|
||||||
{
|
|
||||||
Vector2 pos = mousePos + dragOffset[Selection.objects.Length + i];
|
Vector2 pos = mousePos + dragOffset[Selection.objects.Length + i];
|
||||||
if (gridSnap)
|
if (gridSnap) {
|
||||||
{
|
|
||||||
pos.x = (Mathf.Round(pos.x / 16) * 16);
|
pos.x = (Mathf.Round(pos.x / 16) * 16);
|
||||||
pos.y = (Mathf.Round(pos.y / 16) * 16);
|
pos.y = (Mathf.Round(pos.y / 16) * 16);
|
||||||
}
|
}
|
||||||
selectedReroutes[i].SetPoint(pos);
|
selectedReroutes[i].SetPoint(pos);
|
||||||
}
|
}
|
||||||
Repaint();
|
Repaint();
|
||||||
}
|
} else if (currentActivity == NodeActivity.HoldGrid) {
|
||||||
else if (currentActivity == NodeActivity.HoldGrid)
|
|
||||||
{
|
|
||||||
currentActivity = NodeActivity.DragGrid;
|
currentActivity = NodeActivity.DragGrid;
|
||||||
preBoxSelection = Selection.objects;
|
preBoxSelection = Selection.objects;
|
||||||
preBoxSelectionReroute = selectedReroutes.ToArray();
|
preBoxSelectionReroute = selectedReroutes.ToArray();
|
||||||
dragBoxStart = WindowToGridPosition(e.mousePosition);
|
dragBoxStart = WindowToGridPosition(e.mousePosition);
|
||||||
Repaint();
|
Repaint();
|
||||||
}
|
} else if (currentActivity == NodeActivity.DragGrid) {
|
||||||
else if (currentActivity == NodeActivity.DragGrid)
|
|
||||||
{
|
|
||||||
Vector2 boxStartPos = GridToWindowPosition(dragBoxStart);
|
Vector2 boxStartPos = GridToWindowPosition(dragBoxStart);
|
||||||
Vector2 boxSize = e.mousePosition - boxStartPos;
|
Vector2 boxSize = e.mousePosition - boxStartPos;
|
||||||
if (boxSize.x < 0) { boxStartPos.x += boxSize.x; boxSize.x = Mathf.Abs(boxSize.x); }
|
if (boxSize.x < 0) { boxStartPos.x += boxSize.x; boxSize.x = Mathf.Abs(boxSize.x); }
|
||||||
@ -183,30 +150,22 @@ namespace XNodeEditor
|
|||||||
selectionBox = new Rect(boxStartPos, boxSize);
|
selectionBox = new Rect(boxStartPos, boxSize);
|
||||||
Repaint();
|
Repaint();
|
||||||
}
|
}
|
||||||
}
|
} else if (e.button == 1 || e.button == 2) {
|
||||||
else if (e.button == 1 || e.button == 2)
|
|
||||||
{
|
|
||||||
panOffset += e.delta * zoom;
|
panOffset += e.delta * zoom;
|
||||||
isPanning = true;
|
isPanning = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EventType.MouseDown:
|
case EventType.MouseDown:
|
||||||
Repaint();
|
Repaint();
|
||||||
if (e.button == 0)
|
if (e.button == 0) {
|
||||||
{
|
|
||||||
draggedOutputReroutes.Clear();
|
draggedOutputReroutes.Clear();
|
||||||
|
|
||||||
if (IsHoveringPort)
|
if (IsHoveringPort) {
|
||||||
{
|
if (hoveredPort.IsOutput) {
|
||||||
if (hoveredPort.IsOutput)
|
|
||||||
{
|
|
||||||
draggedOutput = hoveredPort;
|
draggedOutput = hoveredPort;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
hoveredPort.VerifyConnections();
|
hoveredPort.VerifyConnections();
|
||||||
if (hoveredPort.IsConnected)
|
if (hoveredPort.IsConnected) {
|
||||||
{
|
|
||||||
XNode.Node node = hoveredPort.node;
|
XNode.Node node = hoveredPort.node;
|
||||||
XNode.NodePort output = hoveredPort.Connection;
|
XNode.NodePort output = hoveredPort.Connection;
|
||||||
int outputConnectionIndex = output.GetConnectionIndex(hoveredPort);
|
int outputConnectionIndex = output.GetConnectionIndex(hoveredPort);
|
||||||
@ -217,33 +176,25 @@ namespace XNodeEditor
|
|||||||
if (NodeEditor.onUpdateNode != null) NodeEditor.onUpdateNode(node);
|
if (NodeEditor.onUpdateNode != null) NodeEditor.onUpdateNode(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (IsHoveringNode && IsHoveringTitle(hoveredNode)) {
|
||||||
else if (IsHoveringNode && IsHoveringTitle(hoveredNode))
|
|
||||||
{
|
|
||||||
// If mousedown on node header, select or deselect
|
// If mousedown on node header, select or deselect
|
||||||
if (!Selection.Contains(hoveredNode))
|
if (!Selection.Contains(hoveredNode)) {
|
||||||
{
|
|
||||||
SelectNode(hoveredNode, e.control || e.shift);
|
SelectNode(hoveredNode, e.control || e.shift);
|
||||||
if (!e.control && !e.shift) selectedReroutes.Clear();
|
if (!e.control && !e.shift) selectedReroutes.Clear();
|
||||||
}
|
} else if (e.control || e.shift) DeselectNode(hoveredNode);
|
||||||
else if (e.control || e.shift) DeselectNode(hoveredNode);
|
|
||||||
|
|
||||||
// Cache double click state, but only act on it in MouseUp - Except ClickCount only works in mouseDown.
|
// Cache double click state, but only act on it in MouseUp - Except ClickCount only works in mouseDown.
|
||||||
isDoubleClick = (e.clickCount == 2);
|
isDoubleClick = (e.clickCount == 2);
|
||||||
|
|
||||||
e.Use();
|
e.Use();
|
||||||
currentActivity = NodeActivity.HoldNode;
|
currentActivity = NodeActivity.HoldNode;
|
||||||
}
|
} else if (IsHoveringReroute) {
|
||||||
else if (IsHoveringReroute)
|
|
||||||
{
|
|
||||||
// If reroute isn't selected
|
// If reroute isn't selected
|
||||||
if (!selectedReroutes.Contains(hoveredReroute))
|
if (!selectedReroutes.Contains(hoveredReroute)) {
|
||||||
{
|
|
||||||
// Add it
|
// Add it
|
||||||
if (e.control || e.shift) selectedReroutes.Add(hoveredReroute);
|
if (e.control || e.shift) selectedReroutes.Add(hoveredReroute);
|
||||||
// Select it
|
// Select it
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
selectedReroutes = new List<RerouteReference>() { hoveredReroute };
|
selectedReroutes = new List<RerouteReference>() { hoveredReroute };
|
||||||
Selection.activeObject = null;
|
Selection.activeObject = null;
|
||||||
}
|
}
|
||||||
@ -255,11 +206,9 @@ namespace XNodeEditor
|
|||||||
currentActivity = NodeActivity.HoldNode;
|
currentActivity = NodeActivity.HoldNode;
|
||||||
}
|
}
|
||||||
// If mousedown on grid background, deselect all
|
// If mousedown on grid background, deselect all
|
||||||
else if (!IsHoveringNode)
|
else if (!IsHoveringNode) {
|
||||||
{
|
|
||||||
currentActivity = NodeActivity.HoldGrid;
|
currentActivity = NodeActivity.HoldGrid;
|
||||||
if (!e.control && !e.shift)
|
if (!e.control && !e.shift) {
|
||||||
{
|
|
||||||
selectedReroutes.Clear();
|
selectedReroutes.Clear();
|
||||||
Selection.activeObject = null;
|
Selection.activeObject = null;
|
||||||
}
|
}
|
||||||
@ -267,21 +216,17 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EventType.MouseUp:
|
case EventType.MouseUp:
|
||||||
if (e.button == 0)
|
if (e.button == 0) {
|
||||||
{
|
|
||||||
//Port drag release
|
//Port drag release
|
||||||
if (IsDraggingPort)
|
if (IsDraggingPort) {
|
||||||
{
|
|
||||||
//If connection is valid, save it
|
//If connection is valid, save it
|
||||||
if (draggedOutputTarget != null)
|
if (draggedOutputTarget != null) {
|
||||||
{
|
|
||||||
XNode.Node node = draggedOutputTarget.node;
|
XNode.Node node = draggedOutputTarget.node;
|
||||||
if (graph.nodes.Count != 0) draggedOutput.Connect(draggedOutputTarget);
|
if (graph.nodes.Count != 0) draggedOutput.Connect(draggedOutputTarget);
|
||||||
|
|
||||||
// ConnectionIndex can be -1 if the connection is removed instantly after creation
|
// ConnectionIndex can be -1 if the connection is removed instantly after creation
|
||||||
int connectionIndex = draggedOutput.GetConnectionIndex(draggedOutputTarget);
|
int connectionIndex = draggedOutput.GetConnectionIndex(draggedOutputTarget);
|
||||||
if (connectionIndex != -1)
|
if (connectionIndex != -1) {
|
||||||
{
|
|
||||||
draggedOutput.GetReroutePoints(connectionIndex).AddRange(draggedOutputReroutes);
|
draggedOutput.GetReroutePoints(connectionIndex).AddRange(draggedOutputReroutes);
|
||||||
if (NodeEditor.onUpdateNode != null) NodeEditor.onUpdateNode(node);
|
if (NodeEditor.onUpdateNode != null) NodeEditor.onUpdateNode(node);
|
||||||
EditorUtility.SetDirty(graph);
|
EditorUtility.SetDirty(graph);
|
||||||
@ -292,18 +237,13 @@ namespace XNodeEditor
|
|||||||
draggedOutputTarget = null;
|
draggedOutputTarget = null;
|
||||||
EditorUtility.SetDirty(graph);
|
EditorUtility.SetDirty(graph);
|
||||||
if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
|
if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
|
||||||
}
|
} else if (currentActivity == NodeActivity.DragNode) {
|
||||||
else if (currentActivity == NodeActivity.DragNode)
|
|
||||||
{
|
|
||||||
IEnumerable<XNode.Node> nodes = Selection.objects.Where(x => x is XNode.Node).Select(x => x as XNode.Node);
|
IEnumerable<XNode.Node> nodes = Selection.objects.Where(x => x is XNode.Node).Select(x => x as XNode.Node);
|
||||||
foreach (XNode.Node node in nodes) EditorUtility.SetDirty(node);
|
foreach (XNode.Node node in nodes) EditorUtility.SetDirty(node);
|
||||||
if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
|
if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
|
||||||
}
|
} else if (!IsHoveringNode) {
|
||||||
else if (!IsHoveringNode)
|
|
||||||
{
|
|
||||||
// If click outside node, release field focus
|
// If click outside node, release field focus
|
||||||
if (!isPanning)
|
if (!isPanning) {
|
||||||
{
|
|
||||||
EditorGUI.FocusTextInControl(null);
|
EditorGUI.FocusTextInControl(null);
|
||||||
EditorGUIUtility.editingTextField = false;
|
EditorGUIUtility.editingTextField = false;
|
||||||
}
|
}
|
||||||
@ -311,60 +251,43 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If click node header, select it.
|
// If click node header, select it.
|
||||||
if (currentActivity == NodeActivity.HoldNode && !(e.control || e.shift))
|
if (currentActivity == NodeActivity.HoldNode && !(e.control || e.shift)) {
|
||||||
{
|
|
||||||
selectedReroutes.Clear();
|
selectedReroutes.Clear();
|
||||||
SelectNode(hoveredNode, false);
|
SelectNode(hoveredNode, false);
|
||||||
|
|
||||||
// Double click to center node
|
// Double click to center node
|
||||||
if (isDoubleClick)
|
if (isDoubleClick) {
|
||||||
{
|
|
||||||
Vector2 nodeDimension = nodeSizes.ContainsKey(hoveredNode) ? nodeSizes[hoveredNode] / 2 : Vector2.zero;
|
Vector2 nodeDimension = nodeSizes.ContainsKey(hoveredNode) ? nodeSizes[hoveredNode] / 2 : Vector2.zero;
|
||||||
panOffset = -hoveredNode.position - nodeDimension;
|
panOffset = -hoveredNode.position - nodeDimension;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If click reroute, select it.
|
// If click reroute, select it.
|
||||||
if (IsHoveringReroute && !(e.control || e.shift))
|
if (IsHoveringReroute && !(e.control || e.shift)) {
|
||||||
{
|
|
||||||
selectedReroutes = new List<RerouteReference>() { hoveredReroute };
|
selectedReroutes = new List<RerouteReference>() { hoveredReroute };
|
||||||
Selection.activeObject = null;
|
Selection.activeObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Repaint();
|
Repaint();
|
||||||
currentActivity = NodeActivity.Idle;
|
currentActivity = NodeActivity.Idle;
|
||||||
}
|
} else if (e.button == 1 || e.button == 2) {
|
||||||
else if (e.button == 1 || e.button == 2)
|
if (!isPanning) {
|
||||||
{
|
if (IsDraggingPort) {
|
||||||
if (!isPanning)
|
|
||||||
{
|
|
||||||
if (IsDraggingPort)
|
|
||||||
{
|
|
||||||
draggedOutputReroutes.Add(WindowToGridPosition(e.mousePosition));
|
draggedOutputReroutes.Add(WindowToGridPosition(e.mousePosition));
|
||||||
}
|
} else if (currentActivity == NodeActivity.DragNode && Selection.activeObject == null && selectedReroutes.Count == 1) {
|
||||||
else if (currentActivity == NodeActivity.DragNode && Selection.activeObject == null && selectedReroutes.Count == 1)
|
|
||||||
{
|
|
||||||
selectedReroutes[0].InsertPoint(selectedReroutes[0].GetPoint());
|
selectedReroutes[0].InsertPoint(selectedReroutes[0].GetPoint());
|
||||||
selectedReroutes[0] = new RerouteReference(selectedReroutes[0].port, selectedReroutes[0].connectionIndex, selectedReroutes[0].pointIndex + 1);
|
selectedReroutes[0] = new RerouteReference(selectedReroutes[0].port, selectedReroutes[0].connectionIndex, selectedReroutes[0].pointIndex + 1);
|
||||||
}
|
} else if (IsHoveringReroute) {
|
||||||
else if (IsHoveringReroute)
|
|
||||||
{
|
|
||||||
ShowRerouteContextMenu(hoveredReroute);
|
ShowRerouteContextMenu(hoveredReroute);
|
||||||
}
|
} else if (IsHoveringPort) {
|
||||||
else if (IsHoveringPort)
|
|
||||||
{
|
|
||||||
ShowPortContextMenu(hoveredPort);
|
ShowPortContextMenu(hoveredPort);
|
||||||
}
|
} else if (IsHoveringNode && IsHoveringTitle(hoveredNode)) {
|
||||||
else if (IsHoveringNode && IsHoveringTitle(hoveredNode))
|
|
||||||
{
|
|
||||||
if (!Selection.Contains(hoveredNode)) SelectNode(hoveredNode, false);
|
if (!Selection.Contains(hoveredNode)) SelectNode(hoveredNode, false);
|
||||||
GenericMenu menu = new GenericMenu();
|
GenericMenu menu = new GenericMenu();
|
||||||
NodeEditor.GetEditor(hoveredNode, this).AddContextMenuItems(menu);
|
NodeEditor.GetEditor(hoveredNode, this).AddContextMenuItems(menu);
|
||||||
menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
|
menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
|
||||||
e.Use(); // Fixes copy/paste context menu appearing in Unity 5.6.6f2 - doesn't occur in 2018.3.2f1 Probably needs to be used in other places.
|
e.Use(); // Fixes copy/paste context menu appearing in Unity 5.6.6f2 - doesn't occur in 2018.3.2f1 Probably needs to be used in other places.
|
||||||
}
|
} else if (!IsHoveringNode) {
|
||||||
else if (!IsHoveringNode)
|
|
||||||
{
|
|
||||||
GenericMenu menu = new GenericMenu();
|
GenericMenu menu = new GenericMenu();
|
||||||
graphEditor.AddContextMenuItems(menu);
|
graphEditor.AddContextMenuItems(menu);
|
||||||
menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
|
menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
|
||||||
@ -378,29 +301,21 @@ 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 (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();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EventType.ValidateCommand:
|
case EventType.ValidateCommand:
|
||||||
case EventType.ExecuteCommand:
|
case EventType.ExecuteCommand:
|
||||||
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 (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();
|
||||||
}
|
}
|
||||||
@ -408,8 +323,7 @@ namespace XNodeEditor
|
|||||||
break;
|
break;
|
||||||
case EventType.Ignore:
|
case EventType.Ignore:
|
||||||
// If release mouse outside window
|
// If release mouse outside window
|
||||||
if (e.rawType == EventType.MouseUp && currentActivity == NodeActivity.DragGrid)
|
if (e.rawType == EventType.MouseUp && currentActivity == NodeActivity.DragGrid) {
|
||||||
{
|
|
||||||
Repaint();
|
Repaint();
|
||||||
currentActivity = NodeActivity.Idle;
|
currentActivity = NodeActivity.Idle;
|
||||||
}
|
}
|
||||||
@ -417,8 +331,7 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMac()
|
public bool IsMac() {
|
||||||
{
|
|
||||||
#if UNITY_2017_1_OR_NEWER
|
#if UNITY_2017_1_OR_NEWER
|
||||||
return SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX;
|
return SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX;
|
||||||
#else
|
#else
|
||||||
@ -426,47 +339,38 @@ namespace XNodeEditor
|
|||||||
#endif
|
#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
|
||||||
for (int i = 0; i < Selection.objects.Length; i++)
|
for (int i = 0; i < Selection.objects.Length; i++) {
|
||||||
{
|
if (Selection.objects[i] is XNode.Node) {
|
||||||
if (Selection.objects[i] is XNode.Node)
|
|
||||||
{
|
|
||||||
XNode.Node node = Selection.objects[i] as XNode.Node;
|
XNode.Node node = Selection.objects[i] as XNode.Node;
|
||||||
dragOffset[i] = node.position - WindowToGridPosition(current.mousePosition);
|
dragOffset[i] = node.position - WindowToGridPosition(current.mousePosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Selected reroutes
|
// Selected reroutes
|
||||||
for (int i = 0; i < selectedReroutes.Count; i++)
|
for (int i = 0; i < selectedReroutes.Count; i++) {
|
||||||
{
|
|
||||||
dragOffset[Selection.objects.Length + i] = selectedReroutes[i].GetPoint() - WindowToGridPosition(current.mousePosition);
|
dragOffset[Selection.objects.Length + i] = selectedReroutes[i].GetPoint() - WindowToGridPosition(current.mousePosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Puts all nodes in focus. If no nodes are present, resets view to </summary>
|
/// <summary> Puts all nodes in focus. If no nodes are present, resets view to </summary>
|
||||||
public void Home()
|
public void Home() {
|
||||||
{
|
|
||||||
zoom = 2;
|
zoom = 2;
|
||||||
panOffset = Vector2.zero;
|
panOffset = Vector2.zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Remove nodes in the graph in Selection.objects</summary>
|
/// <summary> Remove nodes in the graph in Selection.objects</summary>
|
||||||
public void RemoveSelectedNodes()
|
public void RemoveSelectedNodes() {
|
||||||
{
|
|
||||||
// We need to delete reroutes starting at the highest point index to avoid shifting indices
|
// We need to delete reroutes starting at the highest point index to avoid shifting indices
|
||||||
selectedReroutes = selectedReroutes.OrderByDescending(x => x.pointIndex).ToList();
|
selectedReroutes = selectedReroutes.OrderByDescending(x => x.pointIndex).ToList();
|
||||||
for (int i = 0; i < selectedReroutes.Count; i++)
|
for (int i = 0; i < selectedReroutes.Count; i++) {
|
||||||
{
|
|
||||||
selectedReroutes[i].RemovePoint();
|
selectedReroutes[i].RemovePoint();
|
||||||
}
|
}
|
||||||
selectedReroutes.Clear();
|
selectedReroutes.Clear();
|
||||||
foreach (UnityEngine.Object item in Selection.objects)
|
foreach (UnityEngine.Object item in Selection.objects) {
|
||||||
{
|
if (item is XNode.Node) {
|
||||||
if (item is XNode.Node)
|
|
||||||
{
|
|
||||||
XNode.Node node = item as XNode.Node;
|
XNode.Node node = item as XNode.Node;
|
||||||
graphEditor.RemoveNode(node);
|
graphEditor.RemoveNode(node);
|
||||||
}
|
}
|
||||||
@ -474,43 +378,33 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Initiate a rename on the currently selected node </summary>
|
/// <summary> Initiate a rename on the currently selected node </summary>
|
||||||
public void RenameSelectedNode()
|
public void RenameSelectedNode() {
|
||||||
{
|
if (Selection.objects.Length == 1 && Selection.activeObject is XNode.Node) {
|
||||||
if (Selection.objects.Length == 1 && Selection.activeObject is XNode.Node)
|
|
||||||
{
|
|
||||||
XNode.Node node = Selection.activeObject as XNode.Node;
|
XNode.Node node = Selection.activeObject as XNode.Node;
|
||||||
Vector2 size;
|
Vector2 size;
|
||||||
if (nodeSizes.TryGetValue(node, out size))
|
if (nodeSizes.TryGetValue(node, out size)) {
|
||||||
{
|
|
||||||
RenamePopup.Show(Selection.activeObject, size.x);
|
RenamePopup.Show(Selection.activeObject, size.x);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
RenamePopup.Show(Selection.activeObject);
|
RenamePopup.Show(Selection.activeObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Draw this node on top of other nodes by placing it last in the graph.nodes list </summary>
|
/// <summary> Draw this node on top of other nodes by placing it last in the graph.nodes list </summary>
|
||||||
public void MoveNodeToTop(XNode.Node node)
|
public void MoveNodeToTop(XNode.Node node) {
|
||||||
{
|
|
||||||
int index;
|
int index;
|
||||||
while ((index = graph.nodes.IndexOf(node)) != graph.nodes.Count - 1)
|
while ((index = graph.nodes.IndexOf(node)) != graph.nodes.Count - 1) {
|
||||||
{
|
|
||||||
graph.nodes[index] = graph.nodes[index + 1];
|
graph.nodes[index] = graph.nodes[index + 1];
|
||||||
graph.nodes[index + 1] = node;
|
graph.nodes[index + 1] = node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <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];
|
UnityEngine.Object[] newNodes = new UnityEngine.Object[Selection.objects.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 < Selection.objects.Length; i++) {
|
||||||
{
|
if (Selection.objects[i] is XNode.Node) {
|
||||||
if (Selection.objects[i] is XNode.Node)
|
|
||||||
{
|
|
||||||
XNode.Node srcNode = Selection.objects[i] as XNode.Node;
|
XNode.Node srcNode = Selection.objects[i] as XNode.Node;
|
||||||
if (srcNode.graph != graph) continue; // ignore nodes selected in another graph
|
if (srcNode.graph != graph) continue; // ignore nodes selected in another graph
|
||||||
XNode.Node newNode = graphEditor.CopyNode(srcNode);
|
XNode.Node newNode = graphEditor.CopyNode(srcNode);
|
||||||
@ -521,22 +415,17 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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 < Selection.objects.Length; i++) {
|
||||||
{
|
if (Selection.objects[i] is XNode.Node) {
|
||||||
if (Selection.objects[i] is XNode.Node)
|
|
||||||
{
|
|
||||||
XNode.Node srcNode = Selection.objects[i] as XNode.Node;
|
XNode.Node srcNode = Selection.objects[i] as XNode.Node;
|
||||||
if (srcNode.graph != graph) continue; // ignore nodes selected in another graph
|
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);
|
||||||
@ -551,10 +440,8 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Draw a connection as we are dragging it </summary>
|
/// <summary> Draw a connection as we are dragging it </summary>
|
||||||
public void DrawDraggedConnection()
|
public void DrawDraggedConnection() {
|
||||||
{
|
if (IsDraggingPort) {
|
||||||
if (IsDraggingPort)
|
|
||||||
{
|
|
||||||
Color col = NodeEditorPreferences.GetTypeColor(draggedOutput.ValueType);
|
Color col = NodeEditorPreferences.GetTypeColor(draggedOutput.ValueType);
|
||||||
col.a = draggedOutputTarget != null ? 1.0f : 0.6f;
|
col.a = draggedOutputTarget != null ? 1.0f : 0.6f;
|
||||||
|
|
||||||
@ -562,8 +449,7 @@ namespace XNodeEditor
|
|||||||
if (!_portConnectionPoints.TryGetValue(draggedOutput, out fromRect)) return;
|
if (!_portConnectionPoints.TryGetValue(draggedOutput, out fromRect)) return;
|
||||||
List<Vector2> gridPoints = new List<Vector2>();
|
List<Vector2> gridPoints = new List<Vector2>();
|
||||||
gridPoints.Add(fromRect.center);
|
gridPoints.Add(fromRect.center);
|
||||||
for (int i = 0; i < draggedOutputReroutes.Count; i++)
|
for (int i = 0; i < draggedOutputReroutes.Count; i++) {
|
||||||
{
|
|
||||||
gridPoints.Add(draggedOutputReroutes[i]);
|
gridPoints.Add(draggedOutputReroutes[i]);
|
||||||
}
|
}
|
||||||
if (draggedOutputTarget != null) gridPoints.Add(portConnectionPoints[draggedOutputTarget].center);
|
if (draggedOutputTarget != null) gridPoints.Add(portConnectionPoints[draggedOutputTarget].center);
|
||||||
@ -577,8 +463,7 @@ namespace XNodeEditor
|
|||||||
frcol.a = 0.6f;
|
frcol.a = 0.6f;
|
||||||
|
|
||||||
// Loop through reroute points again and draw the points
|
// Loop through reroute points again and draw the points
|
||||||
for (int i = 0; i < draggedOutputReroutes.Count; i++)
|
for (int i = 0; i < draggedOutputReroutes.Count; i++) {
|
||||||
{
|
|
||||||
// Draw reroute point at position
|
// Draw reroute point at position
|
||||||
Rect rect = new Rect(draggedOutputReroutes[i], new Vector2(16, 16));
|
Rect rect = new Rect(draggedOutputReroutes[i], new Vector2(16, 16));
|
||||||
rect.position = new Vector2(rect.position.x - 8, rect.position.y - 8);
|
rect.position = new Vector2(rect.position.x - 8, rect.position.y - 8);
|
||||||
@ -589,8 +474,7 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsHoveringTitle(XNode.Node node)
|
bool IsHoveringTitle(XNode.Node node) {
|
||||||
{
|
|
||||||
Vector2 mousePos = Event.current.mousePosition;
|
Vector2 mousePos = Event.current.mousePosition;
|
||||||
//Get node position
|
//Get node position
|
||||||
Vector2 nodePos = GridToWindowPosition(node.position);
|
Vector2 nodePos = GridToWindowPosition(node.position);
|
||||||
|
|||||||
@ -4,12 +4,10 @@ using System.Linq;
|
|||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace XNodeEditor
|
namespace XNodeEditor {
|
||||||
{
|
|
||||||
/// <summary> Base class to derive custom Node Graph editors from. Use this to override how graphs are drawn in the editor. </summary>
|
/// <summary> Base class to derive custom Node Graph editors from. Use this to override how graphs are drawn in the editor. </summary>
|
||||||
[CustomNodeGraphEditor(typeof(XNode.NodeGraph))]
|
[CustomNodeGraphEditor(typeof(XNode.NodeGraph))]
|
||||||
public class NodeGraphEditor : XNodeEditor.Internal.NodeEditorBase<NodeGraphEditor, NodeGraphEditor.CustomNodeGraphEditorAttribute, XNode.NodeGraph>
|
public class NodeGraphEditor : XNodeEditor.Internal.NodeEditorBase<NodeGraphEditor, NodeGraphEditor.CustomNodeGraphEditorAttribute, XNode.NodeGraph> {
|
||||||
{
|
|
||||||
[Obsolete("Use window.position instead")]
|
[Obsolete("Use window.position instead")]
|
||||||
public Rect position { get { return window.position; } set { window.position = value; } }
|
public Rect position { get { return window.position; } set { window.position = value; } }
|
||||||
/// <summary> Are we currently renaming a node? </summary>
|
/// <summary> Are we currently renaming a node? </summary>
|
||||||
@ -20,25 +18,21 @@ namespace XNodeEditor
|
|||||||
/// <summary> Called when opened by NodeEditorWindow </summary>
|
/// <summary> Called when opened by NodeEditorWindow </summary>
|
||||||
public virtual void OnOpen() { }
|
public virtual void OnOpen() { }
|
||||||
|
|
||||||
public virtual Texture2D GetGridTexture()
|
public virtual Texture2D GetGridTexture() {
|
||||||
{
|
|
||||||
return NodeEditorPreferences.GetSettings().gridTexture;
|
return NodeEditorPreferences.GetSettings().gridTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Texture2D GetSecondaryGridTexture()
|
public virtual Texture2D GetSecondaryGridTexture() {
|
||||||
{
|
|
||||||
return NodeEditorPreferences.GetSettings().crossTexture;
|
return NodeEditorPreferences.GetSettings().crossTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Return default settings for this graph type. This is the settings the user will load if no previous settings have been saved. </summary>
|
/// <summary> Return default settings for this graph type. This is the settings the user will load if no previous settings have been saved. </summary>
|
||||||
public virtual NodeEditorPreferences.Settings GetDefaultPreferences()
|
public virtual NodeEditorPreferences.Settings GetDefaultPreferences() {
|
||||||
{
|
|
||||||
return new NodeEditorPreferences.Settings();
|
return new NodeEditorPreferences.Settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Returns context node menu path. Null or empty strings for hidden nodes. </summary>
|
/// <summary> Returns context node menu path. Null or empty strings for hidden nodes. </summary>
|
||||||
public virtual string GetNodeMenuName(Type type)
|
public virtual string GetNodeMenuName(Type type) {
|
||||||
{
|
|
||||||
//Check if type has the CreateNodeMenuAttribute
|
//Check if type has the CreateNodeMenuAttribute
|
||||||
XNode.Node.CreateNodeMenuAttribute attrib;
|
XNode.Node.CreateNodeMenuAttribute attrib;
|
||||||
if (NodeEditorUtilities.GetAttrib(type, out attrib)) // Return custom path
|
if (NodeEditorUtilities.GetAttrib(type, out attrib)) // Return custom path
|
||||||
@ -48,19 +42,16 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <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)
|
public virtual void AddContextMenuItems(GenericMenu menu) {
|
||||||
{
|
|
||||||
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 < NodeEditorWindow.nodeTypes.Length; i++) {
|
||||||
{
|
|
||||||
Type type = NodeEditorWindow.nodeTypes[i];
|
Type type = NodeEditorWindow.nodeTypes[i];
|
||||||
|
|
||||||
//Get node context menu path
|
//Get node context menu path
|
||||||
string path = GetNodeMenuName(type);
|
string path = GetNodeMenuName(type);
|
||||||
if (string.IsNullOrEmpty(path)) continue;
|
if (string.IsNullOrEmpty(path)) continue;
|
||||||
|
|
||||||
menu.AddItem(new GUIContent(path), false, () =>
|
menu.AddItem(new GUIContent(path), false, () => {
|
||||||
{
|
|
||||||
CreateNode(type, pos);
|
CreateNode(type, pos);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -69,31 +60,23 @@ namespace XNodeEditor
|
|||||||
NodeEditorWindow.AddCustomContextMenuItems(menu, target);
|
NodeEditorWindow.AddCustomContextMenuItems(menu, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Color GetPortColor(XNode.NodePort port)
|
public virtual Color GetPortColor(XNode.NodePort port) {
|
||||||
{
|
|
||||||
return GetTypeColor(port.ValueType);
|
return GetTypeColor(port.ValueType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Color GetTypeColor(Type type)
|
public virtual Color GetTypeColor(Type type) {
|
||||||
{
|
|
||||||
return NodeEditorPreferences.GetTypeColor(type);
|
return NodeEditorPreferences.GetTypeColor(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void DropItem(object droppedItem) {
|
||||||
|
|
||||||
public virtual void DropItem(object droppedItem)
|
|
||||||
{
|
|
||||||
target.OnDrop(droppedItem, NodeEditorWindow.current.WindowToGridPosition(Event.current.mousePosition));
|
target.OnDrop(droppedItem, NodeEditorWindow.current.WindowToGridPosition(Event.current.mousePosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <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 (string.IsNullOrEmpty(node.name)) {
|
||||||
{
|
|
||||||
// Automatically remove redundant 'Node' postfix
|
// Automatically remove redundant 'Node' postfix
|
||||||
string typeName = type.Name;
|
string typeName = type.Name;
|
||||||
if (typeName.EndsWith("Node")) typeName = typeName.Substring(0, typeName.LastIndexOf("Node"));
|
if (typeName.EndsWith("Node")) typeName = typeName.Substring(0, typeName.LastIndexOf("Node"));
|
||||||
@ -105,8 +88,7 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Creates a copy of the original node in the graph </summary>
|
/// <summary> Creates a copy of the original node in the graph </summary>
|
||||||
public XNode.Node CopyNode(XNode.Node original)
|
public XNode.Node CopyNode(XNode.Node original) {
|
||||||
{
|
|
||||||
XNode.Node node = target.CopyNode(original);
|
XNode.Node node = target.CopyNode(original);
|
||||||
node.name = original.name;
|
node.name = original.name;
|
||||||
AssetDatabase.AddObjectToAsset(node, target);
|
AssetDatabase.AddObjectToAsset(node, target);
|
||||||
@ -115,32 +97,26 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Safely remove a node and all its connections. </summary>
|
/// <summary> Safely remove a node and all its connections. </summary>
|
||||||
public virtual void RemoveNode(XNode.Node node)
|
public virtual void RemoveNode(XNode.Node node) {
|
||||||
{
|
|
||||||
target.RemoveNode(node);
|
target.RemoveNode(node);
|
||||||
UnityEngine.Object.DestroyImmediate(node, true);
|
UnityEngine.Object.DestroyImmediate(node, true);
|
||||||
if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
|
if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[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>
|
||||||
/// <param name="inspectedType">Type that this editor can edit</param>
|
/// <param name="inspectedType">Type that this editor can edit</param>
|
||||||
/// <param name="editorPrefsKey">Define unique key for unique layout settings instance</param>
|
/// <param name="editorPrefsKey">Define unique key for unique layout settings instance</param>
|
||||||
public CustomNodeGraphEditorAttribute(Type inspectedType, string editorPrefsKey = "xNode.Settings")
|
public CustomNodeGraphEditorAttribute(Type inspectedType, string editorPrefsKey = "xNode.Settings") {
|
||||||
{
|
|
||||||
this.inspectedType = inspectedType;
|
this.inspectedType = inspectedType;
|
||||||
this.editorPrefsKey = editorPrefsKey;
|
this.editorPrefsKey = editorPrefsKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type GetInspectedType()
|
public Type GetInspectedType() {
|
||||||
{
|
|
||||||
return inspectedType;
|
return inspectedType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,26 +2,22 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace XNode
|
namespace XNode {
|
||||||
{
|
|
||||||
/// <summary> Base class for all node graphs </summary>
|
/// <summary> Base class for all node graphs </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public abstract class NodeGraph : ScriptableObject
|
public abstract class NodeGraph : ScriptableObject {
|
||||||
{
|
|
||||||
|
|
||||||
/// <summary> All nodes in the graph. <para/>
|
/// <summary> All nodes in the graph. <para/>
|
||||||
/// See: <see cref="AddNode{T}"/> </summary>
|
/// See: <see cref="AddNode{T}"/> </summary>
|
||||||
[SerializeField] public List<Node> nodes = new List<Node>();
|
[SerializeField] public List<Node> nodes = new List<Node>();
|
||||||
|
|
||||||
/// <summary> Add a node to the graph by type (convenience method - will call the System.Type version) </summary>
|
/// <summary> Add a node to the graph by type (convenience method - will call the System.Type version) </summary>
|
||||||
public T AddNode<T>() where T : Node
|
public T AddNode<T>() where T : Node {
|
||||||
{
|
|
||||||
return AddNode(typeof(T)) as T;
|
return AddNode(typeof(T)) as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Add a node to the graph by type </summary>
|
/// <summary> Add a node to the graph by type </summary>
|
||||||
public virtual Node AddNode(Type type)
|
public virtual Node AddNode(Type type) {
|
||||||
{
|
|
||||||
Node.graphHotfix = this;
|
Node.graphHotfix = this;
|
||||||
Node node = ScriptableObject.CreateInstance(type) as Node;
|
Node node = ScriptableObject.CreateInstance(type) as Node;
|
||||||
node.graph = this;
|
node.graph = this;
|
||||||
@ -30,8 +26,7 @@ namespace XNode
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Creates a copy of the original node in the graph </summary>
|
/// <summary> Creates a copy of the original node in the graph </summary>
|
||||||
public virtual Node CopyNode(Node original)
|
public virtual Node CopyNode(Node original) {
|
||||||
{
|
|
||||||
Node.graphHotfix = this;
|
Node.graphHotfix = this;
|
||||||
Node node = ScriptableObject.Instantiate(original);
|
Node node = ScriptableObject.Instantiate(original);
|
||||||
node.graph = this;
|
node.graph = this;
|
||||||
@ -42,20 +37,16 @@ namespace XNode
|
|||||||
|
|
||||||
/// <summary> Safely remove a node and all its connections </summary>
|
/// <summary> Safely remove a node and all its connections </summary>
|
||||||
/// <param name="node"> The node to remove </param>
|
/// <param name="node"> The node to remove </param>
|
||||||
public virtual void RemoveNode(Node node)
|
public virtual void RemoveNode(Node node) {
|
||||||
{
|
|
||||||
node.ClearConnections();
|
node.ClearConnections();
|
||||||
nodes.Remove(node);
|
nodes.Remove(node);
|
||||||
if (Application.isPlaying) Destroy(node);
|
if (Application.isPlaying) Destroy(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Remove all nodes and connections from the graph </summary>
|
/// <summary> Remove all nodes and connections from the graph </summary>
|
||||||
public virtual void Clear()
|
public virtual void Clear() {
|
||||||
{
|
if (Application.isPlaying) {
|
||||||
if (Application.isPlaying)
|
for (int i = 0; i < nodes.Count; i++) {
|
||||||
{
|
|
||||||
for (int i = 0; i < nodes.Count; i++)
|
|
||||||
{
|
|
||||||
Destroy(nodes[i]);
|
Destroy(nodes[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,13 +54,11 @@ namespace XNode
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Create a new deep copy of this graph </summary>
|
/// <summary> Create a new deep copy of this graph </summary>
|
||||||
public virtual XNode.NodeGraph Copy()
|
public virtual XNode.NodeGraph Copy() {
|
||||||
{
|
|
||||||
// Instantiate a new nodegraph instance
|
// Instantiate a new nodegraph instance
|
||||||
NodeGraph graph = Instantiate(this);
|
NodeGraph graph = Instantiate(this);
|
||||||
// Instantiate all nodes inside the graph
|
// Instantiate all nodes inside the graph
|
||||||
for (int i = 0; i < nodes.Count; i++)
|
for (int i = 0; i < nodes.Count; i++) {
|
||||||
{
|
|
||||||
if (nodes[i] == null) continue;
|
if (nodes[i] == null) continue;
|
||||||
Node.graphHotfix = graph;
|
Node.graphHotfix = graph;
|
||||||
Node node = Instantiate(nodes[i]) as Node;
|
Node node = Instantiate(nodes[i]) as Node;
|
||||||
@ -78,11 +67,9 @@ namespace XNode
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Redirect all connections
|
// Redirect all connections
|
||||||
for (int i = 0; i < graph.nodes.Count; i++)
|
for (int i = 0; i < graph.nodes.Count; i++) {
|
||||||
{
|
|
||||||
if (graph.nodes[i] == null) continue;
|
if (graph.nodes[i] == null) continue;
|
||||||
foreach (NodePort port in graph.nodes[i].Ports)
|
foreach (NodePort port in graph.nodes[i].Ports) {
|
||||||
{
|
|
||||||
port.Redirect(nodes, graph.nodes);
|
port.Redirect(nodes, graph.nodes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,17 +77,14 @@ namespace XNode
|
|||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnDestroy()
|
protected virtual void OnDestroy() {
|
||||||
{
|
|
||||||
// Remove all nodes prior to graph destruction
|
// Remove all nodes prior to graph destruction
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary> Is called when something is dragged in the editor </summary>
|
/// <summary> Is called when something is dragged in the editor </summary>
|
||||||
/// <param name="droppedObject">The dropped object</param>
|
/// <param name="droppedObject">The dropped object</param>
|
||||||
public virtual void OnDrop(object droppedObject, Vector2 dropPosition)
|
public virtual void OnDrop(object droppedObject, Vector2 dropPosition) {
|
||||||
{
|
|
||||||
Debug.LogWarning("No OnDrop(NodePort port) override defined for " + GetType());
|
Debug.LogWarning("No OnDrop(NodePort port) override defined for " + GetType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user