diff --git a/src/Artemis.Core/Models/Profile/Conditions/Abstract/DisplayConditionPart.cs b/src/Artemis.Core/Models/Profile/Conditions/Abstract/DisplayConditionPart.cs
index 72ca6a7c4..f751046d0 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Abstract/DisplayConditionPart.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Abstract/DisplayConditionPart.cs
@@ -61,7 +61,7 @@ namespace Artemis.Core
///
public abstract bool EvaluateObject(object target);
- internal abstract void ApplyToEntity();
+ internal abstract void Save();
internal abstract DisplayConditionPartEntity GetEntity();
#region IDisposable
diff --git a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionGroup.cs b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionGroup.cs
index cc4cc7e49..055a40b0b 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionGroup.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionGroup.cs
@@ -105,14 +105,14 @@ namespace Artemis.Core
};
}
- internal override void ApplyToEntity()
+ internal override void Save()
{
Entity.BooleanOperator = (int) BooleanOperator;
Entity.Children.Clear();
Entity.Children.AddRange(Children.Select(c => c.GetEntity()));
foreach (var child in Children)
- child.ApplyToEntity();
+ child.Save();
}
internal override DisplayConditionPartEntity GetEntity()
diff --git a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionList.cs b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionList.cs
index 155ae3489..5ecbc607c 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionList.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionList.cs
@@ -116,7 +116,7 @@ namespace Artemis.Core
CompiledListAccessor = lambda.Compile();
}
- internal override void ApplyToEntity()
+ internal override void Save()
{
// Target list
if (ListDataModel != null)
@@ -132,7 +132,7 @@ namespace Artemis.Core
Entity.Children.Clear();
Entity.Children.AddRange(Children.Select(c => c.GetEntity()));
foreach (var child in Children)
- child.ApplyToEntity();
+ child.Save();
}
internal override DisplayConditionPartEntity GetEntity()
diff --git a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionListPredicate.cs b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionListPredicate.cs
index 41c5890df..ef93a992b 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionListPredicate.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionListPredicate.cs
@@ -190,22 +190,31 @@ namespace Artemis.Core
return result;
}
- internal override void ApplyToEntity()
+ internal override void Save()
{
Entity.PredicateType = (int) PredicateType;
- Entity.ListDataModelGuid = ListDataModel?.PluginInfo?.Guid;
- Entity.ListPropertyPath = ListPropertyPath;
+ if (ListDataModel != null)
+ {
+ Entity.ListDataModelGuid = ListDataModel.PluginInfo.Guid;
+ Entity.ListPropertyPath = ListPropertyPath;
+ }
Entity.LeftPropertyPath = LeftPropertyPath;
Entity.RightPropertyPath = RightPropertyPath;
Entity.RightStaticValue = JsonConvert.SerializeObject(RightStaticValue);
- Entity.OperatorPluginGuid = Operator?.PluginInfo?.Guid;
- Entity.OperatorType = Operator?.GetType().Name;
+ if (Operator != null)
+ {
+ Entity.OperatorPluginGuid = Operator.PluginInfo.Guid;
+ Entity.OperatorType = Operator.GetType().Name;
+ }
}
- internal void Initialize()
+ private void Initialize()
{
+ ConditionOperatorStore.ConditionOperatorAdded += ConditionOperatorStoreOnConditionOperatorAdded;
+ ConditionOperatorStore.ConditionOperatorRemoved += ConditionOperatorStoreOnConditionOperatorRemoved;
+
// Left side
if (Entity.LeftPropertyPath != null && ListContainsInnerPath(Entity.LeftPropertyPath))
UpdateLeftSide(Entity.LeftPropertyPath);
@@ -222,7 +231,7 @@ namespace Artemis.Core
if (PredicateType == ProfileRightSideType.Dynamic && Entity.RightPropertyPath != null)
{
if (ListContainsInnerPath(Entity.RightPropertyPath))
- UpdateLeftSide(Entity.LeftPropertyPath);
+ UpdateRightSideDynamic(Entity.RightPropertyPath);
}
// Right side static
else if (PredicateType == ProfileRightSideType.Static && Entity.RightStaticValue != null)
@@ -384,5 +393,37 @@ namespace Artemis.Core
Expression.Property
);
}
+
+ #region Event handlers
+
+ private void ConditionOperatorStoreOnConditionOperatorAdded(object sender, ConditionOperatorStoreEvent e)
+ {
+ var conditionOperator = e.Registration.ConditionOperator;
+ if (Entity.OperatorPluginGuid == conditionOperator.PluginInfo.Guid && Entity.OperatorType == conditionOperator.GetType().Name)
+ UpdateOperator(conditionOperator);
+ }
+
+ private void ConditionOperatorStoreOnConditionOperatorRemoved(object sender, ConditionOperatorStoreEvent e)
+ {
+ if (e.Registration.ConditionOperator != Operator)
+ return;
+ Operator = null;
+ CompiledListPredicate = null;
+ }
+
+ #endregion
+
+ #region IDisposable
+
+ ///
+ protected override void Dispose(bool disposing)
+ {
+ ConditionOperatorStore.ConditionOperatorAdded -= ConditionOperatorStoreOnConditionOperatorAdded;
+ ConditionOperatorStore.ConditionOperatorRemoved -= ConditionOperatorStoreOnConditionOperatorRemoved;
+
+ base.Dispose(disposing);
+ }
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionPredicate.cs b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionPredicate.cs
index 53d70de8a..a86f57dc1 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionPredicate.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionPredicate.cs
@@ -232,7 +232,7 @@ namespace Artemis.Core
return $"[Static] {LeftPropertyPath} {Operator.Description} {RightStaticValue}";
}
- internal override void ApplyToEntity()
+ internal override void Save()
{
Entity.PredicateType = (int) PredicateType;
Entity.LeftDataModelGuid = LeftDataModel?.PluginInfo?.Guid;
@@ -250,6 +250,8 @@ namespace Artemis.Core
{
DataModelStore.DataModelAdded += DataModelStoreOnDataModelAdded;
DataModelStore.DataModelRemoved += DataModelStoreOnDataModelRemoved;
+ ConditionOperatorStore.ConditionOperatorAdded += ConditionOperatorStoreOnConditionOperatorAdded;
+ ConditionOperatorStore.ConditionOperatorRemoved += ConditionOperatorStoreOnConditionOperatorRemoved;
// Left side
if (Entity.LeftDataModelGuid != null)
@@ -415,19 +417,6 @@ namespace Artemis.Core
);
}
- private Expression CreateListAccessor(DataModel dataModel, string path, ParameterExpression listParameter)
- {
- var listType = dataModel.GetListTypeInPath(path);
- if (listType == null)
- throw new ArtemisCoreException($"Cannot create a list accessor at path {path} because the path does not contain a list");
-
- path = dataModel.GetListInnerPath(path);
- return path.Split('.').Aggregate(
- Expression.Convert(listParameter, listType), // Cast to the appropriate type
- Expression.Property
- );
- }
-
#region Event handlers
private void DataModelStoreOnDataModelAdded(object sender, DataModelStoreEvent e)
@@ -454,6 +443,23 @@ namespace Artemis.Core
}
}
+ private void ConditionOperatorStoreOnConditionOperatorAdded(object sender, ConditionOperatorStoreEvent e)
+ {
+ var conditionOperator = e.Registration.ConditionOperator;
+ if (Entity.OperatorPluginGuid == conditionOperator.PluginInfo.Guid && Entity.OperatorType == conditionOperator.GetType().Name)
+ UpdateOperator(conditionOperator);
+ }
+
+ private void ConditionOperatorStoreOnConditionOperatorRemoved(object sender, ConditionOperatorStoreEvent e)
+ {
+ if (e.Registration.ConditionOperator != Operator)
+ return;
+
+ Operator = null;
+ CompiledStaticPredicate = null;
+ CompiledDynamicPredicate = null;
+ }
+
#endregion
///
@@ -461,6 +467,8 @@ namespace Artemis.Core
{
DataModelStore.DataModelAdded -= DataModelStoreOnDataModelAdded;
DataModelStore.DataModelRemoved -= DataModelStoreOnDataModelRemoved;
+ ConditionOperatorStore.ConditionOperatorAdded -= ConditionOperatorStoreOnConditionOperatorAdded;
+ ConditionOperatorStore.ConditionOperatorRemoved -= ConditionOperatorStoreOnConditionOperatorRemoved;
base.Dispose(disposing);
}
diff --git a/src/Artemis.Core/Models/Profile/Folder.cs b/src/Artemis.Core/Models/Profile/Folder.cs
index 1436f7bcf..4491b8143 100644
--- a/src/Artemis.Core/Models/Profile/Folder.cs
+++ b/src/Artemis.Core/Models/Profile/Folder.cs
@@ -8,24 +8,35 @@ using SkiaSharp;
namespace Artemis.Core
{
+ ///
+ /// Represents a folder in a
+ ///
public sealed class Folder : RenderProfileElement
{
private SKBitmap _folderBitmap;
- public Folder(Profile profile, ProfileElement parent, string name)
+ ///
+ /// Creates a new instance of the class and adds itself to the child collection of the provided
+ ///
+ ///
+ /// The parent of the folder
+ /// The name of the folder
+ public Folder(ProfileElement parent, string name)
{
FolderEntity = new FolderEntity();
EntityId = Guid.NewGuid();
- Profile = profile;
- Parent = parent;
+ Parent = parent ?? throw new ArgumentNullException(nameof(parent));
+ Profile = Parent.Profile;
Name = name;
Enabled = true;
DisplayContinuously = true;
_layerEffects = new List();
_expandedPropertyGroups = new List();
+
ApplyRenderElementDefaults();
+ Parent.AddChild(this);
}
internal Folder(Profile profile, ProfileElement parent, FolderEntity folderEntity)
@@ -182,22 +193,7 @@ namespace Artemis.Core
canvas.Restore();
}
-
- ///
- /// Adds a new folder to the bottom of this folder
- ///
- ///
- ///
- public Folder AddFolder(string name)
- {
- if (_disposed)
- throw new ObjectDisposedException("Folder");
-
- var folder = new Folder(Profile, this, name) {Order = Children.LastOrDefault()?.Order ?? 1};
- AddChild(folder);
- return folder;
- }
-
+
///
public override void AddChild(ProfileElement child, int? order = null)
{
@@ -296,7 +292,7 @@ namespace Artemis.Core
// Conditions
RenderElementEntity.RootDisplayCondition = DisplayConditionGroup?.Entity;
- DisplayConditionGroup?.ApplyToEntity();
+ DisplayConditionGroup?.Save();
SaveRenderElement();
}
diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs
index b1d411e9c..fc8dbb7c6 100644
--- a/src/Artemis.Core/Models/Profile/Layer.cs
+++ b/src/Artemis.Core/Models/Profile/Layer.cs
@@ -11,8 +11,7 @@ using SkiaSharp;
namespace Artemis.Core
{
///
- /// Represents a layer on a profile. To create new layers use the by injecting
- /// into your code
+ /// Represents a layer in a
///
public sealed class Layer : RenderProfileElement
{
@@ -23,13 +22,19 @@ namespace Artemis.Core
private List _leds;
private LayerTransformProperties _transform;
- internal Layer(Profile profile, ProfileElement parent, string name)
+ ///
+ /// Creates a new instance of the class and adds itself to the child collection of the provided
+ ///
+ ///
+ /// The parent of the layer
+ /// The name of the layer
+ public Layer(ProfileElement parent, string name)
{
LayerEntity = new LayerEntity();
EntityId = Guid.NewGuid();
- Profile = profile;
- Parent = parent;
+ Parent = parent ?? throw new ArgumentNullException(nameof(parent));
+ Profile = Parent.Profile;
Name = name;
Enabled = true;
DisplayContinuously = true;
@@ -40,10 +45,10 @@ namespace Artemis.Core
_leds = new List();
_expandedPropertyGroups = new List();
- InitializeDefaultGroups();
-
- parent.AddChild(this);
+ Initialize();
ApplyRenderElementDefaults();
+
+ Parent.AddChild(this);
}
internal Layer(Profile profile, ProfileElement parent, LayerEntity layerEntity)
@@ -58,8 +63,7 @@ namespace Artemis.Core
_leds = new List();
_expandedPropertyGroups = new List();
- InitializeDefaultGroups();
-
+ Initialize();
Load();
}
@@ -114,6 +118,8 @@ namespace Artemis.Core
return $"[Layer] {nameof(Name)}: {Name}, {nameof(Order)}: {Order}";
}
+ #region IDisposable
+
///
protected override void Dispose(bool disposing)
{
@@ -133,8 +139,13 @@ namespace Artemis.Core
_transform?.Dispose();
}
- private void InitializeDefaultGroups()
+ #endregion
+
+ private void Initialize()
{
+ LayerBrushStore.LayerBrushAdded += LayerBrushStoreOnLayerBrushAdded;
+ LayerBrushStore.LayerBrushRemoved += LayerBrushStoreOnLayerBrushRemoved;
+
// Layers have two hardcoded property groups, instantiate them
General.Initialize(this, "General.", Constants.CorePluginInfo);
Transform.Initialize(this, "Transform.", Constants.CorePluginInfo);
@@ -191,7 +202,7 @@ namespace Artemis.Core
// Conditions
RenderElementEntity.RootDisplayCondition = DisplayConditionGroup?.Entity;
- DisplayConditionGroup?.ApplyToEntity();
+ DisplayConditionGroup?.Save();
SaveRenderElement();
}
@@ -711,6 +722,27 @@ namespace Artemis.Core
#endregion
+ #region Event handlers
+
+ private void LayerBrushStoreOnLayerBrushRemoved(object sender, LayerBrushStoreEvent e)
+ {
+ if (LayerBrush.Descriptor == e.Registration.LayerBrushDescriptor)
+ DeactivateLayerBrush();
+ }
+
+ private void LayerBrushStoreOnLayerBrushAdded(object sender, LayerBrushStoreEvent e)
+ {
+ if (LayerBrush != null)
+ return;
+
+ var current = General.BrushReference.CurrentValue;
+ if (e.Registration.Plugin.PluginInfo.Guid == current.BrushPluginGuid &&
+ e.Registration.LayerBrushDescriptor.LayerBrushType.Name == current.BrushType)
+ ActivateLayerBrush();
+ }
+
+ #endregion
+
#region Events
public event EventHandler RenderPropertiesUpdated;
diff --git a/src/Artemis.Core/Models/Profile/Profile.cs b/src/Artemis.Core/Models/Profile/Profile.cs
index 10806d755..583c10119 100644
--- a/src/Artemis.Core/Models/Profile/Profile.cs
+++ b/src/Artemis.Core/Models/Profile/Profile.cs
@@ -16,17 +16,19 @@ namespace Artemis.Core
ProfileEntity = new ProfileEntity();
EntityId = Guid.NewGuid();
+ Profile = this;
Module = module;
Name = name;
UndoStack = new Stack();
RedoStack = new Stack();
- AddChild(new Folder(this, this, "Root folder"));
+ var _ = new Folder(this, "Root folder");
Save();
}
internal Profile(ProfileModule module, ProfileEntity profileEntity)
{
+ Profile = this;
ProfileEntity = profileEntity;
EntityId = profileEntity.Id;
@@ -103,7 +105,9 @@ namespace Artemis.Core
// Populate the profile starting at the root, the rest is populated recursively
var rootFolder = ProfileEntity.Folders.FirstOrDefault(f => f.ParentId == EntityId);
if (rootFolder == null)
- AddChild(new Folder(this, this, "Root folder"));
+ {
+ var _ = new Folder(this, "Root folder");
+ }
else
AddChild(new Folder(this, this, rootFolder));
}
diff --git a/src/Artemis.Core/Models/Profile/ProfileElement.cs b/src/Artemis.Core/Models/Profile/ProfileElement.cs
index 0a2ee39aa..c91bcd2fe 100644
--- a/src/Artemis.Core/Models/Profile/ProfileElement.cs
+++ b/src/Artemis.Core/Models/Profile/ProfileElement.cs
@@ -110,9 +110,12 @@ namespace Artemis.Core
{
if (_disposed)
throw new ObjectDisposedException(GetType().Name);
-
+
lock (ChildrenList)
{
+ if (ChildrenList.Contains(child))
+ return;
+
// Add to the end of the list
if (order == null)
{
diff --git a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs
index 81fd839a1..20c938211 100644
--- a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs
+++ b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Artemis.Core.LayerEffects;
+using Artemis.Core.LayerEffects.Placeholder;
using Artemis.Core.Properties;
using Artemis.Storage.Entities.Profile;
using Artemis.Storage.Entities.Profile.Abstract;
@@ -49,7 +50,7 @@ namespace Artemis.Core
{
Id = layerEffect.EntityId,
PluginGuid = layerEffect.PluginInfo.Guid,
- EffectType = layerEffect.GetType().Name,
+ EffectType = layerEffect.GetEffectTypeName(),
Name = layerEffect.Name,
Enabled = layerEffect.Enabled,
HasBeenRenamed = layerEffect.HasBeenRenamed,
@@ -268,11 +269,29 @@ namespace Artemis.Core
{
foreach (var layerEffectEntity in RenderElementEntity.LayerEffects)
{
- if (_layerEffects.Any(e => e.EntityId == layerEffectEntity.Id))
+ // If there is a non-placeholder existing effect, skip this entity
+ var existing = _layerEffects.FirstOrDefault(e => e.EntityId == layerEffectEntity.Id);
+ if (existing != null && !existing.Descriptor.IsPlaceHolder)
continue;
var descriptor = LayerEffectStore.Get(layerEffectEntity.PluginGuid, layerEffectEntity.EffectType)?.LayerEffectDescriptor;
- descriptor?.CreateInstance(this, layerEffectEntity);
+ if (descriptor != null)
+ {
+ // If a descriptor is found but there is an existing placeholder, remove the placeholder
+ if (existing != null)
+ {
+ _layerEffects.Remove(existing);
+ existing.Dispose();
+ }
+ // Create an instance with the descriptor
+ descriptor.CreateInstance(this, layerEffectEntity);
+ }
+ else if (existing == null)
+ {
+ // If no descriptor was found and there was no existing placeholder, create a placeholder
+ descriptor = PlaceholderLayerEffectDescriptor.Create();
+ descriptor.CreateInstance(this, layerEffectEntity);
+ }
}
}
@@ -297,9 +316,10 @@ namespace Artemis.Core
throw new NotImplementedException();
}
- private void LayerEffectStoreOnLayerEffectAdded(object? sender, LayerEffectStoreEvent e)
+ private void LayerEffectStoreOnLayerEffectAdded(object sender, LayerEffectStoreEvent e)
{
- ActivateEffects();
+ if (RenderElementEntity.LayerEffects.Any(ef => ef.PluginGuid == e.Registration.Plugin.PluginInfo.Guid))
+ ActivateEffects();
}
#endregion
diff --git a/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs b/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs
index f928cbab8..0607a7f24 100644
--- a/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs
+++ b/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs
@@ -148,5 +148,7 @@ namespace Artemis.Core.LayerEffects
// Not only is this needed to initialize properties on the layer effects, it also prevents implementing anything
// but LayerEffect outside the core
internal abstract void Initialize();
+
+ internal virtual string GetEffectTypeName() => GetType().Name;
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs b/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs
index 47d95d396..808869b6f 100644
--- a/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs
+++ b/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs
@@ -1,6 +1,5 @@
using System;
using System.Linq;
-using Artemis.Core.LayerBrushes;
using Artemis.Storage.Entities.Profile;
using Ninject;
@@ -51,6 +50,11 @@ namespace Artemis.Core.LayerEffects
///
internal IKernel Kernel { get; set; }
+ ///
+ /// Gets a boolean indicating if this descriptor is a placeholder for a missing plugin
+ ///
+ public bool IsPlaceHolder { get; internal set; }
+
///
/// Creates an instance of the described effect and applies it to the render element
///
@@ -60,6 +64,12 @@ namespace Artemis.Core.LayerEffects
if (renderElement.LayerEffects.Any(e => e.EntityId == entity.Id))
return;
+ if (IsPlaceHolder)
+ {
+ CreatePlaceHolderInstance(renderElement, entity);
+ return;
+ }
+
var effect = (BaseLayerEffect) Kernel.Get(LayerEffectType);
effect.ProfileElement = renderElement;
effect.EntityId = entity.Id;
@@ -73,5 +83,11 @@ namespace Artemis.Core.LayerEffects
renderElement.ActivateLayerEffect(effect);
}
+
+ private void CreatePlaceHolderInstance(RenderProfileElement renderElement, LayerEffectEntity entity)
+ {
+ var effect = new PlaceholderLayerEffect(entity) {ProfileElement = renderElement, Descriptor = this};
+ renderElement.ActivateLayerEffect(effect);
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/LayerEffects/Placeholder/PlaceholderLayerEffect.cs b/src/Artemis.Core/Plugins/LayerEffects/Placeholder/PlaceholderLayerEffect.cs
new file mode 100644
index 000000000..067417d0d
--- /dev/null
+++ b/src/Artemis.Core/Plugins/LayerEffects/Placeholder/PlaceholderLayerEffect.cs
@@ -0,0 +1,58 @@
+using Artemis.Storage.Entities.Profile;
+using SkiaSharp;
+
+namespace Artemis.Core.LayerEffects
+{
+ ///
+ /// Represents a layer effect that could not be loaded due to a missing plugin
+ ///
+ public class PlaceholderLayerEffect : BaseLayerEffect
+ {
+ internal PlaceholderLayerEffect(LayerEffectEntity originalEntity)
+ {
+ OriginalEntity = originalEntity;
+
+ EntityId = OriginalEntity.Id;
+ Order = OriginalEntity.Order;
+ Name = OriginalEntity.Name;
+ Enabled = OriginalEntity.Enabled;
+ HasBeenRenamed = OriginalEntity.HasBeenRenamed;
+ }
+
+ internal LayerEffectEntity OriginalEntity { get; }
+
+ ///
+ public override void EnableLayerEffect()
+ {
+ }
+
+ ///
+ public override void DisableLayerEffect()
+ {
+ }
+
+ ///
+ public override void Update(double deltaTime)
+ {
+ }
+
+ ///
+ public override void PreProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath renderBounds, SKPaint paint)
+ {
+ }
+
+ ///
+ public override void PostProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath renderBounds, SKPaint paint)
+ {
+ }
+
+ internal override string GetEffectTypeName()
+ {
+ return OriginalEntity.EffectType;
+ }
+
+ internal override void Initialize()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/LayerEffects/Placeholder/PlaceholderLayerEffectDescriptor.cs b/src/Artemis.Core/Plugins/LayerEffects/Placeholder/PlaceholderLayerEffectDescriptor.cs
new file mode 100644
index 000000000..b34583a0f
--- /dev/null
+++ b/src/Artemis.Core/Plugins/LayerEffects/Placeholder/PlaceholderLayerEffectDescriptor.cs
@@ -0,0 +1,11 @@
+namespace Artemis.Core.LayerEffects.Placeholder
+{
+ internal static class PlaceholderLayerEffectDescriptor
+ {
+ public static LayerEffectDescriptor Create()
+ {
+ var descriptor = new LayerEffectDescriptor("Missing effect", "This effect could not be loaded", "FileQuestion", null, null) {IsPlaceHolder = true};
+ return descriptor;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Stores/LayerBrushStore.cs b/src/Artemis.Core/Stores/LayerBrushStore.cs
index 75af208b0..9dd77dc9b 100644
--- a/src/Artemis.Core/Stores/LayerBrushStore.cs
+++ b/src/Artemis.Core/Stores/LayerBrushStore.cs
@@ -51,7 +51,8 @@ namespace Artemis.Core
{
lock (Registrations)
{
- return Registrations.FirstOrDefault(d => d.Plugin.PluginInfo.Guid == pluginGuid && d.LayerBrushDescriptor.LayerBrushType.Name == typeName);
+ return Registrations.FirstOrDefault(d => d.Plugin.PluginInfo.Guid == pluginGuid &&
+ d.LayerBrushDescriptor.LayerBrushType.Name == typeName);
}
}
diff --git a/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs b/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs
index 92df0c90c..b4185660e 100644
--- a/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs
+++ b/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs
@@ -10,7 +10,7 @@ namespace Artemis.UI.Shared.Services
{
Profile SelectedProfile { get; }
RenderProfileElement SelectedProfileElement { get; }
- BaseLayerProperty SelectedDataBinding { get; }
+ ILayerProperty SelectedDataBinding { get; }
TimeSpan CurrentTime { get; set; }
int PixelsPerSecond { get; set; }
IReadOnlyList RegisteredPropertyEditors { get; }
@@ -19,7 +19,7 @@ namespace Artemis.UI.Shared.Services
void UpdateSelectedProfile();
void ChangeSelectedProfileElement(RenderProfileElement profileElement);
void UpdateSelectedProfileElement();
- void ChangeSelectedDataBinding(BaseLayerProperty layerProperty);
+ void ChangeSelectedDataBinding(ILayerProperty layerProperty);
void UpdateProfilePreview();
bool UndoUpdateProfile();
bool RedoUpdateProfile();
@@ -88,5 +88,10 @@ namespace Artemis.UI.Shared.Services
/// A keyframe to exclude during keyframe snapping
///
TimeSpan SnapToTimeline(TimeSpan time, TimeSpan tolerance, bool snapToSegments, bool snapToCurrentTime, bool snapToKeyframes, BaseLayerPropertyKeyframe excludedKeyframe = null);
+
+ ///
+ /// If a matching registration is found, creates a new supporting
+ ///
+ PropertyInputViewModel CreatePropertyInputViewModel(LayerProperty layerProperty);
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Services/ProfileEditorService.cs b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs
index ac437396b..bb651f9bd 100644
--- a/src/Artemis.UI.Shared/Services/ProfileEditorService.cs
+++ b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs
@@ -5,6 +5,7 @@ using Artemis.Core;
using Artemis.Core.Modules;
using Artemis.Core.Services;
using Ninject;
+using Ninject.Parameters;
using Serilog;
using Stylet;
@@ -269,6 +270,16 @@ namespace Artemis.UI.Shared.Services
return time;
}
+ public PropertyInputViewModel CreatePropertyInputViewModel(LayerProperty layerProperty)
+ {
+ var registration = RegisteredPropertyEditors.FirstOrDefault(r => r.SupportedType == typeof(T));
+ if (registration == null)
+ return null;
+
+ var parameter = new ConstructorArgument("layerProperty", layerProperty);
+ return (PropertyInputViewModel) Kernel.Get(registration.ViewModelType, parameter);
+ }
+
public ProfileModule GetCurrentModule()
{
return SelectedProfile?.Module;
diff --git a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
index 68df7dd44..04c3cecef 100644
--- a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
+++ b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
@@ -1,13 +1,10 @@
-using System.Reflection;
-using Artemis.Core;
+using Artemis.Core;
using Artemis.Core.Modules;
using Artemis.UI.Screens.Modules;
using Artemis.UI.Screens.Modules.Tabs;
using Artemis.UI.Screens.ProfileEditor;
using Artemis.UI.Screens.ProfileEditor.DisplayConditions;
-using Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract;
using Artemis.UI.Screens.ProfileEditor.LayerProperties;
-using Artemis.UI.Screens.ProfileEditor.LayerProperties.Abstract;
using Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings;
using Artemis.UI.Screens.ProfileEditor.LayerProperties.LayerEffects;
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline;
@@ -19,7 +16,6 @@ using Artemis.UI.Screens.Settings.Debug;
using Artemis.UI.Screens.Settings.Tabs.Devices;
using Artemis.UI.Screens.Settings.Tabs.Plugins;
using Stylet;
-using Module = Artemis.Core.Modules.Module;
namespace Artemis.UI.Ninject.Factories
{
@@ -46,15 +42,10 @@ namespace Artemis.UI.Ninject.Factories
DeviceDebugViewModel Create(ArtemisDevice device);
}
- public interface IFolderVmFactory : IVmFactory
+ public interface IProfileTreeVmFactory : IVmFactory
{
- FolderViewModel Create(ProfileElement folder);
- FolderViewModel Create(TreeItemViewModel parent, ProfileElement folder);
- }
-
- public interface ILayerVmFactory : IVmFactory
- {
- LayerViewModel Create(TreeItemViewModel parent, ProfileElement folder);
+ FolderViewModel FolderViewModel(ProfileElement folder);
+ LayerViewModel LayerViewModel(ProfileElement layer);
}
public interface IProfileLayerVmFactory : IVmFactory
@@ -72,10 +63,10 @@ namespace Artemis.UI.Ninject.Factories
public interface IDisplayConditionsVmFactory : IVmFactory
{
- DisplayConditionGroupViewModel DisplayConditionGroupViewModel(DisplayConditionGroup displayConditionGroup, DisplayConditionViewModel parent, bool isListGroup);
- DisplayConditionListViewModel DisplayConditionListViewModel(DisplayConditionList displayConditionList, DisplayConditionViewModel parent);
- DisplayConditionPredicateViewModel DisplayConditionPredicateViewModel(DisplayConditionPredicate displayConditionPredicate, DisplayConditionViewModel parent);
- DisplayConditionListPredicateViewModel DisplayConditionListPredicateViewModel(DisplayConditionListPredicate displayConditionListPredicate, DisplayConditionViewModel parent);
+ DisplayConditionGroupViewModel DisplayConditionGroupViewModel(DisplayConditionGroup displayConditionGroup, bool isListGroup);
+ DisplayConditionListViewModel DisplayConditionListViewModel(DisplayConditionList displayConditionList);
+ DisplayConditionPredicateViewModel DisplayConditionPredicateViewModel(DisplayConditionPredicate displayConditionPredicate);
+ DisplayConditionListPredicateViewModel DisplayConditionListPredicateViewModel(DisplayConditionListPredicate displayConditionListPredicate);
}
public interface IDataBindingsVmFactory : IVmFactory
@@ -87,11 +78,13 @@ namespace Artemis.UI.Ninject.Factories
public interface ILayerPropertyVmFactory : IVmFactory
{
+ LayerPropertyViewModel LayerPropertyViewModel(ILayerProperty layerProperty);
+ LayerPropertyGroupViewModel LayerPropertyGroupViewModel(LayerPropertyGroup layerPropertyGroup);
+ LayerPropertyTreeViewModel LayerPropertyGroupViewModel(LayerProperty layerProperty);
+ LayerPropertyGroupTreeViewModel LayerPropertyGroupTreeViewModel(LayerPropertyGroupViewModel layerPropertyGroupViewModel);
LayerPropertyGroupViewModel LayerPropertyGroupViewModel(LayerPropertyGroup layerPropertyGroup, PropertyGroupDescriptionAttribute propertyGroupDescription);
TreeViewModel TreeViewModel(LayerPropertiesViewModel layerPropertiesViewModel, BindableCollection layerPropertyGroups);
EffectsViewModel EffectsViewModel(LayerPropertiesViewModel layerPropertiesViewModel);
TimelineViewModel TimelineViewModel(LayerPropertiesViewModel layerPropertiesViewModel, BindableCollection layerPropertyGroups);
- TreePropertyGroupViewModel TreePropertyGroupViewModel(LayerPropertyBaseViewModel layerPropertyBaseViewModel);
- TimelinePropertyGroupViewModel TimelinePropertyGroupViewModel(LayerPropertyBaseViewModel layerPropertyBaseViewModel);
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Ninject/UiModule.cs b/src/Artemis.UI/Ninject/UiModule.cs
index 2903c5a48..3ae26f21d 100644
--- a/src/Artemis.UI/Ninject/UiModule.cs
+++ b/src/Artemis.UI/Ninject/UiModule.cs
@@ -53,7 +53,7 @@ namespace Artemis.UI.Ninject
{
x.FromThisAssembly()
.SelectAllClasses()
- .InheritedFrom()
+ .InheritedFrom()
.BindAllBaseClasses();
});
diff --git a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/Abstract/DisplayConditionViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/Abstract/DisplayConditionViewModel.cs
index 743fec551..65565fdb2 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/Abstract/DisplayConditionViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/Abstract/DisplayConditionViewModel.cs
@@ -1,44 +1,23 @@
-using System;
-using Artemis.Core;
+using Artemis.Core;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract
{
- public abstract class DisplayConditionViewModel : PropertyChangedBase, IDisposable
+ public abstract class DisplayConditionViewModel : Conductor.Collection.AllActive
{
- protected DisplayConditionViewModel(DisplayConditionPart model, DisplayConditionViewModel parent)
+ protected DisplayConditionViewModel(DisplayConditionPart model)
{
Model = model;
- Parent = parent;
- Children = new BindableCollection();
}
public DisplayConditionPart Model { get; }
- public DisplayConditionViewModel Parent { get; set; }
- public BindableCollection Children { get; }
-
- public void Dispose()
- {
- foreach (var child in Children)
- child.Dispose();
-
- Dispose(true);
- GC.SuppressFinalize(this);
- }
public abstract void Update();
public virtual void Delete()
{
Model.Parent.RemoveChild(Model);
- Parent.Update();
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- }
+ ((DisplayConditionViewModel) Parent).Update();
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionGroupView.xaml b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionGroupView.xaml
index b0ec8a679..f1a770d08 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionGroupView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionGroupView.xaml
@@ -124,7 +124,7 @@
-
+
diff --git a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionGroupViewModel.cs
index 1f1deae4d..a5caf78dd 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionGroupViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionGroupViewModel.cs
@@ -1,7 +1,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
-using System.Windows;
using Artemis.Core;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract;
@@ -11,21 +10,24 @@ using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
{
- public class DisplayConditionGroupViewModel : DisplayConditionViewModel, IViewAware
+ public class DisplayConditionGroupViewModel : DisplayConditionViewModel
{
private readonly IDisplayConditionsVmFactory _displayConditionsVmFactory;
private readonly IProfileEditorService _profileEditorService;
private bool _isInitialized;
private bool _isRootGroup;
- public DisplayConditionGroupViewModel(DisplayConditionGroup displayConditionGroup, DisplayConditionViewModel parent, bool isListGroup,
- IProfileEditorService profileEditorService, IDisplayConditionsVmFactory displayConditionsVmFactory) : base(displayConditionGroup, parent)
+ public DisplayConditionGroupViewModel(DisplayConditionGroup displayConditionGroup,
+ bool isListGroup,
+ IProfileEditorService profileEditorService,
+ IDisplayConditionsVmFactory displayConditionsVmFactory)
+ : base(displayConditionGroup)
{
IsListGroup = isListGroup;
_profileEditorService = profileEditorService;
_displayConditionsVmFactory = displayConditionsVmFactory;
- Children.CollectionChanged += (sender, args) => NotifyOfPropertyChange(nameof(DisplayBooleanOperator));
+ Items.CollectionChanged += (sender, args) => NotifyOfPropertyChange(nameof(DisplayBooleanOperator));
Execute.PostToUIThread(async () =>
{
@@ -50,16 +52,9 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
set => SetAndNotify(ref _isInitialized, value);
}
- public bool DisplayBooleanOperator => Children.Count > 1;
+ public bool DisplayBooleanOperator => Items.Count > 1;
public string SelectedBooleanOperator => DisplayConditionGroup.BooleanOperator.Humanize();
- public void AttachView(UIElement view)
- {
- View = view;
- }
-
- public UIElement View { get; set; }
-
public void SelectBooleanOperator(string type)
{
var enumValue = Enum.Parse(type);
@@ -105,39 +100,36 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
NotifyOfPropertyChange(nameof(SelectedBooleanOperator));
// Remove VMs of effects no longer applied on the layer
- var toRemove = Children.Where(c => !DisplayConditionGroup.Children.Contains(c.Model)).ToList();
+ var toRemove = Items.Where(c => !DisplayConditionGroup.Children.Contains(c.Model)).ToList();
// Using RemoveRange breaks our lovely animations
foreach (var displayConditionViewModel in toRemove)
- {
- Children.Remove(displayConditionViewModel);
- displayConditionViewModel.Dispose();
- }
+ CloseItem(displayConditionViewModel);
foreach (var childModel in Model.Children)
{
- if (Children.Any(c => c.Model == childModel))
+ if (Items.Any(c => c.Model == childModel))
continue;
switch (childModel)
{
case DisplayConditionGroup displayConditionGroup:
- Children.Add(_displayConditionsVmFactory.DisplayConditionGroupViewModel(displayConditionGroup, this, IsListGroup));
+ ActivateItem(_displayConditionsVmFactory.DisplayConditionGroupViewModel(displayConditionGroup, IsListGroup));
break;
case DisplayConditionList displayConditionListPredicate:
- Children.Add(_displayConditionsVmFactory.DisplayConditionListViewModel(displayConditionListPredicate, this));
+ ActivateItem(_displayConditionsVmFactory.DisplayConditionListViewModel(displayConditionListPredicate));
break;
case DisplayConditionPredicate displayConditionPredicate:
if (!IsListGroup)
- Children.Add(_displayConditionsVmFactory.DisplayConditionPredicateViewModel(displayConditionPredicate, this));
+ ActivateItem(_displayConditionsVmFactory.DisplayConditionPredicateViewModel(displayConditionPredicate));
break;
case DisplayConditionListPredicate displayConditionListPredicate:
if (IsListGroup)
- Children.Add(_displayConditionsVmFactory.DisplayConditionListPredicateViewModel(displayConditionListPredicate, this));
+ ActivateItem(_displayConditionsVmFactory.DisplayConditionListPredicateViewModel(displayConditionListPredicate));
break;
}
}
- foreach (var childViewModel in Children)
+ foreach (var childViewModel in Items)
childViewModel.Update();
}
}
diff --git a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListPredicateViewModel.cs
index 08e7165ec..7d07d3c11 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListPredicateViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListPredicateViewModel.cs
@@ -17,9 +17,9 @@ using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
{
- public class DisplayConditionListPredicateViewModel : DisplayConditionViewModel, IHandle, IHandle
+ public class DisplayConditionListPredicateViewModel : DisplayConditionViewModel, IHandle, IHandle, IDisposable
{
- private readonly IDataModelService _dataModelService;
+ private readonly IConditionOperatorService _conditionOperatorService;
private readonly IDataModelUIService _dataModelUIService;
private readonly IEventAggregator _eventAggregator;
private readonly IProfileEditorService _profileEditorService;
@@ -39,16 +39,15 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
public DisplayConditionListPredicateViewModel(
DisplayConditionListPredicate displayConditionListPredicate,
- DisplayConditionViewModel parent,
IProfileEditorService profileEditorService,
IDataModelUIService dataModelUIService,
- IDataModelService dataModelService,
+ IConditionOperatorService conditionOperatorService,
ISettingsService settingsService,
- IEventAggregator eventAggregator) : base(displayConditionListPredicate, parent)
+ IEventAggregator eventAggregator) : base(displayConditionListPredicate)
{
_profileEditorService = profileEditorService;
_dataModelUIService = dataModelUIService;
- _dataModelService = dataModelService;
+ _conditionOperatorService = conditionOperatorService;
_eventAggregator = eventAggregator;
_updateTimer = new Timer(500);
_supportedInputTypes = new List();
@@ -206,7 +205,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
// Get the supported operators
Operators.Clear();
- Operators.AddRange(_dataModelService.GetConditionOperatorsForType(leftSideType));
+ Operators.AddRange(_conditionOperatorService.GetConditionOperatorsForType(leftSideType));
if (DisplayConditionListPredicate.Operator == null)
DisplayConditionListPredicate.UpdateOperator(Operators.FirstOrDefault(o => o.SupportsType(leftSideType)));
SelectedOperator = DisplayConditionListPredicate.Operator;
@@ -277,12 +276,6 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
_eventAggregator.Subscribe(this);
}
- protected override void Dispose(bool disposing)
- {
- _updateTimer.Stop();
- _updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
- }
-
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
{
if (LeftSideDataModelOpen)
@@ -353,5 +346,11 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
SelectedOperator = displayConditionOperator;
ApplyOperator();
}
+
+ public void Dispose()
+ {
+ _updateTimer.Dispose();
+ _updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListView.xaml b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListView.xaml
index 3ed7ca5d1..634955989 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListView.xaml
@@ -105,7 +105,7 @@
-
+
diff --git a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListViewModel.cs
index a2ab2fb6f..73393f6cb 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListViewModel.cs
@@ -14,7 +14,7 @@ using Humanizer;
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
{
- public class DisplayConditionListViewModel : DisplayConditionViewModel
+ public class DisplayConditionListViewModel : DisplayConditionViewModel, IDisposable
{
private readonly IDataModelUIService _dataModelUIService;
private readonly IDisplayConditionsVmFactory _displayConditionsVmFactory;
@@ -30,7 +30,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
IProfileEditorService profileEditorService,
IDataModelUIService dataModelUIService,
IDisplayConditionsVmFactory displayConditionsVmFactory,
- ISettingsService settingsService) : base(displayConditionList, parent)
+ ISettingsService settingsService) : base(displayConditionList)
{
_profileEditorService = profileEditorService;
_dataModelUIService = dataModelUIService;
@@ -152,36 +152,27 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
TargetDataModel.ApplyTypeFilter(true, typeof(IList));
// Remove VMs of effects no longer applied on the layer
- var toRemove = Children.Where(c => !DisplayConditionList.Children.Contains(c.Model)).ToList();
+ var toRemove = Items.Where(c => !DisplayConditionList.Children.Contains(c.Model)).ToList();
// Using RemoveRange breaks our lovely animations
foreach (var displayConditionViewModel in toRemove)
- {
- Children.Remove(displayConditionViewModel);
- displayConditionViewModel.Dispose();
- }
+ CloseItem(displayConditionViewModel);
foreach (var childModel in Model.Children)
{
- if (Children.Any(c => c.Model == childModel))
+ if (Items.Any(c => c.Model == childModel))
continue;
if (!(childModel is DisplayConditionGroup displayConditionGroup))
continue;
- var viewModel = _displayConditionsVmFactory.DisplayConditionGroupViewModel(displayConditionGroup, this, true);
+ var viewModel = _displayConditionsVmFactory.DisplayConditionGroupViewModel(displayConditionGroup, true);
viewModel.IsRootGroup = true;
- Children.Add(viewModel);
+ ActivateItem(viewModel);
}
- foreach (var childViewModel in Children)
+ foreach (var childViewModel in Items)
childViewModel.Update();
}
- protected override void Dispose(bool disposing)
- {
- _updateTimer.Stop();
- _updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
- }
-
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
{
if (TargetDataModelOpen)
@@ -205,5 +196,11 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
SelectedListProperty = dataModelListViewModel;
ApplyList();
}
+
+ public void Dispose()
+ {
+ _updateTimer.Dispose();
+ _updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionPredicateViewModel.cs
index a7750ee91..f8b7833bd 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionPredicateViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionPredicateViewModel.cs
@@ -16,9 +16,9 @@ using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
{
- public class DisplayConditionPredicateViewModel : DisplayConditionViewModel, IHandle, IHandle
+ public class DisplayConditionPredicateViewModel : DisplayConditionViewModel, IHandle, IHandle, IDisposable
{
- private readonly IDataModelService _dataModelService;
+ private readonly IConditionOperatorService _conditionOperatorService;
private readonly IDataModelUIService _dataModelUIService;
private readonly IEventAggregator _eventAggregator;
private readonly IProfileEditorService _profileEditorService;
@@ -38,16 +38,15 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
public DisplayConditionPredicateViewModel(
DisplayConditionPredicate displayConditionPredicate,
- DisplayConditionViewModel parent,
IProfileEditorService profileEditorService,
IDataModelUIService dataModelUIService,
- IDataModelService dataModelService,
+ IConditionOperatorService conditionOperatorService,
ISettingsService settingsService,
- IEventAggregator eventAggregator) : base(displayConditionPredicate, parent)
+ IEventAggregator eventAggregator) : base(displayConditionPredicate)
{
_profileEditorService = profileEditorService;
_dataModelUIService = dataModelUIService;
- _dataModelService = dataModelService;
+ _conditionOperatorService = conditionOperatorService;
_eventAggregator = eventAggregator;
_updateTimer = new Timer(500);
_supportedInputTypes = new List();
@@ -208,7 +207,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
// Get the supported operators
Operators.Clear();
- Operators.AddRange(_dataModelService.GetConditionOperatorsForType(leftSideType));
+ Operators.AddRange(_conditionOperatorService.GetConditionOperatorsForType(leftSideType));
if (DisplayConditionPredicate.Operator == null)
DisplayConditionPredicate.UpdateOperator(Operators.FirstOrDefault(o => o.SupportsType(leftSideType)));
SelectedOperator = DisplayConditionPredicate.Operator;
@@ -278,13 +277,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
);
_eventAggregator.Subscribe(this);
}
-
- protected override void Dispose(bool disposing)
- {
- _updateTimer.Stop();
- _updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
- }
-
+
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
{
if (LeftSideDataModelOpen)
@@ -335,5 +328,11 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
SelectedOperator = displayConditionOperator;
ApplyOperator();
}
+
+ public void Dispose()
+ {
+ _updateTimer.Dispose();
+ _updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsView.xaml b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsView.xaml
index 43ca3526b..68c8ef8f9 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsView.xaml
@@ -43,7 +43,7 @@
-
+
diff --git a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsViewModel.cs
index 2931a2907..e2d3a7a04 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsViewModel.cs
@@ -3,17 +3,17 @@ using Artemis.Core;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
+using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
{
- public class DisplayConditionsViewModel : ProfileEditorPanelViewModel
+ public class DisplayConditionsViewModel : Conductor, IProfileEditorPanelViewModel
{
private readonly IDisplayConditionsVmFactory _displayConditionsVmFactory;
private readonly IProfileEditorService _profileEditorService;
private bool _alwaysFinishTimeline;
private bool _displayContinuously;
private RenderProfileElement _renderProfileElement;
- private DisplayConditionGroupViewModel _rootGroup;
private int _transitionerIndex;
public DisplayConditionsViewModel(IProfileEditorService profileEditorService, IDisplayConditionsVmFactory displayConditionsVmFactory)
@@ -28,11 +28,6 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
set => SetAndNotify(ref _transitionerIndex, value);
}
- public DisplayConditionGroupViewModel RootGroup
- {
- get => _rootGroup;
- set => SetAndNotify(ref _rootGroup, value);
- }
public RenderProfileElement RenderProfileElement
{
@@ -70,9 +65,6 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
protected override void OnDeactivate()
{
_profileEditorService.ProfileElementSelected -= ProfileEditorServiceOnProfileElementSelected;
-
- RootGroup?.Dispose();
- RootGroup = null;
}
private void ProfileEditorServiceOnProfileElementSelected(object sender, RenderProfileElementEventArgs e)
@@ -87,8 +79,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
if (e.RenderProfileElement == null)
{
- RootGroup?.Dispose();
- RootGroup = null;
+ ActiveItem = null;
return;
}
@@ -96,14 +87,13 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
if (e.RenderProfileElement.DisplayConditionGroup == null)
e.RenderProfileElement.DisplayConditionGroup = new DisplayConditionGroup(null);
- RootGroup?.Dispose();
- RootGroup = _displayConditionsVmFactory.DisplayConditionGroupViewModel(e.RenderProfileElement.DisplayConditionGroup, null, false);
- RootGroup.IsRootGroup = true;
- RootGroup.Update();
+ ActiveItem = _displayConditionsVmFactory.DisplayConditionGroupViewModel(e.RenderProfileElement.DisplayConditionGroup, false);
+ ActiveItem.IsRootGroup = true;
+ ActiveItem.Update();
// Only show the intro to conditions once, and only if the layer has no conditions
if (TransitionerIndex != 1)
- TransitionerIndex = RootGroup.Children.Any() ? 1 : 0;
+ TransitionerIndex = ActiveItem.Items.Any() ? 1 : 0;
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorPanelViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/IProfileEditorPanelViewModel.cs
similarity index 55%
rename from src/Artemis.UI/Screens/ProfileEditor/ProfileEditorPanelViewModel.cs
rename to src/Artemis.UI/Screens/ProfileEditor/IProfileEditorPanelViewModel.cs
index e2829cefe..cf5601e85 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorPanelViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/IProfileEditorPanelViewModel.cs
@@ -2,7 +2,7 @@
namespace Artemis.UI.Screens.ProfileEditor
{
- public class ProfileEditorPanelViewModel : Screen
+ public interface IProfileEditorPanelViewModel : IScreen
{
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Abstract/LayerPropertyBaseViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Abstract/LayerPropertyBaseViewModel.cs
deleted file mode 100644
index 96278e0c3..000000000
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Abstract/LayerPropertyBaseViewModel.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Artemis.Core;
-using Stylet;
-
-namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Abstract
-{
- public abstract class LayerPropertyBaseViewModel : PropertyChangedBase, IDisposable
- {
- private BindableCollection _children;
- private bool _isExpanded;
-
- protected LayerPropertyBaseViewModel()
- {
- Children = new BindableCollection();
- }
-
- public abstract bool IsVisible { get; }
-
- public virtual bool IsExpanded
- {
- get => _isExpanded;
- set => SetAndNotify(ref _isExpanded, value);
- }
-
- public BindableCollection Children
- {
- get => _children;
- set => SetAndNotify(ref _children, value);
- }
-
- public abstract void Dispose();
-
- public abstract List GetKeyframes(bool expandedOnly);
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerEffects/EffectsViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerEffects/EffectsViewModel.cs
index 3423e21d3..199318a63 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerEffects/EffectsViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerEffects/EffectsViewModel.cs
@@ -9,32 +9,22 @@ using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.LayerEffects
{
- public class EffectsViewModel : PropertyChangedBase
+ public class EffectsViewModel : Conductor.Collection.AllActive
{
private readonly IPluginService _pluginService;
private readonly IProfileEditorService _profileEditorService;
- private readonly IRenderElementService _renderElementService;
- private BindableCollection _layerEffectDescriptors;
private LayerEffectDescriptor _selectedLayerEffectDescriptor;
- public EffectsViewModel(LayerPropertiesViewModel layerPropertiesViewModel, IPluginService pluginService, IRenderElementService renderElementService, IProfileEditorService profileEditorService)
+ public EffectsViewModel(LayerPropertiesViewModel layerPropertiesViewModel, IPluginService pluginService, IProfileEditorService profileEditorService)
{
_pluginService = pluginService;
- _renderElementService = renderElementService;
_profileEditorService = profileEditorService;
LayerPropertiesViewModel = layerPropertiesViewModel;
- LayerEffectDescriptors = new BindableCollection();
PropertyChanged += HandleSelectedLayerEffectChanged;
}
public LayerPropertiesViewModel LayerPropertiesViewModel { get; }
- public bool HasLayerEffectDescriptors => LayerEffectDescriptors.Any();
-
- public BindableCollection LayerEffectDescriptors
- {
- get => _layerEffectDescriptors;
- set => SetAndNotify(ref _layerEffectDescriptors, value);
- }
+ public bool HasLayerEffectDescriptors => Items.Any();
public LayerEffectDescriptor SelectedLayerEffectDescriptor
{
@@ -46,15 +36,15 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.LayerEffects
{
var layerBrushProviders = _pluginService.GetPluginsOfType();
var descriptors = layerBrushProviders.SelectMany(l => l.LayerEffectDescriptors).ToList();
- LayerEffectDescriptors.AddRange(descriptors.Except(LayerEffectDescriptors));
- LayerEffectDescriptors.RemoveRange(LayerEffectDescriptors.Except(descriptors));
+ Items.AddRange(descriptors.Except(Items));
+ Items.RemoveRange(Items.Except(descriptors));
// Sort by display name
var index = 0;
- foreach (var layerEffectDescriptor in LayerEffectDescriptors.OrderBy(d => d.DisplayName).ToList())
+ foreach (var layerEffectDescriptor in Items.OrderBy(d => d.DisplayName).ToList())
{
- if (LayerEffectDescriptors.IndexOf(layerEffectDescriptor) != index)
- LayerEffectDescriptors.Move(LayerEffectDescriptors.IndexOf(layerEffectDescriptor), index);
+ if (Items.IndexOf(layerEffectDescriptor) != index)
+ ((BindableCollection) Items).Move(Items.IndexOf(layerEffectDescriptor), index);
index++;
}
@@ -78,7 +68,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.LayerEffects
Execute.PostToUIThread(async () =>
{
await Task.Delay(500);
- _renderElementService.AddLayerEffect(renderElement, SelectedLayerEffectDescriptor);
+ renderElement.AddLayerEffect(SelectedLayerEffectDescriptor);
_profileEditorService.UpdateSelectedProfileElement();
});
}
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs
index 4aebe4602..68c462ff1 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs
@@ -16,11 +16,10 @@ using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using GongSolutions.Wpf.DragDrop;
using Stylet;
-using static Artemis.UI.Screens.ProfileEditor.LayerProperties.LayerPropertyGroupViewModel.ViewModelType;
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
{
- public class LayerPropertiesViewModel : ProfileEditorPanelViewModel, IDropTarget
+ public class LayerPropertiesViewModel : Conductor.Collection.AllActive, IProfileEditorPanelViewModel, IDropTarget
{
private readonly ILayerPropertyVmFactory _layerPropertyVmFactory;
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyGroupViewModel.cs
index 15cbe89f3..3f87b3479 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyGroupViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyGroupViewModel.cs
@@ -1,58 +1,31 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
using Artemis.Core;
using Artemis.UI.Ninject.Factories;
-using Artemis.UI.Screens.ProfileEditor.LayerProperties.Abstract;
-using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline;
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree;
-using Artemis.UI.Shared.Services;
-using Humanizer;
-using Ninject;
-using Ninject.Parameters;
+using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
{
- public class LayerPropertyGroupViewModel : LayerPropertyBaseViewModel
+ public class LayerPropertyGroupViewModel : PropertyChangedBase, IDisposable
{
private readonly ILayerPropertyVmFactory _layerPropertyVmFactory;
- private ViewModelType _groupType;
- private TimelinePropertyGroupViewModel _timelinePropertyGroupViewModel;
- private TreePropertyGroupViewModel _treePropertyGroupViewModel;
- public LayerPropertyGroupViewModel(LayerPropertyGroup layerPropertyGroup, PropertyGroupDescriptionAttribute propertyGroupDescription,
- IProfileEditorService profileEditorService, ILayerPropertyVmFactory layerPropertyVmFactory)
+ public LayerPropertyGroupViewModel(LayerPropertyGroup layerPropertyGroup, ILayerPropertyVmFactory layerPropertyVmFactory)
{
_layerPropertyVmFactory = layerPropertyVmFactory;
- ProfileEditorService = profileEditorService;
LayerPropertyGroup = layerPropertyGroup;
- PropertyGroupDescription = propertyGroupDescription;
-
- TreePropertyGroupViewModel = _layerPropertyVmFactory.TreePropertyGroupViewModel(this);
- TimelinePropertyGroupViewModel = _layerPropertyVmFactory.TimelinePropertyGroupViewModel(this);
-
- // Generate a fallback name if the description does not contain one
- if (PropertyGroupDescription.Name == null)
- {
- var propertyInfo = LayerPropertyGroup.Parent?.GetType().GetProperties().FirstOrDefault(p => ReferenceEquals(p.GetValue(LayerPropertyGroup.Parent), LayerPropertyGroup));
- if (propertyInfo != null)
- PropertyGroupDescription.Name = propertyInfo.Name.Humanize();
- else
- PropertyGroupDescription.Name = "Unknown group";
- }
-
- LayerPropertyGroup.VisibilityChanged += LayerPropertyGroupOnVisibilityChanged;
+ LayerPropertyGroupTreeViewModel = layerPropertyVmFactory.LayerPropertyGroupTreeViewModel(this);
PopulateChildren();
- DetermineType();
}
- public override bool IsVisible => !LayerPropertyGroup.IsHidden;
- public IProfileEditorService ProfileEditorService { get; }
public LayerPropertyGroup LayerPropertyGroup { get; }
- public PropertyGroupDescriptionAttribute PropertyGroupDescription { get; }
+ public LayerPropertyGroupTreeViewModel LayerPropertyGroupTreeViewModel { get; }
+ public BindableCollection Children { get; set; }
- public override bool IsExpanded
+ public bool IsVisible => !LayerPropertyGroup.IsHidden;
+
+ public bool IsExpanded
{
get => LayerPropertyGroup.ProfileElement.IsPropertyGroupExpanded(LayerPropertyGroup);
set
@@ -62,81 +35,10 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
}
}
- public ViewModelType GroupType
- {
- get => _groupType;
- set => SetAndNotify(ref _groupType, value);
- }
-
- public TreePropertyGroupViewModel TreePropertyGroupViewModel
- {
- get => _treePropertyGroupViewModel;
- set => SetAndNotify(ref _treePropertyGroupViewModel, value);
- }
-
- public TimelinePropertyGroupViewModel TimelinePropertyGroupViewModel
- {
- get => _timelinePropertyGroupViewModel;
- set => SetAndNotify(ref _timelinePropertyGroupViewModel, value);
- }
-
- 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));
-
- return result;
- }
-
- public override void Dispose()
- {
- foreach (var layerPropertyBaseViewModel in Children)
- layerPropertyBaseViewModel.Dispose();
-
- LayerPropertyGroup.VisibilityChanged -= LayerPropertyGroupOnVisibilityChanged;
- TimelinePropertyGroupViewModel.Dispose();
- }
-
- public List GetAllChildren()
- {
- var result = new List();
- foreach (var layerPropertyBaseViewModel in Children)
- {
- result.Add(layerPropertyBaseViewModel);
- if (layerPropertyBaseViewModel is LayerPropertyGroupViewModel layerPropertyGroupViewModel)
- result.AddRange(layerPropertyGroupViewModel.GetAllChildren());
- }
-
- return result;
- }
-
- public void UpdateOrder(int order)
- {
- LayerPropertyGroup.LayerEffect.Order = order;
- NotifyOfPropertyChange(nameof(IsExpanded));
- }
-
- private void DetermineType()
- {
- if (LayerPropertyGroup is LayerGeneralProperties)
- GroupType = ViewModelType.General;
- else if (LayerPropertyGroup is LayerTransformProperties)
- GroupType = ViewModelType.Transform;
- else if (LayerPropertyGroup.Parent == null && LayerPropertyGroup.LayerBrush != null)
- GroupType = ViewModelType.LayerBrushRoot;
- else if (LayerPropertyGroup.Parent == null && LayerPropertyGroup.LayerEffect != null)
- GroupType = ViewModelType.LayerEffectRoot;
- else
- GroupType = ViewModelType.None;
- }
-
private void PopulateChildren()
{
// Get all properties and property groups and create VMs for them
+ // The group has methods for getting this without reflection but then we lose the order of the properties as they are defined on the group
foreach (var propertyInfo in LayerPropertyGroup.GetType().GetProperties())
{
var propertyAttribute = (PropertyDescriptionAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(PropertyDescriptionAttribute));
@@ -144,50 +46,28 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
var value = propertyInfo.GetValue(LayerPropertyGroup);
// Create VMs for properties on the group
- if (propertyAttribute != null && value is BaseLayerProperty baseLayerProperty)
+ if (propertyAttribute != null && value is ILayerProperty layerProperty)
{
- var viewModel = CreateLayerPropertyViewModel(baseLayerProperty, propertyAttribute);
- if (viewModel != null)
- Children.Add(viewModel);
+ var layerPropertyViewModel = _layerPropertyVmFactory.LayerPropertyViewModel(layerProperty);
+ // After creation ensure a supported input VM was found, if not, discard the VM
+ if (!layerPropertyViewModel.LayerPropertyTreeViewModel.HasPropertyInputViewModel)
+ layerPropertyViewModel.Dispose();
+ else
+ Children.Add(layerPropertyViewModel);
}
// Create VMs for child groups on this group, resulting in a nested structure
else if (groupAttribute != null && value is LayerPropertyGroup layerPropertyGroup)
- Children.Add(_layerPropertyVmFactory.LayerPropertyGroupViewModel(layerPropertyGroup, groupAttribute));
+ Children.Add(_layerPropertyVmFactory.LayerPropertyGroupViewModel(layerPropertyGroup));
}
}
- private LayerPropertyBaseViewModel CreateLayerPropertyViewModel(BaseLayerProperty baseLayerProperty, PropertyDescriptionAttribute propertyDescription)
+ public void Dispose()
{
- // 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[]
+ foreach (var child in Children)
{
- 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));
- }
-
- public enum ViewModelType
- {
- General,
- Transform,
- LayerBrushRoot,
- LayerEffectRoot,
- None
+ if (child is IDisposable disposableChild)
+ disposableChild.Dispose();
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs
index 542c0730b..f436b7f0d 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs
@@ -1,141 +1,37 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
using Artemis.Core;
-using Artemis.UI.Exceptions;
-using Artemis.UI.PropertyInput;
-using Artemis.UI.Screens.ProfileEditor.LayerProperties.Abstract;
-using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline;
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree;
-using Artemis.UI.Shared;
-using Artemis.UI.Shared.Services;
-using Humanizer;
using Ninject;
using Ninject.Parameters;
+using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
{
- public class LayerPropertyViewModel : LayerPropertyViewModel
+ public class LayerPropertyViewModel : PropertyChangedBase, IDisposable
{
- private TimelinePropertyViewModel _timelinePropertyViewModel;
- private TreePropertyViewModel _treePropertyViewModel;
-
- public LayerPropertyViewModel(IProfileEditorService profileEditorService, LayerProperty layerProperty) : base(profileEditorService, layerProperty)
+ public LayerPropertyViewModel(ILayerProperty layerProperty, IKernel kernel)
{
LayerProperty = layerProperty;
- TreePropertyViewModel = CreateTreePropertyViewModel();
- TimelinePropertyViewModel = new TimelinePropertyViewModel(this, profileEditorService);
+ var parameter = new ConstructorArgument("layerProperty", LayerProperty);
+ var treeViewModelType = typeof(LayerPropertyTreeViewModel<>).MakeGenericType(layerProperty.GetType().GetGenericArguments());
+ var timelineViewModelType = typeof(LayerPropertyTimelineViewModel<>).MakeGenericType(layerProperty.GetType().GetGenericArguments());
- TreePropertyBaseViewModel = TreePropertyViewModel;
- TimelinePropertyBaseViewModel = TimelinePropertyViewModel;
-
- // Generate a fallback name if the description does not contain one
- if (LayerProperty.PropertyDescription.Name == null)
- {
- var propertyInfo = LayerProperty.Parent?.GetType().GetProperties().FirstOrDefault(p => ReferenceEquals(p.GetValue(LayerProperty.Parent), LayerProperty));
- if (propertyInfo != null)
- LayerProperty.PropertyDescription.Name = propertyInfo.Name.Humanize();
- else
- LayerProperty.PropertyDescription.Name = $"Unknown {typeof(T).Name} property";
- }
-
- LayerProperty.VisibilityChanged += LayerPropertyOnVisibilityChanged;
+ LayerPropertyTreeViewModel = (ILayerPropertyTreeViewModel) kernel.Get(treeViewModelType, parameter);
+ LayerPropertyTimelineViewModel = (ILayerPropertyTimelineViewModel) kernel.Get(timelineViewModelType, parameter);
}
- public override bool IsVisible => !LayerProperty.IsHidden;
+ public ILayerProperty LayerProperty { get; }
+ public ILayerPropertyTreeViewModel LayerPropertyTreeViewModel { get; }
+ public ILayerPropertyTimelineViewModel LayerPropertyTimelineViewModel { get; }
- public LayerProperty LayerProperty { get; }
+ public bool IsVisible { get; set; }
+ public bool IsExpanded { get; set; }
- public TreePropertyViewModel TreePropertyViewModel
+ public void Dispose()
{
- get => _treePropertyViewModel;
- set => SetAndNotify(ref _treePropertyViewModel, value);
- }
-
- public TimelinePropertyViewModel TimelinePropertyViewModel
- {
- get => _timelinePropertyViewModel;
- set => SetAndNotify(ref _timelinePropertyViewModel, value);
- }
-
- public override List GetKeyframes(bool expandedOnly)
- {
- if (LayerProperty.KeyframesEnabled && !LayerProperty.IsHidden)
- return LayerProperty.BaseKeyframes.ToList();
- return new List();
- }
-
- public override void Dispose()
- {
- TreePropertyViewModel.Dispose();
- TimelinePropertyViewModel.Dispose();
-
- LayerProperty.VisibilityChanged -= LayerPropertyOnVisibilityChanged;
- }
-
- public void SetCurrentValue(T value, bool saveChanges)
- {
- LayerProperty.SetCurrentValue(value, ProfileEditorService.CurrentTime);
- if (saveChanges)
- ProfileEditorService.UpdateSelectedProfileElement();
- else
- 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));
- }
- }
-
- public abstract class LayerPropertyViewModel : LayerPropertyBaseViewModel
- {
- private TimelinePropertyViewModel _timelinePropertyBaseViewModel;
- private TreePropertyViewModel _treePropertyBaseViewModel;
-
- protected LayerPropertyViewModel(IProfileEditorService profileEditorService, BaseLayerProperty baseLayerProperty)
- {
- ProfileEditorService = profileEditorService;
- BaseLayerProperty = baseLayerProperty;
- }
-
- public IProfileEditorService ProfileEditorService { get; }
- public BaseLayerProperty BaseLayerProperty { get; }
-
- public TreePropertyViewModel TreePropertyBaseViewModel
- {
- get => _treePropertyBaseViewModel;
- set => SetAndNotify(ref _treePropertyBaseViewModel, value);
- }
-
- public TimelinePropertyViewModel TimelinePropertyBaseViewModel
- {
- get => _timelinePropertyBaseViewModel;
- set => SetAndNotify(ref _timelinePropertyBaseViewModel, value);
+ LayerPropertyTreeViewModel?.Dispose();
+ LayerPropertyTimelineViewModel?.Dispose();
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/Rails/LayerPropertyTimelineViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/Rails/LayerPropertyTimelineViewModel.cs
new file mode 100644
index 000000000..370dc0904
--- /dev/null
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/Rails/LayerPropertyTimelineViewModel.cs
@@ -0,0 +1,26 @@
+using System;
+using Artemis.Core;
+using Stylet;
+
+namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
+{
+ public class LayerPropertyTimelineViewModel : Screen, ILayerPropertyTimelineViewModel
+ {
+ public LayerProperty LayerProperty { get; }
+ public LayerPropertyViewModel LayerPropertyViewModel { get; }
+
+ public LayerPropertyTimelineViewModel(LayerProperty layerProperty, LayerPropertyViewModel layerPropertyViewModel)
+ {
+ LayerProperty = layerProperty;
+ LayerPropertyViewModel = layerPropertyViewModel;
+ }
+
+ public void Dispose()
+ {
+ }
+ }
+
+ public interface ILayerPropertyTimelineViewModel : IScreen, IDisposable
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/Rails/TimelineGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/Rails/TimelineGroupViewModel.cs
new file mode 100644
index 000000000..fb39a056f
--- /dev/null
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/Rails/TimelineGroupViewModel.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Artemis.Core;
+
+namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline.Rails
+{
+ public class TimelineGroupViewModel
+ {
+ public LayerPropertyGroup LayerPropertyGroup { get; }
+
+ public TimelineGroupViewModel(LayerPropertyGroup layerPropertyGroup)
+ {
+ LayerPropertyGroup = layerPropertyGroup;
+ }
+ }
+}
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreePropertyGroupView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/LayerPropertyGroupTreeView.xaml
similarity index 71%
rename from src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreePropertyGroupView.xaml
rename to src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/LayerPropertyGroupTreeView.xaml
index 406333f4d..a33638fbd 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreePropertyGroupView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/LayerPropertyGroupTreeView.xaml
@@ -9,7 +9,7 @@
xmlns:converters="clr-namespace:Artemis.UI.Converters"
xmlns:dd="urn:gong-wpf-dragdrop"
mc:Ignorable="d"
- d:DataContext="{d:DesignInstance local:TreePropertyGroupViewModel}"
+ d:DataContext="{d:DesignInstance local:LayerPropertyGroupTreeViewModel}"
d:DesignHeight="450" d:DesignWidth="800">
@@ -18,8 +18,8 @@
@@ -27,7 +27,7 @@
- General
+ General
@@ -57,14 +57,14 @@
- Transform
+ Transform
@@ -79,23 +79,23 @@
Brush -
@@ -125,7 +125,7 @@
-
-
+
+
-
-
+
+
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreeViewModel.cs
index 15ba072bb..5c84fa57f 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreeViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreeViewModel.cs
@@ -5,11 +5,13 @@ using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
{
- public class TreeViewModel : PropertyChangedBase
+ public class TreeViewModel : Screen
{
public TreeViewModel(LayerPropertiesViewModel layerPropertiesViewModel, BindableCollection layerPropertyGroups)
{
LayerPropertiesViewModel = layerPropertiesViewModel;
+
+ // Not using the Items collection because the list should persist even after this VM gets closed
LayerPropertyGroups = layerPropertyGroups;
}
diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs
index 52d80ed29..4e459d2b8 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs
@@ -17,7 +17,7 @@ using Stylet;
namespace Artemis.UI.Screens.ProfileEditor
{
- public class ProfileEditorViewModel : Conductor.Collection.AllActive
+ public class ProfileEditorViewModel : Conductor.Collection.AllActive
{
private readonly IModuleService _moduleService;
private readonly IProfileEditorService _profileEditorService;
@@ -36,7 +36,7 @@ namespace Artemis.UI.Screens.ProfileEditor
private PluginSetting _sidePanelsWidth;
public ProfileEditorViewModel(ProfileModule module,
- ICollection viewModels,
+ ICollection viewModels,
IProfileEditorService profileEditorService,
IProfileService profileService,
IDialogService dialogService,
diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml
index c4cbdf640..32eb00d36 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml
@@ -27,7 +27,7 @@
-
+
-
+
diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs
index 1593bfecc..6eee624df 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs
@@ -11,24 +11,17 @@ using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
{
- public class ProfileTreeViewModel : ProfileEditorPanelViewModel, IDropTarget
+ public class ProfileTreeViewModel : Conductor, IProfileEditorPanelViewModel, IDropTarget
{
- private readonly IFolderVmFactory _folderVmFactory;
+ private readonly IProfileTreeVmFactory _profileTreeVmFactory;
private readonly IProfileEditorService _profileEditorService;
- private FolderViewModel _rootFolder;
private TreeItemViewModel _selectedTreeItem;
private bool _updatingTree;
- public ProfileTreeViewModel(IProfileEditorService profileEditorService, IFolderVmFactory folderVmFactory)
+ public ProfileTreeViewModel(IProfileEditorService profileEditorService, IProfileTreeVmFactory profileTreeVmFactory)
{
_profileEditorService = profileEditorService;
- _folderVmFactory = folderVmFactory;
- }
-
- public FolderViewModel RootFolder
- {
- get => _rootFolder;
- set => SetAndNotify(ref _rootFolder, value);
+ _profileTreeVmFactory = profileTreeVmFactory;
}
public TreeItemViewModel SelectedTreeItem
@@ -73,7 +66,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
switch (dragDropType)
{
case DragDropType.Add:
- source.Parent.RemoveExistingElement(source);
+ ((TreeItemViewModel) source.Parent).RemoveExistingElement(source);
target.AddExistingElement(source);
break;
case DragDropType.InsertBefore:
@@ -92,27 +85,25 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
// ReSharper disable once UnusedMember.Global - Called from view
public void AddFolder()
{
- RootFolder?.AddFolder();
+ ActiveItem?.AddFolder();
}
// ReSharper disable once UnusedMember.Global - Called from view
public void AddLayer()
{
- RootFolder?.AddLayer();
+ ActiveItem?.AddLayer();
}
protected override void OnInitialActivate()
{
Subscribe();
CreateRootFolderViewModel();
+ base.OnInitialActivate();
}
protected override void OnClose()
{
Unsubscribe();
-
- RootFolder?.Dispose();
- RootFolder = null;
base.OnClose();
}
@@ -122,12 +113,11 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
var firstChild = _profileEditorService.SelectedProfile?.Children?.FirstOrDefault();
if (!(firstChild is Folder folder))
{
- RootFolder = null;
+ ActivateItem(null);
return;
}
- RootFolder?.Dispose();
- RootFolder = _folderVmFactory.Create(folder);
+ ActivateItem(_profileTreeVmFactory.FolderViewModel(folder));
_updatingTree = false;
// Auto-select the first layer
@@ -150,7 +140,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
{
if (parent == source)
return DragDropType.None;
- parent = parent.Parent;
+ parent = (TreeItemViewModel) parent.Parent;
}
switch (dropInfo.InsertPosition)
@@ -186,20 +176,20 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
if (e.RenderProfileElement == SelectedTreeItem?.ProfileElement)
return;
- if (RootFolder == null)
+ if (ActiveItem == null)
{
CreateRootFolderViewModel();
return;
}
_updatingTree = true;
- RootFolder.UpdateProfileElements();
+ ActiveItem.UpdateProfileElements();
_updatingTree = false;
if (e.RenderProfileElement == null)
SelectedTreeItem = null;
else
{
- var match = RootFolder.GetAllChildren().FirstOrDefault(vm => vm.ProfileElement == e.RenderProfileElement);
+ var match = ActiveItem.GetAllChildren().FirstOrDefault(vm => vm.ProfileElement == e.RenderProfileElement);
if (match != null)
SelectedTreeItem = match;
}
diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/FolderViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/FolderViewModel.cs
index 16d594f11..cfc085612 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/FolderViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/FolderViewModel.cs
@@ -1,5 +1,4 @@
using Artemis.Core;
-using Artemis.Core.Services;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Shared.Services;
@@ -11,36 +10,11 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
public FolderViewModel(ProfileElement folder,
IProfileEditorService profileEditorService,
IDialogService dialogService,
- IRenderElementService renderElementService,
- IFolderVmFactory folderVmFactory,
- ILayerVmFactory layerVmFactory) :
- base(null, folder, profileEditorService, dialogService, renderElementService, folderVmFactory, layerVmFactory)
- {
- }
-
- public FolderViewModel(TreeItemViewModel parent,
- ProfileElement folder,
- IProfileEditorService profileEditorService,
- IDialogService dialogService,
- IRenderElementService renderElementService,
- IFolderVmFactory folderVmFactory,
- ILayerVmFactory layerVmFactory) :
- base(parent, folder, profileEditorService, dialogService, renderElementService, folderVmFactory, layerVmFactory)
+ IProfileTreeVmFactory profileTreeVmFactory) :
+ base(folder, profileEditorService, dialogService, profileTreeVmFactory)
{
}
public override bool SupportsChildren => true;
-
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- foreach (var treeItemViewModel in Children)
- treeItemViewModel.Dispose();
- Children.Clear();
- }
-
- base.Dispose(disposing);
- }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerViewModel.cs
index c539a5a55..ce0e43ebc 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerViewModel.cs
@@ -1,5 +1,4 @@
using Artemis.Core;
-using Artemis.Core.Services;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Shared.Services;
@@ -7,14 +6,11 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
{
public class LayerViewModel : TreeItemViewModel
{
- public LayerViewModel(TreeItemViewModel parent,
- ProfileElement folder,
+ public LayerViewModel(ProfileElement layer,
IProfileEditorService profileEditorService,
IDialogService dialogService,
- IRenderElementService renderElementService,
- IFolderVmFactory folderVmFactory,
- ILayerVmFactory layerVmFactory) :
- base(parent, folder, profileEditorService, dialogService, renderElementService, folderVmFactory, layerVmFactory)
+ IProfileTreeVmFactory profileTreeVmFactory) :
+ base(layer, profileEditorService, dialogService, profileTreeVmFactory)
{
}
diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs
index a8d7f006b..cc923620d 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Artemis.Core;
-using Artemis.Core.Services;
using Artemis.UI.Exceptions;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.ProfileEditor.Dialogs;
@@ -12,66 +11,45 @@ using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
{
- public abstract class TreeItemViewModel : PropertyChangedBase, IDisposable
+ public abstract class TreeItemViewModel : Conductor.Collection.AllActive, IDisposable
{
private readonly IDialogService _dialogService;
- private readonly IFolderVmFactory _folderVmFactory;
- private readonly ILayerVmFactory _layerVmFactory;
private readonly IProfileEditorService _profileEditorService;
- private readonly IRenderElementService _renderElementService;
- private TreeItemViewModel _parent;
+ private readonly IProfileTreeVmFactory _profileTreeVmFactory;
private ProfileElement _profileElement;
- protected TreeItemViewModel(TreeItemViewModel parent,
- ProfileElement profileElement,
+ protected TreeItemViewModel(ProfileElement profileElement,
IProfileEditorService profileEditorService,
IDialogService dialogService,
- IRenderElementService renderElementService,
- IFolderVmFactory folderVmFactory,
- ILayerVmFactory layerVmFactory)
+ IProfileTreeVmFactory profileTreeVmFactory)
{
_profileEditorService = profileEditorService;
_dialogService = dialogService;
- _renderElementService = renderElementService;
- _folderVmFactory = folderVmFactory;
- _layerVmFactory = layerVmFactory;
+ _profileTreeVmFactory = profileTreeVmFactory;
- Parent = parent;
ProfileElement = profileElement;
- Children = new BindableCollection();
-
Subscribe();
UpdateProfileElements();
}
- public TreeItemViewModel Parent
- {
- get => _parent;
- set => SetAndNotify(ref _parent, value);
- }
-
public ProfileElement ProfileElement
{
get => _profileElement;
set => SetAndNotify(ref _profileElement, value);
}
- public BindableCollection Children { get; }
-
public abstract bool SupportsChildren { get; }
public void Dispose()
{
Unsubscribe();
- Dispose(true);
- GC.SuppressFinalize(this);
}
public List GetAllChildren()
{
var children = new List();
- foreach (var childFolder in Children)
+ foreach (var childFolder in Items)
{
// Add all children in this element
children.Add(childFolder);
@@ -84,34 +62,38 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
public void SetElementInFront(TreeItemViewModel source)
{
+ var sourceParent = (TreeItemViewModel) source.Parent;
+ var parent = (TreeItemViewModel) Parent;
if (source.Parent != Parent)
{
- source.Parent.RemoveExistingElement(source);
- Parent.AddExistingElement(source);
+ sourceParent.RemoveExistingElement(source);
+ parent.AddExistingElement(source);
}
- Parent.Unsubscribe();
- Parent.ProfileElement.RemoveChild(source.ProfileElement);
- Parent.ProfileElement.AddChild(source.ProfileElement, ProfileElement.Order);
- Parent.Subscribe();
+ parent.Unsubscribe();
+ parent.ProfileElement.RemoveChild(source.ProfileElement);
+ parent.ProfileElement.AddChild(source.ProfileElement, ProfileElement.Order);
+ parent.Subscribe();
- Parent.UpdateProfileElements();
+ parent.UpdateProfileElements();
}
public void SetElementBehind(TreeItemViewModel source)
{
+ var sourceParent = (TreeItemViewModel) source.Parent;
+ var parent = (TreeItemViewModel) Parent;
if (source.Parent != Parent)
{
- source.Parent.RemoveExistingElement(source);
- Parent.AddExistingElement(source);
+ sourceParent.RemoveExistingElement(source);
+ parent.AddExistingElement(source);
}
- Parent.Unsubscribe();
- Parent.ProfileElement.RemoveChild(source.ProfileElement);
- Parent.ProfileElement.AddChild(source.ProfileElement, ProfileElement.Order + 1);
- Parent.Subscribe();
+ parent.Unsubscribe();
+ parent.ProfileElement.RemoveChild(source.ProfileElement);
+ parent.ProfileElement.AddChild(source.ProfileElement, ProfileElement.Order + 1);
+ parent.Subscribe();
- Parent.UpdateProfileElements();
+ parent.UpdateProfileElements();
}
public void RemoveExistingElement(TreeItemViewModel treeItem)
@@ -138,7 +120,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
if (!SupportsChildren)
throw new ArtemisUIException("Cannot add a folder to a profile element of type " + ProfileElement.GetType().Name);
- ProfileElement.AddChild(new Folder(ProfileElement.Profile, ProfileElement, "New folder"));
+ var _ = new Folder(ProfileElement, "New folder");
_profileEditorService.UpdateSelectedProfile();
}
@@ -147,7 +129,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
if (!SupportsChildren)
throw new ArtemisUIException("Cannot add a layer to a profile element of type " + ProfileElement.GetType().Name);
- _renderElementService.CreateLayer(ProfileElement.Profile, ProfileElement, "New layer");
+ var _ = new Layer(ProfileElement, "New layer");
_profileEditorService.UpdateSelectedProfile();
}
@@ -180,7 +162,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
return;
// Farewell, cruel world
- var parent = Parent;
+ var parent = (TreeItemViewModel) Parent;
ProfileElement.Parent?.RemoveChild(ProfileElement);
parent.RemoveExistingElement(this);
@@ -190,17 +172,17 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
public void UpdateProfileElements()
{
// Remove VMs that are no longer a child
- var toRemove = Children.Where(c => c.ProfileElement.Parent != ProfileElement).ToList();
+ var toRemove = Items.Where(c => c.ProfileElement.Parent != ProfileElement).ToList();
foreach (var treeItemViewModel in toRemove)
- Children.Remove(treeItemViewModel);
+ DeactivateItem(treeItemViewModel);
// Order the children
- var vmsList = Children.OrderBy(v => v.ProfileElement.Order).ToList();
+ var vmsList = Items.OrderBy(v => v.ProfileElement.Order).ToList();
for (var index = 0; index < vmsList.Count; index++)
{
var profileElementViewModel = vmsList[index];
- if (Children.IndexOf(profileElementViewModel) != index)
- Children.Move(Children.IndexOf(profileElementViewModel), index);
+ if (Items.IndexOf(profileElementViewModel) != index)
+ ((BindableCollection) Items).Move(Items.IndexOf(profileElementViewModel), index);
}
// Ensure every child element has an up-to-date VM
@@ -212,13 +194,13 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
{
if (profileElement is Folder folder)
{
- if (Children.FirstOrDefault(p => p is FolderViewModel vm && vm.ProfileElement == folder) == null)
- newChildren.Add(_folderVmFactory.Create((FolderViewModel) this, folder));
+ if (Items.FirstOrDefault(p => p is FolderViewModel vm && vm.ProfileElement == folder) == null)
+ newChildren.Add(_profileTreeVmFactory.FolderViewModel(folder));
}
else if (profileElement is Layer layer)
{
- if (Children.FirstOrDefault(p => p is LayerViewModel vm && vm.ProfileElement == layer) == null)
- newChildren.Add(_layerVmFactory.Create((FolderViewModel) this, layer));
+ if (Items.FirstOrDefault(p => p is LayerViewModel vm && vm.ProfileElement == layer) == null)
+ newChildren.Add(_profileTreeVmFactory.LayerViewModel(layer));
}
}
@@ -229,7 +211,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
foreach (var treeItemViewModel in newChildren)
{
treeItemViewModel.UpdateProfileElements();
- Children.Add(treeItemViewModel);
+ ActivateItem(treeItemViewModel);
}
}
@@ -238,13 +220,6 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
_profileEditorService.UpdateSelectedProfile();
}
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- }
- }
-
private void Subscribe()
{
ProfileElement.ChildAdded += ProfileElementOnChildAdded;
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileDeviceView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileDeviceView.xaml
deleted file mode 100644
index 82a471bc7..000000000
--- a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileDeviceView.xaml
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileDeviceViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileDeviceViewModel.cs
deleted file mode 100644
index 828600820..000000000
--- a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileDeviceViewModel.cs
+++ /dev/null
@@ -1,96 +0,0 @@
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Windows;
-using Artemis.Core;
-using Stylet;
-
-namespace Artemis.UI.Screens.ProfileEditor.Visualization
-{
- public class ProfileDeviceViewModel : CanvasViewModel
- {
- private bool _addedLeds;
- private ArtemisDevice _device;
- private ObservableCollection _leds;
-
- public ProfileDeviceViewModel(ArtemisDevice device)
- {
- Device = device;
- Leds = new ObservableCollection();
-
- Task.Run(AddLedsAsync);
- }
-
- public ObservableCollection Leds
- {
- get => _leds;
- set => SetAndNotify(ref _leds, value);
- }
-
- public ArtemisDevice Device
- {
- get => _device;
- set => SetAndNotify(ref _device, value);
- }
-
- public bool AddedLeds
- {
- get => _addedLeds;
- private set => SetAndNotify(ref _addedLeds, value);
- }
-
- public new double X
- {
- get => Device.X;
- set => Device.X = value;
- }
-
- public new double Y
- {
- get => Device.Y;
- set => Device.Y = value;
- }
-
- public int ZIndex
- {
- get => Device.ZIndex;
- set => Device.ZIndex = value;
- }
-
-
- public Rect DeviceRectangle => Device.RgbDevice == null
- ? new Rect()
- : new Rect(X, Y, Device.RgbDevice.Size.Width, Device.RgbDevice.Size.Height);
-
- ///
- /// Update the color of all LEDs if finished adding
- ///
- public void Update()
- {
- if (!AddedLeds)
- return;
-
- foreach (var ledViewModel in Leds)
- ledViewModel.Update();
- }
-
- ///
- /// Adds LEDs in batches of 5 to avoid UI freezes
- ///
- ///
- private async Task AddLedsAsync()
- {
- var index = 0;
- foreach (var led in Device.Leds.ToList())
- {
- Execute.OnUIThreadSync(() => Leds.Add(new ProfileLedViewModel(led)));
- if (index % 5 == 0)
- await Task.Delay(1);
-
- index++;
- }
-
- AddedLeds = true;
- }
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileLedView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileLedView.xaml
deleted file mode 100644
index 083bfc23c..000000000
--- a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileLedView.xaml
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileLedViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileLedViewModel.cs
deleted file mode 100644
index 26abba437..000000000
--- a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileLedViewModel.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-using System;
-using System.Windows;
-using System.Windows.Media;
-using Artemis.Core;
-using Artemis.UI.Extensions;
-using RGB.NET.Core;
-using Stylet;
-using Color = System.Windows.Media.Color;
-
-namespace Artemis.UI.Screens.ProfileEditor.Visualization
-{
- public class ProfileLedViewModel : PropertyChangedBase
- {
- private Color _displayColor;
- private Geometry _displayGeometry;
- private bool _isDimmed;
- private bool _isSelected;
- private Geometry _strokeGeometry;
-
- public ProfileLedViewModel(ArtemisLed led)
- {
- Led = led;
-
- // Don't want ActualLocation here since rotation is done in XAML
- X = led.RgbLed.Location.X * led.RgbLed.Device.Scale.Horizontal;
- Y = led.RgbLed.Location.Y * led.RgbLed.Device.Scale.Vertical;
- Width = led.RgbLed.ActualSize.Width;
- Height = led.RgbLed.ActualSize.Height;
-
- Execute.PostToUIThread(CreateLedGeometry);
- }
-
- public ArtemisLed Led { get; }
-
- public double X { get; }
- public double Y { get; }
- public double Width { get; }
- public double Height { get; }
-
- public bool IsSelected
- {
- get => _isSelected;
- set => SetAndNotify(ref _isSelected, value);
- }
-
- public bool IsDimmed
- {
- get => _isDimmed;
- set => SetAndNotify(ref _isDimmed, value);
- }
-
- public Geometry DisplayGeometry
- {
- get => _displayGeometry;
- private set => SetAndNotify(ref _displayGeometry, value);
- }
-
- public Geometry StrokeGeometry
- {
- get => _strokeGeometry;
- private set => SetAndNotify(ref _strokeGeometry, value);
- }
-
- public Color DisplayColor
- {
- get => _displayColor;
- private set => SetAndNotify(ref _displayColor, value);
- }
-
- public void Update()
- {
- var newColor = Led.RgbLed.Color.ToMediaColor();
- Execute.PostToUIThread(() =>
- {
- if (!DisplayColor.Equals(newColor))
- DisplayColor = newColor;
- });
- }
-
- private void CreateLedGeometry()
- {
- switch (Led.RgbLed.Shape)
- {
- case Shape.Custom:
- if (Led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keyboard || Led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keypad)
- CreateCustomGeometry(2.0);
- else
- CreateCustomGeometry(1.0);
- break;
- case Shape.Rectangle:
- if (Led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keyboard || Led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keypad)
- CreateKeyCapGeometry();
- else
- CreateRectangleGeometry();
- break;
- case Shape.Circle:
- CreateCircleGeometry();
- break;
- default:
- throw new ArgumentOutOfRangeException();
- }
-
- // Stroke geometry is the display geometry excluding the inner geometry
- StrokeGeometry = DisplayGeometry.GetWidenedPathGeometry(new Pen(null, 1.0), 0.1, ToleranceType.Absolute);
- DisplayGeometry.Freeze();
- StrokeGeometry.Freeze();
- }
-
- private void CreateRectangleGeometry()
- {
- DisplayGeometry = new RectangleGeometry(new Rect(0.5, 0.5, Width - 1, Height - 1));
- }
-
- private void CreateCircleGeometry()
- {
- DisplayGeometry = new EllipseGeometry(new Rect(0.5, 0.5, Width - 1, Height - 1));
- }
-
- private void CreateKeyCapGeometry()
- {
- DisplayGeometry = new RectangleGeometry(new Rect(1, 1, Width - 2, Height - 2), 1.6, 1.6);
- }
-
- private void CreateCustomGeometry(double deflateAmount)
- {
- try
- {
- DisplayGeometry = Geometry.Combine(
- Geometry.Empty,
- Geometry.Parse(Led.RgbLed.ShapeData),
- GeometryCombineMode.Union,
- new TransformGroup
- {
- Children = new TransformCollection
- {
- new ScaleTransform(Width - deflateAmount, Height - deflateAmount),
- new TranslateTransform(deflateAmount / 2, deflateAmount / 2)
- }
- }
- );
- }
- catch (Exception)
- {
- CreateRectangleGeometry();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileViewModel.cs
index c64e1ffcc..0c5b0f566 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileViewModel.cs
@@ -15,7 +15,7 @@ using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.Visualization
{
- public class ProfileViewModel : ProfileEditorPanelViewModel, IHandle, IHandle
+ public class ProfileViewModel : Screen, IProfileEditorPanelViewModel, IHandle, IHandle
{
private readonly IProfileEditorService _profileEditorService;
private readonly IProfileLayerVmFactory _profileLayerVmFactory;
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerBrushSettingsWindowView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Windows/LayerBrushSettingsWindowView.xaml
similarity index 97%
rename from src/Artemis.UI/Screens/ProfileEditor/LayerBrushSettingsWindowView.xaml
rename to src/Artemis.UI/Screens/ProfileEditor/Windows/LayerBrushSettingsWindowView.xaml
index 6acacbc9a..42507087e 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerBrushSettingsWindowView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/Windows/LayerBrushSettingsWindowView.xaml
@@ -1,4 +1,4 @@
-
{
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerEffectSettingsWindowView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Windows/LayerEffectSettingsWindowView.xaml
similarity index 97%
rename from src/Artemis.UI/Screens/ProfileEditor/LayerEffectSettingsWindowView.xaml
rename to src/Artemis.UI/Screens/ProfileEditor/Windows/LayerEffectSettingsWindowView.xaml
index f7f6d2977..1cc495742 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerEffectSettingsWindowView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/Windows/LayerEffectSettingsWindowView.xaml
@@ -1,4 +1,4 @@
-
{