Migrated ClusterEditor to ClusterView

This commit is contained in:
Pascal Serrarens 2026-05-19 12:45:11 +02:00
parent 9d43772b79
commit ebef711981
6 changed files with 1399 additions and 1232 deletions

View File

@ -1,3 +1,4 @@
/*
using UnityEditor; using UnityEditor;
using UnityEditor.UIElements; using UnityEditor.UIElements;
@ -70,4 +71,5 @@ namespace NanoBrain.Unity {
} }
} }
} }
*/

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,10 @@
using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
using UnityEditor; using UnityEditor;
using System;
using System.Reflection;
namespace NanoBrain.Unity { namespace NanoBrain.Unity {
@ -58,7 +61,6 @@ namespace NanoBrain.Unity {
// content rect below header // content rect below header
Rect drawRect = new(fieldRect.x, headerRect.yMax + 2f, fieldRect.width, 450f); Rect drawRect = new(fieldRect.x, headerRect.yMax + 2f, fieldRect.width, 450f);
// IMGUIContainer should be inserted here
ClusterView.Render(drawRect, prefab.cluster, property); ClusterView.Render(drawRect, prefab.cluster, property);
} }
} }
@ -86,4 +88,62 @@ namespace NanoBrain.Unity {
// } // }
} }
/*
[InitializeOnLoad]
static class ClusterPrefabInspectorRepaints {
static ClusterPrefabInspectorRepaints() {
EditorApplication.update += OnEditorUpdate;
}
static double lastRepaint = 0;
const double repaintInterval = 1.0 / 15.0; // up to 15 FPS in inspector
static void OnEditorUpdate() {
if (!Application.isPlaying) return;
// throttle repaint frequency
if (EditorApplication.timeSinceStartup - lastRepaint < repaintInterval) return;
lastRepaint = EditorApplication.timeSinceStartup;
// Find all open inspectors (Editors) that target objects containing ClusterPrefab fields
var editors = Resources.FindObjectsOfTypeAll<Editor>();
foreach (var ed in editors) {
var targets = ed.targets;
if (targets == null)
continue;
bool shouldRepaint = targets.Any(t => ObjectHasClusterPrefabField(t));
if (shouldRepaint) {
try {
ed.Repaint();
}
catch {
// ignore
}
}
}
}
static bool ObjectHasClusterPrefabField(UnityEngine.Object obj) {
if (obj == null)
return false;
Type type = obj.GetType();
// search fields (instance, non-public/public)
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo f in fields) {
if (f.FieldType == typeof(ClusterPrefab))
return true;
// also handle arrays/lists of ClusterPrefab or serializable wrappers:
if (f.FieldType.IsArray && f.FieldType.GetElementType() == typeof(ClusterPrefab))
return true;
if (f.FieldType.IsGenericType) {
Type[] gen = f.FieldType.GetGenericArguments();
if (gen.Length == 1 && gen[0] == typeof(ClusterPrefab))
return true;
}
}
return false;
}
}
*/
} }

View File

@ -9,32 +9,46 @@ namespace NanoBrain.Unity {
private static readonly float discRadius = 20; private static readonly float discRadius = 20;
static readonly Dictionary<string, ClusterView> viewStates = new(); static readonly Dictionary<string, ClusterView> viewStates = new();
private static ClusterView GetClusterView(SerializedProperty property) { public static ClusterView GetClusterView(SerializedProperty property) {
string key = property.propertyPath + "_" + property.serializedObject.targetObject.GetEntityId(); string key = property.propertyPath + "_" + property.serializedObject.targetObject.GetEntityId();
if (!viewStates.TryGetValue(key, out ClusterView state)) if (!viewStates.TryGetValue(key, out ClusterView state))
state = new() { key = key }; state = new() { key = key };
return state; return state;
} }
public static ClusterView GetClusterView(SerializedObject serializedObject) {
string key = serializedObject.targetObject.GetEntityId().ToString();
if (!viewStates.TryGetValue(key, out ClusterView state))
state = new() { key = key };
return state;
}
private static void UpdateViewState(ClusterView viewState) { private void UpdateViewState() {
viewStates[viewState.key] = viewState; viewStates[this.key] = this;
} }
public static void Render(Rect drawRect, Cluster cluster, SerializedProperty property) { public static void Render(Rect drawRect, Cluster cluster, SerializedProperty property) {
ClusterView clusterView = GetClusterView(property); ClusterView clusterView = GetClusterView(property);
clusterView.currentCluster ??= cluster; clusterView.currentCluster ??= cluster;
clusterView.Render(drawRect);
}
public static void Render(Rect drawRect, Cluster cluster, SerializedObject obj) {
ClusterView clusterView = GetClusterView(obj);
clusterView.currentCluster ??= cluster;
clusterView.Render(drawRect);
}
public void Render(Rect drawRect) {
// background // background
EditorGUI.DrawRect(drawRect, Color.black); EditorGUI.DrawRect(drawRect, Color.black);
const float contentWidth = 1000f; const float contentWidth = 1000f;
Rect contentRect = new Rect(0f, 0f, contentWidth, drawRect.height); Rect contentRect = new(0f, 0f, contentWidth, drawRect.height - 20);
// Begin horizontal-only scroll view // Begin horizontal-only scroll view
clusterView.scrollPos = GUI.BeginScrollView(drawRect, clusterView.scrollPos, contentRect, true, false); this.scrollPos = GUI.BeginScrollView(drawRect, this.scrollPos, contentRect, false, false);
// Local content group: draw GUI content using content-local coords (0..contentWidth) // Local content group: draw GUI content using content-local coords (0..contentWidth)
GUI.BeginGroup(new Rect(-clusterView.scrollPos.x, 0f, contentWidth, drawRect.height)); GUI.BeginGroup(new Rect(-this.scrollPos.x, 0f, contentWidth, drawRect.height));
EditorGUI.DrawRect(new Rect(0f, 0f, contentWidth, drawRect.height), new Color(0.08f, 0.08f, 0.08f, 1f)); EditorGUI.DrawRect(new Rect(0f, 0f, contentWidth, drawRect.height), new Color(0.08f, 0.08f, 0.08f, 1f));
GUI.EndGroup(); GUI.EndGroup();
GUI.EndScrollView(); GUI.EndScrollView();
@ -43,16 +57,16 @@ namespace NanoBrain.Unity {
GUI.BeginGroup(drawRect); GUI.BeginGroup(drawRect);
// Inner group positions content origin so local coords match content space and respect scroll // Inner group positions content origin so local coords match content space and respect scroll
GUI.BeginGroup(new Rect(-clusterView.scrollPos.x, 0f, contentWidth, drawRect.height)); GUI.BeginGroup(new Rect(-this.scrollPos.x, 0f, contentWidth, drawRect.height));
Handles.BeginGUI(); Handles.BeginGUI();
clusterView.DrawFocusGraph(); this.DrawFocusGraph();
Handles.EndGUI(); Handles.EndGUI();
GUI.EndGroup(); // end inner group GUI.EndGroup(); // end inner group
GUI.EndGroup(); // end clipping group GUI.EndGroup(); // end clipping group
UpdateViewState(clusterView); UpdateViewState();
} }
public string key = null; public string key = null;

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
using System; using System;
using UnityEngine; using UnityEngine;
/*
namespace NanoBrain.Unity { namespace NanoBrain.Unity {
/// <summary> /// <summary>
@ -65,4 +65,5 @@ namespace NanoBrain.Unity {
} }
} }
} }
*/