mirror of
https://github.com/Siccity/xNode.git
synced 2026-02-19 00:06:42 +08:00
Added inline UI for Node/Group renaming.
This commit is contained in:
parent
62ec9a54cf
commit
5ec46e53a1
@ -24,7 +24,6 @@ namespace XNodeEditor
|
|||||||
/// <summary> Fires every whenever a node was modified through the editor </summary>
|
/// <summary> Fires every whenever a node was modified through the editor </summary>
|
||||||
public static Action<Node> onUpdateNode;
|
public static Action<Node> onUpdateNode;
|
||||||
public static readonly Dictionary<NodePort, Vector2> portPositions = new Dictionary<NodePort, Vector2>();
|
public static readonly Dictionary<NodePort, Vector2> portPositions = new Dictionary<NodePort, Vector2>();
|
||||||
private Vector2 _lastClickPos;
|
|
||||||
|
|
||||||
#if ODIN_INSPECTOR
|
#if ODIN_INSPECTOR
|
||||||
protected internal static bool inNodeEditor = false;
|
protected internal static bool inNodeEditor = false;
|
||||||
@ -32,18 +31,6 @@ namespace XNodeEditor
|
|||||||
|
|
||||||
public virtual void OnHeaderGUI()
|
public virtual void OnHeaderGUI()
|
||||||
{
|
{
|
||||||
Event e = Event.current;
|
|
||||||
if (e.type == EventType.MouseDown)
|
|
||||||
{
|
|
||||||
if ((_lastClickPos - e.mousePosition).sqrMagnitude <= 5 * 5 && e.clickCount > 1)
|
|
||||||
{
|
|
||||||
Debug.Log("Renaming time!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_lastClickPos = e.mousePosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
GUILayout.Label(target.name, NodeEditorResources.styles.nodeHeader, GUILayout.Height(30));
|
GUILayout.Label(target.name, NodeEditorResources.styles.nodeHeader, GUILayout.Height(30));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,8 @@ namespace XNodeEditor
|
|||||||
HoldNode,
|
HoldNode,
|
||||||
DragNode,
|
DragNode,
|
||||||
HoldGrid,
|
HoldGrid,
|
||||||
DragGrid
|
DragGrid,
|
||||||
|
Renaming
|
||||||
}
|
}
|
||||||
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; }
|
||||||
@ -32,6 +33,8 @@ namespace XNodeEditor
|
|||||||
public bool IsHoveringPort => hoveredPort != null;
|
public bool IsHoveringPort => hoveredPort != null;
|
||||||
public bool IsHoveringNode => hoveredNode != null;
|
public bool IsHoveringNode => hoveredNode != null;
|
||||||
public bool IsHoveringReroute => hoveredReroute.port != null;
|
public bool IsHoveringReroute => hoveredReroute.port != null;
|
||||||
|
public bool IsSelectingRenamingObject =>
|
||||||
|
currentActivity == NodeActivity.Renaming && IsHoveringNode && Selection.Contains(hoveredNode);
|
||||||
|
|
||||||
/// <summary> Return the dragged port or null if not exist </summary>
|
/// <summary> Return the dragged port or null if not exist </summary>
|
||||||
public NodePort DraggedOutputPort
|
public NodePort DraggedOutputPort
|
||||||
@ -135,6 +138,7 @@ namespace XNodeEditor
|
|||||||
else if (currentActivity == NodeActivity.HoldNode)
|
else if (currentActivity == NodeActivity.HoldNode)
|
||||||
{
|
{
|
||||||
RecalculateDragOffsets(e);
|
RecalculateDragOffsets(e);
|
||||||
|
isDoubleClick = false;
|
||||||
currentActivity = NodeActivity.DragNode;
|
currentActivity = NodeActivity.DragNode;
|
||||||
Repaint();
|
Repaint();
|
||||||
}
|
}
|
||||||
@ -277,8 +281,14 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentActivity == NodeActivity.Renaming)
|
||||||
|
{
|
||||||
|
currentActivity = NodeActivity.Idle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (IsHoveringNode && IsHoveringTitle(hoveredNode))
|
else if (IsHoveringNode && IsHoveringTitle(hoveredNode) &&
|
||||||
|
(currentActivity != NodeActivity.Renaming || !IsSelectingRenamingObject))
|
||||||
{
|
{
|
||||||
// If mousedown on node header, select or deselect
|
// If mousedown on node header, select or deselect
|
||||||
if (!Selection.Contains(hoveredNode))
|
if (!Selection.Contains(hoveredNode))
|
||||||
@ -415,19 +425,30 @@ 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 || !IsSelectingRenamingObject) &&
|
||||||
|
!(e.control || e.shift))
|
||||||
{
|
{
|
||||||
selectedReroutes.Clear();
|
selectedReroutes.Clear();
|
||||||
SelectNode(hoveredNode, false);
|
SelectNode(hoveredNode, false);
|
||||||
|
|
||||||
// Double click to center node
|
// Double click to rename node
|
||||||
if (isDoubleClick)
|
if (isDoubleClick)
|
||||||
{
|
{
|
||||||
Vector2 nodeDimension = nodeSizes.ContainsKey(hoveredNode)
|
RenameSelectedNodeTextField();
|
||||||
? nodeSizes[hoveredNode] / 2
|
currentActivity = NodeActivity.Renaming;
|
||||||
: Vector2.zero;
|
// Vector2 nodeDimension = nodeSizes.ContainsKey(hoveredNode)
|
||||||
panOffset = -hoveredNode.position - nodeDimension;
|
// ? nodeSizes[hoveredNode] / 2
|
||||||
|
// : Vector2.zero;
|
||||||
|
// panOffset = -hoveredNode.position - nodeDimension;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentActivity = NodeActivity.HoldNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (currentActivity != NodeActivity.Renaming)
|
||||||
|
{
|
||||||
|
currentActivity = NodeActivity.Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If click reroute, select it.
|
// If click reroute, select it.
|
||||||
@ -438,7 +459,6 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
Repaint();
|
Repaint();
|
||||||
currentActivity = NodeActivity.Idle;
|
|
||||||
}
|
}
|
||||||
else if (e.button == 1 || e.button == 2)
|
else if (e.button == 1 || e.button == 2)
|
||||||
{
|
{
|
||||||
@ -483,6 +503,11 @@ namespace XNodeEditor
|
|||||||
graphEditor.AddContextMenuItems(menu);
|
graphEditor.AddContextMenuItems(menu);
|
||||||
menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
|
menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentActivity == NodeActivity.Renaming)
|
||||||
|
{
|
||||||
|
currentActivity = NodeActivity.Idle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isPanning = false;
|
isPanning = false;
|
||||||
@ -604,6 +629,11 @@ namespace XNodeEditor
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentActivity != NodeActivity.Renaming && RenameTextField.IsActive)
|
||||||
|
{
|
||||||
|
RenameTextField.current.SaveAndClose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecalculateDragOffsets(Event current)
|
private void RecalculateDragOffsets(Event current)
|
||||||
@ -686,6 +716,24 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void RenameSelectedNodeTextField()
|
||||||
|
{
|
||||||
|
if (Selection.objects.Length == 1 && Selection.activeObject is Node)
|
||||||
|
{
|
||||||
|
Node node = Selection.activeObject as Node;
|
||||||
|
Vector2 size;
|
||||||
|
if (nodeSizes.TryGetValue(node, out size))
|
||||||
|
{
|
||||||
|
RenameTextField.Show(Selection.activeObject, size.x);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RenameTextField.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(Node node)
|
public void MoveNodeToTop(Node node)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -156,7 +156,7 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
graphEditor.AddContextMenuItems(contextMenu, hoveredPort.ValueType, NodePort.IO.Input);
|
graphEditor.AddContextMenuItems(contextMenu, hoveredPort.ValueType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -681,7 +681,15 @@ namespace XNodeEditor
|
|||||||
EditorGUI.BeginChangeCheck();
|
EditorGUI.BeginChangeCheck();
|
||||||
|
|
||||||
//Draw node contents
|
//Draw node contents
|
||||||
nodeEditor.OnHeaderGUI();
|
if (currentActivity == NodeActivity.Renaming && Selection.activeObject == node)
|
||||||
|
{
|
||||||
|
RenameTextField.current.DrawRenameTextField();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nodeEditor.OnHeaderGUI();
|
||||||
|
}
|
||||||
|
|
||||||
nodeEditor.OnBodyGUI();
|
nodeEditor.OnBodyGUI();
|
||||||
|
|
||||||
//If user changed a value, notify other scripts through onUpdateNode
|
//If user changed a value, notify other scripts through onUpdateNode
|
||||||
|
|||||||
@ -25,7 +25,7 @@ namespace XNodeEditor
|
|||||||
public static GUIStyle OutputPort => new GUIStyle(EditorStyles.label) { alignment = TextAnchor.UpperRight };
|
public static GUIStyle OutputPort => new GUIStyle(EditorStyles.label) { alignment = TextAnchor.UpperRight };
|
||||||
public class Styles
|
public class Styles
|
||||||
{
|
{
|
||||||
public GUIStyle inputPort, outputPort, nodeHeader, nodeBody, tooltip, nodeHighlight;
|
public GUIStyle inputPort, outputPort, nodeHeader, nodeHeaderRename, nodeBody, tooltip, nodeHighlight;
|
||||||
|
|
||||||
public Styles()
|
public Styles()
|
||||||
{
|
{
|
||||||
@ -49,6 +49,13 @@ namespace XNodeEditor
|
|||||||
nodeHeader.fontStyle = FontStyle.Bold;
|
nodeHeader.fontStyle = FontStyle.Bold;
|
||||||
nodeHeader.normal.textColor = Color.white;
|
nodeHeader.normal.textColor = Color.white;
|
||||||
|
|
||||||
|
nodeHeaderRename = new GUIStyle(GUI.skin.textField);
|
||||||
|
nodeHeaderRename.alignment = TextAnchor.MiddleCenter;
|
||||||
|
nodeHeaderRename.fontStyle = FontStyle.Bold;
|
||||||
|
nodeHeaderRename.normal.textColor = Color.white;
|
||||||
|
nodeHeaderRename.fixedHeight = 18;
|
||||||
|
nodeHeaderRename.margin = new RectOffset(5, 5, 10, 8);
|
||||||
|
|
||||||
nodeBody = new GUIStyle();
|
nodeBody = new GUIStyle();
|
||||||
nodeBody.normal.background = NodeEditorResources.nodeBody;
|
nodeBody.normal.background = NodeEditorResources.nodeBody;
|
||||||
nodeBody.border = new RectOffset(32, 32, 32, 32);
|
nodeBody.border = new RectOffset(32, 32, 32, 32);
|
||||||
@ -63,6 +70,20 @@ namespace XNodeEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Texture2D GenerateSolidColorTexture(int width, int height, Color col)
|
||||||
|
{
|
||||||
|
var pix = new Color[width * height];
|
||||||
|
for (int i = 0; i < pix.Length; ++i)
|
||||||
|
{
|
||||||
|
pix[i] = col;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture2D result = new Texture2D(width, height);
|
||||||
|
result.SetPixels(pix);
|
||||||
|
result.Apply();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public static Texture2D GenerateGridTexture(Color line, Color bg)
|
public static Texture2D GenerateGridTexture(Color line, Color bg)
|
||||||
{
|
{
|
||||||
Texture2D tex = new Texture2D(64, 64);
|
Texture2D tex = new Texture2D(64, 64);
|
||||||
|
|||||||
98
Scripts/Editor/RenameTextField.cs
Normal file
98
Scripts/Editor/RenameTextField.cs
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using XNode;
|
||||||
|
|
||||||
|
namespace XNodeEditor
|
||||||
|
{
|
||||||
|
/// <summary> Utility for renaming assets </summary>
|
||||||
|
public class RenameTextField
|
||||||
|
{
|
||||||
|
private const string inputControlName = "nameInput";
|
||||||
|
|
||||||
|
public static RenameTextField current { get; private set; }
|
||||||
|
public static bool IsActive => current != null;
|
||||||
|
public Object target;
|
||||||
|
public string input;
|
||||||
|
|
||||||
|
private bool firstFrame = true;
|
||||||
|
|
||||||
|
/// <summary> Show a rename text field for an asset in the node header. Will trigger reimport of the asset on apply.
|
||||||
|
public static RenameTextField Show(Object target, float width = 200)
|
||||||
|
{
|
||||||
|
RenameTextField textField = new RenameTextField();
|
||||||
|
if (current != null)
|
||||||
|
{
|
||||||
|
current = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = textField;
|
||||||
|
textField.target = target;
|
||||||
|
textField.input = target.name;
|
||||||
|
|
||||||
|
return textField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawRenameTextField()
|
||||||
|
{
|
||||||
|
GUI.SetNextControlName(inputControlName);
|
||||||
|
input = GUILayout.TextField(input, NodeEditorResources.styles.nodeHeaderRename);
|
||||||
|
EditorGUI.FocusTextInControl(inputControlName);
|
||||||
|
|
||||||
|
if (firstFrame)
|
||||||
|
{
|
||||||
|
TextEditor textEditor =
|
||||||
|
(TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl);
|
||||||
|
textEditor.SelectAll();
|
||||||
|
firstFrame = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Event e = Event.current;
|
||||||
|
// If input is empty, revert name to default instead
|
||||||
|
if (input == null || input.Trim() == "")
|
||||||
|
{
|
||||||
|
if (e.isKey && e.keyCode == KeyCode.Return)
|
||||||
|
{
|
||||||
|
SaveAndClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Rename asset to input text
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (e.isKey && e.keyCode == KeyCode.Return)
|
||||||
|
{
|
||||||
|
SaveAndClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.isKey && e.keyCode == KeyCode.Escape)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveAndClose()
|
||||||
|
{
|
||||||
|
target.name = input;
|
||||||
|
NodeEditor.GetEditor((Node)target, NodeEditorWindow.current).OnRename();
|
||||||
|
if (!string.IsNullOrEmpty(AssetDatabase.GetAssetPath(target)))
|
||||||
|
{
|
||||||
|
AssetDatabase.SetMainObject((target as Node).graph, AssetDatabase.GetAssetPath(target));
|
||||||
|
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
Close();
|
||||||
|
target.TriggerOnValidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
firstFrame = true;
|
||||||
|
current = null;
|
||||||
|
NodeEditorWindow.current.Repaint();
|
||||||
|
if (NodeEditorWindow.currentActivity == NodeEditorWindow.NodeActivity.Renaming)
|
||||||
|
{
|
||||||
|
NodeEditorWindow.currentActivity = NodeEditorWindow.NodeActivity.Idle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
Scripts/Editor/RenameTextField.cs.meta
Normal file
3
Scripts/Editor/RenameTextField.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e19c9bf223d748e895841425ac714280
|
||||||
|
timeCreated: 1696534896
|
||||||
Loading…
x
Reference in New Issue
Block a user