Skip to content

Commit

Permalink
Add drawer for Button with parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
vanifatovvlad committed Jun 21, 2023
1 parent 4df61db commit 5b32961
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 24 deletions.
96 changes: 77 additions & 19 deletions Editor.Extras/Drawers/ButtonDrawer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -16,12 +18,10 @@ public class ButtonDrawer : TriAttributeDrawer<ButtonAttribute>

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);
Expand All @@ -33,33 +33,91 @@ memberInfo is MethodInfo mi &&
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;

public TriButtonElement(TriProperty property, ButtonAttribute attribute,
ValueResolver<string> nameResolver)
{
_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;
}

if (string.IsNullOrEmpty(name))
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));
}
}

protected override float GetHeaderHeight(float width)
{
name = property.DisplayName;
return GetButtonHeight();
}

if (string.IsNullOrEmpty(name))
protected override void DrawHeader(Rect position)
{
name = property.RawName;
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);
}
}

if (GUI.Button(position, name))
private float GetButtonHeight()
{
InvokeButton(property, Array.Empty<object>());
return _attribute.ButtonSize != 0
? _attribute.ButtonSize
: EditorGUIUtility.singleLineHeight;
}
}

Expand Down
6 changes: 6 additions & 0 deletions Editor.Samples/Buttons/Buttons_ButtonSample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,10 @@ private void DoButton()
{
Debug.Log("Button clicked!");
}

[Button(ButtonSizes.Large)]
private void DoButtonWithParameters(Vector3 vec, string str = "default value")
{
Debug.Log($"Button with parameters: {vec} {str}");
}
}
16 changes: 11 additions & 5 deletions Editor/TriPropertyDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class TriPropertyDefinition
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;

Expand Down Expand Up @@ -53,6 +53,14 @@ private static TriPropertyDefinition CreateForMemberInfo(
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,
Expand All @@ -74,9 +82,7 @@ internal TriPropertyDefinition(
_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 _);
Expand Down Expand Up @@ -150,7 +156,7 @@ public object GetValue(TriProperty property, int targetIndex)
{
var value = _valueGetter(property, targetIndex);

if (value == null && _isNonPolymorphicSerializedByUnity)
if (value == null && !_skipNullValuesFix)
{
value = TriUnitySerializationUtilities.PopulateUnityDefaultValueForType(FieldType);

Expand Down

0 comments on commit 5b32961

Please sign in to comment.