1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Shared UI - Added ArtemisIcon

Plugins - Added features display
This commit is contained in:
Robert 2021-11-11 23:38:14 +01:00
parent 7954012e31
commit 19685eb516
8 changed files with 227 additions and 24 deletions

View File

@ -4,6 +4,18 @@
<name>Artemis.UI.Avalonia.Shared</name>
</assembly>
<members>
<member name="F:Artemis.UI.Avalonia.Shared.Controls.ArtemisIcon.IconProperty">
<summary>
Gets or sets the currently displayed icon as either a <see cref="T:Material.Icons.MaterialIconKind" /> or an <see cref="T:System.Uri" /> pointing
to an SVG
</summary>
</member>
<member name="P:Artemis.UI.Avalonia.Shared.Controls.ArtemisIcon.Icon">
<summary>
Gets or sets the currently displayed icon as either a <see cref="T:Material.Icons.MaterialIconKind" /> or an <see cref="T:System.Uri" /> pointing
to an SVG
</summary>
</member>
<member name="T:Artemis.UI.Avalonia.Shared.Controls.DeviceVisualizer">
<summary>
Visualizes an <see cref="T:Artemis.Core.ArtemisDevice" /> with optional per-LED colors

View File

@ -0,0 +1,8 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Avalonia.Shared.Controls.ArtemisIcon">
Welcome to Avalonia!
</UserControl>

View File

