Browse Source

Merge pull request #619 from stevehalliwell/CommandByName

Command by name
master
Chris Gregan 8 years ago committed by GitHub
parent
commit
00a2c23400
  1. 425
      Assets/Fungus/Scripts/Editor/BlockEditor.cs

425
Assets/Fungus/Scripts/Editor/BlockEditor.cs

@ -15,8 +15,8 @@ using System.Reflection;
namespace Fungus.EditorUtils namespace Fungus.EditorUtils
{ {
[CustomEditor (typeof(Block))] [CustomEditor(typeof(Block))]
public class BlockEditor : Editor public class BlockEditor : Editor
{ {
protected class SetEventHandlerOperation protected class SetEventHandlerOperation
{ {
@ -26,11 +26,14 @@ namespace Fungus.EditorUtils
protected class AddCommandOperation protected class AddCommandOperation
{ {
public Block block;
public Type commandType; public Type commandType;
public int index;
} }
private static readonly char[] SPLIT_INPUT_ON = new char[] { ' ', '/', '\\' };
private static readonly int MAX_PREVIEW_GRID = 7;
private static readonly string ELIPSIS = "...";
public static List<Action> actionList = new List<Action>(); public static List<Action> actionList = new List<Action>();
protected Texture2D upIcon; protected Texture2D upIcon;
@ -39,6 +42,10 @@ namespace Fungus.EditorUtils
protected Texture2D duplicateIcon; protected Texture2D duplicateIcon;
protected Texture2D deleteIcon; protected Texture2D deleteIcon;
protected string commandTextFieldContents = string.Empty;
protected int filteredCommandPreviewSelectedItem = 0;
protected Type commandSelectedByTextInput;
static List<System.Type> commandTypes; static List<System.Type> commandTypes;
static List<System.Type> eventHandlerTypes; static List<System.Type> eventHandlerTypes;
@ -109,7 +116,7 @@ namespace Fungus.EditorUtils
var block = target as Block; var block = target as Block;
SerializedProperty commandListProperty = serializedObject.FindProperty("commandList"); SerializedProperty commandListProperty = serializedObject.FindProperty("commandList");
if (block == flowchart.SelectedBlock) if (block == flowchart.SelectedBlock)
{ {
// Custom tinting // Custom tinting
@ -130,7 +137,7 @@ namespace Fungus.EditorUtils
EditorGUILayout.PropertyField(descriptionProp); EditorGUILayout.PropertyField(descriptionProp);
DrawEventHandlerGUI(flowchart); DrawEventHandlerGUI(flowchart);
block.UpdateIndentLevels(); block.UpdateIndentLevels();
// Make sure each command has a reference to its parent block // Make sure each command has a reference to its parent block
@ -146,7 +153,7 @@ namespace Fungus.EditorUtils
ReorderableListGUI.Title("Commands"); ReorderableListGUI.Title("Commands");
CommandListAdaptor adaptor = new CommandListAdaptor(commandListProperty, 0); CommandListAdaptor adaptor = new CommandListAdaptor(commandListProperty, 0);
adaptor.nodeRect = block._NodeRect; adaptor.nodeRect = block._NodeRect;
ReorderableListFlags flags = ReorderableListFlags.HideAddButton | ReorderableListFlags.HideRemoveButtons | ReorderableListFlags.DisableContextMenu; ReorderableListFlags flags = ReorderableListFlags.HideAddButton | ReorderableListFlags.HideRemoveButtons | ReorderableListFlags.DisableContextMenu;
if (block.CommandList.Count == 0) if (block.CommandList.Count == 0)
@ -170,7 +177,7 @@ namespace Fungus.EditorUtils
if (GUIUtility.keyboardControl == 0) //Only call keyboard shortcuts when not typing in a text field if (GUIUtility.keyboardControl == 0) //Only call keyboard shortcuts when not typing in a text field
{ {
Event e = Event.current; Event e = Event.current;
// Copy keyboard shortcut // Copy keyboard shortcut
if (e.type == EventType.ValidateCommand && e.commandName == "Copy") if (e.type == EventType.ValidateCommand && e.commandName == "Copy")
{ {
@ -180,12 +187,12 @@ namespace Fungus.EditorUtils
} }
} }
if (e.type == EventType.ExecuteCommand && e.commandName == "Copy") if (e.type == EventType.ExecuteCommand && e.commandName == "Copy")
{ {
actionList.Add(Copy); actionList.Add(Copy);
e.Use(); e.Use();
} }
// Cut keyboard shortcut // Cut keyboard shortcut
if (e.type == EventType.ValidateCommand && e.commandName == "Cut") if (e.type == EventType.ValidateCommand && e.commandName == "Cut")
{ {
@ -200,7 +207,7 @@ namespace Fungus.EditorUtils
actionList.Add(Cut); actionList.Add(Cut);
e.Use(); e.Use();
} }
// Paste keyboard shortcut // Paste keyboard shortcut
if (e.type == EventType.ValidateCommand && e.commandName == "Paste") if (e.type == EventType.ValidateCommand && e.commandName == "Paste")
{ {
@ -211,12 +218,12 @@ namespace Fungus.EditorUtils
} }
} }
if (e.type == EventType.ExecuteCommand && e.commandName == "Paste") if (e.type == EventType.ExecuteCommand && e.commandName == "Paste")
{ {
actionList.Add(Paste); actionList.Add(Paste);
e.Use(); e.Use();
} }
// Duplicate keyboard shortcut // Duplicate keyboard shortcut
if (e.type == EventType.ValidateCommand && e.commandName == "Duplicate") if (e.type == EventType.ValidateCommand && e.commandName == "Duplicate")
{ {
@ -226,13 +233,13 @@ namespace Fungus.EditorUtils
} }
} }
if (e.type == EventType.ExecuteCommand && e.commandName == "Duplicate") if (e.type == EventType.ExecuteCommand && e.commandName == "Duplicate")
{ {
actionList.Add(Copy); actionList.Add(Copy);
actionList.Add(Paste); actionList.Add(Paste);
e.Use(); e.Use();
} }
// Delete keyboard shortcut // Delete keyboard shortcut
if (e.type == EventType.ValidateCommand && e.commandName == "Delete") if (e.type == EventType.ValidateCommand && e.commandName == "Delete")
{ {
@ -242,23 +249,23 @@ namespace Fungus.EditorUtils
} }
} }
if (e.type == EventType.ExecuteCommand && e.commandName == "Delete") if (e.type == EventType.ExecuteCommand && e.commandName == "Delete")
{ {
actionList.Add(Delete); actionList.Add(Delete);
e.Use(); e.Use();
} }
// SelectAll keyboard shortcut // SelectAll keyboard shortcut
if (e.type == EventType.ValidateCommand && e.commandName == "SelectAll") if (e.type == EventType.ValidateCommand && e.commandName == "SelectAll")
{ {
e.Use(); e.Use();
} }
if (e.type == EventType.ExecuteCommand && e.commandName == "SelectAll") if (e.type == EventType.ExecuteCommand && e.commandName == "SelectAll")
{ {
actionList.Add(SelectAll); actionList.Add(SelectAll);
e.Use(); e.Use();
} }
} }
} }
@ -279,7 +286,34 @@ namespace Fungus.EditorUtils
public virtual void DrawButtonToolbar() public virtual void DrawButtonToolbar()
{ {
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
//handle movement along our selection grid before something else eats our inputs
if (Event.current.type == EventType.keyDown)
{
//up down to change selection / esc to clear field
if (Event.current.keyCode == KeyCode.UpArrow)
{
filteredCommandPreviewSelectedItem--;
}
else if (Event.current.keyCode == KeyCode.DownArrow)
{
filteredCommandPreviewSelectedItem++;
}
if (commandSelectedByTextInput != null &&
Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter)
{
AddCommandCallback(commandSelectedByTextInput);
commandSelectedByTextInput = null;
commandTextFieldContents = String.Empty;
//GUI.FocusControl("dummycontrol");
Event.current.Use();
filteredCommandPreviewSelectedItem = 0;
}
}
// Previous Command // Previous Command
if ((Event.current.type == EventType.keyDown) && (Event.current.keyCode == KeyCode.PageUp)) if ((Event.current.type == EventType.keyDown) && (Event.current.keyCode == KeyCode.PageUp))
{ {
@ -299,35 +333,117 @@ namespace Fungus.EditorUtils
{ {
SelectPrevious(); SelectPrevious();
} }
// Down Button // Down Button
if (GUILayout.Button(downIcon)) if (GUILayout.Button(downIcon))
{ {
SelectNext(); SelectNext();
} }
GUILayout.FlexibleSpace(); GUILayout.FlexibleSpace();
//should track if text actually changes and pass that to the ShowPartialMatches so it can cache
commandTextFieldContents = GUILayout.TextField(commandTextFieldContents, GUILayout.MinWidth(20), GUILayout.MaxWidth(200));
// Add Button // Add Button
if (GUILayout.Button(addIcon)) if (GUILayout.Button(addIcon))
{ {
ShowCommandMenu(); ShowCommandMenu();
} }
// Duplicate Button // Duplicate Button
if (GUILayout.Button(duplicateIcon)) if (GUILayout.Button(duplicateIcon))
{ {
Copy(); Copy();
Paste(); Paste();
} }
// Delete Button // Delete Button
if (GUILayout.Button(deleteIcon)) if (GUILayout.Button(deleteIcon))
{ {
Delete(); Delete();
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
if (!string.IsNullOrEmpty(commandTextFieldContents))
ShowPartialMatches();
}
//Handles showing partial matches against the text input next to the AddCommand button
// Splits and matches and can use up down arrows and return/enter/numenter to confirm
// TODO add sorting of results so we get best match at the not just just a match
// e.g. "if" should show Flow/If at the top not Flow/Else If
private void ShowPartialMatches()
{
var block = target as Block;
var flowchart = (Flowchart)block.GetFlowchart();
//TODO this could be cached if input hasn't changed to avoid thrashing
var filteredAttributes = GetFilteredSupportedCommands(flowchart);
var upperCommandText = commandTextFieldContents.ToUpper().Trim();
if (upperCommandText.Length == 0)
return;
var tokens = upperCommandText.Split(SPLIT_INPUT_ON);
//we want commands that have all the elements you have typed
filteredAttributes = filteredAttributes.Where((x) =>
{
bool catAny = tokens.Any(x.Value.Category.ToUpper().Contains);
bool comAny = tokens.Any(x.Value.CommandName.ToUpper().Contains);
bool catAll = tokens.All(x.Value.Category.ToUpper().Contains);
bool comAll = tokens.All(x.Value.CommandName.ToUpper().Contains);
//so if both category and command found something, then there are multiple tokens and they line up with category and command
if (catAny && comAny)
return true;
//or its a single token or a complex token that matches entirely in cat or com
else if (catAll || comAll)
return true;
//this setup avoids multiple bad suggestions due to a complex category name that gives many false matches on complex partials
return false;
}).ToList();
if (filteredAttributes == null || filteredAttributes.Count == 0)
return;
//show results
GUILayout.Space(5);
GUILayout.BeginHorizontal();
filteredCommandPreviewSelectedItem = Mathf.Clamp(filteredCommandPreviewSelectedItem, 0, filteredAttributes.Count - 1);
var toShow = filteredAttributes.Select(x => x.Value.Category + "/" + x.Value.CommandName).ToArray();
//show the first x max that match our filters
if(toShow.Length > MAX_PREVIEW_GRID)
{
toShow = toShow.Take(MAX_PREVIEW_GRID).ToArray();
toShow[MAX_PREVIEW_GRID - 1] = ELIPSIS;
}
filteredCommandPreviewSelectedItem = GUILayout.SelectionGrid(filteredCommandPreviewSelectedItem, toShow, 1);
if (toShow[filteredCommandPreviewSelectedItem] != ELIPSIS)
{
commandSelectedByTextInput = filteredAttributes[filteredCommandPreviewSelectedItem].Key;
}
else
{
commandSelectedByTextInput = null;
}
GUILayout.EndHorizontal();
GUILayout.Space(5);
} }
protected virtual void DrawEventHandlerGUI(Flowchart flowchart) protected virtual void DrawEventHandlerGUI(Flowchart flowchart)
@ -358,7 +474,7 @@ namespace Fungus.EditorUtils
SetEventHandlerOperation noneOperation = new SetEventHandlerOperation(); SetEventHandlerOperation noneOperation = new SetEventHandlerOperation();
noneOperation.block = block; noneOperation.block = block;
noneOperation.eventHandlerType = null; noneOperation.eventHandlerType = null;
GenericMenu eventHandlerMenu = new GenericMenu(); GenericMenu eventHandlerMenu = new GenericMenu();
eventHandlerMenu.AddItem(new GUIContent("None"), false, OnSelectEventHandler, noneOperation); eventHandlerMenu.AddItem(new GUIContent("None"), false, OnSelectEventHandler, noneOperation);
@ -372,7 +488,7 @@ namespace Fungus.EditorUtils
SetEventHandlerOperation operation = new SetEventHandlerOperation(); SetEventHandlerOperation operation = new SetEventHandlerOperation();
operation.block = block; operation.block = block;
operation.eventHandlerType = type; operation.eventHandlerType = type;
eventHandlerMenu.AddItem(new GUIContent(info.EventHandlerName), false, OnSelectEventHandler, operation); eventHandlerMenu.AddItem(new GUIContent(info.EventHandlerName), false, OnSelectEventHandler, operation);
} }
} }
@ -380,10 +496,10 @@ namespace Fungus.EditorUtils
// Add event handlers with a category afterwards // Add event handlers with a category afterwards
foreach (System.Type type in eventHandlerTypes) foreach (System.Type type in eventHandlerTypes)
{ {
EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(type); EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(type);
if (info != null && if (info != null &&
info.Category.Length > 0) info.Category.Length > 0)
{ {
SetEventHandlerOperation operation = new SetEventHandlerOperation(); SetEventHandlerOperation operation = new SetEventHandlerOperation();
operation.block = block; operation.block = block;
operation.eventHandlerType = type; operation.eventHandlerType = type;
@ -444,23 +560,23 @@ namespace Fungus.EditorUtils
} }
var block = property.objectReferenceValue as Block; var block = property.objectReferenceValue as Block;
// Build dictionary of child blocks // Build dictionary of child blocks
List<GUIContent> blockNames = new List<GUIContent>(); List<GUIContent> blockNames = new List<GUIContent>();
int selectedIndex = 0; int selectedIndex = 0;
blockNames.Add(nullLabel); blockNames.Add(nullLabel);
var blocks = flowchart.GetComponents<Block>(); var blocks = flowchart.GetComponents<Block>();
for (int i = 0; i < blocks.Length; ++i) for (int i = 0; i < blocks.Length; ++i)
{ {
blockNames.Add(new GUIContent(blocks[i].BlockName)); blockNames.Add(new GUIContent(blocks[i].BlockName));
if (block == blocks[i]) if (block == blocks[i])
{ {
selectedIndex = i + 1; selectedIndex = i + 1;
} }
} }
selectedIndex = EditorGUILayout.Popup(label, selectedIndex, blockNames.ToArray()); selectedIndex = EditorGUILayout.Popup(label, selectedIndex, blockNames.ToArray());
if (selectedIndex == 0) if (selectedIndex == 0)
{ {
@ -470,7 +586,7 @@ namespace Fungus.EditorUtils
{ {
block = blocks[selectedIndex - 1]; block = blocks[selectedIndex - 1];
} }
property.objectReferenceValue = block; property.objectReferenceValue = block;
} }
@ -480,25 +596,25 @@ namespace Fungus.EditorUtils
{ {
return null; return null;
} }
Block result = block; Block result = block;
// Build dictionary of child blocks // Build dictionary of child blocks
List<GUIContent> blockNames = new List<GUIContent>(); List<GUIContent> blockNames = new List<GUIContent>();
int selectedIndex = 0; int selectedIndex = 0;
blockNames.Add(nullLabel); blockNames.Add(nullLabel);
Block[] blocks = flowchart.GetComponents<Block>(); Block[] blocks = flowchart.GetComponents<Block>();
for (int i = 0; i < blocks.Length; ++i) for (int i = 0; i < blocks.Length; ++i)
{ {
blockNames.Add(new GUIContent(blocks[i].name)); blockNames.Add(new GUIContent(blocks[i].name));
if (block == blocks[i]) if (block == blocks[i])
{ {
selectedIndex = i + 1; selectedIndex = i + 1;
} }
} }
selectedIndex = EditorGUI.Popup(position, selectedIndex, blockNames.ToArray()); selectedIndex = EditorGUI.Popup(position, selectedIndex, blockNames.ToArray());
if (selectedIndex == 0) if (selectedIndex == 0)
{ {
@ -508,7 +624,7 @@ namespace Fungus.EditorUtils
{ {
result = blocks[selectedIndex - 1]; result = blocks[selectedIndex - 1];
} }
return result; return result;
} }
@ -539,31 +655,31 @@ namespace Fungus.EditorUtils
// Dump command info // Dump command info
List<System.Type> menuTypes = EditorExtensions.FindDerivedTypes(typeof(Command)).ToList(); List<System.Type> menuTypes = EditorExtensions.FindDerivedTypes(typeof(Command)).ToList();
List<KeyValuePair<System.Type, CommandInfoAttribute>> filteredAttributes = GetFilteredCommandInfoAttribute(menuTypes); List<KeyValuePair<System.Type, CommandInfoAttribute>> filteredAttributes = GetFilteredCommandInfoAttribute(menuTypes);
filteredAttributes.Sort( CompareCommandAttributes ); filteredAttributes.Sort(CompareCommandAttributes);
// Build list of command categories // Build list of command categories
List<string> commandCategories = new List<string>(); List<string> commandCategories = new List<string>();
foreach(var keyPair in filteredAttributes) foreach (var keyPair in filteredAttributes)
{ {
CommandInfoAttribute info = keyPair.Value; CommandInfoAttribute info = keyPair.Value;
if (info.Category != "" && if (info.Category != "" &&
!commandCategories.Contains(info.Category)) !commandCategories.Contains(info.Category))
{ {
commandCategories.Add (info.Category); commandCategories.Add(info.Category);
} }
} }
commandCategories.Sort(); commandCategories.Sort();
// Output the commands in each category // Output the commands in each category
foreach (string category in commandCategories) foreach (string category in commandCategories)
{ {
string markdown = "# " + category + " commands # {#" + category.ToLower() + "_commands}\n\n"; string markdown = "# " + category + " commands # {#" + category.ToLower() + "_commands}\n\n";
markdown += "[TOC]\n"; markdown += "[TOC]\n";
foreach(var keyPair in filteredAttributes) foreach (var keyPair in filteredAttributes)
{ {
CommandInfoAttribute info = keyPair.Value; CommandInfoAttribute info = keyPair.Value;
if (info.Category == category || if (info.Category == category ||
info.Category == "" && category == "Scripting") info.Category == "" && category == "Scripting")
{ {
@ -573,9 +689,9 @@ namespace Fungus.EditorUtils
markdown += GetPropertyInfo(keyPair.Key); markdown += GetPropertyInfo(keyPair.Key);
} }
} }
string filePath = path + "/command_ref/" + category.ToLower() + "_commands.md"; string filePath = path + "/command_ref/" + category.ToLower() + "_commands.md";
Directory.CreateDirectory(Path.GetDirectoryName(filePath)); Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.WriteAllText(filePath, markdown); File.WriteAllText(filePath, markdown);
} }
@ -597,7 +713,7 @@ namespace Fungus.EditorUtils
} }
} }
eventHandlerCategories.Sort(); eventHandlerCategories.Sort();
// Output the commands in each category // Output the commands in each category
foreach (string category in eventHandlerCategories) foreach (string category in eventHandlerCategories)
{ {
@ -618,21 +734,21 @@ namespace Fungus.EditorUtils
markdown += GetPropertyInfo(type); markdown += GetPropertyInfo(type);
} }
} }
string filePath = path + "/command_ref/" + category.ToLower() + "_events.md"; string filePath = path + "/command_ref/" + category.ToLower() + "_events.md";
Directory.CreateDirectory(Path.GetDirectoryName(filePath)); Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.WriteAllText(filePath, markdown); File.WriteAllText(filePath, markdown);
} }
} }
protected static string GetPropertyInfo(System.Type type) protected static string GetPropertyInfo(System.Type type)
{ {
string markdown = ""; string markdown = "";
foreach(FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) foreach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{ {
TooltipAttribute attribute = (TooltipAttribute)Attribute.GetCustomAttribute(field, typeof(TooltipAttribute)); TooltipAttribute attribute = (TooltipAttribute)Attribute.GetCustomAttribute(field, typeof(TooltipAttribute));
if (attribute == null ) if (attribute == null)
{ {
continue; continue;
} }
@ -641,7 +757,7 @@ namespace Fungus.EditorUtils
string propertyName = Regex.Replace(field.Name, "(\\B[A-Z])", " $1"); string propertyName = Regex.Replace(field.Name, "(\\B[A-Z])", " $1");
if (propertyName.Length > 1) if (propertyName.Length > 1)
{ {
propertyName = propertyName.Substring(0,1).ToUpper() + propertyName.Substring(1); propertyName = propertyName.Substring(0, 1).ToUpper() + propertyName.Substring(1);
} }
else else
{ {
@ -665,40 +781,16 @@ namespace Fungus.EditorUtils
var flowchart = (Flowchart)block.GetFlowchart(); 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;
}
GenericMenu commandMenu = new GenericMenu(); GenericMenu commandMenu = new GenericMenu();
// Build menu list
List<KeyValuePair<System.Type, CommandInfoAttribute>> filteredAttributes = GetFilteredCommandInfoAttribute(commandTypes);
filteredAttributes.Sort( CompareCommandAttributes ); // Build menu list
var filteredAttributes = GetFilteredSupportedCommands(flowchart);
foreach(var keyPair in filteredAttributes) foreach (var keyPair in filteredAttributes)
{ {
// Skip command type if the Flowchart doesn't support it
if (!flowchart.IsCommandSupported(keyPair.Value))
{
continue;
}
AddCommandOperation commandOperation = new AddCommandOperation(); AddCommandOperation commandOperation = new AddCommandOperation();
commandOperation.block = block;
commandOperation.commandType = keyPair.Key; commandOperation.commandType = keyPair.Key;
commandOperation.index = index;
GUIContent menuItem; GUIContent menuItem;
if (keyPair.Value.Category == "") if (keyPair.Value.Category == "")
@ -707,7 +799,7 @@ namespace Fungus.EditorUtils
} }
else else
{ {
menuItem = new GUIContent (keyPair.Value.Category + "/" + keyPair.Value.CommandName); menuItem = new GUIContent(keyPair.Value.Category + "/" + keyPair.Value.CommandName);
} }
commandMenu.AddItem(menuItem, false, AddCommandCallback, commandOperation); commandMenu.AddItem(menuItem, false, AddCommandCallback, commandOperation);
@ -715,11 +807,22 @@ namespace Fungus.EditorUtils
commandMenu.ShowAsContext(); commandMenu.ShowAsContext();
} }
protected static List<KeyValuePair<System.Type,CommandInfoAttribute>> GetFilteredCommandInfoAttribute(List<System.Type> menuTypes) protected static List<KeyValuePair<System.Type, CommandInfoAttribute>> GetFilteredSupportedCommands(Flowchart flowchart)
{
List<KeyValuePair<System.Type, CommandInfoAttribute>> filteredAttributes = GetFilteredCommandInfoAttribute(commandTypes);
filteredAttributes.Sort(CompareCommandAttributes);
filteredAttributes = filteredAttributes.Where(x => flowchart.IsCommandSupported(x.Value)).ToList();
return filteredAttributes;
}
protected static List<KeyValuePair<System.Type, CommandInfoAttribute>> GetFilteredCommandInfoAttribute(List<System.Type> menuTypes)
{ {
Dictionary<string, KeyValuePair<System.Type, CommandInfoAttribute>> filteredAttributes = new Dictionary<string, KeyValuePair<System.Type, CommandInfoAttribute>>(); Dictionary<string, KeyValuePair<System.Type, CommandInfoAttribute>> filteredAttributes = new Dictionary<string, KeyValuePair<System.Type, CommandInfoAttribute>>();
foreach (System.Type type in menuTypes) foreach (System.Type type in menuTypes)
{ {
object[] attributes = type.GetCustomAttributes(false); object[] attributes = type.GetCustomAttributes(false);
@ -729,13 +832,13 @@ namespace Fungus.EditorUtils
if (infoAttr != null) if (infoAttr != null)
{ {
string dictionaryName = string.Format("{0}/{1}", infoAttr.Category, infoAttr.CommandName); string dictionaryName = string.Format("{0}/{1}", infoAttr.Category, infoAttr.CommandName);
int existingItemPriority = -1; int existingItemPriority = -1;
if (filteredAttributes.ContainsKey(dictionaryName)) if (filteredAttributes.ContainsKey(dictionaryName))
{ {
existingItemPriority = filteredAttributes[dictionaryName].Value.Priority; existingItemPriority = filteredAttributes[dictionaryName].Value.Priority;
} }
if (infoAttr.Priority > existingItemPriority) if (infoAttr.Priority > existingItemPriority)
{ {
KeyValuePair<System.Type, CommandInfoAttribute> keyValuePair = new KeyValuePair<System.Type, CommandInfoAttribute>(type, infoAttr); KeyValuePair<System.Type, CommandInfoAttribute> keyValuePair = new KeyValuePair<System.Type, CommandInfoAttribute>(type, infoAttr);
@ -744,14 +847,22 @@ namespace Fungus.EditorUtils
} }
} }
} }
return filteredAttributes.Values.ToList<KeyValuePair<System.Type,CommandInfoAttribute>>(); return filteredAttributes.Values.ToList<KeyValuePair<System.Type, CommandInfoAttribute>>();
} }
protected static void AddCommandCallback(object obj) //Used by GenericMenu Delegate
protected void AddCommandCallback(object obj)
{ {
AddCommandOperation commandOperation = obj as AddCommandOperation; AddCommandOperation commandOperation = obj as AddCommandOperation;
if (commandOperation != null)
var block = commandOperation.block; {
AddCommandCallback(commandOperation.commandType);
}
}
protected void AddCommandCallback(Type commandType)
{
var block = target as Block;
if (block == null) if (block == null)
{ {
return; return;
@ -759,9 +870,21 @@ namespace Fungus.EditorUtils
var flowchart = (Flowchart)block.GetFlowchart(); var flowchart = (Flowchart)block.GetFlowchart();
flowchart.ClearSelectedCommands(); // Use index of last selected command in list, or end of list if nothing selected.
int index = -1;
var newCommand = Undo.AddComponent(block.gameObject, commandOperation.commandType) as Command; 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); block.GetFlowchart().AddSelectedCommand(newCommand);
newCommand.ParentBlock = block; newCommand.ParentBlock = block;
newCommand.ItemId = flowchart.NextItemId(); newCommand.ItemId = flowchart.NextItemId();
@ -770,9 +893,9 @@ namespace Fungus.EditorUtils
newCommand.OnCommandAdded(block); newCommand.OnCommandAdded(block);
Undo.RecordObject(block, "Set command type"); Undo.RecordObject(block, "Set command type");
if (commandOperation.index < block.CommandList.Count - 1) if (index < block.CommandList.Count - 1)
{ {
block.CommandList.Insert(commandOperation.index, newCommand); block.CommandList.Insert(index, newCommand);
} }
else else
{ {
@ -781,6 +904,10 @@ namespace Fungus.EditorUtils
// Because this is an async call, we need to force prefab instances to record changes // Because this is an async call, we need to force prefab instances to record changes
PrefabUtility.RecordPrefabInstancePropertyModifications(block); PrefabUtility.RecordPrefabInstancePropertyModifications(block);
flowchart.ClearSelectedCommands();
commandTextFieldContents = string.Empty;
} }
public virtual void ShowContextMenu() public virtual void ShowContextMenu()
@ -792,7 +919,7 @@ namespace Fungus.EditorUtils
{ {
return; return;
} }
bool showCut = false; bool showCut = false;
bool showCopy = false; bool showCopy = false;
bool showDelete = false; bool showDelete = false;
@ -808,53 +935,53 @@ namespace Fungus.EditorUtils
{ {
showPlay = true; showPlay = true;
} }
} }
CommandCopyBuffer commandCopyBuffer = CommandCopyBuffer.GetInstance(); CommandCopyBuffer commandCopyBuffer = CommandCopyBuffer.GetInstance();
if (commandCopyBuffer.HasCommands()) if (commandCopyBuffer.HasCommands())
{ {
showPaste = true; showPaste = true;
} }
GenericMenu commandMenu = new GenericMenu(); GenericMenu commandMenu = new GenericMenu();
if (showCut) if (showCut)
{ {
commandMenu.AddItem (new GUIContent ("Cut"), false, Cut); commandMenu.AddItem(new GUIContent("Cut"), false, Cut);
} }
else else
{ {
commandMenu.AddDisabledItem(new GUIContent ("Cut")); commandMenu.AddDisabledItem(new GUIContent("Cut"));
} }
if (showCopy) if (showCopy)
{ {
commandMenu.AddItem (new GUIContent ("Copy"), false, Copy); commandMenu.AddItem(new GUIContent("Copy"), false, Copy);
} }
else else
{ {
commandMenu.AddDisabledItem(new GUIContent ("Copy")); commandMenu.AddDisabledItem(new GUIContent("Copy"));
} }
if (showPaste) if (showPaste)
{ {
commandMenu.AddItem (new GUIContent ("Paste"), false, Paste); commandMenu.AddItem(new GUIContent("Paste"), false, Paste);
} }
else else
{ {
commandMenu.AddDisabledItem(new GUIContent ("Paste")); commandMenu.AddDisabledItem(new GUIContent("Paste"));
} }
if (showDelete) if (showDelete)
{ {
commandMenu.AddItem (new GUIContent ("Delete"), false, Delete); commandMenu.AddItem(new GUIContent("Delete"), false, Delete);
} }
else else
{ {
commandMenu.AddDisabledItem(new GUIContent ("Delete")); commandMenu.AddDisabledItem(new GUIContent("Delete"));
} }
if (showPlay) if (showPlay)
@ -864,13 +991,13 @@ namespace Fungus.EditorUtils
} }
commandMenu.AddSeparator(""); commandMenu.AddSeparator("");
commandMenu.AddItem (new GUIContent ("Select All"), false, SelectAll); commandMenu.AddItem(new GUIContent("Select All"), false, SelectAll);
commandMenu.AddItem (new GUIContent ("Select None"), false, SelectNone); commandMenu.AddItem(new GUIContent("Select None"), false, SelectNone);
commandMenu.ShowAsContext(); commandMenu.ShowAsContext();
} }
protected void SelectAll() protected void SelectAll()
{ {
var block = target as Block; var block = target as Block;
@ -881,7 +1008,7 @@ namespace Fungus.EditorUtils
{ {
return; return;
} }
flowchart.ClearSelectedCommands(); flowchart.ClearSelectedCommands();
Undo.RecordObject(flowchart, "Select All"); Undo.RecordObject(flowchart, "Select All");
foreach (Command command in flowchart.SelectedBlock.CommandList) foreach (Command command in flowchart.SelectedBlock.CommandList)
@ -891,7 +1018,7 @@ namespace Fungus.EditorUtils
Repaint(); Repaint();
} }
protected void SelectNone() protected void SelectNone()
{ {
var block = target as Block; var block = target as Block;
@ -902,19 +1029,19 @@ namespace Fungus.EditorUtils
{ {
return; return;
} }
Undo.RecordObject(flowchart, "Select None"); Undo.RecordObject(flowchart, "Select None");
flowchart.ClearSelectedCommands(); flowchart.ClearSelectedCommands();
Repaint(); Repaint();
} }
protected void Cut() protected void Cut()
{ {
Copy(); Copy();
Delete(); Delete();
} }
protected void Copy() protected void Copy()
{ {
var block = target as Block; var block = target as Block;
@ -925,7 +1052,7 @@ namespace Fungus.EditorUtils
{ {
return; return;
} }
CommandCopyBuffer commandCopyBuffer = CommandCopyBuffer.GetInstance(); CommandCopyBuffer commandCopyBuffer = CommandCopyBuffer.GetInstance();
commandCopyBuffer.Clear(); commandCopyBuffer.Clear();
@ -957,7 +1084,7 @@ namespace Fungus.EditorUtils
} }
} }
} }
protected void Paste() protected void Paste()
{ {
var block = target as Block; var block = target as Block;
@ -968,9 +1095,9 @@ namespace Fungus.EditorUtils
{ {
return; return;
} }
CommandCopyBuffer commandCopyBuffer = CommandCopyBuffer.GetInstance(); CommandCopyBuffer commandCopyBuffer = CommandCopyBuffer.GetInstance();
// Find where to paste commands in block (either at end or after last selected command) // Find where to paste commands in block (either at end or after last selected command)
int pasteIndex = flowchart.SelectedBlock.CommandList.Count; int pasteIndex = flowchart.SelectedBlock.CommandList.Count;
if (flowchart.SelectedCommands.Count > 0) if (flowchart.SelectedCommands.Count > 0)
@ -978,7 +1105,7 @@ namespace Fungus.EditorUtils
for (int i = 0; i < flowchart.SelectedBlock.CommandList.Count; ++i) for (int i = 0; i < flowchart.SelectedBlock.CommandList.Count; ++i)
{ {
Command command = flowchart.SelectedBlock.CommandList[i]; Command command = flowchart.SelectedBlock.CommandList[i];
foreach (Command selectedCommand in flowchart.SelectedCommands) foreach (Command selectedCommand in flowchart.SelectedCommands)
{ {
if (command == selectedCommand) if (command == selectedCommand)
@ -988,7 +1115,7 @@ namespace Fungus.EditorUtils
} }
} }
} }
foreach (Command command in commandCopyBuffer.GetCommands()) foreach (Command command in commandCopyBuffer.GetCommands())
{ {
// Using the Editor copy / paste functionality instead instead of reflection // Using the Editor copy / paste functionality instead instead of reflection
@ -1013,10 +1140,10 @@ namespace Fungus.EditorUtils
// Because this is an async call, we need to force prefab instances to record changes // Because this is an async call, we need to force prefab instances to record changes
PrefabUtility.RecordPrefabInstancePropertyModifications(block); PrefabUtility.RecordPrefabInstancePropertyModifications(block);
Repaint(); Repaint();
} }
protected void Delete() protected void Delete()
{ {
var block = target as Block; var block = target as Block;
@ -1061,7 +1188,7 @@ namespace Fungus.EditorUtils
Repaint(); Repaint();
} }
protected void PlayCommand() protected void PlayCommand()
{ {
var targetBlock = target as Block; var targetBlock = target as Block;
@ -1103,7 +1230,7 @@ namespace Fungus.EditorUtils
{ {
var block = target as Block; var block = target as Block;
var flowchart = (Flowchart)block.GetFlowchart(); var flowchart = (Flowchart)block.GetFlowchart();
int firstSelectedIndex = flowchart.SelectedBlock.CommandList.Count; int firstSelectedIndex = flowchart.SelectedBlock.CommandList.Count;
bool firstSelectedCommandFound = false; bool firstSelectedCommandFound = false;
if (flowchart.SelectedCommands.Count > 0) if (flowchart.SelectedCommands.Count > 0)
@ -1111,7 +1238,7 @@ namespace Fungus.EditorUtils
for (int i = 0; i < flowchart.SelectedBlock.CommandList.Count; i++) for (int i = 0; i < flowchart.SelectedBlock.CommandList.Count; i++)
{ {
Command commandInBlock = flowchart.SelectedBlock.CommandList[i]; Command commandInBlock = flowchart.SelectedBlock.CommandList[i];
foreach (Command selectedCommand in flowchart.SelectedCommands) foreach (Command selectedCommand in flowchart.SelectedCommands)
{ {
if (commandInBlock == selectedCommand) if (commandInBlock == selectedCommand)
@ -1133,9 +1260,9 @@ namespace Fungus.EditorUtils
if (firstSelectedIndex > 0) if (firstSelectedIndex > 0)
{ {
flowchart.ClearSelectedCommands(); flowchart.ClearSelectedCommands();
flowchart.AddSelectedCommand(flowchart.SelectedBlock.CommandList[firstSelectedIndex-1]); flowchart.AddSelectedCommand(flowchart.SelectedBlock.CommandList[firstSelectedIndex - 1]);
} }
Repaint(); Repaint();
} }
@ -1143,14 +1270,14 @@ namespace Fungus.EditorUtils
{ {
var block = target as Block; var block = target as Block;
var flowchart = (Flowchart)block.GetFlowchart(); var flowchart = (Flowchart)block.GetFlowchart();
int lastSelectedIndex = -1; int lastSelectedIndex = -1;
if (flowchart.SelectedCommands.Count > 0) if (flowchart.SelectedCommands.Count > 0)
{ {
for (int i = 0; i < flowchart.SelectedBlock.CommandList.Count; i++) for (int i = 0; i < flowchart.SelectedBlock.CommandList.Count; i++)
{ {
Command commandInBlock = flowchart.SelectedBlock.CommandList[i]; Command commandInBlock = flowchart.SelectedBlock.CommandList[i];
foreach (Command selectedCommand in flowchart.SelectedCommands) foreach (Command selectedCommand in flowchart.SelectedCommands)
{ {
if (commandInBlock == selectedCommand) if (commandInBlock == selectedCommand)
@ -1160,13 +1287,13 @@ namespace Fungus.EditorUtils
} }
} }
} }
if (lastSelectedIndex < flowchart.SelectedBlock.CommandList.Count-1) if (lastSelectedIndex < flowchart.SelectedBlock.CommandList.Count - 1)
{ {
flowchart.ClearSelectedCommands(); flowchart.ClearSelectedCommands();
flowchart.AddSelectedCommand(flowchart.SelectedBlock.CommandList[lastSelectedIndex+1]); flowchart.AddSelectedCommand(flowchart.SelectedBlock.CommandList[lastSelectedIndex + 1]);
} }
Repaint(); Repaint();
} }
} }
} }
Loading…
Cancel
Save