I’m currently trying to use a CustomStyleProperty to retrieve a my own custom “–custom-line-width” property from USS. I’ve set this up as follows (simplified example):
[UxmlElement]
public partial class UITest : VisualElement {
private static readonly CustomStyleProperty<float> CustomLineWidthStyleProperty = new("--custom-line-width");
private float _customLineWidth;
UITest() {
RegisterCallback<CustomStyleResolvedEvent>(OnCustomStyleResolved);
}
private void OnCustomStyleResolved(CustomStyleResolvedEvent evt) {
evt.customStyle.TryGetValue(CustomLineWidthStyleProperty, out _customLineWidth);
}
}
This all works as expected for Color and the like, but reading pixel values for a line width gives the error:
Trying to read custom property --custom-line-width value as Float while parsed type is Dimension
I can’t however see a Dimension type that TryGetValue supports, what type should I be using here?
The associated USS is:
UITest {
--custom-line-width: 5px;
}
Hi,
Dimension is an internal class, so this looks like it either needs exposing or we need to provide a conversion to float.
Could you please file a bug report so we can look into it? Unity QA: Building quality with passion
For now, you may be able to work around it by removing the “px” on the value, it should then be treated as a number instead of a Dimension,
Thanks, I have submitted as: IN-76502 (Now tracked publicly as: UUM-72374)
Removing the “px” does work, but gives differing results to a value of 1px (retrieve from another property). If I use my custom property to draw a line with that width, and then use resolvedStyle.borderBottomWidth with a USS value of 1px, they give differing widths. I suspect this is due to my Windows UI scale being set to 150% and px properties are handling this, where as float properties are not?
1 Like
resolvedStyle.border + padding are rounded to fit a whole pixel on screen.
2 Likes
I think exposing is a good idea. And it would be nice to have access to all parsed values/tokens of custom properties (not just the first item). I had to write some asmref/internal code to do just that and it was kind of a pain, but I saw some interesting uses for it
Unfortunately that bug report was closed as wont fix :(.
For future readers of this thread, You can use something similar to the class below in-place to achieve the same effect until this is properly supported (Use CustomLengthProperty
instead of CustomStyleProperty<float>
):
using UnityEditor;
namespace UnityEngine.UIElements {
public readonly struct CustomLengthProperty {
private readonly CustomStyleProperty<string> _internalProperty;
public CustomLengthProperty(string propertyName) {
_internalProperty = new CustomStyleProperty<string>(propertyName);
}
internal bool TryGetValue(ICustomStyle customStyle, out float value) {
if (!customStyle.TryGetValue(_internalProperty, out var dimension)) {
value = float.NaN;
return false;
}
// Dimensional values are not currently supported.
if (dimension.EndsWith("%")) {
value = float.NaN;
return false;
}
// All other values should be interpreted as pixel values, remove the suffix if present.
if (dimension.EndsWith("px")) {
dimension = dimension[..^2];
}
return float.TryParse(dimension, out value)) {
}
}
public static class CustomStyleExtensions {
public static bool TryGetValue(this ICustomStyle customStyle, CustomLengthProperty property, out float value) {
return property.TryGetValue(customStyle, out value);
}
}
}
You could extend this to deal with DPI scaling by multiplying by a value like EditorGUIUtility.pixelsPerPoint
or similar mechanism.
3 Likes