暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

UnitConnectionWidget.cs 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. using System.Collections.Generic;
  2. using UnityEditor;
  3. using UnityEngine;
  4. namespace Unity.VisualScripting
  5. {
  6. public abstract class UnitConnectionWidget<TConnection> : GraphElementWidget<FlowCanvas, TConnection>, IUnitConnectionWidget
  7. where TConnection : class, IUnitConnection
  8. {
  9. protected UnitConnectionWidget(FlowCanvas canvas, TConnection connection) : base(canvas, connection) { }
  10. #region Model
  11. protected TConnection connection => element;
  12. protected IUnitConnectionDebugData ConnectionDebugData => GetDebugData<IUnitConnectionDebugData>();
  13. #endregion
  14. #region Lifecycle
  15. public override void BeforeFrame()
  16. {
  17. base.BeforeFrame();
  18. if (showDroplets)
  19. {
  20. GraphGUI.UpdateDroplets(canvas, droplets, ConnectionDebugData.lastInvokeFrame, ref lastInvokeTime, ref dropTime);
  21. }
  22. }
  23. #endregion
  24. #region Positioning
  25. public override IEnumerable<IWidget> positionDependencies
  26. {
  27. get
  28. {
  29. yield return canvas.Widget(connection.source);
  30. yield return canvas.Widget(connection.destination);
  31. }
  32. }
  33. protected override bool snapToGrid => false;
  34. public Rect sourceHandlePosition { get; private set; }
  35. public Rect destinationHandlePosition { get; private set; }
  36. public Vector2 sourceHandleEdgeCenter { get; private set; }
  37. public Vector2 destinationHandleEdgeCenter { get; private set; }
  38. public Vector2 middlePosition;
  39. private Rect _position;
  40. private Rect _clippingPosition;
  41. public override Rect position
  42. {
  43. get { return _position; }
  44. set { }
  45. }
  46. public override Rect clippingPosition => _clippingPosition;
  47. public override void CachePosition()
  48. {
  49. base.CachePosition();
  50. sourceHandlePosition = canvas.Widget<IUnitPortWidget>(connection.source).handlePosition;
  51. destinationHandlePosition = canvas.Widget<IUnitPortWidget>(connection.destination).handlePosition;
  52. sourceHandleEdgeCenter = sourceHandlePosition.GetEdgeCenter(Edge.Right);
  53. destinationHandleEdgeCenter = destinationHandlePosition.GetEdgeCenter(Edge.Left);
  54. middlePosition = (sourceHandlePosition.center + destinationHandlePosition.center) / 2;
  55. _position = new Rect
  56. (
  57. middlePosition.x,
  58. middlePosition.y,
  59. 0,
  60. 0
  61. );
  62. _clippingPosition = _position.Encompass(sourceHandleEdgeCenter).Encompass(destinationHandleEdgeCenter);
  63. }
  64. #endregion
  65. #region Drawing
  66. protected virtual bool colorIfActive => true;
  67. public abstract Color color { get; }
  68. protected override bool dim
  69. {
  70. get
  71. {
  72. var dim = BoltCore.Configuration.dimInactiveNodes && !connection.destination.unit.Analysis<UnitAnalysis>(context).isEntered;
  73. if (BoltCore.Configuration.dimIncompatibleNodes && canvas.isCreatingConnection)
  74. {
  75. dim = true;
  76. }
  77. return dim;
  78. }
  79. }
  80. public override void DrawBackground()
  81. {
  82. base.DrawBackground();
  83. BeginDim();
  84. DrawConnection();
  85. if (showDroplets)
  86. {
  87. DrawDroplets();
  88. }
  89. EndDim();
  90. }
  91. protected virtual void DrawConnection()
  92. {
  93. var color = this.color;
  94. var sourceWidget = canvas.Widget<IUnitPortWidget>(connection.source);
  95. var destinationWidget = canvas.Widget<IUnitPortWidget>(connection.destination);
  96. var highlight = !canvas.isCreatingConnection && (sourceWidget.isMouseOver || destinationWidget.isMouseOver);
  97. var willDisconnect = sourceWidget.willDisconnect || destinationWidget.willDisconnect;
  98. if (willDisconnect)
  99. {
  100. color = UnitConnectionStyles.disconnectColor;
  101. }
  102. else if (highlight)
  103. {
  104. color = UnitConnectionStyles.highlightColor;
  105. }
  106. else if (colorIfActive)
  107. {
  108. if (EditorApplication.isPaused)
  109. {
  110. if (EditorTimeBinding.frame == ConnectionDebugData.lastInvokeFrame)
  111. {
  112. color = UnitConnectionStyles.activeColor;
  113. }
  114. }
  115. else
  116. {
  117. color = Color.Lerp(UnitConnectionStyles.activeColor, color, (EditorTimeBinding.time - ConnectionDebugData.lastInvokeTime) / UnitWidget<IUnit>.Styles.invokeFadeDuration);
  118. }
  119. }
  120. var thickness = 3;
  121. GraphGUI.DrawConnection(color, sourceHandleEdgeCenter, destinationHandleEdgeCenter, Edge.Right, Edge.Left, null, Vector2.zero, UnitConnectionStyles.relativeBend, UnitConnectionStyles.minBend, thickness);
  122. }
  123. #endregion
  124. #region Selecting
  125. public override bool canSelect => false;
  126. #endregion
  127. #region Dragging
  128. public override bool canDrag => false;
  129. #endregion
  130. #region Deleting
  131. public override bool canDelete => true;
  132. #endregion
  133. #region Droplets
  134. private readonly List<float> droplets = new List<float>();
  135. private float dropTime;
  136. private float lastInvokeTime;
  137. private const float handleAlignmentMargin = 0.1f;
  138. protected virtual bool showDroplets => true;
  139. protected abstract Vector2 GetDropletSize();
  140. protected abstract void DrawDroplet(Rect position);
  141. protected virtual void DrawDroplets()
  142. {
  143. foreach (var droplet in droplets)
  144. {
  145. Vector2 position;
  146. if (droplet < handleAlignmentMargin)
  147. {
  148. var t = droplet / handleAlignmentMargin;
  149. position = Vector2.Lerp(sourceHandlePosition.center, sourceHandleEdgeCenter, t);
  150. }
  151. else if (droplet > 1 - handleAlignmentMargin)
  152. {
  153. var t = (droplet - (1 - handleAlignmentMargin)) / handleAlignmentMargin;
  154. position = Vector2.Lerp(destinationHandleEdgeCenter, destinationHandlePosition.center, t);
  155. }
  156. else
  157. {
  158. var t = (droplet - handleAlignmentMargin) / (1 - 2 * handleAlignmentMargin);
  159. position = GraphGUI.GetPointOnConnection(t, sourceHandleEdgeCenter, destinationHandleEdgeCenter, Edge.Right, Edge.Left, UnitConnectionStyles.relativeBend, UnitConnectionStyles.minBend);
  160. }
  161. var size = GetDropletSize();
  162. using (LudiqGUI.color.Override(GUI.color * color))
  163. {
  164. DrawDroplet(new Rect(position.x - size.x / 2, position.y - size.y / 2, size.x, size.y));
  165. }
  166. }
  167. }
  168. #endregion
  169. }
  170. }