void OnPointerMove(PointerMoveEvent e)
        {
            VseGraphView graphView    = null;
            Vector2      pointerDelta = Vector2.zero;

            if (m_DraggingControlPoint || m_DraggingTightness)
            {
                graphView = GetFirstAncestorOfType <VseGraphView>();
                var pointerPosition = this.ChangeCoordinatesTo(parent, e.localPosition);
                pointerDelta = new Vector2(pointerPosition.x, pointerPosition.y) - m_OriginalPointerPosition;
            }

            if (graphView == null)
            {
                return;
            }

            if (m_DraggingControlPoint)
            {
                var newPosition = m_OriginalElementPosition + pointerDelta;
                graphView.store.Dispatch(new MoveEdgeControlPointAction(m_EdgeModel, m_ControlPointIndex, newPosition, m_OriginalTightness));
                m_EdgeControl.MarkDirtyRepaint();
                e.StopPropagation();
            }
            else if (m_DraggingTightness)
            {
                var tightnessDelta = pointerDelta.x - pointerDelta.y;
                var newTightness   = m_OriginalTightness + tightnessDelta;
                graphView.store.Dispatch(new MoveEdgeControlPointAction(m_EdgeModel, m_ControlPointIndex, m_OriginalElementPosition, newTightness));
                e.StopPropagation();
                m_EdgeControl.MarkDirtyRepaint();
            }
        }
Exemple #2
0
        public static List <Tuple <IVariableDeclarationModel, Vector2> > ExtractVariablesFromDroppedElements(
            IReadOnlyCollection <GraphElement> dropElements,
            VseGraphView graphView,
            Vector2 initialPosition)
        {
            var elementOffset     = Vector2.zero;
            var variablesToCreate = new List <Tuple <IVariableDeclarationModel, Vector2> >();

            foreach (var dropElement in dropElements)
            {
                if (dropElement is TokenDeclaration tokenDeclaration)
                {
                    Vector2 pos = dropElement.GetPosition().position;

                    if (!variablesToCreate.Any(x => ReferenceEquals(x.Item1, tokenDeclaration.Declaration)))
                    {
                        variablesToCreate.Add(new Tuple <IVariableDeclarationModel, Vector2>(tokenDeclaration.Declaration, pos));
                    }
                    tokenDeclaration.RemoveFromHierarchy();
                }
                else if (dropElement is IVisualScriptingField visualScriptingField)
                {
                    Vector2 pos = graphView.contentViewContainer.WorldToLocal(initialPosition) + elementOffset;
                    elementOffset.y += ((GraphElement)visualScriptingField).layout.height + VseGraphView.DragDropSpacer;

                    if (!variablesToCreate.Any(x => ReferenceEquals(x.Item1, visualScriptingField.GraphElementModel)))
                    {
                        variablesToCreate.Add(new Tuple <IVariableDeclarationModel, Vector2>(visualScriptingField.GraphElementModel as IVariableDeclarationModel, pos));
                    }
                }
            }
            return(variablesToCreate);
        }
        public static void HighlightGraphElements(this VseGraphView graphView)
        {
            graphView.ClearGraphElementsHighlight();

            if (graphView.selection.Count == 0)
            {
                return;
            }

            IEnumerable <IHighlightable> highlightables = GetHighlightables(graphView, true).ToList();

            // For all the selected items, highlight the graphElements that share the same declaration model
            // Exception: If the graphElement is selected, do not highlight it
            foreach (ISelectable selectable in graphView.selection)
            {
                if (!(selectable is IHasGraphElementModel hasGraphElementModel))
                {
                    continue;
                }

                foreach (IHighlightable highlightable in highlightables
                         .Where(h => (!Equals(selectable, h) || !ReferenceEquals(selectable, h)) &&
                                h.ShouldHighlightItemUsage(hasGraphElementModel.GraphElementModel)))
                {
                    highlightable.Highlighted = true;
                }
            }
        }
