using System; using System.IO; using Artemis.Core; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Documents; using Avalonia.Layout; using Avalonia.LogicalTree; using Avalonia.Markup.Xaml; using Avalonia.Media; using Avalonia.Media.Imaging; using Avalonia.Threading; using Material.Icons; using Material.Icons.Avalonia; namespace Artemis.UI.Shared; /// /// Represents a control that can display the icon of a specific . /// public partial class ProfileConfigurationIcon : UserControl, IDisposable { private Stream? _stream; /// /// Creates a new instance of the class. /// public ProfileConfigurationIcon() { InitializeComponent(); DetachedFromLogicalTree += OnDetachedFromLogicalTree; PropertyChanged += OnPropertyChanged; } private void Update() { if (ConfigurationIcon == null) return; Dispose(); try { if (ConfigurationIcon.IconType == ProfileConfigurationIconType.MaterialIcon) { Content = Enum.TryParse(ConfigurationIcon.IconName, true, out MaterialIconKind parsedIcon) ? new MaterialIcon {Kind = parsedIcon!} : new MaterialIcon {Kind = MaterialIconKind.QuestionMark}; } else if (ConfigurationIcon.IconBytes != null) Dispatcher.UIThread.Post(LoadFromBitmap, DispatcherPriority.ApplicationIdle); else Content = new MaterialIcon {Kind = MaterialIconKind.QuestionMark}; } catch (Exception) { Content = new MaterialIcon {Kind = MaterialIconKind.QuestionMark}; } } private void LoadFromBitmap() { try { if (ConfigurationIcon?.IconBytes == null) return; _stream = new MemoryStream(ConfigurationIcon.IconBytes); if (!ConfigurationIcon.Fill) { Content = new Image {Source = new Bitmap(_stream)}; return; } Content = new Border { Background = TextElement.GetForeground(this), VerticalAlignment = VerticalAlignment.Stretch, HorizontalAlignment = HorizontalAlignment.Stretch, OpacityMask = new ImageBrush(new Bitmap(_stream)) }; } catch (Exception) { Content = new MaterialIcon {Kind = MaterialIconKind.QuestionMark}; } } private void OnDetachedFromLogicalTree(object? sender, LogicalTreeAttachmentEventArgs e) { if (ConfigurationIcon != null) ConfigurationIcon.IconUpdated -= ConfigurationIconOnIconUpdated; Dispose(); } private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) { if (e.Property != ConfigurationIconProperty) return; if (e.OldValue is Core.ProfileConfigurationIcon oldIcon) oldIcon.IconUpdated -= ConfigurationIconOnIconUpdated; if (e.NewValue is Core.ProfileConfigurationIcon newIcon) newIcon.IconUpdated += ConfigurationIconOnIconUpdated; Update(); } private void ConfigurationIconOnIconUpdated(object? sender, EventArgs e) { Update(); } /// public void Dispose() { if (Content is Image {Source: IDisposable d}) { d.Dispose(); Content = null; } _stream?.Dispose(); } #region Properties /// /// Gets or sets the to display /// public static readonly StyledProperty ConfigurationIconProperty = AvaloniaProperty.Register(nameof(ConfigurationIcon)); /// /// Gets or sets the to display /// public Core.ProfileConfigurationIcon? ConfigurationIcon { get => GetValue(ConfigurationIconProperty); set => SetValue(ConfigurationIconProperty, value); } #endregion }