Experimental UiToolkit support

This commit is contained in:
VladV 2023-07-29 13:08:53 +04:00
parent 6981492ea7
commit 1361246895
8 changed files with 206 additions and 3 deletions

View File

@ -1,5 +1,6 @@
using TriInspector; using TriInspector;
using TriInspector.Drawers; using TriInspector.Drawers;
using TriInspector.Editors;
using TriInspector.Elements; using TriInspector.Elements;
using TriInspector.Utilities; using TriInspector.Utilities;
using TriInspectorUnityInternalBridge; using TriInspectorUnityInternalBridge;
@ -24,6 +25,15 @@ namespace TriInspector.Drawers
if (drawWithHandler) if (drawWithHandler)
{ {
var visualElement = handler.CreatePropertyGUI(serializedProperty);
if (visualElement != null &&
TriEditor.UiElementsRoots.TryGetValue(property.PropertyTree, out var rootElement))
{
return new TriUiToolkitPropertyElement(property, serializedProperty,
visualElement, rootElement);
}
return new TriBuiltInPropertyElement(property, serializedProperty, handler); return new TriBuiltInPropertyElement(property, serializedProperty, handler);
} }
} }

View File

@ -1,11 +1,17 @@
using System;
using System.Collections.Generic;
using TriInspector.Utilities; using TriInspector.Utilities;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements;
namespace TriInspector.Editors namespace TriInspector.Editors
{ {
public abstract class TriEditor : Editor public abstract class TriEditor : Editor
{ {
internal static readonly Dictionary<TriPropertyTree, VisualElement> UiElementsRoots
= new Dictionary<TriPropertyTree, VisualElement>();
private TriPropertyTreeForSerializedObject _inspector; private TriPropertyTreeForSerializedObject _inspector;
private void OnDisable() private void OnDisable()
@ -13,6 +19,11 @@ namespace TriInspector.Editors
OnDisable(this, ref _inspector); OnDisable(this, ref _inspector);
} }
public override VisualElement CreateInspectorGUI()
{
return CreateInspector(root => OnInspectorGUI(this, ref _inspector, root));
}
public override void OnInspectorGUI() public override void OnInspectorGUI()
{ {
OnInspectorGUI(this, ref _inspector); OnInspectorGUI(this, ref _inspector);
@ -20,12 +31,49 @@ namespace TriInspector.Editors
public static void OnDisable(Editor editor, ref TriPropertyTreeForSerializedObject inspector) public static void OnDisable(Editor editor, ref TriPropertyTreeForSerializedObject inspector)
{ {
inspector?.Dispose(); if (inspector != null)
{
UiElementsRoots.Remove(inspector);
inspector.Dispose();
}
inspector = null; inspector = null;
} }
public static VisualElement CreateInspector(Action<VisualElement> onGui)
{
var container = new VisualElement();
var root = new VisualElement()
{
style =
{
position = Position.Absolute,
},
};
container.Add(new IMGUIContainer(() =>
{
const float labelExtraPadding = 2;
const float labelWidthRatio = 0.45f;
const float labelMinWidth = 120;
var space = container.resolvedStyle.left + container.resolvedStyle.right + labelExtraPadding;
EditorGUIUtility.hierarchyMode = false;
EditorGUIUtility.labelWidth = Mathf.Max(labelMinWidth,
container.resolvedStyle.width * labelWidthRatio - space);
onGui?.Invoke(root);
}));
container.Add(root);
return container;
}
public static void OnInspectorGUI(Editor editor, public static void OnInspectorGUI(Editor editor,
ref TriPropertyTreeForSerializedObject inspector) ref TriPropertyTreeForSerializedObject inspector, VisualElement visualRoot = null)
{ {
var serializedObject = editor.serializedObject; var serializedObject = editor.serializedObject;
@ -54,6 +102,11 @@ namespace TriInspector.Editors
inspector = new TriPropertyTreeForSerializedObject(serializedObject); inspector = new TriPropertyTreeForSerializedObject(serializedObject);
} }
if (visualRoot != null)
{
UiElementsRoots[inspector] = visualRoot;
}
serializedObject.UpdateIfRequiredOrScript(); serializedObject.UpdateIfRequiredOrScript();
inspector.Update(); inspector.Update();

View File

@ -1,6 +1,7 @@
using TriInspectorUnityInternalBridge; using TriInspectorUnityInternalBridge;
using UnityEditor; using UnityEditor;
using UnityEditor.AssetImporters; using UnityEditor.AssetImporters;
using UnityEngine.UIElements;
namespace TriInspector.Editors namespace TriInspector.Editors
{ {
@ -17,9 +18,19 @@ namespace TriInspector.Editors
base.OnDisable(); base.OnDisable();
} }
public override VisualElement CreateInspectorGUI()
{
return TriEditor.CreateInspector(root => OnInspectorGUI(root));
}
public override void OnInspectorGUI() public override void OnInspectorGUI()
{ {
TriEditor.OnInspectorGUI(this, ref _inspector); OnInspectorGUI(null);
}
private void OnInspectorGUI(VisualElement root)
{
TriEditor.OnInspectorGUI(this, ref _inspector, root);
if (extraDataType != null) if (extraDataType != null)
{ {

View File

@ -0,0 +1,91 @@
using TriInspectorUnityInternalBridge;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
namespace TriInspector.Elements
{
internal class TriUiToolkitPropertyElement : TriElement
{
private readonly SerializedProperty _serializedProperty;
private readonly VisualElement _rootElement;
private readonly VisualElement _selfElement;
private bool _heightDirty;
public TriUiToolkitPropertyElement(
TriProperty property,
SerializedProperty serializedProperty,
VisualElement selfElement,
VisualElement rootElement)
{
_serializedProperty = serializedProperty;
_selfElement = selfElement;
_rootElement = rootElement;
_selfElement.style.position = Position.Absolute;
}
protected override void OnAttachToPanel()
{
base.OnAttachToPanel();
_rootElement.schedule.Execute(() =>
{
_rootElement.Add(_selfElement);
_selfElement.Bind(_serializedProperty.serializedObject);
});
}
protected override void OnDetachFromPanel()
{
_rootElement.schedule.Execute(() =>
{
_selfElement.Unbind();
_rootElement.Remove(_selfElement);
});
base.OnDetachFromPanel();
}
public override bool Update()
{
var dirty = base.Update();
if (_heightDirty)
{
_heightDirty = false;
dirty = true;
}
return dirty;
}
public override float GetHeight(float width)
{
var height = _selfElement.resolvedStyle.height;
if (float.IsNaN(height))
{
_heightDirty = true;
return 0f;
}
return height;
}
public override void OnGUI(Rect position)
{
if (Event.current.type == EventType.Repaint)
{
var pos = GUIClipProxy.UnClip(position.position);
_selfElement.style.width = position.width;
_selfElement.style.left = pos.x;
_selfElement.style.top = pos.y;
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 535ce5f65f424a8c9e83943eda845fc6
timeCreated: 1690621289

View File

@ -0,0 +1,26 @@
using System;
using UnityEditor;
using UnityEngine;
namespace TriInspectorUnityInternalBridge
{
internal static class GUIClipProxy
{
private static Func<Vector2, Vector2> _guiClipUnClipVector2;
[InitializeOnLoadMethod]
private static void Setup()
{
var imGuiModuleAssembly = typeof(GUI).Assembly;
var guiClipType = imGuiModuleAssembly.GetType("UnityEngine.GUIClip", throwOnError: true);
_guiClipUnClipVector2 = (Func<Vector2, Vector2>) Delegate.CreateDelegate(typeof(Func<Vector2, Vector2>),
guiClipType.GetMethod("Unclip", new[] {typeof(Vector2)}));
}
public static Vector2 UnClip(Vector2 pos)
{
return _guiClipUnClipVector2.Invoke(pos);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e573403f6f844648ab1dc4013c8c4856
timeCreated: 1690734495

View File

@ -1,5 +1,6 @@
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements;
namespace TriInspectorUnityInternalBridge namespace TriInspectorUnityInternalBridge
{ {
@ -24,6 +25,11 @@ namespace TriInspectorUnityInternalBridge
// ReSharper disable once InconsistentNaming // ReSharper disable once InconsistentNaming
public bool hasPropertyDrawer => _handler.hasPropertyDrawer; public bool hasPropertyDrawer => _handler.hasPropertyDrawer;
public VisualElement CreatePropertyGUI(SerializedProperty property)
{
return _handler.propertyDrawer?.CreatePropertyGUI(property);
}
public float GetHeight(SerializedProperty property, GUIContent label, bool includeChildren) public float GetHeight(SerializedProperty property, GUIContent label, bool includeChildren)
{ {
return _handler.GetHeight(property, label, includeChildren); return _handler.GetHeight(property, label, includeChildren);