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()
{
}