123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEditor;
- using UnityEngine;
- using XNode;
- using XNodeEditor.Internal;
- namespace XNodeEditor
- {
- public partial class NodeEditorWindow
- {
- public enum NodeActivity
- {
- Idle,
- HoldNode,
- DragNode,
- HoldGrid,
- DragGrid
- }
- public static NodeActivity currentActivity = NodeActivity.Idle;
- 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; }
- }
- private bool IsHoveringReroute
- {
- get { return hoveredReroute.port != null; }
- }
- private XNode.Node hoveredNode = null;
- [NonSerialized] public XNode.NodePort hoveredPort = null;
- [NonSerialized] private XNode.NodePort draggedOutput = null;
- [NonSerialized] private XNode.NodePort draggedOutputTarget = null;
- [NonSerialized] private XNode.NodePort autoConnectOutput = null;
- [NonSerialized] private List<Vector2> draggedOutputReroutes = new List<Vector2>();
- private RerouteReference hoveredReroute = new RerouteReference();
- public List<RerouteReference> selectedReroutes = new List<RerouteReference>();
- private Vector2 dragBoxStart;
- private List<Node> preBoxSelection;
- private RerouteReference[] preBoxSelectionReroute;
- private Rect selectionBox;
- private bool isDoubleClick = false;
- private Vector2 lastMousePosition;
- private float dragThreshold = 1f;
- 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;
- if (e.delta.y > 0) zoom += 0.1f * zoom;
- else zoom -= 0.1f * zoom;
- if (NodeEditorPreferences.GetSettings().zoomToMouse)
- panOffset += (1 - oldZoom / zoom) * (WindowToGridPosition(e.mousePosition) + panOffset);
- break;
- case EventType.MouseDrag:
- if (e.button == 0)
- {
- if (IsDraggingPort)
- {
- // Set target even if we can't connect, so as to prevent auto-conn menu from opening erroneously
- if (IsHoveringPort && hoveredPort.IsInput && !draggedOutput.IsConnectedTo(hoveredPort))
- {
- draggedOutputTarget = hoveredPort;
- }
- else
- {
- draggedOutputTarget = null;
- }
- Repaint();
- }
- else if (currentActivity == NodeActivity.HoldNode)
- {
- RecalculateDragOffsets(e);
- currentActivity = NodeActivity.DragNode;
- Repaint();
- }
- if (currentActivity == NodeActivity.DragNode)
- {
- // Holding ctrl inverts grid snap
- bool gridSnap = NodeEditorPreferences.GetSettings().gridSnap;
- if (e.control) gridSnap = !gridSnap;
- Vector2 mousePos = WindowToGridPosition(e.mousePosition);
- // Move selected nodes with offset
- for (int i = 0; i < _selectedNodes.Count; i++)
- {
- XNode.Node node = _selectedNodes[i];
- if (node == null)
- continue;
- Undo.RecordObject(node, "Moved Node");
- Vector2 initial = node.position;
- try
- {
- node.position = mousePos + dragOffset[i];
- }
- catch (Exception exception)
- {
- Console.WriteLine(exception);
- throw;
- }
- if (gridSnap)
- {
- node.position.x = (Mathf.Round((node.position.x + 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.
- Vector2 offset = node.position - initial;
- if (offset.sqrMagnitude > 0)
- {
- foreach (XNode.NodePort output in node.Outputs)
- {
- Rect rect;
- if (portConnectionPoints.TryGetValue(output, out rect))
- {
- rect.position += offset;
- portConnectionPoints[output] = rect;
- }
- }
- foreach (XNode.NodePort input in node.Inputs)
- {
- Rect rect;
- if (portConnectionPoints.TryGetValue(input, out rect))
- {
- rect.position += offset;
- portConnectionPoints[input] = rect;
- }
- }
- }
- }
- // Move selected reroutes with offset
- for (int i = 0; i < selectedReroutes.Count; i++)
- {
- Vector2 pos = mousePos + dragOffset[_selectedNodes.Count + i];
- if (gridSnap)
- {
- pos.x = (Mathf.Round(pos.x / 16) * 16);
- pos.y = (Mathf.Round(pos.y / 16) * 16);
- }
- selectedReroutes[i].SetPoint(pos);
- }
- Repaint();
- }
- else if (currentActivity == NodeActivity.HoldGrid)
- {
- currentActivity = NodeActivity.DragGrid;
- preBoxSelection = _selectedNodes;
- preBoxSelectionReroute = selectedReroutes.ToArray();
- dragBoxStart = WindowToGridPosition(e.mousePosition);
- Repaint();
- }
- else if (currentActivity == NodeActivity.DragGrid)
- {
- Vector2 boxStartPos = GridToWindowPosition(dragBoxStart);
- Vector2 boxSize = e.mousePosition - boxStartPos;
- if (boxSize.x < 0)
- {
- boxStartPos.x += boxSize.x;
- boxSize.x = Mathf.Abs(boxSize.x);
- }
- if (boxSize.y < 0)
- {
- boxStartPos.y += boxSize.y;
- boxSize.y = Mathf.Abs(boxSize.y);
- }
- selectionBox = new Rect(boxStartPos, boxSize);
- Repaint();
- }
- }
- else if (e.button == 1 || e.button == 2)
- {
- //check drag threshold for larger screens
- if (e.delta.magnitude > dragThreshold)
- {
- panOffset += e.delta * zoom;
- isPanning = true;
- }
- }
- break;
- case EventType.MouseDown:
- Repaint();
- if (e.button == 0)
- {
- draggedOutputReroutes.Clear();
- if (IsHoveringPort)
- {
- if (hoveredPort.IsOutput)
- {
- draggedOutput = hoveredPort;
- autoConnectOutput = hoveredPort;
- }
- else
- {
- hoveredPort.VerifyConnections();
- autoConnectOutput = null;
- if (hoveredPort.IsConnected)
- {
- XNode.Node node = hoveredPort.node;
- XNode.NodePort output = hoveredPort.Connection;
- int outputConnectionIndex = output.GetConnectionIndex(hoveredPort);
- draggedOutputReroutes = output.GetReroutePoints(outputConnectionIndex);
- hoveredPort.Disconnect(output);
- draggedOutput = output;
- draggedOutputTarget = hoveredPort;
- if (NodeEditor.onUpdateNode != null) NodeEditor.onUpdateNode(node);
- }
- }
- }
- else if (IsHoveringNode && IsHoveringTitle(hoveredNode))
- {
- // If mousedown on node header, select or deselect
- if (!_selectedNodes.Contains(hoveredNode))
- {
- if (e.control || e.shift)
- {
- SelectNode(hoveredNode, true);
- }
- else
- {
- SelectNode(hoveredNode, false);
- }
- if (!e.control && !e.shift) selectedReroutes.Clear();
- }
- // Cache double click state, but only act on it in MouseUp - Except ClickCount only works in mouseDown.
- isDoubleClick = (e.clickCount == 2);
- e.Use();
- currentActivity = NodeActivity.HoldNode;
- }
- else if (IsHoveringReroute)
- {
- // If reroute isn't selected
- if (!selectedReroutes.Contains(hoveredReroute))
- {
- // Add it
- if (e.control || e.shift) selectedReroutes.Add(hoveredReroute);
- // Select it
- else
- {
- selectedReroutes = new List<RerouteReference>() { hoveredReroute };
- Selection.activeObject = null;
- }
- }
- // Deselect
- else if (e.control || e.shift) selectedReroutes.Remove(hoveredReroute);
- e.Use();
- currentActivity = NodeActivity.HoldNode;
- }
- // If mousedown on grid background, deselect all
- else if (!IsHoveringNode)
- {
- // 暂时屏蔽以前的逻辑了
- currentActivity = NodeActivity.HoldGrid;
- if (!e.control && !e.shift)
- {
- selectedReroutes.Clear();
- _selectedNodes.Clear();
- }
- }
- }
- break;
- case EventType.MouseUp:
- if (e.button == 0)
- {
- //Port drag release
- if (IsDraggingPort)
- {
- // If connection is valid, save it
- if (draggedOutputTarget != null && draggedOutput.CanConnectTo(draggedOutputTarget))
- {
- XNode.Node node = draggedOutputTarget.node;
- if (graph.nodes.Count != 0) draggedOutput.Connect(draggedOutputTarget);
- // ConnectionIndex can be -1 if the connection is removed instantly after creation
- int connectionIndex = draggedOutput.GetConnectionIndex(draggedOutputTarget);
- if (connectionIndex != -1)
- {
- draggedOutput.GetReroutePoints(connectionIndex).AddRange(draggedOutputReroutes);
- if (NodeEditor.onUpdateNode != null) NodeEditor.onUpdateNode(node);
- EditorUtility.SetDirty(graph);
- }
- }
- // Open context menu for auto-connection if there is no target node
- else if (draggedOutputTarget == null && NodeEditorPreferences.GetSettings().dragToCreate &&
- autoConnectOutput != null)
- {
- GenericMenu menu = new GenericMenu();
- graphEditor.AddContextMenuItems(menu);
- menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
- }
- //Release dragged connection
- draggedOutput = null;
- draggedOutputTarget = null;
- EditorUtility.SetDirty(graph);
- if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
- }
- else if (currentActivity == NodeActivity.DragNode)
- {
- IEnumerable<XNode.Node> nodes = _selectedNodes;
- foreach (XNode.Node node in nodes) EditorUtility.SetDirty(node);
- if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
- }
- else if (!IsHoveringNode)
- {
- // If click outside node, release field focus
- if (!isPanning)
- {
- EditorGUI.FocusTextInControl(null);
- EditorGUIUtility.editingTextField = false;
- }
- if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
- }
- // If click node header, select it.
- if (currentActivity == NodeActivity.HoldNode && !(e.control || e.shift))
- {
- selectedReroutes.Clear();
- SelectNode(hoveredNode, false);
- // Double click to center node
- if (isDoubleClick)
- {
- Vector2 nodeDimension = nodeSizes.ContainsKey(hoveredNode)
- ? nodeSizes[hoveredNode] / 2
- : Vector2.zero;
- panOffset = -hoveredNode.position - nodeDimension;
- }
- }
- // If click reroute, select it.
- if (IsHoveringReroute && !(e.control || e.shift))
- {
- selectedReroutes = new List<RerouteReference>() { hoveredReroute };
- _selectedNodes.Clear();
- }
- Repaint();
- currentActivity = NodeActivity.Idle;
- }
- else if (e.button == 1 || e.button == 2)
- {
- if (!isPanning)
- {
- if (IsDraggingPort)
- {
- draggedOutputReroutes.Add(WindowToGridPosition(e.mousePosition));
- }
- else if (currentActivity == NodeActivity.DragNode && Selection.activeObject == null &&
- selectedReroutes.Count == 1)
- {
- selectedReroutes[0].InsertPoint(selectedReroutes[0].GetPoint());
- selectedReroutes[0] = new RerouteReference(selectedReroutes[0].port,
- selectedReroutes[0].connectionIndex, selectedReroutes[0].pointIndex + 1);
- }
- else if (IsHoveringReroute)
- {
- ShowRerouteContextMenu(hoveredReroute);
- }
- else if (IsHoveringPort)
- {
- ShowPortContextMenu(hoveredPort);
- }
- else if (IsHoveringNode && IsHoveringTitle(hoveredNode))
- {
- if (!Selection.Contains(hoveredNode)) SelectNode(hoveredNode, false);
- autoConnectOutput = null;
- GenericMenu menu = new GenericMenu();
- NodeEditor.GetEditor(hoveredNode, this).AddContextMenuItems(menu);
- 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.
- }
- else if (!IsHoveringNode)
- {
- autoConnectOutput = null;
- GenericMenu menu = new GenericMenu();
- graphEditor.AddContextMenuItems(menu);
- menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
- }
- }
- isPanning = false;
- }
- // Reset DoubleClick
- isDoubleClick = false;
- break;
- case EventType.KeyDown:
- // if (EditorGUIUtility.editingTextField) break;
- // else if (e.keyCode == KeyCode.F) Home();
- // if (NodeEditorUtilities.IsMac())
- // {
- // if (e.keyCode == KeyCode.Return) RenameSelectedNode();
- // }
- // else
- // {
- // if (e.keyCode == KeyCode.F2) RenameSelectedNode();
- // }
- //
- // if (e.keyCode == KeyCode.A)
- // {
- // if (Selection.objects.Any(x => graph.nodes.Contains(x as XNode.Node)))
- // {
- // foreach (XNode.Node node in graph.nodes)
- // {
- // DeselectNode(node);
- // }
- // }
- // else
- // {
- // foreach (XNode.Node node in graph.nodes)
- // {
- // SelectNode(node, true);
- // }
- // }
- //
- // Repaint();
- // }
- //
- // break;
- case EventType.ValidateCommand:
- case EventType.ExecuteCommand:
- if (e.commandName == "SoftDelete")
- {
- if (e.type == EventType.ExecuteCommand) RemoveSelectedNodes();
- e.Use();
- }
- else if (NodeEditorUtilities.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;
- case EventType.Ignore:
- // If release mouse outside window
- if (e.rawType == EventType.MouseUp && currentActivity == NodeActivity.DragGrid)
- {
- Repaint();
- currentActivity = NodeActivity.Idle;
- }
- break;
- }
- }
- private void RecalculateDragOffsets(Event current)
- {
- dragOffset = new Vector2[_selectedNodes.Count + selectedReroutes.Count];
- // Selected nodes
- for (int i = 0; i < _selectedNodes.Count; i++)
- {
- Node node = _selectedNodes[i];
- dragOffset[i] = node.position - WindowToGridPosition(current.mousePosition);
- }
- // Selected reroutes
- for (int i = 0; i < selectedReroutes.Count; i++)
- {
- dragOffset[_selectedNodes.Count + i] =
- selectedReroutes[i].GetPoint() - WindowToGridPosition(current.mousePosition);
- }
- }
- /// <summary> Puts all selected nodes in focus. If no nodes are present, resets view and zoom to to origin </summary>
- public void Home()
- {
- if (_selectedNodes.Count > 0)
- {
- Vector2 minPos = _selectedNodes.Select(x => x.position)
- .Aggregate((x, y) => new Vector2(Mathf.Min(x.x, y.x), Mathf.Min(x.y, y.y)));
- Vector2 maxPos = _selectedNodes
- .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 _selectedNodes</summary>
- public void RemoveSelectedNodes()
- {
- // We need to delete reroutes starting at the highest point index to avoid shifting indices
- selectedReroutes = selectedReroutes.OrderByDescending(x => x.pointIndex).ToList();
- for (int i = 0; i < selectedReroutes.Count; i++)
- {
- selectedReroutes[i].RemovePoint();
- }
- selectedReroutes.Clear();
- foreach (var node in _selectedNodes)
- {
- if (!node.IsRemove())
- {
- continue;
- }
- graphEditor.RemoveNode(node);
- }
- }
- /// <summary> Initiate a rename on the currently selected node </summary>
- public void RenameSelectedNode()
- {
- if (_selectedNodes.Count == 1 && Selection.activeObject is XNode.Node)
- {
- XNode.Node node = Selection.activeObject as XNode.Node;
- Vector2 size;
- if (nodeSizes.TryGetValue(node, out size))
- {
- RenamePopup.Show(Selection.activeObject, size.x);
- }
- else
- {
- RenamePopup.Show(Selection.activeObject);
- }
- }
- }
- /// <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)
- {
- int index;
- while ((index = graph.nodes.IndexOf(node)) != graph.nodes.Count - 1)
- {
- graph.nodes[index] = graph.nodes[index + 1];
- graph.nodes[index + 1] = node;
- }
- }
- /// <summary> Duplicate selected nodes and select the duplicates </summary>
- public void DuplicateSelectedNodes()
- {
- // Get selected nodes which are part of this graph
- XNode.Node[] selectedNodes = _selectedNodes.Select(x => x as XNode.Node)
- .Where(x => x != null && x.graph == graph).ToArray();
- if (selectedNodes == null || selectedNodes.Length == 0) return;
- // 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 = _selectedNodes.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;
- List<Node> newNodes = new List<Node>();
- Dictionary<XNode.Node, XNode.Node> substitutes = new Dictionary<XNode.Node, XNode.Node>();
- for (int i = 0; i < nodes.Length; i++)
- {
- XNode.Node srcNode = nodes[i];
- if (srcNode == null) continue;
- // Check if user is allowed to add more of given node type
- XNode.Node.DisallowMultipleNodesAttribute disallowAttrib;
- Type nodeType = srcNode.GetType();
- if (NodeEditorUtilities.GetAttrib(nodeType, out disallowAttrib))
- {
- int typeCount = graph.nodes.Count(x => x.GetType() == nodeType);
- if (typeCount >= disallowAttrib.max) continue;
- }
- XNode.Node newNode = graphEditor.CopyNode(srcNode);
- substitutes.Add(srcNode, newNode);
- newNode.position = srcNode.position + offset;
- newNode.ResetUniqueID();
- newNodes.Add(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);
- XNode.Node newNodeIn, newNodeOut;
- if (substitutes.TryGetValue(inputPort.node, out newNodeIn) &&
- substitutes.TryGetValue(outputPort.node, out newNodeOut))
- {
- newNodeIn.UpdatePorts();
- newNodeOut.UpdatePorts();
- inputPort = newNodeIn.GetInputPort(inputPort.fieldName);
- outputPort = newNodeOut.GetOutputPort(outputPort.fieldName);
- }
- if (!inputPort.IsConnectedTo(outputPort)) inputPort.Connect(outputPort);
- }
- }
- }
- // Select the new nodes
- _selectedNodes = newNodes;
- }
- /// <summary> Draw a connection as we are dragging it </summary>
- public void DrawDraggedConnection()
- {
- if (IsDraggingPort)
- {
- Gradient gradient = graphEditor.GetNoodleGradient(draggedOutput, null);
- float thickness = graphEditor.GetNoodleThickness(draggedOutput, null);
- NoodlePath path = graphEditor.GetNoodlePath(draggedOutput, null);
- NoodleStroke stroke = graphEditor.GetNoodleStroke(draggedOutput, null);
- Rect fromRect;
- if (!_portConnectionPoints.TryGetValue(draggedOutput, out fromRect)) return;
- List<Vector2> gridPoints = new List<Vector2>();
- gridPoints.Add(fromRect.center);
- for (int i = 0; i < draggedOutputReroutes.Count; i++)
- {
- gridPoints.Add(draggedOutputReroutes[i]);
- }
- if (draggedOutputTarget != null) gridPoints.Add(portConnectionPoints[draggedOutputTarget].center);
- else gridPoints.Add(WindowToGridPosition(Event.current.mousePosition));
- DrawNoodle(gradient, path, stroke, thickness, gridPoints);
- Color bgcol = Color.black;
- Color frcol = gradient.colorKeys[0].color;
- bgcol.a = 0.6f;
- frcol.a = 0.6f;
- // Loop through reroute points again and draw the points
- for (int i = 0; i < draggedOutputReroutes.Count; i++)
- {
- // Draw reroute point at position
- Rect rect = new Rect(draggedOutputReroutes[i], new Vector2(16, 16));
- rect.position = new Vector2(rect.position.x - 8, rect.position.y - 8);
- rect = GridToWindowRect(rect);
- NodeEditorGUILayout.DrawPortHandle(rect, bgcol, frcol);
- }
- }
- }
- bool IsHoveringTitle(XNode.Node node)
- {
- Vector2 mousePos = Event.current.mousePosition;
- //Get node position
- Vector2 nodePos = GridToWindowPosition(node.position);
- float width;
- Vector2 size;
- if (nodeSizes.TryGetValue(node, out size)) width = size.x;
- else width = 200;
- Rect windowRect = new Rect(nodePos, new Vector2(width / zoom, 30 / zoom));
- return windowRect.Contains(mousePos);
- }
- /// <summary> Attempt to connect dragged output to target node </summary>
- public void AutoConnect(XNode.Node node)
- {
- if (autoConnectOutput == null) return;
- // Find input port of same type
- XNode.NodePort inputPort =
- node.Ports.FirstOrDefault(x => x.IsInput && x.ValueType == autoConnectOutput.ValueType);
- // Fallback to input port
- if (inputPort == null) inputPort = node.Ports.FirstOrDefault(x => x.IsInput);
- // Autoconnect if connection is compatible
- if (inputPort != null && inputPort.CanConnectTo(autoConnectOutput)) autoConnectOutput.Connect(inputPort);
- // Save changes
- EditorUtility.SetDirty(graph);
- if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
- autoConnectOutput = null;
- }
- }
- }
|