// 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