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