TransitionLibraryAliasesPage.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
  2. #if UNITY_EDITOR
  3. using Animancer.TransitionLibraries;
  4. using System;
  5. using System.Collections.Generic;
  6. using UnityEditor;
  7. using UnityEngine;
  8. using static Animancer.Editor.AnimancerGUI;
  9. using static Animancer.Editor.TransitionLibraries.TransitionLibrarySelection;
  10. namespace Animancer.Editor.TransitionLibraries
  11. {
  12. /// <summary>[Editor-Only]
  13. /// A <see cref="TransitionLibraryWindowPage"/> for editing transition aliases.
  14. /// </summary>
  15. /// https://kybernetik.com.au/animancer/api/Animancer.Editor.TransitionLibraries/TransitionLibraryAliasesPage
  16. [Serializable]
  17. public class TransitionLibraryAliasesPage : TransitionLibraryWindowPage
  18. {
  19. /************************************************************************************************************************/
  20. [SerializeField]
  21. private Vector2 _ScrollPosition;
  22. [NonSerialized]
  23. private bool _HasSorted;
  24. /************************************************************************************************************************/
  25. /// <inheritdoc/>
  26. public override string DisplayName
  27. => "Transition Aliases";
  28. /// <inheritdoc/>
  29. public override string HelpTooltip
  30. => "Aliases are custom names which can be used to refer to transitions instead of direct references.";
  31. /// <inheritdoc/>
  32. public override int Index
  33. => 1;
  34. /************************************************************************************************************************/
  35. private static readonly List<Rect>
  36. TransitionAreas = new();
  37. /************************************************************************************************************************/
  38. /// <inheritdoc/>
  39. public override void OnGUI(Rect area)
  40. {
  41. var definition = Window.Data;
  42. if (!_HasSorted)
  43. {
  44. _HasSorted = true;
  45. definition.SortAliases();
  46. }
  47. var currentEvent = Event.current;
  48. var isRepaint = currentEvent.type == EventType.Repaint;
  49. if (isRepaint)
  50. TransitionAreas.Clear();
  51. area.yMin += StandardSpacing;
  52. area.xMin += StandardSpacing;
  53. area.xMax -= StandardSpacing;
  54. var transitions = definition.Transitions;
  55. var aliases = definition.Aliases;
  56. var viewArea = new Rect(
  57. 0,
  58. 0,
  59. area.width,
  60. CalculateHeight(1 + transitions.Length + aliases.Length) + StandardSpacing);
  61. if (viewArea.height > area.height)
  62. viewArea.width -= GUI.skin.verticalScrollbar.fixedWidth;
  63. _ScrollPosition = GUI.BeginScrollView(area, _ScrollPosition, viewArea);
  64. viewArea.height = LineHeight;
  65. DoAliasAllGUI(viewArea);
  66. NextVerticalArea(ref viewArea);
  67. var aliasIndex = 0;
  68. for (int i = 0; i < transitions.Length; i++)
  69. {
  70. var totalTransitionArea = viewArea;
  71. if (isRepaint)
  72. TransitionAreas.Add(viewArea);
  73. DoTransitionGUI(viewArea, transitions[i], i);
  74. NextVerticalArea(ref viewArea);
  75. while (aliasIndex < aliases.Length)
  76. {
  77. var alias = aliases[aliasIndex];
  78. if (alias.Index != i)
  79. {
  80. if (alias.Index < i && currentEvent.type != EventType.Used)
  81. {
  82. Debug.LogError("Aliases aren't properly sorted.");
  83. definition.SortAliases();
  84. GUIUtility.ExitGUI();
  85. }
  86. break;
  87. }
  88. DoAliasGUI(viewArea, alias, aliasIndex++);
  89. NextVerticalArea(ref viewArea);
  90. }
  91. // Highlights.
  92. totalTransitionArea.yMax = viewArea.yMin - StandardSpacing;
  93. var selected = Window.Selection.FromIndex == i || Window.Selection.ToIndex == i;
  94. var hover = totalTransitionArea.Contains(currentEvent.mousePosition);
  95. Window.Highlighter.DrawHighlightGUI(totalTransitionArea, selected, hover);
  96. }
  97. GUI.EndScrollView();
  98. }
  99. /************************************************************************************************************************/
  100. /// <summary>Draws <see cref="TransitionLibraryDefinition.AliasAllTransitions"/>.</summary>
  101. private void DoAliasAllGUI(Rect area)
  102. {
  103. var definition = Window.Data;
  104. using (var label = PooledGUIContent.Acquire(
  105. "Alias All Transitions",
  106. TransitionLibraryDefinition.AliasAllTransitionsTooltip))
  107. definition.AliasAllTransitions = EditorGUI.Toggle(area, label, definition.AliasAllTransitions);
  108. if (TryUseClickEvent(area, 0))
  109. definition.AliasAllTransitions = !definition.AliasAllTransitions;
  110. }
  111. /************************************************************************************************************************/
  112. /// <summary>Draws a `transition`.</summary>
  113. private void DoTransitionGUI(Rect area, TransitionAssetBase transition, int index)
  114. {
  115. var addArea = StealFromLeft(ref area, LineHeight * 5, StandardSpacing);
  116. TransitionModifierTableGUI.HandleTransitionLabelInput(
  117. ref area,
  118. Window,
  119. transition,
  120. index,
  121. SelectionType.ToTransition,
  122. CalculateTargetTransitionIndex);
  123. var typeArea = StealFromRight(ref area, area.width * 0.5f, StandardSpacing);
  124. var label = transition.GetCachedName();
  125. GUI.Label(area, label);
  126. var wrappedTransition = transition.GetTransition();
  127. var type = wrappedTransition != null
  128. ? wrappedTransition.GetType().GetNameCS(false)
  129. : "Null";
  130. GUI.Label(typeArea, type);
  131. if (GUI.Button(addArea, "Add"))
  132. {
  133. var alias = new NamedIndex(null, index);
  134. Window.RecordUndo().AddAlias(alias);
  135. }
  136. }
  137. /************************************************************************************************************************/
  138. /// <summary>Calculates the transition index for a drag and drop operation.</summary>
  139. private static int CalculateTargetTransitionIndex(
  140. Rect area,
  141. int index,
  142. Event currentEvent)
  143. {
  144. var y = currentEvent.mousePosition.y;
  145. for (int i = 0; i < TransitionAreas.Count; i++)
  146. if (y <= TransitionAreas[i].yMax)
  147. return i;
  148. return TransitionAreas.Count;
  149. }
  150. /************************************************************************************************************************/
  151. /// <summary>Draws an `alias`.</summary>
  152. private void DoAliasGUI(Rect area, NamedIndex alias, int index)
  153. {
  154. var removeArea = StealFromLeft(ref area, LineHeight * 5, StandardSpacing);
  155. EditorGUI.BeginChangeCheck();
  156. var name = StringAssetDrawer.DrawGUI(area, GUIContent.none, alias.Name, Window.SourceObject, out _);
  157. if (EditorGUI.EndChangeCheck())
  158. {
  159. Window.RecordUndo().Aliases[index] = alias.With(name as StringAsset);
  160. }
  161. if (GUI.Button(removeArea, "Remove"))
  162. {
  163. Window.RecordUndo().RemoveAlias(index);
  164. }
  165. }
  166. /************************************************************************************************************************/
  167. }
  168. }
  169. #endif