mirror of
https://github.com/codewriter-packages/Tri-Inspector.git
synced 2025-01-22 08:18:49 -05:00
Added InlineEditor attribute
This commit is contained in:
parent
09e2eda979
commit
2e8014ac14
190
Editor.Extras/Drawers/InlineEditorDrawer.cs
Normal file
190
Editor.Extras/Drawers/InlineEditorDrawer.cs
Normal file
@ -0,0 +1,190 @@
|
||||
using TriInspector;
|
||||
using TriInspector.Drawers;
|
||||
using TriInspector.Elements;
|
||||
using TriInspector.GroupDrawers;
|
||||
using TriInspector.Utilities;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
[assembly: RegisterTriAttributeDrawer(typeof(InlineEditorDrawer), TriDrawerOrder.Fallback - 1000,
|
||||
Target = TriTargetPropertyType.Self)]
|
||||
|
||||
namespace TriInspector.Drawers
|
||||
{
|
||||
public class InlineEditorDrawer : TriAttributeDrawer<InlineEditorAttribute>
|
||||
{
|
||||
public override TriElement CreateElement(TriProperty property, TriElement next)
|
||||
{
|
||||
if (!typeof(Object).IsAssignableFrom(property.FieldType))
|
||||
{
|
||||
var stack = new TriElement();
|
||||
stack.AddChild(new TriInfoBoxElement($"InlineEditor valid only on Object fields",
|
||||
MessageType.Error));
|
||||
stack.AddChild(next);
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
var element = new TriBoxGroupDrawer.TriBoxGroupElement(new DeclareBoxGroupAttribute(""));
|
||||
element.AddChild(new ObjectReferenceFoldoutDrawerElement(property));
|
||||
element.AddChild(new InlineEditorDrawerElement(property));
|
||||
return element;
|
||||
}
|
||||
|
||||
private class ObjectReferenceFoldoutDrawerElement : TriElement
|
||||
{
|
||||
private readonly TriProperty _property;
|
||||
|
||||
public ObjectReferenceFoldoutDrawerElement(TriProperty property)
|
||||
{
|
||||
_property = property;
|
||||
}
|
||||
|
||||
public override float GetHeight(float width)
|
||||
{
|
||||
return EditorGUIUtility.singleLineHeight;
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect position)
|
||||
{
|
||||
var prefixRect = new Rect(position)
|
||||
{
|
||||
height = EditorGUIUtility.singleLineHeight,
|
||||
xMax = position.xMin + EditorGUIUtility.labelWidth,
|
||||
};
|
||||
var pickerRect = new Rect(position)
|
||||
{
|
||||
height = EditorGUIUtility.singleLineHeight,
|
||||
xMin = prefixRect.xMax,
|
||||
};
|
||||
|
||||
TriGuiHelper.PushIndentLevel();
|
||||
TriEditorGUI.Foldout(prefixRect, _property);
|
||||
TriGuiHelper.PopIndentLevel();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
var allowSceneObjects = _property.PropertyTree.TargetObjects[0] is var targetObject &&
|
||||
targetObject != null && !EditorUtility.IsPersistent(targetObject);
|
||||
|
||||
var value = (Object) _property.Value;
|
||||
value = EditorGUI.ObjectField(pickerRect, GUIContent.none, value,
|
||||
_property.FieldType, allowSceneObjects);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
_property.SetValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class InlineEditorDrawerElement : TriElement
|
||||
{
|
||||
private readonly TriProperty _property;
|
||||
private Editor _editor;
|
||||
private Rect _editorPosition;
|
||||
private bool _dirty;
|
||||
|
||||
public InlineEditorDrawerElement(TriProperty property)
|
||||
{
|
||||
_property = property;
|
||||
_editorPosition = Rect.zero;
|
||||
}
|
||||
|
||||
protected override void OnDetachFromPanel()
|
||||
{
|
||||
if (_editor != null)
|
||||
{
|
||||
Object.DestroyImmediate(_editor);
|
||||
}
|
||||
|
||||
base.OnDetachFromPanel();
|
||||
}
|
||||
|
||||
public override bool Update()
|
||||
{
|
||||
if (_editor == null || _editor.target != (Object) _property.Value)
|
||||
{
|
||||
if (_editor != null)
|
||||
{
|
||||
Object.DestroyImmediate(_editor);
|
||||
}
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
if (_dirty)
|
||||
{
|
||||
_dirty = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override float GetHeight(float width)
|
||||
{
|
||||
if (_property.IsExpanded && !_property.IsValueMixed)
|
||||
{
|
||||
return _editorPosition.height;
|
||||
}
|
||||
|
||||
return 0f;
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect position)
|
||||
{
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
_editorPosition = position;
|
||||
}
|
||||
|
||||
var lastEditorRect = Rect.zero;
|
||||
|
||||
if (TriGuiHelper.IsEditorForObjectPushed((Object) _property.Value))
|
||||
{
|
||||
GUI.Label(position, "Recursive inline editors not supported");
|
||||
|
||||
lastEditorRect.height = EditorGUIUtility.singleLineHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_editor == null)
|
||||
{
|
||||
_editor = Editor.CreateEditor((Object) _property.Value);
|
||||
}
|
||||
|
||||
if (_editor != null && _property.IsExpanded && !_property.IsValueMixed)
|
||||
{
|
||||
TriGuiHelper.PushIndentLevel();
|
||||
var indentedEditorPosition = EditorGUI.IndentedRect(_editorPosition);
|
||||
TriGuiHelper.PopIndentLevel();
|
||||
|
||||
GUILayout.BeginArea(indentedEditorPosition);
|
||||
GUILayout.BeginVertical();
|
||||
_editor.OnInspectorGUI();
|
||||
GUILayout.EndVertical();
|
||||
lastEditorRect = GUILayoutUtility.GetLastRect();
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_editor != null)
|
||||
{
|
||||
Object.DestroyImmediate(_editor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Event.current.type == EventType.Repaint &&
|
||||
!Mathf.Approximately(_editorPosition.height, lastEditorRect.height))
|
||||
{
|
||||
_editorPosition.height = lastEditorRect.height;
|
||||
_dirty = true;
|
||||
_property.PropertyTree.RequestRepaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
Editor.Extras/Drawers/InlineEditorDrawer.cs.meta
Normal file
3
Editor.Extras/Drawers/InlineEditorDrawer.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 088c34bc4fc448b4aac18ed9bf4f9bc6
|
||||
timeCreated: 1641657562
|
@ -16,7 +16,7 @@ namespace TriInspector.GroupDrawers
|
||||
return new TriBoxGroupElement(attribute);
|
||||
}
|
||||
|
||||
private class TriBoxGroupElement : TriPropertyCollectionBaseElement
|
||||
public class TriBoxGroupElement : TriPropertyCollectionBaseElement
|
||||
{
|
||||
private const float HeaderWidth = 22;
|
||||
private const float InsetTop = 4;
|
||||
|
@ -1,5 +1,6 @@
|
||||
using TriInspector.Utilities;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Profiling;
|
||||
|
||||
namespace TriInspector
|
||||
@ -10,15 +11,24 @@ namespace TriInspector
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
var mode = TriEditorMode.None;
|
||||
|
||||
var isInlineEditor = TriGuiHelper.PushedEditorCount > 0;
|
||||
if (isInlineEditor)
|
||||
{
|
||||
mode |= TriEditorMode.InlineEditor;
|
||||
}
|
||||
|
||||
if (serializedObject.targetObject != null)
|
||||
{
|
||||
_inspector = TriPropertyTree.Create(serializedObject);
|
||||
_inspector = TriPropertyTree.Create(serializedObject, mode);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_inspector?.Destroy();
|
||||
_inspector = null;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
@ -54,6 +64,13 @@ namespace TriInspector
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
if (_inspector.RepaintRequired)
|
||||
{
|
||||
_inspector.RepaintRequired = false;
|
||||
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -15,6 +15,8 @@ namespace TriInspector
|
||||
[PublicAPI]
|
||||
public int ChildrenCount => _children.Count;
|
||||
|
||||
public bool IsAttached => _attached;
|
||||
|
||||
[PublicAPI]
|
||||
public virtual bool Update()
|
||||
{
|
||||
|
@ -11,9 +11,10 @@ namespace TriInspector
|
||||
{
|
||||
public sealed class TriPropertyTree : ITriPropertyParent
|
||||
{
|
||||
private readonly TriEditorMode _mode;
|
||||
private readonly TriInspectorElement _inspectorElement;
|
||||
|
||||
private TriPropertyTree([NotNull] SerializedObject serializedObject)
|
||||
private TriPropertyTree([NotNull] SerializedObject serializedObject, TriEditorMode mode)
|
||||
{
|
||||
SerializedObject = serializedObject ?? throw new ArgumentNullException(nameof(serializedObject));
|
||||
TargetObjects = serializedObject.targetObjects;
|
||||
@ -29,6 +30,7 @@ namespace TriInspector
|
||||
})
|
||||
.ToList();
|
||||
|
||||
_mode = mode;
|
||||
_inspectorElement = new TriInspectorElement(this);
|
||||
_inspectorElement.AttachInternal();
|
||||
}
|
||||
@ -47,15 +49,25 @@ namespace TriInspector
|
||||
|
||||
public TriPropertyTree Root { get; }
|
||||
|
||||
public bool IsInlineEditor => (_mode & TriEditorMode.InlineEditor) != 0;
|
||||
|
||||
internal bool RepaintRequired { get; set; }
|
||||
|
||||
object ITriPropertyParent.GetValue(int targetIndex) => TargetObjects[targetIndex];
|
||||
|
||||
internal static TriPropertyTree Create(SerializedObject scriptableObject)
|
||||
internal static TriPropertyTree Create(SerializedObject scriptableObject,
|
||||
TriEditorMode mode = TriEditorMode.None)
|
||||
{
|
||||
return new TriPropertyTree(scriptableObject);
|
||||
return new TriPropertyTree(scriptableObject, mode);
|
||||
}
|
||||
|
||||
internal void Destroy()
|
||||
{
|
||||
if (!_inspectorElement.IsAttached)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_inspectorElement.DetachInternal();
|
||||
}
|
||||
|
||||
@ -76,5 +88,17 @@ namespace TriInspector
|
||||
var rect = GUILayoutUtility.GetRect(width, height);
|
||||
_inspectorElement.OnGUI(rect);
|
||||
}
|
||||
|
||||
public void RequestRepaint()
|
||||
{
|
||||
RepaintRequired = true;
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum TriEditorMode
|
||||
{
|
||||
None = 0,
|
||||
InlineEditor = 1 << 0,
|
||||
}
|
||||
}
|
@ -18,6 +18,21 @@ namespace TriInspector.Utilities
|
||||
IndentLevelStack.Clear();
|
||||
}
|
||||
|
||||
public static int PushedEditorCount => EditorStack.Count;
|
||||
|
||||
public static bool IsEditorForObjectPushed(Object target)
|
||||
{
|
||||
foreach (var it in EditorStack)
|
||||
{
|
||||
if (it.editor.target == target)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void PushEditor(Editor editor)
|
||||
{
|
||||
EditorStack.Push(new EditorData
|
||||
|
12
Runtime/Attributes/InlineEditorAttribute.cs
Normal file
12
Runtime/Attributes/InlineEditorAttribute.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace TriInspector
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property |
|
||||
AttributeTargets.Class | AttributeTargets.Struct)]
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
public sealed class InlineEditorAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
3
Runtime/Attributes/InlineEditorAttribute.cs.meta
Normal file
3
Runtime/Attributes/InlineEditorAttribute.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d09104644014c71b3b0c3b472b743a5
|
||||
timeCreated: 1641657539
|
Loading…
Reference in New Issue
Block a user