add units support in float, double and Float3 input
This commit is contained in:
@@ -4,6 +4,7 @@ using System;
|
||||
using System.Linq;
|
||||
using FlaxEditor.CustomEditors.Elements;
|
||||
using FlaxEngine;
|
||||
using Utils = FlaxEditor.Utilities.Utils;
|
||||
|
||||
namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
@@ -25,6 +26,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
|
||||
// Try get limit attribute for value min/max range setting and slider speed
|
||||
var attributes = Values.GetAttributes();
|
||||
var categoryAttribute = attributes.FirstOrDefault(x => x is ValueCategoryAttribute);
|
||||
var valueCategory = ((ValueCategoryAttribute)categoryAttribute)?.Category ?? Utils.ValueCategory.None;
|
||||
if (attributes != null)
|
||||
{
|
||||
var limit = attributes.FirstOrDefault(x => x is LimitAttribute);
|
||||
@@ -32,6 +35,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
// Use double value editor with limit
|
||||
var doubleValue = layout.DoubleValue();
|
||||
doubleValue.SetCategory(valueCategory);
|
||||
doubleValue.SetLimits((LimitAttribute)limit);
|
||||
doubleValue.ValueBox.ValueChanged += OnValueChanged;
|
||||
doubleValue.ValueBox.SlidingEnd += ClearToken;
|
||||
@@ -43,6 +47,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
// Use double value editor
|
||||
var doubleValue = layout.DoubleValue();
|
||||
doubleValue.SetCategory(valueCategory);
|
||||
doubleValue.ValueBox.ValueChanged += OnValueChanged;
|
||||
doubleValue.ValueBox.SlidingEnd += ClearToken;
|
||||
_element = doubleValue;
|
||||
|
||||
@@ -4,6 +4,7 @@ using System;
|
||||
using System.Linq;
|
||||
using FlaxEditor.CustomEditors.Elements;
|
||||
using FlaxEngine;
|
||||
using Utils = FlaxEditor.Utilities.Utils;
|
||||
|
||||
namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
@@ -30,6 +31,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
|
||||
// Try get limit attribute for value min/max range setting and slider speed
|
||||
var attributes = Values.GetAttributes();
|
||||
var categoryAttribute = attributes.FirstOrDefault(x => x is ValueCategoryAttribute);
|
||||
var valueCategory = ((ValueCategoryAttribute)categoryAttribute)?.Category ?? Utils.ValueCategory.None;
|
||||
if (attributes != null)
|
||||
{
|
||||
var range = attributes.FirstOrDefault(x => x is RangeAttribute);
|
||||
@@ -49,6 +52,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
// Use float value editor with limit
|
||||
var floatValue = layout.FloatValue();
|
||||
floatValue.SetLimits((LimitAttribute)limit);
|
||||
floatValue.SetCategory(valueCategory);
|
||||
floatValue.ValueBox.ValueChanged += OnValueChanged;
|
||||
floatValue.ValueBox.SlidingEnd += ClearToken;
|
||||
_element = floatValue;
|
||||
@@ -59,6 +63,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
// Use float value editor
|
||||
var floatValue = layout.FloatValue();
|
||||
floatValue.SetCategory(valueCategory);
|
||||
floatValue.ValueBox.ValueChanged += OnValueChanged;
|
||||
floatValue.ValueBox.SlidingEnd += ClearToken;
|
||||
_element = floatValue;
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using FlaxEditor.CustomEditors.Elements;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using Utils = FlaxEditor.Utilities.Utils;
|
||||
|
||||
namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
@@ -70,23 +71,30 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
|
||||
LimitAttribute limit = null;
|
||||
var attributes = Values.GetAttributes();
|
||||
var category = Utils.ValueCategory.None;
|
||||
if (attributes != null)
|
||||
{
|
||||
limit = (LimitAttribute)attributes.FirstOrDefault(x => x is LimitAttribute);
|
||||
var categoryAttribute = (ValueCategoryAttribute)attributes.FirstOrDefault(x => x is ValueCategoryAttribute);
|
||||
if (categoryAttribute != null)
|
||||
category = categoryAttribute.Category;
|
||||
}
|
||||
|
||||
XElement = grid.FloatValue();
|
||||
XElement.SetLimits(limit);
|
||||
XElement.SetCategory(category);
|
||||
XElement.ValueBox.ValueChanged += OnXValueChanged;
|
||||
XElement.ValueBox.SlidingEnd += ClearToken;
|
||||
|
||||
YElement = grid.FloatValue();
|
||||
YElement.SetLimits(limit);
|
||||
YElement.SetCategory(category);
|
||||
YElement.ValueBox.ValueChanged += OnYValueChanged;
|
||||
YElement.ValueBox.SlidingEnd += ClearToken;
|
||||
|
||||
ZElement = grid.FloatValue();
|
||||
ZElement.SetLimits(limit);
|
||||
ZElement.SetCategory(category);
|
||||
ZElement.ValueBox.ValueChanged += OnZValueChanged;
|
||||
ZElement.ValueBox.SlidingEnd += ClearToken;
|
||||
}
|
||||
@@ -248,24 +256,31 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
gridControl.SlotsVertically = 1;
|
||||
|
||||
LimitAttribute limit = null;
|
||||
Utils.ValueCategory category = Utils.ValueCategory.None;
|
||||
var attributes = Values.GetAttributes();
|
||||
if (attributes != null)
|
||||
{
|
||||
limit = (LimitAttribute)attributes.FirstOrDefault(x => x is LimitAttribute);
|
||||
var categoryAttribute = (ValueCategoryAttribute)attributes.FirstOrDefault(x => x is ValueCategoryAttribute);
|
||||
if (categoryAttribute != null)
|
||||
category = categoryAttribute.Category;
|
||||
}
|
||||
|
||||
XElement = grid.DoubleValue();
|
||||
XElement.SetLimits(limit);
|
||||
XElement.SetCategory(category);
|
||||
XElement.ValueBox.ValueChanged += OnValueChanged;
|
||||
XElement.ValueBox.SlidingEnd += ClearToken;
|
||||
|
||||
YElement = grid.DoubleValue();
|
||||
YElement.SetLimits(limit);
|
||||
YElement.SetCategory(category);
|
||||
YElement.ValueBox.ValueChanged += OnValueChanged;
|
||||
YElement.ValueBox.SlidingEnd += ClearToken;
|
||||
|
||||
ZElement = grid.DoubleValue();
|
||||
ZElement.SetLimits(limit);
|
||||
ZElement.SetCategory(category);
|
||||
ZElement.ValueBox.ValueChanged += OnValueChanged;
|
||||
ZElement.ValueBox.SlidingEnd += ClearToken;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Reflection;
|
||||
using FlaxEditor.GUI.Input;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using Utils = FlaxEditor.Utilities.Utils;
|
||||
|
||||
namespace FlaxEditor.CustomEditors.Elements
|
||||
{
|
||||
@@ -51,6 +52,15 @@ namespace FlaxEditor.CustomEditors.Elements
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the value category of this float element
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
public void SetCategory(Utils.ValueCategory category)
|
||||
{
|
||||
ValueBox.Category = category;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the editor limits from member <see cref="LimitAttribute"/>.
|
||||
/// </summary>
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Reflection;
|
||||
using FlaxEditor.GUI.Input;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using Utils = FlaxEditor.Utilities.Utils;
|
||||
|
||||
namespace FlaxEditor.CustomEditors.Elements
|
||||
{
|
||||
@@ -51,6 +52,15 @@ namespace FlaxEditor.CustomEditors.Elements
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the value category of this float element
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
public void SetCategory(Utils.ValueCategory category)
|
||||
{
|
||||
ValueBox.Category = category;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the editor limits from member <see cref="LimitAttribute"/>.
|
||||
/// </summary>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
using System;
|
||||
using FlaxEditor.Utilities;
|
||||
using FlaxEngine;
|
||||
using Utils = FlaxEditor.Utilities.Utils;
|
||||
|
||||
namespace FlaxEditor.GUI.Input
|
||||
{
|
||||
@@ -129,10 +130,15 @@ namespace FlaxEditor.GUI.Input
|
||||
Value = Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get or set the category of the value. This can either be none for just a number, a distance or an angle.
|
||||
/// </summary>
|
||||
public Utils.ValueCategory Category = Utils.ValueCategory.None;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected sealed override void UpdateText()
|
||||
{
|
||||
SetText(Utilities.Utils.FormatFloat(_value));
|
||||
SetText(Utilities.Utils.FormatFloat(_value, Category));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -4,6 +4,7 @@ using System;
|
||||
using System.Globalization;
|
||||
using FlaxEditor.Utilities;
|
||||
using FlaxEngine;
|
||||
using Utils = FlaxEditor.Utilities.Utils;
|
||||
|
||||
namespace FlaxEditor.GUI.Input
|
||||
{
|
||||
@@ -137,10 +138,15 @@ namespace FlaxEditor.GUI.Input
|
||||
Value = Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get or set the category of the value. This can either be none for just a number, a distance or an angle.
|
||||
/// </summary>
|
||||
public Utils.ValueCategory Category = Utils.ValueCategory.None;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected sealed override void UpdateText()
|
||||
{
|
||||
SetText(Utilities.Utils.FormatFloat(_value));
|
||||
SetText(Utilities.Utils.FormatFloat(_value, Category));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -121,6 +121,9 @@ namespace FlaxEditor.Utilities
|
||||
["e"] = Math.E,
|
||||
["infinity"] = double.MaxValue,
|
||||
["-infinity"] = -double.MaxValue,
|
||||
["m"] = Units.Meters2Units,
|
||||
["cm"] = Units.Meters2Units / 100,
|
||||
["km"] = Units.Meters2Units * 1000
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -170,7 +173,7 @@ namespace FlaxEditor.Utilities
|
||||
public static IEnumerable<Token> Tokenize(string text)
|
||||
{
|
||||
// Prepare text
|
||||
text = text.Replace(',', '.');
|
||||
text = text.Replace(',', '.').Replace("°", "");
|
||||
|
||||
// Necessary to correctly parse negative numbers
|
||||
var previous = TokenType.WhiteSpace;
|
||||
@@ -372,6 +375,18 @@ namespace FlaxEditor.Utilities
|
||||
}
|
||||
}
|
||||
|
||||
// if stack has more than one item we're not finished with evaluating
|
||||
// we assume the remaining values are all factors to be multiplied
|
||||
if (stack.Count > 1)
|
||||
{
|
||||
var stackContent = string.Join(",", stack.ToList());
|
||||
Debug.Log($"parsing numbers, stack is {stackContent}");
|
||||
var v1 = stack.Pop();
|
||||
Debug.Log($"first on stack: {v1}");
|
||||
while (stack.Count > 0)
|
||||
v1 *= stack.Pop();
|
||||
return v1;
|
||||
}
|
||||
return stack.Pop();
|
||||
}
|
||||
|
||||
|
||||
9
Source/Editor/Utilities/Units.cs
Normal file
9
Source/Editor/Utilities/Units.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace FlaxEditor.Utilities;
|
||||
|
||||
public class Units
|
||||
{
|
||||
/// <summary>
|
||||
/// Factor of units per meter.
|
||||
/// </summary>
|
||||
public static readonly float Meters2Units = 100f;
|
||||
}
|
||||
@@ -58,6 +58,16 @@ namespace FlaxEditor.Utilities
|
||||
/// </summary>
|
||||
public static readonly string FlaxEngineAssemblyName = "FlaxEngine.CSharp";
|
||||
|
||||
/// <summary>
|
||||
/// A category of number values used for formatting and input boxes
|
||||
/// </summary>
|
||||
public enum ValueCategory
|
||||
{
|
||||
None,
|
||||
Distance,
|
||||
Angle
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to parse number in the name brackets at the end of the value and then increment it to create a new name.
|
||||
/// Supports numbers at the end without brackets.
|
||||
@@ -1171,6 +1181,56 @@ namespace FlaxEditor.Utilities
|
||||
return StringUtils.GetPathWithoutExtension(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format a float value either as-is, with a distance unit or with a degree sign
|
||||
/// </summary>
|
||||
/// <param name="value">the value to format</param>
|
||||
/// <param name="category">the value type: none means just a number, distance will format in cm/m/km, angle with an appended degree sign</param>
|
||||
/// <returns>the formatted string</returns>
|
||||
public static string FormatFloat(float value, ValueCategory category)
|
||||
{
|
||||
switch (category)
|
||||
{
|
||||
case ValueCategory.Distance:
|
||||
var absValue = Mathf.Abs(value);
|
||||
// in case a unit != cm this would be (value / Maters2Units * 100)
|
||||
if (absValue < Units.Meters2Units)
|
||||
return value.ToString("g7", CultureInfo.InvariantCulture) + "cm";
|
||||
if (absValue < Units.Meters2Units * 1000)
|
||||
return (value / Units.Meters2Units).ToString("g7", CultureInfo.InvariantCulture) + "m";
|
||||
return (value / 1000 / Units.Meters2Units).ToString("g7", CultureInfo.InvariantCulture) + "km";
|
||||
case ValueCategory.Angle: return value.ToString("g7", CultureInfo.InvariantCulture) + "°";
|
||||
case ValueCategory.None:
|
||||
default:
|
||||
return FormatFloat(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format a double value either as-is, with a distance unit or with a degree sign
|
||||
/// </summary>
|
||||
/// <param name="value">the value to format</param>
|
||||
/// <param name="category">the value type: none means just a number, distance will format in cm/m/km, angle with an appended degree sign</param>
|
||||
/// <returns>the formatted string</returns>
|
||||
public static string FormatFloat(double value, ValueCategory category)
|
||||
{
|
||||
switch (category)
|
||||
{
|
||||
case ValueCategory.Distance:
|
||||
var absValue = Mathf.Abs(value);
|
||||
// in case a unit != cm this would be (value / Maters2Units * 100)
|
||||
if (absValue < Units.Meters2Units)
|
||||
return value.ToString("g17", CultureInfo.InvariantCulture) + "cm";
|
||||
if (absValue < Units.Meters2Units * 1000)
|
||||
return (value / Units.Meters2Units).ToString("g17", CultureInfo.InvariantCulture) + "m";
|
||||
return (value / 1000 / Units.Meters2Units).ToString("g17", CultureInfo.InvariantCulture) + "km";
|
||||
case ValueCategory.Angle: return value.ToString("g17", CultureInfo.InvariantCulture) + "°";
|
||||
case ValueCategory.None:
|
||||
default:
|
||||
return FormatFloat(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats the floating point value (double precision) into the readable text representation.
|
||||
/// </summary>
|
||||
@@ -1182,7 +1242,7 @@ namespace FlaxEditor.Utilities
|
||||
return "Infinity";
|
||||
if (float.IsNegativeInfinity(value) || value == float.MinValue)
|
||||
return "-Infinity";
|
||||
string str = value.ToString("r", CultureInfo.InvariantCulture);
|
||||
string str = value.ToString("g7", CultureInfo.InvariantCulture);
|
||||
return FormatFloat(str, value < 0);
|
||||
}
|
||||
|
||||
@@ -1197,7 +1257,7 @@ namespace FlaxEditor.Utilities
|
||||
return "Infinity";
|
||||
if (double.IsNegativeInfinity(value) || value == double.MinValue)
|
||||
return "-Infinity";
|
||||
string str = value.ToString("r", CultureInfo.InvariantCulture);
|
||||
string str = value.ToString("g17", CultureInfo.InvariantCulture);
|
||||
return FormatFloat(str, value < 0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user