using System.Globalization; using Unity.Properties; using UnityEngine; using UnityEngine.UIElements; namespace Uigenx.Binding { /// /// Converter groups the compiler can name from UXML (`source-to-ui-converters="ugx.percent"`) /// or the connector can apply in code. Registered once per domain load. /// public static class UgxConverters { public const string IntToString = "ugx.int-to-string"; public const string PercentWidth = "ugx.percent-width"; public const string BoolToDisplay = "ugx.bool-to-display"; static bool _registered; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] public static void Register() { if (_registered) return; _registered = true; var intToString = new ConverterGroup(IntToString, "Integer to text"); intToString.AddConverter((ref int v) => v.ToString(CultureInfo.InvariantCulture)); intToString.AddConverter((ref long v) => v.ToString(CultureInfo.InvariantCulture)); ConverterGroups.RegisterConverterGroup(intToString); // 0..1 becomes a percentage Length, which is what a bar's width binding wants. var percent = new ConverterGroup(PercentWidth, "Normalised value to percent width"); percent.AddConverter((ref float v) => new StyleLength(Length.Percent(Mathf.Clamp01(v) * 100f))); percent.AddConverter((ref float v) => Length.Percent(Mathf.Clamp01(v) * 100f)); ConverterGroups.RegisterConverterGroup(percent); var display = new ConverterGroup(BoolToDisplay, "Boolean to display style"); display.AddConverter((ref bool v) => v ? DisplayStyle.Flex : DisplayStyle.None); display.AddConverter((ref bool v) => new StyleEnum(v ? DisplayStyle.Flex : DisplayStyle.None)); ConverterGroups.RegisterConverterGroup(display); } public static bool TryGet(string id, out ConverterGroup group) { Register(); return ConverterGroups.TryGetConverterGroup(id, out group); } #if UNITY_EDITOR [UnityEditor.InitializeOnLoadMethod] static void RegisterInEditor() => Register(); #endif } }