diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj
index ea172f092..b57dbfde5 100644
--- a/src/Artemis.Core/Artemis.Core.csproj
+++ b/src/Artemis.Core/Artemis.Core.csproj
@@ -149,7 +149,9 @@
-
+
+
+
@@ -161,7 +163,7 @@
-
+
diff --git a/src/Artemis.Core/Models/Profile/Keyframe.cs b/src/Artemis.Core/Models/Profile/Keyframe.cs
deleted file mode 100644
index f89ace002..000000000
--- a/src/Artemis.Core/Models/Profile/Keyframe.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-
-namespace Artemis.Core.Models.Profile
-{
- public class Keyframe
- {
- public Layer Layer { get; set; }
- public LayerProperty Property { get; set; }
-
- public TimeSpan Position { get; set; }
- public object Value { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs
index b1113a996..019148c7e 100644
--- a/src/Artemis.Core/Models/Profile/Layer.cs
+++ b/src/Artemis.Core/Models/Profile/Layer.cs
@@ -2,7 +2,9 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
+using Artemis.Core.Exceptions;
using Artemis.Core.Extensions;
+using Artemis.Core.Models.Profile.LayerProperties;
using Artemis.Core.Models.Profile.LayerShapes;
using Artemis.Core.Models.Surface;
using Artemis.Core.Plugins.LayerBrush;
@@ -14,7 +16,7 @@ namespace Artemis.Core.Models.Profile
{
public sealed class Layer : ProfileElement
{
- private readonly List _properties;
+ private readonly Dictionary _properties;
private LayerShape _layerShape;
private List _leds;
@@ -28,7 +30,7 @@ namespace Artemis.Core.Models.Profile
Name = name;
_leds = new List();
- _properties = new List();
+ _properties = new Dictionary();
CreateDefaultProperties();
}
@@ -44,7 +46,7 @@ namespace Artemis.Core.Models.Profile
Order = layerEntity.Order;
_leds = new List();
- _properties = new List();
+ _properties = new Dictionary();
// TODO: Load properties from entity instead of creating the defaults
CreateDefaultProperties();
@@ -113,32 +115,32 @@ namespace Artemis.Core.Models.Profile
///
/// A collection of all the properties on this layer
///
- public ReadOnlyCollection Properties => _properties.AsReadOnly();
+ public ReadOnlyCollection Properties => _properties.Values.ToList().AsReadOnly();
///
/// The anchor point property of this layer, also found in
///
- public LayerProperty AnchorPointProperty { get; private set; }
+ public LayerProperty AnchorPointProperty { get; private set; }
///
/// The position of this layer, also found in
///
- public LayerProperty PositionProperty { get; private set; }
+ public LayerProperty PositionProperty { get; private set; }
///
/// The scale property of this layer, also found in
///
- public LayerProperty ScaleProperty { get; private set; }
+ public LayerProperty ScaleProperty { get; private set; }
///
/// The rotation property of this layer, also found in
///
- public LayerProperty RotationProperty { get; private set; }
+ public LayerProperty RotationProperty { get; private set; }
///
/// The opacity property of this layer, also found in
///
- public LayerProperty OpacityProperty { get; private set; }
+ public LayerProperty OpacityProperty { get; private set; }
///
/// The brush that will fill the .
@@ -262,6 +264,62 @@ namespace Artemis.Core.Models.Profile
CalculateRenderProperties();
}
+ #region Properties
+
+ public void AddLayerProperty(LayerProperty layerProperty)
+ {
+ if (_properties.ContainsKey(layerProperty.Id))
+ throw new ArtemisCoreException($"Duplicate property ID detected. Layer already contains a property with ID {layerProperty.Id}.");
+
+ _properties.Add(layerProperty.Id, layerProperty);
+ }
+
+ public void AddLayerProperty(BaseLayerProperty layerProperty)
+ {
+ if (_properties.ContainsKey(layerProperty.Id))
+ throw new ArtemisCoreException($"Duplicate property ID detected. Layer already contains a property with ID {layerProperty.Id}.");
+
+ _properties.Add(layerProperty.Id, layerProperty);
+ }
+
+ ///
+ /// If found, returns the matching the provided ID
+ ///
+ /// The type of the layer property
+ ///
+ ///
+ public LayerProperty GetLayerPropertyById(string id)
+ {
+ if (!_properties.ContainsKey(id))
+ return null;
+
+ var property = _properties[id];
+ if (property.Type != typeof(T))
+ throw new ArtemisCoreException($"Property type mismatch. Expected property {property} to have type {typeof(T)} but it has {property.Type} instead.");
+ return (LayerProperty) _properties[id];
+ }
+
+ private void CreateDefaultProperties()
+ {
+ var transformProperty = new LayerProperty(this, null, "Core.Transform", "Transform", "The default properties collection every layer has, allows you to transform the shape.");
+ AnchorPointProperty = new LayerProperty(this, transformProperty, "Core.AnchorPoint", "Anchor Point", "The point at which the shape is attached to its position.");
+ PositionProperty = new LayerProperty(this, transformProperty, "Core.Position", "Position", "The position of the shape.");
+ ScaleProperty = new LayerProperty(this, transformProperty, "Core.Scale", "Scale", "The scale of the shape.") {InputAffix = "%"};
+ RotationProperty = new LayerProperty(this, transformProperty, "Core.Rotation", "Rotation", "The rotation of the shape in degrees.") {InputAffix = "°"};
+ OpacityProperty = new LayerProperty(this, transformProperty, "Core.Opacity", "Opacity", "The opacity of the shape.") {InputAffix = "%"};
+ transformProperty.Children.Add(AnchorPointProperty);
+ transformProperty.Children.Add(PositionProperty);
+ transformProperty.Children.Add(ScaleProperty);
+ transformProperty.Children.Add(RotationProperty);
+ transformProperty.Children.Add(OpacityProperty);
+
+ AddLayerProperty(transformProperty);
+ foreach (var transformPropertyChild in transformProperty.Children)
+ AddLayerProperty(transformPropertyChild);
+ }
+
+ #endregion
+
internal void CalculateRenderProperties()
{
if (!Leds.Any())
@@ -291,23 +349,6 @@ namespace Artemis.Core.Models.Profile
OnRenderPropertiesUpdated();
}
- private void CreateDefaultProperties()
- {
- var transformProperty = new LayerProperty(this, null, "Transform", "The default properties collection every layer has, allows you to transform the shape.", null);
- AnchorPointProperty = new LayerProperty(this, transformProperty, "Anchor Point", "The point at which the shape is attached to its position.", typeof(SKPoint));
- PositionProperty = new LayerProperty(this, transformProperty, "Position", "The position of the shape.", typeof(SKPoint));
- ScaleProperty = new LayerProperty(this, transformProperty, "Scale", "The scale of the shape.", typeof(SKSize)) { InputAffix = "%" };
- RotationProperty = new LayerProperty(this, transformProperty, "Rotation", "The rotation of the shape in degrees.", typeof(int)) {InputAffix = "°" };
- OpacityProperty = new LayerProperty(this, transformProperty, "Opacity", "The opacity of the shape.", typeof(float)) {InputAffix = "%"};
- transformProperty.Children.Add(AnchorPointProperty);
- transformProperty.Children.Add(PositionProperty);
- transformProperty.Children.Add(ScaleProperty);
- transformProperty.Children.Add(RotationProperty);
- transformProperty.Children.Add(OpacityProperty);
-
- _properties.Add(transformProperty);
- _properties.AddRange(transformProperty.Children);
- }
public override string ToString()
{
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/BaseKeyframe.cs b/src/Artemis.Core/Models/Profile/LayerProperties/BaseKeyframe.cs
new file mode 100644
index 000000000..59639f372
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/BaseKeyframe.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace Artemis.Core.Models.Profile.LayerProperties
+{
+ public class BaseKeyframe
+ {
+ protected BaseKeyframe(Layer layer, BaseLayerProperty property)
+ {
+ Layer = layer;
+ BaseProperty = property;
+ }
+
+ public Layer Layer { get; set; }
+ public TimeSpan Position { get; set; }
+
+ protected BaseLayerProperty BaseProperty { get; }
+ protected object BaseValue { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs
new file mode 100644
index 000000000..b65a6f1a7
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Collections.Generic;
+using Artemis.Core.Exceptions;
+
+namespace Artemis.Core.Models.Profile.LayerProperties
+{
+ public abstract class BaseLayerProperty
+ {
+ private object _baseValue;
+
+ protected BaseLayerProperty(Layer layer, BaseLayerProperty parent, string id, string name, string description, Type type)
+ {
+ Layer = layer;
+ Parent = parent;
+ Id = id;
+ Name = name;
+ Description = description;
+ Type = type;
+
+ Children = new List();
+ BaseKeyframes = new List();
+ }
+
+ ///
+ /// The layer this property applies to
+ ///
+ public Layer Layer { get; }
+
+ ///
+ /// The parent property of this property.
+ ///
+ public BaseLayerProperty Parent { get; }
+
+ ///
+ /// The child properties of this property.
+ /// If the layer has children it cannot contain a value or keyframes.
+ ///
+ public List Children { get; set; }
+
+ ///
+ /// A unique identifier for this property, a layer may not contain two properties with the same ID.
+ ///
+ public string Id { get; set; }
+
+ ///
+ /// The user-friendly name for this property, shown in the UI.
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// The user-friendly description for this property, shown in the UI.
+ ///
+ public string Description { get; set; }
+
+ ///
+ /// An optional input prefix to show before input elements in the UI.
+ ///
+ public string InputPrefix { get; set; }
+
+ ///
+ /// An optional input affix to show behind input elements in the UI.
+ ///
+ public string InputAffix { get; set; }
+
+ ///
+ /// The type of value this layer property contains.
+ ///
+ public Type Type { get; set; }
+
+ protected List BaseKeyframes { get; set; }
+ ///
+ /// A list of keyframes defining different values of the property in time, this list contains the untyped .
+ ///
+ public IReadOnlyCollection UntypedKeyframes => BaseKeyframes.AsReadOnly();
+
+ protected object BaseValue
+ {
+ get => _baseValue;
+ set
+ {
+ if (value != null && value.GetType() != Type)
+ throw new ArtemisCoreException($"Cannot set value of type {value.GetType()} on property {this}, expected type is {Type}.");
+ _baseValue = value;
+ }
+ }
+
+
+ public void ApplyToEntity()
+ {
+ // Big o' TODO
+ }
+
+ public override string ToString()
+ {
+ return $"{nameof(Id)}: {Id}, {nameof(Name)}: {Name}, {nameof(Description)}: {Description}";
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/Keyframe.cs b/src/Artemis.Core/Models/Profile/LayerProperties/Keyframe.cs
new file mode 100644
index 000000000..63af5027b
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/Keyframe.cs
@@ -0,0 +1,18 @@
+namespace Artemis.Core.Models.Profile.LayerProperties
+{
+ ///
+ public class Keyframe : BaseKeyframe
+ {
+ public Keyframe(Layer layer, LayerProperty propertyBase) : base(layer, propertyBase)
+ {
+ }
+
+ public LayerProperty Property => (LayerProperty) BaseProperty;
+
+ public T Value
+ {
+ get => (T) BaseValue;
+ set => BaseValue = value;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs
new file mode 100644
index 000000000..4141deac3
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs
@@ -0,0 +1,49 @@
+using System.Collections.ObjectModel;
+using System.Linq;
+
+namespace Artemis.Core.Models.Profile.LayerProperties
+{
+ public class LayerProperty : BaseLayerProperty
+ {
+ public LayerProperty(Layer layer, BaseLayerProperty parent, string id, string name, string description) : base(layer, parent, id, name, description, typeof(T))
+ {
+ }
+
+ public T Value
+ {
+ get => (T) BaseValue;
+ set => BaseValue = value;
+ }
+
+ ///
+ /// A list of keyframes defining different values of the property in time, this list contains the strongly typed
+ ///
+ public ReadOnlyCollection> Keyframes => BaseKeyframes.Cast>().ToList().AsReadOnly();
+
+ ///
+ /// Adds a keyframe to the property.
+ ///
+ /// The keyframe to remove
+ public void AddKeyframe(Keyframe keyframe)
+ {
+ BaseKeyframes.Add(keyframe);
+ }
+
+ ///
+ /// Removes a keyframe from the property.
+ ///
+ /// The keyframe to remove
+ public void RemoveKeyframe(Keyframe keyframe)
+ {
+ BaseKeyframes.Remove(keyframe);
+ }
+
+ ///
+ /// Removes all keyframes from the property.
+ ///
+ public void ClearKeyframes()
+ {
+ BaseKeyframes.Clear();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/LayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperty.cs
deleted file mode 100644
index a18d78351..000000000
--- a/src/Artemis.Core/Models/Profile/LayerProperty.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Artemis.Core.Exceptions;
-
-namespace Artemis.Core.Models.Profile
-{
- public class LayerProperty
- {
- private object _baseValue;
-
- internal LayerProperty(Layer layer, LayerProperty parent, string name, string description, Type type)
- {
- Layer = layer;
- Parent = parent;
- Name = name;
- Description = description;
- Type = type;
-
- Children = new List();
- Keyframes = new List();
- }
-
- public Layer Layer { get; }
- public LayerProperty Parent { get; }
- public List Children { get; set; }
-
- public string Name { get; set; }
- public string Description { get; set; }
- public string InputPrefix { get; set; }
- public string InputAffix { get; set; }
- public Type Type { get; set; }
-
- public object BaseValue
- {
- get => _baseValue;
- set
- {
- if (value != null && value.GetType() != Type)
- throw new ArtemisCoreException($"Cannot set value of type {value.GetType()} on property {Name}, expected type is {Type}.");
- _baseValue = value;
- }
- }
-
- public List Keyframes { get; set; }
-
- public void ApplyToEntity()
- {
- // Big o' TODO
- }
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj
index 914cd321b..878cf7b41 100644
--- a/src/Artemis.UI/Artemis.UI.csproj
+++ b/src/Artemis.UI/Artemis.UI.csproj
@@ -559,6 +559,9 @@
+
+
+
diff --git a/src/Artemis.UI/Ninject/Factories/IViewModelFactory.cs b/src/Artemis.UI/Ninject/Factories/IViewModelFactory.cs
index b1e9a2d43..7ef5d016b 100644
--- a/src/Artemis.UI/Ninject/Factories/IViewModelFactory.cs
+++ b/src/Artemis.UI/Ninject/Factories/IViewModelFactory.cs
@@ -1,8 +1,10 @@
using Artemis.Core.Models.Profile;
+using Artemis.Core.Models.Profile.LayerProperties;
using Artemis.Core.Models.Surface;
using Artemis.Core.Plugins.Abstract;
using Artemis.UI.Screens.Module;
using Artemis.UI.Screens.Module.ProfileEditor;
+using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties;
using Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem;
using Artemis.UI.Screens.Module.ProfileEditor.Visualization;
using Artemis.UI.Screens.Settings.Tabs.Devices;
@@ -43,4 +45,9 @@ namespace Artemis.UI.Ninject.Factories
{
ProfileLayerViewModel Create(Layer layer);
}
+
+ public interface ILayerPropertyViewModelFactory : IViewModelFactory
+ {
+ LayerPropertyViewModel Create(BaseLayerProperty layerProperty, LayerPropertyViewModel parent);
+ }
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Ninject/UiModule.cs b/src/Artemis.UI/Ninject/UiModule.cs
index 0d7773c65..5d2bbc32d 100644
--- a/src/Artemis.UI/Ninject/UiModule.cs
+++ b/src/Artemis.UI/Ninject/UiModule.cs
@@ -2,6 +2,7 @@
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens;
using Artemis.UI.Screens.Module.ProfileEditor;
+using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput;
using Artemis.UI.Services.Interfaces;
using Artemis.UI.Stylet;
using Artemis.UI.ViewModels.Dialogs;
@@ -57,6 +58,15 @@ namespace Artemis.UI.Ninject
.BindAllBaseClasses();
});
+ // Bind property input VMs
+ Kernel.Bind(x =>
+ {
+ x.FromThisAssembly()
+ .SelectAllClasses()
+ .InheritedFrom()
+ .BindAllBaseClasses();
+ });
+
// Bind all UI services as singletons
Kernel.Bind(x =>
{
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs
index c8d8c98ec..2684abcd5 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs
@@ -3,6 +3,7 @@ using System.Linq;
using System.Windows;
using System.Windows.Input;
using Artemis.Core.Models.Profile;
+using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline;
using Artemis.UI.Services.Interfaces;
@@ -12,10 +13,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
public class LayerPropertiesViewModel : ProfileEditorPanelViewModel
{
private readonly IProfileEditorService _profileEditorService;
+ private readonly ILayerPropertyViewModelFactory _layerPropertyViewModelFactory;
- public LayerPropertiesViewModel(IProfileEditorService profileEditorService)
+ public LayerPropertiesViewModel(IProfileEditorService profileEditorService, ILayerPropertyViewModelFactory layerPropertyViewModelFactory)
{
_profileEditorService = profileEditorService;
+ _layerPropertyViewModelFactory = layerPropertyViewModelFactory;
CurrentTime = TimeSpan.Zero;
PixelsPerSecond = 1;
@@ -75,7 +78,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
// Only create VMs for top-level parents, let parents populate their own children recursively
var propertyViewModels = selectedLayer.Properties
.Where(p => p.Children.Any())
- .Select(p => new LayerPropertyViewModel(p, null))
+ .Select(p => _layerPropertyViewModelFactory.Create(p, null))
.ToList();
PropertyTree.PopulateProperties(propertyViewModels);
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs
index b96bac1fc..9b46aed45 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs
@@ -1,26 +1,46 @@
using System.Collections.Generic;
-using Artemis.Core.Models.Profile;
+using System.Linq;
+using Artemis.Core.Models.Profile.LayerProperties;
+using Artemis.UI.Ninject.Factories;
+using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput;
+using Ninject;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
{
public class LayerPropertyViewModel : PropertyChangedBase
{
- public LayerPropertyViewModel(LayerProperty layerProperty, LayerPropertyViewModel parent)
+ private readonly IKernel _kernel;
+
+ public LayerPropertyViewModel(BaseLayerProperty layerProperty,
+ LayerPropertyViewModel parent,
+ ILayerPropertyViewModelFactory layerPropertyViewModelFactory, IKernel kernel)
{
+ _kernel = kernel;
+
LayerProperty = layerProperty;
Parent = parent;
Children = new List();
foreach (var child in layerProperty.Children)
- Children.Add(new LayerPropertyViewModel(child, this));
+ Children.Add(layerPropertyViewModelFactory.Create(child, this));
}
- public LayerProperty LayerProperty { get; }
+ public BaseLayerProperty LayerProperty { get; }
public LayerPropertyViewModel Parent { get; }
public List Children { get; set; }
public bool IsExpanded { get; set; }
+
+ public PropertyInputViewModel GetPropertyInputViewModel()
+ {
+ var match = _kernel.Get>().FirstOrDefault(p => p.CompatibleTypes.Contains(LayerProperty.Type));
+ if (match == null)
+ return null;
+
+ match.Initialize(this);
+ return match;
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/FloatPropertyInputViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/FloatPropertyInputViewModel.cs
index 256820991..e2a9bbdfa 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/FloatPropertyInputViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/FloatPropertyInputViewModel.cs
@@ -1,16 +1,10 @@
-using Artemis.UI.Exceptions;
+using System;
+using System.Collections.Generic;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput
{
public class FloatPropertyInputViewModel : PropertyInputViewModel
{
- public FloatPropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel) : base(layerPropertyViewModel)
- {
- if (layerPropertyViewModel.LayerProperty.Type != typeof(float))
- {
- throw new ArtemisUIException("This input VM expects a layer property of type float, " +
- $"not the provided type {layerPropertyViewModel.LayerProperty.Type.Name}");
- }
- }
+ public sealed override List CompatibleTypes { get; } = new List {typeof(float)};
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/IntPropertyInputViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/IntPropertyInputViewModel.cs
index 46b58cd47..b1a2df52c 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/IntPropertyInputViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/IntPropertyInputViewModel.cs
@@ -1,16 +1,10 @@
-using Artemis.UI.Exceptions;
+using System;
+using System.Collections.Generic;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput
{
public class IntPropertyInputViewModel : PropertyInputViewModel
{
- public IntPropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel) : base(layerPropertyViewModel)
- {
- if (layerPropertyViewModel.LayerProperty.Type != typeof(int))
- {
- throw new ArtemisUIException("This input VM expects a layer property of type int, " +
- $"not the provided type {layerPropertyViewModel.LayerProperty.Type.Name}");
- }
- }
+ public sealed override List CompatibleTypes { get; } = new List {typeof(int)};
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/PropertyInputViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/PropertyInputViewModel.cs
index 6f8b6babe..1b0ab7268 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/PropertyInputViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/PropertyInputViewModel.cs
@@ -1,14 +1,26 @@
-using Stylet;
+using System;
+using System.Collections.Generic;
+using Artemis.UI.Exceptions;
+using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput
{
public abstract class PropertyInputViewModel : PropertyChangedBase
{
- protected PropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel)
- {
- LayerPropertyViewModel = layerPropertyViewModel;
- }
+ public bool Initialized { get; private set; }
- public LayerPropertyViewModel LayerPropertyViewModel { get; }
+ public abstract List CompatibleTypes { get; }
+ public LayerPropertyViewModel LayerPropertyViewModel { get; private set; }
+
+ public void Initialize(LayerPropertyViewModel layerPropertyViewModel)
+ {
+ if (Initialized)
+ throw new ArtemisUIException("Cannot initialize the same property input VM twice");
+ if (!CompatibleTypes.Contains(layerPropertyViewModel.LayerProperty.Type))
+ throw new ArtemisUIException($"This input VM does not support the provided type {layerPropertyViewModel.LayerProperty.Type.Name}");
+
+ LayerPropertyViewModel = layerPropertyViewModel;
+ Initialized = true;
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKPointPropertyInputViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKPointPropertyInputViewModel.cs
index 7dd58c2f0..189d21481 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKPointPropertyInputViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKPointPropertyInputViewModel.cs
@@ -1,17 +1,11 @@
-using Artemis.UI.Exceptions;
+using System;
+using System.Collections.Generic;
using SkiaSharp;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput
{
public class SKPointPropertyInputViewModel : PropertyInputViewModel
{
- public SKPointPropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel) : base(layerPropertyViewModel)
- {
- if (layerPropertyViewModel.LayerProperty.Type != typeof(SKPoint))
- {
- throw new ArtemisUIException($"This input VM expects a layer property of type {nameof(SKPoint)}, " +
- $"not the provided type {layerPropertyViewModel.LayerProperty.Type.Name}");
- }
- }
+ public sealed override List CompatibleTypes { get; } = new List {typeof(SKPoint)};
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKSizePropertyInputViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKSizePropertyInputViewModel.cs
index 00dcb43da..ae184a64f 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKSizePropertyInputViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyInput/SKSizePropertyInputViewModel.cs
@@ -1,17 +1,11 @@
-using Artemis.UI.Exceptions;
+using System;
+using System.Collections.Generic;
using SkiaSharp;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput
{
public class SKSizePropertyInputViewModel : PropertyInputViewModel
{
- public SKSizePropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel) : base(layerPropertyViewModel)
- {
- if (layerPropertyViewModel.LayerProperty.Type != typeof(SKSize))
- {
- throw new ArtemisUIException($"This input VM expects a layer property of type {nameof(SKSize)}, " +
- $"not the provided type {layerPropertyViewModel.LayerProperty.Type.Name}");
- }
- }
+ public sealed override List CompatibleTypes { get; } = new List {typeof(SKSize)};
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyTreeChildViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyTreeChildViewModel.cs
index 132e9f1e4..99cdebf1e 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyTreeChildViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/PropertyTree/PropertyTreeChildViewModel.cs
@@ -1,5 +1,6 @@
-using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput;
-using SkiaSharp;
+using System.Collections.Generic;
+using System.Linq;
+using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree
{
@@ -10,16 +11,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree
public PropertyTreeChildViewModel(LayerPropertyViewModel layerPropertyViewModel)
{
LayerPropertyViewModel = layerPropertyViewModel;
-
- // TODO: Leverage DI for this and make it less shitty :))
- if (LayerPropertyViewModel.LayerProperty.Type == typeof(SKPoint))
- PropertyInputViewModel = new SKPointPropertyInputViewModel(LayerPropertyViewModel);
- else if (LayerPropertyViewModel.LayerProperty.Type == typeof(SKSize))
- PropertyInputViewModel = new SKSizePropertyInputViewModel(LayerPropertyViewModel);
- else if (LayerPropertyViewModel.LayerProperty.Type == typeof(int))
- PropertyInputViewModel = new IntPropertyInputViewModel(LayerPropertyViewModel);
- else if (LayerPropertyViewModel.LayerProperty.Type == typeof(float))
- PropertyInputViewModel = new FloatPropertyInputViewModel(LayerPropertyViewModel);
+ PropertyInputViewModel = layerPropertyViewModel.GetPropertyInputViewModel();
}
public LayerPropertyViewModel LayerPropertyViewModel { get; }
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 3c6f1574e..821ddddf4 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTrackKeyframeViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTrackKeyframeViewModel.cs
@@ -1,17 +1,18 @@
using System;
using Artemis.Core.Models.Profile;
+using Artemis.Core.Models.Profile.LayerProperties;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{
public class PropertyTrackKeyframeViewModel : PropertyChangedBase
{
- public PropertyTrackKeyframeViewModel(Keyframe keyframe)
+ public PropertyTrackKeyframeViewModel(BaseKeyframe keyframe)
{
Keyframe = keyframe;
}
- public Keyframe Keyframe { get; }
+ public BaseKeyframe Keyframe { get; }
public double X { get; set; }
public string Timestamp { get; set; }
diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTrackViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTrackViewModel.cs
index 0e64f6bc6..b998f1512 100644
--- a/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTrackViewModel.cs
+++ b/src/Artemis.UI/Screens/Module/ProfileEditor/LayerProperties/Timeline/PropertyTrackViewModel.cs
@@ -21,7 +21,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
public void PopulateKeyframes()
{
- foreach (var keyframe in LayerPropertyViewModel.LayerProperty.Keyframes)
+ foreach (var keyframe in LayerPropertyViewModel.LayerProperty.UntypedKeyframes)
{
if (KeyframeViewModels.Any(k => k.Keyframe == keyframe))
continue;