@ -0,0 +1,103 @@
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Layout;
using Avalonia.LogicalTree;
using Avalonia.Markup.Xaml;
using Avalonia.Media.Imaging;
using Avalonia.Svg.Skia;
using Material.Icons;
using Material.Icons.Avalonia;
namespace Artemis.UI.Avalonia.Shared.Controls
{
public partial class ArtemisIcon : UserControl
{
#region Properties
/// <summary>
/// Gets or sets the currently displayed icon as either a <see cref="MaterialIconKind" /> or an <see cref="Uri" /> pointing
/// to an SVG
/// </summary>
public static readonly StyledProperty<object?> IconProperty =
AvaloniaProperty.Register<ArtemisIcon, object?>(nameof(Icon), notifying: IconChanging);
private static void IconChanging(IAvaloniaObject sender, bool before)
{
if (before)
((ArtemisIcon) sender).Update();
}
private void Update()
{
try
{
// First look for an enum value instead of a string
if (Icon is MaterialIconKind materialIcon)
Content = new MaterialIcon {Kind = materialIcon, Width = Bounds.Width, Height = Bounds.Height };
// If it's a string there are several options
else if (Icon is string iconString)
{
// An enum defined as a string
if (Enum.TryParse(iconString, true, out MaterialIconKind parsedIcon))
Content = new MaterialIcon {Kind = parsedIcon, Width = Bounds.Width, Height = Bounds.Height};
// An URI pointing to an SVG
else if (iconString.EndsWith(".svg"))
{
SvgSource source = new();
source.Load(iconString);
Content = new SvgImage {Source = source};
}
// An URI pointing to a different kind of image
else
Content = new Image {Source = new Bitmap(iconString), Width = Bounds.Width, Height = Bounds.Height };
}
}
catch
{
Content = new MaterialIcon {Kind = MaterialIconKind.QuestionMark, Width = Bounds.Width, Height = Bounds.Height };
}
}
/// <summary>
/// Gets or sets the currently displayed icon as either a <see cref="MaterialIconKind" /> or an <see cref="Uri" /> pointing
/// to an SVG
/// </summary>
public object? Icon
{
get => GetValue(IconProperty);
set => SetValue(IconProperty, value);
}
#endregion
public ArtemisIcon()
{
InitializeComponent();
DetachedFromLogicalTree += OnDetachedFromLogicalTree;
LayoutUpdated += OnLayoutUpdated;
}
private void OnLayoutUpdated(object? sender, EventArgs e)
{
if (Content is Control contentControl)
{
contentControl.Width = Bounds.Width;
contentControl.Height = Bounds.Height;
}
}
private void OnDetachedFromLogicalTree(object? sender, LogicalTreeAttachmentEventArgs e)
{
if (Content is SvgImage svgImage)
svgImage.Source?.Dispose();
else if (Content is Image image)
((Bitmap) image.Source).Dispose();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}

View File

@ -40,29 +40,35 @@ namespace Artemis.UI.Avalonia.Shared.Controls
PropertyChanged += OnPropertyChanged;
}
private void Update()
{
if (ConfigurationIcon == null)
return;
if (ConfigurationIcon.IconType == ProfileConfigurationIconType.SvgImage && ConfigurationIcon.FileIcon != null)
try
{
SvgSource source = new();
source.Load(ConfigurationIcon.FileIcon);
Content = new SvgImage {Source = source};
if (ConfigurationIcon.IconType == ProfileConfigurationIconType.SvgImage && ConfigurationIcon.FileIcon != null)
{
SvgSource source = new();
source.Load(ConfigurationIcon.FileIcon);
Content = new SvgImage {Source = source};
}
else if (ConfigurationIcon.IconType == ProfileConfigurationIconType.MaterialIcon && ConfigurationIcon.MaterialIcon != null)
{
Content = Enum.TryParse(ConfigurationIcon.MaterialIcon, true, out MaterialIconKind parsedIcon)
? new MaterialIcon {Kind = parsedIcon!}
: new MaterialIcon {Kind = MaterialIconKind.QuestionMark};
}
else if (ConfigurationIcon.IconType == ProfileConfigurationIconType.BitmapImage && ConfigurationIcon.FileIcon != null)
Content = new Image {Source = new Bitmap(ConfigurationIcon.FileIcon)};
else
Content = new MaterialIcon {Kind = MaterialIconKind.QuestionMark};
}
else if (ConfigurationIcon.IconType == ProfileConfigurationIconType.MaterialIcon && ConfigurationIcon.MaterialIcon != null)
catch
{
Content = Enum.TryParse(typeof(MaterialIconKind), ConfigurationIcon.MaterialIcon, true, out object? parsedIcon)
? new MaterialIcon {Kind = (MaterialIconKind) parsedIcon!}
: new MaterialIcon {Kind = MaterialIconKind.QuestionMark};
}
else if (ConfigurationIcon.IconType == ProfileConfigurationIconType.BitmapImage && ConfigurationIcon.FileIcon != null)
Content = new Image {Source = new Bitmap(ConfigurationIcon.FileIcon)};
else
Content = new MaterialIcon {Kind = MaterialIconKind.QuestionMark};
}
}
private void InitializeComponent()
@ -76,6 +82,11 @@ namespace Artemis.UI.Avalonia.Shared.Controls
{
if (ConfigurationIcon != null)
ConfigurationIcon.PropertyChanged -= IconOnPropertyChanged;
if (Content is SvgImage svgImage)
svgImage.Source?.Dispose();
else if (Content is Image image)
((Bitmap) image.Source).Dispose();
}
private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)

View File

