Improve property names displaying in UI and add Unit Test for it

This commit is contained in:
Wojciech Figat
2022-04-27 14:12:27 +02:00
parent 49aa4abc20
commit 27a1dc8966
17 changed files with 105 additions and 63 deletions

View File

@@ -163,7 +163,7 @@ namespace FlaxEditor.Content
public sealed class SpawnableJsonAssetProxy<T> : JsonAssetProxy where T : new()
{
/// <inheritdoc />
public override string Name { get; } = CustomEditors.CustomEditorsUtil.GetPropertyNameUI(typeof(T).Name);
public override string Name { get; } = Utilities.Utils.GetPropertyNameUI(typeof(T).Name);
/// <inheritdoc />
public override bool CanCreate(ContentFolder targetLocation)

View File

@@ -35,7 +35,7 @@ namespace FlaxEditor.Content
/// <inheritdoc />
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);
/// <inheritdoc />
public override bool CanCreate(ContentFolder targetLocation)

View File

@@ -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<Type, string> InBuildTypeNames = new Dictionary<Type, string>()
{
{ typeof(bool), "bool" },
@@ -46,51 +43,6 @@ namespace FlaxEditor.CustomEditors
return result;
}
/// <summary>
/// Gets the property name for UI. Removes unnecessary characters and filters text. Makes it more user-friendly.
/// </summary>
/// <param name="name">The name.</param>
/// <returns>The result.</returns>
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

View File

@@ -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)

View File

@@ -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)
{

View File

@@ -32,7 +32,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
if (_presets != value)
{
_presets = value;
TooltipText = CustomEditorsUtil.GetPropertyNameUI(_presets.ToString());
TooltipText = Utilities.Utils.GetPropertyNameUI(_presets.ToString());
}
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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());

View File

@@ -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
/// </summary>
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
}
}
/// <summary>
/// Gets the property name for UI. Removes unnecessary characters and filters text. Makes it more user-friendly.
/// </summary>
/// <param name="name">The name.</param>
/// <returns>The result.</returns>
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();
}
/// <summary>
/// Creates the search popup with a tree.
/// </summary>

View File

@@ -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);

View File

@@ -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<Rectangle>(ranges.Length);
var style = Style.Current;

View File

@@ -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<JsonAsset>(path);

View File

@@ -48,6 +48,7 @@
<ItemGroup>
<Compile Include="CircularBufferTests.cs" />
<Compile Include="TestModulusOperator.cs" />
<Compile Include="TestPropertyNameUI.cs" />
<Compile Include="TestQuaternion.cs" />
<Compile Include="TestSerialization.cs" />
<Compile Include="TestStringUtils.cs" />

View File

@@ -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"));
}
}
}