Bez popisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UnitEditor.cs 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEditor;
  5. using UnityEngine;
  6. namespace Unity.VisualScripting
  7. {
  8. [Editor(typeof(IUnit))]
  9. public class UnitEditor : GraphElementEditor<FlowGraphContext>
  10. {
  11. public UnitEditor(Metadata metadata) : base(metadata) { }
  12. protected IUnit unit => (IUnit)element;
  13. protected new UnitDescription description => (UnitDescription)base.description;
  14. protected new UnitAnalysis analysis => (UnitAnalysis)base.analysis;
  15. protected override float GetHeight(float width, GUIContent label)
  16. {
  17. var height = 0f;
  18. height += GetHeaderHeight(width);
  19. height += GetWrappedInspectorHeight(width);
  20. if (exception != null)
  21. {
  22. height += GetExceptionHeight(width);
  23. }
  24. height += analysis.warnings.Sum(warning => warning.GetHeight(width));
  25. if (unit.inputs.Any())
  26. {
  27. height += GetPortsHeight(width, new GUIContent("Inputs"), unit.inputs.Cast<IUnitPort>());
  28. }
  29. if (unit.outputs.Any())
  30. {
  31. height += GetPortsHeight(width, new GUIContent("Outputs"), unit.outputs.Cast<IUnitPort>());
  32. }
  33. return height;
  34. }
  35. protected override void OnGUI(Rect position, GUIContent label)
  36. {
  37. y = 0;
  38. OnHeaderGUI(position);
  39. EditorGUI.BeginChangeCheck();
  40. OnWrappedInspectorGUI(position);
  41. if (EditorGUI.EndChangeCheck())
  42. {
  43. unit.Define();
  44. }
  45. if (exception != null)
  46. {
  47. y--;
  48. OnExceptionGUI(position.VerticalSection(ref y, GetExceptionHeight(position.width) + 1));
  49. }
  50. foreach (var warning in analysis.warnings)
  51. {
  52. y--;
  53. warning.OnGUI(position.VerticalSection(ref y, warning.GetHeight(position.width) + 1));
  54. }
  55. if (unit.inputs.Any())
  56. {
  57. y--;
  58. OnPortsGUI(position, new GUIContent("Inputs"), unit.inputs.Cast<IUnitPort>());
  59. }
  60. if (unit.outputs.Any())
  61. {
  62. y--;
  63. OnPortsGUI(position, new GUIContent("Outputs"), unit.outputs.Cast<IUnitPort>());
  64. }
  65. }
  66. private float GetPortsInnerWidth(float totalWidth)
  67. {
  68. return totalWidth - Styles.portsBackground.padding.left - Styles.portsBackground.padding.right;
  69. }
  70. private float GetPortsHeight(float totalWidth, GUIContent label, IEnumerable<IUnitPort> ports)
  71. {
  72. var innerWidth = GetPortsInnerWidth(totalWidth);
  73. var height = 0f;
  74. height += Styles.portsBackground.padding.top;
  75. height += Styles.portsLabel.CalcHeight(label, innerWidth);
  76. foreach (var port in ports)
  77. {
  78. height += Styles.spaceBetweenPorts;
  79. height += GetPortHeight(innerWidth, port);
  80. }
  81. height += Styles.portsBackground.padding.bottom;
  82. return height;
  83. }
  84. private void OnPortsGUI(Rect position, GUIContent label, IEnumerable<IUnitPort> ports)
  85. {
  86. var backgroundPosition = new Rect
  87. (
  88. position.x,
  89. y,
  90. position.width,
  91. GetPortsHeight(position.width, label, ports)
  92. );
  93. if (e.type == EventType.Repaint)
  94. {
  95. Styles.portsBackground.Draw(backgroundPosition, false, false, false, false);
  96. }
  97. var innerWidth = GetPortsInnerWidth(position.width);
  98. y += Styles.portsBackground.padding.top;
  99. position.x += Styles.portsBackground.padding.left;
  100. var labelPosition = new Rect
  101. (
  102. position.x,
  103. y,
  104. innerWidth,
  105. Styles.portsLabel.CalcHeight(label, innerWidth)
  106. );
  107. GUI.Label(labelPosition, label, Styles.portsLabel);
  108. y += labelPosition.height;
  109. foreach (var port in ports)
  110. {
  111. y += Styles.spaceBetweenPorts;
  112. var portPosition = new Rect
  113. (
  114. position.x,
  115. y,
  116. innerWidth,
  117. GetPortHeight(innerWidth, port)
  118. );
  119. OnPortGUI(portPosition, port);
  120. y += portPosition.height;
  121. }
  122. y += Styles.portsBackground.padding.bottom;
  123. }
  124. private GUIContent GetLabelContent(IUnitPort port)
  125. {
  126. string type;
  127. if (port is IUnitControlPort)
  128. {
  129. type = "Flow";
  130. }
  131. else if (port is IUnitValuePort)
  132. {
  133. type = ((IUnitValuePort)port).type.DisplayName();
  134. }
  135. else if (port is IUnitInvalidPort)
  136. {
  137. type = "Invalid";
  138. }
  139. else
  140. {
  141. throw new NotSupportedException();
  142. }
  143. return new GUIContent(string.Format($"<b>{port.Description<UnitPortDescription>().label}</b> <color=#{ColorPalette.unityForegroundDim.ToHexString()}>: {LudiqGUIUtility.EscapeRichText(type)}</color>"));
  144. }
  145. private float GetPortHeight(float paddedWidth, IUnitPort port)
  146. {
  147. var portDescription = port.Description<UnitPortDescription>();
  148. var labelWidth = paddedWidth - Styles.portIcon.fixedWidth - Styles.portIcon.margin.right;
  149. var height = 0f;
  150. height += Styles.portLabel.CalcHeight(GetLabelContent(port), labelWidth);
  151. var summary = portDescription.summary;
  152. if (!StringUtility.IsNullOrWhiteSpace(summary))
  153. {
  154. height += Styles.portDescription.CalcHeight(new GUIContent(summary), labelWidth);
  155. }
  156. return height;
  157. }
  158. private void OnPortGUI(Rect portPosition, IUnitPort port)
  159. {
  160. var portDescription = port.Description<UnitPortDescription>();
  161. var labelWidth = portPosition.width - Styles.portIcon.fixedWidth - Styles.portIcon.margin.right;
  162. var iconPosition = new Rect
  163. (
  164. portPosition.x,
  165. portPosition.y,
  166. Styles.portIcon.fixedWidth,
  167. Styles.portIcon.fixedHeight
  168. );
  169. var icon = portDescription.icon?[IconSize.Small];
  170. if (icon != null)
  171. {
  172. GUI.DrawTexture(iconPosition, icon);
  173. }
  174. var labelContent = GetLabelContent(port);
  175. var labelPosition = new Rect
  176. (
  177. iconPosition.xMax + Styles.portIcon.margin.right,
  178. portPosition.y,
  179. labelWidth,
  180. Styles.portLabel.CalcHeight(labelContent, labelWidth)
  181. );
  182. GUI.Label(labelPosition, labelContent, Styles.portLabel);
  183. var summary = portDescription.summary;
  184. if (!StringUtility.IsNullOrWhiteSpace(summary))
  185. {
  186. var descriptionContent = new GUIContent(summary);
  187. var descriptionPosition = new Rect
  188. (
  189. labelPosition.x,
  190. labelPosition.yMax,
  191. labelWidth,
  192. Styles.portDescription.CalcHeight(descriptionContent, labelWidth)
  193. );
  194. GUI.Label(descriptionPosition, descriptionContent, Styles.portDescription);
  195. }
  196. }
  197. public new static class Styles
  198. {
  199. static Styles()
  200. {
  201. portsBackground = new GUIStyle("IN BigTitle");
  202. portsBackground.padding = new RectOffset(10, 5, 7, 10);
  203. portsLabel = new GUIStyle(EditorStyles.label);
  204. portsLabel.fontSize = 13;
  205. portsLabel.padding = new RectOffset(0, 0, 0, 3);
  206. portLabel = new GUIStyle(EditorStyles.label);
  207. portLabel.imagePosition = ImagePosition.TextOnly;
  208. portLabel.wordWrap = true;
  209. portLabel.richText = true;
  210. portDescription = new GUIStyle(EditorStyles.label);
  211. portDescription.imagePosition = ImagePosition.TextOnly;
  212. portDescription.wordWrap = true;
  213. portDescription.richText = true;
  214. portDescription.fontSize = 10;
  215. portDescription.normal.textColor = ColorPalette.unityForegroundDim;
  216. portIcon = new GUIStyle();
  217. portIcon.imagePosition = ImagePosition.ImageOnly;
  218. portIcon.fixedWidth = portIcon.fixedHeight = IconSize.Small;
  219. portIcon.margin.right = 5;
  220. inspectorBackground = new GUIStyle();
  221. inspectorBackground.padding = new RectOffset(10, 10, 10, 10);
  222. }
  223. public static readonly GUIStyle portsBackground;
  224. public static readonly GUIStyle portsLabel;
  225. public static readonly GUIStyle portLabel;
  226. public static readonly GUIStyle portDescription;
  227. public static readonly GUIStyle portIcon;
  228. public static readonly float spaceBetweenPorts = 5;
  229. public static readonly GUIStyle inspectorBackground;
  230. }
  231. }
  232. }