Skip to content

Commit

Permalink
- Catered for special case where a field is a managedReference to avo…
Browse files Browse the repository at this point in the history
…id double headers

- fixed case where a group would not be drawn/ appear correctly
- fixed group label being cut off
  • Loading branch information
Doppelkeks committed Mar 10, 2023
1 parent 69dff13 commit 1fe97b7
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 50 deletions.
9 changes: 6 additions & 3 deletions Attributes/PortBaseAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class PortBaseAttribute : Attribute {
public string name = null;
public Capacity capacity = Capacity.Single;
public PortDirection direction = PortDirection.Input;
public ConnectionPolicy connectionPolicy = ConnectionPolicy.IdenticalOrSubclass;
public Func<Type, Type, bool> isValidConnectionCheck = null;

private static Dictionary<ConnectionPolicy, Func<Type, Type, bool>> connectionPolicybehaviors = new Dictionary<ConnectionPolicy, Func<Type, Type, bool>>() {
Expand All @@ -32,11 +33,13 @@ public PortBaseAttribute(string name = null, Capacity capacity = Capacity.Unspec
if (direction != PortDirection.Unspecified) {
this.direction = direction;
}
if (connectionPolicy == ConnectionPolicy.Unspecified) {
connectionPolicy = ConnectionPolicy.IdenticalOrSubclass;

if (connectionPolicy != ConnectionPolicy.Unspecified) {
this.connectionPolicy = connectionPolicy;
}

this.name = name;
isValidConnectionCheck = connectionPolicybehaviors[connectionPolicy];
isValidConnectionCheck = connectionPolicybehaviors[this.connectionPolicy];
}
}
}
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- implemented custom foldout states for groups/foldouts and indepedently from nodeView and inspector. This way a graph will always keep track over every expanded state for each node.
- implemented empty method in graphController to extend for new EdgeDrop action

## [0.2.1] - 2023-03-10
### Added
- Catered for special case where a field is a managedReference to avoid double headers
### Fixed
- fixed case where a group would not be drawn/ appear correctly
- fixed group label being cut off

23 changes: 11 additions & 12 deletions Editor/Controllers/GraphController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class GraphController {

private bool isLoading = false;
private Dictionary<object, NodeView> dataToViewLookup = new Dictionary<object, NodeView>();

public Vector2 GetViewScale() {
return graphView.GetCurrentScale();
}
Expand Down Expand Up @@ -67,7 +67,16 @@ public GraphController(VisualElement uxmlRoot, VisualElement root) {
}

private void OnEdgeDrop(object obj) {
//SearchWindow.Open(searchWindow, graphView);
BaseEdge baseEdge = (BaseEdge)obj;
if(baseEdge == null) return;

PortView port = baseEdge.Input != null ? baseEdge.Input as PortView : baseEdge.Output != null ? baseEdge.Output as PortView : null;
if (port != null) {
//Debug.Log(port.type);
foreach (Type type in port.connectableTypes) {
//Debug.Log(type);
}
}
}

private void OpenContextMenu(MouseDownEvent evt) {
Expand Down Expand Up @@ -415,16 +424,6 @@ private void OnShouldLoadGraph(GraphModel graphData) {
Load(graphData);
}

/*
/// <summary>
/// Called when Save was clicked in the inspector panel....
/// </summary>
private void OnSaveClicked() {
Logger.Log("save clicked");
Reload();
}
*/

/// <summary>
/// Opens a new graph from an external resource.
/// </summary>
Expand Down
61 changes: 32 additions & 29 deletions Editor/Helpers/GlobalKeyHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,43 @@
using UnityEditor;
using UnityEngine;

/// <summary>
/// Thanks to https://forum.unity.com/threads/4-6-editorapplication-modifierkeyschanged-how-to-find-out-which-key-was-pressed.357367/#post-2705846
/// </summary>
public static class GlobalKeyEventHandler {
public static event Action<Event> OnKeyEvent;
public static bool RegistrationSucceeded = false;
namespace NewGraph {
/// <summary>
/// Thanks to https://forum.unity.com/threads/4-6-editorapplication-modifierkeyschanged-how-to-find-out-which-key-was-pressed.357367/#post-2705846
/// </summary>
public static class GlobalKeyEventHandler {
public static event Action<Event> OnKeyEvent;
public static bool RegistrationSucceeded = false;
private const string globalEventHandler = nameof(globalEventHandler);

static GlobalKeyEventHandler() {
RegistrationSucceeded = false;
string msg = "";
try {
System.Reflection.FieldInfo info = typeof(EditorApplication).GetField("globalEventHandler", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
if (info != null) {
EditorApplication.CallbackFunction value = (EditorApplication.CallbackFunction)info.GetValue(null);
static GlobalKeyEventHandler() {
RegistrationSucceeded = false;
string msg = "";
try {
System.Reflection.FieldInfo info = typeof(EditorApplication).GetField(globalEventHandler, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
if (info != null) {
EditorApplication.CallbackFunction value = (EditorApplication.CallbackFunction)info.GetValue(null);

value -= onKeyPressed;
value += onKeyPressed;
value -= OnKeyPressed;
value += OnKeyPressed;

info.SetValue(null, value);
info.SetValue(null, value);

RegistrationSucceeded = true;
} else {
msg = "globalEventHandler not found";
}
} catch (Exception e) {
msg = e.Message;
} finally {
if (!RegistrationSucceeded) {
Debug.LogWarning("GlobalKeyEventHandler: error while registering for globalEventHandler: " + msg);
RegistrationSucceeded = true;
} else {
msg = $"{globalEventHandler} not found.";
}
} catch (Exception e) {
msg = e.Message;
} finally {
if (!RegistrationSucceeded) {
Debug.LogWarning($"{nameof(GlobalKeyEventHandler)}: error while registering for {globalEventHandler}: " + msg);
}
}
}
}

private static void onKeyPressed() {
OnKeyEvent?.Invoke(Event.current);
private static void OnKeyPressed() {
OnKeyEvent?.Invoke(Event.current);
}
}
}
}
15 changes: 12 additions & 3 deletions Editor/Serialization/PropertyBag.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,15 @@ private int RetrieveCurrentAttributes() {
if (!IsRealArray(currentProperty) && graphProperty.graphDisplay.createGroup && (currentProperty.propertyType == SerializedPropertyType.Generic || currentProperty.propertyType == SerializedPropertyType.ManagedReference)) {
// create a new group
GroupInfo groupInfo = new GroupInfo(currentProperty.displayName, currentRelativePropertyPath, currentGraphDisplayAttribute);

// check if the new group should be part of another group and add it to the group graphPropertiesAndGroups
FindGroupAndAdd(ref currentRelativePropertyPath, groupInfo);

// add new group to lookup
groupInfoLookup.Add(groupInfo);

if (currentProperty.propertyType == SerializedPropertyType.ManagedReference) {
FindGroupAndAdd(ref currentRelativePropertyPath, graphProperty);
FindGroupAndAdd(ref currentRelativePropertyPath, graphProperty, true);
}
} else {
// check if the property should be part of another group and add it to the group graphPropertiesAndGroups
Expand All @@ -264,7 +266,7 @@ private int RetrieveCurrentAttributes() {
/// </summary>
/// <param name="relativePath"></param>
/// <param name="propertyInfo"></param>
private void FindGroupAndAdd(ref string relativePath, GraphPropertyInfo propertyInfo) {
private void FindGroupAndAdd(ref string relativePath, GraphPropertyInfo propertyInfo, bool embeddedManagedReference = false) {
GroupInfo groupPropertyBelongsTo = null;
if (groupInfoLookup.Count > 0) {
string[] levels = relativePath.Split('.');
Expand All @@ -273,13 +275,20 @@ private void FindGroupAndAdd(ref string relativePath, GraphPropertyInfo property
for (int i = groupInfoLookup.Count - 1; i >= 0; i--) {
GroupInfo groupInfo = groupInfoLookup[i];
if (groupInfo.levels.Length < levels.Length) {
if(levels[levels.Length-2] == groupInfo.levels[groupInfo.levels.Length - 1]) {
if (levels[levels.Length-2] == groupInfo.levels[groupInfo.levels.Length - 1]) {
groupPropertyBelongsTo = groupInfo;
break;
}
} else if (groupInfo.levels.Length == levels.Length) {
if (levels[levels.Length - 1] == groupInfo.levels[groupInfo.levels.Length - 1]) {
groupPropertyBelongsTo = groupInfo;
groupPropertyBelongsTo.hasEmbeddedManagedReference= embeddedManagedReference;
break;
}
}
}
}

if (groupPropertyBelongsTo != null) {
propertyInfo.groupInfo= groupPropertyBelongsTo;
groupPropertyBelongsTo.graphProperties.Add(propertyInfo);
Expand Down
1 change: 1 addition & 0 deletions Editor/Serialization/PropertyInfo/GroupInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public class GroupInfo : GraphPropertyInfo {
public string groupName;
public List<PropertyInfo> graphProperties = new List<PropertyInfo>();
public string[] levels = new string[] {};
public bool hasEmbeddedManagedReference = false;

public GroupInfo(string groupName, string relativePropertyPath, GraphDisplayAttribute graphDisplayAttribute) : base(relativePropertyPath, graphDisplayAttribute) {
this.groupName = groupName;
Expand Down
15 changes: 15 additions & 0 deletions Editor/Serialization/PropertyInfo/PortInfo.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

namespace NewGraph {
public class PortInfo : PropertyInfo {
public PortBaseAttribute portDisplay;
public Type fieldType;
public string fieldName = null;
public List<Type> connectableTypes= new List<Type>();

public PortInfo(string relativePropertyPath, Type fieldType, PortBaseAttribute portDisplay, string portName = null) : base(relativePropertyPath) {
this.portDisplay = portDisplay;
this.fieldType = fieldType;
this.fieldName = portName;

if (portDisplay.connectionPolicy == ConnectionPolicy.IdenticalOrSubclass) {
TypeCache.TypeCollection typeCollection = TypeCache.GetTypesDerivedFrom(fieldType);
foreach (Type type in typeCollection) {
connectableTypes.Add(type);
}
}

if (!connectableTypes.Contains(fieldType)) {
connectableTypes.Add(fieldType);
}
}
}
}
31 changes: 30 additions & 1 deletion Editor/Views/NodeView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,36 @@ void AddAtIndex(int index, bool empty, string prefix) {
foldOutState.used= true;

newGroup.value = foldOutState.isExpanded;


void GeomChanged(GeometryChangedEvent _) {
// handle special cases where we have an embedded managed reference that is within a group
// normally we would have double header labels, so to be able to hide them via styling we need to add some classes.
VisualElement unityContent = newGroup.Q<VisualElement>("unity-content");
if (groupInfo.hasEmbeddedManagedReference) {
PropertyField pField = unityContent.Q<PropertyField>();
if (pField != null) {
Foldout fOut = pField.Q<Foldout>();
fOut.value = true;
fOut.RegisterValueChangedCallback((evt) => {
if (evt.newValue != true) {
fOut.value = true;
}
});
if (fOut != null) {
Toggle tg = fOut.Q<Toggle>();
if (tg != null) {
fOut.AddToClassList("managedReference");
tg.AddToClassList(nameof(groupInfo.hasEmbeddedManagedReference));
}
}
}
}

unityContent.pickingMode = PickingMode.Ignore;
newGroup.UnregisterCallback<GeometryChangedEvent>(GeomChanged);
}
newGroup.RegisterCallback<GeometryChangedEvent>(GeomChanged);

newGroup.RegisterValueChangedCallback((evt) => {
foldOutState.isExpanded = evt.newValue;
controller.GetSerializedObject().ApplyModifiedPropertiesWithoutUndo();
Expand Down
5 changes: 5 additions & 0 deletions Editor/Views/PortView.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using GraphViewBase;
using System;
using System.Collections.Generic;
using UnityEditor;
using static NewGraph.GraphSettingsSingleton;

Expand All @@ -8,12 +9,16 @@ public class PortView : BasePort {

public Type type;
public SerializedProperty boundProperty;
public List<Type> connectableTypes;

private Action connectionChangedCallback;
private Func<Type,Type, bool> isValidConnectionCheck;
private UnityEngine.Color targetColor;

public PortView(PortInfo info, SerializedProperty boundProperty, Action connectionChangedCallback=null) : base(Orientation.Horizontal, (Direction)(int)info.portDisplay.direction, (PortCapacity)(int)info.portDisplay.capacity) {
this.type = info.fieldType;
this.isValidConnectionCheck = info.portDisplay.isValidConnectionCheck;
this.connectableTypes = info.connectableTypes;
this.boundProperty = boundProperty;
this.connectionChangedCallback = connectionChangedCallback;

Expand Down
18 changes: 16 additions & 2 deletions Editor/Views/USS/NewGraph.uss
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,23 @@ GridBackground.grid-background {
border-color: rgba(0, 0, 0, 0.3);
}

Foldout.GroupInfo Toggle{
max-width:50px;
Foldout.GroupInfo {
padding-top: 20px;
}

Foldout.GroupInfo>PropertyField>Foldout.managedReference>Toggle.hasEmbeddedManagedReference {
display: none;
}

Foldout.GroupInfo>PropertyField>Foldout.managedReference>VisualElement#unity-content{
margin-left: 0;
}

Foldout.GroupInfo>Toggle{
position: absolute;
margin-top:-18px;
}

.unity-base-field__label {
min-width: 80px;
}
Expand Down

0 comments on commit 1fe97b7

Please sign in to comment.