PortView.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEditor.Experimental.GraphView;
  5. using UnityEngine.UIElements;
  6. using System;
  7. using System.Reflection;
  8. namespace GraphProcessor
  9. {
  10. public class PortView : Port
  11. {
  12. public string fieldName => fieldInfo.Name;
  13. public Type fieldType => fieldInfo.FieldType;
  14. public new Type portType;
  15. public BaseNodeView owner { get; private set; }
  16. public PortData portData;
  17. public event Action< PortView, Edge > OnConnected;
  18. public event Action< PortView, Edge > OnDisconnected;
  19. protected FieldInfo fieldInfo;
  20. protected BaseEdgeConnectorListener listener;
  21. string userPortStyleFile = "PortViewTypes";
  22. List< EdgeView > edges = new List< EdgeView >();
  23. public int connectionCount => edges.Count;
  24. readonly string portStyle = "GraphProcessorStyles/PortView";
  25. protected PortView(Direction direction, FieldInfo fieldInfo, PortData portData, BaseEdgeConnectorListener edgeConnectorListener)
  26. : base(portData.vertical ? Orientation.Vertical : Orientation.Horizontal, direction, Capacity.Multi, portData.displayType ?? fieldInfo.FieldType)
  27. {
  28. this.fieldInfo = fieldInfo;
  29. this.listener = edgeConnectorListener;
  30. this.portType = portData.displayType ?? fieldInfo.FieldType;
  31. this.portData = portData;
  32. this.portName = fieldName;
  33. styleSheets.Add(Resources.Load<StyleSheet>(portStyle));
  34. UpdatePortSize();
  35. var userPortStyle = Resources.Load<StyleSheet>(userPortStyleFile);
  36. if (userPortStyle != null)
  37. styleSheets.Add(userPortStyle);
  38. if (portData.vertical)
  39. AddToClassList("Vertical");
  40. this.tooltip = portData.tooltip;
  41. }
  42. public static PortView CreatePortView(Direction direction, FieldInfo fieldInfo, PortData portData, BaseEdgeConnectorListener edgeConnectorListener)
  43. {
  44. var pv = new PortView(direction, fieldInfo, portData, edgeConnectorListener);
  45. pv.m_EdgeConnector = new BaseEdgeConnector(edgeConnectorListener);
  46. pv.AddManipulator(pv.m_EdgeConnector);
  47. // Force picking in the port label to enlarge the edge creation zone
  48. var portLabel = pv.Q("type");
  49. if (portLabel != null)
  50. {
  51. portLabel.pickingMode = PickingMode.Position;
  52. portLabel.style.flexGrow = 1;
  53. }
  54. // hide label when the port is vertical
  55. if (portData.vertical && portLabel != null)
  56. portLabel.style.display = DisplayStyle.None;
  57. // Fixup picking mode for vertical top ports
  58. if (portData.vertical)
  59. pv.Q("connector").pickingMode = PickingMode.Position;
  60. return pv;
  61. }
  62. /// <summary>
  63. /// Update the size of the port view (using the portData.sizeInPixel property)
  64. /// </summary>
  65. public void UpdatePortSize()
  66. {
  67. int size = portData.sizeInPixel == 0 ? 8 : portData.sizeInPixel;
  68. var connector = this.Q("connector");
  69. var cap = connector.Q("cap");
  70. connector.style.width = size;
  71. connector.style.height = size;
  72. cap.style.width = size - 4;
  73. cap.style.height = size - 4;
  74. // Update connected edge sizes:
  75. edges.ForEach(e => e.UpdateEdgeSize());
  76. }
  77. public virtual void Initialize(BaseNodeView nodeView, string name)
  78. {
  79. this.owner = nodeView;
  80. AddToClassList(fieldName);
  81. // Correct port type if port accept multiple values (and so is a container)
  82. if (direction == Direction.Input && portData.acceptMultipleEdges && portType == fieldType) // If the user haven't set a custom field type
  83. {
  84. if (fieldType.GetGenericArguments().Length > 0)
  85. portType = fieldType.GetGenericArguments()[0];
  86. }
  87. if (name != null)
  88. portName = name;
  89. visualClass = "Port_" + portType.Name;
  90. tooltip = portData.tooltip;
  91. }
  92. public override void Connect(Edge edge)
  93. {
  94. OnConnected?.Invoke(this, edge);
  95. base.Connect(edge);
  96. var inputNode = (edge.input as PortView).owner;
  97. var outputNode = (edge.output as PortView).owner;
  98. edges.Add(edge as EdgeView);
  99. inputNode.OnPortConnected(edge.input as PortView);
  100. outputNode.OnPortConnected(edge.output as PortView);
  101. }
  102. public override void Disconnect(Edge edge)
  103. {
  104. OnDisconnected?.Invoke(this, edge);
  105. base.Disconnect(edge);
  106. if (!(edge as EdgeView).isConnected)
  107. return ;
  108. var inputNode = (edge.input as PortView)?.owner;
  109. var outputNode = (edge.output as PortView)?.owner;
  110. inputNode?.OnPortDisconnected(edge.input as PortView);
  111. outputNode?.OnPortDisconnected(edge.output as PortView);
  112. edges.Remove(edge as EdgeView);
  113. }
  114. public void UpdatePortView(PortData data)
  115. {
  116. if (data.displayType != null)
  117. {
  118. base.portType = data.displayType;
  119. portType = data.displayType;
  120. visualClass = "Port_" + portType.Name;
  121. }
  122. if (!String.IsNullOrEmpty(data.displayName))
  123. base.portName = data.displayName;
  124. portData = data;
  125. // Update the edge in case the port color have changed
  126. schedule.Execute(() => {
  127. foreach (var edge in edges)
  128. {
  129. edge.UpdateEdgeControl();
  130. edge.MarkDirtyRepaint();
  131. }
  132. }).ExecuteLater(50); // Hummm
  133. UpdatePortSize();
  134. }
  135. public List< EdgeView > GetEdges()
  136. {
  137. return edges;
  138. }
  139. }
  140. }