2025-05-09 15:40:34 +08:00

92 lines
3.5 KiB
C#

// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
// FlexiMotion // https://kybernetik.com.au/flexi-motion // Copyright 2023 Kybernetik //
#if UNITY_EDITOR
using System;
using UnityEditor;
using UnityEngine;
using static Animancer.Editor.AnimancerGUI;
namespace Animancer.Editor
// namespace FlexiMotion.Editor
{
/// <summary>[Editor-Only] A <see cref="PropertyDrawer"/> which adds an "Edit" button to a field.</summary>
/// https://kybernetik.com.au/animancer/api/Animancer.Editor/EditableFieldDrawer
/// https://kybernetik.com.au/flexi-motion/api/FlexiMotion.Editor/EditableFieldDrawer
public abstract class EditableFieldDrawer : PropertyDrawer
{
/************************************************************************************************************************/
/// <summary>The method to call when the "Edit" button is clicked.</summary>
/// <remarks>Set this in a custom editor before drawing the attributed field then clear it afterwards.</remarks>
public static event Action<SerializedProperty> OnEdit;
/************************************************************************************************************************/
/// <inheritdoc/>
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
=> EditorGUI.GetPropertyHeight(property, label);
/************************************************************************************************************************/
/// <inheritdoc/>
public override void OnGUI(Rect area, SerializedProperty property, GUIContent label)
{
DrawEditableArea(area, property);
EditorGUI.PropertyField(area, property, label, true);
}
/************************************************************************************************************************/
private static GUIStyle
_LeftAlignedButtonStyle;
private static readonly GUIContent
EditContent = new();
private void DrawEditableArea(Rect area, SerializedProperty property)
{
if (property.hasMultipleDifferentValues)
return;
var label = EditContent;
label.text = null;
label.tooltip = null;
GetEditButtonLabel(property, label);
if (!string.IsNullOrEmpty(label.text))
{
area.xMin += EditorGUIUtility.labelWidth + StandardSpacing;
area.height = LineHeight;
if (OnEdit != null)
{
_LeftAlignedButtonStyle ??= new GUIStyle(EditorStyles.miniButton)
{
alignment = TextAnchor.MiddleLeft,
padding = EditorStyles.miniPullDown.padding,
};
if (GUI.Button(area, label, _LeftAlignedButtonStyle))
OnEdit(property);
}
else
{
GUI.Label(area, label);
}
}
}
/************************************************************************************************************************/
/// <summary>Sets the `label` for the "Edit" button.</summary>
public abstract void GetEditButtonLabel(SerializedProperty property, GUIContent label);
/************************************************************************************************************************/
}
}
#endif