Maze / Library /PackageCache /com.unity.visualscripting@1.8.0 /Editor /VisualScripting.State /States /FlowStateWidget.cs
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using UnityEditor; | |
| using UnityEngine; | |
| namespace Unity.VisualScripting | |
| { | |
| [] | |
| public sealed class FlowStateWidget : NesterStateWidget<FlowState>, IDragAndDropHandler | |
| { | |
| public FlowStateWidget(StateCanvas canvas, FlowState state) : base(canvas, state) | |
| { | |
| state.nest.beforeGraphChange += BeforeGraphChange; | |
| state.nest.afterGraphChange += AfterGraphChange; | |
| if (state.nest.graph != null) | |
| { | |
| state.nest.graph.elements.CollectionChanged += CacheEventLinesOnUnityThread; | |
| } | |
| } | |
| public override void Dispose() | |
| { | |
| base.Dispose(); | |
| state.nest.beforeGraphChange -= BeforeGraphChange; | |
| state.nest.afterGraphChange -= AfterGraphChange; | |
| } | |
| private void BeforeGraphChange() | |
| { | |
| if (state.nest.graph != null) | |
| { | |
| state.nest.graph.elements.CollectionChanged -= CacheEventLinesOnUnityThread; | |
| } | |
| } | |
| private void AfterGraphChange() | |
| { | |
| CacheEventLinesOnUnityThread(); | |
| if (state.nest.graph != null) | |
| { | |
| state.nest.graph.elements.CollectionChanged += CacheEventLinesOnUnityThread; | |
| } | |
| } | |
| private List<EventLine> eventLines { get; } = new List<EventLine>(); | |
| private void CacheEventLinesOnUnityThread() | |
| { | |
| UnityAPI.Async(CacheEventLines); | |
| } | |
| private void CacheEventLines() | |
| { | |
| eventLines.Clear(); | |
| if (state.nest.graph != null) | |
| { | |
| eventLines.AddRange(state.nest.graph.units | |
| .OfType<IEventUnit>() | |
| .Select(e => e.GetType()) | |
| .Distinct() | |
| .Select(eventType => new EventLine(eventType)) | |
| .OrderBy(eventLine => eventLine.content.text)); | |
| } | |
| Reposition(); | |
| } | |
| protected override void CacheItemFirstTime() | |
| { | |
| base.CacheItemFirstTime(); | |
| CacheEventLines(); | |
| } | |
| public Dictionary<EventLine, Rect> eventLinesPositions { get; } = new Dictionary<EventLine, Rect>(); | |
| public override void CachePosition() | |
| { | |
| base.CachePosition(); | |
| eventLinesPositions.Clear(); | |
| var y = contentInnerPosition.y; | |
| foreach (var eventLine in eventLines) | |
| { | |
| var eventLinePosition = new Rect | |
| ( | |
| contentInnerPosition.x, | |
| y, | |
| contentInnerPosition.width, | |
| eventLine.GetHeight(contentInnerPosition.width) | |
| ); | |
| eventLinesPositions.Add(eventLine, eventLinePosition); | |
| y += eventLinePosition.height; | |
| } | |
| } | |
| protected override float GetContentHeight(float width) | |
| { | |
| var eventLinesHeight = 0f; | |
| foreach (var eventLine in eventLines) | |
| { | |
| eventLinesHeight += eventLine.GetHeight(width); | |
| } | |
| return eventLinesHeight; | |
| } | |
| protected override bool showContent => eventLines.Count > 0; | |
| protected override void DrawContent() | |
| { | |
| foreach (var eventLine in eventLines) | |
| { | |
| eventLine.Draw(eventLinesPositions[eventLine]); | |
| } | |
| } | |
| public DragAndDropVisualMode dragAndDropVisualMode => DragAndDropVisualMode.Generic; | |
| public bool AcceptsDragAndDrop() | |
| { | |
| return DragAndDropUtility.Is<ScriptGraphAsset>(); | |
| } | |
| public void PerformDragAndDrop() | |
| { | |
| UndoUtility.RecordEditedObject("Drag & Drop Macro"); | |
| state.nest.source = GraphSource.Macro; | |
| state.nest.macro = DragAndDropUtility.Get<ScriptGraphAsset>(); | |
| state.nest.embed = null; | |
| GUI.changed = true; | |
| } | |
| public void UpdateDragAndDrop() { } | |
| public void DrawDragAndDropPreview() | |
| { | |
| GraphGUI.DrawDragAndDropPreviewLabel(new Vector2(edgePosition.x, outerPosition.yMax), "Replace with: " + DragAndDropUtility.Get<ScriptGraphAsset>().name, typeof(ScriptGraphAsset).Icon()); | |
| } | |
| public void ExitDragAndDrop() { } | |
| public new static class Styles | |
| { | |
| static Styles() | |
| { | |
| eventLine = new GUIStyle(EditorStyles.label); | |
| eventLine.wordWrap = true; | |
| eventLine.imagePosition = ImagePosition.TextOnly; // The icon is drawn manually | |
| eventLine.padding = new RectOffset(0, 0, 3, 3); | |
| } | |
| public static readonly GUIStyle eventLine; | |
| public static readonly float spaceAroundLineIcon = 5; | |
| } | |
| public class EventLine | |
| { | |
| public EventLine(Type eventType) | |
| { | |
| content = new GUIContent(BoltFlowNameUtility.UnitTitle(eventType, false, true), eventType.Icon()?[IconSize.Small]); | |
| } | |
| public GUIContent content { get; } | |
| public float GetHeight(float width) | |
| { | |
| var labelWidth = width - Styles.spaceAroundLineIcon - IconSize.Small - Styles.spaceAroundLineIcon; | |
| return Styles.eventLine.CalcHeight(content, labelWidth); | |
| } | |
| public void Draw(Rect position) | |
| { | |
| var iconPosition = new Rect | |
| ( | |
| position.x + Styles.spaceAroundLineIcon, | |
| position.y + Styles.eventLine.padding.top - 1, | |
| IconSize.Small, | |
| IconSize.Small | |
| ); | |
| var labelPosition = new Rect | |
| ( | |
| iconPosition.xMax + Styles.spaceAroundLineIcon, | |
| position.y, | |
| position.width - Styles.spaceAroundLineIcon - iconPosition.width - Styles.spaceAroundLineIcon, | |
| position.height | |
| ); | |
| if (content.image != null) | |
| { | |
| GUI.DrawTexture(iconPosition, content.image); | |
| } | |
| GUI.Label(labelPosition, content, Styles.eventLine); | |
| } | |
| } | |
| } | |
| } | |