diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Converters/FloatDataBindingConverter.cs b/src/Artemis.Core/Models/Profile/DataBindings/Converters/FloatDataBindingConverter.cs
index 7a0c3d0a8..ed77db48f 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/Converters/FloatDataBindingConverter.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Converters/FloatDataBindingConverter.cs
@@ -30,14 +30,14 @@ namespace Artemis.Core
///
public override float Interpolate(float a, float b, double progress)
{
- var diff = a - b;
+ var diff = b - a;
return (float) (a + diff * progress);
}
///
public override void ApplyValue(float value)
{
- if (SetExpression == null)
+ if (ValueTypeSetExpression == null)
return;
if (DataBinding.LayerProperty.PropertyDescription.MaxInputValue is float max)
@@ -45,21 +45,7 @@ namespace Artemis.Core
if (DataBinding.LayerProperty.PropertyDescription.MinInputValue is float min)
value = Math.Max(value, min);
- var test = new SKSize(5,5);
- test.Width = 10;
-
- SetExpression(DataBinding.LayerProperty.CurrentValue, value);
- }
-
- private void Mehtest(ref SKSize test)
- {
- test.Width = 20;
- }
-
- ///
- public override float GetValue()
- {
- return GetExpression(DataBinding.LayerProperty.CurrentValue);
+ base.ApplyValue(value);
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Converters/GeneralDataBindingConverter.cs b/src/Artemis.Core/Models/Profile/DataBindings/Converters/GeneralDataBindingConverter.cs
index bb94f06ac..478b17eea 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/Converters/GeneralDataBindingConverter.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Converters/GeneralDataBindingConverter.cs
@@ -22,17 +22,5 @@ namespace Artemis.Core
{
throw new NotSupportedException();
}
-
- ///
- public override void ApplyValue(object value)
- {
- SetExpression?.Invoke(DataBinding.LayerProperty.CurrentValue, value);
- }
-
- ///
- public override object GetValue()
- {
- return GetExpression(DataBinding.LayerProperty.CurrentValue);
- }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Converters/IntDataBindingConverter.cs b/src/Artemis.Core/Models/Profile/DataBindings/Converters/IntDataBindingConverter.cs
index 70daff304..86265461f 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/Converters/IntDataBindingConverter.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Converters/IntDataBindingConverter.cs
@@ -37,17 +37,5 @@ namespace Artemis.Core
var diff = b - a;
return (int) Math.Round(a + diff * progress, InterpolationRoundingMode);
}
-
- ///
- public override void ApplyValue(int value)
- {
- SetExpression?.Invoke(DataBinding.LayerProperty.CurrentValue, value);
- }
-
- ///
- public override int GetValue()
- {
- return GetExpression(DataBinding.LayerProperty.CurrentValue);
- }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Converters/Internal/SKColorArgbDataBindingConverter.cs b/src/Artemis.Core/Models/Profile/DataBindings/Converters/Internal/SKColorArgbDataBindingConverter.cs
index cc8c6c551..e713bd23a 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/Converters/Internal/SKColorArgbDataBindingConverter.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Converters/Internal/SKColorArgbDataBindingConverter.cs
@@ -24,7 +24,7 @@ namespace Artemis.Core
public override byte Interpolate(byte a, byte b, double progress)
{
var diff = b - a;
- return ClampToByte(diff * progress);
+ return ClampToByte(a + diff * progress);
}
public override void ApplyValue(byte value)
@@ -48,21 +48,10 @@ namespace Artemis.Core
}
}
- public override byte GetValue()
+ public override byte ConvertFromObject(object source)
{
- switch (_channel)
- {
- case Channel.Alpha:
- return DataBinding.LayerProperty.CurrentValue.Alpha;
- case Channel.Red:
- return DataBinding.LayerProperty.CurrentValue.Red;
- case Channel.Green:
- return DataBinding.LayerProperty.CurrentValue.Green;
- case Channel.Blue:
- return DataBinding.LayerProperty.CurrentValue.Blue;
- default:
- throw new ArgumentOutOfRangeException();
- }
+ var saveValue = Convert.ToDouble(source);
+ return ClampToByte(saveValue);
}
private static byte ClampToByte(double value)
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
index d584a802a..f167832fe 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
@@ -206,8 +206,8 @@ namespace Artemis.Core
foreach (var dataBindingModifier in Modifiers)
dataBindingValue = dataBindingModifier.Apply(dataBindingValue);
- var value = (TProperty) Convert.ChangeType(dataBindingValue, typeof(TProperty));
-
+ TProperty value = Converter.ConvertFromObject(dataBindingValue);
+
// If no easing is to be applied simple return whatever the current value is
if (EasingTime == TimeSpan.Zero || !Converter.SupportsInterpolate)
return value;
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/DataBindingConverter.cs b/src/Artemis.Core/Models/Profile/DataBindings/DataBindingConverter.cs
index fbe7642fc..380caba36 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/DataBindingConverter.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/DataBindingConverter.cs
@@ -1,5 +1,4 @@
using System;
-using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
@@ -19,7 +18,9 @@ namespace Artemis.Core
///
/// A dynamically compiled setter pointing to the data bound property
///
- public Action SetExpression { get; private set; }
+ public Action ValueTypeSetExpression { get; private set; }
+
+ public Action ReferenceTypeSetExpression { get; private set; }
///
/// Gets the data binding this converter is applied to
@@ -59,12 +60,29 @@ namespace Artemis.Core
/// Applies the to the layer property
///
///
- public abstract void ApplyValue(TProperty value);
+ public virtual void ApplyValue(TProperty value)
+ {
+ if (ReferenceTypeSetExpression != null)
+ ReferenceTypeSetExpression(DataBinding.LayerProperty.CurrentValue, value);
+ else if (ValueTypeSetExpression != null)
+ ValueTypeSetExpression(value);
+ }
///
/// Returns the current base value of the data binding
///
- public abstract TProperty GetValue();
+ public virtual TProperty GetValue()
+ {
+ return GetExpression(DataBinding.LayerProperty.CurrentValue);
+ }
+
+ ///
+ /// Converts the provided object to a type of
+ ///
+ public virtual TProperty ConvertFromObject(object source)
+ {
+ return (TProperty) Convert.ChangeType(source, typeof(TProperty));
+ }
///
/// Called when the data binding converter has been initialized and the is available
@@ -77,40 +95,76 @@ namespace Artemis.Core
{
DataBinding = dataBinding;
GetExpression = dataBinding.Registration.PropertyExpression.Compile();
- SetExpression = CreateValueSetter();
+ CreateSetExpression();
OnInitialized();
}
- private Action CreateValueSetter()
+ private void CreateSetExpression()
{
- MethodInfo setterMethod = null;
-
- if (DataBinding.Registration.Member != null)
+ // If the registration does not point towards a member of LayerProperty.CurrentValue, assign directly to LayerProperty.CurrentValue
+ if (DataBinding.Registration.Member == null)
{
- if (DataBinding.Registration.Member is PropertyInfo propertyInfo)
- setterMethod = propertyInfo.GetSetMethod();
+ CreateSetCurrentValueExpression();
+ return;
}
+ // Ensure the member of LayerProperty.CurrentValue has a setter
+ MethodInfo setterMethod = null;
+ if (DataBinding.Registration.Member is PropertyInfo propertyInfo)
+ setterMethod = propertyInfo.GetSetMethod();
+ // If there is no setter, the built-in data binding cannot do its job, stay null
if (setterMethod == null)
- return null;
+ return;
- var parameter = Expression.Parameter(typeof(TLayerProperty), "currentValue");
+ // If LayerProperty.CurrentValue is a value type, assign it directly to LayerProperty.CurrentValue after applying the changes
+ if (typeof(TLayerProperty).IsValueType)
+ CreateSetValueTypeExpression();
+ // If it is a reference type it can safely be updated by its reference
+ else
+ CreateSetReferenceTypeExpression();
+ }
+
+ private void CreateSetReferenceTypeExpression()
+ {
var propertyValue = Expression.Parameter(typeof(TProperty), "propertyValue");
-
-
+ var parameter = Expression.Parameter(typeof(TLayerProperty), "currentValue");
var memberAccess = Expression.MakeMemberAccess(parameter, DataBinding.Registration.Member);
var assignment = Expression.Assign(memberAccess, propertyValue);
- var lambda = Expression.Lambda>(assignment, parameter, propertyValue);
+ var referenceTypeLambda = Expression.Lambda>(assignment, parameter, propertyValue);
- if (typeof(TLayerProperty).IsValueType)
- {
- // var layerProperty = Expression.Constant(DataBinding.LayerProperty);
- // var layerPropertyMemberAccess = Expression.MakeMemberAccess(layerProperty, DataBinding.LayerProperty.GetType().GetMember(nameof(DataBinding.LayerProperty.CurrentValue))[0]);
- // var assingment = Expression.Assign()
- }
+ ReferenceTypeSetExpression = referenceTypeLambda.Compile();
+ }
- return lambda.Compile();
+ private void CreateSetValueTypeExpression()
+ {
+ var propertyValue = Expression.Parameter(typeof(TProperty), "propertyValue");
+ var variableCurrent = Expression.Variable(typeof(TLayerProperty), "current");
+ var layerProperty = Expression.Constant(DataBinding.LayerProperty);
+ var layerPropertyMemberAccess = Expression.MakeMemberAccess(layerProperty,
+ DataBinding.LayerProperty.GetType().GetMember(nameof(DataBinding.LayerProperty.CurrentValue))[0]);
+
+ var body = Expression.Block(
+ new[] {variableCurrent},
+ Expression.Assign(variableCurrent, layerPropertyMemberAccess),
+ Expression.Assign(Expression.MakeMemberAccess(variableCurrent, DataBinding.Registration.Member), propertyValue),
+ Expression.Assign(layerPropertyMemberAccess, variableCurrent)
+ );
+
+ var valueTypeLambda = Expression.Lambda>(body, propertyValue);
+ ValueTypeSetExpression = valueTypeLambda.Compile();
+ }
+
+ private void CreateSetCurrentValueExpression()
+ {
+ var propertyValue = Expression.Parameter(typeof(TProperty), "propertyValue");
+ var layerProperty = Expression.Constant(DataBinding.LayerProperty);
+ var layerPropertyMemberAccess = Expression.MakeMemberAccess(layerProperty,
+ DataBinding.LayerProperty.GetType().GetMember(nameof(DataBinding.LayerProperty.CurrentValue))[0]);
+
+ var body = Expression.Assign(layerPropertyMemberAccess, propertyValue);
+ var lambda = Expression.Lambda>(body, propertyValue);
+ ValueTypeSetExpression = lambda.Compile();
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/DataBindingModifier.cs b/src/Artemis.Core/Models/Profile/DataBindings/DataBindingModifier.cs
index 05e126771..5ad50d0ee 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/DataBindingModifier.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/DataBindingModifier.cs
@@ -16,18 +16,20 @@ namespace Artemis.Core
///
/// Creates a new instance of the class
///
+ /// The data binding the modifier is to be applied to
/// The type of the parameter, can either be dynamic (based on a data model value) or static
- public DataBindingModifier(ProfileRightSideType parameterType)
+ public DataBindingModifier(DataBinding dataBinding, ProfileRightSideType parameterType)
{
+ _dataBinding = dataBinding ?? throw new ArgumentNullException(nameof(dataBinding));
ParameterType = parameterType;
Entity = new DataBindingModifierEntity();
- Save();
Initialize();
+ Save();
}
internal DataBindingModifier(DataBinding dataBinding, DataBindingModifierEntity entity)
{
- DataBinding = dataBinding;
+ _dataBinding = dataBinding;
Entity = entity;
Load();
Initialize();
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modifiers/Abstract/DataBindingModifierType.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modifiers/Abstract/DataBindingModifierType.cs
index 7f08e7a5a..bf0210834 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/Modifiers/Abstract/DataBindingModifierType.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Modifiers/Abstract/DataBindingModifierType.cs
@@ -31,10 +31,16 @@ namespace Artemis.Core
public abstract string Icon { get; }
///
- /// Gets or sets whether this modifier supports a parameter, defaults to true
+ /// Gets or sets whether this modifier supports a parameter, defaults to true
///
public bool SupportsParameter { get; protected set; } = true;
+ ///
+ /// Gets or sets the preferred parameter type
+ /// If null, the parameter type will match the source property
+ ///
+ public Type PreferredParameterType { get; protected set; } = null;
+
///
/// Returns whether the given type is supported by the modifier
///
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modifiers/DivideModifierType.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modifiers/DivideModifierType.cs
index 7f153d14b..0497fde96 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/Modifiers/DivideModifierType.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Modifiers/DivideModifierType.cs
@@ -5,6 +5,11 @@ namespace Artemis.Core
{
internal class DivideModifierType : DataBindingModifierType
{
+ public DivideModifierType()
+ {
+ PreferredParameterType = typeof(float);
+ }
+
public override IReadOnlyCollection CompatibleTypes => Constants.NumberTypes;
public override string Description => "Divide by";
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modifiers/MultiplicationModifier.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modifiers/MultiplicationModifier.cs
index bf400778d..fe71f7ccc 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/Modifiers/MultiplicationModifier.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Modifiers/MultiplicationModifier.cs
@@ -5,6 +5,11 @@ namespace Artemis.Core
{
internal class MultiplicationModifierType : DataBindingModifierType
{
+ public MultiplicationModifierType()
+ {
+ PreferredParameterType = typeof(float);
+ }
+
public override IReadOnlyCollection CompatibleTypes => Constants.NumberTypes;
public override string Description => "Multiply by";
diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs
index 7fdad81f5..97f705548 100644
--- a/src/Artemis.Core/Models/Profile/Layer.cs
+++ b/src/Artemis.Core/Models/Profile/Layer.cs
@@ -682,9 +682,9 @@ namespace Artemis.Core
}
// Ensure the brush reference matches the brush
- var current = General.BrushReference.CurrentValue;
+ var current = General.BrushReference.BaseValue;
if (!descriptor.MatchesLayerBrushReference(current))
- General.BrushReference.CurrentValue = new LayerBrushReference(descriptor);
+ General.BrushReference.BaseValue = new LayerBrushReference(descriptor);
ActivateLayerBrush();
}
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs
index 2e97c6bbb..34635c846 100644
--- a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs
+++ b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs
@@ -13,7 +13,7 @@ using Stylet;
namespace Artemis.UI.Shared.Input
{
- public class DataModelDynamicViewModel : PropertyChangedBase
+ public class DataModelDynamicViewModel : PropertyChangedBase, IDisposable
{
private readonly IDataModelUIService _dataModelUIService;
private readonly Module _module;
@@ -127,5 +127,12 @@ namespace Artemis.UI.Shared.Input
}
#endregion
+
+ public void Dispose()
+ {
+ _updateTimer.Stop();
+ _updateTimer.Dispose();
+ _updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Modules/ModuleRootViewModel.cs b/src/Artemis.UI/Screens/Modules/ModuleRootViewModel.cs
index 93c6985d0..6437a5cd5 100644
--- a/src/Artemis.UI/Screens/Modules/ModuleRootViewModel.cs
+++ b/src/Artemis.UI/Screens/Modules/ModuleRootViewModel.cs
@@ -29,7 +29,7 @@ namespace Artemis.UI.Screens.Modules
AddTabs();
base.OnActivate();
}
-
+
private void AddTabs()
{
// Create the profile editor and module VMs
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierView.xaml
index a3aaf5c56..48f6007e6 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierView.xaml
@@ -18,14 +18,6 @@
-
-
-
-
-
-
-
-
@@ -62,7 +54,6 @@
Style="{StaticResource DisplayConditionButtonLeftClickMenu}"
Background="#7B7B7B"
BorderBrush="#7B7B7B"
- Content="{Binding SelectedModifierType.Description}"
Click="PropertyButton_OnClick">
@@ -83,6 +74,15 @@
+
+
+
+ « Select a modifier »
+
+
+
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierViewModel.cs
index 4ce493458..431185848 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierViewModel.cs
@@ -1,4 +1,5 @@
-using Artemis.Core;
+using System;
+using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Exceptions;
using Artemis.UI.Shared;
@@ -8,7 +9,7 @@ using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
{
- public class DataBindingModifierViewModel : PropertyChangedBase
+ public class DataBindingModifierViewModel : PropertyChangedBase, IDisposable
{
private readonly IDataBindingService _dataBindingService;
private readonly IDataModelUIService _dataModelUIService;
@@ -34,8 +35,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
SelectModifierTypeCommand = new DelegateCommand(ExecuteSelectModifierTypeCommand);
- // Initialize async, no need to wait for it
- Execute.PostToUIThread(Update);
+ Update();
}
public DelegateCommand SelectModifierTypeCommand { get; }
@@ -92,6 +92,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
if (sourceType == null)
throw new ArtemisUIException("Cannot use a data binding modifier VM for a data binding without a source");
+ if (DynamicSelectionViewModel != null)
+ {
+ DynamicSelectionViewModel.Dispose();
+ DynamicSelectionViewModel.PropertySelected -= ParameterSelectionViewModelOnPropertySelected;
+ }
+
if (Modifier.ModifierType == null || !Modifier.ModifierType.SupportsParameter)
{
StaticInputViewModel = null;
@@ -101,14 +107,22 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
{
StaticInputViewModel = null;
DynamicSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
- DynamicSelectionViewModel.PropertySelected += ParameterSelectionViewModelOnPropertySelected;
- DynamicSelectionViewModel.FilterTypes = new[] {sourceType};
+ if (DynamicSelectionViewModel != null)
+ {
+ DynamicSelectionViewModel.PropertySelected += ParameterSelectionViewModelOnPropertySelected;
+ DynamicSelectionViewModel.FilterTypes = new[] {sourceType};
+ }
}
else
{
DynamicSelectionViewModel = null;
- StaticInputViewModel = _dataModelUIService.GetStaticInputViewModel(sourceType);
- StaticInputViewModel.ValueUpdated += StaticInputViewModelOnValueUpdated;
+ if (Modifier.ModifierType.PreferredParameterType != null && sourceType.IsCastableFrom(Modifier.ModifierType.PreferredParameterType))
+ StaticInputViewModel = _dataModelUIService.GetStaticInputViewModel(Modifier.ModifierType.PreferredParameterType);
+ else
+ StaticInputViewModel = _dataModelUIService.GetStaticInputViewModel(sourceType);
+
+ if (StaticInputViewModel != null)
+ StaticInputViewModel.ValueUpdated += StaticInputViewModelOnValueUpdated;
}
// Modifier type
@@ -118,7 +132,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
// Parameter
if (DynamicSelectionViewModel != null)
- DynamicSelectionViewModel?.PopulateSelectedPropertyViewModel(Modifier.ParameterDataModel, Modifier.ParameterPropertyPath);
+ DynamicSelectionViewModel.PopulateSelectedPropertyViewModel(Modifier.ParameterDataModel, Modifier.ParameterPropertyPath);
else if (StaticInputViewModel != null)
StaticInputViewModel.Value = Modifier.ParameterStaticValue;
}
@@ -133,5 +147,14 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
Update();
}
+
+ public void Dispose()
+ {
+ if (DynamicSelectionViewModel != null)
+ {
+ DynamicSelectionViewModel.Dispose();
+ DynamicSelectionViewModel.PropertySelected -= ParameterSelectionViewModelOnPropertySelected;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml
index 779744f82..12554e038 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml
@@ -126,7 +126,7 @@
FontSize="12"
Padding="6 4"
Height="22"
- IsEnabled="{Binding IsDataBindingEnabled}"
+ IsEnabled="{Binding CanAddModifier}"
Command="{s:Action AddModifier}">
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs
index 0cee22ffa..3ee2cda64 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs
@@ -6,6 +6,7 @@ using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Input;
using Artemis.UI.Shared.Services;
+using Ninject.Planning.Targets;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
@@ -25,6 +26,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
private TProperty _testInputValue;
private TProperty _testResultValue;
private bool _updating;
+ private bool _canAddModifier;
public DataBindingViewModel(DataBindingRegistration registration,
IProfileEditorService profileEditorService,
@@ -51,8 +53,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
_isDataBindingEnabled = DataBinding != null;
- // Initialize async, no need to wait for it
- Execute.PostToUIThread(Initialize);
+ Initialize();
}
public DataBindingRegistration Registration { get; }
@@ -116,6 +117,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
}
}
+ public bool CanAddModifier
+ {
+ get => _canAddModifier;
+ private set => SetAndNotify(ref _canAddModifier, value);
+ }
+
public DataBinding DataBinding
{
get => _dataBinding;
@@ -169,7 +176,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
if (DataBinding == null)
return;
- var modifier = new DataBindingModifier(ProfileRightSideType.Dynamic);
+ var modifier = new DataBindingModifier(DataBinding, ProfileRightSideType.Dynamic);
DataBinding.AddModifier(modifier);
_profileEditorService.UpdateSelectedProfileElement();
@@ -190,6 +197,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
if (_updating)
return;
+ CanAddModifier = IsDataBindingEnabled && DataBinding.SourceDataModel != null;
+
if (DataBinding == null)
{
TargetSelectionViewModel.IsEnabled = false;
@@ -218,9 +227,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
if (_updating)
return;
- DataBinding.Mode = SelectedDataBindingMode;
- DataBinding.EasingTime = TimeSpan.FromMilliseconds(EasingTime);
- DataBinding.EasingFunction = SelectedEasingViewModel?.EasingFunction ?? Easings.Functions.Linear;
+ if (DataBinding != null)
+ {
+ DataBinding.Mode = SelectedDataBindingMode;
+ DataBinding.EasingTime = TimeSpan.FromMilliseconds(EasingTime);
+ DataBinding.EasingFunction = SelectedEasingViewModel?.EasingFunction ?? Easings.Functions.Linear;
+ }
_profileEditorService.UpdateSelectedProfileElement();
Update();
@@ -238,8 +250,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
var currentValue = TargetSelectionViewModel.SelectedPropertyViewModel?.GetCurrentValue();
if (currentValue == null)
currentValue = default(TProperty);
-
- TestInputValue = (TProperty) Convert.ChangeType(currentValue, typeof(TProperty));
+
+ TestInputValue = Registration.Converter.ConvertFromObject(currentValue);
if (DataBinding != null)
TestResultValue = DataBinding.GetValue(TestInputValue);
else
@@ -248,7 +260,10 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
private void UpdateModifierViewModels()
{
+ foreach (var dataBindingModifierViewModel in ModifierViewModels)
+ dataBindingModifierViewModel.Dispose();
ModifierViewModels.Clear();
+
if (DataBinding == null)
return;
@@ -269,6 +284,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
private void TargetSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
{
DataBinding.UpdateSource(e.DataModelVisualizationViewModel.DataModel, e.DataModelVisualizationViewModel.PropertyPath);
+ Update();
+
_profileEditorService.UpdateSelectedProfileElement();
}
@@ -276,8 +293,14 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
{
_profileEditorService.ProfilePreviewUpdated -= ProfileEditorServiceOnProfilePreviewUpdated;
TargetSelectionViewModel.PropertySelected -= TargetSelectionViewModelOnPropertySelected;
+ TargetSelectionViewModel.Dispose();
if (DataBinding != null)
DataBinding.ModifiersUpdated -= DataBindingOnModifiersUpdated;
+
+ foreach (var dataBindingModifierViewModel in ModifierViewModels)
+ dataBindingModifierViewModel.Dispose();
+ ModifierViewModels.Clear();
+
}
}
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyGroupViewModel.cs
index b2a0080bf..b5d6d3a09 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyGroupViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyGroupViewModel.cs
@@ -52,6 +52,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
public void Dispose()
{
+ TimelineGroupViewModel.Dispose();
LayerPropertyGroup.VisibilityChanged -= LayerPropertyGroupOnVisibilityChanged;
foreach (var child in Children)
{
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelineEasingViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelineEasingViewModel.cs
index 859643892..7f4489171 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelineEasingViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelineEasingViewModel.cs
@@ -3,10 +3,11 @@ using System.Windows;
using System.Windows.Media;
using Artemis.Core;
using Humanizer;
+using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
{
- public class TimelineEasingViewModel
+ public class TimelineEasingViewModel : PropertyChangedBase
{
private bool _isEasingModeSelected;
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelineGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelineGroupViewModel.cs
index 60122cc4a..ea75c170b 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelineGroupViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelineGroupViewModel.cs
@@ -7,7 +7,7 @@ using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
{
- public class TimelineGroupViewModel : IDisposable
+ public class TimelineGroupViewModel : PropertyChangedBase, IDisposable
{
private readonly IProfileEditorService _profileEditorService;
diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs
index 6eee624df..1502ac21e 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs
@@ -22,6 +22,8 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
{
_profileEditorService = profileEditorService;
_profileTreeVmFactory = profileTreeVmFactory;
+
+ CreateRootFolderViewModel();
}
public TreeItemViewModel SelectedTreeItem
@@ -94,17 +96,16 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
ActiveItem?.AddLayer();
}
- protected override void OnInitialActivate()
+ protected override void OnActivate()
{
Subscribe();
- CreateRootFolderViewModel();
- base.OnInitialActivate();
+ base.OnActivate();
}
- protected override void OnClose()
+ protected override void OnDeactivate()
{
Unsubscribe();
- base.OnClose();
+ base.OnDeactivate();
}
private void CreateRootFolderViewModel()
@@ -140,7 +141,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
{
if (parent == source)
return DragDropType.None;
- parent = (TreeItemViewModel) parent.Parent;
+ parent = parent.Parent as TreeItemViewModel;
}
switch (dropInfo.InsertPosition)
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileViewModel.cs
index 0c5b0f566..32bc7f957 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/Visualization/ProfileViewModel.cs
@@ -173,8 +173,10 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
.ToList();
}
- protected override void OnInitialActivate()
+ protected override void OnActivate()
{
+ ApplyActiveProfile();
+
OnlyShowSelectedShape = _settingsService.GetSetting("ProfileEditor.OnlyShowSelectedShape", true);
HighlightSelectedLayer = _settingsService.GetSetting("ProfileEditor.HighlightSelectedLayer", true);
@@ -184,10 +186,10 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
_profileEditorService.ProfileElementSelected += OnProfileElementSelected;
_profileEditorService.SelectedProfileElementUpdated += OnSelectedProfileElementUpdated;
- base.OnInitialActivate();
+ base.OnActivate();
}
- protected override void OnClose()
+ protected override void OnDeactivate()
{
HighlightSelectedLayer.SettingChanged -= HighlightSelectedLayerOnSettingChanged;
_surfaceService.ActiveSurfaceConfigurationSelected -= OnActiveSurfaceConfigurationSelected;
@@ -204,12 +206,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
canvasViewModel.Dispose();
CanvasViewModels.Clear();
- base.OnClose();
- }
-
- protected override void OnActivate()
- {
- ApplyActiveProfile();
+ base.OnDeactivate();
}
private void OnActiveSurfaceConfigurationSelected(object sender, SurfaceConfigurationEventArgs e)
diff --git a/src/Artemis.UI/Screens/RootViewModel.cs b/src/Artemis.UI/Screens/RootViewModel.cs
index 448a7d04b..0f551b77c 100644
--- a/src/Artemis.UI/Screens/RootViewModel.cs
+++ b/src/Artemis.UI/Screens/RootViewModel.cs
@@ -247,13 +247,14 @@ namespace Artemis.UI.Screens
_colorScheme.SettingChanged -= ColorSchemeOnSettingChanged;
_themeWatcher.ThemeChanged -= ThemeWatcherOnThemeChanged;
SidebarViewModel.PropertyChanged -= SidebarViewModelOnPropertyChanged;
+
+ base.OnDeactivate();
}
protected override void OnClose()
{
SidebarViewModel.Dispose();
-
-
+
// Lets force the GC to run after closing the window so it is obvious to users watching task manager
// that closing the UI will decrease the memory footprint of the application.
Task.Run(async () =>
@@ -263,6 +264,8 @@ namespace Artemis.UI.Screens
GC.WaitForPendingFinalizers();
GC.Collect();
});
+
+ base.OnClose();
}
#endregion