using Codice.CM.Common; using TNode.BaseViews; using TNode.Cache; using TNode.Editor.BaseViews; using TNode.Editor.Inspector; using TNode.Editor.Model; using TNode.Models; using UnityEditor; using UnityEditor.Experimental.GraphView; using UnityEngine; using UnityEngine.Serialization; using UnityEngine.UIElements; namespace TNode.Editor{ public abstract class GraphEditor : EditorWindow where T:GraphData{ protected DataGraphView _graphView; [SerializeField] private VisualTreeAsset mVisualTreeAsset = default; //Persist editor data ,such as node position,node size ,etc ,in this script object [FormerlySerializedAs("nodeEditorData")] public GraphEditorData graphEditorData; public void CreateGUI(){ // Each editor window contains a root VisualElement object VisualElement root = rootVisualElement; // Instantiate UXML VisualElement labelFromUXML = mVisualTreeAsset.Instantiate(); root.Add(labelFromUXML); BuildGraphView(); DefineGraphEditorActions(); OnCreate(); } private void BuildGraphView(){ _graphView = NodeEditorExtensions.CreateInstance>(); rootVisualElement.Add(_graphView); _graphView.StretchToParentSize(); _graphView.ConstructViewContextualMenu(evt => { //Current issue is that the search window don't show up at the exact position of the mouse click by dma.eventInfo.mousePosition //So I have to manually set the position of the search window to fit the mouse click position by add an offset driven by Editor's position //Maybe a better way exists to fix this issue Vector2 editorPosition = this.position.position; evt.menu.AppendAction("Create Node", dma => { var dmaPos = dma.eventInfo.mousePosition+editorPosition; SearchWindowContext searchWindowContext = new SearchWindowContext(dmaPos,200,200); var searchWindow = CreateInstance(); searchWindow.Setup(typeof(T),_graphView,this); SearchWindow.Open(searchWindowContext, searchWindow); }); }); } private void DefineGraphEditorActions(){ //Register a event when user press ctrl + s rootVisualElement.RegisterCallback((evt) => { if (evt.keyCode == KeyCode.S && evt.ctrlKey) { Save(); } }); } private void Save(){ //if no graph is loaded ,create a file save dialogue if (_graphView.Data == null) { string path = EditorUtility.SaveFilePanel("Save Graph", "", "", "asset"); if (path.Length != 0){ //Create a new asset file with type of GraphDataType T asset = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(asset, path); AssetDatabase.SaveAssets(); } } else{ _graphView.SaveWithEditorData(graphEditorData); AssetDatabase.Refresh(); } } protected virtual void OnCreate(){ } } }