ParameterGUI.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
  2. #if UNITY_EDITOR
  3. using System;
  4. using System.Collections.Generic;
  5. using UnityEditor;
  6. using UnityEngine;
  7. namespace Animancer.Editor
  8. {
  9. /// <summary>[Editor-Only] A custom GUI for <see cref="IParameter"/>.</summary>
  10. /// https://kybernetik.com.au/animancer/api/Animancer.Editor/ParameterGUI_1
  11. ///
  12. [CustomGUI(typeof(IParameter))]
  13. public class ParameterGUI<TParameter> : CustomGUI<TParameter>
  14. where TParameter : IParameter
  15. {
  16. /************************************************************************************************************************/
  17. private static readonly HashSet<string>
  18. ExpandedNames = new();
  19. /************************************************************************************************************************/
  20. private static ICustomGUI _ValueGUI;
  21. private static ICustomGUI _DelegateGUI;
  22. /************************************************************************************************************************/
  23. /// <inheritdoc/>
  24. public override void DoGUI()
  25. {
  26. ParameterDictionary.IsDrawingInspector = true;
  27. var isExpanded = DoFoldoutGUI(out var startArea);
  28. DoValueGUI();
  29. if (isExpanded)
  30. {
  31. EditorGUI.indentLevel++;
  32. DoDetailsGUI();
  33. EditorGUI.indentLevel--;
  34. }
  35. ParameterDictionary.IsDrawingInspector = false;
  36. var endArea = GUILayoutUtility.GetLastRect();
  37. var totalArea = startArea;
  38. totalArea.yMax = endArea.yMax;
  39. if (AnimancerGUI.TryUseClickEvent(totalArea, 1))
  40. ShowContextMenu();
  41. }
  42. /************************************************************************************************************************/
  43. /// <summary>Draws the <see cref="CustomGUI{T}.Value"/> and returns the area used.</summary>
  44. private Rect DoValueGUI()
  45. {
  46. _ValueGUI ??= CustomGUIFactory.GetOrCreateForType(Value.ValueType);
  47. _ValueGUI.Label = Label;
  48. _ValueGUI.Value = Value.Value;
  49. _ValueGUI.DoGUI();
  50. Value.Value = _ValueGUI.Value;
  51. return GUILayoutUtility.GetLastRect();
  52. }
  53. /************************************************************************************************************************/
  54. /// <summary>Draws a foldout for the parameter details and returns true if expanded.</summary>
  55. private bool DoFoldoutGUI(out Rect totalArea)
  56. {
  57. var area = AnimancerGUI.LayoutSingleLineRect();
  58. totalArea = area;
  59. GUILayout.Space(-AnimancerGUI.LineHeight - AnimancerGUI.StandardSpacing);
  60. var indented = EditorGUI.IndentedRect(area);
  61. area.xMax = indented.xMin;
  62. EditorGUIUtility.AddCursorRect(area, MouseCursor.Arrow);
  63. return AnimancerGUI.DoHashedFoldoutGUI(area, ExpandedNames, Label.text);
  64. }
  65. /************************************************************************************************************************/
  66. /// <summary>Draws the details of the parameter.</summary>
  67. private void DoDetailsGUI()
  68. {
  69. EditorGUILayout.LabelField("Type", Value.ValueType.GetNameCS(false));
  70. _DelegateGUI ??= CustomGUIFactory.GetOrCreateForType(typeof(MulticastDelegate));
  71. _DelegateGUI.SetLabel("On Value Changed");
  72. _DelegateGUI.Value = Value.GetOnValueChanged();
  73. _DelegateGUI.DoGUI();
  74. }
  75. /************************************************************************************************************************/
  76. /// <summary>Shows a context menu for the parameter.</summary>
  77. private void ShowContextMenu()
  78. {
  79. var menu = new GenericMenu();
  80. menu.AddItem(new("Log Interactions"), Value.LogContext != null, () =>
  81. {
  82. Value.LogContext = Value.LogContext is null
  83. ? ""
  84. : null;
  85. });
  86. menu.AddItem(new("Inspector Control Only"), Value.InspectorControlOnly, () =>
  87. {
  88. Value.InspectorControlOnly = !Value.InspectorControlOnly;
  89. });
  90. AnimancerEditorUtilities.AddDocumentationLink(
  91. menu,
  92. "Parameters Documentation",
  93. Strings.DocsURLs.Parameters);
  94. menu.ShowAsContext();
  95. }
  96. /************************************************************************************************************************/
  97. }
  98. }
  99. #endif