Exemple #4
0
        public void DuplicateStackedNode([Values] TestingMode mode)
        {
            var stack = GraphModel.CreateStack("stack", Vector2.zero);

            stack.CreateStackedNode <Type0FakeNodeModel>("test");

            TestPrereqActionPostreq(mode,
                                    () =>
            {
                Assert.That(stack.NodeModels.Count, Is.EqualTo(1));
            }, () =>
            {
                var node = stack.NodeModels.Single();

                TargetInsertionInfo info;
                info.OperationName             = "Duplicate";
                info.Delta                     = Vector2.one;
                info.TargetStack               = stack;
                info.TargetStackInsertionIndex = -1;

                IEditorDataModel editorDataModel         = m_Store.GetState().EditorDataModel;
                VseGraphView.CopyPasteData copyPasteData = VseGraphView.GatherCopiedElementsData(VseGraphView.CopyMode.KeepReference, new List <IGraphElementModel> {
                    node
                });
                Assert.That(copyPasteData.IsEmpty(), Is.False);

                return(new PasteSerializedDataAction(GraphModel, info, editorDataModel, copyPasteData.ToJson()));
            }, () =>
            {
                Assert.That(stack.NodeModels.Count, Is.EqualTo(2));
            });
        }
Exemple #5
0
 public VseContextualMenuBuilder(Store store, ContextualMenuPopulateEvent evt, IList <ISelectable> selection, VseGraphView graphView)
 {
     m_Store     = store;
     m_Evt       = evt;
     m_Selection = selection;
     m_GraphView = graphView;
 }
        public override void OnStartDragging(GraphElement ge)
        {
            if (ge is TokenDeclaration tokenDeclaration)
            {
                VseGraphView  gView       = GetFirstOfType <VseGraphView>();
                VisualElement tokenParent = tokenDeclaration.parent;
                int           childIndex  = tokenDeclaration.FindIndexInParent();

                gView.RemoveElement(tokenDeclaration);
                tokenDeclaration.SetClasses();
                gView.AddElement(tokenDeclaration);
                // By removing the tokenDeclaration from the graph view, we also removed it from the selection.
                // We need to add the tokenDeclaration back in order to properly drag.
                tokenDeclaration.Select(gView, true);
                tokenDeclaration.BringToFront();

                TokenDeclaration placeHolderTokenDeclaration = tokenDeclaration.Clone();
                placeHolderTokenDeclaration.AddToClassList("placeHolder");
                tokenParent.Insert(childIndex, placeHolderTokenDeclaration);
                placeHolderTokenDeclaration.MarkDirtyRepaint();

                gView.AddPlaceholderToken(tokenDeclaration);
            }
            else
            {
                var originalWidth  = ge.resolvedStyle.width;
                var originalHeight = ge.resolvedStyle.height;
                base.OnStartDragging(ge);
                // Revert to same width and height after element became unstacked
                ge.style.width  = originalWidth;
                ge.style.height = originalHeight;
            }
        }
Exemple #7
0
        public GtfErrorToolbar(Store store, VseGraphView graphView)
        {
            m_Store     = store;
            m_GraphView = graphView;
            name        = "errorToolbar";
            AddToClassList("gtf-toolbar");
            styleSheets.Add(
                AssetDatabase.LoadAssetAtPath <StyleSheet>(PackageTransitionHelper.AssetPath +
                                                           "VisualScripting/Editor/Menu/VseMenu.uss"));

            AssetDatabase
            .LoadAssetAtPath <VisualTreeAsset>(PackageTransitionHelper.AssetPath +
                                               "VisualScripting/Editor/Menu/GtfErrorToolbar.uxml").CloneTree(this);

            m_ErrorIconLabel = this.MandatoryQ("errorIconLabel");

            m_PreviousErrorButton         = this.MandatoryQ <ToolbarButton>("previousErrorButton");
            m_PreviousErrorButton.tooltip = "Go To Previous Error";
            m_PreviousErrorButton.RemoveManipulator(m_PreviousErrorButton.clickable);
            m_PreviousErrorButton.AddManipulator(new Clickable(OnPreviousErrorButton));

            m_NextErrorButton         = this.MandatoryQ <ToolbarButton>("nextErrorButton");
            m_NextErrorButton.tooltip = "Go To Next Error";
            m_NextErrorButton.RemoveManipulator(m_NextErrorButton.clickable);
            m_NextErrorButton.AddManipulator(new Clickable(OnNextErrorButton));

            m_ErrorCounterLabel = this.MandatoryQ <Label>("errorCounterLabel");
        }
        public TracingTimeline(VseGraphView vseGraphView, State vsWindowState, IMGUIContainer imguiContainer)
        {
            m_VseGraphView   = vseGraphView;
            m_VSWindowState  = vsWindowState;
            m_ImguiContainer = imguiContainer;
            m_TimeArea       = new TimeArea();
            m_Overlay        = new AnimEditorOverlay()
            {
                PlayHeadColor = new Color(0.2117647F, 0.6039216F, 0.8F)
            };
            m_State         = new TimelineState(m_TimeArea);
            m_Overlay.state = m_State;

            var         debugger = m_VSWindowState?.CurrentGraphModel?.Stencil?.Debugger;
            IGraphTrace trace    = debugger?.GetGraphTrace(m_VSWindowState?.CurrentGraphModel,
                                                           m_VSWindowState.CurrentTracingTarget);

            if (trace?.AllFrames != null && trace.AllFrames.Count > 0)
            {
                int firstFrame = trace.AllFrames[0].Frame;
                int lastFrame  = trace.AllFrames[trace.AllFrames.Count - 1].Frame;
                m_TimeArea.SetShownRange(
                    firstFrame - k_MinTimeVisibleOnTheRight,
                    lastFrame + k_MinTimeVisibleOnTheRight);
            }
        }
