Field&Property
private GraphWindow m_GraphWindow;
private SearchWindowProvider m_SearchWindow;
public Dictionary<Node, NodeView> nodeViewsPerNode = new Dictionary<Node, NodeView>();
public Graph graph { get { return m_GraphWindow.graph; } }
public GraphView()
{
viewTransformChanged += ViewTransformChangedCallback;
graphViewChanged += GraphViewChangedCallback;
AddManipulators();
InitializeView();
Undo.undoRedoPerformed += Reload;
}
~GraphView()
{
Undo.undoRedoPerformed -= Reload;
}
Method
AddManipulators
private void AddManipulators()
{
this.AddManipulator(new ContentDragger());
this.AddManipulator(new SelectionDragger());
this.AddManipulator(new RectangleSelector());
this.AddManipulator(new ClickSelector());
}
InitializeView
private void InitializeView()
{
this.styleSheets.Add(Resources.Load<StyleSheet>("GraphView"));
GridBackground gridBackground = new GridBackground();
gridBackground.name = "GridBackground";
Insert(0, gridBackground);
this.SetupZoom(0.5f, 2.0f);
this.StretchToParentSize();
m_SearchWindow = new SearchWindowProvider();
m_SearchWindow.OnSelect = OnSelect;
nodeCreationRequest = (NodeCreationContext context) =>
{ SearchWindow.Open(new SearchWindowContext(context.screenMousePosition), m_SearchWindow); };
}
Initialize
public void Initialize(GraphWindow graphWindow)
{
m_GraphWindow = graphWindow;
UpdateViewTransform(graph.position, graph.scale);
Reload();
}
Reload
public void Reload()
{
Debug.Log("Reload");
RemoveNodeView();
RemovePortView();
InitializeNodeView();
InitializePortView();
}
RemoveNodeView
public void RemoveNodeView()
{
foreach (var node in nodeViewsPerNode)
{
NodeView nodeView = node.Value;
nodeView.OnRemove();
RemoveElement(nodeView);
}
nodeViewsPerNode.Clear();
}
RemovePortView
public void RemovePortView()
{
var edges = this.edges;
edges.ForEach((edge) =>
{
RemoveElement(edge);
});
}
InitializeNodeView
public void InitializeNodeView()
{
var nodes = graph.GetComponentsInChildren<Node>();
foreach (var node in nodes)
{
var nodeView = AddNodeView(node, node.position);
nodeView.Initialize(node, this);
nodeViewsPerNode.Add(node, nodeView);
}
}
InitializePortView
public void InitializePortView()
{
foreach (var node in nodeViewsPerNode)
{
node.Value.InitializePortView();
}
}
OnSelect
private bool OnSelect(SearchTreeEntry SearchTreeEntry, SearchWindowContext context)
{
var node = AddNode(SearchTreeEntry.userData as Type);
var windowRoot = m_GraphWindow.rootVisualElement;
var windowMousePosition = windowRoot.ChangeCoordinatesTo(windowRoot.parent, context.screenMousePosition - m_GraphWindow.position.position);
var graphMousePosition = this.contentViewContainer.WorldToLocal(windowMousePosition);
var nodeView = AddNodeView(node, graphMousePosition);
nodeViewsPerNode.Add(node, nodeView);
return true;
}
AddNode
Node AddNode(Type type)
{
var obj = new GameObject(type.Name);
Undo.RegisterCreatedObjectUndo(obj, $"Create:{obj.name}");
var component = obj.AddComponent(type);
obj.transform.parent = graph.transform;
return component as Node;
}
AddNodeView
NodeView AddNodeView(Node node, Vector2 pos)
{
Type nodeViewType = m_SearchWindow.GetNodeView(node.GetType());
var nodeView = System.Activator.CreateInstance(nodeViewType) as NodeView;
nodeView.Initialize(node, this);
nodeView.SetPosition(new Rect(pos, new Vector2(100, 100)));
nodeView.RefreshPorts();
nodeView.RefreshExpandedState();
AddElement(nodeView);
return nodeView;
}
GetCompatiblePorts
public override List<Port> GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter)
{
return base.GetCompatiblePorts(startPort, nodeAdapter);
}
ViewTransformChangedCallback
private void ViewTransformChangedCallback(GraphViewBase graphView)
{
Undo.RecordObject(graph, $"{graph.name} Transform Change");
graph.position = graphView.viewTransform.position;
graph.scale = graphView.viewTransform.scale;
EditorUtility.SetDirty(graph);
}
GraphViewChangedCallback
private GraphViewChange GraphViewChangedCallback(GraphViewChange graphViewChange)
{
return graphViewChange;
}
BuildContextualMenu
public override void BuildContextualMenu(ContextualMenuPopulateEvent evt)
{
base.BuildContextualMenu(evt);
evt.menu.AppendAction("Test", TestBuildContextualMenu);
}
private void TestBuildContextualMenu(DropdownMenuAction obj)
{
Debug.Log("右键菜单Test");
}