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