Exemple #9
0
        public void Test_DuplicateAction_OneNode([Values] TestingMode mode)
        {
            GraphModel.CreateNode <Type0FakeNodeModel>("Node0", Vector2.zero);
            TestPrereqActionPostreq(mode,
                                    () =>
            {
                Assert.That(GetNodeCount(), Is.EqualTo(1));
                var nodeModel = GetNode(0);
                Assert.That(nodeModel, Is.TypeOf <Type0FakeNodeModel>());

                TargetInsertionInfo info = new TargetInsertionInfo();
                info.OperationName       = "Duplicate";
                info.Delta = Vector2.one;
                info.TargetStackInsertionIndex = -1;

                IEditorDataModel editorDataModel         = m_Store.GetState().EditorDataModel;
                VseGraphView.CopyPasteData copyPasteData = VseGraphView.GatherCopiedElementsData(x => x, new List <IGraphElementModel> {
                    nodeModel
                });

                return(new PasteSerializedDataAction(GraphModel, info, editorDataModel, copyPasteData.ToJson()));
            },
                                    () =>
            {
                Assert.That(GetNodeCount(), Is.EqualTo(2));
                Assert.That(GraphModel.NodeModels.Count(n => n == null), Is.Zero);
            });
        }
        public static void ClearGraphElementsHighlight(this VseGraphView graphView)
        {
            IEnumerable <IHighlightable> elements = GetHighlightables(graphView, true);

            foreach (var element in elements)
            {
                element.Highlighted = false;
            }
        }
Exemple #11
0
        public Blackboard(Store store, VseGraphView graphView, bool windowed)
        {
            base.Store = store;

            styleSheets.Add(AssetDatabase.LoadAssetAtPath <StyleSheet>(UICreationHelper.templatePath + "Blackboard.uss"));

            AddToClassList("blackboard");

            scrollable = true;
            title      = k_ClassLibraryTitle;
            subTitle   = "";

            viewDataKey = string.Empty;

            addItemRequested  = OnAddItemRequested;
            moveItemRequested = OnMoveItemRequested;

            // TODO 0.5: hack - we have two conflicting renaming systems
            // the blackboard one seems to win
            // for 0.4, just rewire it to dispatch the same action as ours
            editTextRequested = OnEditTextRequested;

            RegisterCallback <AttachToPanelEvent>(OnAttachToPanel);
            RegisterCallback <DetachFromPanelEvent>(OnDetachFromPanel);

            this.AddManipulator(new ContextualMenuManipulator(OnContextualMenuEvent));

            graphView.OnSelectionChangedCallback += s =>
            {
                IGraphModel currentGraphModel = Store.GetState().CurrentGraphModel;
                if (!(currentGraphModel as Object))
                {
                    return;
                }

                if (currentGraphModel == GraphView.UIController.LastGraphModel &&
                    (GraphView.selection.LastOrDefault() is BlackboardField ||
                     GraphView.selection.LastOrDefault() is IVisualScriptingField))
                {
                    ((VSGraphModel)currentGraphModel).LastChanges.RequiresRebuild = true;
                    return;
                }

                RebuildSections();
            };

            var header = this.Query("header").First();

            m_AddButton = header?.Query <Button>("addButton").First();
            if (m_AddButton != null)
            {
                m_AddButton.style.visibility = Visibility.Hidden;
            }

            this.windowed  = windowed;
            this.graphView = graphView;
        }
