From 92faafe1de76636bbc572e3cbe91d967f020b820 Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Tue, 2 Jun 2020 22:23:09 +0200 Subject: [PATCH] Profile editor - Moved layer property input to the Shared UI project --- .../LayerProperties/BaseLayerProperty.cs | 5 +- .../Profile/LayerProperties/LayerProperty.cs | 7 +- .../Models/Profile/LayerPropertyGroup.cs | 7 +- .../Plugins/Abstract/DeviceProvider.cs | 8 +- src/Artemis.Core/Plugins/Abstract/Plugin.cs | 65 +- .../Plugins/Abstract/ProfileModule.cs | 5 - src/Artemis.Core/Services/PluginService.cs | 8 +- .../Events/ProfileElementEventArgs.cs | 2 +- .../PropertyInputRegistration.cs | 44 ++ .../PropertyInput}/PropertyInputViewModel.cs | 64 +- .../Interfaces/IProfileEditorService.cs | 21 +- .../Services/ProfileEditorService.cs | 111 ++-- .../Artemis.UI_u2tszd0b_wpftmp.csproj | 565 ++++++++++++++++++ src/Artemis.UI/Ninject/UiModule.cs | 10 +- .../PropertyInput/BrushPropertyInputView.xaml | 8 +- .../BrushPropertyInputViewModel.cs | 20 +- .../ColorGradientPropertyInputView.xaml | 8 +- .../ColorGradientPropertyInputViewModel.cs | 9 +- .../PropertyInput/EnumPropertyInputView.xaml | 6 +- .../EnumPropertyInputViewModel.cs | 10 +- .../PropertyInput/FloatPropertyInputView.xaml | 12 +- .../FloatPropertyInputViewModel.cs | 30 + .../PropertyInput/IntPropertyInputView.xaml | 12 +- .../IntPropertyInputViewModel.cs | 30 + .../SKColorPropertyInputView.xaml | 10 +- .../SKColorPropertyInputViewModel.cs | 14 + .../SKPointPropertyInputView.xaml | 14 +- .../SKPointPropertyInputViewModel.cs | 26 +- .../SKSizePropertyInputView.xaml | 12 +- .../SKSizePropertyInputViewModel.cs | 59 ++ .../LayerPropertiesViewModel.cs | 2 + .../LayerPropertyGroupViewModel.cs | 76 ++- .../LayerProperties/LayerPropertyViewModel.cs | 44 +- .../Timeline/TimelineKeyframeViewModel.cs | 1 + .../Timeline/TimelinePropertyViewModel.cs | 1 + .../FloatPropertyInputViewModel.cs | 28 - .../IntPropertyInputViewModel.cs | 28 - .../SKColorPropertyInputViewModel.cs | 12 - .../SKSizePropertyInputViewModel.cs | 57 -- .../Tree/TreePropertyView.xaml | 21 +- .../Tree/TreePropertyViewModel.cs | 6 +- .../ProfileTree/ProfileTreeViewModel.cs | 1 + .../Visualization/ProfileLayerViewModel.cs | 1 + .../Visualization/ProfileViewModel.cs | 3 +- .../Visualization/Tools/EditToolViewModel.cs | 1 + .../Tools/SelectionRemoveToolViewModel.cs | 1 + .../Tools/SelectionToolViewModel.cs | 1 + .../Tools/ViewpointMoveToolViewModel.cs | 1 + .../Tools/VisualizationToolViewModel.cs | 1 + src/Artemis.UI/Services/LayerEditorService.cs | 21 +- .../AsusDeviceProvider.cs | 2 +- .../CoolerMasterDeviceProvider.cs | 2 +- .../CorsairDeviceProvider.cs | 2 +- .../DMXDeviceProvider.cs | 2 +- .../LogitechDeviceProvider.cs | 2 +- .../MsiDeviceProvider.cs | 2 +- .../NovationDeviceProvider.cs | 2 +- .../RazerDeviceProvider.cs | 2 +- .../RoccatDeviceProvider.cs | 2 +- .../SteelSeriesDeviceProvider.cs | 2 +- .../WS281XDeviceProvider.cs | 13 +- .../WootingDeviceProvider.cs | 11 +- .../ColorBrushProvider.cs | 8 +- ...is.Plugins.LayerBrushes.ColorRgbNet.csproj | 1 + .../StringPropertyInputView.xaml | 23 + .../StringPropertyInputViewModel.cs | 14 + .../RgbNetColorBrush.cs | 3 +- .../RgbNetColorBrushProperties.cs | 5 + .../RgbNetColorBrushProvider.cs | 16 +- .../NoiseBrushProvider.cs | 8 +- .../GeneralModule.cs | 14 +- 71 files changed, 1211 insertions(+), 434 deletions(-) rename src/{Artemis.UI => Artemis.UI.Shared}/Events/ProfileElementEventArgs.cs (94%) create mode 100644 src/Artemis.UI.Shared/PropertyInput/PropertyInputRegistration.cs rename src/{Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/Abstract => Artemis.UI.Shared/PropertyInput}/PropertyInputViewModel.cs (57%) rename src/{Artemis.UI => Artemis.UI.Shared}/Services/Interfaces/IProfileEditorService.cs (73%) rename src/{Artemis.UI => Artemis.UI.Shared}/Services/ProfileEditorService.cs (68%) create mode 100644 src/Artemis.UI/Artemis.UI_u2tszd0b_wpftmp.csproj rename src/Artemis.UI/{Screens/Module/ProfileEditor/LayerProperties/Tree => }/PropertyInput/BrushPropertyInputView.xaml (66%) rename src/Artemis.UI/{Screens/Module/ProfileEditor/LayerProperties/Tree => }/PropertyInput/BrushPropertyInputViewModel.cs (82%) rename src/Artemis.UI/{Screens/Module/ProfileEditor/LayerProperties/Tree => }/PropertyInput/ColorGradientPropertyInputView.xaml (65%) rename src/Artemis.UI/{Screens/Module/ProfileEditor/LayerProperties/Tree => }/PropertyInput/ColorGradientPropertyInputViewModel.cs (54%) rename src/Artemis.UI/{Screens/Module/ProfileEditor/LayerProperties/Tree => }/PropertyInput/EnumPropertyInputView.xaml (70%) rename src/Artemis.UI/{Screens/Module/ProfileEditor/LayerProperties/Tree => }/PropertyInput/EnumPropertyInputViewModel.cs (51%) rename src/Artemis.UI/{Screens/Module/ProfileEditor/LayerProperties/Tree => }/PropertyInput/FloatPropertyInputView.xaml (63%) create mode 100644 src/Artemis.UI/PropertyInput/FloatPropertyInputViewModel.cs rename src/Artemis.UI/{Screens/Module/ProfileEditor/LayerProperties/Tree => }/PropertyInput/IntPropertyInputView.xaml (63%) create mode 100644 src/Artemis.UI/PropertyInput/IntPropertyInputViewModel.cs rename src/Artemis.UI/{Screens/Module/ProfileEditor/LayerProperties/Tree => }/PropertyInput/SKColorPropertyInputView.xaml (64%) create mode 100644 src/Artemis.UI/PropertyInput/SKColorPropertyInputViewModel.cs rename src/Artemis.UI/{Screens/Module/ProfileEditor/LayerProperties/Tree => }/PropertyInput/SKPointPropertyInputView.xaml (61%) rename src/Artemis.UI/{Screens/Module/ProfileEditor/LayerProperties/Tree => }/PropertyInput/SKPointPropertyInputViewModel.cs (57%) rename src/Artemis.UI/{Screens/Module/ProfileEditor/LayerProperties/Tree => }/PropertyInput/SKSizePropertyInputView.xaml (64%) create mode 100644 src/Artemis.UI/PropertyInput/SKSizePropertyInputViewModel.cs delete mode 100644 src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/FloatPropertyInputViewModel.cs delete mode 100644 src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/IntPropertyInputViewModel.cs delete mode 100644 src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKColorPropertyInputViewModel.cs delete mode 100644 src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKSizePropertyInputViewModel.cs create mode 100644 src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/PropertyInput/StringPropertyInputView.xaml create mode 100644 src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/PropertyInput/StringPropertyInputViewModel.cs diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs index bed89fd32..7c5115364 100644 --- a/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs +++ b/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Artemis.Core.Models.Profile.LayerProperties.Attributes; using Artemis.Storage.Entities.Profile; namespace Artemis.Core.Models.Profile.LayerProperties @@ -74,6 +75,8 @@ namespace Artemis.Core.Models.Profile.LayerProperties /// public bool IsCoreProperty { get; internal set; } + public PropertyDescriptionAttribute PropertyDescription { get; internal set; } + /// /// Gets a list of all the keyframes in their non-generic base form, without their values being available /// @@ -81,7 +84,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties internal PropertyEntity PropertyEntity { get; set; } internal LayerPropertyGroup LayerPropertyGroup { get; set; } - + /// /// Applies the provided property entity to the layer property by deserializing the JSON base value and keyframe values diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs index edf61b8d5..c2c4e84d8 100644 --- a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs +++ b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs @@ -18,7 +18,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties /// /// /// The type of property encapsulated in this layer property - public abstract class LayerProperty : BaseLayerProperty + public class LayerProperty : BaseLayerProperty { private T _baseValue; private T _currentValue; @@ -172,7 +172,10 @@ namespace Artemis.Core.Models.Profile.LayerProperties /// /// The linear current keyframe progress /// The current keyframe progress, eased with the current easing function - protected abstract void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased); + protected virtual void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased) + { + throw new NotImplementedException(); + } /// /// Updates the property, moving the timeline forwards by the provided diff --git a/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs b/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs index 68d4bf8ae..2277c9157 100644 --- a/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs +++ b/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs @@ -51,6 +51,8 @@ namespace Artemis.Core.Models.Profile /// public bool IsCorePropertyGroup { get; internal set; } + public PropertyGroupDescriptionAttribute GroupDescription { get; internal set; } + /// /// Gets or sets whether the property is hidden in the UI /// @@ -132,7 +134,9 @@ namespace Artemis.Core.Models.Profile var instance = (BaseLayerProperty) Activator.CreateInstance(propertyInfo.PropertyType, true); instance.Parent = this; + instance.PropertyDescription = (PropertyDescriptionAttribute)propertyDescription; instance.Layer = layer; + InitializeProperty(layer, path + propertyInfo.Name, instance); propertyInfo.SetValue(this, instance); _layerProperties.Add(instance); @@ -147,6 +151,7 @@ namespace Artemis.Core.Models.Profile var instance = (LayerPropertyGroup) Activator.CreateInstance(propertyInfo.PropertyType); instance.Parent = this; + instance.GroupDescription = (PropertyGroupDescriptionAttribute)propertyGroupDescription; instance.InitializeProperties(layerService, layer, $"{path}{propertyInfo.Name}."); propertyInfo.SetValue(this, instance); _layerPropertyGroups.Add(instance); @@ -162,7 +167,7 @@ namespace Artemis.Core.Models.Profile PropertiesInitialized = true; OnPropertyGroupInitialized(); } - + internal void ApplyToEntity() { if (!PropertiesInitialized) diff --git a/src/Artemis.Core/Plugins/Abstract/DeviceProvider.cs b/src/Artemis.Core/Plugins/Abstract/DeviceProvider.cs index 6c0db6ef4..8226b0cad 100644 --- a/src/Artemis.Core/Plugins/Abstract/DeviceProvider.cs +++ b/src/Artemis.Core/Plugins/Abstract/DeviceProvider.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.IO; using Artemis.Core.Extensions; using Artemis.Core.Plugins.Models; @@ -44,12 +43,7 @@ namespace Artemis.Core.Plugins.Abstract } } - public override void Dispose() - { - // Does not happen with device providers, they require Artemis to restart - } - - public override void DisablePlugin() + protected override void DisablePlugin() { // Does not happen with device providers, they require Artemis to restart } diff --git a/src/Artemis.Core/Plugins/Abstract/Plugin.cs b/src/Artemis.Core/Plugins/Abstract/Plugin.cs index 711275ea5..94f1f1b49 100644 --- a/src/Artemis.Core/Plugins/Abstract/Plugin.cs +++ b/src/Artemis.Core/Plugins/Abstract/Plugin.cs @@ -17,30 +17,35 @@ namespace Artemis.Core.Plugins.Abstract public PluginInfo PluginInfo { get; internal set; } + /// + /// Gets whether the plugin is enabled + /// + public bool Enabled { get; private set; } + /// /// Gets or sets whether this plugin has a configuration view model. /// If set to true, will be called when the plugin is configured from the UI. /// public bool HasConfigurationViewModel { get; protected set; } - /// - /// - /// Called when the plugin is unloaded, clean up any unmanaged resources here - /// - public abstract void Dispose(); + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } /// /// Called when the plugin is activated /// - public abstract void EnablePlugin(); + protected abstract void EnablePlugin(); /// /// Called when the plugin is deactivated /// - public abstract void DisablePlugin(); + protected abstract void DisablePlugin(); /// - /// Called when the plugin's configuration window is opened from the UI. The UI will only attempt to open if + /// Called when the plugins configuration window is opened from the UI. The UI will only attempt to open if /// is set to True. /// /// @@ -48,5 +53,49 @@ namespace Artemis.Core.Plugins.Abstract { return null; } + + /// + /// Called when Artemis shuts down + /// + /// + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + } + } + + internal void SetEnabled(bool enable) + { + if (enable && !Enabled) + { + EnablePlugin(); + OnPluginEnabled(); + } + else if (!enable && Enabled) + { + DisablePlugin(); + OnPluginDisabled(); + } + + Enabled = enable; + } + + #region Events + + public event EventHandler PluginEnabled; + public event EventHandler PluginDisabled; + + protected virtual void OnPluginEnabled() + { + PluginEnabled?.Invoke(this, EventArgs.Empty); + } + + protected virtual void OnPluginDisabled() + { + PluginDisabled?.Invoke(this, EventArgs.Empty); + } + + #endregion } } \ No newline at end of file diff --git a/src/Artemis.Core/Plugins/Abstract/ProfileModule.cs b/src/Artemis.Core/Plugins/Abstract/ProfileModule.cs index 72c07af99..38ef43055 100644 --- a/src/Artemis.Core/Plugins/Abstract/ProfileModule.cs +++ b/src/Artemis.Core/Plugins/Abstract/ProfileModule.cs @@ -15,11 +15,6 @@ namespace Artemis.Core.Plugins.Abstract public Profile ActiveProfile { get; private set; } - public override void EnablePlugin() - { - throw new NotImplementedException(); - } - /// public override void Update(double deltaTime) { diff --git a/src/Artemis.Core/Services/PluginService.cs b/src/Artemis.Core/Services/PluginService.cs index 5001580b2..94c5967ab 100644 --- a/src/Artemis.Core/Services/PluginService.cs +++ b/src/Artemis.Core/Services/PluginService.cs @@ -167,7 +167,7 @@ namespace Artemis.Core.Services var threwException = false; try { - pluginInfo.Instance.EnablePlugin(); + pluginInfo.Instance.SetEnabled(true); } catch (Exception e) { @@ -289,7 +289,7 @@ namespace Artemis.Core.Services { try { - pluginInfo.Instance.DisablePlugin(); + pluginInfo.Instance.SetEnabled(false); } catch (Exception) { @@ -320,7 +320,7 @@ namespace Artemis.Core.Services var threwException = false; try { - plugin.EnablePlugin(); + plugin.SetEnabled(true); } catch (Exception e) { @@ -352,7 +352,7 @@ namespace Artemis.Core.Services return; } - plugin.DisablePlugin(); + plugin.SetEnabled(false); OnPluginDisabled(new PluginEventArgs(plugin.PluginInfo)); } diff --git a/src/Artemis.UI/Events/ProfileElementEventArgs.cs b/src/Artemis.UI.Shared/Events/ProfileElementEventArgs.cs similarity index 94% rename from src/Artemis.UI/Events/ProfileElementEventArgs.cs rename to src/Artemis.UI.Shared/Events/ProfileElementEventArgs.cs index cb842ac10..d4909cc2e 100644 --- a/src/Artemis.UI/Events/ProfileElementEventArgs.cs +++ b/src/Artemis.UI.Shared/Events/ProfileElementEventArgs.cs @@ -1,7 +1,7 @@ using System; using Artemis.Core.Models.Profile; -namespace Artemis.UI.Events +namespace Artemis.UI.Shared.Events { public class ProfileElementEventArgs : EventArgs { diff --git a/src/Artemis.UI.Shared/PropertyInput/PropertyInputRegistration.cs b/src/Artemis.UI.Shared/PropertyInput/PropertyInputRegistration.cs new file mode 100644 index 000000000..54fba5073 --- /dev/null +++ b/src/Artemis.UI.Shared/PropertyInput/PropertyInputRegistration.cs @@ -0,0 +1,44 @@ +using System; +using Artemis.Core; +using Artemis.Core.Plugins.Models; +using Artemis.UI.Shared.Services.Interfaces; + +namespace Artemis.UI.Shared.PropertyInput +{ + public class PropertyInputRegistration + { + private readonly IProfileEditorService _profileEditorService; + + internal PropertyInputRegistration(IProfileEditorService profileEditorService, PluginInfo pluginInfo, Type supportedType, Type viewModelType) + { + _profileEditorService = profileEditorService; + PluginInfo = pluginInfo; + SupportedType = supportedType; + ViewModelType = viewModelType; + + if (PluginInfo != Constants.CorePluginInfo) + PluginInfo.Instance.PluginDisabled += InstanceOnPluginDisabled; + } + + public PluginInfo PluginInfo { get; } + public Type SupportedType { get; } + public Type ViewModelType { get; } + + internal void Unsubscribe() + { + if (PluginInfo != Constants.CorePluginInfo) + PluginInfo.Instance.PluginDisabled -= InstanceOnPluginDisabled; + } + + internal void Remove() + { + // It'll call Unsubscribe for us + _profileEditorService.RemovePropertyInput(this); + } + + private void InstanceOnPluginDisabled(object sender, EventArgs e) + { + Remove(); + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/Abstract/PropertyInputViewModel.cs b/src/Artemis.UI.Shared/PropertyInput/PropertyInputViewModel.cs similarity index 57% rename from src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/Abstract/PropertyInputViewModel.cs rename to src/Artemis.UI.Shared/PropertyInput/PropertyInputViewModel.cs index fcbc47752..36f3ba376 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/Abstract/PropertyInputViewModel.cs +++ b/src/Artemis.UI.Shared/PropertyInput/PropertyInputViewModel.cs @@ -1,27 +1,32 @@ using System; +using Artemis.Core.Models.Profile.LayerProperties; +using Artemis.UI.Shared.Services.Interfaces; using Stylet; -namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput.Abstract +namespace Artemis.UI.Shared.PropertyInput { public abstract class PropertyInputViewModel : ValidatingModelBase, IDisposable { private T _inputValue; - protected PropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel) + protected PropertyInputViewModel(LayerProperty layerProperty, IProfileEditorService profileEditorService) { - LayerPropertyViewModel = layerPropertyViewModel; - LayerPropertyViewModel.LayerProperty.Updated += LayerPropertyOnUpdated; + LayerProperty = layerProperty; + ProfileEditorService = profileEditorService; + LayerProperty.Updated += LayerPropertyOnUpdated; UpdateInputValue(); } - protected PropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel, IModelValidator validator) : base(validator) + protected PropertyInputViewModel(LayerProperty layerProperty, IProfileEditorService profileEditorService, IModelValidator validator) : base(validator) { - LayerPropertyViewModel = layerPropertyViewModel; - LayerPropertyViewModel.LayerProperty.Updated += LayerPropertyOnUpdated; + LayerProperty = layerProperty; + ProfileEditorService = profileEditorService; + LayerProperty.Updated += LayerPropertyOnUpdated; UpdateInputValue(); } - public LayerPropertyViewModel LayerPropertyViewModel { get; } + public LayerProperty LayerProperty { get; } + public IProfileEditorService ProfileEditorService { get; } public bool InputDragging { get; private set; } @@ -37,7 +42,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyI public virtual void Dispose() { - LayerPropertyViewModel.LayerProperty.Updated -= LayerPropertyOnUpdated; + LayerProperty.Updated -= LayerPropertyOnUpdated; } protected virtual void OnInputValueApplied() @@ -48,6 +53,19 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyI { } + protected void ApplyInputValue() + { + // Force the validator to run + if (Validator != null) + Validate(); + // Only apply the input value to the layer property if the validator found no errors + if (!HasErrors) + SetCurrentValue(_inputValue, !InputDragging); + + OnInputValueChanged(); + OnInputValueApplied(); + } + private void LayerPropertyOnUpdated(object sender, EventArgs e) { UpdateInputValue(); @@ -56,11 +74,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyI private void UpdateInputValue() { // Avoid unnecessary UI updates and validator cycles - if (_inputValue != null && _inputValue.Equals(LayerPropertyViewModel.LayerProperty.CurrentValue) || _inputValue == null && LayerPropertyViewModel.LayerProperty.CurrentValue == null) + if (_inputValue != null && _inputValue.Equals(LayerProperty.CurrentValue) || _inputValue == null && LayerProperty.CurrentValue == null) return; // Override the input value - _inputValue = LayerPropertyViewModel.LayerProperty.CurrentValue; + _inputValue = LayerProperty.CurrentValue; // Notify a change in the input value OnInputValueChanged(); @@ -71,19 +89,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyI Validate(); } - protected void ApplyInputValue() - { - // Force the validator to run - if (Validator != null) - Validate(); - // Only apply the input value to the layer property if the validator found no errors - if (!HasErrors) - LayerPropertyViewModel.SetCurrentValue(_inputValue, !InputDragging); - - OnInputValueChanged(); - OnInputValueApplied(); - } - #region Event handlers @@ -95,7 +100,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyI public void InputDragEnded(object sender, EventArgs e) { InputDragging = false; - LayerPropertyViewModel.ProfileEditorService.UpdateSelectedProfileElement(); + ProfileEditorService.UpdateSelectedProfileElement(); + } + + private void SetCurrentValue(T value, bool saveChanges) + { + LayerProperty.SetCurrentValue(value, ProfileEditorService.CurrentTime); + if (saveChanges) + ProfileEditorService.UpdateSelectedProfileElement(); + else + ProfileEditorService.UpdateProfilePreview(); } #endregion diff --git a/src/Artemis.UI/Services/Interfaces/IProfileEditorService.cs b/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs similarity index 73% rename from src/Artemis.UI/Services/Interfaces/IProfileEditorService.cs rename to src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs index 2a393ecc1..2623b8c32 100644 --- a/src/Artemis.UI/Services/Interfaces/IProfileEditorService.cs +++ b/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs @@ -1,23 +1,23 @@ using System; +using System.Collections.Generic; using Artemis.Core.Models.Profile; -using Artemis.Core.Models.Profile.LayerProperties; -using Artemis.Core.Models.Profile.LayerProperties.Attributes; using Artemis.Core.Plugins.Abstract; -using Artemis.UI.Events; -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties; -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract; -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree; +using Artemis.Core.Plugins.Models; +using Artemis.UI.Shared.Events; +using Artemis.UI.Shared.PropertyInput; +using Ninject; -namespace Artemis.UI.Services.Interfaces +namespace Artemis.UI.Shared.Services.Interfaces { - public interface IProfileEditorService : IArtemisUIService + public interface IProfileEditorService : IArtemisSharedUIService { Profile SelectedProfile { get; } ProfileElement SelectedProfileElement { get; } TimeSpan CurrentTime { get; set; } int PixelsPerSecond { get; set; } + IReadOnlyList RegisteredPropertyEditors { get; } + IKernel Kernel { get; } - LayerPropertyBaseViewModel CreateLayerPropertyViewModel(BaseLayerProperty baseLayerProperty, PropertyDescriptionAttribute propertyDescription); void ChangeSelectedProfile(Profile profile); void UpdateSelectedProfile(); void ChangeSelectedProfileElement(ProfileElement profileElement); @@ -63,6 +63,7 @@ namespace Artemis.UI.Services.Interfaces /// event EventHandler ProfilePreviewUpdated; - TreePropertyViewModel CreateTreePropertyViewModel(LayerPropertyViewModel layerPropertyViewModel); + PropertyInputRegistration RegisterPropertyInput(PluginInfo pluginInfo, Type viewModelType); + void RemovePropertyInput(PropertyInputRegistration registration); } } \ No newline at end of file diff --git a/src/Artemis.UI/Services/ProfileEditorService.cs b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs similarity index 68% rename from src/Artemis.UI/Services/ProfileEditorService.cs rename to src/Artemis.UI.Shared/Services/ProfileEditorService.cs index 2f3fd1bb1..aaae33cc0 100644 --- a/src/Artemis.UI/Services/ProfileEditorService.cs +++ b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs @@ -1,32 +1,24 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Linq; using Artemis.Core.Models.Profile; -using Artemis.Core.Models.Profile.Colors; -using Artemis.Core.Models.Profile.LayerProperties; -using Artemis.Core.Models.Profile.LayerProperties.Attributes; using Artemis.Core.Plugins.Abstract; +using Artemis.Core.Plugins.Exceptions; +using Artemis.Core.Plugins.Models; using Artemis.Core.Services.Interfaces; using Artemis.Core.Services.Storage.Interfaces; -using Artemis.UI.Events; -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties; -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract; -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree; -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput; -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput.Abstract; -using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Events; +using Artemis.UI.Shared.PropertyInput; +using Artemis.UI.Shared.Services.Interfaces; using Ninject; -using Ninject.Parameters; -using SkiaSharp; -namespace Artemis.UI.Services +namespace Artemis.UI.Shared.Services { public class ProfileEditorService : IProfileEditorService { private readonly ICoreService _coreService; private readonly IProfileService _profileService; - private readonly IKernel _kernel; + private readonly List _registeredPropertyEditors; private TimeSpan _currentTime; private TimeSpan _lastUpdateTime; private int _pixelsPerSecond; @@ -35,23 +27,14 @@ namespace Artemis.UI.Services { _coreService = coreService; _profileService = profileService; - _kernel = kernel; + _registeredPropertyEditors = new List(); - RegisteredPropertyEditors = new Dictionary - { - {typeof(LayerBrushReference), typeof(BrushPropertyInputViewModel)}, - {typeof(ColorGradient), typeof(ColorGradientPropertyInputViewModel)}, - {typeof(float), typeof(FloatPropertyInputViewModel)}, - {typeof(int), typeof(IntPropertyInputViewModel)}, - {typeof(SKColor), typeof(SKColorPropertyInputViewModel)}, - {typeof(SKPoint), typeof(SKPointPropertyInputViewModel)}, - {typeof(SKSize), typeof(SKSizePropertyInputViewModel)} - }; + Kernel = kernel; PixelsPerSecond = 31; } - public Dictionary RegisteredPropertyEditors { get; set; } - + public IKernel Kernel { get; } + public IReadOnlyList RegisteredPropertyEditors => _registeredPropertyEditors.AsReadOnly(); public Profile SelectedProfile { get; private set; } public ProfileElement SelectedProfileElement { get; private set; } @@ -77,36 +60,6 @@ namespace Artemis.UI.Services OnPixelsPerSecondChanged(); } } - - public LayerPropertyBaseViewModel CreateLayerPropertyViewModel(BaseLayerProperty baseLayerProperty, PropertyDescriptionAttribute propertyDescription) - { - // Go through the pain of instantiating a generic type VM now via reflection to make things a lot simpler down the line - var genericType = baseLayerProperty.GetType().BaseType.GetGenericArguments()[0]; - // Only create entries for types supported by a tree input VM - if (!genericType.IsEnum && !RegisteredPropertyEditors.ContainsKey(genericType)) - return null; - var genericViewModel = typeof(LayerPropertyViewModel<>).MakeGenericType(genericType); - var parameters = new IParameter[] - { - new ConstructorArgument("layerProperty", baseLayerProperty), - new ConstructorArgument("propertyDescription", propertyDescription) - }; - - return (LayerPropertyBaseViewModel) _kernel.Get(genericViewModel, parameters); - } - - public TreePropertyViewModel CreateTreePropertyViewModel(LayerPropertyViewModel layerPropertyViewModel) - { - var type = typeof(T).IsEnum - ? typeof(EnumPropertyInputViewModel<>).MakeGenericType(typeof(T)) - : RegisteredPropertyEditors[typeof(T)]; - - var parameters = new IParameter[] - { - new ConstructorArgument("layerPropertyViewModel", layerPropertyViewModel) - }; - return new TreePropertyViewModel(layerPropertyViewModel, (PropertyInputViewModel) _kernel.Get(type, parameters), this); - } public void ChangeSelectedProfile(Profile profile) { @@ -138,7 +91,7 @@ namespace Artemis.UI.Services UpdateProfilePreview(); OnSelectedProfileElementUpdated(new ProfileElementEventArgs(SelectedProfileElement)); } - + public void UpdateProfilePreview() { if (SelectedProfile == null) @@ -193,6 +146,44 @@ namespace Artemis.UI.Services UpdateProfilePreview(); } + public PropertyInputRegistration RegisterPropertyInput(PluginInfo pluginInfo, Type viewModelType) + { + // Bit ugly to do a name comparison but I don't know a nicer way right now + if (viewModelType.BaseType == null || viewModelType.BaseType.Name != typeof(PropertyInputViewModel<>).Name) + throw new ArtemisPluginException($"{nameof(viewModelType)} base type must be of type PropertyInputViewModel"); + + lock (_registeredPropertyEditors) + { + var supportedType = viewModelType.BaseType.GetGenericArguments()[0]; + var 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 {pluginInfo.Name}"); + return existing; + } + + Kernel.Bind(viewModelType).ToSelf(); + var registration = new PropertyInputRegistration(this, pluginInfo, supportedType, viewModelType); + _registeredPropertyEditors.Add(registration); + return registration; + } + } + + public void RemovePropertyInput(PropertyInputRegistration registration) + { + lock (_registeredPropertyEditors) + { + if (_registeredPropertyEditors.Contains(registration)) + { + registration.Unsubscribe(); + _registeredPropertyEditors.Remove(registration); + + Kernel.Unbind(registration.ViewModelType); + } + } + } + public event EventHandler ProfileSelected; public event EventHandler SelectedProfileUpdated; public event EventHandler ProfileElementSelected; @@ -200,7 +191,7 @@ namespace Artemis.UI.Services public event EventHandler CurrentTimeChanged; public event EventHandler PixelsPerSecondChanged; public event EventHandler ProfilePreviewUpdated; - + public void StopRegularRender() { _coreService.ModuleUpdatingDisabled = true; diff --git a/src/Artemis.UI/Artemis.UI_u2tszd0b_wpftmp.csproj b/src/Artemis.UI/Artemis.UI_u2tszd0b_wpftmp.csproj new file mode 100644 index 000000000..3370246ca --- /dev/null +++ b/src/Artemis.UI/Artemis.UI_u2tszd0b_wpftmp.csproj @@ -0,0 +1,565 @@ + + + WinExe + netcoreapp3.1 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + true + Artemis + Artemis + en-US + Adds third-party support for RGB keyboards to games. + Copyright © Robert Beekman - 2019 + 2.0.0.0 + 2.0.0.0 + true + MinimumRecommendedRules.ruleset + bin\$(Platform)\$(Configuration)\ + true + + + full + + + pdbonly + + + Resources\Images\Logo\logo-512.ico + + + + + + + + + + + + + + + + + + + + ResXFileCodeGenerator + Designer + Resources.Designer.cs + + + + + true + + + true + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Ninject/UiModule.cs b/src/Artemis.UI/Ninject/UiModule.cs index 22d640f81..484fab1b9 100644 --- a/src/Artemis.UI/Ninject/UiModule.cs +++ b/src/Artemis.UI/Ninject/UiModule.cs @@ -2,8 +2,8 @@ using Artemis.UI.Ninject.Factories; using Artemis.UI.Screens; using Artemis.UI.Screens.Module.ProfileEditor; -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput.Abstract; using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.PropertyInput; using Artemis.UI.Shared.Services.Dialog; using Artemis.UI.Stylet; using FluentValidation; @@ -77,14 +77,6 @@ namespace Artemis.UI.Ninject .InheritedFrom() .BindAllInterfaces(); }); - - Kernel.Bind(x => - { - x.FromThisAssembly() - .SelectAllClasses() - .InheritedFrom(typeof(PropertyInputViewModel<>)) - .BindToSelf(); - }); } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/BrushPropertyInputView.xaml b/src/Artemis.UI/PropertyInput/BrushPropertyInputView.xaml similarity index 66% rename from src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/BrushPropertyInputView.xaml rename to src/Artemis.UI/PropertyInput/BrushPropertyInputView.xaml index 144bc1a21..fda36c166 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/BrushPropertyInputView.xaml +++ b/src/Artemis.UI/PropertyInput/BrushPropertyInputView.xaml @@ -1,15 +1,15 @@ - - + - + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/BrushPropertyInputViewModel.cs b/src/Artemis.UI/PropertyInput/BrushPropertyInputViewModel.cs similarity index 82% rename from src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/BrushPropertyInputViewModel.cs rename to src/Artemis.UI/PropertyInput/BrushPropertyInputViewModel.cs index 3b79f8c22..d0fcafbfa 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/BrushPropertyInputViewModel.cs +++ b/src/Artemis.UI/PropertyInput/BrushPropertyInputViewModel.cs @@ -2,21 +2,23 @@ using System.Linq; using Artemis.Core.Events; using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Profile.LayerProperties; using Artemis.Core.Plugins.LayerBrush; using Artemis.Core.Services.Interfaces; -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput.Abstract; +using Artemis.UI.Shared.PropertyInput; +using Artemis.UI.Shared.Services.Interfaces; using Artemis.UI.Shared.Utilities; using Stylet; -namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput +namespace Artemis.UI.PropertyInput { public class BrushPropertyInputViewModel : PropertyInputViewModel { private readonly ILayerService _layerService; private readonly IPluginService _pluginService; - public BrushPropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel, ILayerService layerService, IPluginService pluginService) - : base(layerPropertyViewModel) + public BrushPropertyInputViewModel(LayerProperty layerProperty, IProfileEditorService profileEditorService, + ILayerService layerService, IPluginService pluginService) : base(layerProperty, profileEditorService) { _layerService = layerService; _pluginService = pluginService; @@ -54,14 +56,14 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyI base.Dispose(); } + protected override void OnInputValueApplied() + { + _layerService.InstantiateLayerBrush(LayerProperty.Layer); + } + private void PluginServiceOnPluginLoaded(object sender, PluginEventArgs e) { UpdateEnumValues(); } - - protected override void OnInputValueApplied() - { - _layerService.InstantiateLayerBrush(LayerPropertyViewModel.LayerProperty.Layer); - } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/ColorGradientPropertyInputView.xaml b/src/Artemis.UI/PropertyInput/ColorGradientPropertyInputView.xaml similarity index 65% rename from src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/ColorGradientPropertyInputView.xaml rename to src/Artemis.UI/PropertyInput/ColorGradientPropertyInputView.xaml index 36b05107a..c9f307925 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/ColorGradientPropertyInputView.xaml +++ b/src/Artemis.UI/PropertyInput/ColorGradientPropertyInputView.xaml @@ -1,22 +1,22 @@ - - + - + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/ColorGradientPropertyInputViewModel.cs b/src/Artemis.UI/PropertyInput/ColorGradientPropertyInputViewModel.cs similarity index 54% rename from src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/ColorGradientPropertyInputViewModel.cs rename to src/Artemis.UI/PropertyInput/ColorGradientPropertyInputViewModel.cs index 222a8d690..5b6c6df99 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/ColorGradientPropertyInputViewModel.cs +++ b/src/Artemis.UI/PropertyInput/ColorGradientPropertyInputViewModel.cs @@ -1,12 +1,15 @@ using System; using Artemis.Core.Models.Profile.Colors; -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput.Abstract; +using Artemis.Core.Models.Profile.LayerProperties; +using Artemis.UI.Shared.PropertyInput; +using Artemis.UI.Shared.Services.Interfaces; -namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput +namespace Artemis.UI.PropertyInput { public class ColorGradientPropertyInputViewModel : PropertyInputViewModel { - public ColorGradientPropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel) : base(layerPropertyViewModel) + public ColorGradientPropertyInputViewModel(LayerProperty layerProperty, IProfileEditorService profileEditorService) + : base(layerProperty, profileEditorService) { } diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/EnumPropertyInputView.xaml b/src/Artemis.UI/PropertyInput/EnumPropertyInputView.xaml similarity index 70% rename from src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/EnumPropertyInputView.xaml rename to src/Artemis.UI/PropertyInput/EnumPropertyInputView.xaml index 1d5d36fe4..92b18d134 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/EnumPropertyInputView.xaml +++ b/src/Artemis.UI/PropertyInput/EnumPropertyInputView.xaml @@ -1,4 +1,4 @@ - - + - + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/EnumPropertyInputViewModel.cs b/src/Artemis.UI/PropertyInput/EnumPropertyInputViewModel.cs similarity index 51% rename from src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/EnumPropertyInputViewModel.cs rename to src/Artemis.UI/PropertyInput/EnumPropertyInputViewModel.cs index 57ccfcd44..e52a177e5 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/EnumPropertyInputViewModel.cs +++ b/src/Artemis.UI/PropertyInput/EnumPropertyInputViewModel.cs @@ -1,17 +1,19 @@ using System; using System.Collections.Generic; -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput.Abstract; +using Artemis.Core.Models.Profile.LayerProperties; +using Artemis.UI.Shared.PropertyInput; +using Artemis.UI.Shared.Services.Interfaces; using Artemis.UI.Shared.Utilities; -namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput +namespace Artemis.UI.PropertyInput { public class EnumPropertyInputViewModel : PropertyInputViewModel where T : Enum { - public EnumPropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel) : base(layerPropertyViewModel) + public EnumPropertyInputViewModel(LayerProperty layerProperty, IProfileEditorService profileEditorService) : base(layerProperty, profileEditorService) { EnumValues = EnumUtilities.GetAllValuesAndDescriptions(typeof(T)); } - + public IEnumerable EnumValues { get; } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/FloatPropertyInputView.xaml b/src/Artemis.UI/PropertyInput/FloatPropertyInputView.xaml similarity index 63% rename from src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/FloatPropertyInputView.xaml rename to src/Artemis.UI/PropertyInput/FloatPropertyInputView.xaml index 6febaabd1..4d8968600 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/FloatPropertyInputView.xaml +++ b/src/Artemis.UI/PropertyInput/FloatPropertyInputView.xaml @@ -1,24 +1,24 @@ - - + - + \ No newline at end of file diff --git a/src/Artemis.UI/PropertyInput/FloatPropertyInputViewModel.cs b/src/Artemis.UI/PropertyInput/FloatPropertyInputViewModel.cs new file mode 100644 index 000000000..1f1a5fd89 --- /dev/null +++ b/src/Artemis.UI/PropertyInput/FloatPropertyInputViewModel.cs @@ -0,0 +1,30 @@ +using Artemis.Core.Models.Profile.LayerProperties; +using Artemis.UI.Shared.PropertyInput; +using Artemis.UI.Shared.Services.Interfaces; +using FluentValidation; +using Stylet; + +namespace Artemis.UI.PropertyInput +{ + public class FloatPropertyInputViewModel : PropertyInputViewModel + { + public FloatPropertyInputViewModel(LayerProperty layerProperty, IProfileEditorService profileEditorService, IModelValidator validator) + : base(layerProperty, profileEditorService, validator) + { + } + } + + public class FloatPropertyInputViewModelValidator : AbstractValidator + { + public FloatPropertyInputViewModelValidator() + { + RuleFor(vm => vm.InputValue) + .LessThanOrEqualTo(vm => (float) vm.LayerProperty.PropertyDescription.MaxInputValue) + .When(vm => vm.LayerProperty.PropertyDescription.MaxInputValue is float); + + RuleFor(vm => vm.InputValue) + .GreaterThanOrEqualTo(vm => (float) vm.LayerProperty.PropertyDescription.MinInputValue) + .When(vm => vm.LayerProperty.PropertyDescription.MinInputValue is float); + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/IntPropertyInputView.xaml b/src/Artemis.UI/PropertyInput/IntPropertyInputView.xaml similarity index 63% rename from src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/IntPropertyInputView.xaml rename to src/Artemis.UI/PropertyInput/IntPropertyInputView.xaml index b0cd46d65..da20c954f 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/IntPropertyInputView.xaml +++ b/src/Artemis.UI/PropertyInput/IntPropertyInputView.xaml @@ -1,24 +1,24 @@ - - + - + \ No newline at end of file diff --git a/src/Artemis.UI/PropertyInput/IntPropertyInputViewModel.cs b/src/Artemis.UI/PropertyInput/IntPropertyInputViewModel.cs new file mode 100644 index 000000000..f3ec8eb35 --- /dev/null +++ b/src/Artemis.UI/PropertyInput/IntPropertyInputViewModel.cs @@ -0,0 +1,30 @@ +using Artemis.Core.Models.Profile.LayerProperties; +using Artemis.UI.Shared.PropertyInput; +using Artemis.UI.Shared.Services.Interfaces; +using FluentValidation; +using Stylet; + +namespace Artemis.UI.PropertyInput +{ + public class IntPropertyInputViewModel : PropertyInputViewModel + { + public IntPropertyInputViewModel(LayerProperty layerProperty, IProfileEditorService profileEditorService, IModelValidator validator) + : base(layerProperty, profileEditorService, validator) + { + } + } + + public class IntPropertyInputViewModelValidator : AbstractValidator + { + public IntPropertyInputViewModelValidator() + { + RuleFor(vm => vm.InputValue) + .LessThanOrEqualTo(vm => (int) vm.LayerProperty.PropertyDescription.MaxInputValue) + .When(vm => vm.LayerProperty.PropertyDescription.MaxInputValue is int); + + RuleFor(vm => vm.InputValue) + .GreaterThanOrEqualTo(vm => (int) vm.LayerProperty.PropertyDescription.MinInputValue) + .When(vm => vm.LayerProperty.PropertyDescription.MinInputValue is int); + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKColorPropertyInputView.xaml b/src/Artemis.UI/PropertyInput/SKColorPropertyInputView.xaml similarity index 64% rename from src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKColorPropertyInputView.xaml rename to src/Artemis.UI/PropertyInput/SKColorPropertyInputView.xaml index 691cf7544..c1eb6cfaa 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKColorPropertyInputView.xaml +++ b/src/Artemis.UI/PropertyInput/SKColorPropertyInputView.xaml @@ -1,13 +1,13 @@ - @@ -15,11 +15,11 @@ - + - + \ No newline at end of file diff --git a/src/Artemis.UI/PropertyInput/SKColorPropertyInputViewModel.cs b/src/Artemis.UI/PropertyInput/SKColorPropertyInputViewModel.cs new file mode 100644 index 000000000..7232e963f --- /dev/null +++ b/src/Artemis.UI/PropertyInput/SKColorPropertyInputViewModel.cs @@ -0,0 +1,14 @@ +using Artemis.Core.Models.Profile.LayerProperties; +using Artemis.UI.Shared.PropertyInput; +using Artemis.UI.Shared.Services.Interfaces; +using SkiaSharp; + +namespace Artemis.UI.PropertyInput +{ + public class SKColorPropertyInputViewModel : PropertyInputViewModel + { + public SKColorPropertyInputViewModel(LayerProperty layerProperty, IProfileEditorService profileEditorService) : base(layerProperty, profileEditorService) + { + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKPointPropertyInputView.xaml b/src/Artemis.UI/PropertyInput/SKPointPropertyInputView.xaml similarity index 61% rename from src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKPointPropertyInputView.xaml rename to src/Artemis.UI/PropertyInput/SKPointPropertyInputView.xaml index e4c49615d..38f9ce08e 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKPointPropertyInputView.xaml +++ b/src/Artemis.UI/PropertyInput/SKPointPropertyInputView.xaml @@ -1,29 +1,29 @@ - - + , - + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKPointPropertyInputViewModel.cs b/src/Artemis.UI/PropertyInput/SKPointPropertyInputViewModel.cs similarity index 57% rename from src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKPointPropertyInputViewModel.cs rename to src/Artemis.UI/PropertyInput/SKPointPropertyInputViewModel.cs index 692a8416f..82bd7cd00 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKPointPropertyInputViewModel.cs +++ b/src/Artemis.UI/PropertyInput/SKPointPropertyInputViewModel.cs @@ -1,15 +1,17 @@ -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput.Abstract; +using Artemis.Core.Models.Profile.LayerProperties; +using Artemis.UI.Shared.PropertyInput; +using Artemis.UI.Shared.Services.Interfaces; using FluentValidation; using PropertyChanged; using SkiaSharp; using Stylet; -namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput +namespace Artemis.UI.PropertyInput { public class SKPointPropertyInputViewModel : PropertyInputViewModel { - public SKPointPropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel, IModelValidator validator) - : base(layerPropertyViewModel, validator) + public SKPointPropertyInputViewModel(LayerProperty layerProperty, IProfileEditorService profileEditorService, + IModelValidator validator) : base(layerProperty, profileEditorService, validator) { } @@ -40,18 +42,18 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyI public SKPointPropertyInputViewModelValidator() { RuleFor(vm => vm.X) - .LessThanOrEqualTo(vm => ((SKPoint) vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue).X) - .When(vm => vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue is SKPoint); + .LessThanOrEqualTo(vm => ((SKPoint) vm.LayerProperty.PropertyDescription.MaxInputValue).X) + .When(vm => vm.LayerProperty.PropertyDescription.MaxInputValue is SKPoint); RuleFor(vm => vm.X) - .GreaterThanOrEqualTo(vm => ((SKPoint) vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue).X) - .When(vm => vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue is SKPoint); + .GreaterThanOrEqualTo(vm => ((SKPoint) vm.LayerProperty.PropertyDescription.MaxInputValue).X) + .When(vm => vm.LayerProperty.PropertyDescription.MaxInputValue is SKPoint); RuleFor(vm => vm.Y) - .LessThanOrEqualTo(vm => ((SKPoint) vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue).Y) - .When(vm => vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue is SKPoint); + .LessThanOrEqualTo(vm => ((SKPoint) vm.LayerProperty.PropertyDescription.MaxInputValue).Y) + .When(vm => vm.LayerProperty.PropertyDescription.MaxInputValue is SKPoint); RuleFor(vm => vm.Y) - .GreaterThanOrEqualTo(vm => ((SKPoint) vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue).Y) - .When(vm => vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue is SKPoint); + .GreaterThanOrEqualTo(vm => ((SKPoint) vm.LayerProperty.PropertyDescription.MaxInputValue).Y) + .When(vm => vm.LayerProperty.PropertyDescription.MaxInputValue is SKPoint); } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKSizePropertyInputView.xaml b/src/Artemis.UI/PropertyInput/SKSizePropertyInputView.xaml similarity index 64% rename from src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKSizePropertyInputView.xaml rename to src/Artemis.UI/PropertyInput/SKSizePropertyInputView.xaml index d581fa6a9..237e29db1 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKSizePropertyInputView.xaml +++ b/src/Artemis.UI/PropertyInput/SKSizePropertyInputView.xaml @@ -1,9 +1,9 @@ - - + , - + \ No newline at end of file diff --git a/src/Artemis.UI/PropertyInput/SKSizePropertyInputViewModel.cs b/src/Artemis.UI/PropertyInput/SKSizePropertyInputViewModel.cs new file mode 100644 index 000000000..b0021c4d5 --- /dev/null +++ b/src/Artemis.UI/PropertyInput/SKSizePropertyInputViewModel.cs @@ -0,0 +1,59 @@ +using Artemis.Core.Models.Profile.LayerProperties; +using Artemis.UI.Shared.PropertyInput; +using Artemis.UI.Shared.Services.Interfaces; +using FluentValidation; +using PropertyChanged; +using SkiaSharp; +using Stylet; + +namespace Artemis.UI.PropertyInput +{ + public class SKSizePropertyInputViewModel : PropertyInputViewModel + { + public SKSizePropertyInputViewModel(LayerProperty layerProperty, IProfileEditorService profileEditorService, + IModelValidator validator) : base(layerProperty, profileEditorService, validator) + { + } + + // Since SKSize is immutable we need to create properties that replace the SKSize entirely + [DependsOn(nameof(InputValue))] + public float Width + { + get => InputValue.Width; + set => InputValue = new SKSize(value, Height); + } + + [DependsOn(nameof(InputValue))] + public float Height + { + get => InputValue.Height; + set => InputValue = new SKSize(Width, value); + } + + protected override void OnInputValueChanged() + { + NotifyOfPropertyChange(nameof(Width)); + NotifyOfPropertyChange(nameof(Height)); + } + } + + public class SKSizePropertyInputViewModelValidator : AbstractValidator + { + public SKSizePropertyInputViewModelValidator() + { + RuleFor(vm => vm.Width) + .LessThanOrEqualTo(vm => ((SKSize) vm.LayerProperty.PropertyDescription.MaxInputValue).Width) + .When(vm => vm.LayerProperty.PropertyDescription.MaxInputValue is SKSize); + RuleFor(vm => vm.Width) + .GreaterThanOrEqualTo(vm => ((SKSize) vm.LayerProperty.PropertyDescription.MaxInputValue).Width) + .When(vm => vm.LayerProperty.PropertyDescription.MaxInputValue is SKSize); + + RuleFor(vm => vm.Height) + .LessThanOrEqualTo(vm => ((SKSize) vm.LayerProperty.PropertyDescription.MaxInputValue).Height) + .When(vm => vm.LayerProperty.PropertyDescription.MaxInputValue is SKSize); + RuleFor(vm => vm.Height) + .GreaterThanOrEqualTo(vm => ((SKSize) vm.LayerProperty.PropertyDescription.MaxInputValue).Height) + .When(vm => vm.LayerProperty.PropertyDescription.MaxInputValue is SKSize); + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs index b6fc0e6dd..a5c7e79a7 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs @@ -16,6 +16,8 @@ using Artemis.UI.Events; using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline; using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree; using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Events; +using Artemis.UI.Shared.Services.Interfaces; using Stylet; namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyGroupViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyGroupViewModel.cs index 44d33dfa0..dbc638142 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyGroupViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyGroupViewModel.cs @@ -1,18 +1,22 @@ using System; using System.Collections.Generic; +using System.Linq; using Artemis.Core.Models.Profile; using Artemis.Core.Models.Profile.LayerProperties; using Artemis.Core.Models.Profile.LayerProperties.Attributes; using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract; using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline; using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree; -using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Services.Interfaces; +using Ninject; +using Ninject.Parameters; namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties { public class LayerPropertyGroupViewModel : LayerPropertyBaseViewModel { - public LayerPropertyGroupViewModel(IProfileEditorService profileEditorService, LayerPropertyGroup layerPropertyGroup, PropertyGroupDescriptionAttribute propertyGroupDescription) + public LayerPropertyGroupViewModel(IProfileEditorService profileEditorService, LayerPropertyGroup layerPropertyGroup, + PropertyGroupDescriptionAttribute propertyGroupDescription) { ProfileEditorService = profileEditorService; @@ -43,36 +47,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties public TreePropertyGroupViewModel TreePropertyGroupViewModel { get; set; } public TimelinePropertyGroupViewModel TimelinePropertyGroupViewModel { get; set; } - private void PopulateChildren() - { - // Get all properties and property groups and create VMs for them - foreach (var propertyInfo in LayerPropertyGroup.GetType().GetProperties()) - { - var propertyAttribute = (PropertyDescriptionAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(PropertyDescriptionAttribute)); - var groupAttribute = (PropertyGroupDescriptionAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(PropertyGroupDescriptionAttribute)); - var value = propertyInfo.GetValue(LayerPropertyGroup); - - // Create VMs for properties on the group - if (propertyAttribute != null && value is BaseLayerProperty baseLayerProperty) - { - var viewModel = ProfileEditorService.CreateLayerPropertyViewModel(baseLayerProperty, propertyAttribute); - if (viewModel != null) - Children.Add(viewModel); - } - // Create VMs for child groups on this group, resulting in a nested structure - else if (groupAttribute != null && value is LayerPropertyGroup layerPropertyGroup) - { - Children.Add(new LayerPropertyGroupViewModel(ProfileEditorService, layerPropertyGroup, groupAttribute)); - } - } - } - public override List GetKeyframes(bool expandedOnly) { var result = new List(); if (expandedOnly && !IsExpanded || LayerPropertyGroup.IsHidden) return result; - + foreach (var layerPropertyBaseViewModel in Children) result.AddRange(layerPropertyBaseViewModel.GetKeyframes(expandedOnly)); @@ -101,6 +81,48 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties return result; } + private void PopulateChildren() + { + // Get all properties and property groups and create VMs for them + foreach (var propertyInfo in LayerPropertyGroup.GetType().GetProperties()) + { + var propertyAttribute = (PropertyDescriptionAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(PropertyDescriptionAttribute)); + var groupAttribute = (PropertyGroupDescriptionAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(PropertyGroupDescriptionAttribute)); + var value = propertyInfo.GetValue(LayerPropertyGroup); + + // Create VMs for properties on the group + if (propertyAttribute != null && value is BaseLayerProperty baseLayerProperty) + { + var viewModel = CreateLayerPropertyViewModel(baseLayerProperty, propertyAttribute); + if (viewModel != null) + Children.Add(viewModel); + } + // Create VMs for child groups on this group, resulting in a nested structure + else if (groupAttribute != null && value is LayerPropertyGroup layerPropertyGroup) + Children.Add(new LayerPropertyGroupViewModel(ProfileEditorService, layerPropertyGroup, groupAttribute)); + } + } + + private LayerPropertyBaseViewModel CreateLayerPropertyViewModel(BaseLayerProperty baseLayerProperty, PropertyDescriptionAttribute propertyDescription) + { + // Go through the pain of instantiating a generic type VM now via reflection to make things a lot simpler down the line + var genericType = baseLayerProperty.GetType().Name == typeof(LayerProperty<>).Name + ? baseLayerProperty.GetType().GetGenericArguments()[0] + : baseLayerProperty.GetType().BaseType.GetGenericArguments()[0]; + + // Only create entries for types supported by a tree input VM + if (!genericType.IsEnum && ProfileEditorService.RegisteredPropertyEditors.All(r => r.SupportedType != genericType)) + return null; + var genericViewModel = typeof(LayerPropertyViewModel<>).MakeGenericType(genericType); + var parameters = new IParameter[] + { + new ConstructorArgument("layerProperty", baseLayerProperty), + new ConstructorArgument("propertyDescription", propertyDescription) + }; + + return (LayerPropertyBaseViewModel) ProfileEditorService.Kernel.Get(genericViewModel, parameters); + } + private void LayerPropertyGroupOnVisibilityChanged(object sender, EventArgs e) { NotifyOfPropertyChange(nameof(IsVisible)); diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs index ae4a6fbf7..22e7e31ff 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs @@ -2,37 +2,39 @@ using System.Collections.Generic; using System.Linq; using Artemis.Core.Models.Profile.LayerProperties; -using Artemis.Core.Models.Profile.LayerProperties.Attributes; +using Artemis.UI.Exceptions; using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract; using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline; using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree; -using Artemis.UI.Services.Interfaces; +using Artemis.UI.PropertyInput; +using Artemis.UI.Shared.PropertyInput; +using Artemis.UI.Shared.Services.Interfaces; using Humanizer; +using Ninject; +using Ninject.Parameters; namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties { public class LayerPropertyViewModel : LayerPropertyViewModel { - public LayerPropertyViewModel(IProfileEditorService profileEditorService, LayerProperty layerProperty, PropertyDescriptionAttribute propertyDescription) - : base(profileEditorService, layerProperty) + public LayerPropertyViewModel(IProfileEditorService profileEditorService, LayerProperty layerProperty) : base(profileEditorService, layerProperty) { LayerProperty = layerProperty; - PropertyDescription = propertyDescription; - TreePropertyViewModel = ProfileEditorService.CreateTreePropertyViewModel(this); + TreePropertyViewModel = CreateTreePropertyViewModel(); TimelinePropertyViewModel = new TimelinePropertyViewModel(this, profileEditorService); TreePropertyBaseViewModel = TreePropertyViewModel; TimelinePropertyBaseViewModel = TimelinePropertyViewModel; // Generate a fallback name if the description does not contain one - if (PropertyDescription.Name == null) + if (LayerProperty.PropertyDescription.Name == null) { var propertyInfo = LayerProperty.Parent?.GetType().GetProperties().FirstOrDefault(p => ReferenceEquals(p.GetValue(LayerProperty.Parent), LayerProperty)); if (propertyInfo != null) - PropertyDescription.Name = propertyInfo.Name.Humanize(); + LayerProperty.PropertyDescription.Name = propertyInfo.Name.Humanize(); else - PropertyDescription.Name = $"Unknown {typeof(T).Name} property"; + LayerProperty.PropertyDescription.Name = $"Unknown {typeof(T).Name} property"; } LayerProperty.VisibilityChanged += LayerPropertyOnVisibilityChanged; @@ -69,6 +71,29 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties ProfileEditorService.UpdateProfilePreview(); } + private TreePropertyViewModel CreateTreePropertyViewModel() + { + // Make sure there is a supported property editor VM, unless the type is an enum, then we'll use the EnumPropertyInputViewModel + Type vmType = null; + if (typeof(T).IsEnum) + vmType = typeof(EnumPropertyInputViewModel<>).MakeGenericType(typeof(T)); + else + { + var registration = ProfileEditorService.RegisteredPropertyEditors.FirstOrDefault(r => r.SupportedType == typeof(T)); + if (registration != null) + vmType = registration.ViewModelType; + } + + if (vmType == null) + throw new ArtemisUIException($"Cannot create a tree property view model for type {typeof(T)}, found no matching property editor"); + + var parameters = new IParameter[] + { + new ConstructorArgument("layerProperty", LayerProperty) + }; + return new TreePropertyViewModel(this, (PropertyInputViewModel) ProfileEditorService.Kernel.Get(vmType, parameters), ProfileEditorService); + } + private void LayerPropertyOnVisibilityChanged(object sender, EventArgs e) { NotifyOfPropertyChange(nameof(IsVisible)); @@ -86,7 +111,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties public IProfileEditorService ProfileEditorService { get; } public BaseLayerProperty BaseLayerProperty { get; } - public PropertyDescriptionAttribute PropertyDescription { get; protected set; } public TreePropertyViewModel TreePropertyBaseViewModel { get; set; } public TimelinePropertyViewModel TimelinePropertyBaseViewModel { get; set; } } diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineKeyframeViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineKeyframeViewModel.cs index f979a5dc1..d8aeb87c3 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineKeyframeViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelineKeyframeViewModel.cs @@ -5,6 +5,7 @@ using System.Windows.Input; using Artemis.Core.Models.Profile.LayerProperties; using Artemis.Core.Utilities; using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Services.Interfaces; using Stylet; namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyViewModel.cs index 79aa4be1d..688b621e0 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/TimelinePropertyViewModel.cs @@ -3,6 +3,7 @@ using System.Linq; using Artemis.UI.Exceptions; using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract; using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Services.Interfaces; using Stylet; namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/FloatPropertyInputViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/FloatPropertyInputViewModel.cs deleted file mode 100644 index 55954397d..000000000 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/FloatPropertyInputViewModel.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput.Abstract; -using FluentValidation; -using Stylet; - -namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput -{ - public class FloatPropertyInputViewModel : PropertyInputViewModel - { - public FloatPropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel, IModelValidator validator) - : base(layerPropertyViewModel, validator) - { - } - } - - public class FloatPropertyInputViewModelValidator : AbstractValidator - { - public FloatPropertyInputViewModelValidator() - { - RuleFor(vm => vm.InputValue) - .LessThanOrEqualTo(vm => (float) vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue) - .When(vm => vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue is float); - - RuleFor(vm => vm.InputValue) - .GreaterThanOrEqualTo(vm => (float) vm.LayerPropertyViewModel.PropertyDescription.MinInputValue) - .When(vm => vm.LayerPropertyViewModel.PropertyDescription.MinInputValue is float); - } - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/IntPropertyInputViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/IntPropertyInputViewModel.cs deleted file mode 100644 index adce93b8b..000000000 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/IntPropertyInputViewModel.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput.Abstract; -using FluentValidation; -using Stylet; - -namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput -{ - public class IntPropertyInputViewModel : PropertyInputViewModel - { - public IntPropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel, IModelValidator validator) - : base(layerPropertyViewModel, validator) - { - } - } - - public class IntPropertyInputViewModelValidator : AbstractValidator - { - public IntPropertyInputViewModelValidator() - { - RuleFor(vm => vm.InputValue) - .LessThanOrEqualTo(vm => (int) vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue) - .When(vm => vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue is int); - - RuleFor(vm => vm.InputValue) - .GreaterThanOrEqualTo(vm => (int) vm.LayerPropertyViewModel.PropertyDescription.MinInputValue) - .When(vm => vm.LayerPropertyViewModel.PropertyDescription.MinInputValue is int); - } - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKColorPropertyInputViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKColorPropertyInputViewModel.cs deleted file mode 100644 index 8e28eaeb2..000000000 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKColorPropertyInputViewModel.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput.Abstract; -using SkiaSharp; - -namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput -{ - public class SKColorPropertyInputViewModel : PropertyInputViewModel - { - public SKColorPropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel) : base(layerPropertyViewModel) - { - } - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKSizePropertyInputViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKSizePropertyInputViewModel.cs deleted file mode 100644 index 715b855c4..000000000 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/PropertyInput/SKSizePropertyInputViewModel.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput.Abstract; -using FluentValidation; -using PropertyChanged; -using SkiaSharp; -using Stylet; - -namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput -{ - public class SKSizePropertyInputViewModel : PropertyInputViewModel - { - public SKSizePropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel, IModelValidator validator) - : base(layerPropertyViewModel, validator) - { - } - - // Since SKSize is immutable we need to create properties that replace the SKSize entirely - [DependsOn(nameof(InputValue))] - public float Width - { - get => InputValue.Width; - set => InputValue = new SKSize(value, Height); - } - - [DependsOn(nameof(InputValue))] - public float Height - { - get => InputValue.Height; - set => InputValue = new SKSize(Width, value); - } - - protected override void OnInputValueChanged() - { - NotifyOfPropertyChange(nameof(Width)); - NotifyOfPropertyChange(nameof(Height)); - } - } - - public class SKSizePropertyInputViewModelValidator : AbstractValidator - { - public SKSizePropertyInputViewModelValidator() - { - RuleFor(vm => vm.Width) - .LessThanOrEqualTo(vm => ((SKSize)vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue).Width) - .When(vm => vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue is SKSize); - RuleFor(vm => vm.Width) - .GreaterThanOrEqualTo(vm => ((SKSize)vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue).Width) - .When(vm => vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue is SKSize); - - RuleFor(vm => vm.Height) - .LessThanOrEqualTo(vm => ((SKSize)vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue).Height) - .When(vm => vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue is SKSize); - RuleFor(vm => vm.Height) - .GreaterThanOrEqualTo(vm => ((SKSize)vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue).Height) - .When(vm => vm.LayerPropertyViewModel.PropertyDescription.MaxInputValue is SKSize); - } - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/TreePropertyView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/TreePropertyView.xaml index 8feb55e17..287b137c4 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/TreePropertyView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/TreePropertyView.xaml @@ -1,12 +1,12 @@  @@ -32,11 +32,18 @@ Padding="0,0,5,0" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" - Text="{Binding LayerPropertyViewModel.PropertyDescription.Name}" - ToolTip="{Binding LayerPropertyViewModel.PropertyDescription.Description}" + Text="{Binding LayerPropertyViewModel.LayerProperty.PropertyDescription.Name}" + ToolTip="{Binding LayerPropertyViewModel.LayerProperty.PropertyDescription.Description}" HorizontalAlignment="Left" /> - + + + + + - + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/TreePropertyViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/TreePropertyViewModel.cs index 874a013bf..4162a9a51 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/TreePropertyViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Tree/TreePropertyViewModel.cs @@ -3,8 +3,8 @@ using System.Linq; using Artemis.Core.Models.Profile.LayerProperties; using Artemis.Core.Utilities; using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract; -using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput.Abstract; -using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.PropertyInput; +using Artemis.UI.Shared.Services.Interfaces; namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree { @@ -47,7 +47,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree )); } // If disabling keyframes, set the base value to the current value - else if (!enable && LayerPropertyViewModel.LayerProperty.Keyframes.Any()) + else if (!enable && LayerPropertyViewModel.LayerProperty.Keyframes.Any()) LayerPropertyViewModel.LayerProperty.BaseValue = LayerPropertyViewModel.LayerProperty.CurrentValue; LayerPropertyViewModel.LayerProperty.KeyframesEnabled = enable; diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs index 8bd77cedf..386a8b01d 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs @@ -5,6 +5,7 @@ using Artemis.Core.Models.Profile; using Artemis.UI.Ninject.Factories; using Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem; using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Services.Interfaces; using GongSolutions.Wpf.DragDrop; namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerViewModel.cs index f10d565df..08cd6475d 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileLayerViewModel.cs @@ -9,6 +9,7 @@ using Artemis.Core.Models.Profile.LayerShapes; using Artemis.Core.Models.Surface; using Artemis.UI.Extensions; using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Services.Interfaces; using RGB.NET.Core; using Stylet; using Rectangle = Artemis.Core.Models.Profile.LayerShapes.Rectangle; diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs index f338700ad..2e45471e7 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs @@ -16,6 +16,7 @@ using Artemis.UI.Ninject.Factories; using Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools; using Artemis.UI.Screens.Shared; using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Services.Interfaces; using Stylet; namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization @@ -338,7 +339,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization UpdateCanSelectEditTool(); } - private void SelectedLayerOnLayerBrushUpdated(object? sender, EventArgs e) + private void SelectedLayerOnLayerBrushUpdated(object sender, EventArgs e) { UpdateCanSelectEditTool(); } diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs index 66eaaec3e..0d905f5c2 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolViewModel.cs @@ -5,6 +5,7 @@ using System.Windows.Media; using Artemis.Core.Models.Profile; using Artemis.UI.Events; using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Services.Interfaces; using SkiaSharp; using SkiaSharp.Views.WPF; using Stylet; diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/SelectionRemoveToolViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/SelectionRemoveToolViewModel.cs index 75570f727..21d4a2ec7 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/SelectionRemoveToolViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/SelectionRemoveToolViewModel.cs @@ -5,6 +5,7 @@ using System.Windows.Input; using Artemis.Core.Models.Profile; using Artemis.UI.Properties; using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Services.Interfaces; namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools { diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/SelectionToolViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/SelectionToolViewModel.cs index df928ce6b..afb3c66c5 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/SelectionToolViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/SelectionToolViewModel.cs @@ -5,6 +5,7 @@ using System.Windows.Input; using Artemis.Core.Models.Profile; using Artemis.UI.Properties; using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Services.Interfaces; namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools { diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/ViewpointMoveToolViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/ViewpointMoveToolViewModel.cs index 1e5458478..28246086f 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/ViewpointMoveToolViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/ViewpointMoveToolViewModel.cs @@ -1,5 +1,6 @@ using System.Windows.Input; using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Services.Interfaces; namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools { diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/VisualizationToolViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/VisualizationToolViewModel.cs index 26d6c38b6..d0c7ad1b7 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/VisualizationToolViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/VisualizationToolViewModel.cs @@ -2,6 +2,7 @@ using System.Windows; using System.Windows.Input; using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Services.Interfaces; namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools { diff --git a/src/Artemis.UI/Services/LayerEditorService.cs b/src/Artemis.UI/Services/LayerEditorService.cs index 57a405fd5..3ad8008f2 100644 --- a/src/Artemis.UI/Services/LayerEditorService.cs +++ b/src/Artemis.UI/Services/LayerEditorService.cs @@ -1,9 +1,14 @@ using System; using System.Windows; using System.Windows.Media; +using Artemis.Core; using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Profile.Colors; using Artemis.Core.Services; +using Artemis.UI.PropertyInput; +using Artemis.UI.PropertyInput; using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Services.Interfaces; using SkiaSharp; using SkiaSharp.Views.WPF; @@ -12,10 +17,24 @@ namespace Artemis.UI.Services public class LayerEditorService : ILayerEditorService { private readonly ISettingsService _settingsService; + private readonly IProfileEditorService _profileEditorService; - public LayerEditorService(ISettingsService settingsService) + public LayerEditorService(ISettingsService settingsService, IProfileEditorService profileEditorService) { _settingsService = settingsService; + _profileEditorService = profileEditorService; + RegisterBuiltInPropertyEditors(); + } + + private void RegisterBuiltInPropertyEditors() + { + _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo, typeof(BrushPropertyInputViewModel)); + _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo, typeof(ColorGradientPropertyInputViewModel)); + _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo, typeof(FloatPropertyInputViewModel)); + _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo, typeof(IntPropertyInputViewModel)); + _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo, typeof(SKColorPropertyInputViewModel)); + _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo, typeof(SKPointPropertyInputViewModel)); + _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo, typeof(SKSizePropertyInputViewModel)); } /// diff --git a/src/Plugins/Artemis.Plugins.Devices.Asus/AsusDeviceProvider.cs b/src/Plugins/Artemis.Plugins.Devices.Asus/AsusDeviceProvider.cs index f2bd5d9d9..21397cf43 100644 --- a/src/Plugins/Artemis.Plugins.Devices.Asus/AsusDeviceProvider.cs +++ b/src/Plugins/Artemis.Plugins.Devices.Asus/AsusDeviceProvider.cs @@ -16,7 +16,7 @@ namespace Artemis.Plugins.Devices.Asus _rgbService = rgbService; } - public override void EnablePlugin() + protected override void EnablePlugin() { PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(AsusRGBDevice<>), sender, args); _rgbService.AddDeviceProvider(RgbDeviceProvider); diff --git a/src/Plugins/Artemis.Plugins.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs b/src/Plugins/Artemis.Plugins.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs index 46c4f0779..7ed66a7cd 100644 --- a/src/Plugins/Artemis.Plugins.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs +++ b/src/Plugins/Artemis.Plugins.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs @@ -17,7 +17,7 @@ namespace Artemis.Plugins.Devices.CoolerMaster _rgbService = rgbService; } - public override void EnablePlugin() + protected override void EnablePlugin() { PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(CoolerMasterRGBDevice<>), sender, args); RGB.NET.Devices.CoolerMaster.CoolerMasterDeviceProvider.PossibleX64NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x64", "CMSDK.dll")); diff --git a/src/Plugins/Artemis.Plugins.Devices.Corsair/CorsairDeviceProvider.cs b/src/Plugins/Artemis.Plugins.Devices.Corsair/CorsairDeviceProvider.cs index d51c8f0ca..9175a9318 100644 --- a/src/Plugins/Artemis.Plugins.Devices.Corsair/CorsairDeviceProvider.cs +++ b/src/Plugins/Artemis.Plugins.Devices.Corsair/CorsairDeviceProvider.cs @@ -17,7 +17,7 @@ namespace Artemis.Plugins.Devices.Corsair _rgbService = rgbService; } - public override void EnablePlugin() + protected override void EnablePlugin() { PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(CorsairRGBDevice<>), sender, args); RGB.NET.Devices.Corsair.CorsairDeviceProvider.PossibleX64NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x64", "CUESDK.x64_2017.dll")); diff --git a/src/Plugins/Artemis.Plugins.Devices.DMX/DMXDeviceProvider.cs b/src/Plugins/Artemis.Plugins.Devices.DMX/DMXDeviceProvider.cs index b4c1a4c2c..03c7d82cc 100644 --- a/src/Plugins/Artemis.Plugins.Devices.DMX/DMXDeviceProvider.cs +++ b/src/Plugins/Artemis.Plugins.Devices.DMX/DMXDeviceProvider.cs @@ -17,7 +17,7 @@ namespace Artemis.Plugins.Devices.DMX HasConfigurationViewModel = true; } - public override void EnablePlugin() + protected override void EnablePlugin() { // TODO: Load from configuration // RGB.NET.Devices.DMX.DMXDeviceProvider.Instance.AddDeviceDefinition(); diff --git a/src/Plugins/Artemis.Plugins.Devices.Logitech/LogitechDeviceProvider.cs b/src/Plugins/Artemis.Plugins.Devices.Logitech/LogitechDeviceProvider.cs index 2110311e7..19fbb9619 100644 --- a/src/Plugins/Artemis.Plugins.Devices.Logitech/LogitechDeviceProvider.cs +++ b/src/Plugins/Artemis.Plugins.Devices.Logitech/LogitechDeviceProvider.cs @@ -25,7 +25,7 @@ namespace Artemis.Plugins.Devices.Logitech _logger = logger; } - public override void EnablePlugin() + protected override void EnablePlugin() { PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(LogitechRGBDevice<>), sender, args); RGB.NET.Devices.Logitech.LogitechDeviceProvider.PossibleX64NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x64", "LogitechLedEnginesWrapper.dll")); diff --git a/src/Plugins/Artemis.Plugins.Devices.Msi/MsiDeviceProvider.cs b/src/Plugins/Artemis.Plugins.Devices.Msi/MsiDeviceProvider.cs index aa51d1e9e..9efa7be72 100644 --- a/src/Plugins/Artemis.Plugins.Devices.Msi/MsiDeviceProvider.cs +++ b/src/Plugins/Artemis.Plugins.Devices.Msi/MsiDeviceProvider.cs @@ -17,7 +17,7 @@ namespace Artemis.Plugins.Devices.Msi _rgbService = rgbService; } - public override void EnablePlugin() + protected override void EnablePlugin() { PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(MsiRGBDevice<>), sender, args); RGB.NET.Devices.Msi.MsiDeviceProvider.PossibleX64NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x64", "MysticLight_SDK.dll")); diff --git a/src/Plugins/Artemis.Plugins.Devices.Novation/NovationDeviceProvider.cs b/src/Plugins/Artemis.Plugins.Devices.Novation/NovationDeviceProvider.cs index d5c794cfd..e05fd0446 100644 --- a/src/Plugins/Artemis.Plugins.Devices.Novation/NovationDeviceProvider.cs +++ b/src/Plugins/Artemis.Plugins.Devices.Novation/NovationDeviceProvider.cs @@ -16,7 +16,7 @@ namespace Artemis.Plugins.Devices.Novation _rgbService = rgbService; } - public override void EnablePlugin() + protected override void EnablePlugin() { PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(NovationRGBDevice<>), sender, args); _rgbService.AddDeviceProvider(RgbDeviceProvider); diff --git a/src/Plugins/Artemis.Plugins.Devices.Razer/RazerDeviceProvider.cs b/src/Plugins/Artemis.Plugins.Devices.Razer/RazerDeviceProvider.cs index c4d40870f..141854a29 100644 --- a/src/Plugins/Artemis.Plugins.Devices.Razer/RazerDeviceProvider.cs +++ b/src/Plugins/Artemis.Plugins.Devices.Razer/RazerDeviceProvider.cs @@ -18,7 +18,7 @@ namespace Artemis.Plugins.Devices.Razer _rgbService = rgbService; } - public override void EnablePlugin() + protected override void EnablePlugin() { PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(RazerRGBDevice<>), sender, args); RGB.NET.Devices.Razer.RazerDeviceProvider.PossibleX64NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x64", "RzChromaSDK.dll")); diff --git a/src/Plugins/Artemis.Plugins.Devices.Roccat/RoccatDeviceProvider.cs b/src/Plugins/Artemis.Plugins.Devices.Roccat/RoccatDeviceProvider.cs index c2f24c09f..e6cad1a44 100644 --- a/src/Plugins/Artemis.Plugins.Devices.Roccat/RoccatDeviceProvider.cs +++ b/src/Plugins/Artemis.Plugins.Devices.Roccat/RoccatDeviceProvider.cs @@ -15,7 +15,7 @@ namespace Artemis.Plugins.Devices.Roccat _rgbService = rgbService; } - public override void EnablePlugin() + protected override void EnablePlugin() { // TODO: Find out why this is missing, Roccat seems unimplemented // PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(RoccatRGBDevice<>), sender, args); diff --git a/src/Plugins/Artemis.Plugins.Devices.SteelSeries/SteelSeriesDeviceProvider.cs b/src/Plugins/Artemis.Plugins.Devices.SteelSeries/SteelSeriesDeviceProvider.cs index 3e63cf3ee..7ea539c09 100644 --- a/src/Plugins/Artemis.Plugins.Devices.SteelSeries/SteelSeriesDeviceProvider.cs +++ b/src/Plugins/Artemis.Plugins.Devices.SteelSeries/SteelSeriesDeviceProvider.cs @@ -16,7 +16,7 @@ namespace Artemis.Plugins.Devices.SteelSeries _rgbService = rgbService; } - public override void EnablePlugin() + protected override void EnablePlugin() { // TODO Check to see if this works, it's usually a generic type after all PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(SteelSeriesRGBDevice), sender, args); diff --git a/src/Plugins/Artemis.Plugins.Devices.WS281X/WS281XDeviceProvider.cs b/src/Plugins/Artemis.Plugins.Devices.WS281X/WS281XDeviceProvider.cs index 45111b8f3..80a7384f0 100644 --- a/src/Plugins/Artemis.Plugins.Devices.WS281X/WS281XDeviceProvider.cs +++ b/src/Plugins/Artemis.Plugins.Devices.WS281X/WS281XDeviceProvider.cs @@ -25,7 +25,7 @@ namespace Artemis.Plugins.Devices.WS281X public PluginSettings Settings { get; } - public override void EnablePlugin() + protected override void EnablePlugin() { var definitions = Settings.GetSetting>("DeviceDefinitions"); if (definitions.Value == null) @@ -49,18 +49,11 @@ namespace Artemis.Plugins.Devices.WS281X _rgbService.AddDeviceProvider(RgbDeviceProvider); } - public override void DisablePlugin() + protected override void DisablePlugin() { // TODO: Remove the device provider from the surface } - - public override void Dispose() - { - // TODO: This will probably not go well without first removing the device provider - // WS281XDeviceProvider.Instance.ResetDevices(); - // WS281XDeviceProvider.Instance.Dispose(); - } - + public override PluginConfigurationViewModel GetConfigurationViewModel() { return new WS281XConfigurationViewModel(this, Settings); diff --git a/src/Plugins/Artemis.Plugins.Devices.Wooting/WootingDeviceProvider.cs b/src/Plugins/Artemis.Plugins.Devices.Wooting/WootingDeviceProvider.cs index 01ac495f0..f4827d031 100644 --- a/src/Plugins/Artemis.Plugins.Devices.Wooting/WootingDeviceProvider.cs +++ b/src/Plugins/Artemis.Plugins.Devices.Wooting/WootingDeviceProvider.cs @@ -17,7 +17,7 @@ namespace Artemis.Plugins.Devices.Wooting _rgbService = rgbService; } - public override void EnablePlugin() + protected override void EnablePlugin() { PathHelper.ResolvingAbsolutePath += (sender, args) => ResolveAbsolutePath(typeof(WootingRGBDevice<>), sender, args); RGB.NET.Devices.Wooting.WootingDeviceProvider.PossibleX64NativePaths.Add(Path.Combine(PluginInfo.Directory.FullName, "x64", "wooting-rgb-sdk64.dll")); @@ -25,16 +25,9 @@ namespace Artemis.Plugins.Devices.Wooting _rgbService.AddDeviceProvider(RgbDeviceProvider); } - public override void DisablePlugin() + protected override void DisablePlugin() { // TODO: Remove the device provider from the surface } - - public override void Dispose() - { - // TODO: This will probably not go well without first removing the device provider - // WootingDeviceProvider.Instance.ResetDevices(); - // WootingDeviceProvider.Instance.Dispose(); - } } } \ No newline at end of file diff --git a/src/Plugins/Artemis.Plugins.LayerBrushes.Color/ColorBrushProvider.cs b/src/Plugins/Artemis.Plugins.LayerBrushes.Color/ColorBrushProvider.cs index f6997a637..b0e5e73fb 100644 --- a/src/Plugins/Artemis.Plugins.LayerBrushes.Color/ColorBrushProvider.cs +++ b/src/Plugins/Artemis.Plugins.LayerBrushes.Color/ColorBrushProvider.cs @@ -10,15 +10,11 @@ namespace Artemis.Plugins.LayerBrushes.Color AddLayerBrushDescriptor("Color", "A color with an (optional) gradient", "Brush"); } - public override void EnablePlugin() + protected override void EnablePlugin() { } - public override void DisablePlugin() - { - } - - public override void Dispose() + protected override void DisablePlugin() { } } diff --git a/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/Artemis.Plugins.LayerBrushes.ColorRgbNet.csproj b/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/Artemis.Plugins.LayerBrushes.ColorRgbNet.csproj index f4ea5ac8d..fe7e89e03 100644 --- a/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/Artemis.Plugins.LayerBrushes.ColorRgbNet.csproj +++ b/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/Artemis.Plugins.LayerBrushes.ColorRgbNet.csproj @@ -35,6 +35,7 @@ false + diff --git a/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/PropertyInput/StringPropertyInputView.xaml b/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/PropertyInput/StringPropertyInputView.xaml new file mode 100644 index 000000000..3f2e1f71d --- /dev/null +++ b/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/PropertyInput/StringPropertyInputView.xaml @@ -0,0 +1,23 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/PropertyInput/StringPropertyInputViewModel.cs b/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/PropertyInput/StringPropertyInputViewModel.cs new file mode 100644 index 000000000..b296d1f08 --- /dev/null +++ b/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/PropertyInput/StringPropertyInputViewModel.cs @@ -0,0 +1,14 @@ +using Artemis.Core.Models.Profile.LayerProperties; +using Artemis.UI.Shared.PropertyInput; +using Artemis.UI.Shared.Services.Interfaces; + +namespace Artemis.Plugins.LayerBrushes.ColorRgbNet.PropertyInput +{ + public class StringPropertyInputViewModel : PropertyInputViewModel + { + public StringPropertyInputViewModel(LayerProperty layerProperty, IProfileEditorService profileEditorService) : base(layerProperty, profileEditorService) + { + // This is a fairly dumb input that can only take text and nothing else so it needs no special logic in its VM + } + } +} \ No newline at end of file diff --git a/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/RgbNetColorBrush.cs b/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/RgbNetColorBrush.cs index 7cf6a9e86..a9f88ca25 100644 --- a/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/RgbNetColorBrush.cs +++ b/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/RgbNetColorBrush.cs @@ -1,4 +1,5 @@ -using Artemis.Core.Extensions; +using System; +using Artemis.Core.Extensions; using Artemis.Core.Models.Profile; using Artemis.Core.Plugins.LayerBrush; using RGB.NET.Brushes; diff --git a/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/RgbNetColorBrushProperties.cs b/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/RgbNetColorBrushProperties.cs index 5364e5d32..ab0a7dcc2 100644 --- a/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/RgbNetColorBrushProperties.cs +++ b/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/RgbNetColorBrushProperties.cs @@ -1,4 +1,5 @@ using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Profile.LayerProperties; using Artemis.Core.Models.Profile.LayerProperties.Attributes; using Artemis.Core.Models.Profile.LayerProperties.Types; using SkiaSharp; @@ -10,9 +11,13 @@ namespace Artemis.Plugins.LayerBrushes.ColorRgbNet [PropertyDescription(Description = "The color of the brush")] public SKColorLayerProperty Color { get; set; } + [PropertyDescription(InputPrefix = "Test")] + public LayerProperty TestProperty { get; set; } + protected override void PopulateDefaults() { Color.DefaultValue = new SKColor(255, 0, 0); + TestProperty.DefaultValue = "I was empty before!"; } protected override void OnPropertiesInitialized() diff --git a/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/RgbNetColorBrushProvider.cs b/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/RgbNetColorBrushProvider.cs index ec6116510..06c28000f 100644 --- a/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/RgbNetColorBrushProvider.cs +++ b/src/Plugins/Artemis.Plugins.LayerBrushes.ColorRgbNet/RgbNetColorBrushProvider.cs @@ -1,24 +1,26 @@ using Artemis.Core.Plugins.LayerBrush; using Artemis.Core.Plugins.Models; +using Artemis.Plugins.LayerBrushes.ColorRgbNet.PropertyInput; +using Artemis.UI.Shared.Services.Interfaces; namespace Artemis.Plugins.LayerBrushes.ColorRgbNet { public class RgbNetColorBrushProvider : LayerBrushProvider { - public RgbNetColorBrushProvider(PluginInfo pluginInfo) : base(pluginInfo) + private readonly IProfileEditorService _profileEditorService; + + public RgbNetColorBrushProvider(PluginInfo pluginInfo, IProfileEditorService profileEditorService) : base(pluginInfo) { + _profileEditorService = profileEditorService; AddLayerBrushDescriptor("RGB.NET Color", "A RGB.NET based color", "Brush"); } - public override void EnablePlugin() + protected override void EnablePlugin() { + _profileEditorService.RegisterPropertyInput(PluginInfo, typeof(StringPropertyInputViewModel)); } - public override void DisablePlugin() - { - } - - public override void Dispose() + protected override void DisablePlugin() { } } diff --git a/src/Plugins/Artemis.Plugins.LayerBrushes.Noise/NoiseBrushProvider.cs b/src/Plugins/Artemis.Plugins.LayerBrushes.Noise/NoiseBrushProvider.cs index f2b0e8f50..d55370b7d 100644 --- a/src/Plugins/Artemis.Plugins.LayerBrushes.Noise/NoiseBrushProvider.cs +++ b/src/Plugins/Artemis.Plugins.LayerBrushes.Noise/NoiseBrushProvider.cs @@ -10,15 +10,11 @@ namespace Artemis.Plugins.LayerBrushes.Noise AddLayerBrushDescriptor("Noise", "A brush of that shows an animated random noise", "ScatterPlot"); } - public override void EnablePlugin() + protected override void EnablePlugin() { } - public override void DisablePlugin() - { - } - - public override void Dispose() + protected override void DisablePlugin() { } } diff --git a/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs b/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs index d3e52b7dc..d5cb76f93 100644 --- a/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs +++ b/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs @@ -22,20 +22,16 @@ namespace Artemis.Plugins.Modules.General var testSetting = _settings.GetSetting("TestSetting", DateTime.Now); } - public override void EnablePlugin() - { - } - - public override void DisablePlugin() - { - } - public override IEnumerable GetViewModels() { return new List {new GeneralViewModel(this)}; } - public override void Dispose() + protected override void EnablePlugin() + { + } + + protected override void DisablePlugin() { } }