Plugin prerequisites - Added UI for installing/removing prerequisites

Plugin settings - Added button to reload plugin from disk
Confirm dialogs - Made cancel text optional so you can hide the button
This commit is contained in:
Robert committed 2021-04-28 00:33:56 +02:00
1 parent f1874d9fe3
commit 0cfddcbbaf
25 files changed
+741 -158

No files matched your search

@@ -52,7 +52,7 @@
<CheckBox Style="{StaticResource MaterialDesignCheckBox}" IsChecked="{Binding IsDeviceEnabled}">
Device enabled
</CheckBox>
<materialDesign:PopupBox Style="{StaticResource MaterialDesignToolPopupBox}" Padding="2 0 2 0">
<materialDesign:PopupBox Style="{StaticResource MaterialDesignToolPopupBox}" Padding="2 0 2 0" Foreground="{StaticResource MaterialDesignBody}">
<StackPanel>
<Button Command="{s:Action OpenPluginDirectory}">
<StackPanel Orientation="Horizontal">
@@ -49,7 +49,6 @@
<ListBox Grid.Row="1"
ItemsSource="{Binding Items}"
materialDesign:RippleAssist.IsDisabled="True"
VirtualizingPanel.ScrollUnit="Pixel"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
@@ -12,6 +12,14 @@
d:DataContext="{d:DesignInstance devices:PluginSettingsViewModel}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PopupBox.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<materialDesign:Card Width="900">
<Grid Margin="8">
<Grid.ColumnDefinitions>
@@ -61,34 +69,60 @@
</Grid>
<StackPanel Grid.Row="1"
Grid.Column="0"
VerticalAlignment="Bottom"
Orientation="Horizontal">
<Button
VerticalAlignment="Bottom"
Style="{StaticResource MaterialDesignRaisedButton}"
ToolTip="Open the plugins settings window"
Margin="4"
Command="{s:Action OpenSettings}">
<StackPanel Grid.Row="1" Grid.Column="0" VerticalAlignment="Bottom" Orientation="Horizontal">
<Button VerticalAlignment="Bottom"
Style="{StaticResource MaterialDesignRaisedButton}"
ToolTip="Open the plugins settings window"
Margin="4"
Command="{s:Action OpenSettings}">
SETTINGS
</Button>
<Button
VerticalAlignment="Bottom"
Style="{StaticResource MaterialDesignOutlinedButton}"
ToolTip="Clear plugin settings"
Margin="4"
Command="{s:Action RemoveSettings}">
<materialDesign:PackIcon Kind="DatabaseRemove" />
</Button>
<Button
VerticalAlignment="Bottom"
Style="{StaticResource MaterialDesignOutlinedButton}"
ToolTip="Remove plugin"
Margin="4"
Command="{s:Action Remove}">
<materialDesign:PackIcon Kind="DeleteForever" />
</Button>
<materialDesign:PopupBox Style="{StaticResource MaterialDesignToolPopupBox}"
Padding="2 0 2 0"
Foreground="{StaticResource MaterialDesignBody}"
IsPopupOpen="{Binding IsSettingsPopupOpen, Mode=TwoWay}">
<StackPanel>
<Button Command="{s:Action OpenPluginDirectory}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="FolderOpen" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Open plugin directory</TextBlock>
</StackPanel>
</Button>
<Button Command="{s:Action Reload}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Reload" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Reload plugin</TextBlock>
</StackPanel>
</Button>
<Separator />
<Button Command="{s:Action InstallPrerequisites}" >
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="CheckAll" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Install prerequisites</TextBlock>
</StackPanel>
</Button>
<Button Command="{s:Action RemovePrerequisites}" >
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Delete" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Remove prerequisites</TextBlock>
</StackPanel>
</Button>
<Separator />
<Button Command="{s:Action RemoveSettings}" >
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="DatabaseRemove" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Clear plugin settings</TextBlock>
</StackPanel>
</Button>
<Button Command="{s:Action Remove}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="DeleteForever" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Remove plugin</TextBlock>
</StackPanel>
</Button>
</StackPanel>
</materialDesign:PopupBox>
</StackPanel>
@@ -10,23 +10,24 @@ using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Plugins;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using MaterialDesignThemes.Wpf;
using Ninject;
using Stylet;
using Constants = Artemis.Core.Constants;
namespace Artemis.UI.Screens.Settings.Tabs.Plugins
{
public class PluginSettingsViewModel : Conductor<PluginFeatureViewModel>.Collection.AllActive
{
private readonly ICoreService _coreService;
private readonly IDialogService _dialogService;
private readonly IMessageService _messageService;
private readonly IPluginManagementService _pluginManagementService;
private readonly ISettingsVmFactory _settingsVmFactory;
private readonly ICoreService _coreService;
private readonly IMessageService _messageService;
private readonly IWindowManager _windowManager;
private bool _enabling;
private Plugin _plugin;
private bool _isSettingsPopupOpen;
private bool _canInstallPrerequisites;
private bool _canRemovePrerequisites;
public PluginSettingsViewModel(Plugin plugin,
ISettingsVmFactory settingsVmFactory,
@@ -70,6 +71,28 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
set => Task.Run(() => UpdateEnabled(value));
}
public bool IsSettingsPopupOpen
{
get => _isSettingsPopupOpen;
set
{
if (!SetAndNotify(ref _isSettingsPopupOpen, value)) return;
CheckPrerequisites();
}
}
public bool CanInstallPrerequisites
{
get => _canInstallPrerequisites;
set => SetAndNotify(ref _canInstallPrerequisites, value);
}
public bool CanRemovePrerequisites
{
get => _canRemovePrerequisites;
set => SetAndNotify(ref _canRemovePrerequisites, value);
}
public void OpenSettings()
{
PluginConfigurationDialog configurationViewModel = (PluginConfigurationDialog) Plugin.ConfigurationDialog;
@@ -88,6 +111,49 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
}
}
public void OpenPluginDirectory()
{
try
{
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Plugin.Directory.FullName);
}
catch (Exception e)
{
_dialogService.ShowExceptionDialog("Welp, we couldn't open the device's plugin folder for you", e);
}
}
public async Task Reload()
{
bool wasEnabled = IsEnabled;
_pluginManagementService.UnloadPlugin(Plugin);
Items.Clear();
Plugin = _pluginManagementService.LoadPlugin(Plugin.Directory);
foreach (PluginFeatureInfo pluginFeatureInfo in Plugin.Features)
Items.Add(_settingsVmFactory.CreatePluginFeatureViewModel(pluginFeatureInfo, false));
if (wasEnabled)
await UpdateEnabled(true);
}
public async Task InstallPrerequisites()
{
if (Plugin.Prerequisites.Any())
await ShowPrerequisitesDialog(false);
}
public async Task RemovePrerequisites()
{
if (Plugin.Prerequisites.Any(p => p.UninstallActions.Any()))
{
await ShowPrerequisitesDialog(true);
NotifyOfPropertyChange(nameof(IsEnabled));
NotifyOfPropertyChange(nameof(CanOpenSettings));
}
}
public async Task RemoveSettings()
{
bool confirmed = await _dialogService.ShowConfirmDialog("Clear plugin settings", "Are you sure you want to clear the settings of this plugin?");
@@ -109,7 +175,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
public async Task Remove()
{
bool confirmed = await _dialogService.ShowConfirmDialog("Delete plugin", "Are you sure you want to delete this plugin?");
bool confirmed = await _dialogService.ShowConfirmDialog("Remove plugin", "Are you sure you want to remove this plugin?");
if (!confirmed)
return;
@@ -170,10 +236,10 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
}
// Check if all prerequisites are met async
if (!await ArePrerequisitesMetAsync())
if (!Plugin.ArePrerequisitesMet())
{
await _dialogService.ShowDialog<PluginPrerequisitesDialogViewModel>(new Dictionary<string, object> {{"pluginOrFeature", Plugin}});
if (!await ArePrerequisitesMetAsync())
await ShowPrerequisitesDialog(false);
if (!Plugin.ArePrerequisitesMet())
{
CancelEnable();
return;
@@ -194,9 +260,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
}
}
else
{
_pluginManagementService.DisablePlugin(Plugin, true);
}
NotifyOfPropertyChange(nameof(IsEnabled));
NotifyOfPropertyChange(nameof(CanOpenSettings));
@@ -209,19 +273,17 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
NotifyOfPropertyChange(nameof(CanOpenSettings));
}
private async Task<bool> ArePrerequisitesMetAsync()
private void CheckPrerequisites()
{
bool needsPrerequisites = false;
foreach (PluginPrerequisite pluginPrerequisite in Plugin.Prerequisites)
{
if (await pluginPrerequisite.IsMet())
continue;
CanInstallPrerequisites = Plugin.Prerequisites.Any();
CanRemovePrerequisites = Plugin.Prerequisites.Any(p => p.UninstallActions.Any());
}
needsPrerequisites = true;
break;
}
return !needsPrerequisites;
private async Task<object> ShowPrerequisitesDialog(bool uninstall)
{
if (uninstall)
return await _dialogService.ShowDialog<PluginPrerequisitesUninstallDialogViewModel>(new Dictionary<string, object> { { "pluginOrFeature", Plugin } });
return await _dialogService.ShowDialog<PluginPrerequisitesInstallDialogViewModel>(new Dictionary<string, object> { { "pluginOrFeature", Plugin } });
}
}
}