Exemple #12
0
        static void OnDropOutsideCallback(Store store, Vector2 pos, Edge edge)
        {
            VseGraphView graphView = edge.GetFirstAncestorOfType <VseGraphView>();
            Vector2      worldPos  = pos;

            pos = graphView.contentViewContainer.WorldToLocal(pos);

            List <IEdgeModel> edgesToDelete = GetDropEdgeModelsToDelete(edge);

            // when grabbing an existing edge's end, the edgeModel should be deleted
            if ((edge).GraphElementModel != null)
            {
                edgesToDelete.Add((IEdgeModel)edge.GraphElementModel);
            }

            IStackModel     targetStackModel = null;
            int             targetIndex      = -1;
            IGroupNodeModel groupModel       = null;
            StackNode       stackNode        = graphView.lastHoveredVisualElement as StackNode ??
                                               graphView.lastHoveredVisualElement.GetFirstOfType <StackNode>();

            if (stackNode != null)
            {
                targetStackModel = stackNode.stackModel;
                targetIndex      = stackNode.GetInsertionIndex(worldPos);
            }
            else if (graphView.lastHoveredVisualElement is Group group)
            {
                groupModel = group.model;
            }

            IPortModel existingPortModel;

            // warning: when dragging the end of an existing edge, both ports are non null.
            if (edge.input != null && edge.output != null)
            {
                float distanceToOutput = Vector2.Distance(edge.edgeControl.from, pos);
                float distanceToInput  = Vector2.Distance(edge.edgeControl.to, pos);
                // note: if the user was able to stack perfectly both ports, we'd be in trouble
                if (distanceToOutput < distanceToInput)
                {
                    existingPortModel = (IPortModel)edge.input.userData;
                }
                else
                {
                    existingPortModel = (IPortModel)edge.output.userData;
                }
            }
            else
            {
                Port existingPort = (Port)(edge.input ?? edge.output);
                existingPortModel = existingPort.userData as IPortModel;
            }

            CreateNodes(store, existingPortModel, pos, edgesToDelete, targetStackModel, targetIndex, groupModel);
        }
 public TracingTimeline(VseGraphView vseGraphView, State vsWindowState, IMGUIContainer imguiContainer)
 {
     m_VseGraphView   = vseGraphView;
     m_VSWindowState  = vsWindowState;
     m_ImguiContainer = imguiContainer;
     m_TimeArea       = new TimeArea();
     m_Overlay        = new AnimEditorOverlay();
     m_State          = new TimelineState(m_TimeArea);
     m_Overlay.state  = m_State;
 }
        static IEnumerable <IHighlightable> GetHighlightables(VseGraphView graphView,
                                                              bool includeBlackboard = false)
        {
            IEnumerable <IHighlightable> elements = graphView.graphElements.ToList()
                                                    .OfType <IHighlightable>()
                                                    .Where(x => x is IHasGraphElementModel);
            Blackboard blackboard = graphView.UIController.Blackboard;

            return(includeBlackboard ? elements.Concat(blackboard.GraphVariables) : elements);
        }
        public DebugDisplayElement(VseGraphView graphView)
        {
            m_GraphView = graphView;

            pickingMode = PickingMode.Ignore;

            m_Crosses = new List <DebugRectData>();
            m_Boxes   = new List <DebugRectData>();

            AddCross(Rect.MinMaxRect(-10, -10, 10, 10), Color.green);
        }
 public VseUIController(VseGraphView graphView, Store store)
 {
     m_GraphView   = graphView;
     m_Store       = store;
     m_IconsParent = new VisualElement {
         name = "iconsParent"
     };
     m_IconsParent.style.overflow = Overflow.Visible;
     Blackboard       = new Blackboard(m_Store, m_GraphView, windowed: true);
     m_LastGraphModel = null;
 }
        public VseMenu(Store store, VseGraphView graphView)
        {
            m_Store     = store;
            m_GraphView = graphView;
            name        = "vseMenu";
            styleSheets.Add(AssetDatabase.LoadAssetAtPath <StyleSheet>(PackageTransitionHelper.AssetPath + "VisualScripting/Editor/Menu/VseMenu.uss"));

            AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(PackageTransitionHelper.AssetPath + "VisualScripting/Editor/Menu/VseMenu.uxml").CloneTree(this);

            CreateCommonMenu();
            CreateErrorMenu();
            CreateBreadcrumbMenu();
            CreateTracingMenu();
            CreateOptionsMenu();
        }
        public void DisplayAppropriateSearcher(Vector2 mousePosition, VseGraphView graphView)
        {
            VisualElement picked = graphView.panel.Pick(mousePosition);

            while (picked != null && !(picked is IVisualScriptingField))
            {
                picked = picked.parent;
            }

            // optimization: stop at the first IVsBlackboardField, but still exclude BlackboardThisFields
            if (picked != null && picked is BlackboardVariableField field)
            {
                graphView.window.DisplayTokenDeclarationSearcher((VariableDeclarationModel)field.VariableDeclarationModel, mousePosition);
            }
            else
            {
                graphView.window.DisplayAddVariableSearcher(mousePosition);
            }
        }
        public static void ClearGraphElementsHighlight(this VseGraphView graphView,
                                                       Func <IGraphElementModel, bool> predicate)
        {
            IEnumerable <IHighlightable> elements = GetHighlightables(graphView, true);

            foreach (var element in elements)
            {
                var hasGraphElementModel = element as IHasGraphElementModel;
                if (hasGraphElementModel == null)
                {
                    continue;
                }

                if (predicate(hasGraphElementModel.GraphElementModel))
                {
                    element.Highlighted = false;
                }
            }
        }
