TransitionsDrawer.cs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using UnityEditor;
  6. using UnityEngine;
  7. using UnityEngine.UI;
  8. namespace TheraBytes.BetterUi.Editor
  9. {
  10. [CustomPropertyDrawer(typeof(Transitions))]
  11. public class TransitionsDrawer : PropertyDrawer
  12. {
  13. const float LineHeight = 20;
  14. const float SmallSpacing = 2;
  15. const float BigSpacing = 5;
  16. Transitions info;
  17. public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
  18. {
  19. var cur = property.GetValue<Transitions>();
  20. int lineCount = 1;
  21. int defaultCount = 1 + cur.StateNames.Count;
  22. float extraHeight = 2 * BigSpacing;
  23. switch (cur.Mode)
  24. {
  25. case Transitions.TransitionMode.SpriteSwap:
  26. case Transitions.TransitionMode.Animation:
  27. case Transitions.TransitionMode.ObjectActiveness:
  28. case Transitions.TransitionMode.LocationAnimationTransition:
  29. lineCount += defaultCount;
  30. break;
  31. case Transitions.TransitionMode.Alpha:
  32. case Transitions.TransitionMode.Color32Tint:
  33. lineCount += defaultCount + 1;
  34. extraHeight += BigSpacing;
  35. break;
  36. case Transitions.TransitionMode.MaterialProperty:
  37. lineCount += defaultCount + 2;
  38. extraHeight += 2 * BigSpacing;
  39. break;
  40. case Transitions.TransitionMode.ColorTint:
  41. lineCount += defaultCount + 3;
  42. extraHeight += BigSpacing;
  43. break;
  44. case Transitions.TransitionMode.CustomCallback:
  45. for(int i = 0; i < cur.StateNames.Count; i++)
  46. {
  47. extraHeight += GetCustomCallbackHeight(cur, i);
  48. }
  49. break;
  50. case Transitions.TransitionMode.None:
  51. default:
  52. break;
  53. }
  54. return lineCount * LineHeight + extraHeight;
  55. }
  56. public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
  57. {
  58. info = property.GetValue<Transitions>();
  59. DrawGui(position, info, property);
  60. }
  61. [Obsolete(EditorGuiUtils.ObsoleteMessage)]
  62. public static void DrawGui(Transitions sel, SerializedProperty property)
  63. {
  64. EditorGuiUtils.DrawOldMethodCallWarning();
  65. }
  66. public static void DrawGui(Rect position, Transitions sel, SerializedProperty property)
  67. {
  68. var rect = new Rect(position.x, position.y + BigSpacing, position.width, EditorGUIUtility.singleLineHeight);
  69. var mode = (Transitions.TransitionMode)EditorGUI.EnumPopup(rect, "Mode", sel.Mode);
  70. rect.y += rect.height + SmallSpacing;
  71. if (mode != sel.Mode)
  72. {
  73. sel.SetMode(mode);
  74. }
  75. if (sel.Mode == Transitions.TransitionMode.None)
  76. return;
  77. SerializedProperty transitionProp = null;
  78. List<string> postProps = new List<string>();
  79. switch (mode)
  80. {
  81. case Transitions.TransitionMode.ColorTint:
  82. transitionProp = property.FindPropertyRelative("colorTransitions");
  83. postProps.Add("affectedColor");
  84. postProps.Add("colorMultiplier");
  85. postProps.Add("fadeDuration");
  86. break;
  87. case Transitions.TransitionMode.Color32Tint:
  88. transitionProp = property.FindPropertyRelative("color32Transitions");
  89. postProps.Add("fadeDuration");
  90. break;
  91. case Transitions.TransitionMode.SpriteSwap:
  92. transitionProp = property.FindPropertyRelative("spriteSwapTransitions");
  93. break;
  94. case Transitions.TransitionMode.Animation:
  95. transitionProp = property.FindPropertyRelative("animationTransitions");
  96. break;
  97. case Transitions.TransitionMode.ObjectActiveness:
  98. transitionProp = property.FindPropertyRelative("activenessTransitions");
  99. break;
  100. case Transitions.TransitionMode.Alpha:
  101. transitionProp = property.FindPropertyRelative("alphaTransitions");
  102. postProps.Add("fadeDuration");
  103. break;
  104. case Transitions.TransitionMode.MaterialProperty:
  105. transitionProp = property.FindPropertyRelative("materialPropertyTransitions");
  106. postProps.Add("fadeDuration");
  107. break;
  108. case Transitions.TransitionMode.LocationAnimationTransition:
  109. transitionProp = property.FindPropertyRelative("locationAnimationTransitions");
  110. break;
  111. case Transitions.TransitionMode.CustomCallback:
  112. transitionProp = property.FindPropertyRelative("customTransitions");
  113. break;
  114. }
  115. var targetProp = transitionProp.FindPropertyRelative("target");
  116. if (targetProp != null)
  117. {
  118. EditorGUI.PropertyField(rect, targetProp);
  119. rect.y += rect.height + SmallSpacing;
  120. }
  121. rect.y += BigSpacing;
  122. if (targetProp == null || sel.TransitionStates.Target != null)
  123. {
  124. if(mode == Transitions.TransitionMode.MaterialProperty)
  125. {
  126. DrawMaterialPropertySelector(rect, sel, transitionProp);
  127. rect.y += rect.height + BigSpacing;
  128. }
  129. EditorGUI.indentLevel += 1;
  130. var statesProp = transitionProp.FindPropertyRelative("states");
  131. for (int i = 0; i < statesProp.arraySize; i++)
  132. {
  133. var p = statesProp.GetArrayElementAtIndex(i);
  134. var pName = p.FindPropertyRelative("Name");
  135. var pVal = p.FindPropertyRelative("StateObject");
  136. if (mode == Transitions.TransitionMode.LocationAnimationTransition)
  137. {
  138. // special drawer for location transitions
  139. var options = (sel.TransitionStates.Target as LocationAnimations).Animations.Select(o => o.Name).ToList();
  140. options.Insert(0, "[ None ]");
  141. int prevIdx = options.IndexOf(pVal.stringValue);
  142. int newIdx = EditorGUI.Popup(rect, pName.stringValue, prevIdx, options.ToArray());
  143. rect.y += rect.height + SmallSpacing;
  144. if (prevIdx != newIdx)
  145. {
  146. pVal.stringValue = (newIdx > 0) ? options[newIdx] : "";
  147. pVal.serializedObject.ApplyModifiedProperties();
  148. }
  149. }
  150. else if(mode == Transitions.TransitionMode.CustomCallback)
  151. {
  152. rect.height = GetCustomCallbackHeight(sel, i);
  153. EditorGUI.PropertyField(rect, pVal, new GUIContent(pName.stringValue));
  154. rect.y += rect.height + SmallSpacing;
  155. }
  156. else
  157. {
  158. EditorGUI.PropertyField(rect, pVal, new GUIContent(pName.stringValue));
  159. rect.y += rect.height + SmallSpacing;
  160. }
  161. }
  162. EditorGUI.indentLevel -= 1;
  163. if (postProps.Count > 0)
  164. {
  165. rect.y += BigSpacing;
  166. foreach (string pName in postProps)
  167. {
  168. var p = transitionProp.FindPropertyRelative(pName);
  169. EditorGUI.PropertyField(rect, p);
  170. rect.y += rect.height + SmallSpacing;
  171. }
  172. #if UNITY_2019_1_OR_NEWER
  173. if (!sel.StateNames.Contains("Selected") && sel.StateNames.Contains("Pressed"))
  174. {
  175. if (GUI.Button(rect, "Upgrade"))
  176. {
  177. sel.ComplementStateNames(Transitions.SelectionStateNames);
  178. }
  179. rect.y += rect.height + SmallSpacing;
  180. }
  181. #endif
  182. }
  183. }
  184. }
  185. private static float GetCustomCallbackHeight(Transitions sel, int i)
  186. {
  187. var custom = sel.TransitionStates as CustomTransitions;
  188. var state = custom.GetStates().ToList()[i];
  189. int cnt = state.StateObject.GetPersistentEventCount();
  190. if(cnt == 0)
  191. {
  192. return 5.75f * EditorGUIUtility.singleLineHeight;
  193. }
  194. return (3 + 2.75f * cnt) * EditorGUIUtility.singleLineHeight;
  195. }
  196. private static void DrawMaterialPropertySelector(Rect rect, Transitions sel, SerializedProperty transitionProp)
  197. {
  198. var matPropTrans = (sel.TransitionStates as MaterialPropertyTransition);
  199. if (matPropTrans == null)
  200. return;
  201. var img = (matPropTrans.Target as BetterImage);
  202. if (img == null)
  203. return;
  204. var options = img.MaterialProperties.FloatProperties.Select(o => o.Name).ToArray();
  205. var sp = transitionProp.FindPropertyRelative("propertyIndex");
  206. int cur = sp.intValue;
  207. int matPropIndex = EditorGUI.Popup(rect, "Affected Property", cur, options);
  208. sp.intValue = matPropIndex;
  209. }
  210. }
  211. }