Add drawer for Button with parameters

This commit is contained in:
VladV 2023-06-21 21:48:08 +04:00
parent 58bbdb57b2
commit 20faf1bef5
5 changed files with 105 additions and 28 deletions

View File

@ -2,7 +2,9 @@
using System.Reflection;
using TriInspector;
using TriInspector.Drawers;
using TriInspector.Elements;
using TriInspector.Resolvers;
using TriInspector.Utilities;
using UnityEditor;
using UnityEngine;
@ -16,12 +18,10 @@ namespace TriInspector.Drawers
public override TriExtensionInitializationResult Initialize(TriPropertyDefinition propertyDefinition)
{
var isValidMethod = propertyDefinition.TryGetMemberInfo(out var memberInfo) &&
memberInfo is MethodInfo mi &&
mi.GetParameters().Length == 0;
var isValidMethod = propertyDefinition.TryGetMemberInfo(out var memberInfo) && memberInfo is MethodInfo;
if (!isValidMethod)
{
return "[Button] valid only on methods without parameters";
return "[Button] valid only on methods";
}
_nameResolver = ValueResolver.ResolveString(propertyDefinition, Attribute.Name);
@ -33,33 +33,94 @@ namespace TriInspector.Drawers
return TriExtensionInitializationResult.Ok;
}
public override float GetHeight(float width, TriProperty property, TriElement next)
public override TriElement CreateElement(TriProperty property, TriElement next)
{
if (Attribute.ButtonSize != 0)
{
return Attribute.ButtonSize;
}
return EditorGUIUtility.singleLineHeight;
return new TriButtonElement(property, Attribute, _nameResolver);
}
public override void OnGUI(Rect position, TriProperty property, TriElement next)
private class TriButtonElement : TriHeaderGroupBaseElement
{
var name = _nameResolver.GetValue(property);
private readonly TriProperty _property;
private readonly ButtonAttribute _attribute;
private readonly ValueResolver<string> _nameResolver;
private readonly object[] _invocationArgs;
if (string.IsNullOrEmpty(name))
public TriButtonElement(TriProperty property, ButtonAttribute attribute,
ValueResolver<string> nameResolver)
{
name = property.DisplayName;
_property = property;
_attribute = attribute;
_nameResolver = nameResolver;
var mi = property.TryGetMemberInfo(out var memberInfo)
? (MethodInfo) memberInfo
: throw new Exception("TriButtonElement requires MethodInfo");
var parameters = mi.GetParameters();
_invocationArgs = new object[parameters.Length];
for (var i = 0; i < parameters.Length; i++)
{
var pIndex = i;
var pInfo = parameters[pIndex];
if (pInfo.HasDefaultValue)
{
_invocationArgs[pIndex] = pInfo.DefaultValue;
}
var pTriDefinition = TriPropertyDefinition.CreateForGetterSetter(
pIndex, pInfo.Name, pInfo.ParameterType,
((self, targetIndex) => _invocationArgs[pIndex]),
((self, targetIndex, value) => _invocationArgs[pIndex] = value));
var pTriProperty = new TriProperty(_property.PropertyTree, _property, pTriDefinition, null);
AddChild(new TriPropertyElement(pTriProperty));
}
}
if (string.IsNullOrEmpty(name))
protected override float GetHeaderHeight(float width)
{
name = property.RawName;
return GetButtonHeight();
}
if (GUI.Button(position, name))
protected override void DrawHeader(Rect position)
{
InvokeButton(property, Array.Empty<object>());
if (_invocationArgs.Length > 0)
{
TriEditorGUI.DrawBox(position, TriEditorStyles.TabOnlyOne);
}
var name = _nameResolver.GetValue(_property);
if (string.IsNullOrEmpty(name))
{
name = _property.DisplayName;
}
if (string.IsNullOrEmpty(name))
{
name = _property.RawName;
}
var buttonRect = new Rect(position)
{
height = GetButtonHeight(),
};
if (GUI.Button(buttonRect, name))
{
InvokeButton(_property, _invocationArgs);
}
}
private float GetButtonHeight()
{
return _attribute.ButtonSize != 0
? _attribute.ButtonSize
: EditorGUIUtility.singleLineHeight;
}
}

View File

@ -8,4 +8,10 @@ public class Buttons_ButtonSample : ScriptableObject
{
Debug.Log("Button clicked!");
}
[Button(ButtonSizes.Large)]
private void DoButtonWithParameters(Vector3 vec, string str = "default value")
{
Debug.Log($"Button with parameters: {vec} {str}");
}
}

View File

@ -18,7 +18,7 @@ namespace TriInspector
private readonly List<string> _extensionErrors = new List<string>();
private readonly MemberInfo _memberInfo;
private readonly List<Attribute> _attributes;
private readonly bool _isNonPolymorphicSerializedByUnity;
private readonly bool _skipNullValuesFix;
private TriPropertyDefinition _arrayElementDefinitionBackingField;
@ -53,6 +53,14 @@ namespace TriInspector
memberInfo, ownerType, order, propertyName, propertyType, valueGetter, valueSetter, attributes, false);
}
internal static TriPropertyDefinition CreateForGetterSetter(
int order, string name, Type fieldType,
ValueGetterDelegate valueGetter, ValueSetterDelegate valueSetter)
{
return new TriPropertyDefinition(
null, null, order, name, fieldType, valueGetter, valueSetter, null, false);
}
internal TriPropertyDefinition(
MemberInfo memberInfo,
Type ownerType,
@ -74,9 +82,7 @@ namespace TriInspector
_valueGetter = valueGetter;
_valueSetter = valueSetter;
_isNonPolymorphicSerializedByUnity = memberInfo is FieldInfo fi &&
TriUnitySerializationUtilities.IsSerializableByUnity(fi) &&
fi.GetCustomAttribute<SerializeReference>() == null;
_skipNullValuesFix = memberInfo != null && memberInfo.GetCustomAttribute<SerializeReference>() != null;
Order = order;
IsReadOnly = _valueSetter == null || Attributes.TryGet(out ReadOnlyAttribute _);
@ -150,7 +156,7 @@ namespace TriInspector
{
var value = _valueGetter(property, targetIndex);
if (value == null && _isNonPolymorphicSerializedByUnity)
if (value == null && !_skipNullValuesFix)
{
value = TriUnitySerializationUtilities.PopulateUnityDefaultValueForType(FieldType);

View File

@ -544,13 +544,16 @@ public float val;
#### Button
![Button](https://user-images.githubusercontent.com/26966368/168235907-2b5ed6d4-d00b-4cd6-999c-432abd0a2230.png)
![Button](https://github.com/codewriter-packages/Tri-Inspector/assets/26966368/76f4a3a4-4bf9-4f58-8615-17adb986ab81)
```csharp
[Button("Click me!")]
private void DoButton()
private void Button() => Debug.Log("Button clicked!");
[Button(ButtonSizes.Large)]
private void ButtonWithParameters(Vector3 vec, string str = "default value")
{
Debug.Log("Button clicked!");
Debug.Log($"Button with parameters: {vec} {str}");
}
```

View File

@ -16,9 +16,10 @@ namespace TriInspector
Name = name;
}
public ButtonAttribute(ButtonSizes buttonSize)
public ButtonAttribute(ButtonSizes buttonSize, string name = null)
{
ButtonSize = (int) buttonSize;
Name = name;
}
public string Name { get; set; }