diff --git a/Editor.Extras/Drawers/InlineButtonDrawer.cs b/Editor.Extras/Drawers/InlineButtonDrawer.cs new file mode 100644 index 0000000..19648f2 --- /dev/null +++ b/Editor.Extras/Drawers/InlineButtonDrawer.cs @@ -0,0 +1,101 @@ +using System; +using System.Reflection; +using TriInspector; +using TriInspector.Drawers; +using UnityEngine; + +[assembly: RegisterTriAttributeDrawer(typeof(InlineButtonDrawer), TriDrawerOrder.Drawer)] + +namespace TriInspector.Drawers +{ + public class InlineButtonDrawer : TriAttributeDrawer + { + private const float MinButtonWidth = 28f; + private const float ButtonSpacing = 4f; + private const float ButtonPadding = 12f; + private const float MaxButtonWidthRatio = 0.25f; + + public override TriExtensionInitializationResult Initialize(TriPropertyDefinition propertyDefinition) + { + if (string.IsNullOrEmpty(Attribute.Name)) + { + return "[InlineButton] method name cannot be empty"; + } + + return TriExtensionInitializationResult.Ok; + } + + public override float GetHeight(float width, TriProperty property, TriElement next) + { + return next.GetHeight(width); + } + + public override void OnGUI(Rect position, TriProperty property, TriElement next) + { + var buttonText = !string.IsNullOrEmpty(Attribute.ButtonLabel) + ? Attribute.ButtonLabel + : Attribute.Name; + + var buttonContent = new GUIContent(buttonText); + var maxButtonWidth = position.width * MaxButtonWidthRatio; + var buttonWidth = Attribute.ButtonWidth > 0f + ? Attribute.ButtonWidth + : Mathf.Clamp(GUI.skin.button.CalcSize(buttonContent).x + ButtonPadding, MinButtonWidth, maxButtonWidth); + + var propertyRect = new Rect(position) + { + width = position.width - buttonWidth - ButtonSpacing, + }; + + var buttonRect = new Rect(position) + { + x = position.x + position.width - buttonWidth, + width = buttonWidth, + }; + + next.OnGUI(propertyRect); + + if (GUI.Button(buttonRect, buttonContent)) + { + InvokeMethod(property); + } + } + + private void InvokeMethod(TriProperty property) + { + var methodName = Attribute.Name; + + property.ModifyAndRecordForUndo(targetIndex => + { + try + { + var parentValue = property.Parent.GetValue(targetIndex); + var targetType = parentValue?.GetType() ?? property.Parent.FieldType; + + var methodInfo = targetType.GetMethod( + methodName, + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + + if (methodInfo == null) + { + Debug.LogError($"[InlineButton] Method '{methodName}' not found on type '{targetType.Name}'"); + return; + } + + var parameters = methodInfo.GetParameters(); + if (parameters.Length > 0) + { + Debug.LogError($"[InlineButton] Method '{methodName}' must have no parameters"); + return; + } + + methodInfo.Invoke(parentValue, null); + } + catch (Exception e) + { + Debug.LogException(e); + } + }); + } + } +} \ No newline at end of file diff --git a/Editor.Extras/Drawers/InlineButtonDrawer.cs.meta b/Editor.Extras/Drawers/InlineButtonDrawer.cs.meta new file mode 100644 index 0000000..57e6bad --- /dev/null +++ b/Editor.Extras/Drawers/InlineButtonDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 57fc012cb96c4072977620de6d06ad47 +timeCreated: 1783932151 \ No newline at end of file diff --git a/Editor.Samples/Buttons/Buttons_InlineButtonSample.cs b/Editor.Samples/Buttons/Buttons_InlineButtonSample.cs new file mode 100644 index 0000000..7fb8cea --- /dev/null +++ b/Editor.Samples/Buttons/Buttons_InlineButtonSample.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +namespace TriInspector.Editor.Samples.Buttons +{ + public class Buttons_InlineButtonSample : ScriptableObject + { + [InlineButton("click add age",nameof(Add))] + public int age; + + void Add() + { + age++; + Debug.Log(age); + } + } +} \ No newline at end of file diff --git a/Editor.Samples/Buttons/Buttons_InlineButtonSample.cs.meta b/Editor.Samples/Buttons/Buttons_InlineButtonSample.cs.meta new file mode 100644 index 0000000..0370554 --- /dev/null +++ b/Editor.Samples/Buttons/Buttons_InlineButtonSample.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9f423d2669314cf39920e28fef12e9fb +timeCreated: 1783928615 \ No newline at end of file diff --git a/Runtime/Attributes/Buttons/InlineButtonAttribute.cs b/Runtime/Attributes/Buttons/InlineButtonAttribute.cs new file mode 100644 index 0000000..b36657c --- /dev/null +++ b/Runtime/Attributes/Buttons/InlineButtonAttribute.cs @@ -0,0 +1,31 @@ +using System; +using System.Diagnostics; + +namespace TriInspector +{ + [AttributeUsage(AttributeTargets.Field|AttributeTargets.Property)] + [Conditional("UNITY_EDITOR")] + public class InlineButtonAttribute : Attribute + { + public InlineButtonAttribute(string name) + { + Name = name; + } + public InlineButtonAttribute(string label,string name):this(name) + { + ButtonLabel = label; + } + + public string Name { get; set; } + + /// + /// Optional custom label for the button. If not set, the method name is used. + /// + public string ButtonLabel { get; set; } + + /// + /// Width of the inline button in pixels. Default is 60. + /// + public float ButtonWidth { get; set; } + } +} \ No newline at end of file diff --git a/Runtime/Attributes/Buttons/InlineButtonAttribute.cs.meta b/Runtime/Attributes/Buttons/InlineButtonAttribute.cs.meta new file mode 100644 index 0000000..7bfd6a3 --- /dev/null +++ b/Runtime/Attributes/Buttons/InlineButtonAttribute.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2d6cd060f30d4f63af031e6b38ef9041 +timeCreated: 1783927895 \ No newline at end of file