mirror of
https://github.com/Siccity/xNode.git
synced 2025-12-20 17:26:02 +08:00
Merge branch 'context_menu_filter'
This commit is contained in:
commit
6b893fd5a4
@ -233,7 +233,7 @@ namespace XNodeEditor {
|
||||
// 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);
|
||||
graphEditor.AddContextMenuItems(menu, draggedOutput.ValueType);
|
||||
menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
|
||||
}
|
||||
//Release dragged connection
|
||||
@ -512,6 +512,7 @@ namespace XNodeEditor {
|
||||
|
||||
DrawNoodle(gradient, path, stroke, thickness, gridPoints);
|
||||
|
||||
GUIStyle portStyle = NodeEditorWindow.current.graphEditor.GetPortStyle(draggedOutput);
|
||||
Color bgcol = Color.black;
|
||||
Color frcol = gradient.colorKeys[0].color;
|
||||
bgcol.a = 0.6f;
|
||||
@ -524,7 +525,7 @@ namespace XNodeEditor {
|
||||
rect.position = new Vector2(rect.position.x - 8, rect.position.y - 8);
|
||||
rect = GridToWindowRect(rect);
|
||||
|
||||
NodeEditorGUILayout.DrawPortHandle(rect, bgcol, frcol);
|
||||
NodeEditorGUILayout.DrawPortHandle(rect, bgcol, frcol, portStyle.normal.background, portStyle.active.background);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,6 +118,15 @@ namespace XNodeEditor {
|
||||
contextMenu.AddItem(new GUIContent($"Disconnect({name})"), false, () => hoveredPort.Disconnect(index));
|
||||
}
|
||||
contextMenu.AddItem(new GUIContent("Clear Connections"), false, () => hoveredPort.ClearConnections());
|
||||
//Get compatible nodes with this port
|
||||
if (NodeEditorPreferences.GetSettings().createFilter) {
|
||||
contextMenu.AddSeparator("");
|
||||
|
||||
if (hoveredPort.direction == XNode.NodePort.IO.Input)
|
||||
graphEditor.AddContextMenuItems(contextMenu, hoveredPort.ValueType, XNode.NodePort.IO.Output);
|
||||
else
|
||||
graphEditor.AddContextMenuItems(contextMenu, hoveredPort.ValueType, XNode.NodePort.IO.Input);
|
||||
}
|
||||
contextMenu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
|
||||
if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
|
||||
}
|
||||
@ -334,6 +343,8 @@ namespace XNodeEditor {
|
||||
if (!_portConnectionPoints.TryGetValue(output, out fromRect)) continue;
|
||||
|
||||
Color portColor = graphEditor.GetPortColor(output);
|
||||
GUIStyle portStyle = graphEditor.GetPortStyle(output);
|
||||
|
||||
for (int k = 0; k < output.ConnectionCount; k++) {
|
||||
XNode.NodePort input = output.GetConnection(k);
|
||||
|
||||
@ -367,11 +378,11 @@ namespace XNodeEditor {
|
||||
// Draw selected reroute points with an outline
|
||||
if (selectedReroutes.Contains(rerouteRef)) {
|
||||
GUI.color = NodeEditorPreferences.GetSettings().highlightColor;
|
||||
GUI.DrawTexture(rect, NodeEditorResources.dotOuter);
|
||||
GUI.DrawTexture(rect, portStyle.normal.background);
|
||||
}
|
||||
|
||||
GUI.color = portColor;
|
||||
GUI.DrawTexture(rect, NodeEditorResources.dot);
|
||||
GUI.DrawTexture(rect, portStyle.active.background);
|
||||
if (rect.Overlaps(selectionBox)) selection.Add(rerouteRef);
|
||||
if (rect.Contains(mousePos)) hoveredReroute = rerouteRef;
|
||||
|
||||
@ -561,8 +572,7 @@ namespace XNodeEditor {
|
||||
string tooltip = null;
|
||||
if (hoveredPort != null) {
|
||||
tooltip = graphEditor.GetPortTooltip(hoveredPort);
|
||||
}
|
||||
else if (hoveredNode != null && IsHoveringNode && IsHoveringTitle(hoveredNode)) {
|
||||
} else if (hoveredNode != null && IsHoveringNode && IsHoveringTitle(hoveredNode)) {
|
||||
tooltip = NodeEditor.GetEditor(hoveredNode, this).GetHeaderTooltip();
|
||||
}
|
||||
if (string.IsNullOrEmpty(tooltip)) return;
|
||||
|
||||
@ -16,7 +16,7 @@ namespace XNodeEditor {
|
||||
|
||||
/// <summary> Make a field for a serialized property. Automatically displays relevant node port. </summary>
|
||||
public static void PropertyField(SerializedProperty property, bool includeChildren = true, params GUILayoutOption[] options) {
|
||||
PropertyField(property, (GUIContent) null, includeChildren, options);
|
||||
PropertyField(property, (GUIContent)null, includeChildren, options);
|
||||
}
|
||||
|
||||
/// <summary> Make a field for a serialized property. Automatically displays relevant node port. </summary>
|
||||
@ -101,7 +101,7 @@ namespace XNodeEditor {
|
||||
}
|
||||
|
||||
rect = GUILayoutUtility.GetLastRect();
|
||||
float paddingLeft = NodeEditorResources.styles.inputPort.padding.left;
|
||||
float paddingLeft = NodeEditorWindow.current.graphEditor.GetPortStyle(port).padding.left;
|
||||
rect.position = rect.position - new Vector2(16 + paddingLeft, -spacePadding);
|
||||
// If property is an output, display a text label and put a port handle on the right side
|
||||
} else if (port.direction == XNode.NodePort.IO.Output) {
|
||||
@ -161,7 +161,7 @@ namespace XNodeEditor {
|
||||
}
|
||||
|
||||
rect = GUILayoutUtility.GetLastRect();
|
||||
rect.width += NodeEditorResources.styles.outputPort.padding.right;
|
||||
rect.width += NodeEditorWindow.current.graphEditor.GetPortStyle(port).padding.right;
|
||||
rect.position = rect.position + new Vector2(rect.width, spacePadding);
|
||||
}
|
||||
|
||||
@ -169,7 +169,8 @@ namespace XNodeEditor {
|
||||
|
||||
Color backgroundColor = NodeEditorWindow.current.graphEditor.GetPortBackgroundColor(port);
|
||||
Color col = NodeEditorWindow.current.graphEditor.GetPortColor(port);
|
||||
DrawPortHandle(rect, backgroundColor, col);
|
||||
GUIStyle portStyle = NodeEditorWindow.current.graphEditor.GetPortStyle(port);
|
||||
DrawPortHandle(rect, backgroundColor, col, portStyle.normal.background, portStyle.active.background);
|
||||
|
||||
// Register the handle position
|
||||
Vector2 portPos = rect.center;
|
||||
@ -201,7 +202,7 @@ namespace XNodeEditor {
|
||||
EditorGUILayout.LabelField(content, options);
|
||||
|
||||
Rect rect = GUILayoutUtility.GetLastRect();
|
||||
float paddingLeft = NodeEditorResources.styles.inputPort.padding.left;
|
||||
float paddingLeft = NodeEditorWindow.current.graphEditor.GetPortStyle(port).padding.left;
|
||||
position = rect.position - new Vector2(16 + paddingLeft, 0);
|
||||
}
|
||||
// If property is an output, display a text label and put a port handle on the right side
|
||||
@ -210,7 +211,7 @@ namespace XNodeEditor {
|
||||
EditorGUILayout.LabelField(content, NodeEditorResources.OutputPort, options);
|
||||
|
||||
Rect rect = GUILayoutUtility.GetLastRect();
|
||||
rect.width += NodeEditorResources.styles.outputPort.padding.right;
|
||||
rect.width += NodeEditorWindow.current.graphEditor.GetPortStyle(port).padding.right;
|
||||
position = rect.position + new Vector2(rect.width, 0);
|
||||
}
|
||||
PortField(position, port);
|
||||
@ -224,7 +225,9 @@ namespace XNodeEditor {
|
||||
|
||||
Color backgroundColor = NodeEditorWindow.current.graphEditor.GetPortBackgroundColor(port);
|
||||
Color col = NodeEditorWindow.current.graphEditor.GetPortColor(port);
|
||||
DrawPortHandle(rect, backgroundColor, col);
|
||||
GUIStyle portStyle = NodeEditorWindow.current.graphEditor.GetPortStyle(port);
|
||||
|
||||
DrawPortHandle(rect, backgroundColor, col, portStyle.normal.background, portStyle.active.background);
|
||||
|
||||
// Register the handle position
|
||||
Vector2 portPos = rect.center;
|
||||
@ -239,12 +242,12 @@ namespace XNodeEditor {
|
||||
// If property is an input, display a regular property field and put a port handle on the left side
|
||||
if (port.direction == XNode.NodePort.IO.Input) {
|
||||
rect = GUILayoutUtility.GetLastRect();
|
||||
float paddingLeft = NodeEditorResources.styles.inputPort.padding.left;
|
||||
float paddingLeft = NodeEditorWindow.current.graphEditor.GetPortStyle(port).padding.left;
|
||||
rect.position = rect.position - new Vector2(16 + paddingLeft, 0);
|
||||
// If property is an output, display a text label and put a port handle on the right side
|
||||
} else if (port.direction == XNode.NodePort.IO.Output) {
|
||||
rect = GUILayoutUtility.GetLastRect();
|
||||
rect.width += NodeEditorResources.styles.outputPort.padding.right;
|
||||
rect.width += NodeEditorWindow.current.graphEditor.GetPortStyle(port).padding.right;
|
||||
rect.position = rect.position + new Vector2(rect.width, 0);
|
||||
}
|
||||
|
||||
@ -252,7 +255,9 @@ namespace XNodeEditor {
|
||||
|
||||
Color backgroundColor = NodeEditorWindow.current.graphEditor.GetPortBackgroundColor(port);
|
||||
Color col = NodeEditorWindow.current.graphEditor.GetPortColor(port);
|
||||
DrawPortHandle(rect, backgroundColor, col);
|
||||
GUIStyle portStyle = NodeEditorWindow.current.graphEditor.GetPortStyle(port);
|
||||
|
||||
DrawPortHandle(rect, backgroundColor, col, portStyle.normal.background, portStyle.active.background);
|
||||
|
||||
// Register the handle position
|
||||
Vector2 portPos = rect.center;
|
||||
@ -267,16 +272,25 @@ namespace XNodeEditor {
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
public static void DrawPortHandle(Rect rect, Color backgroundColor, Color typeColor) {
|
||||
/// <summary>
|
||||
/// Draw the port
|
||||
/// </summary>
|
||||
/// <param name="rect">position and size</param>
|
||||
/// <param name="backgroundColor">color for background texture of the port. Normaly used to Border</param>
|
||||
/// <param name="typeColor"></param>
|
||||
/// <param name="border">texture for border of the dot port</param>
|
||||
/// <param name="dot">texture for the dot port</param>
|
||||
public static void DrawPortHandle(Rect rect, Color backgroundColor, Color typeColor, Texture2D border, Texture2D dot) {
|
||||
Color col = GUI.color;
|
||||
GUI.color = backgroundColor;
|
||||
GUI.DrawTexture(rect, NodeEditorResources.dotOuter);
|
||||
GUI.DrawTexture(rect, border);
|
||||
GUI.color = typeColor;
|
||||
GUI.DrawTexture(rect, NodeEditorResources.dot);
|
||||
GUI.DrawTexture(rect, dot);
|
||||
GUI.color = col;
|
||||
}
|
||||
|
||||
#region Obsolete
|
||||
|
||||
#region Obsolete
|
||||
[Obsolete("Use IsDynamicPortListPort instead")]
|
||||
public static bool IsInstancePortListPort(XNode.NodePort port) {
|
||||
return IsDynamicPortListPort(port);
|
||||
@ -286,7 +300,7 @@ namespace XNodeEditor {
|
||||
public static void InstancePortList(string fieldName, Type type, SerializedObject serializedObject, XNode.NodePort.IO io, XNode.Node.ConnectionType connectionType = XNode.Node.ConnectionType.Multiple, XNode.Node.TypeConstraint typeConstraint = XNode.Node.TypeConstraint.None, Action<ReorderableList> onCreation = null) {
|
||||
DynamicPortList(fieldName, type, serializedObject, io, connectionType, typeConstraint, onCreation);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
/// <summary> Is this port part of a DynamicPortList? </summary>
|
||||
public static bool IsDynamicPortListPort(XNode.NodePort port) {
|
||||
@ -317,7 +331,7 @@ namespace XNodeEditor {
|
||||
return new { index = i, port = x };
|
||||
}
|
||||
}
|
||||
return new { index = -1, port = (XNode.NodePort) null };
|
||||
return new { index = -1, port = (XNode.NodePort)null };
|
||||
}).Where(x => x.port != null);
|
||||
List<XNode.NodePort> dynamicPorts = indexedPorts.OrderBy(x => x.index).Select(x => x.port).ToList();
|
||||
|
||||
@ -454,7 +468,7 @@ namespace XNodeEditor {
|
||||
return new { index = i, port = x };
|
||||
}
|
||||
}
|
||||
return new { index = -1, port = (XNode.NodePort) null };
|
||||
return new { index = -1, port = (XNode.NodePort)null };
|
||||
}).Where(x => x.port != null);
|
||||
dynamicPorts = indexedPorts.OrderBy(x => x.index).Select(x => x.port).ToList();
|
||||
|
||||
|
||||
@ -38,6 +38,7 @@ namespace XNodeEditor {
|
||||
public bool autoSave = true;
|
||||
public bool openOnCreate = true;
|
||||
public bool dragToCreate = true;
|
||||
public bool createFilter = true;
|
||||
public bool zoomToMouse = true;
|
||||
public bool portTooltips = true;
|
||||
[SerializeField] private string typeColorsData = "";
|
||||
@ -168,6 +169,9 @@ namespace XNodeEditor {
|
||||
settings.noodleStroke = (NoodleStroke) EditorGUILayout.EnumPopup("Noodle stroke", (Enum) settings.noodleStroke);
|
||||
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.createFilter = EditorGUILayout.Toggle(new GUIContent("Create Filter", "Only show nodes that are compatible with the selected port"), settings.createFilter);
|
||||
|
||||
//END
|
||||
if (GUI.changed) {
|
||||
SavePrefs(key, settings);
|
||||
NodeEditorWindow.RepaintAll();
|
||||
|
||||
@ -27,10 +27,14 @@ namespace XNodeEditor {
|
||||
inputPort = new GUIStyle(baseStyle);
|
||||
inputPort.alignment = TextAnchor.UpperLeft;
|
||||
inputPort.padding.left = 0;
|
||||
inputPort.active.background = dot;
|
||||
inputPort.normal.background = dotOuter;
|
||||
|
||||
outputPort = new GUIStyle(baseStyle);
|
||||
outputPort.alignment = TextAnchor.UpperRight;
|
||||
outputPort.padding.right = 0;
|
||||
outputPort.active.background = dot;
|
||||
outputPort.normal.background = dotOuter;
|
||||
|
||||
nodeHeader = new GUIStyle();
|
||||
nodeHeader.alignment = TextAnchor.MiddleCenter;
|
||||
|
||||
@ -127,6 +127,57 @@ namespace XNodeEditor {
|
||||
return methods.Count() > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looking for ports with value Type compatible with a given type.
|
||||
/// </summary>
|
||||
/// <param name="nodeType">Node to search</param>
|
||||
/// <param name="compatibleType">Type to find compatiblities</param>
|
||||
/// <param name="direction"></param>
|
||||
/// <returns>True if NodeType has some port with value type compatible</returns>
|
||||
public static bool HasCompatiblePortType(Type nodeType, Type compatibleType, XNode.NodePort.IO direction = XNode.NodePort.IO.Input) {
|
||||
Type findType = typeof(XNode.Node.InputAttribute);
|
||||
if (direction == XNode.NodePort.IO.Output)
|
||||
findType = typeof(XNode.Node.OutputAttribute);
|
||||
|
||||
//Get All fields from node type and we go filter only field with portAttribute.
|
||||
//This way is possible to know the values of the all ports and if have some with compatible value tue
|
||||
foreach (FieldInfo f in XNode.NodeDataCache.GetNodeFields(nodeType)) {
|
||||
var portAttribute = f.GetCustomAttributes(findType, false).FirstOrDefault();
|
||||
if (portAttribute != null) {
|
||||
if (IsCastableTo(f.FieldType, compatibleType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter only node types that contains some port value type compatible with an given type
|
||||
/// </summary>
|
||||
/// <param name="nodeTypes">List with all nodes type to filter</param>
|
||||
/// <param name="compatibleType">Compatible Type to Filter</param>
|
||||
/// <returns>Return Only Node Types with ports compatible, or an empty list</returns>
|
||||
public static List<Type> GetCompatibleNodesTypes(Type[] nodeTypes, Type compatibleType, XNode.NodePort.IO direction = XNode.NodePort.IO.Input) {
|
||||
//Result List
|
||||
List<Type> filteredTypes = new List<Type>();
|
||||
|
||||
//Return empty list
|
||||
if (nodeTypes == null) { return filteredTypes; }
|
||||
if (compatibleType == null) { return filteredTypes; }
|
||||
|
||||
//Find compatiblity
|
||||
foreach (Type findType in nodeTypes) {
|
||||
if (HasCompatiblePortType(findType, compatibleType, direction)) {
|
||||
filteredTypes.Add(findType);
|
||||
}
|
||||
}
|
||||
|
||||
return filteredTypes;
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Return a prettiefied type name. </summary>
|
||||
public static string PrettyName(this Type type) {
|
||||
if (type == null) return "null";
|
||||
|
||||
@ -57,11 +57,24 @@ namespace XNodeEditor {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <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) {
|
||||
/// <summary>
|
||||
/// Add items for the context menu when right-clicking this node.
|
||||
/// Override to add custom menu items.
|
||||
/// </summary>
|
||||
/// <param name="menu"></param>
|
||||
/// <param name="compatibleType">Use it to filter only nodes with ports value type, compatible with this type</param>
|
||||
/// <param name="direction">Direction of the compatiblity</param>
|
||||
public virtual void AddContextMenuItems(GenericMenu menu, Type compatibleType = null, XNode.NodePort.IO direction = XNode.NodePort.IO.Input) {
|
||||
Vector2 pos = NodeEditorWindow.current.WindowToGridPosition(Event.current.mousePosition);
|
||||
var nodeTypes = NodeEditorReflection.nodeTypes.OrderBy(type => GetNodeMenuOrder(type)).ToArray();
|
||||
|
||||
Type[] nodeTypes = NodeEditorReflection.nodeTypes.OrderBy(type => GetNodeMenuOrder(type)).ToArray();
|
||||
|
||||
if (compatibleType != null && NodeEditorPreferences.GetSettings().createFilter) {
|
||||
nodeTypes = NodeEditorUtilities.GetCompatibleNodesTypes(NodeEditorReflection.nodeTypes, compatibleType, direction).ToArray();
|
||||
}
|
||||
|
||||
for (int i = 0; i < nodeTypes.Length; i++) {
|
||||
|
||||
Type type = nodeTypes[i];
|
||||
|
||||
//Get node context menu path
|
||||
@ -141,6 +154,23 @@ namespace XNodeEditor {
|
||||
return GetTypeColor(port.ValueType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The returned Style is used to configure the paddings and icon texture of the ports.
|
||||
/// Use these properties to customize your port style.
|
||||
///
|
||||
/// The properties used is:
|
||||
/// <see cref="GUIStyle.padding"/>[Left and Right], <see cref="GUIStyle.normal"/> [Background] = border texture,
|
||||
/// and <seealso cref="GUIStyle.active"/> [Background] = dot texture;
|
||||
/// </summary>
|
||||
/// <param name="port">the owner of the style</param>
|
||||
/// <returns></returns>
|
||||
public virtual GUIStyle GetPortStyle(XNode.NodePort port) {
|
||||
if (port.direction == XNode.NodePort.IO.Input)
|
||||
return NodeEditorResources.styles.inputPort;
|
||||
|
||||
return NodeEditorResources.styles.outputPort;
|
||||
}
|
||||
|
||||
/// <summary> The returned color is used to color the background of the door.
|
||||
/// Usually used for outer edge effect </summary>
|
||||
public virtual Color GetPortBackgroundColor(XNode.NodePort port) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user