Files
ClaudeDo/src/ClaudeDo.Ui/Converters/IconKeyConverter.cs
T

51 lines
1.8 KiB
C#

using System.Globalization;
using Avalonia;
using Avalonia.Data.Converters;
using Avalonia.Media;
using Material.Icons;
namespace ClaudeDo.Ui.Converters;
/// <summary>
/// Converts an icon key to its geometry: "Sun" → the "Icon.Sun" StreamGeometry resource,
/// "mdi:RocketLaunch" → the Material Design Icons path of that <see cref="MaterialIconKind"/>.
/// </summary>
public class IconKeyConverter : IValueConverter
{
/// <summary>Key prefix marking a Material Design Icons kind.</summary>
public const string MdiPrefix = "mdi:";
public static IconKeyConverter Instance { get; } = new();
private static readonly Dictionary<string, Geometry?> MdiCache = new();
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is not string key || string.IsNullOrEmpty(key))
return null;
if (key.StartsWith(MdiPrefix, StringComparison.Ordinal))
return MdiGeometry(key[MdiPrefix.Length..]);
var resourceKey = $"Icon.{key}";
if (Application.Current?.TryGetResource(resourceKey, null, out var res) == true)
return res as StreamGeometry;
return null;
}
/// <summary>Parses (and caches) the geometry for an MDI kind name; null for unknown names.</summary>
private static Geometry? MdiGeometry(string name)
{
if (MdiCache.TryGetValue(name, out var cached))
return cached;
var geometry = Enum.TryParse<MaterialIconKind>(name, out var kind)
? StreamGeometry.Parse(MaterialIconDataProvider.GetData(kind))
: null;
MdiCache[name] = geometry;
return geometry;
}
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
=> throw new NotSupportedException();
}