Add VRChat and GitHub packages to Unity project
This commit is contained in:
1 parent
0334a52b21
commit
85538aaccc
3297 files changed
+847877
No files matched your search
+71
@@ -0,0 +1,71 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Experimental.UIElements.GraphView;
|
||||
using System.Collections.Generic;
|
||||
using VRC.Udon.Graph.Interfaces;
|
||||
using VRC.Udon.Graph;
|
||||
|
||||
namespace VRC.Udon.Editor.ProgramSources.UdonGraphProgram.UI.GraphView
|
||||
{
|
||||
|
||||
public class UdonFocusedSearchWindow : UdonSearchWindowBase
|
||||
{
|
||||
|
||||
public INodeRegistry targetRegistry;
|
||||
internal List<SearchTreeEntry> _fullRegistry;
|
||||
|
||||
#region ISearchWindowProvider
|
||||
|
||||
override public List<SearchTreeEntry> CreateSearchTree(SearchWindowContext context)
|
||||
{
|
||||
|
||||
_fullRegistry = new List<SearchTreeEntry>();
|
||||
|
||||
Texture2D icon = EditorGUIUtility.FindTexture("cs Script Icon");
|
||||
|
||||
var registryName = GetSimpleNameForRegistry(targetRegistry);
|
||||
_fullRegistry.Add(new SearchTreeGroupEntry(new GUIContent($"{registryName} Search"), 0));
|
||||
|
||||
// add Registry Level
|
||||
AddEntriesForRegistry(_fullRegistry, targetRegistry, 1, true);
|
||||
|
||||
return _fullRegistry;
|
||||
}
|
||||
|
||||
override public bool OnSelectEntry(SearchTreeEntry entry, SearchWindowContext context)
|
||||
{
|
||||
// should check for adding duplicate event nodes here, look at Legacy.UdonGraph.TryCreateNodeInstance
|
||||
// Assuming that if we've made it to this point we're allowed to add the node
|
||||
|
||||
UdonNode node;
|
||||
// checking type so we can support selecting registries as well
|
||||
if (entry.userData is UdonNodeDefinition && !_graphView.IsDuplicateEventNode((entry.userData as UdonNodeDefinition).fullName))
|
||||
{
|
||||
node = UdonNode.CreateNode(entry.userData as UdonNodeDefinition, _graphView);
|
||||
_graphView.AddElement(node);
|
||||
node.SetPosition(new Rect(GetGraphPositionFromContext(context), Vector2.zero));
|
||||
node.Select(_graphView, false);
|
||||
|
||||
// Do we need to do this to reserialize, etc?
|
||||
_graphView.ReSerializeData();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: move this to Extension
|
||||
private string GetSimpleNameForRegistry(INodeRegistry registry)
|
||||
{
|
||||
string registryName = registry.ToString().Replace("NodeRegistry", "").FriendlyNameify();
|
||||
registryName = registryName.Substring(registryName.LastIndexOf(".") + 1);
|
||||
registryName = registryName.Replace("UnityEngine", "");
|
||||
return registryName;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6581176c97993bb40976acff208bd0b1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor.Experimental.UIElements.GraphView;
|
||||
using System.Collections.Generic;
|
||||
using VRC.Udon.Graph.Interfaces;
|
||||
using System.Linq;
|
||||
using VRC.Udon.Graph;
|
||||
|
||||
namespace VRC.Udon.Editor.ProgramSources.UdonGraphProgram.UI.GraphView
|
||||
{
|
||||
|
||||
public class UdonFullSearchWindow : UdonSearchWindowBase
|
||||
{
|
||||
|
||||
static private List<SearchTreeEntry> _slowRegistryCache;
|
||||
#region ISearchWindowProvider
|
||||
|
||||
override public List<SearchTreeEntry> CreateSearchTree(SearchWindowContext context)
|
||||
{
|
||||
if (_slowRegistryCache != null && _slowRegistryCache.Count > 0) return _slowRegistryCache;
|
||||
|
||||
_slowRegistryCache = new List<SearchTreeEntry>
|
||||
{
|
||||
new SearchTreeGroupEntry(new GUIContent("Full Search"), 0)
|
||||
};
|
||||
|
||||
var topRegistries = UdonEditorManager.Instance.GetTopRegistries();
|
||||
|
||||
Texture2D icon = null;
|
||||
var groupEntries = new Dictionary<string, SearchTreeGroupEntry>();
|
||||
foreach (var topRegistry in topRegistries)
|
||||
{
|
||||
string topName = topRegistry.Key.Replace("NodeRegistry", "");
|
||||
|
||||
if (topName != "Udon")
|
||||
{
|
||||
_slowRegistryCache.Add(new SearchTreeGroupEntry(new GUIContent(topName), 1));
|
||||
}
|
||||
|
||||
// get all registries, save into registryName > INodeRegistry Lookup
|
||||
var subRegistries = new Dictionary<string, INodeRegistry>();
|
||||
foreach (KeyValuePair<string, INodeRegistry> registry in topRegistry.Value.OrderBy(s => s.Key))
|
||||
{
|
||||
string baseRegistryName = registry.Key.Replace("NodeRegistry", "").FriendlyNameify().ReplaceFirst(topName, "");
|
||||
string registryName = baseRegistryName.UppercaseFirst();
|
||||
subRegistries.Add(registryName, registry.Value);
|
||||
}
|
||||
|
||||
// Go through each registry entry and add the top-level registry and associated array registry
|
||||
foreach (KeyValuePair<string, INodeRegistry> regEntry in subRegistries)
|
||||
{
|
||||
INodeRegistry registry = regEntry.Value;
|
||||
string registryName = regEntry.Key;
|
||||
|
||||
int level = 2;
|
||||
// Special cases for Udon sub-levels, added at top
|
||||
if (topName == "Udon")
|
||||
{
|
||||
level = 1;
|
||||
if (registryName == "Event" || registryName == "Type")
|
||||
{
|
||||
registryName = $"{registryName}s";
|
||||
}
|
||||
}
|
||||
|
||||
if (!registryName.EndsWith("[]"))
|
||||
{
|
||||
// add Registry Level
|
||||
var groupEntry = new SearchTreeGroupEntry(new GUIContent(registryName, icon), level) { userData = registry };
|
||||
_slowRegistryCache.Add(groupEntry);
|
||||
}
|
||||
|
||||
// Check for Array Type first
|
||||
string regArrayType = $"{registryName}[]";
|
||||
if (subRegistries.TryGetValue(regArrayType, out INodeRegistry arrayRegistry))
|
||||
{
|
||||
// we have a matching subRegistry, add that next
|
||||
var arrayLevel = level + 1;
|
||||
var arrayGroupEntry = new SearchTreeGroupEntry(new GUIContent(regArrayType, icon), arrayLevel) { userData = registry };
|
||||
_slowRegistryCache.Add(arrayGroupEntry);
|
||||
|
||||
// Add all array entries
|
||||
AddEntriesForRegistry(_slowRegistryCache, arrayRegistry, arrayLevel + 1);
|
||||
}
|
||||
|
||||
AddEntriesForRegistry(_slowRegistryCache, registry, level + 1, true);
|
||||
|
||||
}
|
||||
}
|
||||
return _slowRegistryCache;
|
||||
}
|
||||
|
||||
override public bool OnSelectEntry(SearchTreeEntry entry, SearchWindowContext context)
|
||||
{
|
||||
// should check for adding duplicate event nodes here, look at Legacy.UdonGraph.TryCreateNodeInstance
|
||||
// Assuming that if we've made it to this point we're allowed to add the node
|
||||
|
||||
UdonNode node;
|
||||
// checking type so we can support selecting registries as well
|
||||
if (entry.userData is UdonNodeDefinition && !_graphView.IsDuplicateEventNode((entry.userData as UdonNodeDefinition).fullName))
|
||||
{
|
||||
node = UdonNode.CreateNode(entry.userData as UdonNodeDefinition, _graphView);
|
||||
_graphView.AddElement(node);
|
||||
|
||||
node.SetPosition(new Rect(GetGraphPositionFromContext(context), Vector2.zero));
|
||||
node.Select(_graphView, false);
|
||||
|
||||
// Do we need to do this to reserialize, etc?
|
||||
_graphView.ReSerializeData();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b721120e6c1d320448a55fe87a7de824
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Experimental.UIElements.GraphView;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using VRC.Udon.Graph;
|
||||
|
||||
namespace VRC.Udon.Editor.ProgramSources.UdonGraphProgram.UI.GraphView
|
||||
{
|
||||
|
||||
public class UdonPortSearchWindow : UdonSearchWindowBase
|
||||
{
|
||||
|
||||
internal List<SearchTreeEntry> _fullRegistry;
|
||||
|
||||
#region ISearchWindowProvider
|
||||
|
||||
public Type typeToSearch;
|
||||
public Port startingPort;
|
||||
public Direction direction;
|
||||
|
||||
public class VariableInfo
|
||||
{
|
||||
public string uid;
|
||||
public bool isGetter;
|
||||
|
||||
public VariableInfo(string uid, bool isGetter)
|
||||
{
|
||||
this.uid = uid;
|
||||
this.isGetter = isGetter;
|
||||
}
|
||||
}
|
||||
|
||||
override public List<SearchTreeEntry> CreateSearchTree(SearchWindowContext context)
|
||||
{
|
||||
_fullRegistry = new List<SearchTreeEntry>
|
||||
{
|
||||
new SearchTreeGroupEntry(new GUIContent($"{direction.ToString()} Search"), 0)
|
||||
};
|
||||
|
||||
var defsToAdd = new Dictionary<string, List<UdonNodeDefinition>>();
|
||||
var registries = UdonEditorManager.Instance.GetNodeRegistries();
|
||||
foreach (var item in registries)
|
||||
{
|
||||
var definitions = item.Value.GetNodeDefinitions().ToList();
|
||||
|
||||
var registryName = item.Key.FriendlyNameify().Replace("NodeRegistry", "");
|
||||
defsToAdd.Add(registryName, new List<UdonNodeDefinition>());
|
||||
|
||||
foreach (var def in definitions)
|
||||
{
|
||||
var collection = direction == Direction.Input ? def.Inputs : def.Outputs;
|
||||
if(collection.Any(p=>p.type == typeToSearch))
|
||||
{
|
||||
defsToAdd[registryName].Add(def);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var variables = _graphView.GetVariableNodes;
|
||||
|
||||
// Add Getters and Setters for matched variable types
|
||||
Texture2D icon = EditorGUIUtility.FindTexture("GameManager Icon");
|
||||
string typeToSearchSimple = typeToSearch.ToString().Replace(".", "");
|
||||
foreach (var item in variables)
|
||||
{
|
||||
string variableSimpleName = item.fullName.Replace("Variable_", "");
|
||||
string getOrSet = direction == Direction.Output ? "Get" : "Set";
|
||||
if(variableSimpleName == typeToSearchSimple)
|
||||
{
|
||||
string customVariableName = item.nodeValues[1].Deserialize().ToString();
|
||||
_fullRegistry.Add(new SearchTreeEntry(new GUIContent($"{getOrSet} {customVariableName}", icon))
|
||||
{
|
||||
level = 1,
|
||||
userData = new VariableInfo(item.uid, direction == Direction.Output),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in defsToAdd)
|
||||
{
|
||||
// Skip empty lists
|
||||
if (item.Value.Count == 0) continue;
|
||||
|
||||
_fullRegistry.Add(new SearchTreeGroupEntry(new GUIContent(item.Key), 1));
|
||||
AddEntries(_fullRegistry, item.Value, 2);
|
||||
}
|
||||
|
||||
return _fullRegistry;
|
||||
}
|
||||
|
||||
override public bool OnSelectEntry(SearchTreeEntry entry, SearchWindowContext context)
|
||||
{
|
||||
UdonNode node;
|
||||
// checking type so we can support selecting registries as well
|
||||
if (entry.userData is UdonNodeDefinition && !_graphView.IsDuplicateEventNode((entry.userData as UdonNodeDefinition).fullName))
|
||||
{
|
||||
node = UdonNode.CreateNode(entry.userData as UdonNodeDefinition, _graphView);
|
||||
_graphView.AddElement(node);
|
||||
var position = GetGraphPositionFromContext(context);
|
||||
position.x -= 140; // this offset is added for the search window, remove it for the node
|
||||
node.SetPosition(new Rect(position, Vector2.zero));
|
||||
node.Select(_graphView, false);
|
||||
var collection = direction == Direction.Input ? node.portsIn : node.portsOut;
|
||||
var port = collection.FirstOrDefault(p => p.Value.portType == typeToSearch).Value;
|
||||
if(port != null)
|
||||
{
|
||||
var e = startingPort.ConnectTo(port);
|
||||
_graphView.AddElement(e);
|
||||
}
|
||||
|
||||
// Do we need to do this to reserialize, etc?
|
||||
_graphView.ReSerializeData();
|
||||
return true;
|
||||
}
|
||||
else if(entry.userData is VariableInfo)
|
||||
{
|
||||
var data = entry.userData as VariableInfo;
|
||||
var position = GetGraphPositionFromContext(context);
|
||||
position.x -= 140; // this offset is added for the search window, remove it for the node
|
||||
|
||||
UdonNode udonNode = _graphView.MakeVariableNode(data.uid, position, data.isGetter);
|
||||
_graphView.AddElement(udonNode);
|
||||
var collection = direction == Direction.Input ? udonNode.portsIn : udonNode.portsOut;
|
||||
var port = collection.First().Value;
|
||||
if (port != null)
|
||||
{
|
||||
var e = startingPort.ConnectTo(port);
|
||||
_graphView.AddElement(e);
|
||||
}
|
||||
_graphView.ReSerializeData();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e94c084f399869b42a21244fd07778c4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Experimental.UIElements.GraphView;
|
||||
using System.Collections.Generic;
|
||||
using VRC.Udon.Graph.Interfaces;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using VRC.Udon.Graph;
|
||||
|
||||
namespace VRC.Udon.Editor.ProgramSources.UdonGraphProgram.UI.GraphView
|
||||
{
|
||||
public class UdonRegistrySearchWindow : UdonSearchWindowBase
|
||||
{
|
||||
private UdonSearchManager _searchManager;
|
||||
private static List<SearchTreeEntry> _registryCache;
|
||||
private List<(string, string)> _shortcutRegistries = new List<(string, string)>()
|
||||
{
|
||||
("UnityEngine","Debug"),
|
||||
("Udon","Special"),
|
||||
("Udon","Type"),
|
||||
("VRC", "UdonCommonInterfacesIUdonEventReceiver")
|
||||
};
|
||||
|
||||
public void Initialize(UdonGraphWindow editorWindow, UdonGraph graphView, UdonSearchManager manager)
|
||||
{
|
||||
base.Initialize(editorWindow, graphView);
|
||||
_searchManager = manager;
|
||||
}
|
||||
|
||||
#region ISearchWindowProvider
|
||||
|
||||
override public List<SearchTreeEntry> CreateSearchTree(SearchWindowContext context)
|
||||
{
|
||||
if (_registryCache != null && _registryCache.Count > 0) return _registryCache;
|
||||
|
||||
_registryCache = new List<SearchTreeEntry>();
|
||||
|
||||
Texture2D icon = EditorGUIUtility.FindTexture("cs Script Icon");
|
||||
_registryCache.Add(new SearchTreeGroupEntry(new GUIContent("Quick Search"), 0));
|
||||
|
||||
var topRegistriesLookup = new Dictionary<string, List<KeyValuePair<string, INodeRegistry>>>();
|
||||
foreach (var entry in UdonEditorManager.Instance.GetTopRegistries())
|
||||
{
|
||||
topRegistriesLookup.Add(entry.Key, new List<KeyValuePair<string, INodeRegistry>>(entry.Value));
|
||||
}
|
||||
|
||||
// Add shortcut registries
|
||||
foreach (var item in _shortcutRegistries)
|
||||
{
|
||||
if (topRegistriesLookup.TryGetValue(item.Item1, out var searchRegistry))
|
||||
{
|
||||
string subRegistryName = $"{item.Item1}{item.Item2}NodeRegistry";
|
||||
var subRegistry = searchRegistry.FindAll(r => r.Key == subRegistryName);
|
||||
if (subRegistry.Count == 1)
|
||||
{
|
||||
topRegistriesLookup.Add(item.Item2, subRegistry);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Could not find sub-registry {subRegistryName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Combine Events into special top-level element
|
||||
var vrcEvents = topRegistriesLookup["VRC"].Find(r=>r.Key == "VRCEventNodeRegistry").Value.GetNodeDefinitions();
|
||||
var udonEvents = topRegistriesLookup["Udon"].Find(r => r.Key == "UdonEventNodeRegistry").Value.GetNodeDefinitions();
|
||||
var allEvents = vrcEvents.Concat(udonEvents);
|
||||
var eventRegistry = new EventRegistry();
|
||||
foreach (var item in allEvents)
|
||||
{
|
||||
eventRegistry.definitions.Add(item);
|
||||
}
|
||||
topRegistriesLookup.Add("Events", new List<KeyValuePair<string, INodeRegistry>>() { new KeyValuePair<string, INodeRegistry>("Events", eventRegistry) });
|
||||
|
||||
// Build lookup from newly organized list
|
||||
var topRegistries = topRegistriesLookup.OrderBy(s => s.Key);
|
||||
foreach (var topRegistry in topRegistries)
|
||||
{
|
||||
string topName = topRegistry.Key.Replace("NodeRegistry", "");
|
||||
|
||||
// Handle Shortcut registries with only 1 top-level registry listed
|
||||
if (topRegistry.Value.Count == 1)
|
||||
{
|
||||
string registryName = UdonGraphExtensions.FriendlyNameify(topName);
|
||||
_registryCache.Add(new SearchTreeGroupEntry(new GUIContent(registryName)) { level = 1, userData = topRegistry.Value });
|
||||
AddEntriesForRegistry(_registryCache, topRegistry.Value.First().Value, 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip empty 'Udon' top level
|
||||
if (topName != "Udon")
|
||||
{
|
||||
_registryCache.Add(new SearchTreeGroupEntry(new GUIContent(topName), 1));
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, INodeRegistry> registry in topRegistry.Value.OrderBy(s => s.Key))
|
||||
{
|
||||
string baseRegistryName = registry.Key.Replace("NodeRegistry", "").FriendlyNameify().ReplaceFirst(topName, "");
|
||||
string registryName = baseRegistryName.UppercaseFirst();
|
||||
|
||||
// Plural-ize Event->Events and Type->Types
|
||||
if (topName == "Udon" && (registryName == "Event" || registryName == "Type"))
|
||||
{
|
||||
registryName = $"{registryName}s";
|
||||
}
|
||||
else
|
||||
{
|
||||
// add Registry Level
|
||||
if (registryName.StartsWithCached("Object") || registryName.StartsWithCached("Type"))
|
||||
{
|
||||
registryName = $"{topName}.{registryName}";
|
||||
}
|
||||
_registryCache.Add(new SearchTreeEntry(new GUIContent(registryName, icon, $"{topName}.{registryName}")) { level = 2, userData = registry.Value });
|
||||
}
|
||||
}
|
||||
}
|
||||
return _registryCache;
|
||||
}
|
||||
|
||||
override public bool OnSelectEntry(SearchTreeEntry entry, SearchWindowContext context)
|
||||
{
|
||||
// should check for adding duplicate event nodes here, look at Legacy.UdonGraph.TryCreateNodeInstance
|
||||
// Assuming that if we've made it to this point we're allowed to add the node
|
||||
|
||||
// checking type so we can support selecting registries as well
|
||||
if (entry.userData is INodeRegistry)
|
||||
{
|
||||
_searchManager.QueueOpenFocusedSearch(entry.userData as INodeRegistry, context.screenMousePosition);
|
||||
return true;
|
||||
}
|
||||
else if (entry.userData is UdonNodeDefinition && !_graphView.IsDuplicateEventNode((entry.userData as UdonNodeDefinition).fullName))
|
||||
{
|
||||
UdonNode node = UdonNode.CreateNode(entry.userData as UdonNodeDefinition, _graphView);
|
||||
|
||||
_graphView.AddElement(node);
|
||||
|
||||
node.SetPosition(new Rect(GetGraphPositionFromContext(context), Vector2.zero));
|
||||
node.Select(_graphView, false);
|
||||
|
||||
// Do we need to do this to reserialize, etc?
|
||||
_graphView.ReSerializeData();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public class EventRegistry : INodeRegistry
|
||||
{
|
||||
public List<UdonNodeDefinition> definitions = new List<UdonNodeDefinition>();
|
||||
|
||||
public UdonNodeDefinition GetNodeDefinition(string identifier)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<UdonNodeDefinition> GetNodeDefinitions()
|
||||
{
|
||||
return definitions;
|
||||
}
|
||||
|
||||
public IEnumerable<UdonNodeDefinition> GetNodeDefinitions(string baseIdentifier)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Dictionary<string, INodeRegistry> GetNodeRegistries()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a6c453fae11b5349a33399e258d1578
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Experimental.UIElements.GraphView;
|
||||
using UnityEngine;
|
||||
using VRC.Udon.Graph.Interfaces;
|
||||
|
||||
namespace VRC.Udon.Editor.ProgramSources.UdonGraphProgram.UI.GraphView
|
||||
{
|
||||
public class UdonSearchManager
|
||||
{
|
||||
private UdonGraph _view;
|
||||
private UdonGraphWindow _window;
|
||||
|
||||
// Search Windows
|
||||
private UdonFocusedSearchWindow _focusedSearchWindow;
|
||||
private UdonRegistrySearchWindow _registrySearchWindow;
|
||||
private UdonFullSearchWindow _fullSearchWindow;
|
||||
public UdonVariableTypeWindow _variableSearchWindow;
|
||||
public UdonPortSearchWindow _portSearchWindow;
|
||||
|
||||
public UdonSearchManager(UdonGraph view, UdonGraphWindow window)
|
||||
{
|
||||
_view = view;
|
||||
_window = window;
|
||||
|
||||
SetupSearchTypes();
|
||||
|
||||
view.nodeCreationRequest += OnRequestNodeCreation;
|
||||
}
|
||||
|
||||
private void SetupSearchTypes()
|
||||
{
|
||||
if (_registrySearchWindow == null)
|
||||
_registrySearchWindow = ScriptableObject.CreateInstance<UdonRegistrySearchWindow>();
|
||||
_registrySearchWindow.Initialize(_window, _view, this);
|
||||
|
||||
if (_fullSearchWindow == null)
|
||||
_fullSearchWindow = ScriptableObject.CreateInstance<UdonFullSearchWindow>();
|
||||
_fullSearchWindow.Initialize(_window, _view);
|
||||
|
||||
if (_focusedSearchWindow == null)
|
||||
_focusedSearchWindow = ScriptableObject.CreateInstance<UdonFocusedSearchWindow>();
|
||||
_focusedSearchWindow.Initialize(_window, _view);
|
||||
|
||||
if (_variableSearchWindow == null)
|
||||
_variableSearchWindow = ScriptableObject.CreateInstance<UdonVariableTypeWindow>();
|
||||
_variableSearchWindow.Initialize(_window, _view);
|
||||
|
||||
if (_portSearchWindow == null)
|
||||
_portSearchWindow = ScriptableObject.CreateInstance<UdonPortSearchWindow>();
|
||||
_portSearchWindow.Initialize(_window, _view);
|
||||
}
|
||||
|
||||
private void OnRequestNodeCreation(NodeCreationContext context)
|
||||
{
|
||||
// started on empty space
|
||||
if (context.target == null)
|
||||
{
|
||||
// If we have a node selected (but not set as context.target because that's a container for new nodes to go into), search within that node's registry
|
||||
if (Settings.SearchOnSelectedNodeRegistry && _view.selection.Count > 0 && _view.selection.First() is UdonNode)
|
||||
{
|
||||
_focusedSearchWindow.targetRegistry = (_view.selection.First() as UdonNode).Registry;
|
||||
SearchWindow.Open(new SearchWindowContext(context.screenMousePosition), _focusedSearchWindow);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create Search Window that only searches Top-Level Registries
|
||||
SearchWindow.Open(new SearchWindowContext(context.screenMousePosition), _registrySearchWindow);
|
||||
}
|
||||
}
|
||||
else if (context.target is UdonGraph)
|
||||
{
|
||||
// Slightly hacky method to figure out that we want a full-search window
|
||||
SearchWindow.Open(new SearchWindowContext(context.screenMousePosition), _fullSearchWindow);
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenVariableSearch(Vector2 screenMousePosition)
|
||||
{
|
||||
// offset search window to appear next to mouse
|
||||
screenMousePosition.x += 140;
|
||||
screenMousePosition.y += 0;
|
||||
SearchWindow.Open(new SearchWindowContext(screenMousePosition), _variableSearchWindow);
|
||||
}
|
||||
|
||||
public void OpenPortSearch(Type type, Vector2 screenMousePosition, Port port, Direction direction)
|
||||
{
|
||||
// offset search window to appear next to mouse
|
||||
screenMousePosition.x += 140;
|
||||
screenMousePosition.y += 0;
|
||||
_portSearchWindow.typeToSearch = type;
|
||||
_portSearchWindow.startingPort = port;
|
||||
_portSearchWindow.direction = direction;
|
||||
SearchWindow.Open(new SearchWindowContext(screenMousePosition, 400, 360), _portSearchWindow);
|
||||
}
|
||||
|
||||
private Vector2 _searchWindowPosition;
|
||||
public void QueueOpenFocusedSearch(INodeRegistry registry, Vector2 position)
|
||||
{
|
||||
_searchWindowPosition = position;
|
||||
_focusedSearchWindow.targetRegistry = registry;
|
||||
EditorApplication.update += TryOpenFocusedSearch;
|
||||
}
|
||||
|
||||
private void TryOpenFocusedSearch()
|
||||
{
|
||||
if (SearchWindow.Open(new SearchWindowContext(_searchWindowPosition), _focusedSearchWindow))
|
||||
{
|
||||
EditorApplication.update -= TryOpenFocusedSearch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5a10bb1987c27944bd08a88119b2844
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.UIElements;
|
||||
using UnityEditor.Experimental.UIElements;
|
||||
using UnityEditor.Experimental.UIElements.GraphView;
|
||||
using System.Collections.Generic;
|
||||
using VRC.Udon.Graph.Interfaces;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using VRC.Udon.Graph;
|
||||
|
||||
namespace VRC.Udon.Editor.ProgramSources.UdonGraphProgram.UI.GraphView
|
||||
{
|
||||
|
||||
public class UdonSearchWindowBase : ScriptableObject, ISearchWindowProvider
|
||||
{
|
||||
// Reference to actual Graph View
|
||||
internal UdonGraph _graphView;
|
||||
private List<SearchTreeEntry> _exampleLookup;
|
||||
internal UdonGraphWindow _editorWindow;
|
||||
|
||||
public virtual void Initialize(UdonGraphWindow editorWindow, UdonGraph graphView)
|
||||
{
|
||||
_editorWindow = editorWindow;
|
||||
_graphView = graphView;
|
||||
}
|
||||
|
||||
#region ISearchWindowProvider
|
||||
|
||||
public virtual List<SearchTreeEntry> CreateSearchTree(SearchWindowContext context)
|
||||
{
|
||||
if (_exampleLookup != null && _exampleLookup.Count > 0) return _exampleLookup;
|
||||
|
||||
_exampleLookup = new List<SearchTreeEntry>();
|
||||
|
||||
Texture2D icon = EditorGUIUtility.FindTexture("cs Script Icon");
|
||||
_exampleLookup.Add(new SearchTreeGroupEntry(new GUIContent("Create Node"), 0));
|
||||
|
||||
return _exampleLookup;
|
||||
}
|
||||
|
||||
public virtual bool OnSelectEntry(SearchTreeEntry entry, SearchWindowContext context)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
internal Vector2 GetGraphPositionFromContext(SearchWindowContext context)
|
||||
{
|
||||
var windowRoot = _editorWindow.GetRootVisualContainer();
|
||||
var windowMousePosition = windowRoot.ChangeCoordinatesTo(windowRoot.parent, context.screenMousePosition - _editorWindow.position.position);
|
||||
var graphMousePosition = _graphView.contentViewContainer.WorldToLocal(windowMousePosition);
|
||||
return graphMousePosition;
|
||||
}
|
||||
|
||||
internal void AddEntries(List<SearchTreeEntry> cache, IEnumerable<UdonNodeDefinition> definitions, int level, bool stripToLastDot = false)
|
||||
{
|
||||
Texture2D icon = EditorGUIUtility.FindTexture("cs Script Icon");
|
||||
Dictionary<string, UdonNodeDefinition> baseNodeDefinition = new Dictionary<string, UdonNodeDefinition>();
|
||||
|
||||
foreach (UdonNodeDefinition nodeDefinition in definitions.OrderBy(s => UdonGraphExtensions.PrettyFullName(s)))
|
||||
{
|
||||
string baseIdentifier = nodeDefinition.fullName;
|
||||
string[] splitBaseIdentifier = baseIdentifier.Split(new[] { "__" }, StringSplitOptions.None);
|
||||
if (splitBaseIdentifier.Length >= 2)
|
||||
{
|
||||
baseIdentifier = $"{splitBaseIdentifier[0]}__{splitBaseIdentifier[1]}";
|
||||
}
|
||||
if (baseNodeDefinition.ContainsKey(baseIdentifier))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
baseNodeDefinition.Add(baseIdentifier, nodeDefinition);
|
||||
}
|
||||
|
||||
// add all subTypes
|
||||
foreach (KeyValuePair<string, UdonNodeDefinition> nodeDefinitionsEntry in baseNodeDefinition)
|
||||
{
|
||||
string nodeName = UdonGraphExtensions.PrettyBaseName(nodeDefinitionsEntry.Key);
|
||||
nodeName = nodeName.UppercaseFirst();
|
||||
nodeName = nodeName.Replace("_", " ");
|
||||
if (stripToLastDot)
|
||||
{
|
||||
int lastDotIndex = nodeName.LastIndexOf('.');
|
||||
nodeName = nodeName.Substring(lastDotIndex + 1);
|
||||
}
|
||||
|
||||
// don't add Variable or Comment nodes
|
||||
if (nodeName.StartsWithCached("Variable") || nodeName.StartsWithCached("Get Var") || nodeName.StartsWithCached("Set Var") || nodeName.StartsWithCached("Comment"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (nodeName.StartsWithCached("Object"))
|
||||
{
|
||||
nodeName = $"{nodeDefinitionsEntry.Value.type.Namespace}.{nodeName}";
|
||||
}
|
||||
cache.Add(new SearchTreeEntry(new GUIContent(nodeName, icon)) { level = level, userData = nodeDefinitionsEntry.Value });
|
||||
}
|
||||
}
|
||||
|
||||
// adds all entries so we can use this for regular and array registries
|
||||
internal void AddEntriesForRegistry(List<SearchTreeEntry> cache, INodeRegistry registry, int level, bool stripToLastDot = false)
|
||||
{
|
||||
AddEntries(cache, registry.GetNodeDefinitions(), level, stripToLastDot);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d825ed3ba6aa7f14294e73efefc217d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor.Experimental.UIElements.GraphView;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace VRC.Udon.Editor.ProgramSources.UdonGraphProgram.UI.GraphView
|
||||
{
|
||||
public class UdonVariableTypeWindow : UdonSearchWindowBase
|
||||
{
|
||||
internal List<SearchTreeEntry> _fullRegistry;
|
||||
|
||||
#region ISearchWindowProvider
|
||||
|
||||
override public List<SearchTreeEntry> CreateSearchTree(SearchWindowContext context)
|
||||
{
|
||||
if (_fullRegistry != null) return _fullRegistry;
|
||||
|
||||
_fullRegistry = new List<SearchTreeEntry>();
|
||||
|
||||
_fullRegistry.Add(new SearchTreeGroupEntry(new GUIContent("Variable Type Search"), 0));
|
||||
|
||||
var definitions = UdonEditorManager.Instance.GetNodeDefinitions("Variable_").ToList().OrderBy(n=>n.name);
|
||||
foreach (var definition in definitions)
|
||||
{
|
||||
_fullRegistry.Add(new SearchTreeEntry(new GUIContent(UdonGraphExtensions.FriendlyTypeName(definition.type).FriendlyNameify()))
|
||||
{
|
||||
level = 1,
|
||||
userData = definition.fullName,
|
||||
});
|
||||
}
|
||||
|
||||
return _fullRegistry;
|
||||
}
|
||||
|
||||
override public bool OnSelectEntry(SearchTreeEntry entry, SearchWindowContext context)
|
||||
{
|
||||
if(_graphView == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_graphView.AddNewVariable((string)entry.userData);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16fc7a7a059deeb458fdcdf719b467a4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in new issue
Block a user