51 lines
1.8 KiB
C#
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();
|
|
}
|