Beispiel #1
0
        public static Port CreateInputPort(Store store, IPortModel inputPortModel, VisualElement instanceContainer, VisualElement dataContainer, VisualElement existingIcon = null, Orientation orientation = Orientation.Horizontal)
        {
            Assert.IsTrue(inputPortModel.Direction == Direction.Input, "Expected input port model");

            var port = Create(inputPortModel, store, orientation, existingIcon);

            if (inputPortModel.PortType == PortType.Instance)
            {
                port.AddToClassList("instance");
                instanceContainer.Insert(0, port);
            }
            else
            {
                VisualElement innerContainer = new VisualElement {
                    name = "innerContainer"
                };
                innerContainer.style.flexDirection = FlexDirection.Row;
                innerContainer.Add(port);
                dataContainer.Add(innerContainer);

                IConstantNodeModel modelToShow = port.GetModelToWatch();

                if (modelToShow != null)
                {
                    VisualElement editor = port.CreateEditorForNodeModel(modelToShow, _ => store.Dispatch(new RefreshUIAction(UpdateFlags.RequestCompilation)));
                    if (editor != null)
                    {
                        innerContainer.Add(editor);
                        port.m_InputEditor = editor;
                    }
                }
            }

            return(port);
        }
Beispiel #2
0
 public void AddItemRequested <TAction>(Store store, TAction _) where TAction : IAction
 {
     store.Dispatch(new CreateGraphVariableDeclarationAction(k_FieldName, true, typeof(float).GenerateTypeHandle(m_Stencil)));
 }
Beispiel #3
0
        public void BuildContextualMenu()
        {
            var selectedModelsDictionary = m_Selection
                                           .OfType <IHasGraphElementModel>()
                                           .Where(x => !(x is BlackboardThisField)) // this blackboard field
                                           .Distinct(s_HasGraphElementModelComparer)
                                           .ToDictionary(x => x.GraphElementModel);

            IReadOnlyCollection <IGraphElementModel> selectedModelsKeys = selectedModelsDictionary.Keys.ToList();

            BuildBlackboardContextualMenu();

            var originatesFromBlackboard = (m_Evt.target as VisualElement)?.GetFirstOfType <Blackboard>() != null;

            if (!originatesFromBlackboard || m_Evt.target is IHasGraphElementModel)
            {
                BuildGraphViewContextualMenu();
                if (!originatesFromBlackboard)
                {
                    BuildNodeContextualMenu(selectedModelsDictionary);
                    BuildStackContextualMenu(selectedModelsKeys);
                    BuildEdgeContextualMenu(selectedModelsKeys);
                }

                BuildVariableNodeContextualMenu(selectedModelsKeys);
                if (!originatesFromBlackboard)
                {
                    BuildConstantNodeContextualMenu(selectedModelsKeys);
                    BuildStaticConstantNodeContextualMenu(selectedModelsKeys);
                    BuildPropertyNodeContextualMenu(selectedModelsKeys);
                    BuildSpecialContextualMenu(selectedModelsKeys);
                    BuildStickyNoteContextualMenu();
                    BuildRefactorContextualMenu(selectedModelsKeys);
                }

                if (selectedModelsDictionary.Any())
                {
                    m_Evt.menu.AppendAction("Delete", menuAction =>
                    {
                        m_Store.Dispatch(new DeleteElementsAction(selectedModelsKeys.ToArray()));
                    }, eventBase => DropdownMenuAction.Status.Normal);
                }
            }

            if (originatesFromBlackboard && !(m_Evt.target is IHasGraphElementModel))
            {
                var currentGraphModel = m_Store.GetState().CurrentGraphModel;
                currentGraphModel?.Stencil.GetBlackboardProvider()
                .BuildContextualMenu(m_Evt.menu,
                                     (VisualElement)m_Evt.target,
                                     m_Store,
                                     m_Evt.mousePosition);
            }

            var renamable = originatesFromBlackboard && m_Evt.target is IRenamable ? m_Evt.target as IRenamable :
                            (!originatesFromBlackboard && selectedModelsDictionary.Count == 1) ? selectedModelsDictionary.Single().Value as IRenamable : null;

            if (renamable != null)
            {
                m_Evt.menu.AppendAction("Rename", menuAction =>
                {
                    renamable.Rename(true);
                    m_Evt.PreventDefault();
                    m_Evt.StopImmediatePropagation();
                }, eventBase => DropdownMenuAction.Status.Normal);
            }

            if (m_Evt.target is IContextualMenuBuilder contextualMenuBuilder)
            {
                contextualMenuBuilder.BuildContextualMenu(m_Evt);
            }
        }
Beispiel #4
0
 void OnTypeChanged(TypeHandle handle)
 {
     m_Store.Dispatch(new UpdateTypeAction((VariableDeclarationModel)VariableDeclarationModel, handle));
     RefreshUI();
 }
Beispiel #5
0
        protected 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 <ScriptableObject>();
            }

            if (m_ElementModelsToActivateUponCreation == null)
            {
                m_ElementModelsToActivateUponCreation = new List <ScriptableObject>();
            }

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

            rootVisualElement.RegisterCallback <ValidateCommandEvent>(OnValidateCommand);
            rootVisualElement.RegisterCallback <ExecuteCommandEvent>(OnExecuteCommand);

            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             = new VseGraphView(this, m_Store);
            m_Menu                  = CreateMenu();
            m_Menu.OnToggleTracing += OnToggleTracing;
            m_BlankPage             = new VseBlankPage(m_Store);

            rootVisualElement.Add(m_Menu);
            rootVisualElement.Add(m_GraphContainer);
            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;
            }
        }
Beispiel #6
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>(_ => 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();

            SetupWindow();

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

            m_SidePanel = new VisualElement()
            {
                name = "sidePanel"
            };
            m_ImguiContainer = new IMGUIContainer(DrawSidePanel)
            {
                name = "sidePanelInspector"
            };
            m_SidePanel.Add(m_ImguiContainer);

            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, m_GraphView);

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

            if (DataModel is VSEditorDataModel vsDataModel)
            {
                vsDataModel.PluginRepository     = m_PluginRepository;
                vsDataModel.OnCompilationRequest = OnCompilationRequest;
            }
        }