// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Animancer.Editor
{
/// [Editor-Only] A GUI wrapper for drawing any object as a label with an icon.
/// https://kybernetik.com.au/animancer/api/Animancer.Editor/FastObjectField
///
public struct FastObjectField
{
/************************************************************************************************************************/
/// A representing null.
public static FastObjectField Null => new()
{
Text = "Null"
};
/************************************************************************************************************************/
/// The object passed into the last Draw call.
public object Value { get; private set; }
/// The text used for the label in the last Draw call.
public string Text { get; private set; }
/// The icon drawn in the last Draw call.
public Texture Icon { get; private set; }
/************************************************************************************************************************/
/// Sets the current details directly.
public void Set(object value, string text, Texture icon)
{
Value = value;
Text = text;
Icon = icon;
}
/************************************************************************************************************************/
/// Draws a field for the `value`.
public Rect Draw(Rect area, string label, object value, bool drawPing = true)
{
if (drawPing)
ObjectHighlightGUI.Draw(area, value);
if (!string.IsNullOrEmpty(label))
{
var labelWidth = EditorGUIUtility.labelWidth - area.x + AnimancerGUI.StandardSpacing + 1;
var labelArea = AnimancerGUI.StealFromLeft(ref area, labelWidth);
EditorGUI.LabelField(labelArea, label);
}
Draw(area, value, false);
return area;
}
/************************************************************************************************************************/
/// Draws a field for the `value`.
public void Draw(Rect area, object value, bool drawPing = true)
{
if (Value != value && Event.current.type == EventType.Layout)
SetValue(value);
Draw(area, drawPing);
}
/************************************************************************************************************************/
/// Draws a field for the .
public readonly void Draw(Rect area, bool drawPing = true)
{
HandleClick(area, drawPing);
if (Icon != null)
{
var iconArea = AnimancerGUI.StealFromLeft(ref area, area.height);
GUI.DrawTexture(iconArea, Icon);
}
GUI.Label(area, Text);
}
/************************************************************************************************************************/
private readonly void HandleClick(Rect area, bool drawPing)
{
var currentEvent = Event.current;
switch (currentEvent.rawType)
{
case EventType.MouseUp:
if (currentEvent.button == 0 &&
area.Contains(currentEvent.mousePosition))
{
ObjectHighlightGUI.Highlight(Value);
}
break;
case EventType.Repaint:
if (drawPing)
ObjectHighlightGUI.Draw(area, Value);
break;
}
}
/************************************************************************************************************************/
/// Sets the cached details.
public void SetValue(object value, string text, Texture icon = null)
{
Value = value;
Text = text;
Icon = icon;
}
/************************************************************************************************************************/
/// Sets the cached details based on the `value`.
public void SetValue(object value)
{
Value = value;
Text = GetText();
Icon = GetIcon();
}
/************************************************************************************************************************/
/// Returns a string based on the .
private readonly string GetText()
{
if (Value == null)
return "Null";
if (Value is Object obj)
{
if (obj == null)
return $"Null({obj.GetType().Name})";
return obj.GetCachedName();
}
if (Value is string str)
return $"\"{str}\"";
return Value.ToString();
}
/************************************************************************************************************************/
/// Returns an icon based on the type of the .
private readonly Texture GetIcon()
=> GetIcon(Value);
/// Returns an icon based on the type of the `value`.
public static Texture GetIcon(object value)
{
if (value == null)
return null;
if (value is Object obj)
return AssetPreview.GetMiniThumbnail(obj);
var type = value is AnimancerState
? typeof(AnimatorState)
: value.GetType();
return AssetPreview.GetMiniTypeThumbnail(type);
}
/************************************************************************************************************************/
/// Clears all cached details.
public void Clear()
{
Value = null;
Text = null;
Icon = null;
}
/************************************************************************************************************************/
}
}
#endif