1
0
mirror of https://github.com/Siccity/xNode.git synced 2025-12-20 17:26:02 +08:00

Added virtual NodeEditorGraph.GetNoodlePath and GetNoodleStroke for additional customization

This commit is contained in:
Thor Brigsted 2019-10-17 00:16:36 +02:00
parent 08af93c2e3
commit 421fb5747e
4 changed files with 66 additions and 33 deletions

View File

@ -473,6 +473,8 @@ namespace XNodeEditor {
if (IsDraggingPort) { if (IsDraggingPort) {
Gradient gradient = graphEditor.GetNoodleGradient(draggedOutput, null); Gradient gradient = graphEditor.GetNoodleGradient(draggedOutput, null);
float thickness = graphEditor.GetNoodleThickness(draggedOutput, null); float thickness = graphEditor.GetNoodleThickness(draggedOutput, null);
NoodlePath path = graphEditor.GetNoodlePath(draggedOutput, null);
NoodleStroke stroke = graphEditor.GetNoodleStroke(draggedOutput, null);
Rect fromRect; Rect fromRect;
if (!_portConnectionPoints.TryGetValue(draggedOutput, out fromRect)) return; if (!_portConnectionPoints.TryGetValue(draggedOutput, out fromRect)) return;
@ -484,7 +486,7 @@ namespace XNodeEditor {
if (draggedOutputTarget != null) gridPoints.Add(portConnectionPoints[draggedOutputTarget].center); if (draggedOutputTarget != null) gridPoints.Add(portConnectionPoints[draggedOutputTarget].center);
else gridPoints.Add(WindowToGridPosition(Event.current.mousePosition)); else gridPoints.Add(WindowToGridPosition(Event.current.mousePosition));
DrawNoodle(gradient, thickness, gridPoints); DrawNoodle(gradient, path, stroke, thickness, gridPoints);
Color bgcol = Color.black; Color bgcol = Color.black;
Color frcol = gradient.colorKeys[0].color; Color frcol = gradient.colorKeys[0].color;

View File

@ -117,12 +117,12 @@ namespace XNodeEditor {
} }
/// <summary> Draw a bezier from output to input in grid coordinates </summary> /// <summary> Draw a bezier from output to input in grid coordinates </summary>
public void DrawNoodle(Gradient gradient, float width, List<Vector2> gridPoints) { public void DrawNoodle(Gradient gradient, NoodlePath path, NoodleStroke stroke, float thickness, List<Vector2> gridPoints) {
Vector2[] windowPoints = gridPoints.Select(x => GridToWindowPosition(x)).ToArray(); Vector2[] windowPoints = gridPoints.Select(x => GridToWindowPosition(x)).ToArray();
Handles.color = gradient.Evaluate(0f); Handles.color = gradient.Evaluate(0f);
int length = gridPoints.Count; int length = gridPoints.Count;
switch (NodeEditorPreferences.GetSettings().noodleType) { switch (path) {
case NodeEditorPreferences.NoodleType.Curve: case NoodlePath.Curvy:
Vector2 outputTangent = Vector2.right; Vector2 outputTangent = Vector2.right;
for (int i = 0; i < length - 1; i++) { for (int i = 0; i < length - 1; i++) {
Vector2 inputTangent = Vector2.left; Vector2 inputTangent = Vector2.left;
@ -150,31 +150,47 @@ namespace XNodeEditor {
Vector2 tangent_a = point_a + outputTangent * 50 / zoom; Vector2 tangent_a = point_a + outputTangent * 50 / zoom;
Vector2 tangent_b = point_b + inputTangent * 50 / zoom; Vector2 tangent_b = point_b + inputTangent * 50 / zoom;
// Hover effect. // Hover effect.
int division = Mathf.RoundToInt(.1f * dist_ab) + 3; int division = Mathf.RoundToInt(.2f * dist_ab) + 3;
Vector3[] points = Handles.MakeBezierPoints(point_a, point_b, tangent_a, tangent_b, division); Vector3[] points = Handles.MakeBezierPoints(point_a, point_b, tangent_a, tangent_b, division);
int draw = 0;
// Coloring and bezier drawing. // Coloring and bezier drawing.
for (int j = 0; j < points.Length - 1; j++) { for (int j = 0; j < points.Length - 1; j++) {
if (stroke == NoodleStroke.Dashed) {
draw++;
if (draw >= 2) draw = -2;
if (draw < 0) continue;
}
if (i == gridPoints.Count - 2) Handles.color = gradient.Evaluate((j + 1f) / points.Length); if (i == gridPoints.Count - 2) Handles.color = gradient.Evaluate((j + 1f) / points.Length);
Handles.DrawAAPolyLine(width, points[j], points[j + 1]); Handles.DrawAAPolyLine(thickness, points[j], points[j + 1]);
} }
outputTangent = -inputTangent; outputTangent = -inputTangent;
} }
break; break;
case NodeEditorPreferences.NoodleType.Line: case NoodlePath.Straight:
for (int i = 0; i < length - 1; i++) { for (int i = 0; i < length - 1; i++) {
Vector2 point_a = windowPoints[i]; Vector2 point_a = windowPoints[i];
Vector2 point_b = windowPoints[i + 1]; Vector2 point_b = windowPoints[i + 1];
// Draws the line with the coloring. // Draws the line with the coloring.
Vector2 prev_point = point_a; Vector2 prev_point = point_a;
for (float j = 0; j < 1; j += 10f / Vector2.Distance(point_a, point_b)) { // Approximately one segment per 5 pixels
Vector2 lerp = Vector2.Lerp(point_a, point_b, j); int segments = (int) Vector2.Distance(point_a, point_b) / 5;
if (i == gridPoints.Count - 2) Handles.color = gradient.Evaluate(j);
Handles.DrawAAPolyLine(width, prev_point, lerp); int draw = 0;
for (int j = 0; j <= segments; j++) {
draw++;
float t = j / (float) segments;
Vector2 lerp = Vector2.Lerp(point_a, point_b, t);
if (draw > 0) {
if (i == gridPoints.Count - 2) Handles.color = gradient.Evaluate(t);
Handles.DrawAAPolyLine(thickness, prev_point, lerp);
}
prev_point = lerp; prev_point = lerp;
if (stroke == NoodleStroke.Dashed && draw >= 2) draw = -2;
} }
} }
break; break;
case NodeEditorPreferences.NoodleType.Angled: case NoodlePath.Angled:
for (int i = 0; i < length - 1; i++) { for (int i = 0; i < length - 1; i++) {
if (i == length - 1) continue; // Skip last index if (i == length - 1) continue; // Skip last index
if (windowPoints[i].x <= windowPoints[i + 1].x - (50 / zoom)) { if (windowPoints[i].x <= windowPoints[i + 1].x - (50 / zoom)) {
@ -184,15 +200,15 @@ namespace XNodeEditor {
start_1.x = midpoint; start_1.x = midpoint;
end_1.x = midpoint; end_1.x = midpoint;
if (i == gridPoints.Count - 2) { if (i == gridPoints.Count - 2) {
Handles.DrawAAPolyLine(width, windowPoints[i], start_1); Handles.DrawAAPolyLine(thickness, windowPoints[i], start_1);
Handles.color = gradient.Evaluate(0.5f); Handles.color = gradient.Evaluate(0.5f);
Handles.DrawAAPolyLine(width, start_1, end_1); Handles.DrawAAPolyLine(thickness, start_1, end_1);
Handles.color = gradient.Evaluate(1f); Handles.color = gradient.Evaluate(1f);
Handles.DrawAAPolyLine(width, end_1, windowPoints[i + 1]); Handles.DrawAAPolyLine(thickness, end_1, windowPoints[i + 1]);
} else { } else {
Handles.DrawAAPolyLine(width, windowPoints[i], start_1); Handles.DrawAAPolyLine(thickness, windowPoints[i], start_1);
Handles.DrawAAPolyLine(width, start_1, end_1); Handles.DrawAAPolyLine(thickness, start_1, end_1);
Handles.DrawAAPolyLine(width, end_1, windowPoints[i + 1]); Handles.DrawAAPolyLine(thickness, end_1, windowPoints[i + 1]);
} }
} else { } else {
float midpoint = (windowPoints[i].y + windowPoints[i + 1].y) * 0.5f; float midpoint = (windowPoints[i].y + windowPoints[i + 1].y) * 0.5f;
@ -205,21 +221,21 @@ namespace XNodeEditor {
start_2.y = midpoint; start_2.y = midpoint;
end_2.y = midpoint; end_2.y = midpoint;
if (i == gridPoints.Count - 2) { if (i == gridPoints.Count - 2) {
Handles.DrawAAPolyLine(width, windowPoints[i], start_1); Handles.DrawAAPolyLine(thickness, windowPoints[i], start_1);
Handles.color = gradient.Evaluate(0.25f); Handles.color = gradient.Evaluate(0.25f);
Handles.DrawAAPolyLine(width, start_1, start_2); Handles.DrawAAPolyLine(thickness, start_1, start_2);
Handles.color = gradient.Evaluate(0.5f); Handles.color = gradient.Evaluate(0.5f);
Handles.DrawAAPolyLine(width, start_2, end_2); Handles.DrawAAPolyLine(thickness, start_2, end_2);
Handles.color = gradient.Evaluate(0.75f); Handles.color = gradient.Evaluate(0.75f);
Handles.DrawAAPolyLine(width, end_2, end_1); Handles.DrawAAPolyLine(thickness, end_2, end_1);
Handles.color = gradient.Evaluate(1f); Handles.color = gradient.Evaluate(1f);
Handles.DrawAAPolyLine(width, end_1, windowPoints[i + 1]); Handles.DrawAAPolyLine(thickness, end_1, windowPoints[i + 1]);
} else { } else {
Handles.DrawAAPolyLine(width, windowPoints[i], start_1); Handles.DrawAAPolyLine(thickness, windowPoints[i], start_1);
Handles.DrawAAPolyLine(width, start_1, start_2); Handles.DrawAAPolyLine(thickness, start_1, start_2);
Handles.DrawAAPolyLine(width, start_2, end_2); Handles.DrawAAPolyLine(thickness, start_2, end_2);
Handles.DrawAAPolyLine(width, end_2, end_1); Handles.DrawAAPolyLine(thickness, end_2, end_1);
Handles.DrawAAPolyLine(width, end_1, windowPoints[i + 1]); Handles.DrawAAPolyLine(thickness, end_1, windowPoints[i + 1]);
} }
} }
} }
@ -250,6 +266,8 @@ namespace XNodeEditor {
Gradient noodleGradient = graphEditor.GetNoodleGradient(output, input); Gradient noodleGradient = graphEditor.GetNoodleGradient(output, input);
float noodleThickness = graphEditor.GetNoodleThickness(output, input); float noodleThickness = graphEditor.GetNoodleThickness(output, input);
NoodlePath noodlePath = graphEditor.GetNoodlePath(output, input);
NoodleStroke noodleStroke = graphEditor.GetNoodleStroke(output, input);
// Error handling // Error handling
if (input == null) continue; //If a script has been updated and the port doesn't exist, it is removed and null is returned. If this happens, return. if (input == null) continue; //If a script has been updated and the port doesn't exist, it is removed and null is returned. If this happens, return.
@ -263,7 +281,7 @@ namespace XNodeEditor {
gridPoints.Add(fromRect.center); gridPoints.Add(fromRect.center);
gridPoints.AddRange(reroutePoints); gridPoints.AddRange(reroutePoints);
gridPoints.Add(toRect.center); gridPoints.Add(toRect.center);
DrawNoodle(noodleGradient, noodleThickness, gridPoints); DrawNoodle(noodleGradient, noodlePath, noodleStroke, noodleThickness, gridPoints);
// Loop through reroute points again and draw the points // Loop through reroute points again and draw the points
for (int i = 0; i < reroutePoints.Count; i++) { for (int i = 0; i < reroutePoints.Count; i++) {

View File

@ -2,10 +2,13 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization;
namespace XNodeEditor { namespace XNodeEditor {
public enum NoodlePath { Curvy, Straight, Angled }
public enum NoodleStroke { Full, Dashed }
public static class NodeEditorPreferences { public static class NodeEditorPreferences {
public enum NoodleType { Curve, Line, Angled }
/// <summary> The last editor we checked. This should be the one we modify </summary> /// <summary> The last editor we checked. This should be the one we modify </summary>
private static XNodeEditor.NodeGraphEditor lastEditor; private static XNodeEditor.NodeGraphEditor lastEditor;
@ -37,7 +40,8 @@ namespace XNodeEditor {
public bool portTooltips = true; public bool portTooltips = true;
[SerializeField] private string typeColorsData = ""; [SerializeField] private string typeColorsData = "";
[NonSerialized] public Dictionary<string, Color> typeColors = new Dictionary<string, Color>(); [NonSerialized] public Dictionary<string, Color> typeColors = new Dictionary<string, Color>();
public NoodleType noodleType = NoodleType.Curve; [FormerlySerializedAs("noodleType")] public NoodlePath noodlePath = NoodlePath.Curvy;
public NoodleStroke noodleStroke = NoodleStroke.Full;
private Texture2D _gridTexture; private Texture2D _gridTexture;
public Texture2D gridTexture { public Texture2D gridTexture {
@ -151,7 +155,8 @@ namespace XNodeEditor {
//Label //Label
EditorGUILayout.LabelField("Node", EditorStyles.boldLabel); EditorGUILayout.LabelField("Node", EditorStyles.boldLabel);
settings.highlightColor = EditorGUILayout.ColorField("Selection", settings.highlightColor); settings.highlightColor = EditorGUILayout.ColorField("Selection", settings.highlightColor);
settings.noodleType = (NoodleType) EditorGUILayout.EnumPopup("Noodle type", (Enum) settings.noodleType); settings.noodlePath = (NoodlePath) EditorGUILayout.EnumPopup("Noodle path", (Enum) settings.noodlePath);
settings.noodleStroke = (NoodleStroke) EditorGUILayout.EnumPopup("Noodle stroke", (Enum) settings.noodleStroke);
settings.portTooltips = EditorGUILayout.Toggle("Port Tooltips", settings.portTooltips); settings.portTooltips = EditorGUILayout.Toggle("Port Tooltips", settings.portTooltips);
settings.dragToCreate = EditorGUILayout.Toggle(new GUIContent("Drag to Create", "Drag a port connection anywhere on the grid to create and connect a node"), settings.dragToCreate); settings.dragToCreate = EditorGUILayout.Toggle(new GUIContent("Drag to Create", "Drag a port connection anywhere on the grid to create and connect a node"), settings.dragToCreate);
if (GUI.changed) { if (GUI.changed) {

View File

@ -101,6 +101,14 @@ namespace XNodeEditor {
return 5f; return 5f;
} }
public virtual NoodlePath GetNoodlePath(XNode.NodePort output, XNode.NodePort input) {
return NodeEditorPreferences.GetSettings().noodlePath;
}
public virtual NoodleStroke GetNoodleStroke(XNode.NodePort output, XNode.NodePort input) {
return NodeEditorPreferences.GetSettings().noodleStroke;
}
/// <summary> Returned color is used to color ports </summary> /// <summary> Returned color is used to color ports </summary>
public virtual Color GetPortColor(XNode.NodePort port) { public virtual Color GetPortColor(XNode.NodePort port) {
return GetTypeColor(port.ValueType); return GetTypeColor(port.ValueType);