Added generic typing to layer properties and keyframes

Restructured the way property input VMs are created
This commit is contained in:
Robert committed 2020-01-08 12:23:52 +01:00
1 parent 39cc8bfbdb
commit 7a3b5dec3e
21 files changed
+342 -155

No files matched your search

@@ -3,6 +3,7 @@ using System.Linq;
using System.Windows;
using System.Windows.Input;
using Artemis.Core.Models.Profile;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline;
using Artemis.UI.Services.Interfaces;
@@ -12,10 +13,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
public class LayerPropertiesViewModel : ProfileEditorPanelViewModel
{
private readonly IProfileEditorService _profileEditorService;
private readonly ILayerPropertyViewModelFactory _layerPropertyViewModelFactory;
public LayerPropertiesViewModel(IProfileEditorService profileEditorService)
public LayerPropertiesViewModel(IProfileEditorService profileEditorService, ILayerPropertyViewModelFactory layerPropertyViewModelFactory)
{
_profileEditorService = profileEditorService;
_layerPropertyViewModelFactory = layerPropertyViewModelFactory;
CurrentTime = TimeSpan.Zero;
PixelsPerSecond = 1;
@@ -75,7 +78,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
// Only create VMs for top-level parents, let parents populate their own children recursively
var propertyViewModels = selectedLayer.Properties
.Where(p => p.Children.Any())
.Select(p => new LayerPropertyViewModel(p, null))
.Select(p => _layerPropertyViewModelFactory.Create(p, null))
.ToList();
PropertyTree.PopulateProperties(propertyViewModels);
@@ -1,26 +1,46 @@
using System.Collections.Generic;
using Artemis.Core.Models.Profile;
using System.Linq;
using Artemis.Core.Models.Profile.LayerProperties;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput;
using Ninject;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
{
public class LayerPropertyViewModel : PropertyChangedBase
{
public LayerPropertyViewModel(LayerProperty layerProperty, LayerPropertyViewModel parent)
private readonly IKernel _kernel;
public LayerPropertyViewModel(BaseLayerProperty layerProperty,
LayerPropertyViewModel parent,
ILayerPropertyViewModelFactory layerPropertyViewModelFactory, IKernel kernel)
{
_kernel = kernel;
LayerProperty = layerProperty;
Parent = parent;
Children = new List<LayerPropertyViewModel>();
foreach (var child in layerProperty.Children)
Children.Add(new LayerPropertyViewModel(child, this));
Children.Add(layerPropertyViewModelFactory.Create(child, this));
}
public LayerProperty LayerProperty { get; }
public BaseLayerProperty LayerProperty { get; }
public LayerPropertyViewModel Parent { get; }
public List<LayerPropertyViewModel> Children { get; set; }
public bool IsExpanded { get; set; }
public PropertyInputViewModel GetPropertyInputViewModel()
{
var match = _kernel.Get<List<PropertyInputViewModel>>().FirstOrDefault(p => p.CompatibleTypes.Contains(LayerProperty.Type));
if (match == null)
return null;
match.Initialize(this);
return match;
}
}
}
@@ -1,16 +1,10 @@
using Artemis.UI.Exceptions;
using System;
using System.Collections.Generic;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput
{
public class FloatPropertyInputViewModel : PropertyInputViewModel
{
public FloatPropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel) : base(layerPropertyViewModel)
{
if (layerPropertyViewModel.LayerProperty.Type != typeof(float))
{
throw new ArtemisUIException("This input VM expects a layer property of type float, " +
$"not the provided type {layerPropertyViewModel.LayerProperty.Type.Name}");
}
}
public sealed override List<Type> CompatibleTypes { get; } = new List<Type> {typeof(float)};
}
}
@@ -1,16 +1,10 @@
using Artemis.UI.Exceptions;
using System;
using System.Collections.Generic;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput
{
public class IntPropertyInputViewModel : PropertyInputViewModel
{
public IntPropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel) : base(layerPropertyViewModel)
{
if (layerPropertyViewModel.LayerProperty.Type != typeof(int))
{
throw new ArtemisUIException("This input VM expects a layer property of type int, " +
$"not the provided type {layerPropertyViewModel.LayerProperty.Type.Name}");
}
}
public sealed override List<Type> CompatibleTypes { get; } = new List<Type> {typeof(int)};
}
}
@@ -1,14 +1,26 @@
using Stylet;
using System;
using System.Collections.Generic;
using Artemis.UI.Exceptions;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput
{
public abstract class PropertyInputViewModel : PropertyChangedBase
{
protected PropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel)
{
LayerPropertyViewModel = layerPropertyViewModel;
}
public bool Initialized { get; private set; }
public LayerPropertyViewModel LayerPropertyViewModel { get; }
public abstract List<Type> CompatibleTypes { get; }
public LayerPropertyViewModel LayerPropertyViewModel { get; private set; }
public void Initialize(LayerPropertyViewModel layerPropertyViewModel)
{
if (Initialized)
throw new ArtemisUIException("Cannot initialize the same property input VM twice");
if (!CompatibleTypes.Contains(layerPropertyViewModel.LayerProperty.Type))
throw new ArtemisUIException($"This input VM does not support the provided type {layerPropertyViewModel.LayerProperty.Type.Name}");
LayerPropertyViewModel = layerPropertyViewModel;
Initialized = true;
}
}
}
@@ -1,17 +1,11 @@
using Artemis.UI.Exceptions;
using System;
using System.Collections.Generic;
using SkiaSharp;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput
{
public class SKPointPropertyInputViewModel : PropertyInputViewModel
{
public SKPointPropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel) : base(layerPropertyViewModel)
{
if (layerPropertyViewModel.LayerProperty.Type != typeof(SKPoint))
{
throw new ArtemisUIException($"This input VM expects a layer property of type {nameof(SKPoint)}, " +
$"not the provided type {layerPropertyViewModel.LayerProperty.Type.Name}");
}
}
public sealed override List<Type> CompatibleTypes { get; } = new List<Type> {typeof(SKPoint)};
}
}
@@ -1,17 +1,11 @@
using Artemis.UI.Exceptions;
using System;
using System.Collections.Generic;
using SkiaSharp;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput
{
public class SKSizePropertyInputViewModel : PropertyInputViewModel
{
public SKSizePropertyInputViewModel(LayerPropertyViewModel layerPropertyViewModel) : base(layerPropertyViewModel)
{
if (layerPropertyViewModel.LayerProperty.Type != typeof(SKSize))
{
throw new ArtemisUIException($"This input VM expects a layer property of type {nameof(SKSize)}, " +
$"not the provided type {layerPropertyViewModel.LayerProperty.Type.Name}");
}
}
public sealed override List<Type> CompatibleTypes { get; } = new List<Type> {typeof(SKSize)};
}
}
@@ -1,5 +1,6 @@
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput;
using SkiaSharp;
using System.Collections.Generic;
using System.Linq;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree.PropertyInput;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree
{
@@ -10,16 +11,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.PropertyTree
public PropertyTreeChildViewModel(LayerPropertyViewModel layerPropertyViewModel)
{
LayerPropertyViewModel = layerPropertyViewModel;
// TODO: Leverage DI for this and make it less shitty :))
if (LayerPropertyViewModel.LayerProperty.Type == typeof(SKPoint))
PropertyInputViewModel = new SKPointPropertyInputViewModel(LayerPropertyViewModel);
else if (LayerPropertyViewModel.LayerProperty.Type == typeof(SKSize))
PropertyInputViewModel = new SKSizePropertyInputViewModel(LayerPropertyViewModel);
else if (LayerPropertyViewModel.LayerProperty.Type == typeof(int))
PropertyInputViewModel = new IntPropertyInputViewModel(LayerPropertyViewModel);
else if (LayerPropertyViewModel.LayerProperty.Type == typeof(float))
PropertyInputViewModel = new FloatPropertyInputViewModel(LayerPropertyViewModel);
PropertyInputViewModel = layerPropertyViewModel.GetPropertyInputViewModel();
}
public LayerPropertyViewModel LayerPropertyViewModel { get; }
@@ -1,17 +1,18 @@
using System;
using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Profile.LayerProperties;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{
public class PropertyTrackKeyframeViewModel : PropertyChangedBase
{
public PropertyTrackKeyframeViewModel(Keyframe keyframe)
public PropertyTrackKeyframeViewModel(BaseKeyframe keyframe)
{
Keyframe = keyframe;
}
public Keyframe Keyframe { get; }
public BaseKeyframe Keyframe { get; }
public double X { get; set; }
public string Timestamp { get; set; }
@@ -21,7 +21,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
public void PopulateKeyframes()
{
foreach (var keyframe in LayerPropertyViewModel.LayerProperty.Keyframes)
foreach (var keyframe in LayerPropertyViewModel.LayerProperty.UntypedKeyframes)
{
if (KeyframeViewModels.Any(k => k.Keyframe == keyframe))
continue;