diff --git a/Source/Editor/Content/Proxy/JsonAssetProxy.cs b/Source/Editor/Content/Proxy/JsonAssetProxy.cs index 15d5e89f1..3f2863f74 100644 --- a/Source/Editor/Content/Proxy/JsonAssetProxy.cs +++ b/Source/Editor/Content/Proxy/JsonAssetProxy.cs @@ -163,7 +163,7 @@ namespace FlaxEditor.Content public sealed class SpawnableJsonAssetProxy : JsonAssetProxy where T : new() { /// - public override string Name { get; } = CustomEditors.CustomEditorsUtil.GetPropertyNameUI(typeof(T).Name); + public override string Name { get; } = Utilities.Utils.GetPropertyNameUI(typeof(T).Name); /// public override bool CanCreate(ContentFolder targetLocation) diff --git a/Source/Editor/Content/Proxy/SettingsProxy.cs b/Source/Editor/Content/Proxy/SettingsProxy.cs index 6b1b5a6cb..0bbd2830f 100644 --- a/Source/Editor/Content/Proxy/SettingsProxy.cs +++ b/Source/Editor/Content/Proxy/SettingsProxy.cs @@ -35,7 +35,7 @@ namespace FlaxEditor.Content /// public override string Name => "Settings"; - //public override string Name { get; } = CustomEditors.CustomEditorsUtil.GetPropertyNameUI(_type.Name); + //public override string Name { get; } = Utilities.Utils.GetPropertyNameUI(_type.Name); /// public override bool CanCreate(ContentFolder targetLocation) diff --git a/Source/Editor/CustomEditors/CustomEditorsUtil.cs b/Source/Editor/CustomEditors/CustomEditorsUtil.cs index 27e9896ee..211e69d3a 100644 --- a/Source/Editor/CustomEditors/CustomEditorsUtil.cs +++ b/Source/Editor/CustomEditors/CustomEditorsUtil.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; -using System.Text; using FlaxEditor.CustomEditors.Editors; using FlaxEditor.Scripting; using FlaxEngine; @@ -13,8 +12,6 @@ namespace FlaxEditor.CustomEditors { internal static class CustomEditorsUtil { - private static readonly StringBuilder CachedSb = new StringBuilder(256); - internal static readonly Dictionary InBuildTypeNames = new Dictionary() { { typeof(bool), "bool" }, @@ -46,51 +43,6 @@ namespace FlaxEditor.CustomEditors return result; } - /// - /// Gets the property name for UI. Removes unnecessary characters and filters text. Makes it more user-friendly. - /// - /// The name. - /// The result. - public static string GetPropertyNameUI(string name) - { - int length = name.Length; - StringBuilder sb = CachedSb; - sb.Clear(); - sb.EnsureCapacity(length + 8); - int startIndex = 0; - - // Skip some prefixes - if (name.StartsWith("g_") || name.StartsWith("m_")) - startIndex = 2; - - // Filter text - for (int i = startIndex; i < length; i++) - { - var c = name[i]; - - // Space before word starting with uppercase letter - if (char.IsUpper(c) && i > 0) - { - if (i + 1 < length && !char.IsUpper(name[i + 1])) - sb.Append(' '); - } - // Space instead of underscore - else if (c == '_') - { - if (sb.Length > 0) - sb.Append(' '); - continue; - } - // Space before digits sequence - else if (i > 1 && char.IsDigit(c) && !char.IsDigit(name[i - 1])) - sb.Append(' '); - - sb.Append(c); - } - - return sb.ToString(); - } - internal static CustomEditor CreateEditor(ValueContainer values, CustomEditor overrideEditor, bool canUseRefPicker = true) { // Check if use provided editor diff --git a/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs b/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs index 4a46c32c7..49cc67868 100644 --- a/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs +++ b/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs @@ -209,13 +209,13 @@ namespace FlaxEditor.CustomEditors.Dedicated if (editor is RemovedScriptDummy removed) { node.TextColor = Color.OrangeRed; - node.Text = CustomEditorsUtil.GetPropertyNameUI(removed.PrefabObject.GetType().Name); + node.Text = Utilities.Utils.GetPropertyNameUI(removed.PrefabObject.GetType().Name); } // Actor or Script else if (editor.Values[0] is SceneObject sceneObject) { node.TextColor = sceneObject.HasPrefabLink ? FlaxEngine.GUI.Style.Current.ProgressNormal : FlaxEngine.GUI.Style.Current.BackgroundSelected; - node.Text = CustomEditorsUtil.GetPropertyNameUI(sceneObject.GetType().Name); + node.Text = Utilities.Utils.GetPropertyNameUI(sceneObject.GetType().Name); } // Array Item else if (editor.ParentEditor?.Values?.Type.IsArray ?? false) @@ -225,7 +225,7 @@ namespace FlaxEditor.CustomEditors.Dedicated // Common type else if (editor.Values.Info != ScriptMemberInfo.Null) { - node.Text = CustomEditorsUtil.GetPropertyNameUI(editor.Values.Info.Name); + node.Text = Utilities.Utils.GetPropertyNameUI(editor.Values.Info.Name); } // Custom type else if (editor.Values[0] != null) diff --git a/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs b/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs index a85770fbb..c165824eb 100644 --- a/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs +++ b/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs @@ -611,7 +611,7 @@ namespace FlaxEditor.CustomEditors.Dedicated var editor = CustomEditorsUtil.CreateEditor(scriptType, false); // Create group - var title = CustomEditorsUtil.GetPropertyNameUI(scriptType.Name); + var title = Utilities.Utils.GetPropertyNameUI(scriptType.Name); var group = layout.Group(title, editor); if ((Presenter.Features & FeatureFlags.CacheExpandedGroups) != 0) { diff --git a/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs b/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs index 55473d42c..60915ff8e 100644 --- a/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs +++ b/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs @@ -32,7 +32,7 @@ namespace FlaxEditor.CustomEditors.Dedicated if (_presets != value) { _presets = value; - TooltipText = CustomEditorsUtil.GetPropertyNameUI(_presets.ToString()); + TooltipText = Utilities.Utils.GetPropertyNameUI(_presets.ToString()); } } } diff --git a/Source/Editor/CustomEditors/Editors/GenericEditor.cs b/Source/Editor/CustomEditors/Editors/GenericEditor.cs index 79ae1dd94..a69ae7ba4 100644 --- a/Source/Editor/CustomEditors/Editors/GenericEditor.cs +++ b/Source/Editor/CustomEditors/Editors/GenericEditor.cs @@ -137,7 +137,7 @@ namespace FlaxEditor.CustomEditors.Editors ExpandGroups = attributes.FirstOrDefault(x => x is ExpandGroupsAttribute) != null; IsReadOnly |= !info.HasSet; - DisplayName = Display?.Name ?? CustomEditorsUtil.GetPropertyNameUI(info.Name); + DisplayName = Display?.Name ?? Utilities.Utils.GetPropertyNameUI(info.Name); var editor = Editor.Instance; TooltipText = editor.CodeDocs.GetTooltip(info, attributes); _membersOrder = editor.Options.Options.General.ScriptMembersOrder; diff --git a/Source/Editor/GUI/EnumComboBox.cs b/Source/Editor/GUI/EnumComboBox.cs index 27563bd7a..24f818d0d 100644 --- a/Source/Editor/GUI/EnumComboBox.cs +++ b/Source/Editor/GUI/EnumComboBox.cs @@ -261,7 +261,7 @@ namespace FlaxEditor.GUI switch (formatMode) { case EnumDisplayAttribute.FormatMode.Default: - name = CustomEditorsUtil.GetPropertyNameUI(field.Name); + name = Utilities.Utils.GetPropertyNameUI(field.Name); break; case EnumDisplayAttribute.FormatMode.None: name = field.Name; diff --git a/Source/Editor/GUI/Timeline/Tracks/ActorTrack.cs b/Source/Editor/GUI/Timeline/Tracks/ActorTrack.cs index 8758c7622..9a7f4dfed 100644 --- a/Source/Editor/GUI/Timeline/Tracks/ActorTrack.cs +++ b/Source/Editor/GUI/Timeline/Tracks/ActorTrack.cs @@ -177,7 +177,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks if (SubTracks.Any(x => x is IObjectTrack y && y.Object == script)) continue; - var name = CustomEditorsUtil.GetPropertyNameUI(script.GetType().Name); + var name = Utilities.Utils.GetPropertyNameUI(script.GetType().Name); menu.AddButton(name, OnAddScriptTrack).Tag = script; } } diff --git a/Source/Editor/Surface/AttributesEditor.cs b/Source/Editor/Surface/AttributesEditor.cs index 74bfe2e25..6de6d60da 100644 --- a/Source/Editor/Surface/AttributesEditor.cs +++ b/Source/Editor/Surface/AttributesEditor.cs @@ -41,7 +41,7 @@ namespace FlaxEditor.Surface for (int i = 0; i < options.Count; i++) { var type = options[i]; - _options[i] = new OptionType(CustomEditorsUtil.GetPropertyNameUI(type.Name), type, Creator); + _options[i] = new OptionType(Utilities.Utils.GetPropertyNameUI(type.Name), type, Creator); } base.Initialize(layout); diff --git a/Source/Editor/Surface/NodeElementArchetype.cs b/Source/Editor/Surface/NodeElementArchetype.cs index d5a8ea122..d365668ea 100644 --- a/Source/Editor/Surface/NodeElementArchetype.cs +++ b/Source/Editor/Surface/NodeElementArchetype.cs @@ -457,7 +457,7 @@ namespace FlaxEditor.Surface if (field.Name.Equals("value__")) continue; - var name = CustomEditorsUtil.GetPropertyNameUI(field.Name); + var name = Utilities.Utils.GetPropertyNameUI(field.Name); values.Add(name); } return ComboBox(x, y, width, valueIndex, values.ToArray()); diff --git a/Source/Editor/Utilities/Utils.cs b/Source/Editor/Utilities/Utils.cs index 9ec08aacc..183442542 100644 --- a/Source/Editor/Utilities/Utils.cs +++ b/Source/Editor/Utilities/Utils.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.InteropServices; +using System.Text; using FlaxEditor.GUI.ContextMenu; using FlaxEditor.GUI.Tree; using FlaxEditor.SceneGraph; @@ -27,6 +28,8 @@ namespace FlaxEditor.Utilities /// public static class Utils { + private static readonly StringBuilder CachedSb = new StringBuilder(256); + private static readonly string[] MemorySizePostfixes = { "B", @@ -862,6 +865,62 @@ namespace FlaxEditor.Utilities } } + /// + /// Gets the property name for UI. Removes unnecessary characters and filters text. Makes it more user-friendly. + /// + /// The name. + /// The result. + public static string GetPropertyNameUI(string name) + { + int length = name.Length; + StringBuilder sb = CachedSb; + sb.Clear(); + sb.EnsureCapacity(length + 8); + int startIndex = 0; + + // Skip some prefixes + if (name.StartsWith("g_") || name.StartsWith("m_")) + startIndex = 2; + + // Filter text + var lastChar = '\0'; + for (int i = startIndex; i < length; i++) + { + var c = name[i]; + + // Space before word starting with uppercase letter + if (char.IsUpper(c) && i > 0) + { + if (lastChar != ' ' && (!char.IsUpper(name[i - 1]) || (i + 1 != length && !char.IsUpper(name[i + 1])))) + { + lastChar = ' '; + sb.Append(lastChar); + } + } + // Space instead of underscore + else if (c == '_') + { + if (sb.Length > 0 && lastChar != ' ') + { + lastChar = ' '; + sb.Append(lastChar); + } + continue; + } + // Space before digits sequence + else if (i > 1 && char.IsDigit(c) && !char.IsDigit(name[i - 1]) && lastChar != ' ') + { + lastChar = ' '; + sb.Append(lastChar); + } + + lastChar = c; + sb.Append(lastChar); + } + + return sb.ToString(); + } + /// /// Creates the search popup with a tree. /// diff --git a/Source/Editor/Windows/GameCookerWindow.cs b/Source/Editor/Windows/GameCookerWindow.cs index 01cd8efae..74ca3ea9b 100644 --- a/Source/Editor/Windows/GameCookerWindow.cs +++ b/Source/Editor/Windows/GameCookerWindow.cs @@ -278,7 +278,7 @@ namespace FlaxEditor.Windows name = "Mac"; break; default: - name = CustomEditorsUtil.GetPropertyNameUI(_platform.ToString()); + name = Utilities.Utils.GetPropertyNameUI(_platform.ToString()); break; } var group = layout.Group(name); diff --git a/Source/Editor/Windows/ToolboxWindow.cs b/Source/Editor/Windows/ToolboxWindow.cs index 0d47a92b3..2925df386 100644 --- a/Source/Editor/Windows/ToolboxWindow.cs +++ b/Source/Editor/Windows/ToolboxWindow.cs @@ -223,7 +223,7 @@ namespace FlaxEditor.Windows if (!QueryFilterHelper.Match(filterText, text, out QueryFilterHelper.Range[] ranges)) continue; - var item = _groupSearch.AddChild(CreateActorItem(CustomEditors.CustomEditorsUtil.GetPropertyNameUI(text), actorType)); + var item = _groupSearch.AddChild(CreateActorItem(Utilities.Utils.GetPropertyNameUI(text), actorType)); var highlights = new List(ranges.Length); var style = Style.Current; diff --git a/Source/Engine/Core/Config/GameSettings.cs b/Source/Engine/Core/Config/GameSettings.cs index a8519fe4c..7e70f29bd 100644 --- a/Source/Engine/Core/Config/GameSettings.cs +++ b/Source/Engine/Core/Config/GameSettings.cs @@ -334,7 +334,7 @@ namespace FlaxEditor.Content.Settings } // Create new settings asset and link it to the game settings - var path = StringUtils.CombinePaths(Globals.ProjectContentFolder, "Settings", CustomEditors.CustomEditorsUtil.GetPropertyNameUI(typeof(T).Name) + ".json"); + var path = StringUtils.CombinePaths(Globals.ProjectContentFolder, "Settings", Utilities.Utils.GetPropertyNameUI(typeof(T).Name) + ".json"); if (Editor.SaveJsonAsset(path, obj)) return true; asset = FlaxEngine.Content.LoadAsync(path); diff --git a/Source/Tools/FlaxEngine.Tests/FlaxEngine.Tests.csproj b/Source/Tools/FlaxEngine.Tests/FlaxEngine.Tests.csproj index 9ee085dc4..89e433e28 100644 --- a/Source/Tools/FlaxEngine.Tests/FlaxEngine.Tests.csproj +++ b/Source/Tools/FlaxEngine.Tests/FlaxEngine.Tests.csproj @@ -48,6 +48,7 @@ + diff --git a/Source/Tools/FlaxEngine.Tests/TestPropertyNameUI.cs b/Source/Tools/FlaxEngine.Tests/TestPropertyNameUI.cs new file mode 100644 index 000000000..0b7644190 --- /dev/null +++ b/Source/Tools/FlaxEngine.Tests/TestPropertyNameUI.cs @@ -0,0 +1,30 @@ +// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved. + +using FlaxEditor.Utilities; +using NUnit.Framework; + +namespace FlaxEditor.Tests +{ + [TestFixture] + public class TestPropertyNameUI + { + [Test] + public void TestFormatting() + { + Assert.AreEqual("property", Utils.GetPropertyNameUI("property")); + Assert.AreEqual("property", Utils.GetPropertyNameUI("_property")); + Assert.AreEqual("property", Utils.GetPropertyNameUI("m_property")); + Assert.AreEqual("property", Utils.GetPropertyNameUI("g_property")); + Assert.AreEqual("Property", Utils.GetPropertyNameUI("Property")); + Assert.AreEqual("Property 1", Utils.GetPropertyNameUI("Property1")); + Assert.AreEqual("Property Name", Utils.GetPropertyNameUI("PropertyName")); + Assert.AreEqual("Property Name", Utils.GetPropertyNameUI("Property_Name")); + Assert.AreEqual("Property 123", Utils.GetPropertyNameUI("Property_123")); + Assert.AreEqual("Property TMP", Utils.GetPropertyNameUI("Property_TMP")); + Assert.AreEqual("Property TMP", Utils.GetPropertyNameUI("PropertyTMP")); + Assert.AreEqual("Property T", Utils.GetPropertyNameUI("PropertyT")); + Assert.AreEqual("Property TMP Word", Utils.GetPropertyNameUI("PropertyTMPWord")); + Assert.AreEqual("Generate SDF On Model Import", Utils.GetPropertyNameUI("GenerateSDFOnModelImport")); + } + } +}