mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 03:48:56 +00:00
Plugins - Implemented features
Core - Removed Stylet dependency for #500
This commit is contained in:
1 parent
b56966c585
commit
e812929215
139 files changed
+1635
-1106
No files matched your search
@@ -55,7 +55,7 @@ namespace Artemis.UI.Screens.Settings.Debug
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Device.PluginImplementation.PluginInfo.Directory.FullName);
|
||||
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Device.PluginFeature.Plugin.Directory.FullName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||
|
||||
private void PopulateModules()
|
||||
{
|
||||
Modules = _pluginManagementService.GetPluginsOfType<Module>().Where(p => p.IsEnabled).ToList();
|
||||
Modules = _pluginManagementService.GetFeaturesOfType<Module>().Where(p => p.IsEnabled).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Devices
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Device.PluginImplementation.PluginInfo.Directory.FullName);
|
||||
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Device.PluginFeature.Plugin.Directory.FullName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -46,12 +46,12 @@ namespace Artemis.UI.Screens.Settings.Tabs.General
|
||||
// Anything else is kinda broken right now
|
||||
SampleSizes = new List<int> {1, 9};
|
||||
|
||||
List<LayerBrushProvider> layerBrushProviders = pluginManagementService.GetPluginsOfType<LayerBrushProvider>();
|
||||
List<LayerBrushProvider> layerBrushProviders = pluginManagementService.GetFeaturesOfType<LayerBrushProvider>();
|
||||
|
||||
LayerBrushDescriptors = new BindableCollection<LayerBrushDescriptor>(layerBrushProviders.SelectMany(l => l.LayerBrushDescriptors));
|
||||
_defaultLayerBrushDescriptor = _settingsService.GetSetting("ProfileEditor.DefaultLayerBrushDescriptor", new LayerBrushReference
|
||||
{
|
||||
BrushPluginGuid = Guid.Parse("92a9d6ba-6f7a-4937-94d5-c1d715b4141a"),
|
||||
LayerBrushProviderId = "Artemis.Plugins.LayerBrushes.Color.ColorBrushProvider-92a9d6ba",
|
||||
BrushType = "ColorBrush"
|
||||
});
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Modules
|
||||
|
||||
_pluginManagementService = pluginManagementService;
|
||||
_moduleService = moduleService;
|
||||
_modules = new List<ModuleOrderModuleViewModel>(pluginManagementService.GetPluginsOfType<Module>().Select(m => new ModuleOrderModuleViewModel(m)));
|
||||
_modules = new List<ModuleOrderModuleViewModel>(pluginManagementService.GetFeaturesOfType<Module>().Select(m => new ModuleOrderModuleViewModel(m)));
|
||||
_defaultDropHandler = new DefaultDropHandler();
|
||||
|
||||
NormalModules = new BindableCollection<ModuleOrderModuleViewModel>();
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.Settings.Tabs.Plugins.PluginFeatureView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Artemis.UI.Screens.Settings.Tabs.Plugins"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance local:PluginFeatureViewModel}">
|
||||
<Grid Margin="-3 -8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="30" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Icon column -->
|
||||
<materialDesign:PackIcon Kind="{Binding Icon}" VerticalAlignment="Center" HorizontalAlignment="Center" />
|
||||
<!-- Display name column -->
|
||||
<TextBlock Grid.Column="1" Text="{Binding Name}" VerticalAlignment="Center" />
|
||||
|
||||
<!-- Enable toggle column -->
|
||||
<StackPanel Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="8"
|
||||
Visibility="{Binding Enabling, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}">
|
||||
<CheckBox Style="{StaticResource MaterialDesignCheckBox}" IsChecked="{Binding IsEnabled}">
|
||||
Feature enabled
|
||||
</CheckBox>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="8"
|
||||
Visibility="{Binding Enabling, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
<ProgressBar Style="{StaticResource MaterialDesignCircularProgressBar}" Value="0" IsIndeterminate="True" />
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,160 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.DeviceProviders;
|
||||
using Artemis.Core.LayerBrushes;
|
||||
using Artemis.Core.LayerEffects;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Humanizer;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
{
|
||||
public class PluginFeatureViewModel : Screen
|
||||
{
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly IPluginManagementService _pluginManagementService;
|
||||
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
|
||||
private bool _enabling;
|
||||
private bool _isEnabled;
|
||||
|
||||
public PluginFeatureViewModel(PluginFeature feature,
|
||||
IDialogService dialogService,
|
||||
IPluginManagementService pluginManagementService,
|
||||
ISnackbarMessageQueue snackbarMessageQueue)
|
||||
{
|
||||
_dialogService = dialogService;
|
||||
_pluginManagementService = pluginManagementService;
|
||||
_snackbarMessageQueue = snackbarMessageQueue;
|
||||
|
||||
Feature = feature;
|
||||
Icon = GetIconKind();
|
||||
|
||||
IsEnabled = Feature.IsEnabled;
|
||||
}
|
||||
|
||||
public PluginFeature Feature { get; }
|
||||
public PackIconKind Icon { get; }
|
||||
|
||||
public string Name => Feature.GetType().Name.Humanize();
|
||||
|
||||
public Exception LoadException => Feature.LoadException;
|
||||
|
||||
public bool Enabling
|
||||
{
|
||||
get => _enabling;
|
||||
set => SetAndNotify(ref _enabling, value);
|
||||
}
|
||||
|
||||
public bool IsEnabled
|
||||
{
|
||||
get => _isEnabled;
|
||||
set => SetAndNotify(ref _isEnabled, value);
|
||||
}
|
||||
|
||||
public void ShowLogsFolder()
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_dialogService.ShowExceptionDialog("Welp, we couldn\'t open the logs folder for you", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
{
|
||||
base.OnInitialActivate();
|
||||
_pluginManagementService.PluginFeatureEnabling += OnFeatureEnabling;
|
||||
_pluginManagementService.PluginFeatureEnabled += OnFeatureEnableStopped;
|
||||
_pluginManagementService.PluginFeatureEnableFailed += OnFeatureEnableStopped;
|
||||
}
|
||||
|
||||
protected override void OnClose()
|
||||
{
|
||||
base.OnClose();
|
||||
_pluginManagementService.PluginFeatureEnabling -= OnFeatureEnabling;
|
||||
_pluginManagementService.PluginFeatureEnabled -= OnFeatureEnableStopped;
|
||||
_pluginManagementService.PluginFeatureEnableFailed -= OnFeatureEnableStopped;
|
||||
}
|
||||
|
||||
private async Task UpdateEnabled(bool enable)
|
||||
{
|
||||
if (IsEnabled == enable)
|
||||
{
|
||||
NotifyOfPropertyChange(nameof(IsEnabled));
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable)
|
||||
{
|
||||
Enabling = true;
|
||||
|
||||
try
|
||||
{
|
||||
await Task.Run(() => _pluginManagementService.EnablePluginFeature(Feature));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_snackbarMessageQueue.Enqueue($"Failed to enable {Name}\r\n{e.Message}", "VIEW LOGS", ShowLogsFolder);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Enabling = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_pluginManagementService.DisablePluginFeature(Feature);
|
||||
}
|
||||
}
|
||||
|
||||
private PackIconKind GetIconKind()
|
||||
{
|
||||
switch (Feature)
|
||||
{
|
||||
case BaseDataModelExpansion _:
|
||||
return PackIconKind.TableAdd;
|
||||
case DeviceProvider _:
|
||||
return PackIconKind.Devices;
|
||||
case ProfileModule _:
|
||||
return PackIconKind.VectorRectangle;
|
||||
case Module _:
|
||||
return PackIconKind.GearBox;
|
||||
case LayerBrushProvider _:
|
||||
return PackIconKind.Brush;
|
||||
case LayerEffectProvider _:
|
||||
return PackIconKind.AutoAwesome;
|
||||
}
|
||||
|
||||
return PackIconKind.Plugin;
|
||||
}
|
||||
|
||||
#region Event handlers
|
||||
|
||||
private void OnFeatureEnabling(object? sender, PluginFeatureEventArgs e)
|
||||
{
|
||||
if (e.PluginFeature != Feature) return;
|
||||
Enabling = true;
|
||||
}
|
||||
|
||||
private void OnFeatureEnableStopped(object? sender, PluginFeatureEventArgs e)
|
||||
{
|
||||
if (e.PluginFeature != Feature) return;
|
||||
Enabling = false;
|
||||
IsEnabled = e.PluginFeature.IsEnabled;
|
||||
|
||||
NotifyOfPropertyChange(nameof(LoadException));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
{
|
||||
private readonly IPluginManagementService _pluginManagementService;
|
||||
private readonly ISettingsVmFactory _settingsVmFactory;
|
||||
private BindableCollection<PluginSettingsViewModel> _plugins;
|
||||
|
||||
public PluginSettingsTabViewModel(IPluginManagementService pluginManagementService, ISettingsVmFactory settingsVmFactory)
|
||||
{
|
||||
@@ -29,8 +28,8 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
Items.Clear();
|
||||
await Task.Delay(200);
|
||||
|
||||
List<PluginSettingsViewModel> instances = _pluginManagementService.GetAllPluginInfo().Select(p => _settingsVmFactory.CreatePluginSettingsViewModel(p.Plugin)).ToList();
|
||||
foreach (PluginSettingsViewModel pluginSettingsViewModel in instances)
|
||||
List<PluginSettingsViewModel> instances = _pluginManagementService.GetAllPlugins().Select(p => _settingsVmFactory.CreatePluginSettingsViewModel(p)).ToList();
|
||||
foreach (PluginSettingsViewModel pluginSettingsViewModel in instances.OrderBy(i => i.Plugin.Info.Name))
|
||||
Items.Add(pluginSettingsViewModel);
|
||||
});
|
||||
|
||||
|
||||
@@ -6,17 +6,19 @@
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:devices="clr-namespace:Artemis.UI.Screens.Settings.Tabs.Plugins"
|
||||
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
|
||||
d:DataContext="{d:DesignInstance devices:PluginSettingsViewModel}"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<materialDesign:Card Width="400">
|
||||
<materialDesign:Card Width="800">
|
||||
<Grid Margin="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="2*" />
|
||||
<ColumnDefinition Width="3*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="100" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
@@ -24,45 +26,27 @@
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="80" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<materialDesign:PackIcon Kind="{Binding Icon}" Width="48" Height="48" Grid.Row="0" Grid.RowSpan="2" HorizontalAlignment="Center" />
|
||||
|
||||
<TextBlock Grid.Column="1" Grid.Row="0" Style="{StaticResource MaterialDesignTextBlock}" Text="{Binding PluginInfo.Name}" />
|
||||
<Button Grid.Column="2" Grid.Row="0"
|
||||
Background="#FF4343"
|
||||
BorderBrush="#FF7474"
|
||||
Foreground="White"
|
||||
Height="22"
|
||||
Padding="4"
|
||||
Margin="0 -18 0 0"
|
||||
Visibility="{Binding DisplayLoadFailed, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}"
|
||||
Style="{StaticResource MaterialDesignRaisedButton}"
|
||||
ToolTip="Click to see the full error that occured"
|
||||
Command="{s:Action ShowLoadException}">
|
||||
<TextBlock FontSize="11">LOAD FAILED</TextBlock>
|
||||
</Button>
|
||||
<Button Grid.Column="2" Grid.Row="0"
|
||||
Height="22"
|
||||
Padding="4"
|
||||
Margin="0 -18 0 0"
|
||||
Visibility="{Binding RequiresRestart, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}"
|
||||
Style="{StaticResource MaterialDesignRaisedButton}"
|
||||
ToolTip="Click to restart"
|
||||
Command="{s:Action Restart}">
|
||||
<TextBlock FontSize="11">NEEDS RESTART</TextBlock>
|
||||
</Button>
|
||||
<controls:ArtemisIcon Icon="{Binding Icon}"
|
||||
Width="48"
|
||||
Height="48"
|
||||
Margin="0 5 0 0"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Top" />
|
||||
|
||||
<TextBlock Grid.Column="1" Grid.Row="0" Style="{StaticResource MaterialDesignBody2TextBlock}" Text="{Binding Plugin.Info.Name}" />
|
||||
|
||||
<TextBlock Grid.Column="1"
|
||||
Grid.Row="1"
|
||||
Grid.ColumnSpan="2"
|
||||
TextWrapping="Wrap"
|
||||
Text="{Binding PluginInfo.Description}"
|
||||
Text="{Binding Plugin.Info.Description}"
|
||||
Style="{StaticResource MaterialDesignTextBlock}"
|
||||
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" />
|
||||
</Grid>
|
||||
@@ -82,6 +66,23 @@
|
||||
Visibility="{Binding Enabling, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
<ProgressBar Style="{StaticResource MaterialDesignCircularProgressBar}" Value="0" IsIndeterminate="True" />
|
||||
</StackPanel>
|
||||
|
||||
<Border Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" BorderBrush="{StaticResource MaterialDesignDivider}" BorderThickness="1 0 0 0" Margin="10 0 0 0" Padding="10 0 0 0">
|
||||
<StackPanel>
|
||||
<TextBlock Margin="10 10 0 5" Style="{StaticResource MaterialDesignBody2TextBlock}">Plugin features</TextBlock>
|
||||
<ListBox ItemsSource="{Binding Items}"
|
||||
materialDesign:RippleAssist.IsDisabled="True"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
VirtualizingPanel.ScrollUnit="Pixel">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</StackPanel>
|
||||
|
||||
</Border>
|
||||
</Grid>
|
||||
</materialDesign:Card>
|
||||
</UserControl>
|
||||
@@ -2,64 +2,50 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.DeviceProviders;
|
||||
using Artemis.Core.LayerBrushes;
|
||||
using Artemis.Core.LayerEffects;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Exceptions;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Ninject;
|
||||
using Ninject.Parameters;
|
||||
using Serilog;
|
||||
using Stylet;
|
||||
using Module = Artemis.Core.Modules.Module;
|
||||
|
||||
namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
{
|
||||
public class PluginSettingsViewModel : PropertyChangedBase
|
||||
public class PluginSettingsViewModel : Conductor<PluginFeatureViewModel>.Collection.AllActive
|
||||
{
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IPluginManagementService _pluginManagementService;
|
||||
private readonly ISettingsVmFactory _settingsVmFactory;
|
||||
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
|
||||
private readonly IWindowManager _windowManager;
|
||||
private bool _enabling;
|
||||
private PluginImplementation _pluginImplementation;
|
||||
private PluginInfo _pluginInfo;
|
||||
private Plugin _plugin;
|
||||
|
||||
public PluginSettingsViewModel(PluginImplementation pluginImplementation,
|
||||
ILogger logger,
|
||||
public PluginSettingsViewModel(Plugin plugin,
|
||||
ISettingsVmFactory settingsVmFactory,
|
||||
IWindowManager windowManager,
|
||||
IDialogService dialogService,
|
||||
IPluginManagementService pluginManagementService,
|
||||
ISnackbarMessageQueue snackbarMessageQueue)
|
||||
{
|
||||
PluginImplementation = pluginImplementation;
|
||||
PluginInfo = pluginImplementation.PluginInfo;
|
||||
Plugin = plugin;
|
||||
|
||||
_logger = logger;
|
||||
_settingsVmFactory = settingsVmFactory;
|
||||
_windowManager = windowManager;
|
||||
_dialogService = dialogService;
|
||||
_pluginManagementService = pluginManagementService;
|
||||
_snackbarMessageQueue = snackbarMessageQueue;
|
||||
|
||||
Icon = PluginUtilities.GetPluginIcon(Plugin, Plugin.Info.Icon);
|
||||
}
|
||||
|
||||
public PluginImplementation PluginImplementation
|
||||
public Plugin Plugin
|
||||
{
|
||||
get => _pluginImplementation;
|
||||
set => SetAndNotify(ref _pluginImplementation, value);
|
||||
}
|
||||
|
||||
public PluginInfo PluginInfo
|
||||
{
|
||||
get => _pluginInfo;
|
||||
set => SetAndNotify(ref _pluginInfo, value);
|
||||
get => _plugin;
|
||||
set => SetAndNotify(ref _plugin, value);
|
||||
}
|
||||
|
||||
public bool Enabling
|
||||
@@ -68,34 +54,25 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
set => SetAndNotify(ref _enabling, value);
|
||||
}
|
||||
|
||||
public PackIconKind Icon => GetIconKind();
|
||||
public string Type => PluginImplementation.GetType().BaseType?.Name ?? PluginImplementation.GetType().Name;
|
||||
public bool CanOpenSettings => IsEnabled && PluginImplementation.ConfigurationDialog != null;
|
||||
public bool DisplayLoadFailed => !Enabling && PluginInfo.LoadException != null;
|
||||
public bool RequiresRestart => PluginImplementation.IsEnabled && !PluginInfo.IsEnabled;
|
||||
public object Icon { get; set; }
|
||||
public string Type => Plugin.GetType().BaseType?.Name ?? Plugin.GetType().Name;
|
||||
public bool CanOpenSettings => IsEnabled && Plugin.ConfigurationDialog != null;
|
||||
|
||||
public bool IsEnabled
|
||||
{
|
||||
get => PluginImplementation.PluginInfo.IsEnabled;
|
||||
get => Plugin.IsEnabled;
|
||||
set => Task.Run(() => UpdateEnabled(value));
|
||||
}
|
||||
|
||||
public void OpenSettings()
|
||||
{
|
||||
PluginConfigurationDialog configurationViewModel = PluginImplementation.ConfigurationDialog;
|
||||
PluginConfigurationDialog configurationViewModel = (PluginConfigurationDialog) Plugin.ConfigurationDialog;
|
||||
if (configurationViewModel == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
// Limit to one constructor, there's no need to have more and it complicates things anyway
|
||||
ConstructorInfo[] constructors = configurationViewModel.Type.GetConstructors();
|
||||
if (constructors.Length != 1)
|
||||
throw new ArtemisUIException("Plugin configuration dialogs must have exactly one constructor");
|
||||
|
||||
ParameterInfo pluginParameter = constructors.First().GetParameters().First(p => typeof(PluginImplementation).IsAssignableFrom(p.ParameterType));
|
||||
ConstructorArgument plugin = new ConstructorArgument(pluginParameter.Name, PluginImplementation);
|
||||
PluginConfigurationViewModel viewModel = (PluginConfigurationViewModel) PluginInfo.Kernel.Get(configurationViewModel.Type, plugin);
|
||||
PluginConfigurationViewModel viewModel = (PluginConfigurationViewModel) Plugin.Kernel.Get(configurationViewModel.Type);
|
||||
_windowManager.ShowDialog(new PluginSettingsWindowViewModel(viewModel, Icon));
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -117,49 +94,22 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowLoadException()
|
||||
protected override void OnInitialActivate()
|
||||
{
|
||||
if (PluginInfo.LoadException == null)
|
||||
return;
|
||||
Plugin.FeatureAdded += PluginOnFeatureAdded;
|
||||
Plugin.FeatureRemoved += PluginOnFeatureRemoved;
|
||||
foreach (PluginFeature pluginFeature in Plugin.Features)
|
||||
Items.Add(_settingsVmFactory.CreatePluginFeatureViewModel(pluginFeature));
|
||||
|
||||
_dialogService.ShowExceptionDialog("The plugin failed to load: " + PluginInfo.LoadException.Message, PluginInfo.LoadException);
|
||||
base.OnInitialActivate();
|
||||
}
|
||||
|
||||
public async Task Restart()
|
||||
protected override void OnClose()
|
||||
{
|
||||
_logger.Debug("Restarting for device provider disable {pluginInfo}", PluginImplementation.PluginInfo);
|
||||
Plugin.FeatureAdded -= PluginOnFeatureAdded;
|
||||
Plugin.FeatureRemoved -= PluginOnFeatureRemoved;
|
||||
|
||||
// Give the logger a chance to write, might not always be enough but oh well
|
||||
await Task.Delay(500);
|
||||
Core.Utilities.Shutdown(2, true);
|
||||
}
|
||||
|
||||
private PackIconKind GetIconKind()
|
||||
{
|
||||
if (PluginInfo.Icon != null)
|
||||
{
|
||||
bool parsedIcon = Enum.TryParse<PackIconKind>(PluginInfo.Icon, true, out PackIconKind iconEnum);
|
||||
if (parsedIcon)
|
||||
return iconEnum;
|
||||
}
|
||||
|
||||
switch (PluginImplementation)
|
||||
{
|
||||
case BaseDataModelExpansion _:
|
||||
return PackIconKind.TableAdd;
|
||||
case DeviceProvider _:
|
||||
return PackIconKind.Devices;
|
||||
case ProfileModule _:
|
||||
return PackIconKind.VectorRectangle;
|
||||
case Module _:
|
||||
return PackIconKind.GearBox;
|
||||
case LayerBrushProvider _:
|
||||
return PackIconKind.Brush;
|
||||
case LayerEffectProvider _:
|
||||
return PackIconKind.AutoAwesome;
|
||||
}
|
||||
|
||||
return PackIconKind.Plugin;
|
||||
base.OnClose();
|
||||
}
|
||||
|
||||
private async Task UpdateEnabled(bool enable)
|
||||
@@ -170,24 +120,17 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
return;
|
||||
}
|
||||
|
||||
if (!enable && PluginImplementation is DeviceProvider)
|
||||
{
|
||||
await DisableDeviceProvider();
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable)
|
||||
{
|
||||
Enabling = true;
|
||||
NotifyOfPropertyChange(nameof(DisplayLoadFailed));
|
||||
|
||||
try
|
||||
{
|
||||
_pluginManagementService.EnablePluginImplementation(PluginImplementation);
|
||||
await Task.Run(() => _pluginManagementService.EnablePlugin(Plugin));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_snackbarMessageQueue.Enqueue($"Failed to enable plugin {PluginInfo.Name}\r\n{e.Message}", "VIEW LOGS", ShowLogsFolder);
|
||||
_snackbarMessageQueue.Enqueue($"Failed to enable plugin {Plugin.Info.Name}\r\n{e.Message}", "VIEW LOGS", ShowLogsFolder);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -195,44 +138,24 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
}
|
||||
}
|
||||
else
|
||||
_pluginManagementService.DisablePluginImplementation(PluginImplementation);
|
||||
{
|
||||
_pluginManagementService.DisablePlugin(Plugin);
|
||||
}
|
||||
|
||||
NotifyOfPropertyChange(nameof(IsEnabled));
|
||||
NotifyOfPropertyChange(nameof(CanOpenSettings));
|
||||
NotifyOfPropertyChange(nameof(RequiresRestart));
|
||||
NotifyOfPropertyChange(nameof(DisplayLoadFailed));
|
||||
}
|
||||
|
||||
private async Task DisableDeviceProvider()
|
||||
private void PluginOnFeatureRemoved(object? sender, PluginFeatureEventArgs e)
|
||||
{
|
||||
bool restart = false;
|
||||
PluginFeatureViewModel viewModel = Items.FirstOrDefault(i => i.Feature == e.PluginFeature);
|
||||
if (viewModel != null)
|
||||
Items.Remove(viewModel);
|
||||
}
|
||||
|
||||
// If any plugin already requires a restart, don't ask the user again
|
||||
bool restartQueued = _pluginManagementService.GetAllPluginInfo().Any(p => p.Plugin != null && !p.IsEnabled && p.Plugin.IsEnabled);
|
||||
// If the plugin isn't enabled (load failed), it can be disabled without a restart
|
||||
if (!restartQueued && PluginImplementation.IsEnabled)
|
||||
{
|
||||
restart = await _dialogService.ShowConfirmDialog(
|
||||
"Disable device provider",
|
||||
"You are disabling a device provider, Artemis has to restart to \r\nfully disable this type of plugin",
|
||||
"Restart now",
|
||||
"Restart later"
|
||||
);
|
||||
}
|
||||
|
||||
_pluginManagementService.DisablePluginImplementation(PluginImplementation);
|
||||
if (restart)
|
||||
{
|
||||
_logger.Debug("Restarting for device provider disable {pluginInfo}", PluginImplementation.PluginInfo);
|
||||
|
||||
// Give the logger a chance to write, might not always be enough but oh well
|
||||
await Task.Delay(500);
|
||||
Core.Utilities.Shutdown(2, true);
|
||||
}
|
||||
|
||||
NotifyOfPropertyChange(nameof(IsEnabled));
|
||||
NotifyOfPropertyChange(nameof(RequiresRestart));
|
||||
NotifyOfPropertyChange(nameof(DisplayLoadFailed));
|
||||
private void PluginOnFeatureAdded(object? sender, PluginFeatureEventArgs e)
|
||||
{
|
||||
Items.Add(_settingsVmFactory.CreatePluginFeatureViewModel(e.PluginFeature));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@
|
||||
Identifier="PluginSettingsDialog"
|
||||
DialogTheme="Inherit">
|
||||
<DockPanel>
|
||||
<controls:AppBar Type="Dense" Title="{Binding ActiveItem.PluginImplementation.PluginInfo.Name}" DockPanel.Dock="Top" Margin="-18 0 0 0" ShowShadow="False">
|
||||
<controls:AppBar Type="Dense" Title="{Binding ActiveItem.Plugin.Info.Name}" DockPanel.Dock="Top" Margin="-18 0 0 0" ShowShadow="False">
|
||||
<controls:AppBar.AppIcon>
|
||||
<materialDesign:PackIcon Kind="{Binding Icon}" Width="20" Height="28" />
|
||||
</controls:AppBar.AppIcon>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using Artemis.Core;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Artemis.UI.Shared;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
@@ -9,12 +8,14 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
{
|
||||
private readonly PluginConfigurationViewModel _configurationViewModel;
|
||||
|
||||
public PluginSettingsWindowViewModel(PluginConfigurationViewModel configurationViewModel, PackIconKind icon)
|
||||
public PluginSettingsWindowViewModel(PluginConfigurationViewModel configurationViewModel, object icon)
|
||||
{
|
||||
_configurationViewModel = configurationViewModel ?? throw new ArgumentNullException(nameof(configurationViewModel));
|
||||
Icon = icon;
|
||||
}
|
||||
|
||||
public object Icon { get; }
|
||||
|
||||
protected override void OnInitialActivate()
|
||||
{
|
||||
ActiveItem = _configurationViewModel;
|
||||
@@ -23,8 +24,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
base.OnInitialActivate();
|
||||
}
|
||||
|
||||
public PackIconKind Icon { get; }
|
||||
|
||||
private void ActiveItemOnClosed(object sender, CloseEventArgs e)
|
||||
{
|
||||
ActiveItem.Closed -= ActiveItemOnClosed;
|
||||
|
||||
Reference in new issue
Block a user