Exemple #20
0
        void ClearHighlights()
        {
            VseGraphView gv = (VseGraphView)m_GraphView;

            if (gv?.UIController.ModelsToNodeMapping != null)
            {
                foreach (GraphElement x in gv.UIController.ModelsToNodeMapping.Values)
                {
                    x.RemoveFromClassList(k_TraceHighlight);
                    x.RemoveFromClassList(k_TraceSecondaryHighlight);
                    x.RemoveFromClassList(k_ExceptionHighlight);

                    VseUIController.ClearErrorBadge(x);
                    VseUIController.ClearValue(x);

                    // TODO ugly
                    gv.UIController.DisplayCompilationErrors(gv.store.GetState());
                }
            }
        }
Exemple #21
0
        public VseUIController(VseGraphView graphView, Store store)
        {
            m_GraphView   = graphView;
            m_Store       = store;
            m_IconsParent = new VisualElement {
                name = "iconsParent"
            };
            m_IconsParent.style.overflow = Overflow.Visible;
            Blackboard = new Blackboard(m_Store, m_GraphView);
            var blackboardPosition = m_Store.GetState().EditorDataModel.BlackboardPosition;

            if (Math.Abs(blackboardPosition.size.x) > float.Epsilon && Math.Abs(blackboardPosition.size.y) > float.Epsilon)
            {
                Blackboard.SetPosition(m_Store.GetState().EditorDataModel.BlackboardPosition);
            }
            else
            {
                ResetBlackboard();
            }
            m_LastGraphModel = null;
        }
        protected virtual void OnEnable()
        {
            if (m_PreviousGraphModels == null)
            {
                m_PreviousGraphModels = new List <GraphModel>();
            }

            if (m_BlackboardExpandedRowStates == null)
            {
                m_BlackboardExpandedRowStates = new List <string>();
            }

            if (m_ElementModelsToSelectUponCreation == null)
            {
                m_ElementModelsToSelectUponCreation = new List <string>();
            }

            if (m_ElementModelsToExpandUponCreation == null)
            {
                m_ElementModelsToExpandUponCreation = new List <string>();
            }

            rootVisualElement.RegisterCallback <ValidateCommandEvent>(OnValidateCommand);
            rootVisualElement.RegisterCallback <ExecuteCommandEvent>(OnExecuteCommand);
            rootVisualElement.RegisterCallback <MouseMoveEvent>(_ => m_IdleTimer?.Restart());

            rootVisualElement.styleSheets.Add(AssetDatabase.LoadAssetAtPath <StyleSheet>(k_StyleSheetPath + "VSEditor.uss"));

            rootVisualElement.Clear();
            rootVisualElement.style.overflow      = Overflow.Hidden;
            rootVisualElement.pickingMode         = PickingMode.Ignore;
            rootVisualElement.style.flexDirection = FlexDirection.Column;
            rootVisualElement.name = "vseRoot";

            // Create the store.
            DataModel = CreateDataModel();
            State initialState = CreateInitialState();

            m_Store = new Store(initialState, Store.Options.TrackUndoRedo);

            VseUtility.SetupLogStickyCallback();

            m_GraphContainer = new VisualElement {
                name = "graphContainer"
            };
            m_GraphView = CreateGraphView();
            m_Menu      = CreateMenu();
            m_BlankPage = CreateBlankPage();


            IMGUIContainer imguiContainer = null;

            imguiContainer = new IMGUIContainer(() =>
            {
                var timeRect = new Rect(0, 0, rootVisualElement.layout.width, imguiContainer.layout.height);
                m_TracingTimeline.OnGUI(timeRect);
            });
            m_TracingTimeline = new TracingTimeline(m_Store.GetState(), imguiContainer);
            m_TracingTimeline.SyncVisible();

            rootVisualElement.Add(m_Menu);
            rootVisualElement.Add(imguiContainer);
            rootVisualElement.Add(m_GraphContainer);

            m_CompilationPendingLabel = new Label("Compilation Pending")
            {
                name = "compilationPendingLabel"
            };

            m_GraphContainer.Add(m_GraphView);

            m_ShortcutHandler = new ShortcutHandler(
                new Dictionary <Event, ShortcutDelegate>
            {
                { Event.KeyboardEvent("F2"), () => Application.platform != RuntimePlatform.OSXEditor ? RenameElement() : EventPropagation.Continue },
                { Event.KeyboardEvent("F5"), () =>
                  {
                      RefreshUI(UpdateFlags.All);
                      return(EventPropagation.Continue);
                  } },
                { Event.KeyboardEvent("return"), () => Application.platform == RuntimePlatform.OSXEditor ? RenameElement() : EventPropagation.Continue },
                { Event.KeyboardEvent("[enter]"), () => Application.platform == RuntimePlatform.OSXEditor ? RenameElement() : EventPropagation.Continue },
                { Event.KeyboardEvent("backspace"), OnBackspaceKeyDown },
                { Event.KeyboardEvent("space"), OnSpaceKeyDown },
                { Event.KeyboardEvent("C"), () =>
                  {
                      IGraphElementModel[] selectedModels = m_GraphView.selection
                                                            .OfType <IHasGraphElementModel>()
                                                            .Select(x => x.GraphElementModel)
                                                            .ToArray();

                      // Convert variable -> constant if selection contains at least one item that satisfies conditions
                      IVariableModel[] variableModels = selectedModels.OfType <VariableNodeModel>().Cast <IVariableModel>().ToArray();
                      if (variableModels.Any())
                      {
                          m_Store.Dispatch(new ConvertVariableNodesToConstantNodesAction(variableModels));
                          return(EventPropagation.Stop);
                      }

                      IConstantNodeModel[] constantModels = selectedModels.OfType <IConstantNodeModel>().ToArray();
                      if (constantModels.Any())
                      {
                          m_Store.Dispatch(new ConvertConstantNodesToVariableNodesAction(constantModels));
                      }
                      return(EventPropagation.Stop);
                  } },
                { Event.KeyboardEvent("Q"), () => m_GraphView.AlignSelection(false) },
                { Event.KeyboardEvent("#Q"), () => m_GraphView.AlignSelection(true) },
                // DEBUG
                { Event.KeyboardEvent("1"), () => OnCreateLogNode(LogNodeModel.LogTypes.Message) },
                { Event.KeyboardEvent("2"), () => OnCreateLogNode(LogNodeModel.LogTypes.Warning) },
                { Event.KeyboardEvent("3"), () => OnCreateLogNode(LogNodeModel.LogTypes.Error) },
                { Event.KeyboardEvent("`"), () => OnCreateStickyNote(new Rect(m_GraphView.ChangeCoordinatesTo(m_GraphView.contentViewContainer, m_GraphView.WorldToLocal(Event.current.mousePosition)), StickyNote.defaultSize)) },
            });

            rootVisualElement.parent.AddManipulator(m_ShortcutHandler);
            Selection.selectionChanged += OnGlobalSelectionChange;

            m_Store.StateChanged   += StoreOnStateChanged;
            Undo.undoRedoPerformed += UndoRedoPerformed;

            rootVisualElement.RegisterCallback <AttachToPanelEvent>(OnEnterPanel);
            rootVisualElement.RegisterCallback <DetachFromPanelEvent>(OnLeavePanel);

            titleContent = new GUIContent("Visual Script");

            // After a domain reload, all loaded objects will get reloaded and their OnEnable() called again
            // It looks like all loaded objects are put in a deserialization/OnEnable() queue
            // the previous graph's nodes/edges/... might be queued AFTER this window's OnEnable
            // so relying on objects to be loaded/initialized is not safe
            // hence, we need to defer the loading action
            rootVisualElement.schedule.Execute(() =>
            {
                if (!String.IsNullOrEmpty(LastGraphFilePath))
                {
                    try
                    {
                        m_Store.Dispatch(new LoadGraphAssetAction(LastGraphFilePath, loadType: LoadGraphAssetAction.Type.KeepHistory));
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(e);
                    }
                }
                else             // will display the blank page. not needed otherwise as the LoadGraphAsset reducer will refresh
                {
                    m_Store.Dispatch(new RefreshUIAction(UpdateFlags.All));
                }
            }).ExecuteLater(0);


            m_LockTracker.lockStateChanged.AddListener(OnLockStateChanged);

            m_PluginRepository = new PluginRepository(m_Store, m_GraphView);

            EditorApplication.playModeStateChanged += OnEditorPlayModeStateChanged;
            EditorApplication.pauseStateChanged    += OnEditorPauseStateChanged;

            if (DataModel is VSEditorDataModel vsDataModel)
            {
                vsDataModel.PluginRepository     = m_PluginRepository;
                vsDataModel.OnCompilationRequest = OnCompilationRequest;
            }
        }
 static State PasteSerializedData(State previousState, PasteSerializedDataAction action)
 {
     VseGraphView.OnUnserializeAndPaste(action.Graph, action.Info, action.EditorDataModel, action.Data);
     return(previousState);
 }
