using System; using System.Globalization; using Avalonia.Data.Converters; namespace Avalonia.PropertyGrid.Controls; /// /// Converts indent level to left margin /// public sealed class IndentToMarginConverter : IValueConverter { /// /// Converts indent level to left margin. /// public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is int indentLevel) { return new Thickness(indentLevel * 16, 0, 0, 0); } return new Thickness(0); } /// /// Not implemented. /// public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// Converts enum type to list of enum values /// public sealed class EnumValuesConverter : IValueConverter { /// /// Converts an enum type to an array of its values. /// public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is Type enumType && enumType.IsEnum) { return Enum.GetValues(enumType); } return null; } /// /// Not implemented. /// public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// Checks if a type is an enum /// public sealed class IsEnumConverter : IValueConverter { /// /// Checks if the provided type is an enum. /// /// The Type to check. /// The target type. /// Optional parameter. /// Culture information. /// True if the type is an enum, otherwise false. public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is Type type) { return type.IsEnum; } return false; } /// /// Not supported for this converter. /// /// This converter does not support ConvertBack. public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// Checks if a type is a simple type (string, number, bool, etc.) /// public sealed class IsSimpleTypeConverter : IValueConverter { /// /// Checks if the provided type is a simple type like string, number, DateTime, etc. /// /// The Type to check. /// The target type. /// Optional parameter. /// Culture information. /// True if the type is a simple type, otherwise false. public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is Type type) { return type == typeof(string) || type == typeof(int) || type == typeof(long) || type == typeof(short) || type == typeof(uint) || type == typeof(ulong) || type == typeof(ushort) || type == typeof(byte) || type == typeof(sbyte) || type == typeof(float) || type == typeof(double) || type == typeof(decimal) || type == typeof(DateTime) || type == typeof(TimeSpan) || type == typeof(Guid) || type == typeof(DateTimeOffset) || !type.IsEnum; } return false; } /// /// Not supported for this converter. /// /// This converter does not support ConvertBack. public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// Checks if a type matches the specified type name /// public sealed class TypeToBoolConverter : IValueConverter { /// /// Checks if the type's name matches the specified parameter string. /// /// The Type to check. /// The target type. /// The type name to match against. /// Culture information. /// True if the type name matches, otherwise false. public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is Type type && parameter is string typeName) { return type.FullName == typeName || type.Name == typeName; } return false; } /// /// Not supported for this converter. /// /// This converter does not support ConvertBack. public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// Converts Color to/from hex string representation /// public sealed class ColorToStringConverter : IValueConverter { /// /// Converts a Color to a hex string representation. /// /// The Color to convert. /// The target type. /// Optional parameter. /// Culture information. /// A hex string representation of the color (e.g., "#AARRGGBB"). public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is Media.Color color) { return $"#{color.A:X2}{color.R:X2}{color.G:X2}{color.B:X2}"; } return value?.ToString(); } /// /// Converts a hex string back to a Color. /// /// The hex string to convert. /// The target type. /// Optional parameter. /// Culture information. /// The parsed Color, or Black if parsing fails. public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is string hexString && !string.IsNullOrWhiteSpace(hexString)) { try { hexString = hexString.Trim(); if (!hexString.StartsWith('#')) hexString = "#" + hexString; return Media.Color.Parse(hexString); } catch { // If parsing fails, return the original color or default return Media.Colors.Black; } } return null; } } /// /// Checks if a type is Color /// public sealed class IsColorTypeConverter : IValueConverter { /// /// Checks if the provided type is Avalonia.Media.Color. /// /// The Type to check. /// The target type. /// Optional "Invert" parameter to invert the result. /// Culture information. /// True if the type is Color (or inverted if parameter is "Invert"), otherwise false. public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is Type type) { bool isColor = type == typeof(Media.Color); // Support inverting the result if (parameter is string param && param.Equals("Invert", StringComparison.OrdinalIgnoreCase)) { return !isColor; } return isColor; } // Default to showing TextBox (inverted result) if (parameter is string param2 && param2.Equals("Invert", StringComparison.OrdinalIgnoreCase)) { return true; } return false; } /// /// Not supported for this converter. /// /// This converter does not support ConvertBack. public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// Checks if a type is numeric /// public sealed class IsNumericTypeConverter : IValueConverter { /// /// Checks if the provided type is a numeric type (int, long, float, double, decimal, etc.). /// /// The Type to check. /// The target type. /// Optional "Invert" parameter to invert the result. /// Culture information. /// True if the type is numeric (or inverted if parameter is "Invert"), otherwise false. public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is Type type) { bool isNumeric = type == typeof(int) || type == typeof(long) || type == typeof(short) || type == typeof(byte) || type == typeof(uint) || type == typeof(ulong) || type == typeof(ushort) || type == typeof(sbyte) || type == typeof(float) || type == typeof(double) || type == typeof(decimal); // Support inverting the result if (parameter is string param && param.Equals("Invert", StringComparison.OrdinalIgnoreCase)) { return !isNumeric; } return isNumeric; } // Default to showing TextBox (inverted result) if (parameter is string param2 && param2.Equals("Invert", StringComparison.OrdinalIgnoreCase)) { return true; } return false; } /// /// Not supported for this converter. /// /// This converter does not support ConvertBack. public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// Checks if a type is neither Color nor Numeric nor Boolean nor Enum (for fallback TextBox) /// public sealed class IsOtherTypeConverter : IValueConverter { /// /// Checks if the type is not Color, Numeric, Boolean, or Enum (used for fallback TextBox editor). /// /// The Type to check. /// The target type. /// Optional parameter. /// Culture information. /// True if the type is not a special type, otherwise false. public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is Type type) { bool isColor = type == typeof(Media.Color); bool isNumeric = type == typeof(int) || type == typeof(long) || type == typeof(short) || type == typeof(byte) || type == typeof(uint) || type == typeof(ulong) || type == typeof(ushort) || type == typeof(sbyte) || type == typeof(float) || type == typeof(double) || type == typeof(decimal); bool isBool = type == typeof(bool); bool isEnum = type.IsEnum; // Return true if it's neither color nor numeric nor boolean nor enum return !isColor && !isNumeric && !isBool && !isEnum; } return true; // Default to showing TextBox } /// /// Not supported for this converter. /// /// This converter does not support ConvertBack. public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// Checks if a type is boolean /// public sealed class IsBooleanTypeConverter : IValueConverter { /// /// Checks if the provided type is boolean. /// /// The Type to check. /// The target type. /// Optional "Invert" parameter to invert the result. /// Culture information. /// True if the type is boolean (or inverted if parameter is "Invert"), otherwise false. public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is Type type) { bool isBool = type == typeof(bool); // Support inverting the result if (parameter is string param && param.Equals("Invert", StringComparison.OrdinalIgnoreCase)) { return !isBool; } return isBool; } // Default to showing TextBox (inverted result) if (parameter is string param2 && param2.Equals("Invert", StringComparison.OrdinalIgnoreCase)) { return true; } return false; } /// /// Not supported for this converter. /// /// This converter does not support ConvertBack. public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotImplementedException(); } }