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:
parent
7954012e31
commit
19685eb516
@ -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
|
||||
|
||||
@ -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>
|
||||
103
src/Artemis.UI.Avalonia.Shared/Controls/ArtemisIcon.axaml.cs
Normal file
103
src/Artemis.UI.Avalonia.Shared/Controls/ArtemisIcon.axaml.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
|
||||
@ -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>
|
||||
@ -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()
|
||||
{
|
||||
|
||||
@ -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}" />
|
||||
|
||||
|
||||
@ -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()
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user