diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index 3a632ed07..8869fac59 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -56,4 +56,7 @@ ..\..\..\RGB.NET\bin\netstandard2.0\RGB.NET.Groups.dll + + + \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/ColorGradient.cs b/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs similarity index 80% rename from src/Artemis.Core/Models/Profile/ColorGradient.cs rename to src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs index 7414f13ef..f6f2d721a 100644 --- a/src/Artemis.Core/Models/Profile/ColorGradient.cs +++ b/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs @@ -6,7 +6,7 @@ using Artemis.Core.Annotations; using SkiaSharp; using Stylet; -namespace Artemis.Core.Models.Profile +namespace Artemis.Core.Models.Profile.Colors { public class ColorGradient : INotifyPropertyChanged { @@ -88,28 +88,4 @@ namespace Artemis.Core.Models.Profile #endregion } - - public class ColorGradientStop : INotifyPropertyChanged - { - public ColorGradientStop(SKColor color, float position) - { - Color = color; - Position = position; - } - - public SKColor Color { get; set; } - public float Position { get; set; } - - #region PropertyChanged - - public event PropertyChangedEventHandler PropertyChanged; - - [NotifyPropertyChangedInvocator] - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - #endregion - } } \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Colors/ColorGradientStop.cs b/src/Artemis.Core/Models/Profile/Colors/ColorGradientStop.cs new file mode 100644 index 000000000..7a860da42 --- /dev/null +++ b/src/Artemis.Core/Models/Profile/Colors/ColorGradientStop.cs @@ -0,0 +1,31 @@ +using System.ComponentModel; +using System.Runtime.CompilerServices; +using Artemis.Core.Annotations; +using SkiaSharp; + +namespace Artemis.Core.Models.Profile.Colors +{ + public class ColorGradientStop : INotifyPropertyChanged + { + public ColorGradientStop(SKColor color, float position) + { + Color = color; + Position = position; + } + + public SKColor Color { get; set; } + public float Position { get; set; } + + #region PropertyChanged + + public event PropertyChangedEventHandler PropertyChanged; + + [NotifyPropertyChangedInvocator] + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Conditions/LayerCondition.cs b/src/Artemis.Core/Models/Profile/Conditions/LayerCondition.cs new file mode 100644 index 000000000..fb91ef3b6 --- /dev/null +++ b/src/Artemis.Core/Models/Profile/Conditions/LayerCondition.cs @@ -0,0 +1,11 @@ +using System; +using System.Linq.Expressions; +using Artemis.Core.Plugins.Abstract.DataModels; + +namespace Artemis.Core.Models.Profile.Conditions +{ + public class LayerCondition + { + public Expression> ExpressionTree { get; set; } + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Plugins/Abstract/DataModels/Attributes/DataModelProperty.cs b/src/Artemis.Core/Plugins/Abstract/DataModels/Attributes/DataModelProperty.cs new file mode 100644 index 000000000..030f951c2 --- /dev/null +++ b/src/Artemis.Core/Plugins/Abstract/DataModels/Attributes/DataModelProperty.cs @@ -0,0 +1,43 @@ +using System; + +namespace Artemis.Core.Plugins.Abstract.DataModels.Attributes +{ + [AttributeUsage(System.AttributeTargets.Property)] + public class DataModelPropertyAttribute : Attribute + { + /// + /// Gets or sets the user-friendly name for this property, shown in the UI. + /// + public string Name { get; set; } + + /// + /// Gets or sets the user-friendly description for this property, shown in the UI. + /// + public string Description { get; set; } + + /// + /// Gets or sets the an optional input prefix to show before input elements in the UI. + /// + public string InputPrefix { get; set; } + + /// + /// Gets or sets an optional input affix to show behind input elements in the UI. + /// + public string InputAffix { get; set; } + + /// + /// Gets or sets an optional maximum input value, only enforced in the UI. + /// + public object MaxInputValue { get; set; } + + /// + /// Gets or sets the input drag step size, used in the UI. + /// + public float InputStepSize { get; set; } + + /// + /// Gets or sets an optional minimum input value, only enforced in the UI. + /// + public object MinInputValue { get; set; } + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Plugins/Abstract/DataModels/DataModel.cs b/src/Artemis.Core/Plugins/Abstract/DataModels/DataModel.cs new file mode 100644 index 000000000..114b1aedb --- /dev/null +++ b/src/Artemis.Core/Plugins/Abstract/DataModels/DataModel.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Artemis.Core.Plugins.Abstract.DataModels.Attributes; +using Artemis.Core.Plugins.Exceptions; +using SkiaSharp; + +namespace Artemis.Core.Plugins.Abstract.DataModels +{ + public abstract class DataModel + { + private static readonly List SupportedTypes = new List + { + typeof(bool), + typeof(byte), + typeof(decimal), + typeof(double), + typeof(float), + typeof(int), + typeof(long), + typeof(string), + typeof(SKColor), + typeof(SKPoint) + }; + + protected DataModel(Module module) + { + Module = module; + Validate(); + } + + public Module Module { get; } + + /// + /// Recursively validates the current datamodel, ensuring all properties annotated with + /// are of supported types. + /// + /// + public bool Validate() + { + return ValidateType(GetType()); + } + + private bool ValidateType(Type type) + { + foreach (var propertyInfo in type.GetProperties()) + { + var dataModelPropertyAttribute = (DataModelPropertyAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(DataModelPropertyAttribute)); + if (dataModelPropertyAttribute == null) + continue; + + // If the a nested datamodel, ensure the properties on there are valid + if (propertyInfo.PropertyType == typeof(DataModel)) + ValidateType(propertyInfo.PropertyType); + else if (!SupportedTypes.Contains(propertyInfo.PropertyType)) + { + // Show a useful error for plugin devs + throw new ArtemisPluginException(Module.PluginInfo, + $"Plugin datamodel contains property of unsupported type {propertyInfo.PropertyType.Name}. \r\n\r\n" + + $"Property name: {propertyInfo.Name}\r\n" + + $"Property declared on: {propertyInfo.DeclaringType?.Name ?? "-"} \r\n\r\n" + + $"Supported properties:\r\n{string.Join("\r\n", SupportedTypes.Select(t => $" - {t.Name}"))}"); + } + } + + return true; + } + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Plugins/Abstract/Module.cs b/src/Artemis.Core/Plugins/Abstract/Module.cs index 2c69f9d4e..1e0b3951a 100644 --- a/src/Artemis.Core/Plugins/Abstract/Module.cs +++ b/src/Artemis.Core/Plugins/Abstract/Module.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Artemis.Core.Models.Surface; +using Artemis.Core.Plugins.Abstract.DataModels; using Artemis.Core.Plugins.Abstract.ViewModels; using Artemis.Core.Plugins.Models; using SkiaSharp; @@ -27,6 +28,11 @@ namespace Artemis.Core.Plugins.Abstract /// public string DisplayIcon { get; set; } + /// + /// The optional datamodel driving this module + /// + public DataModel DataModel { get; set; } + /// /// Whether or not this module expands upon the main data model. If set to true any data in main data model can be /// accessed by profiles in this module diff --git a/src/Artemis.Core/Plugins/Abstract/ModuleDataModel.cs b/src/Artemis.Core/Plugins/Abstract/ModuleDataModel.cs deleted file mode 100644 index aef8fe778..000000000 --- a/src/Artemis.Core/Plugins/Abstract/ModuleDataModel.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Artemis.Core.Plugins.Abstract -{ - public abstract class ModuleDataModel - { - protected ModuleDataModel(Module module) - { - Module = module; - } - - public Module Module { get; } - } -} \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Controls/GradientPicker.xaml.cs b/src/Artemis.UI.Shared/Controls/GradientPicker.xaml.cs index 3a3a59c97..a001c5c9d 100644 --- a/src/Artemis.UI.Shared/Controls/GradientPicker.xaml.cs +++ b/src/Artemis.UI.Shared/Controls/GradientPicker.xaml.cs @@ -5,6 +5,7 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Input; using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Profile.Colors; using Artemis.UI.Shared.Annotations; using Artemis.UI.Shared.Services.Interfaces; diff --git a/src/Artemis.UI.Shared/Converters/ColorGradientToGradientStopsConverter.cs b/src/Artemis.UI.Shared/Converters/ColorGradientToGradientStopsConverter.cs index a5c82a4cb..67618268a 100644 --- a/src/Artemis.UI.Shared/Converters/ColorGradientToGradientStopsConverter.cs +++ b/src/Artemis.UI.Shared/Converters/ColorGradientToGradientStopsConverter.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Windows.Data; using System.Windows.Media; using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Profile.Colors; using SkiaSharp; using Stylet; diff --git a/src/Artemis.UI.Shared/Ninject/Factories/IVMFactory.cs b/src/Artemis.UI.Shared/Ninject/Factories/IVMFactory.cs index 026791701..44ba4b651 100644 --- a/src/Artemis.UI.Shared/Ninject/Factories/IVMFactory.cs +++ b/src/Artemis.UI.Shared/Ninject/Factories/IVMFactory.cs @@ -1,4 +1,5 @@ using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Profile.Colors; using Artemis.UI.Shared.Screens.GradientEditor; namespace Artemis.UI.Shared.Ninject.Factories diff --git a/src/Artemis.UI.Shared/Screens/GradientEditor/ColorStopViewModel.cs b/src/Artemis.UI.Shared/Screens/GradientEditor/ColorStopViewModel.cs index 67227cfd1..f43242776 100644 --- a/src/Artemis.UI.Shared/Screens/GradientEditor/ColorStopViewModel.cs +++ b/src/Artemis.UI.Shared/Screens/GradientEditor/ColorStopViewModel.cs @@ -6,6 +6,7 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Input; using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Profile.Colors; using Artemis.UI.Shared.Utilities; using Stylet; diff --git a/src/Artemis.UI.Shared/Screens/GradientEditor/GradientEditorViewModel.cs b/src/Artemis.UI.Shared/Screens/GradientEditor/GradientEditorViewModel.cs index f80008f53..9f25b57c9 100644 --- a/src/Artemis.UI.Shared/Screens/GradientEditor/GradientEditorViewModel.cs +++ b/src/Artemis.UI.Shared/Screens/GradientEditor/GradientEditorViewModel.cs @@ -5,6 +5,7 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Input; using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Profile.Colors; using Artemis.UI.Shared.Services.Dialog; using Artemis.UI.Shared.Utilities; using Stylet; diff --git a/src/Artemis.UI.Shared/Services/GradientPickerService.cs b/src/Artemis.UI.Shared/Services/GradientPickerService.cs index 012aedad5..f246c5dd4 100644 --- a/src/Artemis.UI.Shared/Services/GradientPickerService.cs +++ b/src/Artemis.UI.Shared/Services/GradientPickerService.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Profile.Colors; using Artemis.UI.Shared.Screens.GradientEditor; using Artemis.UI.Shared.Services.Interfaces; diff --git a/src/Artemis.UI.Shared/Services/Interfaces/IGradientPickerService.cs b/src/Artemis.UI.Shared/Services/Interfaces/IGradientPickerService.cs index d01d54495..6ce388682 100644 --- a/src/Artemis.UI.Shared/Services/Interfaces/IGradientPickerService.cs +++ b/src/Artemis.UI.Shared/Services/Interfaces/IGradientPickerService.cs @@ -1,4 +1,5 @@ using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Profile.Colors; namespace Artemis.UI.Shared.Services.Interfaces { diff --git a/src/Artemis.UI/Bootstrapper.cs b/src/Artemis.UI/Bootstrapper.cs index 77b25d542..c24342daa 100644 --- a/src/Artemis.UI/Bootstrapper.cs +++ b/src/Artemis.UI/Bootstrapper.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Threading; +using Artemis.Core.Models.Profile.Conditions; using Artemis.Core.Ninject; using Artemis.Core.Services.Interfaces; using Artemis.UI.Ninject; @@ -33,6 +34,8 @@ namespace Artemis.UI protected override void Launch() { + var test = new LayerCondition(); + StartupArguments = Args.ToList(); var logger = Kernel.Get(); diff --git a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs index 34986e68d..d803e5918 100644 --- a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs +++ b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs @@ -1,5 +1,6 @@ using Artemis.Core.Models.Profile; using Artemis.Core.Models.Profile.LayerProperties; +using Artemis.Core.Models.Profile.LayerProperties.Abstract; using Artemis.Core.Models.Surface; using Artemis.Core.Plugins.Abstract; using Artemis.UI.Screens.Module; diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/ColorGradientPropertyInputViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/ColorGradientPropertyInputViewModel.cs index c03a8ac86..beeb353c7 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/ColorGradientPropertyInputViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/ColorGradientPropertyInputViewModel.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Profile.Colors; using Artemis.UI.Services.Interfaces; namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTrackKeyframeViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTrackKeyframeViewModel.cs index 30876cdbe..79d4e6483 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTrackKeyframeViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTrackKeyframeViewModel.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Windows; using System.Windows.Input; using Artemis.Core.Models.Profile.LayerProperties; +using Artemis.Core.Models.Profile.LayerProperties.Abstract; using Artemis.Core.Utilities; using Artemis.UI.Services.Interfaces; using Stylet; diff --git a/src/Plugins/Artemis.Plugins.LayerBrushes.Color/ColorBrush.cs b/src/Plugins/Artemis.Plugins.LayerBrushes.Color/ColorBrush.cs index dcfe1ee33..ac9956297 100644 --- a/src/Plugins/Artemis.Plugins.LayerBrushes.Color/ColorBrush.cs +++ b/src/Plugins/Artemis.Plugins.LayerBrushes.Color/ColorBrush.cs @@ -2,6 +2,7 @@ using System.ComponentModel; using System.Linq; using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Profile.Colors; using Artemis.Core.Models.Profile.LayerProperties; using Artemis.Core.Plugins.LayerBrush; using SkiaSharp; diff --git a/src/Plugins/Artemis.Plugins.LayerBrushes.Noise/NoiseBrush.cs b/src/Plugins/Artemis.Plugins.LayerBrushes.Noise/NoiseBrush.cs index 8bd35f190..81627c599 100644 --- a/src/Plugins/Artemis.Plugins.LayerBrushes.Noise/NoiseBrush.cs +++ b/src/Plugins/Artemis.Plugins.LayerBrushes.Noise/NoiseBrush.cs @@ -2,6 +2,7 @@ using System.ComponentModel; using System.Linq; using Artemis.Core.Models.Profile; +using Artemis.Core.Models.Profile.Colors; using Artemis.Core.Models.Profile.LayerProperties; using Artemis.Core.Plugins.LayerBrush; using Artemis.Core.Services.Interfaces; diff --git a/src/Plugins/Artemis.Plugins.Modules.General/GeneralDataModel.cs b/src/Plugins/Artemis.Plugins.Modules.General/GeneralDataModel.cs index c80f4d24d..3ecf70361 100644 --- a/src/Plugins/Artemis.Plugins.Modules.General/GeneralDataModel.cs +++ b/src/Plugins/Artemis.Plugins.Modules.General/GeneralDataModel.cs @@ -1,15 +1,35 @@ -using Artemis.Core.Attributes; -using Artemis.Core.Plugins.Abstract; +using Artemis.Core.Plugins.Abstract; +using Artemis.Core.Plugins.Abstract.DataModels; +using Artemis.Core.Plugins.Abstract.DataModels.Attributes; +using SkiaSharp; namespace Artemis.Plugins.Modules.General { - public class GeneralDataModel : ModuleDataModel + public class GeneralDataModel : DataModel { public GeneralDataModel(Module module) : base(module) { } - [DataModelProperty(DisplayName = "Unique boolean")] - public bool PropertyUniqueToThisDm { get; set; } + [DataModelProperty(Name = "A test string", Description = "This is a test string that's not of any use outside testing!")] + public string TestString { get; set; } + + [DataModelProperty(Name = "A test boolean", Description = "This is a test boolean that's not of any use outside testing!")] + public bool TestBoolean { get; set; } + + [DataModelProperty(Name = "Player info", Description = "[TEST] Contains information about the player")] + public PlayerInfo PlayerInfo { get; set; } + } + + public class PlayerInfo + { + [DataModelProperty(Name = "A test string", Description = "This is a test string that's not of any use outside testing!")] + public string TestString { get; set; } + + [DataModelProperty(Name = "A test boolean", Description = "This is a test boolean that's not of any use outside testing!")] + public bool TestBoolean { get; set; } + + [DataModelProperty()] + public SKRect SkRect { get; set; } } } \ No newline at end of file diff --git a/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs b/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs index 5f4c10688..4c9871d64 100644 --- a/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs +++ b/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs @@ -17,10 +17,11 @@ namespace Artemis.Plugins.Modules.General DisplayName = "General"; DisplayIcon = "AllInclusive"; ExpandsMainDataModel = true; + DataModel = new GeneralDataModel(this); var testSetting = _settings.GetSetting("TestSetting", DateTime.Now); } - + public override void EnablePlugin() { }