using UnityEditor;
using UnityEngine.UIElements;
using UnityEditor.Experimental.GraphView;
using TagFighter.Dialogue;
using System.Linq;
using System.Collections.Generic;
using System;
public class DialogueView : GraphView
{
Dialogue _dialogue;
public Action<DialogueNodeView> OnNodeSelected;
public new class UxmlFactory : UxmlFactory<DialogueView, GraphView.UxmlTraits> { }
public DialogueView() {
Insert(0, new GridBackground());
this.AddManipulator(new ContentZoomer());
this.AddManipulator(new ContentDragger());
this.AddManipulator(new SelectionDragger());
this.AddManipulator(new RectangleSelector());
var styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/Editor/Dialogue/DialogueEditor.uss");
styleSheets.Add(styleSheet);
}
internal void PopulateView(Dialogue dialogueCandidate) {
graphViewChanged -= OnGraphViewChanged;
DeleteElements(graphElements);
_dialogue = dialogueCandidate;
if (_dialogue == null) {
return;
}
graphViewChanged += OnGraphViewChanged;
CreateNodeViews();
CreateEdges();
}
void CreateNodeViews() {
foreach (var node in _dialogue.Nodes) {
CreateNodeView(node);
}
}
void CreateEdges() {
foreach (var parentNode in _dialogue.Nodes) {
var parentView = GetNodeByGuid(parentNode.name) as DialogueNodeView;
foreach (var child in parentNode.GetChildren()) {
var childView = GetNodeByGuid(child) as DialogueNodeView;
var edge = parentView.Output.ConnectTo(childView.Input);
AddElement(edge);
}
}
}
GraphViewChange OnGraphViewChanged(GraphViewChange graphViewChange) {
if (graphViewChange.elementsToRemove != null) {
foreach (var elementToRemove in graphViewChange.elementsToRemove) {
switch (elementToRemove) {
case DialogueNodeView dialogueNodeView:
_dialogue.DeleteNode(dialogueNodeView.Node);
break;
case Edge edge:
var parent = edge.output.node as DialogueNodeView;
var child = edge.input.node as DialogueNodeView;
parent.Node.RemoveChild(child.viewDataKey);
break;
}
}
}
if (graphViewChange.edgesToCreate != null) {
foreach (var edge in graphViewChange.edgesToCreate) {
var parent = edge.output.node as DialogueNodeView;
var child = edge.input.node as DialogueNodeView;
parent.Node.AddChild(child.viewDataKey);
}
}
return graphViewChange;
}
public override void BuildContextualMenu(ContextualMenuPopulateEvent e) {
// base.BuildContextualMenu(e);
{
e.menu.AppendAction($"Create DialogueNode", action => CreateNode(action.eventInfo.mousePosition));
}
}
public override List<Port> GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter) {
return ports.Where(endPort => endPort.direction != startPort.direction && endPort.node != startPort.node).ToList();
}
void CreateNode(UnityEngine.Vector2 position) {
if (_dialogue == null) {
return;
}
var node = _dialogue.CreateNode(null);
node.Position = viewTransform.matrix.inverse.MultiplyPoint(this.WorldToLocal(position));
CreateNodeView(node);
}
void CreateNodeView(DialogueNode node) {
DialogueNodeView nodeView = new(node) {
OnNodeSelected = OnNodeSelected,
};
AddElement(nodeView);
}
}