revival/game/Assets/Plugins/FMOD/src/Editor/CreateEventPopup.cs

386 lines
14 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
namespace FMODUnity
{
class CreateEventPopup : EditorWindow
{
class FolderEntry
{
public FolderEntry parent;
public string name;
public string guid;
public List<FolderEntry> entries = new List<FolderEntry>();
public Rect rect;
}
SerializedProperty outputProperty;
internal void SelectEvent(SerializedProperty property)
{
outputProperty = property;
}
class BankEntry
{
public string name;
public string guid;
}
FolderEntry rootFolder;
FolderEntry currentFolder;
List<BankEntry> banks;
public CreateEventPopup()
{
}
private void BuildTree()
{
var rootGuid = EditorUtils.GetScriptOutput("studio.project.workspace.masterEventFolder.id");
rootFolder = new FolderEntry();
rootFolder.guid = rootGuid;
BuildTreeItem(rootFolder);
wantsMouseMove = true;
banks = new List<BankEntry>();
EditorUtils.GetScriptOutput("children = \"\";");
EditorUtils.GetScriptOutput("func = function(val) {{ children += \",\" + val.id + val.name; }};");
EditorUtils.GetScriptOutput("studio.project.workspace.masterBankFolder.items.forEach(func, this); ");
string bankList = EditorUtils.GetScriptOutput("children;");
string[] bankListSplit = bankList.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach(var bank in bankListSplit)
{
var entry = new BankEntry();
entry.guid = bank.Substring(0, 38);
entry.name = bank.Substring(38);
banks.Add(entry);
}
banks.Sort((a, b) => a.name.CompareTo(b.name));
}
private void BuildTreeItem(FolderEntry entry)
{
// lookup the entry
EditorUtils.GetScriptOutput(string.Format("cur = studio.project.lookup(\"{0}\");", entry.guid));
// get child count
string itemCountString = EditorUtils.GetScriptOutput("cur.items.length;");
int itemCount;
Int32.TryParse(itemCountString, out itemCount);
// iterate children looking for folder
for (int item = 0; item < itemCount; item++)
{
EditorUtils.GetScriptOutput(String.Format("child = cur.items[{0}]", item));
// check if it's a folder
string isFolder = EditorUtils.GetScriptOutput("child.isOfExactType(\"EventFolder\")");
if (isFolder == "false")
{
continue;
}
// Get guid and name
string info = EditorUtils.GetScriptOutput("child.id + child.name");
var childEntry = new FolderEntry();
childEntry.guid = info.Substring(0, 38);
childEntry.name = info.Substring(38);
childEntry.parent = entry;
entry.entries.Add(childEntry);
}
// Recurse for child entries
foreach(var childEntry in entry.entries)
{
BuildTreeItem(childEntry);
}
}
int lastHover = 0;
string eventFolder = "/";
string eventName = "";
string currentFilter = "";
int selectedBank = 0;
bool resetCursor = true;
Vector2 scrollPos = new Vector2();
Rect scrollRect = new Rect();
bool isConnected = false;
public void OnGUI()
{
var borderIcon = EditorGUIUtility.Load("FMOD/Border.png") as Texture2D;
var border = new GUIStyle(GUI.skin.box);
border.normal.background = borderIcon;
GUI.Box(new Rect(1, 1, position.width - 1, position.height - 1), GUIContent.none, border);
if (Event.current.type == EventType.Layout)
{
isConnected = EditorUtils.IsConnectedToStudio();
}
if (!isConnected)
{
this.ShowNotification(new GUIContent("FMOD Studio not running"));
return;
}
this.RemoveNotification();
if (rootFolder == null)
{
BuildTree();
currentFolder = rootFolder;
}
var arrowIcon = EditorGUIUtility.Load("FMOD/ArrowIcon.png") as Texture;
var hoverIcon = EditorGUIUtility.Load("FMOD/SelectedAlt.png") as Texture2D;
var titleIcon = EditorGUIUtility.Load("IN BigTitle") as Texture2D;
var nextEntry = currentFolder;
var filteredEntries = currentFolder.entries.FindAll((x) => x.name.StartsWith(currentFilter, StringComparison.CurrentCultureIgnoreCase));
// Process key strokes for the folder list
{
if (Event.current.keyCode == KeyCode.UpArrow)
{
if (Event.current.type == EventType.KeyDown)
{
lastHover = Math.Max(lastHover - 1, 0);
if (filteredEntries[lastHover].rect.y < scrollPos.y)
{
scrollPos.y = filteredEntries[lastHover].rect.y;
}
}
Event.current.Use();
}
if (Event.current.keyCode == KeyCode.DownArrow)
{
if (Event.current.type == EventType.KeyDown)
{
lastHover = Math.Min(lastHover + 1, filteredEntries.Count - 1);
if (filteredEntries[lastHover].rect.y + filteredEntries[lastHover].rect.height > scrollPos.y + scrollRect.height)
{
scrollPos.y = filteredEntries[lastHover].rect.y - scrollRect.height + filteredEntries[lastHover].rect.height * 2;
}
}
Event.current.Use();
}
if (Event.current.keyCode == KeyCode.RightArrow)
{
if (Event.current.type == EventType.KeyDown)
nextEntry = filteredEntries[lastHover];
Event.current.Use();
}
if (Event.current.keyCode == KeyCode.LeftArrow)
{
if (Event.current.type == EventType.KeyDown)
if (currentFolder.parent != null)
{
nextEntry = currentFolder.parent;
}
Event.current.Use();
}
}
bool disabled = eventName.Length == 0;
EditorGUI.BeginDisabledGroup(disabled);
if (GUILayout.Button("Create Event"))
{
CreateEventInStudio();
this.Close();
}
EditorGUI.EndDisabledGroup();
{
GUI.SetNextControlName("name");
EditorGUILayout.LabelField("Name");
eventName = EditorGUILayout.TextField(eventName);
}
{
EditorGUILayout.LabelField("Bank");
selectedBank = EditorGUILayout.Popup(selectedBank, banks.Select(x => x.name).ToArray());
}
bool updateEventPath = false;
{
GUI.SetNextControlName("folder");
EditorGUI.BeginChangeCheck();
EditorGUILayout.LabelField("Path");
eventFolder = GUILayout.TextField(eventFolder);
if (EditorGUI.EndChangeCheck())
{
updateEventPath = true;
}
}
if (resetCursor)
{
resetCursor = false;
var textEditor = (TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl);
if (textEditor != null)
{
textEditor.MoveCursorToPosition(new Vector2(9999, 9999));
}
}
// Draw the current folder as a title bar, click to go back one level
{
Rect currentRect = EditorGUILayout.GetControlRect();
var bg = new GUIStyle(GUI.skin.box);
bg.normal.background = titleIcon;
Rect bgRect = new Rect(currentRect);
bgRect.x = 2;
bgRect.width = position.width-4;
GUI.Box(bgRect, GUIContent.none, bg);
Rect textureRect = currentRect;
textureRect.width = arrowIcon.width;
if (currentFolder.name != null)
{
GUI.DrawTextureWithTexCoords(textureRect, arrowIcon, new Rect(1, 1, -1, -1));
}
Rect labelRect = currentRect;
labelRect.x += arrowIcon.width + 50;
labelRect.width -= arrowIcon.width + 50;
GUI.Label(labelRect, currentFolder.name != null ? currentFolder.name : "Folders", EditorStyles.boldLabel);
if (Event.current.type == EventType.MouseDown && currentRect.Contains(Event.current.mousePosition) &&
currentFolder.parent != null)
{
nextEntry = currentFolder.parent;
Event.current.Use();
}
}
var normal = new GUIStyle(GUI.skin.label);
normal.padding.left = 14;
var hover = new GUIStyle(normal);
hover.normal.background = hoverIcon;
scrollPos = EditorGUILayout.BeginScrollView(scrollPos, false, false);
for (int i = 0; i < filteredEntries.Count; i++)
{
var entry = filteredEntries[i];
var content = new GUIContent(entry.name);
var rect = EditorGUILayout.GetControlRect();
if ((rect.Contains(Event.current.mousePosition) && Event.current.type == EventType.MouseMove) || i == lastHover)
{
lastHover = i;
GUI.Label(rect, content, hover);
if (rect.Contains(Event.current.mousePosition) && Event.current.type == EventType.MouseDown)
{
nextEntry = entry;
}
}
else
{
GUI.Label(rect, content, normal);
}
Rect textureRect = rect;
textureRect.x = textureRect.width - arrowIcon.width;
textureRect.width = arrowIcon.width;
GUI.DrawTexture(textureRect, arrowIcon);
if (Event.current.type == EventType.Repaint)
{
entry.rect = rect;
}
}
EditorGUILayout.EndScrollView();
if (Event.current.type == EventType.Repaint)
{
scrollRect = GUILayoutUtility.GetLastRect();
}
if (currentFolder != nextEntry)
{
lastHover = 0;
currentFolder = nextEntry;
UpdateTextFromList();
Repaint();
}
if (updateEventPath)
{
UpdateListFromText();
}
if (Event.current.type == EventType.MouseMove)
{
Repaint();
}
}
private void CreateEventInStudio()
{
string eventGuid = EditorUtils.CreateStudioEvent(eventFolder, eventName);
if (!string.IsNullOrEmpty(eventGuid))
{
EditorUtils.GetScriptOutput(String.Format("studio.project.lookup(\"{0}\").relationships.banks.add(studio.project.lookup(\"{1}\"));", eventGuid, banks[selectedBank].guid));
EditorUtils.GetScriptOutput("studio.project.build();");
string fullPath = "event:" + eventFolder + eventName;
outputProperty.stringValue = fullPath;
EditorUtils.UpdateParamsOnEmitter(outputProperty.serializedObject, fullPath);
outputProperty.serializedObject.ApplyModifiedProperties();
}
}
private void UpdateListFromText()
{
int endFolders = eventFolder.LastIndexOf("/");
currentFilter = eventFolder.Substring(endFolders + 1);
var folders = eventFolder.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
FolderEntry entry = rootFolder;
int i;
for (i = 0; i < folders.Length; i++)
{
var newEntry = entry.entries.Find((x) => x.name.Equals(folders[i], StringComparison.CurrentCultureIgnoreCase));
if (newEntry == null)
{
break;
}
entry = newEntry;
}
currentFolder = entry;
// Treat an exact filter match as being in that folder and clear the filter
if (entry.name != null && entry.name.Equals(currentFilter, StringComparison.CurrentCultureIgnoreCase))
{
currentFilter = "";
}
}
private void UpdateTextFromList()
{
string path = "";
var entry = currentFolder;
while (entry.parent != null)
{
path = entry.name + "/" + path;
entry = entry.parent;
}
eventFolder = "/" + path;
resetCursor = true;
currentFilter = "";
}
}
}