From 0a42c8c48d3ff9184956f19968365ee5619e07fd Mon Sep 17 00:00:00 2001 From: desktop-maesty/steve Date: Thu, 13 Jul 2017 19:32:46 +1000 Subject: [PATCH 1/9] Started refactor and work on textfield for typing command name in block editor --- Assets/Fungus/Scripts/Editor/BlockEditor.cs | 249 ++++++++++---------- 1 file changed, 130 insertions(+), 119 deletions(-) diff --git a/Assets/Fungus/Scripts/Editor/BlockEditor.cs b/Assets/Fungus/Scripts/Editor/BlockEditor.cs index 77dd47d7..ae7f488d 100644 --- a/Assets/Fungus/Scripts/Editor/BlockEditor.cs +++ b/Assets/Fungus/Scripts/Editor/BlockEditor.cs @@ -15,8 +15,8 @@ using System.Reflection; namespace Fungus.EditorUtils { - [CustomEditor (typeof(Block))] - public class BlockEditor : Editor + [CustomEditor(typeof(Block))] + public class BlockEditor : Editor { protected class SetEventHandlerOperation { @@ -38,6 +38,7 @@ namespace Fungus.EditorUtils protected Texture2D addIcon; protected Texture2D duplicateIcon; protected Texture2D deleteIcon; + protected string commandTextFieldContents = string.Empty; static List commandTypes; static List eventHandlerTypes; @@ -109,7 +110,7 @@ namespace Fungus.EditorUtils var block = target as Block; SerializedProperty commandListProperty = serializedObject.FindProperty("commandList"); - + if (block == flowchart.SelectedBlock) { // Custom tinting @@ -130,7 +131,7 @@ namespace Fungus.EditorUtils EditorGUILayout.PropertyField(descriptionProp); DrawEventHandlerGUI(flowchart); - + block.UpdateIndentLevels(); // Make sure each command has a reference to its parent block @@ -146,7 +147,7 @@ namespace Fungus.EditorUtils ReorderableListGUI.Title("Commands"); CommandListAdaptor adaptor = new CommandListAdaptor(commandListProperty, 0); adaptor.nodeRect = block._NodeRect; - + ReorderableListFlags flags = ReorderableListFlags.HideAddButton | ReorderableListFlags.HideRemoveButtons | ReorderableListFlags.DisableContextMenu; if (block.CommandList.Count == 0) @@ -170,7 +171,7 @@ namespace Fungus.EditorUtils if (GUIUtility.keyboardControl == 0) //Only call keyboard shortcuts when not typing in a text field { Event e = Event.current; - + // Copy keyboard shortcut if (e.type == EventType.ValidateCommand && e.commandName == "Copy") { @@ -180,12 +181,12 @@ namespace Fungus.EditorUtils } } - if (e.type == EventType.ExecuteCommand && e.commandName == "Copy") + if (e.type == EventType.ExecuteCommand && e.commandName == "Copy") { actionList.Add(Copy); e.Use(); } - + // Cut keyboard shortcut if (e.type == EventType.ValidateCommand && e.commandName == "Cut") { @@ -200,7 +201,7 @@ namespace Fungus.EditorUtils actionList.Add(Cut); e.Use(); } - + // Paste keyboard shortcut if (e.type == EventType.ValidateCommand && e.commandName == "Paste") { @@ -211,12 +212,12 @@ namespace Fungus.EditorUtils } } - if (e.type == EventType.ExecuteCommand && e.commandName == "Paste") + if (e.type == EventType.ExecuteCommand && e.commandName == "Paste") { actionList.Add(Paste); e.Use(); } - + // Duplicate keyboard shortcut if (e.type == EventType.ValidateCommand && e.commandName == "Duplicate") { @@ -226,13 +227,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(Paste); e.Use(); } - + // Delete keyboard shortcut if (e.type == EventType.ValidateCommand && e.commandName == "Delete") { @@ -242,23 +243,23 @@ namespace Fungus.EditorUtils } } - if (e.type == EventType.ExecuteCommand && e.commandName == "Delete") + if (e.type == EventType.ExecuteCommand && e.commandName == "Delete") { actionList.Add(Delete); e.Use(); } - + // SelectAll keyboard shortcut if (e.type == EventType.ValidateCommand && e.commandName == "SelectAll") { e.Use(); } - - if (e.type == EventType.ExecuteCommand && e.commandName == "SelectAll") + + if (e.type == EventType.ExecuteCommand && e.commandName == "SelectAll") { actionList.Add(SelectAll); e.Use(); - } + } } } @@ -279,7 +280,7 @@ namespace Fungus.EditorUtils public virtual void DrawButtonToolbar() { GUILayout.BeginHorizontal(); - + // Previous Command if ((Event.current.type == EventType.keyDown) && (Event.current.keyCode == KeyCode.PageUp)) { @@ -299,34 +300,36 @@ namespace Fungus.EditorUtils { SelectPrevious(); } - + // Down Button if (GUILayout.Button(downIcon)) { SelectNext(); } - + GUILayout.FlexibleSpace(); - + + commandTextFieldContents = GUILayout.TextField(commandTextFieldContents, GUILayout.MinWidth(20), GUILayout.MaxWidth(200)); + // Add Button if (GUILayout.Button(addIcon)) { ShowCommandMenu(); } - + // Duplicate Button if (GUILayout.Button(duplicateIcon)) { Copy(); Paste(); } - + // Delete Button if (GUILayout.Button(deleteIcon)) { Delete(); } - + GUILayout.EndHorizontal(); } @@ -358,7 +361,7 @@ namespace Fungus.EditorUtils SetEventHandlerOperation noneOperation = new SetEventHandlerOperation(); noneOperation.block = block; noneOperation.eventHandlerType = null; - + GenericMenu eventHandlerMenu = new GenericMenu(); eventHandlerMenu.AddItem(new GUIContent("None"), false, OnSelectEventHandler, noneOperation); @@ -372,7 +375,7 @@ namespace Fungus.EditorUtils SetEventHandlerOperation operation = new SetEventHandlerOperation(); operation.block = block; operation.eventHandlerType = type; - + eventHandlerMenu.AddItem(new GUIContent(info.EventHandlerName), false, OnSelectEventHandler, operation); } } @@ -380,10 +383,10 @@ namespace Fungus.EditorUtils // Add event handlers with a category afterwards foreach (System.Type type in eventHandlerTypes) { - EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(type); - if (info != null && + EventHandlerInfoAttribute info = EventHandlerEditor.GetEventHandlerInfo(type); + if (info != null && info.Category.Length > 0) - { + { SetEventHandlerOperation operation = new SetEventHandlerOperation(); operation.block = block; operation.eventHandlerType = type; @@ -444,23 +447,23 @@ namespace Fungus.EditorUtils } var block = property.objectReferenceValue as Block; - + // Build dictionary of child blocks List blockNames = new List(); - + int selectedIndex = 0; blockNames.Add(nullLabel); var blocks = flowchart.GetComponents(); for (int i = 0; i < blocks.Length; ++i) { blockNames.Add(new GUIContent(blocks[i].BlockName)); - + if (block == blocks[i]) { selectedIndex = i + 1; } } - + selectedIndex = EditorGUILayout.Popup(label, selectedIndex, blockNames.ToArray()); if (selectedIndex == 0) { @@ -470,7 +473,7 @@ namespace Fungus.EditorUtils { block = blocks[selectedIndex - 1]; } - + property.objectReferenceValue = block; } @@ -480,25 +483,25 @@ namespace Fungus.EditorUtils { return null; } - + Block result = block; - + // Build dictionary of child blocks List blockNames = new List(); - + int selectedIndex = 0; blockNames.Add(nullLabel); Block[] blocks = flowchart.GetComponents(); for (int i = 0; i < blocks.Length; ++i) { blockNames.Add(new GUIContent(blocks[i].name)); - + if (block == blocks[i]) { selectedIndex = i + 1; } } - + selectedIndex = EditorGUI.Popup(position, selectedIndex, blockNames.ToArray()); if (selectedIndex == 0) { @@ -508,7 +511,7 @@ namespace Fungus.EditorUtils { result = blocks[selectedIndex - 1]; } - + return result; } @@ -539,31 +542,31 @@ namespace Fungus.EditorUtils // Dump command info List menuTypes = EditorExtensions.FindDerivedTypes(typeof(Command)).ToList(); List> filteredAttributes = GetFilteredCommandInfoAttribute(menuTypes); - filteredAttributes.Sort( CompareCommandAttributes ); - + filteredAttributes.Sort(CompareCommandAttributes); + // Build list of command categories List commandCategories = new List(); - foreach(var keyPair in filteredAttributes) + foreach (var keyPair in filteredAttributes) { CommandInfoAttribute info = keyPair.Value; if (info.Category != "" && !commandCategories.Contains(info.Category)) { - commandCategories.Add (info.Category); + commandCategories.Add(info.Category); } } commandCategories.Sort(); - + // Output the commands in each category foreach (string category in commandCategories) { string markdown = "# " + category + " commands # {#" + category.ToLower() + "_commands}\n\n"; markdown += "[TOC]\n"; - foreach(var keyPair in filteredAttributes) + foreach (var keyPair in filteredAttributes) { CommandInfoAttribute info = keyPair.Value; - + if (info.Category == category || info.Category == "" && category == "Scripting") { @@ -573,9 +576,9 @@ namespace Fungus.EditorUtils markdown += GetPropertyInfo(keyPair.Key); } } - + string filePath = path + "/command_ref/" + category.ToLower() + "_commands.md"; - + Directory.CreateDirectory(Path.GetDirectoryName(filePath)); File.WriteAllText(filePath, markdown); } @@ -597,7 +600,7 @@ namespace Fungus.EditorUtils } } eventHandlerCategories.Sort(); - + // Output the commands in each category foreach (string category in eventHandlerCategories) { @@ -618,21 +621,21 @@ namespace Fungus.EditorUtils markdown += GetPropertyInfo(type); } } - + string filePath = path + "/command_ref/" + category.ToLower() + "_events.md"; - + Directory.CreateDirectory(Path.GetDirectoryName(filePath)); File.WriteAllText(filePath, markdown); - } + } } protected static string GetPropertyInfo(System.Type type) { 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)); - if (attribute == null ) + if (attribute == null) { continue; } @@ -641,7 +644,7 @@ namespace Fungus.EditorUtils string propertyName = Regex.Replace(field.Name, "(\\B[A-Z])", " $1"); if (propertyName.Length > 1) { - propertyName = propertyName.Substring(0,1).ToUpper() + propertyName.Substring(1); + propertyName = propertyName.Substring(0, 1).ToUpper() + propertyName.Substring(1); } else { @@ -680,22 +683,22 @@ namespace Fungus.EditorUtils } GenericMenu commandMenu = new GenericMenu(); - + // Build menu list List> filteredAttributes = GetFilteredCommandInfoAttribute(commandTypes); - filteredAttributes.Sort( CompareCommandAttributes ); + filteredAttributes.Sort(CompareCommandAttributes); - 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(); - + commandOperation.block = block; commandOperation.commandType = keyPair.Key; commandOperation.index = index; @@ -707,7 +710,7 @@ namespace Fungus.EditorUtils } 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); @@ -715,11 +718,11 @@ namespace Fungus.EditorUtils commandMenu.ShowAsContext(); } - - protected static List> GetFilteredCommandInfoAttribute(List menuTypes) + + protected static List> GetFilteredCommandInfoAttribute(List menuTypes) { Dictionary> filteredAttributes = new Dictionary>(); - + foreach (System.Type type in menuTypes) { object[] attributes = type.GetCustomAttributes(false); @@ -729,13 +732,13 @@ namespace Fungus.EditorUtils if (infoAttr != null) { string dictionaryName = string.Format("{0}/{1}", infoAttr.Category, infoAttr.CommandName); - + int existingItemPriority = -1; if (filteredAttributes.ContainsKey(dictionaryName)) { existingItemPriority = filteredAttributes[dictionaryName].Value.Priority; } - + if (infoAttr.Priority > existingItemPriority) { KeyValuePair keyValuePair = new KeyValuePair(type, infoAttr); @@ -744,13 +747,21 @@ namespace Fungus.EditorUtils } } } - return filteredAttributes.Values.ToList>(); + return filteredAttributes.Values.ToList>(); } - + + //Used by GenericMenu Delegate protected static void AddCommandCallback(object obj) { AddCommandOperation commandOperation = obj as AddCommandOperation; - + if (commandOperation != null) + { + AddCommandCallback(commandOperation); + } + } + + protected static void AddCommandCallback(AddCommandOperation commandOperation) + { var block = commandOperation.block; if (block == null) { @@ -760,7 +771,7 @@ namespace Fungus.EditorUtils var flowchart = (Flowchart)block.GetFlowchart(); flowchart.ClearSelectedCommands(); - + var newCommand = Undo.AddComponent(block.gameObject, commandOperation.commandType) as Command; block.GetFlowchart().AddSelectedCommand(newCommand); newCommand.ParentBlock = block; @@ -792,7 +803,7 @@ namespace Fungus.EditorUtils { return; } - + bool showCut = false; bool showCopy = false; bool showDelete = false; @@ -808,53 +819,53 @@ namespace Fungus.EditorUtils { showPlay = true; } - } - - - + } + + + CommandCopyBuffer commandCopyBuffer = CommandCopyBuffer.GetInstance(); - + if (commandCopyBuffer.HasCommands()) { showPaste = true; } - + GenericMenu commandMenu = new GenericMenu(); - + if (showCut) { - commandMenu.AddItem (new GUIContent ("Cut"), false, Cut); + commandMenu.AddItem(new GUIContent("Cut"), false, Cut); } else { - commandMenu.AddDisabledItem(new GUIContent ("Cut")); + commandMenu.AddDisabledItem(new GUIContent("Cut")); } - + if (showCopy) { - commandMenu.AddItem (new GUIContent ("Copy"), false, Copy); + commandMenu.AddItem(new GUIContent("Copy"), false, Copy); } else { - commandMenu.AddDisabledItem(new GUIContent ("Copy")); + commandMenu.AddDisabledItem(new GUIContent("Copy")); } - + if (showPaste) { - commandMenu.AddItem (new GUIContent ("Paste"), false, Paste); + commandMenu.AddItem(new GUIContent("Paste"), false, Paste); } else { - commandMenu.AddDisabledItem(new GUIContent ("Paste")); + commandMenu.AddDisabledItem(new GUIContent("Paste")); } - + if (showDelete) { - commandMenu.AddItem (new GUIContent ("Delete"), false, Delete); + commandMenu.AddItem(new GUIContent("Delete"), false, Delete); } else { - commandMenu.AddDisabledItem(new GUIContent ("Delete")); + commandMenu.AddDisabledItem(new GUIContent("Delete")); } if (showPlay) @@ -864,13 +875,13 @@ namespace Fungus.EditorUtils } commandMenu.AddSeparator(""); - - commandMenu.AddItem (new GUIContent ("Select All"), false, SelectAll); - commandMenu.AddItem (new GUIContent ("Select None"), false, SelectNone); + + commandMenu.AddItem(new GUIContent("Select All"), false, SelectAll); + commandMenu.AddItem(new GUIContent("Select None"), false, SelectNone); commandMenu.ShowAsContext(); } - + protected void SelectAll() { var block = target as Block; @@ -881,7 +892,7 @@ namespace Fungus.EditorUtils { return; } - + flowchart.ClearSelectedCommands(); Undo.RecordObject(flowchart, "Select All"); foreach (Command command in flowchart.SelectedBlock.CommandList) @@ -891,7 +902,7 @@ namespace Fungus.EditorUtils Repaint(); } - + protected void SelectNone() { var block = target as Block; @@ -902,19 +913,19 @@ namespace Fungus.EditorUtils { return; } - + Undo.RecordObject(flowchart, "Select None"); flowchart.ClearSelectedCommands(); Repaint(); } - + protected void Cut() { Copy(); Delete(); } - + protected void Copy() { var block = target as Block; @@ -925,7 +936,7 @@ namespace Fungus.EditorUtils { return; } - + CommandCopyBuffer commandCopyBuffer = CommandCopyBuffer.GetInstance(); commandCopyBuffer.Clear(); @@ -957,7 +968,7 @@ namespace Fungus.EditorUtils } } } - + protected void Paste() { var block = target as Block; @@ -968,9 +979,9 @@ namespace Fungus.EditorUtils { return; } - + CommandCopyBuffer commandCopyBuffer = CommandCopyBuffer.GetInstance(); - + // Find where to paste commands in block (either at end or after last selected command) int pasteIndex = flowchart.SelectedBlock.CommandList.Count; if (flowchart.SelectedCommands.Count > 0) @@ -978,7 +989,7 @@ namespace Fungus.EditorUtils for (int i = 0; i < flowchart.SelectedBlock.CommandList.Count; ++i) { Command command = flowchart.SelectedBlock.CommandList[i]; - + foreach (Command selectedCommand in flowchart.SelectedCommands) { if (command == selectedCommand) @@ -988,7 +999,7 @@ namespace Fungus.EditorUtils } } } - + foreach (Command command in commandCopyBuffer.GetCommands()) { // Using the Editor copy / paste functionality instead instead of reflection @@ -1013,10 +1024,10 @@ namespace Fungus.EditorUtils // Because this is an async call, we need to force prefab instances to record changes PrefabUtility.RecordPrefabInstancePropertyModifications(block); - + Repaint(); } - + protected void Delete() { var block = target as Block; @@ -1061,7 +1072,7 @@ namespace Fungus.EditorUtils Repaint(); } - + protected void PlayCommand() { var targetBlock = target as Block; @@ -1103,7 +1114,7 @@ namespace Fungus.EditorUtils { var block = target as Block; var flowchart = (Flowchart)block.GetFlowchart(); - + int firstSelectedIndex = flowchart.SelectedBlock.CommandList.Count; bool firstSelectedCommandFound = false; if (flowchart.SelectedCommands.Count > 0) @@ -1111,7 +1122,7 @@ namespace Fungus.EditorUtils for (int i = 0; i < flowchart.SelectedBlock.CommandList.Count; i++) { Command commandInBlock = flowchart.SelectedBlock.CommandList[i]; - + foreach (Command selectedCommand in flowchart.SelectedCommands) { if (commandInBlock == selectedCommand) @@ -1133,9 +1144,9 @@ namespace Fungus.EditorUtils if (firstSelectedIndex > 0) { flowchart.ClearSelectedCommands(); - flowchart.AddSelectedCommand(flowchart.SelectedBlock.CommandList[firstSelectedIndex-1]); + flowchart.AddSelectedCommand(flowchart.SelectedBlock.CommandList[firstSelectedIndex - 1]); } - + Repaint(); } @@ -1143,14 +1154,14 @@ namespace Fungus.EditorUtils { var block = target as Block; var flowchart = (Flowchart)block.GetFlowchart(); - + int lastSelectedIndex = -1; if (flowchart.SelectedCommands.Count > 0) { for (int i = 0; i < flowchart.SelectedBlock.CommandList.Count; i++) { Command commandInBlock = flowchart.SelectedBlock.CommandList[i]; - + foreach (Command selectedCommand in flowchart.SelectedCommands) { if (commandInBlock == selectedCommand) @@ -1160,13 +1171,13 @@ namespace Fungus.EditorUtils } } } - if (lastSelectedIndex < flowchart.SelectedBlock.CommandList.Count-1) + if (lastSelectedIndex < flowchart.SelectedBlock.CommandList.Count - 1) { flowchart.ClearSelectedCommands(); - flowchart.AddSelectedCommand(flowchart.SelectedBlock.CommandList[lastSelectedIndex+1]); + flowchart.AddSelectedCommand(flowchart.SelectedBlock.CommandList[lastSelectedIndex + 1]); } - + Repaint(); } - } + } } \ No newline at end of file From 285b2294461d81fd0501254f329a704cf59f81b5 Mon Sep 17 00:00:00 2001 From: desktop-maesty/steve Date: Thu, 13 Jul 2017 19:57:26 +1000 Subject: [PATCH 2/9] Show results of partial match -requires case independance and a way to actually confirm it --- Assets/Fungus/Scripts/Editor/BlockEditor.cs | 58 +++++++++++++++++---- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/Assets/Fungus/Scripts/Editor/BlockEditor.cs b/Assets/Fungus/Scripts/Editor/BlockEditor.cs index ae7f488d..1d0f7af0 100644 --- a/Assets/Fungus/Scripts/Editor/BlockEditor.cs +++ b/Assets/Fungus/Scripts/Editor/BlockEditor.cs @@ -331,6 +331,37 @@ namespace Fungus.EditorUtils } GUILayout.EndHorizontal(); + + if(!string.IsNullOrEmpty(commandTextFieldContents)) + ShowPartialMatches(); + + } + + private void ShowPartialMatches() + { + var block = target as Block; + + var flowchart = (Flowchart)block.GetFlowchart(); + + var filteredAttributes = GetFilteredSupportedCommands(flowchart); + + filteredAttributes = filteredAttributes.Where((x) => { + return x.Value.Category.Contains(commandTextFieldContents) || x.Value.CommandName.Contains(commandTextFieldContents); + }).ToList(); + + if (filteredAttributes == null || filteredAttributes.Count == 0) + return; + + //show results + GUILayout.Space(5); + + GUILayout.BeginHorizontal(); + + GUILayout.TextArea(string.Join("\n", filteredAttributes.Select(x => x.Value.Category + "/" + x.Value.CommandName).ToArray())); + + GUILayout.EndHorizontal(); + + GUILayout.Space(5); } protected virtual void DrawEventHandlerGUI(Flowchart flowchart) @@ -685,18 +716,10 @@ namespace Fungus.EditorUtils GenericMenu commandMenu = new GenericMenu(); // Build menu list - List> filteredAttributes = GetFilteredCommandInfoAttribute(commandTypes); - - filteredAttributes.Sort(CompareCommandAttributes); + var filteredAttributes = GetFilteredSupportedCommands(flowchart); 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(); commandOperation.block = block; @@ -719,6 +742,17 @@ namespace Fungus.EditorUtils commandMenu.ShowAsContext(); } + protected static List> GetFilteredSupportedCommands(Flowchart flowchart) + { + List> filteredAttributes = GetFilteredCommandInfoAttribute(commandTypes); + + filteredAttributes.Sort(CompareCommandAttributes); + + filteredAttributes = filteredAttributes.Where(x => flowchart.IsCommandSupported(x.Value)).ToList(); + + return filteredAttributes; + } + protected static List> GetFilteredCommandInfoAttribute(List menuTypes) { Dictionary> filteredAttributes = new Dictionary>(); @@ -751,7 +785,7 @@ namespace Fungus.EditorUtils } //Used by GenericMenu Delegate - protected static void AddCommandCallback(object obj) + protected void AddCommandCallback(object obj) { AddCommandOperation commandOperation = obj as AddCommandOperation; if (commandOperation != null) @@ -760,7 +794,7 @@ namespace Fungus.EditorUtils } } - protected static void AddCommandCallback(AddCommandOperation commandOperation) + protected void AddCommandCallback(AddCommandOperation commandOperation) { var block = commandOperation.block; if (block == null) @@ -792,6 +826,8 @@ namespace Fungus.EditorUtils // Because this is an async call, we need to force prefab instances to record changes PrefabUtility.RecordPrefabInstancePropertyModifications(block); + + commandTextFieldContents = string.Empty; } public virtual void ShowContextMenu() From a2d1c7392e4b34d90888d2ca7309458d8a50d747 Mon Sep 17 00:00:00 2001 From: desktop-maesty/steve Date: Fri, 14 Jul 2017 17:55:58 +1000 Subject: [PATCH 3/9] Can now filter more intelligently -Can add the command by hitting enter if there is exactly 1 of them --- Assets/Fungus/Scripts/Editor/BlockEditor.cs | 86 ++++++++++++++------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/Assets/Fungus/Scripts/Editor/BlockEditor.cs b/Assets/Fungus/Scripts/Editor/BlockEditor.cs index 1d0f7af0..28c89bdb 100644 --- a/Assets/Fungus/Scripts/Editor/BlockEditor.cs +++ b/Assets/Fungus/Scripts/Editor/BlockEditor.cs @@ -26,9 +26,8 @@ namespace Fungus.EditorUtils protected class AddCommandOperation { - public Block block; + //public Block block; public Type commandType; - public int index; } public static List actionList = new List(); @@ -331,12 +330,13 @@ namespace Fungus.EditorUtils } GUILayout.EndHorizontal(); - - if(!string.IsNullOrEmpty(commandTextFieldContents)) + + if (!string.IsNullOrEmpty(commandTextFieldContents)) ShowPartialMatches(); } + private static readonly char[] SPLIT_INPUT_ON = new char[] { ' ', '/', '\\' }; private void ShowPartialMatches() { var block = target as Block; @@ -345,9 +345,24 @@ namespace Fungus.EditorUtils var filteredAttributes = GetFilteredSupportedCommands(flowchart); - filteredAttributes = filteredAttributes.Where((x) => { - return x.Value.Category.Contains(commandTextFieldContents) || x.Value.CommandName.Contains(commandTextFieldContents); - }).ToList(); + var upperCommandText = commandTextFieldContents.ToUpper().Trim(); + var tokens = upperCommandText.Split(); + + 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); + + if (catAny && comAny) + return true; + else if (catAll || comAll) + return true; + + return false; + + }).ToList(); if (filteredAttributes == null || filteredAttributes.Count == 0) return; @@ -359,6 +374,17 @@ namespace Fungus.EditorUtils GUILayout.TextArea(string.Join("\n", filteredAttributes.Select(x => x.Value.Category + "/" + x.Value.CommandName).ToArray())); + // Previous Command + if ((Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter) && + filteredAttributes.Count == 1) + { + commandTextFieldContents = String.Empty; + //GUI.FocusControl("dummycontrol"); + //Event.current.Use(); + AddCommandCallback(filteredAttributes[0].Key); + + } + GUILayout.EndHorizontal(); GUILayout.Space(5); @@ -699,20 +725,6 @@ namespace Fungus.EditorUtils 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(); // Build menu list @@ -722,9 +734,9 @@ namespace Fungus.EditorUtils { AddCommandOperation commandOperation = new AddCommandOperation(); - commandOperation.block = block; + //commandOperation.block = block; commandOperation.commandType = keyPair.Key; - commandOperation.index = index; + //commandOperation.index = index; GUIContent menuItem; if (keyPair.Value.Category == "") @@ -790,13 +802,13 @@ namespace Fungus.EditorUtils AddCommandOperation commandOperation = obj as AddCommandOperation; if (commandOperation != null) { - AddCommandCallback(commandOperation); + AddCommandCallback(commandOperation.commandType); } } - protected void AddCommandCallback(AddCommandOperation commandOperation) + protected void AddCommandCallback(Type commandType) { - var block = commandOperation.block; + var block = target as Block; if (block == null) { return; @@ -804,9 +816,21 @@ namespace Fungus.EditorUtils 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; + 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, commandOperation.commandType) as Command; + var newCommand = Undo.AddComponent(block.gameObject, commandType) as Command; block.GetFlowchart().AddSelectedCommand(newCommand); newCommand.ParentBlock = block; newCommand.ItemId = flowchart.NextItemId(); @@ -815,9 +839,9 @@ namespace Fungus.EditorUtils newCommand.OnCommandAdded(block); 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 { @@ -827,6 +851,8 @@ namespace Fungus.EditorUtils // Because this is an async call, we need to force prefab instances to record changes PrefabUtility.RecordPrefabInstancePropertyModifications(block); + flowchart.ClearSelectedCommands(); + commandTextFieldContents = string.Empty; } From 08e7f8d3118ece5fd0b22dfb9236af360e5a0799 Mon Sep 17 00:00:00 2001 From: desktop-maesty/steve Date: Fri, 14 Jul 2017 20:32:28 +1000 Subject: [PATCH 4/9] Working command list preview and navigable via arrow keys and confirmable via Enter/Return --- Assets/Fungus/Scripts/Editor/BlockEditor.cs | 35 +++++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/Assets/Fungus/Scripts/Editor/BlockEditor.cs b/Assets/Fungus/Scripts/Editor/BlockEditor.cs index 28c89bdb..3bb24c98 100644 --- a/Assets/Fungus/Scripts/Editor/BlockEditor.cs +++ b/Assets/Fungus/Scripts/Editor/BlockEditor.cs @@ -38,6 +38,7 @@ namespace Fungus.EditorUtils protected Texture2D duplicateIcon; protected Texture2D deleteIcon; protected string commandTextFieldContents = string.Empty; + protected int filteredCommandPreviewSelectedItem = 0; static List commandTypes; static List eventHandlerTypes; @@ -280,6 +281,22 @@ namespace Fungus.EditorUtils { 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++; + } + } + // Previous Command if ((Event.current.type == EventType.keyDown) && (Event.current.keyCode == KeyCode.PageUp)) { @@ -351,7 +368,7 @@ namespace Fungus.EditorUtils filteredAttributes = filteredAttributes.Where((x) => { bool catAny = tokens.Any(x.Value.Category.ToUpper().Contains); - bool comAny = tokens.Any( x.Value.CommandName.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); @@ -372,17 +389,22 @@ namespace Fungus.EditorUtils GUILayout.BeginHorizontal(); - GUILayout.TextArea(string.Join("\n", filteredAttributes.Select(x => x.Value.Category + "/" + x.Value.CommandName).ToArray())); + filteredCommandPreviewSelectedItem = Mathf.Clamp(filteredCommandPreviewSelectedItem, 0, filteredAttributes.Count - 1); - // Previous Command + //GUILayout.TextArea(string.Join("\n", filteredAttributes.Select(x => x.Value.Category + "/" + x.Value.CommandName).ToArray())); + filteredCommandPreviewSelectedItem = GUILayout.SelectionGrid(filteredCommandPreviewSelectedItem, filteredAttributes.Select(x => x.Value.Category + "/" + x.Value.CommandName).ToArray(), 1); + + + + // if enter is hit then create that command and reset the preview window if ((Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter) && - filteredAttributes.Count == 1) + filteredAttributes.Count > filteredCommandPreviewSelectedItem) { commandTextFieldContents = String.Empty; //GUI.FocusControl("dummycontrol"); //Event.current.Use(); - AddCommandCallback(filteredAttributes[0].Key); - + AddCommandCallback(filteredAttributes[filteredCommandPreviewSelectedItem].Key); + filteredCommandPreviewSelectedItem = 0; } GUILayout.EndHorizontal(); @@ -852,6 +874,7 @@ namespace Fungus.EditorUtils PrefabUtility.RecordPrefabInstancePropertyModifications(block); flowchart.ClearSelectedCommands(); + flowchart.AddSelectedCommand(newCommand); commandTextFieldContents = string.Empty; } From c14363f3276e70130a258e6a2a78fc6007c04c25 Mon Sep 17 00:00:00 2001 From: desktop-maesty/steve Date: Fri, 14 Jul 2017 21:24:24 +1000 Subject: [PATCH 5/9] Comments added to clarify filter conditions on preview commands Limit the number of suggested commands and show elipsis if there are more than that --- Assets/Fungus/Scripts/Editor/BlockEditor.cs | 29 ++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/Assets/Fungus/Scripts/Editor/BlockEditor.cs b/Assets/Fungus/Scripts/Editor/BlockEditor.cs index 3bb24c98..8119a2e4 100644 --- a/Assets/Fungus/Scripts/Editor/BlockEditor.cs +++ b/Assets/Fungus/Scripts/Editor/BlockEditor.cs @@ -30,6 +30,11 @@ namespace Fungus.EditorUtils public Type commandType; } + + 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 actionList = new List(); protected Texture2D upIcon; @@ -325,6 +330,7 @@ namespace Fungus.EditorUtils 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 @@ -353,18 +359,23 @@ namespace Fungus.EditorUtils } - private static readonly char[] SPLIT_INPUT_ON = new char[] { ' ', '/', '\\' }; + //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(); var tokens = upperCommandText.Split(); + //we want commands that have all the elements you have typed filteredAttributes = filteredAttributes.Where((x) => { bool catAny = tokens.Any(x.Value.Category.ToUpper().Contains); @@ -372,10 +383,13 @@ namespace Fungus.EditorUtils 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; @@ -392,13 +406,22 @@ namespace Fungus.EditorUtils filteredCommandPreviewSelectedItem = Mathf.Clamp(filteredCommandPreviewSelectedItem, 0, filteredAttributes.Count - 1); //GUILayout.TextArea(string.Join("\n", filteredAttributes.Select(x => x.Value.Category + "/" + x.Value.CommandName).ToArray())); - filteredCommandPreviewSelectedItem = GUILayout.SelectionGrid(filteredCommandPreviewSelectedItem, filteredAttributes.Select(x => x.Value.Category + "/" + x.Value.CommandName).ToArray(), 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 enter is hit then create that command and reset the preview window if ((Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter) && - filteredAttributes.Count > filteredCommandPreviewSelectedItem) + filteredAttributes.Count > filteredCommandPreviewSelectedItem && toShow[filteredCommandPreviewSelectedItem] != ELIPSIS) { commandTextFieldContents = String.Empty; //GUI.FocusControl("dummycontrol"); From c8f8bf4d8b46654b07cd1b113fecbc8ce6481b0b Mon Sep 17 00:00:00 2001 From: desktop-maesty/steve Date: Fri, 14 Jul 2017 21:51:52 +1000 Subject: [PATCH 6/9] Smarter split actually being tested now Remove attempt to keep index in command list as it is not required for this feature and is causing an exception due to unmatched GUILayouts --- Assets/Fungus/Scripts/Editor/BlockEditor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Assets/Fungus/Scripts/Editor/BlockEditor.cs b/Assets/Fungus/Scripts/Editor/BlockEditor.cs index 8119a2e4..9aa852a6 100644 --- a/Assets/Fungus/Scripts/Editor/BlockEditor.cs +++ b/Assets/Fungus/Scripts/Editor/BlockEditor.cs @@ -373,7 +373,7 @@ namespace Fungus.EditorUtils var filteredAttributes = GetFilteredSupportedCommands(flowchart); var upperCommandText = commandTextFieldContents.ToUpper().Trim(); - var tokens = upperCommandText.Split(); + var tokens = upperCommandText.Split(SPLIT_INPUT_ON); //we want commands that have all the elements you have typed filteredAttributes = filteredAttributes.Where((x) => @@ -897,7 +897,7 @@ namespace Fungus.EditorUtils PrefabUtility.RecordPrefabInstancePropertyModifications(block); flowchart.ClearSelectedCommands(); - flowchart.AddSelectedCommand(newCommand); + //flowchart.AddSelectedCommand(newCommand); commandTextFieldContents = string.Empty; } From 8a2d2b4c6573c9f1454a767c8b5463267912912a Mon Sep 17 00:00:00 2001 From: desktop-maesty/steve Date: Fri, 14 Jul 2017 22:10:47 +1000 Subject: [PATCH 7/9] CommandByName text enter caches command for next frame to be added during the normal keyboard input section to avoid those events being eaten by other parts of the gui and us playing nice with what Unity GUILayout expects --- Assets/Fungus/Scripts/Editor/BlockEditor.cs | 32 ++++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/Assets/Fungus/Scripts/Editor/BlockEditor.cs b/Assets/Fungus/Scripts/Editor/BlockEditor.cs index 9aa852a6..63c74863 100644 --- a/Assets/Fungus/Scripts/Editor/BlockEditor.cs +++ b/Assets/Fungus/Scripts/Editor/BlockEditor.cs @@ -42,8 +42,10 @@ namespace Fungus.EditorUtils protected Texture2D addIcon; protected Texture2D duplicateIcon; protected Texture2D deleteIcon; + protected string commandTextFieldContents = string.Empty; protected int filteredCommandPreviewSelectedItem = 0; + protected Type commandSelectedByTextInput; static List commandTypes; static List eventHandlerTypes; @@ -300,6 +302,17 @@ namespace Fungus.EditorUtils { 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 @@ -373,6 +386,10 @@ namespace Fungus.EditorUtils 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 @@ -417,19 +434,12 @@ namespace Fungus.EditorUtils filteredCommandPreviewSelectedItem = GUILayout.SelectionGrid(filteredCommandPreviewSelectedItem, toShow, 1); + if (toShow[filteredCommandPreviewSelectedItem] != ELIPSIS) + commandSelectedByTextInput = filteredAttributes[filteredCommandPreviewSelectedItem].Key; + else + commandSelectedByTextInput = null; - // if enter is hit then create that command and reset the preview window - if ((Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter) && - filteredAttributes.Count > filteredCommandPreviewSelectedItem && toShow[filteredCommandPreviewSelectedItem] != ELIPSIS) - { - commandTextFieldContents = String.Empty; - //GUI.FocusControl("dummycontrol"); - //Event.current.Use(); - AddCommandCallback(filteredAttributes[filteredCommandPreviewSelectedItem].Key); - filteredCommandPreviewSelectedItem = 0; - } - GUILayout.EndHorizontal(); GUILayout.Space(5); From 6eae87c4dc75378dbad7d46349741a2bc72e0aeb Mon Sep 17 00:00:00 2001 From: desktop-maesty/steve Date: Fri, 14 Jul 2017 22:12:38 +1000 Subject: [PATCH 8/9] Missed check --- Assets/Fungus/Scripts/Editor/BlockEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/Fungus/Scripts/Editor/BlockEditor.cs b/Assets/Fungus/Scripts/Editor/BlockEditor.cs index 63c74863..e30b9d43 100644 --- a/Assets/Fungus/Scripts/Editor/BlockEditor.cs +++ b/Assets/Fungus/Scripts/Editor/BlockEditor.cs @@ -387,7 +387,7 @@ namespace Fungus.EditorUtils var upperCommandText = commandTextFieldContents.ToUpper().Trim(); - if (upperCommandText.Length > 0) + if (upperCommandText.Length == 0) return; var tokens = upperCommandText.Split(SPLIT_INPUT_ON); From 8765f7ea4e5246dd02601cd4de7350ba3403544d Mon Sep 17 00:00:00 2001 From: desktop-maesty/steve Date: Fri, 21 Jul 2017 17:30:17 +1000 Subject: [PATCH 9/9] Remove commented out code --- Assets/Fungus/Scripts/Editor/BlockEditor.cs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Assets/Fungus/Scripts/Editor/BlockEditor.cs b/Assets/Fungus/Scripts/Editor/BlockEditor.cs index e30b9d43..a0b6853d 100644 --- a/Assets/Fungus/Scripts/Editor/BlockEditor.cs +++ b/Assets/Fungus/Scripts/Editor/BlockEditor.cs @@ -26,7 +26,6 @@ namespace Fungus.EditorUtils protected class AddCommandOperation { - //public Block block; public Type commandType; } @@ -422,9 +421,8 @@ namespace Fungus.EditorUtils filteredCommandPreviewSelectedItem = Mathf.Clamp(filteredCommandPreviewSelectedItem, 0, filteredAttributes.Count - 1); - //GUILayout.TextArea(string.Join("\n", filteredAttributes.Select(x => x.Value.Category + "/" + x.Value.CommandName).ToArray())); - 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) { @@ -435,10 +433,13 @@ namespace Fungus.EditorUtils filteredCommandPreviewSelectedItem = GUILayout.SelectionGrid(filteredCommandPreviewSelectedItem, toShow, 1); if (toShow[filteredCommandPreviewSelectedItem] != ELIPSIS) + { commandSelectedByTextInput = filteredAttributes[filteredCommandPreviewSelectedItem].Key; + } else + { commandSelectedByTextInput = null; - + } GUILayout.EndHorizontal(); @@ -788,10 +789,8 @@ namespace Fungus.EditorUtils foreach (var keyPair in filteredAttributes) { AddCommandOperation commandOperation = new AddCommandOperation(); - - //commandOperation.block = block; + commandOperation.commandType = keyPair.Key; - //commandOperation.index = index; GUIContent menuItem; if (keyPair.Value.Category == "") @@ -907,7 +906,6 @@ namespace Fungus.EditorUtils PrefabUtility.RecordPrefabInstancePropertyModifications(block); flowchart.ClearSelectedCommands(); - //flowchart.AddSelectedCommand(newCommand); commandTextFieldContents = string.Empty; }