mirror of
https://github.com/Siccity/xNode.git
synced 2025-12-22 02:06:05 +08:00
Added comments
This commit is contained in:
parent
a278f4c2f4
commit
4730f6a0df
@ -6,7 +6,7 @@ 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, HoldComment, ResizeComment }
|
||||||
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; }
|
||||||
public static Vector2[] dragOffset;
|
public static Vector2[] dragOffset;
|
||||||
@ -15,11 +15,17 @@ namespace XNodeEditor {
|
|||||||
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; } }
|
||||||
private bool IsHoveringReroute { get { return hoveredReroute.port != null; } }
|
private bool IsHoveringReroute { get { return hoveredReroute.port != null; } }
|
||||||
|
private bool IsHoveringComment { get { return hoveredComment != null; } }
|
||||||
|
private bool IsResizingComment { get { return resizingComment != null; } }
|
||||||
private XNode.Node hoveredNode = null;
|
private XNode.Node hoveredNode = null;
|
||||||
[NonSerialized] private XNode.NodePort hoveredPort = null;
|
[NonSerialized] private XNode.NodePort hoveredPort = null;
|
||||||
[NonSerialized] private XNode.NodePort draggedOutput = null;
|
[NonSerialized] private XNode.NodePort draggedOutput = null;
|
||||||
[NonSerialized] private XNode.NodePort draggedOutputTarget = null;
|
[NonSerialized] private XNode.NodePort draggedOutputTarget = null;
|
||||||
[NonSerialized] private List<Vector2> draggedOutputReroutes = new List<Vector2>();
|
[NonSerialized] private List<Vector2> draggedOutputReroutes = new List<Vector2>();
|
||||||
|
[NonSerialized] private XNode.NodeGraphComment hoveredComment = null;
|
||||||
|
[NonSerialized] private XNode.NodeGraphComment resizingComment = null;
|
||||||
|
public enum NodeGraphCommentSide { Top, TopRight, Right, BottomRight, Bottom, BottomLeft, Left, TopLeft }
|
||||||
|
public static NodeGraphCommentSide resizingCommentSide;
|
||||||
private RerouteReference hoveredReroute = new RerouteReference();
|
private RerouteReference hoveredReroute = new RerouteReference();
|
||||||
private List<RerouteReference> selectedReroutes = new List<RerouteReference>();
|
private List<RerouteReference> selectedReroutes = new List<RerouteReference>();
|
||||||
private Rect nodeRects;
|
private Rect nodeRects;
|
||||||
@ -68,7 +74,7 @@ namespace XNodeEditor {
|
|||||||
draggedOutputTarget = null;
|
draggedOutputTarget = null;
|
||||||
}
|
}
|
||||||
Repaint();
|
Repaint();
|
||||||
} else if (currentActivity == NodeActivity.HoldNode) {
|
} else if (currentActivity == NodeActivity.HoldNode || currentActivity == NodeActivity.HoldComment) {
|
||||||
RecalculateDragOffsets(e);
|
RecalculateDragOffsets(e);
|
||||||
currentActivity = NodeActivity.DragNode;
|
currentActivity = NodeActivity.DragNode;
|
||||||
Repaint();
|
Repaint();
|
||||||
@ -110,6 +116,15 @@ namespace XNodeEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(Selection.objects[i] is XNode.NodeGraphComment) {
|
||||||
|
XNode.NodeGraphComment comment = Selection.objects[i] as XNode.NodeGraphComment;
|
||||||
|
Vector2 initial = comment.position;
|
||||||
|
comment.position = mousePos + dragOffset[i];
|
||||||
|
if (gridSnap) {
|
||||||
|
comment.position.x = (Mathf.Round((comment.position.x + 8) / 16) * 16) - 8;
|
||||||
|
comment.position.y = (Mathf.Round((comment.position.y + 8) / 16) * 16) - 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 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++) {
|
||||||
@ -133,6 +148,44 @@ namespace XNodeEditor {
|
|||||||
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); }
|
||||||
if (boxSize.y < 0) { boxStartPos.y += boxSize.y; boxSize.y = Mathf.Abs(boxSize.y); }
|
if (boxSize.y < 0) { boxStartPos.y += boxSize.y; boxSize.y = Mathf.Abs(boxSize.y); }
|
||||||
selectionBox = new Rect(boxStartPos, boxSize);
|
selectionBox = new Rect(boxStartPos, boxSize);
|
||||||
|
Repaint();
|
||||||
|
} else if (currentActivity == NodeActivity.ResizeComment) {
|
||||||
|
switch (resizingCommentSide) {
|
||||||
|
case NodeGraphCommentSide.Top:
|
||||||
|
resizingComment.size.y -= e.delta.y;
|
||||||
|
resizingComment.position.y += e.delta.y;
|
||||||
|
break;
|
||||||
|
case NodeGraphCommentSide.TopRight:
|
||||||
|
resizingComment.size.y -= e.delta.y;
|
||||||
|
resizingComment.position.y += e.delta.y;
|
||||||
|
resizingComment.size.x += e.delta.x;
|
||||||
|
break;
|
||||||
|
case NodeGraphCommentSide.Right:
|
||||||
|
resizingComment.size.x += e.delta.x;
|
||||||
|
break;
|
||||||
|
case NodeGraphCommentSide.BottomRight:
|
||||||
|
resizingComment.size += e.delta;
|
||||||
|
break;
|
||||||
|
case NodeGraphCommentSide.Bottom:
|
||||||
|
resizingComment.size.y += e.delta.y;
|
||||||
|
break;
|
||||||
|
case NodeGraphCommentSide.BottomLeft:
|
||||||
|
resizingComment.size.x -= e.delta.x;
|
||||||
|
resizingComment.position.x += e.delta.x;
|
||||||
|
resizingComment.size.y += e.delta.y;
|
||||||
|
break;
|
||||||
|
case NodeGraphCommentSide.Left:
|
||||||
|
resizingComment.size.x -= e.delta.x;
|
||||||
|
resizingComment.position.x += e.delta.x;
|
||||||
|
break;
|
||||||
|
case NodeGraphCommentSide.TopLeft:
|
||||||
|
resizingComment.size.x -= e.delta.x;
|
||||||
|
resizingComment.position.x += e.delta.x;
|
||||||
|
resizingComment.size.y -= e.delta.y;
|
||||||
|
resizingComment.position.y += e.delta.y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Repaint();
|
Repaint();
|
||||||
}
|
}
|
||||||
} else if (e.button == 1 || e.button == 2) {
|
} else if (e.button == 1 || e.button == 2) {
|
||||||
@ -191,8 +244,33 @@ namespace XNodeEditor {
|
|||||||
e.Use();
|
e.Use();
|
||||||
currentActivity = NodeActivity.HoldNode;
|
currentActivity = NodeActivity.HoldNode;
|
||||||
}
|
}
|
||||||
|
else if (IsHoveringComment && !IsHoveringNode) {
|
||||||
|
if (!Selection.Contains(hoveredComment)) {
|
||||||
|
if (e.shift) {
|
||||||
|
SelectComment(hoveredComment, true);
|
||||||
|
SelectNodesInComment(hoveredComment);
|
||||||
|
}
|
||||||
|
else SelectComment(hoveredComment, e.control || e.shift);
|
||||||
|
}
|
||||||
|
else if (e.control || e.shift) {
|
||||||
|
DeselectComment(hoveredComment);
|
||||||
|
if (e.shift)
|
||||||
|
{
|
||||||
|
DeselectNodesInComment(hoveredComment);
|
||||||
|
}
|
||||||
|
} else SelectComment(hoveredComment, false);
|
||||||
|
|
||||||
|
e.Use();
|
||||||
|
currentActivity = NodeActivity.HoldComment;
|
||||||
|
} else if (IsResizingComment && !e.control && !e.shift) {
|
||||||
|
selectedReroutes.Clear();
|
||||||
|
Selection.activeObject = null;
|
||||||
|
|
||||||
|
e.Use();
|
||||||
|
currentActivity = NodeActivity.ResizeComment;
|
||||||
|
}
|
||||||
// If mousedown on grid background, deselect all
|
// If mousedown on grid background, deselect all
|
||||||
else if (!IsHoveringNode) {
|
else if (!IsHoveringNode && !IsHoveringComment) {
|
||||||
currentActivity = NodeActivity.HoldGrid;
|
currentActivity = NodeActivity.HoldGrid;
|
||||||
if (!e.control && !e.shift) {
|
if (!e.control && !e.shift) {
|
||||||
selectedReroutes.Clear();
|
selectedReroutes.Clear();
|
||||||
@ -227,7 +305,7 @@ namespace XNodeEditor {
|
|||||||
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 && !IsHoveringComment && !IsResizingComment) {
|
||||||
// If click outside node, release field focus
|
// If click outside node, release field focus
|
||||||
if (!isPanning) {
|
if (!isPanning) {
|
||||||
EditorGUI.FocusTextInControl(null);
|
EditorGUI.FocusTextInControl(null);
|
||||||
@ -265,6 +343,11 @@ namespace XNodeEditor {
|
|||||||
GenericMenu menu = new GenericMenu();
|
GenericMenu menu = new GenericMenu();
|
||||||
NodeEditor.GetEditor(hoveredNode).AddContextMenuItems(menu);
|
NodeEditor.GetEditor(hoveredNode).AddContextMenuItems(menu);
|
||||||
menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
|
menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
|
||||||
|
} else if (IsHoveringComment && !IsHoveringNode) {
|
||||||
|
if (!Selection.Contains(hoveredComment)) SelectComment(hoveredComment, false);
|
||||||
|
GenericMenu menu = new GenericMenu();
|
||||||
|
graphEditor.AddCommentContextMenuItems(menu);
|
||||||
|
menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
|
||||||
} else if (!IsHoveringNode) {
|
} else if (!IsHoveringNode) {
|
||||||
GenericMenu menu = new GenericMenu();
|
GenericMenu menu = new GenericMenu();
|
||||||
graphEditor.AddContextMenuItems(menu);
|
graphEditor.AddContextMenuItems(menu);
|
||||||
@ -315,6 +398,11 @@ namespace XNodeEditor {
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
else if (Selection.objects[i] is XNode.NodeGraphComment)
|
||||||
|
{
|
||||||
|
XNode.NodeGraphComment comment = Selection.objects[i] as XNode.NodeGraphComment;
|
||||||
|
dragOffset[i] = comment.position - WindowToGridPosition(current.mousePosition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Selected reroutes
|
// Selected reroutes
|
||||||
@ -342,6 +430,10 @@ namespace XNodeEditor {
|
|||||||
XNode.Node node = item as XNode.Node;
|
XNode.Node node = item as XNode.Node;
|
||||||
graphEditor.RemoveNode(node);
|
graphEditor.RemoveNode(node);
|
||||||
}
|
}
|
||||||
|
else if (item is XNode.NodeGraphComment) {
|
||||||
|
XNode.NodeGraphComment comment = item as XNode.NodeGraphComment;
|
||||||
|
graphEditor.RemoveComment(comment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,6 +445,15 @@ namespace XNodeEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Initiate a rename on the currently selected comment </summary>
|
||||||
|
public void RenameSelectedComment()
|
||||||
|
{
|
||||||
|
if (Selection.objects.Length == 1 && Selection.activeObject is XNode.NodeGraphComment)
|
||||||
|
{
|
||||||
|
renamingComment = Selection.activeObject as XNode.NodeGraphComment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <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;
|
||||||
@ -374,6 +475,12 @@ namespace XNodeEditor {
|
|||||||
substitutes.Add(srcNode, newNode);
|
substitutes.Add(srcNode, newNode);
|
||||||
newNode.position = srcNode.position + new Vector2(30, 30);
|
newNode.position = srcNode.position + new Vector2(30, 30);
|
||||||
newNodes[i] = newNode;
|
newNodes[i] = newNode;
|
||||||
|
} else if (Selection.objects[i] is XNode.NodeGraphComment) {
|
||||||
|
XNode.NodeGraphComment srcComment = Selection.objects[i] as XNode.NodeGraphComment;
|
||||||
|
if (srcComment.graph != graph) continue; // ignore comments selected in another graph
|
||||||
|
XNode.NodeGraphComment newComment = graphEditor.CopyComment(srcComment);
|
||||||
|
newComment.position = srcComment.position + new Vector2(30, 30);
|
||||||
|
newNodes[i] = newComment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,8 @@ namespace XNodeEditor {
|
|||||||
private int topPadding { get { return isDocked() ? 19 : 22; } }
|
private int topPadding { get { return isDocked() ? 19 : 22; } }
|
||||||
/// <summary> Executed after all other window GUI. Useful if Zoom is ruining your day. Automatically resets after being run.</summary>
|
/// <summary> Executed after all other window GUI. Useful if Zoom is ruining your day. Automatically resets after being run.</summary>
|
||||||
public event Action onLateGUI;
|
public event Action onLateGUI;
|
||||||
|
public XNode.NodeGraphComment renamingComment;
|
||||||
|
public bool renamingStarted = false;
|
||||||
|
|
||||||
private void OnGUI() {
|
private void OnGUI() {
|
||||||
Event e = Event.current;
|
Event e = Event.current;
|
||||||
@ -23,7 +25,13 @@ namespace XNodeEditor {
|
|||||||
|
|
||||||
Controls();
|
Controls();
|
||||||
|
|
||||||
|
if (e.type == EventType.Layout)
|
||||||
|
{
|
||||||
|
selectionCache = new List<UnityEngine.Object>(Selection.objects);
|
||||||
|
}
|
||||||
|
|
||||||
DrawGrid(position, zoom, panOffset);
|
DrawGrid(position, zoom, panOffset);
|
||||||
|
DrawComments();
|
||||||
DrawConnections();
|
DrawConnections();
|
||||||
DrawDraggedConnection();
|
DrawDraggedConnection();
|
||||||
DrawNodes();
|
DrawNodes();
|
||||||
@ -237,9 +245,6 @@ namespace XNodeEditor {
|
|||||||
|
|
||||||
private void DrawNodes() {
|
private void DrawNodes() {
|
||||||
Event e = Event.current;
|
Event e = Event.current;
|
||||||
if (e.type == EventType.Layout) {
|
|
||||||
selectionCache = new List<UnityEngine.Object>(Selection.objects);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Active node is hashed before and after node GUI to detect changes
|
//Active node is hashed before and after node GUI to detect changes
|
||||||
int nodeHash = 0;
|
int nodeHash = 0;
|
||||||
@ -419,5 +424,165 @@ namespace XNodeEditor {
|
|||||||
Repaint();
|
Repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawComments()
|
||||||
|
{
|
||||||
|
Event e = Event.current;
|
||||||
|
|
||||||
|
BeginZoomed(position, zoom, topPadding);
|
||||||
|
Vector2 mousePos = Event.current.mousePosition;
|
||||||
|
|
||||||
|
if (e.type != EventType.Layout) {
|
||||||
|
hoveredComment = null;
|
||||||
|
if (currentActivity != NodeActivity.ResizeComment) resizingComment = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<UnityEngine.Object> preSelection = preBoxSelection != null ? new List<UnityEngine.Object>(preBoxSelection) : new List<UnityEngine.Object>();
|
||||||
|
|
||||||
|
Vector2 boxStartPos = GridToWindowPositionNoClipped(dragBoxStart);
|
||||||
|
Vector2 boxSize = mousePos - 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); }
|
||||||
|
Rect selectionBox = new Rect(boxStartPos, boxSize);
|
||||||
|
|
||||||
|
for (int n = 0; n < graph.comments.Count; n++) {
|
||||||
|
XNode.NodeGraphComment comment = graph.comments[n];
|
||||||
|
if (comment == null) continue;
|
||||||
|
|
||||||
|
Vector2 commentPos = GridToWindowPositionNoClipped(comment.position);
|
||||||
|
GUILayout.BeginArea(new Rect(commentPos, new Vector2(comment.size.x, comment.size.y)));
|
||||||
|
|
||||||
|
bool selected = selectionCache.Contains(comment);
|
||||||
|
|
||||||
|
if (selected) {
|
||||||
|
GUIStyle style = new GUIStyle(NodeEditorResources.styles.commentBody);
|
||||||
|
GUIStyle highlightStyle = new GUIStyle(NodeEditorResources.styles.nodeHighlight);
|
||||||
|
highlightStyle.padding = style.padding;
|
||||||
|
style.padding = new RectOffset();
|
||||||
|
GUI.color = Color.white;
|
||||||
|
GUILayout.BeginVertical(style);
|
||||||
|
GUI.color = NodeEditorPreferences.GetSettings().highlightColor;
|
||||||
|
GUILayout.BeginVertical(new GUIStyle(highlightStyle));
|
||||||
|
} else {
|
||||||
|
GUIStyle style = new GUIStyle(NodeEditorResources.styles.commentBody);
|
||||||
|
GUI.color = Color.white;
|
||||||
|
GUILayout.BeginVertical(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renamingComment == comment) {
|
||||||
|
if (Selection.Contains(renamingComment)) {
|
||||||
|
int controlID = EditorGUIUtility.GetControlID(FocusType.Keyboard) + 1;
|
||||||
|
if (!renamingStarted) {
|
||||||
|
EditorGUIUtility.keyboardControl = controlID;
|
||||||
|
EditorGUIUtility.editingTextField = true;
|
||||||
|
renamingStarted = true;
|
||||||
|
}
|
||||||
|
comment.comment = EditorGUILayout.TextField(comment.comment, NodeEditorResources.styles.commentHeader, GUILayout.Height(26));
|
||||||
|
if (!EditorGUIUtility.editingTextField) {
|
||||||
|
Debug.Log("Finish renaming");
|
||||||
|
renamingComment = null;
|
||||||
|
renamingStarted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Selection changed, so stop renaming.
|
||||||
|
GUILayout.Label(comment.comment, NodeEditorResources.styles.commentHeader, GUILayout.Height(26));
|
||||||
|
renamingComment = null;
|
||||||
|
renamingStarted = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GUIStyle blackStyle = new GUIStyle(NodeEditorResources.styles.commentHeader);
|
||||||
|
blackStyle.normal.textColor = new Color(0.2f, 0.2f, 0.2f);
|
||||||
|
|
||||||
|
GUILayout.Label(comment.comment, blackStyle, GUILayout.Height(26));
|
||||||
|
|
||||||
|
Rect lastRect = GUILayoutUtility.GetLastRect();
|
||||||
|
lastRect.x -= 0.5f;
|
||||||
|
lastRect.y -= 1;
|
||||||
|
GUI.Label(lastRect, comment.comment, NodeEditorResources.styles.commentHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GUILayout.FlexibleSpace();
|
||||||
|
|
||||||
|
GUILayout.EndVertical();
|
||||||
|
|
||||||
|
if (selected) GUILayout.EndVertical();
|
||||||
|
|
||||||
|
if (e.type != EventType.Layout && currentActivity != NodeActivity.ResizeComment) {
|
||||||
|
//Check if we are hovering this node
|
||||||
|
Vector2 commentSize = GUILayoutUtility.GetLastRect().size;
|
||||||
|
Rect windowRect = new Rect(commentPos, commentSize);
|
||||||
|
|
||||||
|
float padding = 12;
|
||||||
|
|
||||||
|
// Resizing areas
|
||||||
|
// Follows the NodeGraphCommentSide order
|
||||||
|
Rect[] resizeRects = new[] {
|
||||||
|
new Rect(padding, 0, commentSize.x - padding * 2, padding),
|
||||||
|
new Rect(commentSize.x - padding, 0, padding, padding),
|
||||||
|
new Rect(commentSize.x - padding, padding, padding, commentSize.y - padding * 2),
|
||||||
|
new Rect(commentSize.x - padding, commentSize.y - padding, padding, padding),
|
||||||
|
new Rect(padding, commentSize.y - padding, commentSize.x - padding * 2, padding),
|
||||||
|
new Rect(0, commentSize.y - padding, padding, padding),
|
||||||
|
new Rect(0, padding, padding, commentSize.y - padding * 2),
|
||||||
|
new Rect(0, 0, padding, padding),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Icons for the resize area list
|
||||||
|
MouseCursor[] resizeIcons = new[] {
|
||||||
|
MouseCursor.ResizeVertical,
|
||||||
|
MouseCursor.ResizeUpRight,
|
||||||
|
MouseCursor.ResizeHorizontal,
|
||||||
|
MouseCursor.ResizeUpLeft,
|
||||||
|
MouseCursor.ResizeVertical,
|
||||||
|
MouseCursor.ResizeUpRight,
|
||||||
|
MouseCursor.ResizeHorizontal,
|
||||||
|
MouseCursor.ResizeUpLeft,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < resizeRects.Length; i++) {
|
||||||
|
EditorGUIUtility.AddCursorRect(resizeRects[i], resizeIcons[i]);
|
||||||
|
|
||||||
|
// Transform the locations now to gui space locations
|
||||||
|
resizeRects[i].position += commentPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (windowRect.Contains(mousePos)) {
|
||||||
|
//If dragging a selection box, add nodes inside to selection
|
||||||
|
if (currentActivity == NodeActivity.DragGrid) {
|
||||||
|
if (windowRect.Overlaps(selectionBox)) preSelection.Add(comment);
|
||||||
|
} else {
|
||||||
|
// Check if we should resize or select
|
||||||
|
bool resizeAreaClicked = false;
|
||||||
|
for (int i = 0; i < resizeRects.Length; i++) {
|
||||||
|
if (resizeRects[i].Contains(mousePos)) {
|
||||||
|
resizingComment = comment;
|
||||||
|
// i can be cast to NodeGraphCommentSide as resizeRects
|
||||||
|
// has one element per NodeGraphCommentSide value and
|
||||||
|
// uses the same order
|
||||||
|
resizingCommentSide = (NodeGraphCommentSide)i;
|
||||||
|
resizeAreaClicked = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!resizeAreaClicked) hoveredComment = comment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//If dragging a selection box, add nodes inside to selection
|
||||||
|
if (currentActivity == NodeActivity.DragGrid) {
|
||||||
|
if (windowRect.Overlaps(selectionBox)) preSelection.Add(comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.EndArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.type != EventType.Layout && currentActivity == NodeActivity.DragGrid) Selection.objects = preSelection.ToArray();
|
||||||
|
EndZoomed(position, zoom, topPadding);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -12,13 +12,15 @@ namespace XNodeEditor {
|
|||||||
private static Texture2D _nodeBody;
|
private static Texture2D _nodeBody;
|
||||||
public static Texture2D nodeHighlight { get { return _nodeHighlight != null ? _nodeHighlight : _nodeHighlight = Resources.Load<Texture2D>("xnode_node_highlight"); } }
|
public static Texture2D nodeHighlight { get { return _nodeHighlight != null ? _nodeHighlight : _nodeHighlight = Resources.Load<Texture2D>("xnode_node_highlight"); } }
|
||||||
private static Texture2D _nodeHighlight;
|
private static Texture2D _nodeHighlight;
|
||||||
|
public static Texture2D commentBody { get { return _commentBody != null ? _commentBody : _commentBody = Resources.Load<Texture2D>("xnode_comment"); } }
|
||||||
|
private static Texture2D _commentBody;
|
||||||
|
|
||||||
// Styles
|
// Styles
|
||||||
public static Styles styles { get { return _styles != null ? _styles : _styles = new Styles(); } }
|
public static Styles styles { get { return _styles != null ? _styles : _styles = new Styles(); } }
|
||||||
public static Styles _styles = null;
|
public static Styles _styles = null;
|
||||||
public static GUIStyle OutputPort { get { return new GUIStyle(EditorStyles.label) { alignment = TextAnchor.UpperRight }; } }
|
public static GUIStyle OutputPort { get { return new GUIStyle(EditorStyles.label) { alignment = TextAnchor.UpperRight }; } }
|
||||||
public class Styles {
|
public class Styles {
|
||||||
public GUIStyle inputPort, nodeHeader, nodeBody, tooltip, nodeHighlight;
|
public GUIStyle inputPort, nodeHeader, nodeBody, tooltip, nodeHighlight, commentHeader, commentBody;
|
||||||
|
|
||||||
public Styles() {
|
public Styles() {
|
||||||
GUIStyle baseStyle = new GUIStyle("Label");
|
GUIStyle baseStyle = new GUIStyle("Label");
|
||||||
@ -44,6 +46,17 @@ namespace XNodeEditor {
|
|||||||
|
|
||||||
tooltip = new GUIStyle("helpBox");
|
tooltip = new GUIStyle("helpBox");
|
||||||
tooltip.alignment = TextAnchor.MiddleCenter;
|
tooltip.alignment = TextAnchor.MiddleCenter;
|
||||||
|
|
||||||
|
commentHeader = new GUIStyle();
|
||||||
|
commentHeader.alignment = TextAnchor.MiddleCenter;
|
||||||
|
commentHeader.fontStyle = FontStyle.Bold;
|
||||||
|
commentHeader.fontSize = 20;
|
||||||
|
commentHeader.normal.textColor = new Color(0.93f, 0.93f, 0.93f);
|
||||||
|
|
||||||
|
commentBody = new GUIStyle();
|
||||||
|
commentBody.normal.background = NodeEditorResources.commentBody;
|
||||||
|
commentBody.border = new RectOffset(32, 32, 32, 32);
|
||||||
|
commentBody.padding = new RectOffset(16, 16, 4, 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -142,6 +142,46 @@ namespace XNodeEditor {
|
|||||||
Selection.objects = selection.ToArray();
|
Selection.objects = selection.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SelectComment(XNode.NodeGraphComment comment, bool add) {
|
||||||
|
if (add) {
|
||||||
|
List<Object> selection = new List<Object>(Selection.objects);
|
||||||
|
selection.Add(comment);
|
||||||
|
Selection.objects = selection.ToArray();
|
||||||
|
} else Selection.objects = new Object[] { comment };
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeselectComment(XNode.NodeGraphComment comment) {
|
||||||
|
List<Object> selection = new List<Object>(Selection.objects);
|
||||||
|
selection.Remove(comment);
|
||||||
|
Selection.objects = selection.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectNodesInComment(XNode.NodeGraphComment comment) {
|
||||||
|
Rect commentRect = new Rect(comment.position, comment.size);
|
||||||
|
for (int i = 0; i < graph.nodes.Count; i++) {
|
||||||
|
XNode.Node node = graph.nodes[i];
|
||||||
|
if (!node) continue;
|
||||||
|
|
||||||
|
if (commentRect.Contains(node.position)) SelectNode(node, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeselectNodesInComment(XNode.NodeGraphComment comment)
|
||||||
|
{
|
||||||
|
List<Object> selection = new List<Object>(Selection.objects);
|
||||||
|
|
||||||
|
|
||||||
|
Rect commentRect = new Rect(comment.position, comment.size);
|
||||||
|
for (int i = 0; i < graph.nodes.Count; i++) {
|
||||||
|
XNode.Node node = graph.nodes[i];
|
||||||
|
if (!node) continue;
|
||||||
|
|
||||||
|
if (commentRect.Contains(node.position)) selection.Remove(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
Selection.objects = selection.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
[OnOpenAsset(0)]
|
[OnOpenAsset(0)]
|
||||||
public static bool OnOpen(int instanceID, int line) {
|
public static bool OnOpen(int instanceID, int line) {
|
||||||
XNode.NodeGraph nodeGraph = EditorUtility.InstanceIDToObject(instanceID) as XNode.NodeGraph;
|
XNode.NodeGraph nodeGraph = EditorUtility.InstanceIDToObject(instanceID) as XNode.NodeGraph;
|
||||||
|
|||||||
@ -53,10 +53,41 @@ namespace XNodeEditor {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
menu.AddSeparator("");
|
menu.AddSeparator("");
|
||||||
|
menu.AddItem(new GUIContent("Add comment"), false, () => CreateComment(pos));
|
||||||
|
menu.AddSeparator("");
|
||||||
menu.AddItem(new GUIContent("Preferences"), false, () => NodeEditorWindow.OpenPreferences());
|
menu.AddItem(new GUIContent("Preferences"), false, () => NodeEditorWindow.OpenPreferences());
|
||||||
NodeEditorWindow.AddCustomContextMenuItems(menu, target);
|
NodeEditorWindow.AddCustomContextMenuItems(menu, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Add items for the context menu when right-clicking this node. Override to add custom menu items. </summary>
|
||||||
|
public virtual void AddCommentContextMenuItems(GenericMenu menu) {
|
||||||
|
Vector2 pos = NodeEditorWindow.current.WindowToGridPosition(Event.current.mousePosition);
|
||||||
|
for (int i = 0; i < NodeEditorWindow.nodeTypes.Length; i++) {
|
||||||
|
Type type = NodeEditorWindow.nodeTypes[i];
|
||||||
|
|
||||||
|
//Get node context menu path
|
||||||
|
string path = GetNodeMenuName(type);
|
||||||
|
if (string.IsNullOrEmpty(path)) continue;
|
||||||
|
|
||||||
|
menu.AddItem(new GUIContent(path), false, () => {
|
||||||
|
CreateNode(type, pos);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.AddSeparator("");
|
||||||
|
menu.AddItem(new GUIContent("Add comment"), false, () => CreateComment(pos));
|
||||||
|
menu.AddSeparator("");
|
||||||
|
// Actions if only one node is selected
|
||||||
|
if (Selection.objects.Length == 1 && Selection.activeObject is XNode.NodeGraphComment) {
|
||||||
|
XNode.NodeGraphComment comment = Selection.activeObject as XNode.NodeGraphComment;
|
||||||
|
menu.AddItem(new GUIContent("Rename"), false, NodeEditorWindow.current.RenameSelectedComment);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add actions to any number of selected nodes
|
||||||
|
menu.AddItem(new GUIContent("Duplicate"), false, NodeEditorWindow.current.DuplicateSelectedNodes);
|
||||||
|
menu.AddItem(new GUIContent("Remove"), false, NodeEditorWindow.current.RemoveSelectedNodes);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual Color GetTypeColor(Type type) {
|
public virtual Color GetTypeColor(Type type) {
|
||||||
return NodeEditorPreferences.GetTypeColor(type);
|
return NodeEditorPreferences.GetTypeColor(type);
|
||||||
}
|
}
|
||||||
@ -87,6 +118,32 @@ namespace XNodeEditor {
|
|||||||
if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
|
if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Create a comment and save it in the graph asset </summary>
|
||||||
|
public void CreateComment(Vector2 position) {
|
||||||
|
XNode.NodeGraphComment comment = target.AddComment();
|
||||||
|
comment.position = position;
|
||||||
|
comment.comment = "New comment";
|
||||||
|
AssetDatabase.AddObjectToAsset(comment, target);
|
||||||
|
if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
|
||||||
|
NodeEditorWindow.RepaintAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Creates a copy of the original comment in the graph </summary>
|
||||||
|
public XNode.NodeGraphComment CopyComment(XNode.NodeGraphComment original) {
|
||||||
|
XNode.NodeGraphComment comment = target.CopyComment(original);
|
||||||
|
comment.name = original.name;
|
||||||
|
AssetDatabase.AddObjectToAsset(comment, target);
|
||||||
|
if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
|
||||||
|
return comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Safely remove a comment </summary>
|
||||||
|
public void RemoveComment(XNode.NodeGraphComment comment) {
|
||||||
|
UnityEngine.Object.DestroyImmediate(comment, true);
|
||||||
|
target.RemoveComment(comment);
|
||||||
|
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 {
|
||||||
|
|||||||
BIN
Scripts/Editor/Resources/xnode_comment.png
Normal file
BIN
Scripts/Editor/Resources/xnode_comment.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 999 B |
98
Scripts/Editor/Resources/xnode_comment.png.meta
Normal file
98
Scripts/Editor/Resources/xnode_comment.png.meta
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 043280fd1ad23004487ead415d2b11dd
|
||||||
|
timeCreated: 1507454532
|
||||||
|
licenseType: Free
|
||||||
|
TextureImporter:
|
||||||
|
fileIDToRecycleName: {}
|
||||||
|
serializedVersion: 4
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 0
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: -1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: -1
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 2
|
||||||
|
textureShape: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
platformSettings:
|
||||||
|
- buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
- buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
- buildTarget: Android
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
- buildTarget: WebGL
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
spritePackingTag:
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Scripts/Editor/Resources/xnode_node_comment_workfile.psd
Normal file
BIN
Scripts/Editor/Resources/xnode_node_comment_workfile.psd
Normal file
Binary file not shown.
@ -0,0 +1,88 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 18f697c0521665f48b9b797ec72852e8
|
||||||
|
TextureImporter:
|
||||||
|
fileIDToRecycleName: {}
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 7
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: -1
|
||||||
|
aniso: -1
|
||||||
|
mipBias: -100
|
||||||
|
wrapU: -1
|
||||||
|
wrapV: -1
|
||||||
|
wrapW: -1
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
spritePackingTag:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
pSDShowRemoveMatteOption: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -10,6 +10,9 @@ namespace XNode {
|
|||||||
/// <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> All comments in the graph. <para/>
|
||||||
|
/// See: <see cref="AddComment"/> </summary>
|
||||||
|
[SerializeField] public List<NodeGraphComment> comments = new List<NodeGraphComment>();
|
||||||
|
|
||||||
/// <summary> Add a node to the graph by type </summary>
|
/// <summary> Add a node to the graph by type </summary>
|
||||||
public T AddNode<T>() where T : Node {
|
public T AddNode<T>() where T : Node {
|
||||||
@ -53,6 +56,29 @@ namespace XNode {
|
|||||||
nodes.Clear();
|
nodes.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Add a comment to the graph</summary>
|
||||||
|
public NodeGraphComment AddComment() {
|
||||||
|
NodeGraphComment comment = ScriptableObject.CreateInstance<NodeGraphComment>();
|
||||||
|
comment.graph = this;
|
||||||
|
comments.Add(comment);
|
||||||
|
|
||||||
|
return comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Creates a copy of the comment node in the graph </summary>
|
||||||
|
public virtual NodeGraphComment CopyComment(NodeGraphComment original) {
|
||||||
|
NodeGraphComment comment = ScriptableObject.Instantiate(original);
|
||||||
|
comment.graph = this;
|
||||||
|
comments.Add(comment);
|
||||||
|
return comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Safely remove a comment </summary>
|
||||||
|
public void RemoveComment(NodeGraphComment comment) {
|
||||||
|
comments.Remove(comment);
|
||||||
|
if (Application.isPlaying) Destroy(comment);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary> Create a new deep copy of this graph </summary>
|
/// <summary> Create a new deep copy of this graph </summary>
|
||||||
public XNode.NodeGraph Copy() {
|
public XNode.NodeGraph Copy() {
|
||||||
// Instantiate a new nodegraph instance
|
// Instantiate a new nodegraph instance
|
||||||
|
|||||||
14
Scripts/NodeGraphComment.cs
Normal file
14
Scripts/NodeGraphComment.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace XNode
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class NodeGraphComment : ScriptableObject
|
||||||
|
{
|
||||||
|
[SerializeField] public NodeGraph graph;
|
||||||
|
[SerializeField] public Vector2 position;
|
||||||
|
[SerializeField] public Vector2 size = new Vector2(200, 300);
|
||||||
|
[SerializeField] public string comment;
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Scripts/NodeGraphComment.cs.meta
Normal file
11
Scripts/NodeGraphComment.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c8a458777eab4f84287de1d8a542972c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Loading…
x
Reference in New Issue
Block a user