forked from alelievr/NodeGraphProcessor
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBaseStackNodeView.cs
More file actions
116 lines (99 loc) · 3.97 KB
/
Copy pathBaseStackNodeView.cs
File metadata and controls
116 lines (99 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
using System.Collections.Generic;
using System.Linq;
namespace GraphProcessor
{
/// <summary>
/// Stack node view implementation, can be used to stack multiple node inside a context like VFX graph does.
/// </summary>
public class BaseStackNodeView : StackNode
{
public delegate void ReorderNodeAction(BaseNodeView nodeView, int oldIndex, int newIndex);
/// <summary>
/// StackNode data from the graph
/// </summary>
protected internal BaseStackNode stackNode;
protected BaseGraphView owner;
readonly string styleSheet = "GraphProcessorStyles/BaseStackNodeView";
/// <summary>Triggered when a node is re-ordered in the stack.</summary>
public event ReorderNodeAction onNodeReordered;
public BaseStackNodeView(BaseStackNode stackNode)
{
this.stackNode = stackNode;
styleSheets.Add(Resources.Load<StyleSheet>(styleSheet));
}
/// <inheritdoc />
protected override void OnSeparatorContextualMenuEvent(ContextualMenuPopulateEvent evt, int separatorIndex)
{
// TODO: write the context menu for stack node
}
/// <summary>
/// Called after the StackNode have been added to the graph view
/// </summary>
public virtual void Initialize(BaseGraphView graphView)
{
owner = graphView;
headerContainer.Add(new Label(stackNode.title));
SetPosition(new Rect(stackNode.position, Vector2.one));
InitializeInnerNodes();
}
void InitializeInnerNodes()
{
int i = 0;
// Sanitize the GUID list in case some nodes were removed
stackNode.nodeGUIDs.RemoveAll(nodeGUID =>
{
if (owner.graph.nodesPerGUID.ContainsKey(nodeGUID))
{
var node = owner.graph.nodesPerGUID[nodeGUID];
var view = owner.nodeViewsPerNode[node];
view.AddToClassList("stack-child__" + i);
i++;
AddElement(view);
return false;
}
else
{
return true; // remove the entry as the GUID doesn't exist anymore
}
});
}
/// <inheritdoc />
public override void SetPosition(Rect newPos)
{
base.SetPosition(newPos);
stackNode.position = newPos.position;
}
/// <inheritdoc />
protected override bool AcceptsElement(GraphElement element, ref int proposedIndex, int maxIndex)
{
bool accept = base.AcceptsElement(element, ref proposedIndex, maxIndex);
if (accept && element is BaseNodeView nodeView)
{
var index = Mathf.Clamp(proposedIndex, 0, stackNode.nodeGUIDs.Count - 1);
int oldIndex = stackNode.nodeGUIDs.FindIndex(g => g == nodeView.nodeTarget.GUID);
if (oldIndex != -1)
{
stackNode.nodeGUIDs.Remove(nodeView.nodeTarget.GUID);
if (oldIndex != index)
onNodeReordered?.Invoke(nodeView, oldIndex, index);
}
stackNode.nodeGUIDs.Insert(index, nodeView.nodeTarget.GUID);
}
return accept;
}
public override bool DragLeave(DragLeaveEvent evt, IEnumerable<ISelectable> selection, IDropTarget leftTarget, ISelection dragSource)
{
foreach (var elem in selection)
{
if (elem is BaseNodeView nodeView)
stackNode.nodeGUIDs.Remove(nodeView.nodeTarget.GUID);
}
return base.DragLeave(evt, selection, leftTarget, dragSource);
}
}
}