@ -2,7 +2,71 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:shared="clr-namespace:Artemis.UI.Avalonia.Shared.Controls;assembly=Artemis.UI.Avalonia.Shared"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Avalonia.Screens.Plugins.Views.PluginFeatureView">
Welcome to Avalonia!
</UserControl>
<Grid ColumnDefinitions="30,*,Auto">
<Grid.ContextFlyout>
<MenuFlyout>
<MenuItem Header="Install prerequisites" Command="{Binding InstallPrerequisites}">
<MenuItem.Icon>
<avalonia:MaterialIcon Kind="CheckAll" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Remove prerequisites" Command="{Binding RemovePrerequisites}">
<MenuItem.Icon>
<avalonia:MaterialIcon Kind="Delete" />
</MenuItem.Icon>
</MenuItem>
</MenuFlyout>
</Grid.ContextFlyout>
<!-- Icon column -->
<shared:ArtemisIcon Grid.Column="0"
Icon="{Binding FeatureInfo.ResolvedIcon}"
Width="20"
Height="20"
IsVisible="{Binding LoadException, Converter={x:Static ObjectConverters.IsNull}}" />
<Button Grid.Column="0"
Margin="-8"
IsVisible="{Binding LoadException, Converter={x:Static ObjectConverters.IsNotNull}}"
Foreground="#E74C4C"
ToolTip.Tip="An exception occurred while enabling this feature, click to view"
Command="{Binding ViewLoadException}">
<avalonia:MaterialIcon Kind="AlertCircle" />
</Button>
<!-- Display name column -->
<TextBlock Grid.Column="1"
Text="{Binding FeatureInfo.Name}"
TextWrapping="Wrap"
VerticalAlignment="Center"
ToolTip.Tip="{Binding FeatureInfo.Description}" />
<!-- Enable toggle column -->
<StackPanel Grid.Column="2"
HorizontalAlignment="Right"
IsVisible="{Binding !Enabling}"
Orientation="Horizontal"
ToolTip.Tip="This feature cannot be disabled without disabling the whole plugin">
<avalonia:MaterialIcon Kind="ShieldHalfFull"
ToolTip.Tip="Plugin requires admin rights"
VerticalAlignment="Center"
Margin="0 0 5 0"
IsVisible="{Binding ShowShield}" />
<CheckBox IsChecked="{Binding IsEnabled}" IsEnabled="{Binding CanToggleEnabled}">
Feature enabled
</CheckBox>
</StackPanel>
<StackPanel Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="7" IsVisible="{Binding Enabling}">
<ProgressBar Value="0" IsIndeterminate="True" />
</StackPanel>
</Grid>
</UserControl>

View File

@ -1,9 +1,11 @@
using Artemis.UI.Avalonia.Screens.Plugins.ViewModels;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Avalonia.Screens.Plugins.Views
{
public partial class PluginFeatureView : UserControl
public partial class PluginFeatureView : ReactiveUserControl<PluginFeatureViewModel>
{
public PluginFeatureView()
{

View File

@ -4,18 +4,19 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:shared="clr-namespace:Artemis.UI.Avalonia.Shared.Controls;assembly=Artemis.UI.Avalonia.Shared"
mc:Ignorable="d" d:DesignWidth="900" d:DesignHeight="450"
x:Class="Artemis.UI.Avalonia.Screens.Plugins.Views.PluginSettingsView">
<Border Classes="card" Width="900" Padding="15" Margin="0 5">
<Grid RowDefinitions="*,Auto" ColumnDefinitions="4*,5*">
<Grid Grid.Row="0" RowDefinitions="Auto,Auto,*" ColumnDefinitions="80,*">
<avalonia:MaterialIcon Kind="{Binding Plugin.Info.ResolvedIcon}"
Width="48"
Height="48"
Margin="0 5 0 0"
Grid.Row="0"
Grid.RowSpan="3"
VerticalAlignment="Top" />
<shared:ArtemisIcon Icon="{Binding Plugin.Info.ResolvedIcon}"
Width="48"
Height="48"
Margin="0 5 0 0"
Grid.Row="0"
Grid.RowSpan="3"
VerticalAlignment="Top" />
<TextBlock Grid.Column="1" Grid.Row="0" Classes="h5 no-margin" Text="{Binding Plugin.Info.Name}" />

View File

@ -1,9 +1,11 @@
using Artemis.UI.Avalonia.Screens.Plugins.ViewModels;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Avalonia.Screens.Plugins.Views
{
public partial class PluginSettingsView : UserControl
public partial class PluginSettingsView : ReactiveUserControl<PluginSettingsViewModel>
{
public PluginSettingsView()
{