Plugins - Implemented features enable/disable UI

This commit is contained in:
Robert committed 2020-11-12 21:48:17 +01:00
1 parent e812929215
commit c146479393
38 files changed
+571 -164

No files matched your search

@@ -8,10 +8,11 @@
xmlns:wpf="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:modules="clr-namespace:Artemis.Core.Modules;assembly=Artemis.Core"
xmlns:dataModel="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance local:DataModelDebugViewModel}">
<UserControl.Resources>
<dataModel:TypeToStringConverter x:Key="TypeToStringConverter"/>
<dataModel:TypeToStringConverter x:Key="TypeToStringConverter" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
@@ -43,19 +44,11 @@
wpf:HintAssist.Hint="Select a module"
IsEditable="True"
TextSearch.TextPath="DisplayName"
DisplayMemberPath="DisplayName"
Margin="5 0 0 0"
IsEnabled="{Binding IsModuleFilterEnabled}"
SelectedItem="{Binding SelectedModule}"
ItemsSource="{Binding Modules}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel d:DataContext="{d:DesignInstance Type=modules:Module}" Orientation="Horizontal">
<wpf:PackIcon Kind="{Binding DisplayIcon}" VerticalAlignment="Center" Margin="0 0 5 0" />
<TextBlock Text="{Binding DisplayName}" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
ItemsSource="{Binding Modules}" />
</Grid>
<TreeView Grid.Row="1" ItemsSource="{Binding MainDataModel.Children}" HorizontalContentAlignment="Stretch">
<TreeView.Resources>
@@ -73,12 +66,12 @@
<Run>[</Run><Run Text="{Binding DisplayValueType, Converter={StaticResource TypeToStringConverter}, Mode=OneWay}" /><Run>]</Run>
</TextBlock>
<TextBlock Grid.Column="1" Text="{Binding PropertyDescription.Name}" ToolTip="{Binding PropertyDescription.Description}" />
<TextBlock Grid.Column="2"
Text="{Binding DisplayValue}"
FontFamily="Consolas"
HorizontalAlignment="Right"/>
<TextBlock Grid.Column="2"
Text="{Binding DisplayValue}"
FontFamily="Consolas"
HorizontalAlignment="Right" />
</Grid>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type dataModel:DataModelListViewModel}" ItemsSource="{Binding ListChildren}">
<Grid>
@@ -28,6 +28,7 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
_updateTimer = new Timer(500);
DisplayName = "Data model";
Modules = new BindableCollection<Module>();
}
public DataModelPropertiesViewModel MainDataModel
@@ -42,11 +43,7 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
set => SetAndNotify(ref _propertySearch, value);
}
public List<Module> Modules
{
get => _modules;
set => SetAndNotify(ref _modules, value);
}
public BindableCollection<Module> Modules { get; }
public Module SelectedModule
{
@@ -77,8 +74,8 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
GetDataModel();
_updateTimer.Start();
_updateTimer.Elapsed += OnUpdateTimerOnElapsed;
_pluginManagementService.PluginEnabled += PluginManagementServiceOnPluginManagementToggled;
_pluginManagementService.PluginDisabled += PluginManagementServiceOnPluginManagementToggled;
_pluginManagementService.PluginFeatureEnabled += OnPluginFeatureToggled;
_pluginManagementService.PluginFeatureDisabled += OnPluginFeatureToggled;
PopulateModules();
@@ -89,14 +86,23 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
{
_updateTimer.Stop();
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
_pluginManagementService.PluginEnabled -= PluginManagementServiceOnPluginManagementToggled;
_pluginManagementService.PluginDisabled -= PluginManagementServiceOnPluginManagementToggled;
_pluginManagementService.PluginFeatureEnabled -= OnPluginFeatureToggled;
_pluginManagementService.PluginFeatureDisabled -= OnPluginFeatureToggled;
base.OnDeactivate();
}
private void OnPluginFeatureToggled(object sender, PluginFeatureEventArgs e)
{
if (e.PluginFeature is DataModelPluginFeature)
PopulateModules();
}
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs args)
{
if (MainDataModel == null)
return;
lock (MainDataModel)
{
MainDataModel.Update(_dataModelUIService, null);
@@ -110,14 +116,15 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
: _dataModelUIService.GetMainDataModelVisualization();
}
private void PluginManagementServiceOnPluginManagementToggled(object? sender, PluginEventArgs e)
{
PopulateModules();
}
private void PopulateModules()
{
Modules = _pluginManagementService.GetFeaturesOfType<Module>().Where(p => p.IsEnabled).ToList();
Modules.Clear();
Modules.AddRange(_pluginManagementService.GetFeaturesOfType<Module>().Where(p => p.IsEnabled).OrderBy(m => m.DisplayName));
if (SelectedModule == null)
_dataModelUIService.UpdateModules(MainDataModel);
else if (!SelectedModule.IsEnabled)
SelectedModule = null;
}
}
}
@@ -12,7 +12,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Modules
private readonly IModuleService _moduleService;
private readonly IPluginManagementService _pluginManagementService;
private readonly DefaultDropHandler _defaultDropHandler;
private readonly List<ModuleOrderModuleViewModel> _modules;
private List<ModuleOrderModuleViewModel> _modules;
public ModuleOrderTabViewModel(IPluginManagementService pluginManagementService, IModuleService moduleService)
{
@@ -20,16 +20,25 @@ namespace Artemis.UI.Screens.Settings.Tabs.Modules
_pluginManagementService = pluginManagementService;
_moduleService = moduleService;
_modules = new List<ModuleOrderModuleViewModel>(pluginManagementService.GetFeaturesOfType<Module>().Select(m => new ModuleOrderModuleViewModel(m)));
_defaultDropHandler = new DefaultDropHandler();
NormalModules = new BindableCollection<ModuleOrderModuleViewModel>();
ApplicationModules = new BindableCollection<ModuleOrderModuleViewModel>();
OverlayModules = new BindableCollection<ModuleOrderModuleViewModel>();
}
protected override void OnActivate()
{
base.OnActivate();
Update();
}
protected override void OnDeactivate()
{
base.OnDeactivate();
_modules = null;
}
public BindableCollection<ModuleOrderModuleViewModel> NormalModules { get; set; }
public BindableCollection<ModuleOrderModuleViewModel> ApplicationModules { get; set; }
public BindableCollection<ModuleOrderModuleViewModel> OverlayModules { get; set; }
@@ -67,6 +76,8 @@ namespace Artemis.UI.Screens.Settings.Tabs.Modules
public void Update()
{
if (_modules == null)
_modules = _pluginManagementService.GetFeaturesOfType<Module>().Select(m => new ModuleOrderModuleViewModel(m)).ToList();
NormalModules.Clear();
NormalModules.AddRange(_modules.Where(m => m.Module.PriorityCategory == ModulePriorityCategory.Normal).OrderBy(m => m.Module.Priority));
@@ -22,7 +22,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
private readonly IPluginManagementService _pluginManagementService;
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
private bool _enabling;
private bool _isEnabled;
public PluginFeatureViewModel(PluginFeature feature,
IDialogService dialogService,
@@ -35,8 +34,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
Feature = feature;
Icon = GetIconKind();
IsEnabled = Feature.IsEnabled;
}
public PluginFeature Feature { get; }
@@ -54,8 +51,8 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
public bool IsEnabled
{
get => _isEnabled;
set => SetAndNotify(ref _isEnabled, value);
get => Feature.IsEnabled;
set => Task.Run(() => UpdateEnabled(value));
}
public void ShowLogsFolder()
@@ -100,7 +97,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
try
{
await Task.Run(() => _pluginManagementService.EnablePluginFeature(Feature));
await Task.Run(() => _pluginManagementService.EnablePluginFeature(Feature, true));
}
catch (Exception e)
{
@@ -113,7 +110,8 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
}
else
{
_pluginManagementService.DisablePluginFeature(Feature);
_pluginManagementService.DisablePluginFeature(Feature, true);
NotifyOfPropertyChange(nameof(IsEnabled));
}
}
@@ -150,8 +148,8 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
{
if (e.PluginFeature != Feature) return;
Enabling = false;
IsEnabled = e.PluginFeature.IsEnabled;
NotifyOfPropertyChange(nameof(IsEnabled));
NotifyOfPropertyChange(nameof(LoadException));
}
@@ -9,10 +9,30 @@
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:PluginSettingsTabViewModel}">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Margin="0 12 0 0">
<DockPanel Margin="15" MaxWidth="1230" HorizontalAlignment="Center">
<TextBlock DockPanel.Dock="Top">The list below shows all loaded plugins. If you're missing something, view your logs folder.</TextBlock>
<ItemsControl ItemsSource="{Binding Items}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Margin="0 15" MaxWidth="800" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" TextWrapping="Wrap">
The list below shows all loaded plugins. If you're missing something, view your logs folder.
</TextBlock>
<materialDesign:PackIcon Grid.Column="1" Kind="Search" VerticalAlignment="Top" Margin="15 5 0 0" />
<TextBox Grid.Column="2"
materialDesign:TextFieldAssist.HasClearButton="True"
materialDesign:HintAssist.Hint="Search plugin"
VerticalAlignment="Top"
Margin="5 0"
Text="{Binding SearchPluginInput, Delay=300, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<ItemsControl ItemsSource="{Binding Items}" Margin="15 0 15 15" HorizontalAlignment="Center" MaxWidth="1700">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
@@ -24,6 +44,8 @@
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DockPanel>
</ScrollViewer>
</ScrollViewer>
</Grid>
</UserControl>
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Artemis.Core.Services;
@@ -11,6 +12,8 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
{
private readonly IPluginManagementService _pluginManagementService;
private readonly ISettingsVmFactory _settingsVmFactory;
private string _searchPluginInput;
private List<PluginSettingsViewModel> _instances;
public PluginSettingsTabViewModel(IPluginManagementService pluginManagementService, ISettingsVmFactory settingsVmFactory)
{
@@ -20,17 +23,42 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
_settingsVmFactory = settingsVmFactory;
}
public string SearchPluginInput
{
get => _searchPluginInput;
set
{
if (!SetAndNotify(ref _searchPluginInput, value)) return;
UpdatePluginSearch();
}
}
private void UpdatePluginSearch()
{
if (_instances == null)
return;
Items.Clear();
if (string.IsNullOrWhiteSpace(SearchPluginInput))
Items.AddRange(_instances);
else
Items.AddRange(_instances.Where(i => i.Plugin.Info.Name.Contains(SearchPluginInput, StringComparison.OrdinalIgnoreCase) ||
i.Plugin.Info.Description.Contains(SearchPluginInput, StringComparison.OrdinalIgnoreCase)));
}
protected override void OnActivate()
{
// Take it off the UI thread to avoid freezing on tab change
Task.Run(async () =>
{
Items.Clear();
await Task.Delay(200);
_instances = _pluginManagementService.GetAllPlugins()
.Select(p => _settingsVmFactory.CreatePluginSettingsViewModel(p))
.OrderBy(i => i.Plugin.Info.Name)
.ToList();
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);
UpdatePluginSearch();
});
base.OnActivate();
@@ -7,6 +7,8 @@
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"
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
d:DataContext="{d:DesignInstance devices:PluginSettingsViewModel}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
@@ -42,7 +44,7 @@
VerticalAlignment="Top" />
<TextBlock Grid.Column="1" Grid.Row="0" Style="{StaticResource MaterialDesignBody2TextBlock}" Text="{Binding Plugin.Info.Name}" />
<TextBlock Grid.Column="1"
Grid.Row="1"
TextWrapping="Wrap"
@@ -51,37 +53,69 @@
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" />
</Grid>
<StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal">
<Button Style="{StaticResource MaterialDesignOutlinedButton}" ToolTip="MaterialDesignOutlinedButton" Margin="4" Command="{s:Action OpenSettings}">
SETTINGS
</Button>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="8"
Visibility="{Binding Enabling, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}">
<CheckBox Style="{StaticResource MaterialDesignCheckBox}" IsChecked="{Binding IsEnabled}">
Plugin enabled
</CheckBox>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" 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>
<Button Grid.Row="1"
Grid.Column="0"
VerticalAlignment="Bottom"
Style="{StaticResource MaterialDesignOutlinedButton}"
ToolTip="Open the plugins settings window"
Margin="4"
Command="{s:Action OpenSettings}">
SETTINGS
</Button>
<CheckBox Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Margin="8"
Visibility="{Binding Enabling, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}"
Style="{StaticResource MaterialDesignCheckBox}" IsChecked="{Binding IsEnabled}">
Plugin enabled
</CheckBox>
<ProgressBar Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Margin="8"
Visibility="{Binding Enabling, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}"
Style="{StaticResource MaterialDesignCircularProgressBar}" Value="0"
IsIndeterminate="True" />
<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>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Margin="10 10 0 5" Style="{StaticResource MaterialDesignBody2TextBlock}">Plugin features</TextBlock>
<ListBox ItemsSource="{Binding Items}"
<TextBlock Grid.Row="1"
HorizontalAlignment="Center"
Margin="0 30 0 0"
Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
Visibility="{Binding IsEnabled, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}">
Enable the plugin to view its features
</TextBlock>
<ListBox Grid.Row="1"
MaxHeight="135"
ItemsSource="{Binding Items}"
materialDesign:RippleAssist.IsDisabled="True"
HorizontalContentAlignment="Stretch"
VirtualizingPanel.ScrollUnit="Pixel">
VirtualizingPanel.ScrollUnit="Pixel"
Visibility="{Binding IsEnabled, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
<b:Interaction.Behaviors>
<shared:ScrollParentWhenAtMax />
</b:Interaction.Behaviors>
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Grid>
</Border>
</Grid>
</materialDesign:Card>
@@ -126,7 +126,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
try
{
await Task.Run(() => _pluginManagementService.EnablePlugin(Plugin));
await Task.Run(() => _pluginManagementService.EnablePlugin(Plugin, true));
}
catch (Exception e)
{
@@ -139,7 +139,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
}
else
{
_pluginManagementService.DisablePlugin(Plugin);
_pluginManagementService.DisablePlugin(Plugin, true);
}
NotifyOfPropertyChange(nameof(IsEnabled));
+1 -2
View File
@@ -1,5 +1,4 @@
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.Core.Services;
using Artemis.UI.Events;
using Artemis.UI.Screens.Splash;
using Artemis.UI.Services.Interfaces;