Plugins - Implemented features

Core - Removed Stylet dependency for #500
This commit is contained in:
SpoinkyNL committed 2020-11-11 23:53:52 +01:00
1 parent b56966c585
commit e812929215
139 files changed
+1635 -1106

No files matched your search

@@ -8,6 +8,7 @@
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=events/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=exceptions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=extensions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=propertyinput/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cdatamodelvisualization/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cdialog/@EntryIndexedValue">True</s:Boolean>
@@ -11,22 +11,22 @@ namespace Artemis.UI.Shared
public DataModelVisualizationRegistration(IDataModelUIService dataModelUIService,
RegistrationType registrationType,
PluginInfo pluginInfo,
Plugin plugin,
Type supportedType,
Type viewModelType)
{
_dataModelUIService = dataModelUIService;
RegistrationType = registrationType;
PluginInfo = pluginInfo;
Plugin = plugin;
SupportedType = supportedType;
ViewModelType = viewModelType;
if (PluginInfo != Constants.CorePluginInfo)
PluginInfo.Plugin.Disabled += InstanceOnDisabled;
if (Plugin != Constants.CorePlugin)
Plugin.Disabled += InstanceOnDisabled;
}
public RegistrationType RegistrationType { get; }
public PluginInfo PluginInfo { get; }
public Plugin Plugin { get; }
public Type SupportedType { get; }
public Type ViewModelType { get; }
@@ -34,8 +34,8 @@ namespace Artemis.UI.Shared
internal void Unsubscribe()
{
if (PluginInfo != Constants.CorePluginInfo)
PluginInfo.Plugin.Disabled -= InstanceOnDisabled;
if (Plugin != Constants.CorePlugin)
Plugin.Disabled -= InstanceOnDisabled;
}
private void InstanceOnDisabled(object sender, EventArgs e)
@@ -0,0 +1,35 @@
using Artemis.Core.LayerBrushes;
using Stylet;
namespace Artemis.UI.Shared.LayerBrushes
{
/// <summary>
/// Represents a view model for a brush configuration window
/// </summary>
public abstract class BrushConfigurationViewModel : Screen
{
/// <summary>
/// Creates a new instance of the <see cref="BrushConfigurationViewModel" /> class
/// </summary>
/// <param name="layerBrush"></param>
protected BrushConfigurationViewModel(BaseLayerBrush layerBrush)
{
LayerBrush = layerBrush;
}
/// <summary>
/// Creates a new instance of the <see cref="BrushConfigurationViewModel" /> class with a validator
/// </summary>
/// <param name="layerBrush"></param>
/// <param name="validator"></param>
protected BrushConfigurationViewModel(BaseLayerBrush layerBrush, IModelValidator validator) : base(validator)
{
LayerBrush = layerBrush;
}
/// <summary>
/// Gets the layer brush this view model is associated with
/// </summary>
public BaseLayerBrush LayerBrush { get; }
}
}
@@ -0,0 +1,28 @@
using System;
using Artemis.Core.LayerBrushes;
namespace Artemis.UI.Shared.LayerBrushes
{
/// <inheritdoc />
public class LayerBrushConfigurationDialog<T> : LayerBrushConfigurationDialog where T : BrushConfigurationViewModel
{
/// <inheritdoc />
public override Type Type => typeof(T);
}
/// <summary>
/// Describes a UI tab for a layer brush
/// </summary>
public abstract class LayerBrushConfigurationDialog : ILayerBrushConfigurationDialog
{
/// <summary>
/// The layer brush this dialog belongs to
/// </summary>
internal BaseLayerBrush LayerBrush { get; set; }
/// <summary>
/// The type of view model the tab contains
/// </summary>
public abstract Type Type { get; }
}
}
@@ -0,0 +1,35 @@
using Artemis.Core.LayerEffects;
using Stylet;
namespace Artemis.UI.Shared.LayerEffects
{
/// <summary>
/// Represents a view model for an effect configuration window
/// </summary>
public abstract class EffectConfigurationViewModel : Screen
{
/// <summary>
/// Creates a new instance of the <see cref="EffectConfigurationViewModel" /> class
/// </summary>
/// <param name="layerEffect"></param>
protected EffectConfigurationViewModel(BaseLayerEffect layerEffect)
{
LayerEffect = layerEffect;
}
/// <summary>
/// Creates a new instance of the <see cref="EffectConfigurationViewModel" /> class with a validator
/// </summary>
/// <param name="layerEffect"></param>
/// <param name="validator"></param>
protected EffectConfigurationViewModel(BaseLayerEffect layerEffect, IModelValidator validator) : base(validator)
{
LayerEffect = layerEffect;
}
/// <summary>
/// Gets the layer effect this view model is associated with
/// </summary>
public BaseLayerEffect LayerEffect { get; }
}
}
@@ -0,0 +1,28 @@
using System;
using Artemis.Core.LayerEffects;
namespace Artemis.UI.Shared.LayerEffects
{
/// <inheritdoc />
public class LayerEffectConfigurationDialog<T> : LayerEffectConfigurationDialog where T : EffectConfigurationViewModel
{
/// <inheritdoc />
public override Type Type => typeof(T);
}
/// <summary>
/// Describes a UI tab for a specific layer effect
/// </summary>
public abstract class LayerEffectConfigurationDialog : ILayerEffectConfigurationDialog
{
/// <summary>
/// The layer effect this dialog belongs to
/// </summary>
internal BaseLayerEffect LayerEffect { get; set; }
/// <summary>
/// The type of view model the tab contains
/// </summary>
public abstract Type Type { get; }
}
}
@@ -0,0 +1,27 @@
using Artemis.Core.Modules;
using Stylet;
namespace Artemis.UI.Shared.Modules
{
/// <summary>
/// The base class for any view model that belongs to a module
/// </summary>
public abstract class ModuleViewModel : Screen, IModuleViewModel
{
/// <summary>
/// The base class for any view model that belongs to a module
/// </summary>
/// <param name="module">The module this view model belongs to</param>
/// <param name="displayName">The name of the tab that's shown on the modules UI page</param>
protected ModuleViewModel(Module module, string displayName)
{
Module = module;
DisplayName = displayName.ToUpper();
}
/// <summary>
/// Gets the module this view model belongs to
/// </summary>
public Module Module { get; }
}
}
@@ -0,0 +1,28 @@
using System;
using Artemis.Core;
namespace Artemis.UI.Shared
{
/// <inheritdoc />
public class PluginConfigurationDialog<T> : PluginConfigurationDialog where T : PluginConfigurationViewModel
{
/// <inheritdoc />
public override Type Type => typeof(T);
}
/// <summary>
/// Describes a configuration dialog for a specific plugin
/// </summary>
public abstract class PluginConfigurationDialog : IPluginConfigurationDialog
{
/// <summary>
/// The layer brush this dialog belongs to
/// </summary>
internal PluginFeature PluginFeature { get; set; }
/// <summary>
/// The type of view model the tab contains
/// </summary>
public abstract Type Type { get; }
}
}
@@ -0,0 +1,35 @@
using Artemis.Core;
using Stylet;
namespace Artemis.UI.Shared
{
/// <summary>
/// Represents a view model for a plugin configuration window
/// </summary>
public abstract class PluginConfigurationViewModel : Screen, IPluginConfigurationViewModel
{
/// <summary>
/// Creates a new instance of the <see cref="PluginConfigurationViewModel" /> class
/// </summary>
/// <param name="plugin"></param>
protected PluginConfigurationViewModel(Plugin plugin)
{
Plugin = plugin;
}
/// <summary>
/// Creates a new instance of the <see cref="PluginConfigurationViewModel" /> class with a validator
/// </summary>
/// <param name="plugin"></param>
/// <param name="validator"></param>
protected PluginConfigurationViewModel(Plugin plugin, IModelValidator validator) : base(validator)
{
Plugin = plugin;
}
/// <summary>
/// Gets the plugin this configuration view model is associated with
/// </summary>
public Plugin Plugin { get; }
}
}
@@ -8,25 +8,25 @@ namespace Artemis.UI.Shared
{
private readonly IProfileEditorService _profileEditorService;
internal PropertyInputRegistration(IProfileEditorService profileEditorService, PluginInfo pluginInfo, Type supportedType, Type viewModelType)
internal PropertyInputRegistration(IProfileEditorService profileEditorService, Plugin plugin, Type supportedType, Type viewModelType)
{
_profileEditorService = profileEditorService;
PluginInfo = pluginInfo;
Plugin = plugin;
SupportedType = supportedType;
ViewModelType = viewModelType;
if (PluginInfo != Constants.CorePluginInfo)
PluginInfo.Plugin.Disabled += InstanceOnDisabled;
if (Plugin != Constants.CorePlugin)
Plugin.Disabled += InstanceOnDisabled;
}
public PluginInfo PluginInfo { get; }
public Plugin Plugin { get; }
public Type SupportedType { get; }
public Type ViewModelType { get; }
internal void Unsubscribe()
{
if (PluginInfo != Constants.CorePluginInfo)
PluginInfo.Plugin.Disabled -= InstanceOnDisabled;
if (Plugin != Constants.CorePlugin)
Plugin.Disabled -= InstanceOnDisabled;
}
private void InstanceOnDisabled(object sender, EventArgs e)
@@ -42,24 +42,24 @@ namespace Artemis.UI.Shared.Services
return viewModel;
}
public DataModelPropertiesViewModel GetPluginDataModelVisualization(PluginImplementation pluginImplementation, bool includeMainDataModel)
public DataModelPropertiesViewModel GetPluginDataModelVisualization(PluginFeature pluginFeature, bool includeMainDataModel)
{
if (includeMainDataModel)
{
DataModelPropertiesViewModel mainDataModel = GetMainDataModelVisualization();
// If the main data model already includes the plugin data model we're done
if (mainDataModel.Children.Any(c => c.DataModel.Implementation.Instance == pluginImplementation))
if (mainDataModel.Children.Any(c => c.DataModel.Feature == pluginFeature))
return mainDataModel;
// Otherwise get just the plugin data model and add it
DataModelPropertiesViewModel pluginDataModel = GetPluginDataModelVisualization(pluginImplementation, false);
DataModelPropertiesViewModel pluginDataModel = GetPluginDataModelVisualization(pluginFeature, false);
if (pluginDataModel != null)
mainDataModel.Children.Add(pluginDataModel);
return mainDataModel;
}
DataModel dataModel = _dataModelService.GetPluginDataModel(pluginImplementation);
DataModel dataModel = _dataModelService.GetPluginDataModel(pluginFeature);
if (dataModel == null)
return null;
@@ -72,7 +72,7 @@ namespace Artemis.UI.Shared.Services
return viewModel;
}
public DataModelVisualizationRegistration RegisterDataModelInput<T>(PluginInfo pluginInfo, IReadOnlyCollection<Type> compatibleConversionTypes = null) where T : DataModelInputViewModel
public DataModelVisualizationRegistration RegisterDataModelInput<T>(Plugin plugin, IReadOnlyCollection<Type> compatibleConversionTypes = null) where T : DataModelInputViewModel
{
if (compatibleConversionTypes == null)
compatibleConversionTypes = new List<Type>();
@@ -83,19 +83,16 @@ namespace Artemis.UI.Shared.Services
DataModelVisualizationRegistration existing = _registeredDataModelEditors.FirstOrDefault(r => r.SupportedType == supportedType);
if (existing != null)
{
if (existing.PluginInfo != pluginInfo)
{
throw new ArtemisPluginException($"Cannot register data model input for type {supportedType.Name} " +
$"because an editor was already registered by {pluginInfo.Name}");
}
if (existing.Plugin != plugin)
throw new ArtemisPluginException($"Cannot register data model input for type {supportedType.Name} because an editor was already" +
$" registered by {existing.Plugin}");
return existing;
}
_kernel.Bind(viewModelType).ToSelf();
// Create the registration
DataModelVisualizationRegistration registration = new DataModelVisualizationRegistration(this, RegistrationType.Input, pluginInfo, supportedType, viewModelType)
DataModelVisualizationRegistration registration = new DataModelVisualizationRegistration(this, RegistrationType.Input, plugin, supportedType, viewModelType)
{
// Apply the compatible conversion types to the registration
CompatibleConversionTypes = compatibleConversionTypes
@@ -106,7 +103,7 @@ namespace Artemis.UI.Shared.Services
}
}
public DataModelVisualizationRegistration RegisterDataModelDisplay<T>(PluginInfo pluginInfo) where T : DataModelDisplayViewModel
public DataModelVisualizationRegistration RegisterDataModelDisplay<T>(Plugin plugin) where T : DataModelDisplayViewModel
{
Type viewModelType = typeof(T);
lock (_registeredDataModelDisplays)
@@ -115,17 +112,14 @@ namespace Artemis.UI.Shared.Services
DataModelVisualizationRegistration existing = _registeredDataModelDisplays.FirstOrDefault(r => r.SupportedType == supportedType);
if (existing != null)
{
if (existing.PluginInfo != pluginInfo)
{
throw new ArtemisPluginException($"Cannot register data model display for type {supportedType.Name} " +
$"because an editor was already registered by {pluginInfo.Name}");
}
if (existing.Plugin != plugin)
throw new ArtemisPluginException($"Cannot register data model display for type {supportedType.Name} because an editor was already" +
$" registered by {existing.Plugin}");
return existing;
}
_kernel.Bind(viewModelType).ToSelf();
DataModelVisualizationRegistration registration = new DataModelVisualizationRegistration(this, RegistrationType.Display, pluginInfo, supportedType, viewModelType);
DataModelVisualizationRegistration registration = new DataModelVisualizationRegistration(this, RegistrationType.Display, plugin, supportedType, viewModelType);
_registeredDataModelDisplays.Add(registration);
return registration;
}
@@ -167,7 +161,7 @@ namespace Artemis.UI.Shared.Services
DataModelVisualizationRegistration match = _registeredDataModelDisplays.FirstOrDefault(d => d.SupportedType == propertyType);
if (match != null)
result = (DataModelDisplayViewModel) match.PluginInfo.Kernel.Get(match.ViewModelType);
result = (DataModelDisplayViewModel) match.Plugin.Kernel.Get(match.ViewModelType);
else if (!fallBackToDefault)
result = null;
else
@@ -220,11 +214,12 @@ namespace Artemis.UI.Shared.Services
if (initialValue != null && initialValue.GetType() != registration.SupportedType)
initialValue = Convert.ChangeType(initialValue, registration.SupportedType);
IParameter[] parameters = {
IParameter[] parameters =
{
new ConstructorArgument("targetDescription", description),
new ConstructorArgument("initialValue", initialValue)
};
DataModelInputViewModel viewModel = (DataModelInputViewModel) registration.PluginInfo.Kernel.Get(registration.ViewModelType, parameters);
DataModelInputViewModel viewModel = (DataModelInputViewModel) registration.Plugin.Kernel.Get(registration.ViewModelType, parameters);
viewModel.CompatibleConversionTypes = registration.CompatibleConversionTypes;
return viewModel;
}
@@ -109,11 +109,12 @@ namespace Artemis.UI.Shared.Services
private async Task<object> ShowDialogAt<T>(string identifier, IParameter[] parameters) where T : DialogViewModelBase
{
PluginImplementation callingPluginImplementation = _pluginManagementService.GetCallingPlugin();
if (parameters == null) throw new ArgumentNullException(nameof(parameters));
Plugin callingPlugin = _pluginManagementService.GetCallingPlugin();
if (parameters == null)
throw new ArgumentNullException(nameof(parameters));
if (callingPluginImplementation != null)
return await ShowDialog(identifier, callingPluginImplementation.PluginInfo.Kernel.Get<T>(parameters));
if (callingPlugin != null)
return await ShowDialog(identifier, callingPlugin.Kernel.Get<T>(parameters));
return await ShowDialog(identifier, _kernel.Get<T>(parameters));
}
@@ -12,10 +12,10 @@ namespace Artemis.UI.Shared.Services
IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelEditors { get; }
IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelDisplays { get; }
DataModelPropertiesViewModel GetMainDataModelVisualization();
DataModelPropertiesViewModel GetPluginDataModelVisualization(PluginImplementation pluginImplementation, bool includeMainDataModel);
DataModelPropertiesViewModel GetPluginDataModelVisualization(PluginFeature pluginFeature, bool includeMainDataModel);
DataModelVisualizationRegistration RegisterDataModelInput<T>(PluginInfo pluginInfo, IReadOnlyCollection<Type> compatibleConversionTypes) where T : DataModelInputViewModel;
DataModelVisualizationRegistration RegisterDataModelDisplay<T>(PluginInfo pluginInfo) where T : DataModelDisplayViewModel;
DataModelVisualizationRegistration RegisterDataModelInput<T>(Plugin plugin, IReadOnlyCollection<Type> compatibleConversionTypes) where T : DataModelInputViewModel;
DataModelVisualizationRegistration RegisterDataModelDisplay<T>(Plugin plugin) where T : DataModelDisplayViewModel;
void RemoveDataModelInput(DataModelVisualizationRegistration registration);
void RemoveDataModelDisplay(DataModelVisualizationRegistration registration);
@@ -71,9 +71,9 @@ namespace Artemis.UI.Shared.Services
/// <see cref="PropertyInputViewModel{T}" />
/// <para>Note: Registration will remove itself on plugin disable so you don't have to</para>
/// </summary>
/// <param name="pluginInfo"></param>
/// <param name="plugin"></param>
/// <returns></returns>
PropertyInputRegistration RegisterPropertyInput<T>(PluginInfo pluginInfo) where T : PropertyInputViewModel;
PropertyInputRegistration RegisterPropertyInput<T>(Plugin plugin) where T : PropertyInputViewModel;
/// <summary>
/// Registers a new property input view model used in the profile editor for the generic type defined in
@@ -81,9 +81,9 @@ namespace Artemis.UI.Shared.Services
/// <para>Note: Registration will remove itself on plugin disable so you don't have to</para>
/// </summary>
/// <param name="viewModelType"></param>
/// <param name="pluginInfo"></param>
/// <param name="plugin"></param>
/// <returns></returns>
PropertyInputRegistration RegisterPropertyInput(Type viewModelType, PluginInfo pluginInfo);
PropertyInputRegistration RegisterPropertyInput(Type viewModelType, Plugin plugin);
void RemovePropertyInput(PropertyInputRegistration registration);
@@ -177,12 +177,12 @@ namespace Artemis.UI.Shared.Services
return true;
}
public PropertyInputRegistration RegisterPropertyInput<T>(PluginInfo pluginInfo) where T : PropertyInputViewModel
public PropertyInputRegistration RegisterPropertyInput<T>(Plugin plugin) where T : PropertyInputViewModel
{
return RegisterPropertyInput(typeof(T), pluginInfo);
return RegisterPropertyInput(typeof(T), plugin);
}
public PropertyInputRegistration RegisterPropertyInput(Type viewModelType, PluginInfo pluginInfo)
public PropertyInputRegistration RegisterPropertyInput(Type viewModelType, Plugin plugin)
{
if (!typeof(PropertyInputViewModel).IsAssignableFrom(viewModelType))
throw new ArtemisSharedUIException($"Property input VM type must implement {nameof(PropertyInputViewModel)}");
@@ -201,13 +201,14 @@ namespace Artemis.UI.Shared.Services
PropertyInputRegistration existing = _registeredPropertyEditors.FirstOrDefault(r => r.SupportedType == supportedType);
if (existing != null)
{
if (existing.PluginInfo != pluginInfo)
throw new ArtemisPluginException($"Cannot register property editor for type {supportedType.Name} because an editor was already registered by {existing.PluginInfo.Name}");
if (existing.Plugin != plugin)
throw new ArtemisPluginException($"Cannot register property editor for type {supportedType.Name} because an editor was already " +
$"registered by {existing.Plugin}");
return existing;
}
Kernel.Bind(viewModelType).ToSelf();
PropertyInputRegistration registration = new PropertyInputRegistration(this, pluginInfo, supportedType, viewModelType);
PropertyInputRegistration registration = new PropertyInputRegistration(this, plugin, supportedType, viewModelType);
_registeredPropertyEditors.Add(registration);
return registration;
}
@@ -281,7 +282,7 @@ namespace Artemis.UI.Shared.Services
return null;
ConstructorArgument parameter = new ConstructorArgument("layerProperty", layerProperty);
IKernel kernel = registration != null ? registration.PluginInfo.Kernel : Kernel;
IKernel kernel = registration != null ? registration.Plugin.Kernel : Kernel;
return (PropertyInputViewModel<T>) kernel.Get(viewModelType, parameter);
}
@@ -14,13 +14,13 @@ namespace Artemis.UI.Shared
/// <summary>
/// Transforms the provided icon so that it is usable by the <see cref="ArtemisIcon" /> control
/// </summary>
/// <param name="pluginInfo">The info of the plugin the icon belongs to</param>
/// <param name="plugin">The plugin the icon belongs to</param>
/// <param name="icon">
/// The icon, may be a string representation of a <see cref="PackIconKind" /> or a relative path
/// pointing to a .svg file
/// </param>
/// <returns></returns>
public static object GetPluginIcon(PluginInfo pluginInfo, string icon)
public static object GetPluginIcon(Plugin plugin, string icon)
{
if (icon == null)
return PackIconKind.QuestionMarkCircle;
@@ -28,7 +28,7 @@ namespace Artemis.UI.Shared
// Icon is provided as a path
if (icon.EndsWith(".svg"))
{
string iconPath = pluginInfo.ResolveRelativePath(icon);
string iconPath = plugin.ResolveRelativePath(icon);
if (!File.Exists(iconPath))
return PackIconKind.QuestionMarkCircle;
return iconPath;
-1
View File
@@ -1300,7 +1300,6 @@
"Serilog.Sinks.Debug": "1.0.1",
"Serilog.Sinks.File": "4.1.0",
"SkiaSharp": "1.68.3",
"Stylet": "1.3.4",
"System.Buffers": "4.5.0",
"System.Numerics.Vectors": "4.5.0",
"System.Reflection.Metadata": "1.8.0",