1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00
Artemis/src/Artemis.UI.Shared/Controls/ProfileConfigurationIcon.axaml.cs
RobertBeekman 551921db9f
Storage - Replace LiteDB with SQLite + EF Core (#843)
Storage - Added LiteDB to SQLite migration
UI - Try to die a bit more gracefully
Core - Delay start watching plugins for hot reload after initializing
UI - Simplify category management logic
UI - Avoid crash during profile icon load
Storage - Fix entry metadata retrieval
2024-03-13 20:19:21 +01:00

145 lines
4.3 KiB
C#

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;
/// <summary>
/// Represents a control that can display the icon of a specific <see cref="ProfileConfiguration" />.
/// </summary>
public partial class ProfileConfigurationIcon : UserControl, IDisposable
{
private Stream? _stream;
/// <summary>
/// Creates a new instance of the <see cref="ProfileConfigurationIcon" /> class.
/// </summary>
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();
}
/// <inheritdoc />
public void Dispose()
{
if (Content is Image {Source: IDisposable d})
{
d.Dispose();
Content = null;
}
_stream?.Dispose();
}
#region Properties
/// <summary>
/// Gets or sets the <see cref="Core.ProfileConfigurationIcon" /> to display
/// </summary>
public static readonly StyledProperty<Core.ProfileConfigurationIcon?> ConfigurationIconProperty =
AvaloniaProperty.Register<ProfileConfigurationIcon, Core.ProfileConfigurationIcon?>(nameof(ConfigurationIcon));
/// <summary>
/// Gets or sets the <see cref="Core.ProfileConfigurationIcon" /> to display
/// </summary>
public Core.ProfileConfigurationIcon? ConfigurationIcon
{
get => GetValue(ConfigurationIconProperty);
set => SetValue(ConfigurationIconProperty, value);
}
#endregion
}