FastObjectField.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
  2. #if UNITY_EDITOR
  3. using UnityEditor;
  4. using UnityEditor.Animations;
  5. using UnityEngine;
  6. using Object = UnityEngine.Object;
  7. namespace Animancer.Editor
  8. {
  9. /// <summary>[Editor-Only] A GUI wrapper for drawing any object as a label with an icon.</summary>
  10. /// https://kybernetik.com.au/animancer/api/Animancer.Editor/FastObjectField
  11. ///
  12. public struct FastObjectField
  13. {
  14. /************************************************************************************************************************/
  15. /// <summary>A <see cref="FastObjectField"/> representing <c>null</c>.</summary>
  16. public static FastObjectField Null => new()
  17. {
  18. Text = "Null"
  19. };
  20. /************************************************************************************************************************/
  21. /// <summary>The object passed into the last <c>Draw</c> call.</summary>
  22. public object Value { get; private set; }
  23. /// <summary>The text used for the label in the last <c>Draw</c> call.</summary>
  24. public string Text { get; private set; }
  25. /// <summary>The icon drawn in the last <c>Draw</c> call.</summary>
  26. public Texture Icon { get; private set; }
  27. /************************************************************************************************************************/
  28. /// <summary>Sets the current details directly.</summary>
  29. public void Set(object value, string text, Texture icon)
  30. {
  31. Value = value;
  32. Text = text;
  33. Icon = icon;
  34. }
  35. /************************************************************************************************************************/
  36. /// <summary>Draws a field for the `value`.</summary>
  37. public Rect Draw(Rect area, string label, object value, bool drawPing = true)
  38. {
  39. if (drawPing)
  40. ObjectHighlightGUI.Draw(area, value);
  41. if (!string.IsNullOrEmpty(label))
  42. {
  43. var labelWidth = EditorGUIUtility.labelWidth - area.x + AnimancerGUI.StandardSpacing + 1;
  44. var labelArea = AnimancerGUI.StealFromLeft(ref area, labelWidth);
  45. EditorGUI.LabelField(labelArea, label);
  46. }
  47. Draw(area, value, false);
  48. return area;
  49. }
  50. /************************************************************************************************************************/
  51. /// <summary>Draws a field for the `value`.</summary>
  52. public void Draw(Rect area, object value, bool drawPing = true)
  53. {
  54. if (Value != value && Event.current.type == EventType.Layout)
  55. SetValue(value);
  56. Draw(area, drawPing);
  57. }
  58. /************************************************************************************************************************/
  59. /// <summary>Draws a field for the <see cref="Value"/>.</summary>
  60. public readonly void Draw(Rect area, bool drawPing = true)
  61. {
  62. HandleClick(area, drawPing);
  63. if (Icon != null)
  64. {
  65. var iconArea = AnimancerGUI.StealFromLeft(ref area, area.height);
  66. GUI.DrawTexture(iconArea, Icon);
  67. }
  68. GUI.Label(area, Text);
  69. }
  70. /************************************************************************************************************************/
  71. private readonly void HandleClick(Rect area, bool drawPing)
  72. {
  73. var currentEvent = Event.current;
  74. switch (currentEvent.rawType)
  75. {
  76. case EventType.MouseUp:
  77. if (currentEvent.button == 0 &&
  78. area.Contains(currentEvent.mousePosition))
  79. {
  80. ObjectHighlightGUI.Highlight(Value);
  81. }
  82. break;
  83. case EventType.Repaint:
  84. if (drawPing)
  85. ObjectHighlightGUI.Draw(area, Value);
  86. break;
  87. }
  88. }
  89. /************************************************************************************************************************/
  90. /// <summary>Sets the cached details.</summary>
  91. public void SetValue(object value, string text, Texture icon = null)
  92. {
  93. Value = value;
  94. Text = text;
  95. Icon = icon;
  96. }
  97. /************************************************************************************************************************/
  98. /// <summary>Sets the cached details based on the `value`.</summary>
  99. public void SetValue(object value)
  100. {
  101. Value = value;
  102. Text = GetText();
  103. Icon = GetIcon();
  104. }
  105. /************************************************************************************************************************/
  106. /// <summary>Returns a string based on the <see cref="Value"/>.</summary>
  107. private readonly string GetText()
  108. {
  109. if (Value == null)
  110. return "Null";
  111. if (Value is Object obj)
  112. {
  113. if (obj == null)
  114. return $"Null({obj.GetType().Name})";
  115. return obj.GetCachedName();
  116. }
  117. if (Value is string str)
  118. return $"\"{str}\"";
  119. return Value.ToString();
  120. }
  121. /************************************************************************************************************************/
  122. /// <summary>Returns an icon based on the type of the <see cref="Value"/>.</summary>
  123. private readonly Texture GetIcon()
  124. => GetIcon(Value);
  125. /// <summary>Returns an icon based on the type of the `value`.</summary>
  126. public static Texture GetIcon(object value)
  127. {
  128. if (value == null)
  129. return null;
  130. if (value is Object obj)
  131. return AssetPreview.GetMiniThumbnail(obj);
  132. var type = value is AnimancerState
  133. ? typeof(AnimatorState)
  134. : value.GetType();
  135. return AssetPreview.GetMiniTypeThumbnail(type);
  136. }
  137. /************************************************************************************************************************/
  138. /// <summary>Clears all cached details.</summary>
  139. public void Clear()
  140. {
  141. Value = null;
  142. Text = null;
  143. Icon = null;
  144. }
  145. /************************************************************************************************************************/
  146. }
  147. }
  148. #endif