An easy to use Unity 3D library for creating illustrated Interactive Fiction games and more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
5.6 KiB

using UnityEditor;
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Fungus.EditorUtils
{
/// <summary>
/// Searchable Popup Window for adding a command to a block
/// </summary>
public class CommandSelectorPopupWindowContent : BasePopupWindowContent
{
static List<System.Type> commandTypes;
static void CacheCommandTypes()
{
commandTypes = EditorExtensions.FindDerivedTypes(typeof(Command)).Where(x => !x.IsAbstract).ToList();
}
[UnityEditor.Callbacks.DidReloadScripts]
private static void OnScriptsReloaded()
{
CacheCommandTypes();
}
static Block curBlock;
static protected List<KeyValuePair<System.Type, CommandInfoAttribute>> filteredAttributes;
public CommandSelectorPopupWindowContent(string currentHandlerName, int width, int height)
: base(currentHandlerName, width, height)
{
}
protected override void SelectByOrigIndex(int index)
{
var commandType = (index >= 0 && index < commandTypes.Count) ? commandTypes[index] : null;
AddCommandCallback(commandType);
}
protected override void PrepareAllItems()
{
if (commandTypes == null || commandTypes.Count == 0)
{
CacheCommandTypes();
}
filteredAttributes = GetFilteredSupportedCommands(curBlock.GetFlowchart());
int i = 0;
foreach (var item in filteredAttributes)
{
allItems.Add(new FilteredListItem(i, (item.Value.Category.Length > 0 ? item.Value.Category + CATEGORY_CHAR : "") + item.Value.CommandName, item.Value.HelpText));
i++;
}
}
static public void ShowCommandMenu(Rect position, string currentHandlerName, Block block, int width, int height)
{
curBlock = block;
if (FungusEditorPreferences.useExperimentalMenus)
{
var win = new CommandSelectorPopupWindowContent(currentHandlerName,
width, (int)(height - EditorGUIUtility.singleLineHeight * 3));
PopupWindow.Show(position, win);
}
else
{
//need to ensure we have filtered data
filteredAttributes = GetFilteredSupportedCommands(curBlock.GetFlowchart());
}
//old method
DoOlderMenu();
}
protected static List<KeyValuePair<System.Type, CommandInfoAttribute>> GetFilteredSupportedCommands(Flowchart flowchart)
{
List<KeyValuePair<System.Type, CommandInfoAttribute>> filteredAttributes = BlockEditor.GetFilteredCommandInfoAttribute(commandTypes);
filteredAttributes.Sort(BlockEditor.CompareCommandAttributes);
filteredAttributes = filteredAttributes.Where(x => flowchart.IsCommandSupported(x.Value)).ToList();
return filteredAttributes;
}
static protected void DoOlderMenu()
{
GenericMenu commandMenu = new GenericMenu();
// Build menu list
foreach (var keyPair in filteredAttributes)
{
GUIContent menuItem;
if (keyPair.Value.Category == "")
{
menuItem = new GUIContent(keyPair.Value.CommandName);
}
else
{
menuItem = new GUIContent(keyPair.Value.Category + CATEGORY_CHAR + keyPair.Value.CommandName);
}
commandMenu.AddItem(menuItem, false, AddCommandCallback, keyPair.Key);
}
commandMenu.ShowAsContext();
}
//Used by GenericMenu Delegate
static protected void AddCommandCallback(object obj)
{
Type command = obj as Type;
if (command != null)
{
AddCommandCallback(command);
}
}
static protected void AddCommandCallback(Type commandType)
{
var block = curBlock;
if (block == null || commandType == null)
{
return;
}
var flowchart = (Flowchart)block.GetFlowchart();
// Use index of last selected command in list, or end of list if nothing selected.
int index = -1;
foreach (var command in flowchart.SelectedCommands)
{
if (command.CommandIndex + 1 > index)
{
index = command.CommandIndex + 1;
}
}
if (index == -1)
{
index = block.CommandList.Count;
}
var newCommand = Undo.AddComponent(block.gameObject, commandType) as Command;
block.GetFlowchart().AddSelectedCommand(newCommand);
newCommand.ParentBlock = block;
newCommand.ItemId = flowchart.NextItemId();
// Let command know it has just been added to the block
newCommand.OnCommandAdded(block);
Undo.RecordObject(block, "Set command type");
if (index < block.CommandList.Count - 1)
{
block.CommandList.Insert(index, newCommand);
}
else
{
block.CommandList.Add(newCommand);
}
// Because this is an async call, we need to force prefab instances to record changes
PrefabUtility.RecordPrefabInstancePropertyModifications(block);
flowchart.ClearSelectedCommands();
}
}
}