Exemple #24
0
        protected virtual void OnEnable()
        {
            if (m_PreviousGraphModels == null)
            {
                m_PreviousGraphModels = new List <OpenedGraph>();
            }

            if (m_BlackboardExpandedRowStates == null)
            {
                m_BlackboardExpandedRowStates = new List <string>();
            }

            if (m_ElementModelsToSelectUponCreation == null)
            {
                m_ElementModelsToSelectUponCreation = new List <string>();
            }

            if (m_ElementModelsToExpandUponCreation == null)
            {
                m_ElementModelsToExpandUponCreation = new List <string>();
            }

            rootVisualElement.RegisterCallback <ValidateCommandEvent>(OnValidateCommand);
            rootVisualElement.RegisterCallback <ExecuteCommandEvent>(OnExecuteCommand);
            rootVisualElement.RegisterCallback <MouseMoveEvent>(_ => _compilationTimer.Restart(m_Store.GetState().EditorDataModel));

            rootVisualElement.styleSheets.Add(AssetDatabase.LoadAssetAtPath <StyleSheet>(k_StyleSheetPath + "VSEditor.uss"));

            rootVisualElement.Clear();
            rootVisualElement.style.overflow      = Overflow.Hidden;
            rootVisualElement.pickingMode         = PickingMode.Ignore;
            rootVisualElement.style.flexDirection = FlexDirection.Column;
            rootVisualElement.name = "vseRoot";

            // Create the store.
            DataModel = CreateDataModel();
            State initialState = CreateInitialState();

            m_Store = new Store(initialState, Store.Options.TrackUndoRedo);

            VseUtility.SetupLogStickyCallback();

            m_GraphContainer = new VisualElement {
                name = "graphContainer"
            };
            m_GraphView    = CreateGraphView();
            m_Menu         = CreateMenu();
            m_ErrorToolbar = CreateErrorToolbar();
            m_BlankPage    = CreateBlankPage();

            SetupWindow();

            m_CompilationPendingLabel = new Label("Compilation Pending")
            {
                name = "compilationPendingLabel"
            };

            m_SidePanel = new VisualElement()
            {
                name = "sidePanel"
            };
            m_SidePanelTitle = new Label();
            m_SidePanel.Add(m_SidePanelTitle);
            m_SidePanelPropertyElement = new Unity.Properties.UI.PropertyElement {
                name = "sidePanelInspector"
            };
            m_SidePanelPropertyElement.OnChanged += (element, path) =>
            {
                if (m_ElementShownInSidePanel is IHasGraphElementModel hasGraphElementModel && hasGraphElementModel.GraphElementModel is IPropertyVisitorNodeTarget nodeTarget2)
                {
                    nodeTarget2.Target = element.GetTarget <object>();
                }
                (m_ElementShownInSidePanel as Node)?.NodeModel.DefineNode();
                (m_ElementShownInSidePanel as Node)?.UpdateFromModel();
            };
            m_SidePanel.Add(m_SidePanelPropertyElement);
            ShowNodeInSidePanel(null, false);

            m_GraphContainer.Add(m_GraphView);
            m_GraphContainer.Add(m_SidePanel);

            Dictionary <Event, ShortcutDelegate> dictionaryShortcuts = GetShortcutDictionary();

            m_ShortcutHandler = new ShortcutHandler(GetShortcutDictionary());

            rootVisualElement.parent.AddManipulator(m_ShortcutHandler);

            m_Store.StateChanged   += StoreOnStateChanged;
            Undo.undoRedoPerformed += UndoRedoPerformed;

            rootVisualElement.RegisterCallback <AttachToPanelEvent>(OnEnterPanel);
            rootVisualElement.RegisterCallback <DetachFromPanelEvent>(OnLeavePanel);
            // that will be true when the window is restored during the editor startup, so OnEnterPanel won't be called later
            if (rootVisualElement.panel != null)
            {
                OnEnterPanel(null);
            }

            titleContent = new GUIContent("Visual Script");

            // After a domain reload, all loaded objects will get reloaded and their OnEnable() called again
            // It looks like all loaded objects are put in a deserialization/OnEnable() queue
            // the previous graph's nodes/edges/... might be queued AFTER this window's OnEnable
            // so relying on objects to be loaded/initialized is not safe
            // hence, we need to defer the loading action
            rootVisualElement.schedule.Execute(() =>
            {
                if (!String.IsNullOrEmpty(LastGraphFilePath))
                {
                    try
                    {
                        m_Store.Dispatch(new LoadGraphAssetAction(LastGraphFilePath, boundObject: m_BoundObject, loadType: LoadGraphAssetAction.Type.KeepHistory));
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(e);
                    }
                }
                else             // will display the blank page. not needed otherwise as the LoadGraphAsset reducer will refresh
                {
                    m_Store.Dispatch(new RefreshUIAction(UpdateFlags.All));
                }
            }).ExecuteLater(0);


            m_LockTracker.lockStateChanged.AddListener(OnLockStateChanged);

            m_PluginRepository = new PluginRepository(m_Store, this);

            EditorApplication.playModeStateChanged += OnEditorPlayModeStateChanged;
            EditorApplication.pauseStateChanged    += OnEditorPauseStateChanged;

            if (DataModel is VSEditorDataModel vsDataModel)
            {
                vsDataModel.PluginRepository     = m_PluginRepository;
                vsDataModel.OnCompilationRequest = OnCompilationRequest;
            }
        }
        public void AlignNodes(VseGraphView vseGraphView, bool follow, List <ISelectable> selection)
        {
            HashSet <INodeModel> topMostModels = new HashSet <INodeModel>();

            topMostModels.Clear();

            var selectedNodeModels          = selection.OfType <Node>().Select(e => e.model);
            var nodeModelsFromSelectedEdges = selection.OfType <Edge>().SelectMany(e => e.model.GetPortModels().Select(p => p.NodeModel));
            var affectedNodeModels          = selectedNodeModels.Concat(nodeModelsFromSelectedEdges);

            foreach (INodeModel stackedNode in affectedNodeModels.Where(n => n.IsStacked))
            {
                InitModelPositionFromUI(stackedNode);
            }

            bool anyEdge = false;

            foreach (Edge edge in selection.OfType <Edge>())
            {
                anyEdge = true;

                LinkedNodesDependency dependency = CreateDependencyFromEdge(edge.model, out INodeModel parent);
                GraphElement          element    = vseGraphView.UIController.ModelsToNodeMapping[dependency.DependentNode];
                AlignDependency(element, dependency, Vector2.zero, parent);
                topMostModels.Add(dependency.DependentNode);
            }

            if (anyEdge && !follow)
            {
                return;
            }

            if (!topMostModels.Any())
            {
                foreach (GraphElement element in selection.OfType <GraphElement>())
                {
                    if (element is IHasGraphElementModel hasModel &&
                        hasModel.GraphElementModel is INodeModel nodeModel)
                    {
                        topMostModels.Add(nodeModel);
                    }
                }
            }

            if (!anyEdge && !follow)
            {
                // Align each top-most node then move dependencies by the same delta
                foreach (INodeModel model in topMostModels)
                {
                    if (!m_DependenciesByNode.TryGetValue(model.Guid, out Dictionary <GUID, IDependency> dependencies))
                    {
                        continue;
                    }
                    foreach (KeyValuePair <GUID, IDependency> dependency in dependencies)
                    {
                        INodeModel   dependentNode = dependency.Value.DependentNode;
                        GraphElement element       = vseGraphView.UIController.ModelsToNodeMapping[dependentNode];
                        Vector2      startPos      = dependentNode.Position;
                        AlignDependency(element, dependency.Value, Vector2.zero, model);
                        Vector2 endPos = dependentNode.Position;
                        Vector2 delta  = endPos - startPos;

                        OffsetNodeDependencies(dependentNode, delta);
                    }
                }
            }
            else
            {
                // Align recursively
                m_ModelsToMove.AddRange(topMostModels);
                ProcessMovedNodes(Vector2.zero, AlignDependency);
            }

            m_ModelsToMove.Clear();
            m_TempMovedModels.Clear();
        }
 public PositionDependenciesManager(VseGraphView vseGraphView, VSPreferences vsPreferences)
 {
     m_VseGraphView = vseGraphView;
     m_Preferences  = vsPreferences;
 }