public void OnGUI()
{
DrawGUIToolBar();
using (new EditorGUILayout.HorizontalScope()) {
DrawGUINodeGraph();
if(showErrors) {
DrawGUINodeErrors();
}
}
/*
Event Handling:
- Supporting dragging script into window to create node.
- Context Menu
- NodeGUI connection.
- Command(Delete, Copy, etc...)
*/
switch (Event.current.type) {
// detect dragging script then change interface to "(+)" icon.
case EventType.DragUpdated: {
var refs = DragAndDrop.objectReferences;
foreach (var refe in refs) {
if (refe.GetType() == typeof(UnityEditor.MonoScript)) {
Type scriptTypeInfo = ((MonoScript)refe).GetClass();
Type inheritedTypeInfo = GetDragAndDropAcceptableScriptType(scriptTypeInfo);
if (inheritedTypeInfo != null) {
// at least one asset is script. change interface.
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
break;
}
}
}
break;
}
// script drop on editor.
case EventType.DragPerform: {
var pathAndRefs = new Dictionary<string, object>();
for (var i = 0; i < DragAndDrop.paths.Length; i++) {
var path = DragAndDrop.paths[i];
var refe = DragAndDrop.objectReferences[i];
pathAndRefs[path] = refe;
}
var shouldSave = false;
foreach (var item in pathAndRefs) {
var refe = (MonoScript)item.Value;
if (refe.GetType() == typeof(UnityEditor.MonoScript)) {
Type scriptTypeInfo = refe.GetClass();
Type inheritedTypeInfo = GetDragAndDropAcceptableScriptType(scriptTypeInfo);
if (inheritedTypeInfo != null) {
var dropPos = Event.current.mousePosition;
var scriptName = refe.name;
var scriptClassName = scriptName;
AddNodeFromCode(scriptName, scriptClassName, inheritedTypeInfo, dropPos.x, dropPos.y);
shouldSave = true;
}
}
}
if (shouldSave) {
SaveGraphWithReload();
}
break;
}
// show context menu
case EventType.ContextClick: {
var rightClickPos = Event.current.mousePosition;
var menu = new GenericMenu();
foreach (var menuItemStr in AssetBundleGraphSettings.GUI_Menu_Item_TargetGUINodeDict.Keys) {
var kind = AssetBundleGraphSettings.GUI_Menu_Item_TargetGUINodeDict[menuItemStr];
menu.AddItem(
new GUIContent(menuItemStr),
false,
() => {
AddNodeFromGUI(kind, rightClickPos.x, rightClickPos.y);
SaveGraphWithReload();
Repaint();
}
);
}
menu.ShowAsContext();
break;
}
/*
Handling mouseUp at empty space.
*/
case EventType.MouseUp: {
modifyMode = ModifyMode.NONE;
HandleUtility.Repaint();
if (activeObject.idPosDict.ReadonlyDict().Any()) {
Undo.RecordObject(this, "Unselect");
foreach (var activeObjectId in activeObject.idPosDict.ReadonlyDict().Keys) {
// unselect all.
foreach (var node in nodes) {
if (activeObjectId == node.Id) {
node.SetInactive();
}
}
foreach (var connection in connections) {
if (activeObjectId == connection.Id) {
connection.SetInactive();
}
}
}
activeObject = RenewActiveObject(new List<string>());
}
// clear inspector
if( Selection.activeObject is NodeGUIInspectorHelper || Selection.activeObject is ConnectionGUIInspectorHelper) {
Selection.activeObject = null;
}
break;
}
/*
scale up or down by command & + or command & -.
*/
case EventType.KeyDown: {
if (Event.current.command) {
if (Event.current.shift && Event.current.keyCode == KeyCode.Semicolon) {
NodeGUI.scaleFactor = NodeGUI.scaleFactor + 0.1f;
if (NodeGUI.scaleFactor < NodeGUI.SCALE_MIN) NodeGUI.scaleFactor = NodeGUI.SCALE_MIN;
if (NodeGUI.SCALE_MAX < NodeGUI.scaleFactor) NodeGUI.scaleFactor = NodeGUI.SCALE_MAX;
Event.current.Use();
break;
}
if (Event.current.keyCode == KeyCode.Minus) {
NodeGUI.scaleFactor = NodeGUI.scaleFactor - 0.1f;
if (NodeGUI.scaleFactor < NodeGUI.SCALE_MIN) NodeGUI.scaleFactor = NodeGUI.SCALE_MIN;
if (NodeGUI.SCALE_MAX < NodeGUI.scaleFactor) NodeGUI.scaleFactor = NodeGUI.SCALE_MAX;
Event.current.Use();
break;
}
}
break;
}
case EventType.ValidateCommand:
{
switch (Event.current.commandName) {
// Delete active node or connection.
case "Delete": {
if (activeObject.idPosDict.ReadonlyDict().Any()) {
Event.current.Use();
}
break;
}
case "Copy": {
if (activeObject.idPosDict.ReadonlyDict().Any()) {
Event.current.Use();
}
break;
}
case "Cut": {
if (activeObject.idPosDict.ReadonlyDict().Any()) {
Event.current.Use();
}
break;
}
case "Paste": {
if(copyField.datas == null) {
break;
}
if (copyField.datas.Any()) {
Event.current.Use();
}
break;
}
case "SelectAll": {
Event.current.Use();
break;
}
}
break;
}
case EventType.ExecuteCommand:
{
switch (Event.current.commandName) {
// Delete active node or connection.
case "Delete": {
if (!activeObject.idPosDict.ReadonlyDict().Any()) break;
Undo.RecordObject(this, "Delete Selection");
foreach (var targetId in activeObject.idPosDict.ReadonlyDict().Keys) {
DeleteNode(targetId);
DeleteConnectionById(targetId);
}
SaveGraphWithReload();
activeObject = RenewActiveObject(new List<string>());
UpdateActivationOfObjects(activeObject);
Event.current.Use();
break;
}
case "Copy": {
if (!activeObject.idPosDict.ReadonlyDict().Any()) {
break;
}
Undo.RecordObject(this, "Copy Selection");
var targetNodeIds = activeObject.idPosDict.ReadonlyDict().Keys.ToList();
var targetNodeJsonRepresentations = JsonRepresentations(targetNodeIds);
copyField = new CopyField(targetNodeJsonRepresentations, CopyType.COPYTYPE_COPY);
Event.current.Use();
break;
}
case "Cut": {
if (!activeObject.idPosDict.ReadonlyDict().Any()) {
break;
}
Undo.RecordObject(this, "Cut Selection");
var targetNodeIds = activeObject.idPosDict.ReadonlyDict().Keys.ToList();
var targetNodeJsonRepresentations = JsonRepresentations(targetNodeIds);
copyField = new CopyField(targetNodeJsonRepresentations, CopyType.COPYTYPE_CUT);
foreach (var targetId in activeObject.idPosDict.ReadonlyDict().Keys) {
DeleteNode(targetId);
DeleteConnectionById(targetId);
}
SaveGraphWithReload();
InitializeGraph();
activeObject = RenewActiveObject(new List<string>());
UpdateActivationOfObjects(activeObject);
Event.current.Use();
break;
}
case "Paste": {
if(copyField.datas == null) {
break;
}
var nodeNames = nodes.Select(node => node.Name).ToList();
var duplicatingData = new List<NodeGUI>();
if (copyField.datas.Any()) {
var pasteType = copyField.type;
foreach (var copyFieldData in copyField.datas) {
var nodeJsonDict = AssetBundleGraph.Json.Deserialize(copyFieldData) as Dictionary<string, object>;
var pastingNode = new NodeGUI(new NodeData(nodeJsonDict));
var pastingNodeName = pastingNode.Name;
var nameOverlapping = nodeNames.Where(name => name == pastingNodeName).ToList();
switch (pasteType) {
case CopyType.COPYTYPE_COPY: {
if (2 <= nameOverlapping.Count) {
continue;
}
break;
}
case CopyType.COPYTYPE_CUT: {
if (1 <= nameOverlapping.Count) {
continue;
}
break;
}
}
duplicatingData.Add(pastingNode);
}
}
// consume copyField
copyField.datas = null;
if (!duplicatingData.Any()) {
break;
}
Undo.RecordObject(this, "Paste");
foreach (var newNode in duplicatingData) {
DuplicateNode(newNode);
}
SaveGraphWithReload();
InitializeGraph();
Event.current.Use();
break;
}
case "SelectAll": {
Undo.RecordObject(this, "Select All Objects");
var nodeIds = nodes.Select(node => node.Id).ToList();
activeObject = RenewActiveObject(nodeIds);
// select all.
foreach (var node in nodes) {
node.SetActive();
}
foreach (var connection in connections) {
connection.SetActive();
}
Event.current.Use();
break;
}
default: {
break;
}
}
break;
}
}
}