diff --git a/src/Artemis.Core/Artemis.Core.csproj.DotSettings b/src/Artemis.Core/Artemis.Core.csproj.DotSettings
index abb086d59..d0a878038 100644
--- a/src/Artemis.Core/Artemis.Core.csproj.DotSettings
+++ b/src/Artemis.Core/Artemis.Core.csproj.DotSettings
@@ -16,6 +16,7 @@
True
True
True
+ True
True
True
True
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
index f167832fe..9f26d5d28 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Linq.Expressions;
-using Artemis.Core.DataModelExpansions;
using Artemis.Storage.Entities.Profile.DataBindings;
namespace Artemis.Core
@@ -24,7 +21,7 @@ namespace Artemis.Core
ApplyRegistration(dataBindingRegistration);
Save();
- Initialize();
+ ApplyDataBindingMode();
}
internal DataBinding(LayerProperty layerProperty, DataBindingEntity entity)
@@ -33,8 +30,8 @@ namespace Artemis.Core
Entity = entity;
// Load will add children so be initialized before that
- Initialize();
Load();
+ ApplyDataBindingMode();
}
///
@@ -53,16 +50,9 @@ namespace Artemis.Core
public DataBindingConverter Converter { get; private set; }
///
- /// Gets the currently used instance of the data model that contains the source of the data binding
+ /// Gets the data binding mode
///
- public DataModel SourceDataModel { get; private set; }
-
- ///
- /// Gets the path of the source property in the
- ///
- public string SourcePropertyPath { get; private set; }
-
- public DataBindingMode Mode { get; set; }
+ public IDataBindingMode DataBindingMode { get; private set; }
///
/// Gets or sets the easing time of the data binding
@@ -74,15 +64,6 @@ namespace Artemis.Core
///
public Easings.Functions EasingFunction { get; set; }
- ///
- /// Gets a list of modifiers applied to this data binding
- ///
- public IReadOnlyList> Modifiers => _modifiers.AsReadOnly();
-
- ///
- /// Gets the compiled function that gets the current value of the data binding target
- ///
- public Func CompiledTargetAccessor { get; private set; }
internal DataBindingEntity Entity { get; }
@@ -122,72 +103,9 @@ namespace Artemis.Core
{
_disposed = true;
- DataModelStore.DataModelAdded -= DataModelStoreOnDataModelAdded;
- DataModelStore.DataModelRemoved -= DataModelStoreOnDataModelRemoved;
-
- foreach (var dataBindingModifier in Modifiers)
- dataBindingModifier.Dispose();
+ DataBindingMode?.Dispose();
}
- ///
- /// Adds a modifier to the data binding's collection
- ///
- public void AddModifier(DataBindingModifier modifier)
- {
- if (_disposed)
- throw new ObjectDisposedException("DataBinding");
-
- if (!_modifiers.Contains(modifier))
- {
- modifier.DataBinding = this;
- _modifiers.Add(modifier);
-
- OnModifiersUpdated();
- }
- }
-
- ///
- /// Removes a modifier from the data binding's collection
- ///
- public void RemoveModifier(DataBindingModifier modifier)
- {
- if (_disposed)
- throw new ObjectDisposedException("DataBinding");
-
- if (_modifiers.Contains(modifier))
- {
- modifier.DataBinding = null;
- _modifiers.Remove(modifier);
-
- OnModifiersUpdated();
- }
- }
-
- ///
- /// Updates the source of the data binding and re-compiles the expression
- ///
- /// The data model of the source
- /// The path pointing to the source inside the data model
- public void UpdateSource(DataModel dataModel, string path)
- {
- if (_disposed)
- throw new ObjectDisposedException("DataBinding");
-
- if (dataModel != null && path == null)
- throw new ArtemisCoreException("If a data model is provided, a path is also required");
- if (dataModel == null && path != null)
- throw new ArtemisCoreException("If path is provided, a data model is also required");
-
- if (dataModel != null)
- {
- if (!dataModel.ContainsPath(path))
- throw new ArtemisCoreException($"Data model of type {dataModel.GetType().Name} does not contain a property at path '{path}'");
- }
-
- SourceDataModel = dataModel;
- SourcePropertyPath = path;
- CreateExpression();
- }
///
/// Gets the current value of the data binding
@@ -199,15 +117,11 @@ namespace Artemis.Core
if (_disposed)
throw new ObjectDisposedException("DataBinding");
- if (CompiledTargetAccessor == null || Converter == null)
+ if (Converter == null || DataBindingMode == null)
return baseValue;
- var dataBindingValue = CompiledTargetAccessor(SourceDataModel);
- foreach (var dataBindingModifier in Modifiers)
- dataBindingValue = dataBindingModifier.Apply(dataBindingValue);
+ var value = DataBindingMode.GetValue(baseValue);
- 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;
@@ -228,28 +142,6 @@ namespace Artemis.Core
return Registration.PropertyExpression.ReturnType;
}
- ///
- /// Returns the type of the source property of this data binding
- ///
- public Type GetSourceType()
- {
- return SourceDataModel?.GetTypeAtPath(SourcePropertyPath);
- }
-
- private void Initialize()
- {
- DataModelStore.DataModelAdded += DataModelStoreOnDataModelAdded;
- DataModelStore.DataModelRemoved += DataModelStoreOnDataModelRemoved;
-
- // Source
- if (Entity.SourceDataModelGuid != null && SourceDataModel == null)
- {
- var dataModel = DataModelStore.Get(Entity.SourceDataModelGuid.Value)?.DataModel;
- if (dataModel != null && dataModel.ContainsPath(Entity.SourcePropertyPath))
- UpdateSource(dataModel, Entity.SourcePropertyPath);
- }
- }
-
private void ResetEasing(TProperty value)
{
_previousValue = GetInterpolatedValue();
@@ -284,25 +176,48 @@ namespace Artemis.Core
var easingAmount = _easingProgress.TotalSeconds / EasingTime.TotalSeconds;
return Converter.Interpolate(_previousValue, _currentValue, Easings.Interpolate(easingAmount, EasingFunction));
}
+
+ #region Mode management
- private void CreateExpression()
+ ///
+ /// Changes the data binding mode of the data binding to the specified
+ ///
+ public void ChangeDataBindingMode(DataBindingModeType dataBindingMode)
{
- var listType = SourceDataModel.GetListTypeInPath(SourcePropertyPath);
- if (listType != null)
- throw new ArtemisCoreException($"Cannot create a regular accessor at path {SourcePropertyPath} because the path contains a list");
+ switch (dataBindingMode)
+ {
+ case DataBindingModeType.Direct:
+ Entity.DataBindingMode = new DirectDataBindingEntity();
+ break;
+ case DataBindingModeType.Conditional:
+ Entity.DataBindingMode = new ConditionalDataBindingEntity();
+ break;
+ default:
+ Entity.DataBindingMode = null;
+ break;
+ }
- var parameter = Expression.Parameter(typeof(DataModel), "targetDataModel");
- var accessor = SourcePropertyPath.Split('.').Aggregate(
- Expression.Convert(parameter, SourceDataModel.GetType()), // Cast to the appropriate type
- Expression.Property
- );
-
- var returnValue = Expression.Convert(accessor, typeof(object));
-
- var lambda = Expression.Lambda>(returnValue, parameter);
- CompiledTargetAccessor = lambda.Compile();
+ ApplyDataBindingMode();
}
+ private void ApplyDataBindingMode()
+ {
+ DataBindingMode?.Dispose();
+ DataBindingMode = null;
+
+ switch (Entity.DataBindingMode)
+ {
+ case DirectDataBindingEntity directDataBindingEntity:
+ DataBindingMode = new DirectDataBinding(this, directDataBindingEntity);
+ break;
+ case ConditionalDataBindingEntity conditionalDataBindingEntity:
+ DataBindingMode = new ConditionalDataBinding(this, conditionalDataBindingEntity);
+ break;
+ }
+ }
+
+ #endregion
+
#region Storage
///
@@ -314,15 +229,10 @@ namespace Artemis.Core
var registration = LayerProperty.GetDataBindingRegistration(Entity.TargetExpression);
ApplyRegistration(registration);
- Mode = (DataBindingMode) Entity.DataBindingMode;
EasingTime = Entity.EasingTime;
EasingFunction = (Easings.Functions) Entity.EasingFunction;
- // Data model is done during Initialize
-
- // Modifiers
- foreach (var dataBindingModifierEntity in Entity.Modifiers)
- _modifiers.Add(new DataBindingModifier(this, dataBindingModifierEntity));
+ DataBindingMode?.Load();
}
///
@@ -336,54 +246,10 @@ namespace Artemis.Core
// General
Entity.TargetExpression = Registration.PropertyExpression.ToString();
- Entity.DataBindingMode = (int) Mode;
Entity.EasingTime = EasingTime;
Entity.EasingFunction = (int) EasingFunction;
- // Data model
- if (SourceDataModel != null)
- {
- Entity.SourceDataModelGuid = SourceDataModel.PluginInfo.Guid;
- Entity.SourcePropertyPath = SourcePropertyPath;
- }
-
- // Modifiers
- Entity.Modifiers.Clear();
- foreach (var dataBindingModifier in Modifiers)
- dataBindingModifier.Save();
- }
-
- #endregion
-
- #region Event handlers
-
- private void DataModelStoreOnDataModelAdded(object sender, DataModelStoreEvent e)
- {
- var dataModel = e.Registration.DataModel;
- if (dataModel.PluginInfo.Guid == Entity.SourceDataModelGuid && dataModel.ContainsPath(Entity.SourcePropertyPath))
- UpdateSource(dataModel, Entity.SourcePropertyPath);
- }
-
- private void DataModelStoreOnDataModelRemoved(object sender, DataModelStoreEvent e)
- {
- if (SourceDataModel != e.Registration.DataModel)
- return;
- SourceDataModel = null;
- CompiledTargetAccessor = null;
- }
-
- #endregion
-
- #region Events
-
- ///
- /// Occurs when a modifier is added or removed
- ///
- public event EventHandler ModifiersUpdated;
-
- protected virtual void OnModifiersUpdated()
- {
- ModifiersUpdated?.Invoke(this, EventArgs.Empty);
+ DataBindingMode?.Save();
}
#endregion
@@ -392,16 +258,21 @@ namespace Artemis.Core
///
/// A mode that determines how the data binding is applied to the layer property
///
- public enum DataBindingMode
+ public enum DataBindingModeType
{
+ ///
+ /// Disables the data binding
+ ///
+ None,
+
///
/// Replaces the layer property value with the data binding value
///
- Replace,
+ Direct,
///
- /// Adds the data binding value to the layer property value
+ /// Replaces the layer property value with the data binding value
///
- Add
+ Conditional,
}
}
\ 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 5ad50d0ee..d8b2c117d 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/DataBindingModifier.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/DataBindingModifier.cs
@@ -10,49 +10,40 @@ namespace Artemis.Core
///
public class DataBindingModifier : IDataBindingModifier
{
- private DataBinding _dataBinding;
private bool _disposed;
///
/// Creates a new instance of the class
///
- /// The data binding the modifier is to be applied to
+ /// The direct 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(DataBinding dataBinding, ProfileRightSideType parameterType)
+ public DataBindingModifier(DirectDataBinding directDataBinding, ProfileRightSideType parameterType)
{
- _dataBinding = dataBinding ?? throw new ArgumentNullException(nameof(dataBinding));
+ DirectDataBinding = directDataBinding ?? throw new ArgumentNullException(nameof(directDataBinding));
ParameterType = parameterType;
Entity = new DataBindingModifierEntity();
Initialize();
Save();
}
- internal DataBindingModifier(DataBinding dataBinding, DataBindingModifierEntity entity)
+ internal DataBindingModifier(DirectDataBinding directDataBinding, DataBindingModifierEntity entity)
{
- _dataBinding = dataBinding;
+ DirectDataBinding = directDataBinding ?? throw new ArgumentNullException(nameof(directDataBinding));
Entity = entity;
Load();
Initialize();
}
- ///
- /// Gets the data binding this modifier is applied to
- ///
- public DataBinding DataBinding
- {
- get => _dataBinding;
- internal set
- {
- _dataBinding = value;
- CreateExpression();
- }
- }
-
///
/// Gets the type of modifier that is being applied
///
public DataBindingModifierType ModifierType { get; private set; }
+ ///
+ /// Gets the direct data binding this modifier is applied to
+ ///
+ public DirectDataBinding DirectDataBinding { get; }
+
///
/// Gets the type of the parameter, can either be dynamic (based on a data model value) or static
///
@@ -93,8 +84,8 @@ namespace Artemis.Core
if (_disposed)
throw new ObjectDisposedException("DataBindingModifier");
- if (!DataBinding.Entity.Modifiers.Contains(Entity))
- DataBinding.Entity.Modifiers.Add(Entity);
+ if (!DirectDataBinding.Entity.Modifiers.Contains(Entity))
+ DirectDataBinding.Entity.Modifiers.Add(Entity);
// Modifier
if (ModifierType != null)
@@ -177,7 +168,7 @@ namespace Artemis.Core
return;
}
- var targetType = DataBinding.GetTargetType();
+ var targetType = DirectDataBinding.DataBinding.GetTargetType();
if (!modifierType.SupportsType(targetType))
{
throw new ArtemisCoreException($"Cannot apply modifier type {modifierType.GetType().Name} to this modifier because " +
@@ -229,7 +220,7 @@ namespace Artemis.Core
ParameterDataModel = null;
ParameterPropertyPath = null;
- var targetType = DataBinding.GetTargetType();
+ var targetType = DirectDataBinding.DataBinding.GetTargetType();
// If not null ensure the types match and if not, convert it
if (staticValue != null && staticValue.GetType() == targetType)
@@ -271,7 +262,7 @@ namespace Artemis.Core
else if (ParameterType == ProfileRightSideType.Static && Entity.ParameterStaticValue != null && ParameterStaticValue == null)
{
// Use the target type so JSON.NET has a better idea what to do
- var targetType = DataBinding.GetTargetType();
+ var targetType = DirectDataBinding.DataBinding.GetTargetType();
object staticValue;
try
@@ -293,7 +284,7 @@ namespace Artemis.Core
{
CompiledParameterAccessor = null;
- if (ModifierType == null || DataBinding == null)
+ if (ModifierType == null)
return;
if (ParameterType == ProfileRightSideType.Dynamic && ModifierType.SupportsParameter)
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/ConditionalDataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/ConditionalDataBinding.cs
new file mode 100644
index 000000000..9d844bd9b
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Modes/ConditionalDataBinding.cs
@@ -0,0 +1,50 @@
+using Artemis.Storage.Entities.Profile.DataBindings;
+
+namespace Artemis.Core
+{
+ ///
+ /// Represents a data binding mode that applies a value depending on conditions
+ ///
+ public class ConditionalDataBinding : IDataBindingMode
+ {
+ internal ConditionalDataBinding(DataBinding dataBinding, ConditionalDataBindingEntity entity)
+ {
+ DataBinding = dataBinding;
+ Entity = entity;
+ }
+
+ ///
+ public DataBinding DataBinding { get; }
+
+ ///
+ public TProperty GetValue(TProperty baseValue)
+ {
+ return default;
+ }
+
+ internal ConditionalDataBindingEntity Entity { get; }
+
+ #region Storage
+
+ ///
+ public void Load()
+ {
+ }
+
+ ///
+ public void Save()
+ {
+ }
+
+ #endregion
+
+ #region IDisposable
+
+ ///
+ public void Dispose()
+ {
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/DirectDataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/DirectDataBinding.cs
new file mode 100644
index 000000000..e31296d73
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Modes/DirectDataBinding.cs
@@ -0,0 +1,255 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using Artemis.Core.DataModelExpansions;
+using Artemis.Storage.Entities.Profile.DataBindings;
+
+namespace Artemis.Core
+{
+ ///
+ /// Represents a data binding mode that directly applies a data model value to a data binding
+ ///
+ public class DirectDataBinding : IDataBindingMode
+ {
+ private readonly List> _modifiers = new List>();
+ private bool _disposed;
+
+ internal DirectDataBinding(DataBinding dataBinding, DirectDataBindingEntity entity)
+ {
+ DataBinding = dataBinding;
+ Entity = entity;
+
+ Initialize();
+ Load();
+ }
+
+ ///
+ public DataBinding DataBinding { get; }
+
+ internal DirectDataBindingEntity Entity { get; }
+
+ ///
+ /// Gets the currently used instance of the data model that contains the source of the data binding
+ ///
+ public DataModel SourceDataModel { get; private set; }
+
+ ///
+ /// Gets the path of the source property in the
+ ///
+ public string SourcePropertyPath { get; private set; }
+
+ ///
+ /// Gets a list of modifiers applied to this data binding
+ ///
+ public IReadOnlyList> Modifiers => _modifiers.AsReadOnly();
+
+ ///
+ /// Gets the compiled function that gets the current value of the data binding target
+ ///
+ public Func CompiledTargetAccessor { get; private set; }
+
+ ///
+ public TProperty GetValue(TProperty baseValue)
+ {
+ if (_disposed)
+ throw new ObjectDisposedException("DataBinding");
+
+ if (CompiledTargetAccessor == null)
+ return baseValue;
+
+ var dataBindingValue = CompiledTargetAccessor(SourceDataModel);
+ foreach (var dataBindingModifier in Modifiers)
+ dataBindingValue = dataBindingModifier.Apply(dataBindingValue);
+
+ return DataBinding.Converter.ConvertFromObject(dataBindingValue);
+ }
+
+ #region IDisposable
+
+ ///
+ public void Dispose()
+ {
+ _disposed = true;
+
+ foreach (var dataBindingModifier in Modifiers)
+ dataBindingModifier.Dispose();
+ }
+
+ #endregion
+
+ #region Storage
+
+ ///
+ public void Load()
+ {
+ // Data model is done during Initialize
+
+ // Modifiers
+ foreach (var dataBindingModifierEntity in Entity.Modifiers)
+ _modifiers.Add(new DataBindingModifier(this, dataBindingModifierEntity));
+ }
+
+ ///
+ public void Save()
+ {
+ // Data model
+ if (SourceDataModel != null)
+ {
+ Entity.SourceDataModelGuid = SourceDataModel.PluginInfo.Guid;
+ Entity.SourcePropertyPath = SourcePropertyPath;
+ }
+
+ // Modifiers
+ Entity.Modifiers.Clear();
+ foreach (var dataBindingModifier in Modifiers)
+ dataBindingModifier.Save();
+ }
+
+ #endregion
+
+ #region Initialization
+
+ private void Initialize()
+ {
+ DataModelStore.DataModelAdded += DataModelStoreOnDataModelAdded;
+ DataModelStore.DataModelRemoved += DataModelStoreOnDataModelRemoved;
+
+ // Source
+ if (Entity.SourceDataModelGuid != null && SourceDataModel == null)
+ {
+ var dataModel = DataModelStore.Get(Entity.SourceDataModelGuid.Value)?.DataModel;
+ if (dataModel != null && dataModel.ContainsPath(Entity.SourcePropertyPath))
+ UpdateSource(dataModel, Entity.SourcePropertyPath);
+ }
+ }
+
+ private void CreateExpression()
+ {
+ var listType = SourceDataModel.GetListTypeInPath(SourcePropertyPath);
+ if (listType != null)
+ throw new ArtemisCoreException($"Cannot create a regular accessor at path {SourcePropertyPath} because the path contains a list");
+
+ var parameter = Expression.Parameter(typeof(DataModel), "targetDataModel");
+ var accessor = SourcePropertyPath.Split('.').Aggregate(
+ Expression.Convert(parameter, SourceDataModel.GetType()), // Cast to the appropriate type
+ Expression.Property
+ );
+
+ var returnValue = Expression.Convert(accessor, typeof(object));
+
+ var lambda = Expression.Lambda>(returnValue, parameter);
+ CompiledTargetAccessor = lambda.Compile();
+ }
+
+ #endregion
+
+ #region Source
+
+ ///
+ /// Returns the type of the source property of this data binding
+ ///
+ public Type GetSourceType()
+ {
+ return SourceDataModel?.GetTypeAtPath(SourcePropertyPath);
+ }
+
+
+ ///
+ /// Updates the source of the data binding and re-compiles the expression
+ ///
+ /// The data model of the source
+ /// The path pointing to the source inside the data model
+ public void UpdateSource(DataModel dataModel, string path)
+ {
+ if (_disposed)
+ throw new ObjectDisposedException("DataBinding");
+
+ if (dataModel != null && path == null)
+ throw new ArtemisCoreException("If a data model is provided, a path is also required");
+ if (dataModel == null && path != null)
+ throw new ArtemisCoreException("If path is provided, a data model is also required");
+
+ if (dataModel != null)
+ {
+ if (!dataModel.ContainsPath(path))
+ throw new ArtemisCoreException($"Data model of type {dataModel.GetType().Name} does not contain a property at path '{path}'");
+ }
+
+ SourceDataModel = dataModel;
+ SourcePropertyPath = path;
+ CreateExpression();
+ }
+
+ #endregion
+
+ #region Modifiers
+
+ ///
+ /// Adds a modifier to the data binding's collection
+ ///
+ public DataBindingModifier AddModifier(ProfileRightSideType type)
+ {
+ if (_disposed)
+ throw new ObjectDisposedException("DataBinding");
+
+ var modifier = new DataBindingModifier(this, type);
+ _modifiers.Add(modifier);
+ OnModifiersUpdated();
+
+ return modifier;
+ }
+
+ ///
+ /// Removes a modifier from the data binding's collection and disposes it
+ ///
+ public void RemoveModifier(DataBindingModifier modifier)
+ {
+ if (_disposed)
+ throw new ObjectDisposedException("DataBinding");
+
+ if (_modifiers.Contains(modifier))
+ {
+ _modifiers.Remove(modifier);
+ modifier.Dispose();
+
+ OnModifiersUpdated();
+ }
+ }
+
+ #endregion
+
+ #region Event handlers
+
+ private void DataModelStoreOnDataModelAdded(object sender, DataModelStoreEvent e)
+ {
+ var dataModel = e.Registration.DataModel;
+ if (dataModel.PluginInfo.Guid == Entity.SourceDataModelGuid && dataModel.ContainsPath(Entity.SourcePropertyPath))
+ UpdateSource(dataModel, Entity.SourcePropertyPath);
+ }
+
+ private void DataModelStoreOnDataModelRemoved(object sender, DataModelStoreEvent e)
+ {
+ if (SourceDataModel != e.Registration.DataModel)
+ return;
+ SourceDataModel = null;
+ CompiledTargetAccessor = null;
+ }
+
+ #endregion
+
+ #region Events
+
+ ///
+ /// Occurs when a modifier is added or removed
+ ///
+ public event EventHandler ModifiersUpdated;
+
+ protected virtual void OnModifiersUpdated()
+ {
+ ModifiersUpdated?.Invoke(this, EventArgs.Empty);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingMode.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingMode.cs
new file mode 100644
index 000000000..d9cea1a86
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingMode.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace Artemis.Core
+{
+ ///
+ /// Represents a data binding mode
+ ///
+ public interface IDataBindingMode : IStorageModel, IDisposable
+ {
+ ///
+ /// Gets the data binding this mode is applied to
+ ///
+ DataBinding DataBinding { get; }
+
+ ///
+ /// Gets the current value of the data binding
+ ///
+ /// The base value of the property the data binding is applied to
+ ///
+ TProperty GetValue(TProperty baseValue);
+ }
+}
diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs
index 97f705548..fd3f22521 100644
--- a/src/Artemis.Core/Models/Profile/Layer.cs
+++ b/src/Artemis.Core/Models/Profile/Layer.cs
@@ -738,7 +738,7 @@ namespace Artemis.Core
private void LayerBrushStoreOnLayerBrushAdded(object sender, LayerBrushStoreEvent e)
{
- if (LayerBrush != null)
+ if (LayerBrush != null || General.BrushReference?.CurrentValue == null)
return;
var current = General.BrushReference.CurrentValue;
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKSizeLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKSizeLayerProperty.cs
index b8f54a741..f23a5ac19 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKSizeLayerProperty.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKSizeLayerProperty.cs
@@ -7,8 +7,8 @@ namespace Artemis.Core
{
internal SKSizeLayerProperty()
{
- RegisterDataBindingProperty(size => size.Width, new FloatDataBindingConverter());
RegisterDataBindingProperty(size => size.Height, new FloatDataBindingConverter());
+ RegisterDataBindingProperty(size => size.Width, new FloatDataBindingConverter());
}
///
diff --git a/src/Artemis.Storage/Entities/Profile/DataBindings/ConditionalDataBindingEntity.cs b/src/Artemis.Storage/Entities/Profile/DataBindings/ConditionalDataBindingEntity.cs
new file mode 100644
index 000000000..02a8768e3
--- /dev/null
+++ b/src/Artemis.Storage/Entities/Profile/DataBindings/ConditionalDataBindingEntity.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+
+namespace Artemis.Storage.Entities.Profile.DataBindings
+{
+ public class ConditionalDataBindingEntity : IDataBindingModeEntity
+ {
+ public ConditionalDataBindingEntity()
+ {
+ Values = new List();
+ }
+
+ public List Values { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingConditionValueEntity.cs b/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingConditionValueEntity.cs
new file mode 100644
index 000000000..17bace120
--- /dev/null
+++ b/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingConditionValueEntity.cs
@@ -0,0 +1,10 @@
+using Artemis.Storage.Entities.Profile.Conditions;
+
+namespace Artemis.Storage.Entities.Profile.DataBindings
+{
+ public class DataBindingConditionValueEntity
+ {
+ public string Value { get; set; }
+ public DisplayConditionGroupEntity RootGroup { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingEntity.cs b/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingEntity.cs
index 14011e683..0a0dc030c 100644
--- a/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingEntity.cs
+++ b/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingEntity.cs
@@ -1,23 +1,13 @@
using System;
-using System.Collections.Generic;
namespace Artemis.Storage.Entities.Profile.DataBindings
{
public class DataBindingEntity
{
- public DataBindingEntity()
- {
- Modifiers = new List();
- }
-
public string TargetExpression { get; set; }
- public Guid? SourceDataModelGuid { get; set; }
- public string SourcePropertyPath { get; set; }
- public int DataBindingMode { get; set; }
public TimeSpan EasingTime { get; set; }
public int EasingFunction { get; set; }
- public List Modifiers { get; set; }
-
+ public IDataBindingModeEntity DataBindingMode { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Storage/Entities/Profile/DataBindings/DirectDataBindingEntity.cs b/src/Artemis.Storage/Entities/Profile/DataBindings/DirectDataBindingEntity.cs
new file mode 100644
index 000000000..ce1fc189e
--- /dev/null
+++ b/src/Artemis.Storage/Entities/Profile/DataBindings/DirectDataBindingEntity.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+
+namespace Artemis.Storage.Entities.Profile.DataBindings
+{
+ public class DirectDataBindingEntity : IDataBindingModeEntity
+ {
+ public DirectDataBindingEntity()
+ {
+ Modifiers = new List();
+ }
+
+ public Guid? SourceDataModelGuid { get; set; }
+ public string SourcePropertyPath { get; set; }
+
+ public List Modifiers { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Storage/Entities/Profile/DataBindings/IDataBindingModeEntity.cs b/src/Artemis.Storage/Entities/Profile/DataBindings/IDataBindingModeEntity.cs
new file mode 100644
index 000000000..d1d189588
--- /dev/null
+++ b/src/Artemis.Storage/Entities/Profile/DataBindings/IDataBindingModeEntity.cs
@@ -0,0 +1,6 @@
+namespace Artemis.Storage.Entities.Profile.DataBindings
+{
+ public interface IDataBindingModeEntity
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Storage/Migrations/M4ProfileSegments.cs b/src/Artemis.Storage/Migrations/M4ProfileSegments.cs
index 144d77e9b..b8d07325e 100644
--- a/src/Artemis.Storage/Migrations/M4ProfileSegments.cs
+++ b/src/Artemis.Storage/Migrations/M4ProfileSegments.cs
@@ -1,8 +1,8 @@
-using System;
-using System.Linq;
-using Artemis.Storage.Entities.Profile;
+using Artemis.Storage.Entities.Profile;
using Artemis.Storage.Migrations.Interfaces;
using LiteDB;
+using System;
+using System.Linq;
namespace Artemis.Storage.Migrations
{
diff --git a/src/Artemis.Storage/Migrations/M5DataBindingTypes.cs b/src/Artemis.Storage/Migrations/M5DataBindingTypes.cs
new file mode 100644
index 000000000..daede9a17
--- /dev/null
+++ b/src/Artemis.Storage/Migrations/M5DataBindingTypes.cs
@@ -0,0 +1,31 @@
+using Artemis.Storage.Migrations.Interfaces;
+using LiteDB;
+
+namespace Artemis.Storage.Migrations
+{
+ public class M5DataBindingTypes : IStorageMigration
+ {
+ public int UserVersion => 5;
+
+ public void Apply(LiteRepository repository)
+ {
+ var collection = repository.Database.GetCollection("ProfileEntity");
+ foreach (var bsonDocument in collection.FindAll())
+ {
+ foreach (var bsonLayer in bsonDocument["Layers"].AsArray)
+ {
+ foreach (var bsonPropertyEntity in bsonLayer["PropertyEntities"].AsArray)
+ bsonPropertyEntity["DataBindingEntities"].AsArray.Clear();
+ }
+
+ foreach (var bsonLayer in bsonDocument["Folders"].AsArray)
+ {
+ foreach (var bsonPropertyEntity in bsonLayer["PropertyEntities"].AsArray)
+ bsonPropertyEntity["DataBindingEntities"].AsArray.Clear();
+ }
+
+ collection.Update(bsonDocument);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
index cd50678b0..8290e0002 100644
--- a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
+++ b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
@@ -6,6 +6,8 @@ using Artemis.UI.Screens.ProfileEditor;
using Artemis.UI.Screens.ProfileEditor.DisplayConditions;
using Artemis.UI.Screens.ProfileEditor.LayerProperties;
using Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings;
+using Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.ConditionalDataBinding;
+using Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding;
using Artemis.UI.Screens.ProfileEditor.LayerProperties.LayerEffects;
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline;
using Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree;
@@ -87,6 +89,8 @@ namespace Artemis.UI.Ninject.Factories
{
IDataBindingViewModel DataBindingViewModel(IDataBindingRegistration registration);
DataBindingModifierViewModel DataBindingModifierViewModel(DataBindingModifier modifier);
+ DirectDataBindingModeViewModel DirectDataBindingModeViewModel(DirectDataBinding directDataBinding);
+ ConditionalDataBindingModeViewModel ConditionalDataBindingModeViewModel(ConditionalDataBinding conditionalDataBinding);
}
public interface IPropertyVmFactory
diff --git a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsView.xaml b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsView.xaml
index 14f88f21f..838d58ddf 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsView.xaml
@@ -31,6 +31,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Click the plus icon to start using display conditions!
+
+
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/ConditionalDataBindingModeView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/ConditionalDataBindingModeView.xaml
new file mode 100644
index 000000000..461452e5f
--- /dev/null
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/ConditionalDataBindingModeView.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+ Conditional data bindings not yet implemented
+
+
+ This is where you'd provide values and their conditions.. :>
+
+
+
+
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/ConditionalDataBindingModeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/ConditionalDataBindingModeViewModel.cs
new file mode 100644
index 000000000..9ef950be5
--- /dev/null
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/ConditionalDataBindingModeViewModel.cs
@@ -0,0 +1,28 @@
+using Artemis.Core;
+using Stylet;
+
+namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.ConditionalDataBinding
+{
+ public class ConditionalDataBindingModeViewModel : Screen, IDataBindingModeViewModel
+ {
+ public ConditionalDataBindingModeViewModel(ConditionalDataBinding conditionalDataBinding)
+ {
+ ConditionalDataBinding = conditionalDataBinding;
+ }
+
+ public ConditionalDataBinding ConditionalDataBinding { get; }
+
+ public void Dispose()
+ {
+ }
+
+ public void Update()
+ {
+ }
+
+ public object GetTestValue()
+ {
+ return null;
+ }
+ }
+}
\ 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 12554e038..fc0637bbf 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml
@@ -17,152 +17,112 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+ SelectedValue="{Binding SelectedDataBindingMode}"
+ ItemsSource="{Binding DataBindingModes}"
+ SelectedValuePath="Value"
+ DisplayMemberPath="Description" >
+
-
-
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Test result
-
-
-
-
-
-
-
-
-
-
-
- Input
-
-
- Output
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Enable data binding
-
-
-
-
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+ Test result
+
+
+
+
+
+
+
+
+
+
+
+ Input
+
+
+ Output
+
+
+
+
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs
index 3ee2cda64..34c1c4c3a 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs
@@ -4,38 +4,32 @@ using Artemis.Core;
using Artemis.UI.Ninject.Factories;
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
{
- public class DataBindingViewModel : Screen, IDataBindingViewModel
+ public class DataBindingViewModel : Conductor, IDataBindingViewModel
{
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
- private readonly IDataModelUIService _dataModelUIService;
private readonly IProfileEditorService _profileEditorService;
private DataBinding _dataBinding;
private int _easingTime;
- private bool _isDataBindingEnabled;
private bool _isEasingTimeEnabled;
- private DataBindingMode _selectedDataBindingMode;
+ private DataBindingModeType _selectedDataBindingMode;
private TimelineEasingViewModel _selectedEasingViewModel;
- private DataModelDynamicViewModel _targetSelectionViewModel;
+
private TProperty _testInputValue;
private TProperty _testResultValue;
private bool _updating;
- private bool _canAddModifier;
+ private bool _isDataBindingEnabled;
public DataBindingViewModel(DataBindingRegistration registration,
IProfileEditorService profileEditorService,
- IDataModelUIService dataModelUIService,
IDataBindingsVmFactory dataBindingsVmFactory)
{
Registration = registration;
_profileEditorService = profileEditorService;
- _dataModelUIService = dataModelUIService;
_dataBindingsVmFactory = dataBindingsVmFactory;
if (Registration.Member != null)
@@ -43,15 +37,10 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
else
DisplayName = Registration.LayerProperty.PropertyDescription.Name.ToUpper();
- DataBindingModes = new BindableCollection(EnumUtilities.GetAllValuesAndDescriptions(typeof(DataBindingMode)));
+ DataBindingModes = new BindableCollection(EnumUtilities.GetAllValuesAndDescriptions(typeof(DataBindingModeType)));
EasingViewModels = new BindableCollection();
- ModifierViewModels = new BindableCollection>();
DataBinding = Registration.DataBinding;
- if (DataBinding != null)
- DataBinding.ModifiersUpdated += DataBindingOnModifiersUpdated;
-
- _isDataBindingEnabled = DataBinding != null;
Initialize();
}
@@ -60,12 +49,21 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
public BindableCollection DataBindingModes { get; }
public BindableCollection EasingViewModels { get; }
- public BindableCollection> ModifierViewModels { get; }
- public DataBindingMode SelectedDataBindingMode
+ public DataBindingModeType SelectedDataBindingMode
{
get => _selectedDataBindingMode;
- set => SetAndNotify(ref _selectedDataBindingMode, value);
+ set
+ {
+ if (!SetAndNotify(ref _selectedDataBindingMode, value)) return;
+ ApplyDataBindingMode();
+ }
+ }
+
+ public bool IsDataBindingEnabled
+ {
+ get => _isDataBindingEnabled;
+ set => SetAndNotify(ref _isDataBindingEnabled, value);
}
public TimelineEasingViewModel SelectedEasingViewModel
@@ -98,39 +96,10 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
}
}
- public DataModelDynamicViewModel TargetSelectionViewModel
- {
- get => _targetSelectionViewModel;
- private set => SetAndNotify(ref _targetSelectionViewModel, value);
- }
-
- public bool IsDataBindingEnabled
- {
- get => _isDataBindingEnabled;
- set
- {
- if (!SetAndNotify(ref _isDataBindingEnabled, value)) return;
- if (value)
- EnableDataBinding();
- else
- RemoveDataBinding();
- }
- }
-
- public bool CanAddModifier
- {
- get => _canAddModifier;
- private set => SetAndNotify(ref _canAddModifier, value);
- }
-
public DataBinding DataBinding
{
get => _dataBinding;
- set
- {
- if (!SetAndNotify(ref _dataBinding, value)) return;
- UpdateModifierViewModels();
- }
+ set => SetAndNotify(ref _dataBinding, value);
}
public TProperty TestInputValue
@@ -145,79 +114,70 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
set => SetAndNotify(ref _testResultValue, value);
}
- public void EnableDataBinding()
+ public void Dispose()
{
- if (DataBinding != null)
- return;
-
- DataBinding = Registration.LayerProperty.EnableDataBinding(Registration);
- DataBinding.ModifiersUpdated += DataBindingOnModifiersUpdated;
- Update();
-
- _profileEditorService.UpdateSelectedProfileElement();
- }
-
- public void RemoveDataBinding()
- {
- if (DataBinding == null)
- return;
-
- var toDisable = DataBinding;
- DataBinding = null;
- Registration.LayerProperty.DisableDataBinding(toDisable);
- toDisable.ModifiersUpdated -= DataBindingOnModifiersUpdated;
- Update();
-
- _profileEditorService.UpdateSelectedProfileElement();
- }
-
- public void AddModifier()
- {
- if (DataBinding == null)
- return;
-
- var modifier = new DataBindingModifier(DataBinding, ProfileRightSideType.Dynamic);
- DataBinding.AddModifier(modifier);
-
- _profileEditorService.UpdateSelectedProfileElement();
+ _profileEditorService.ProfilePreviewUpdated -= ProfileEditorServiceOnProfilePreviewUpdated;
}
private void Initialize()
{
EasingViewModels.AddRange(Enum.GetValues(typeof(Easings.Functions)).Cast().Select(v => new TimelineEasingViewModel(v, false)));
- TargetSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
- TargetSelectionViewModel.PropertySelected += TargetSelectionViewModelOnPropertySelected;
_profileEditorService.ProfilePreviewUpdated += ProfileEditorServiceOnProfilePreviewUpdated;
+ CreateDataBindingModeModeViewModel();
Update();
}
+ private void CreateDataBindingModeModeViewModel()
+ {
+ if (DataBinding?.DataBindingMode == null)
+ {
+ ActiveItem = null;
+ return;
+ }
+
+ switch (DataBinding.DataBindingMode)
+ {
+ case DirectDataBinding directDataBinding:
+ ActiveItem = _dataBindingsVmFactory.DirectDataBindingModeViewModel(directDataBinding);
+ break;
+ case ConditionalDataBinding conditionalDataBinding:
+ ActiveItem = _dataBindingsVmFactory.ConditionalDataBindingModeViewModel(conditionalDataBinding);
+ break;
+ }
+ }
+
private void Update()
{
if (_updating)
return;
- CanAddModifier = IsDataBindingEnabled && DataBinding.SourceDataModel != null;
-
if (DataBinding == null)
{
- TargetSelectionViewModel.IsEnabled = false;
IsEasingTimeEnabled = false;
return;
}
_updating = true;
- SelectedDataBindingMode = DataBinding.Mode;
+ IsDataBindingEnabled = ActiveItem != null;
EasingTime = (int) DataBinding.EasingTime.TotalMilliseconds;
SelectedEasingViewModel = EasingViewModels.First(vm => vm.EasingFunction == DataBinding.EasingFunction);
IsEasingTimeEnabled = EasingTime > 0;
+ switch (DataBinding.DataBindingMode)
+ {
+ case DirectDataBinding _:
+ SelectedDataBindingMode = DataBindingModeType.Direct;
+ break;
+ case ConditionalDataBinding _:
+ SelectedDataBindingMode = DataBindingModeType.Conditional;
+ break;
+ default:
+ SelectedDataBindingMode = DataBindingModeType.None;
+ break;
+ }
- TargetSelectionViewModel.IsEnabled = true;
- TargetSelectionViewModel.PopulateSelectedPropertyViewModel(DataBinding.SourceDataModel, DataBinding.SourcePropertyPath);
- TargetSelectionViewModel.FilterTypes = new[] {DataBinding.GetTargetType()};
-
- UpdateModifierViewModels();
+ ActiveItem?.Update();
_updating = false;
}
@@ -229,7 +189,6 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
if (DataBinding != null)
{
- DataBinding.Mode = SelectedDataBindingMode;
DataBinding.EasingTime = TimeSpan.FromMilliseconds(EasingTime);
DataBinding.EasingFunction = SelectedEasingViewModel?.EasingFunction ?? Easings.Functions.Linear;
}
@@ -238,6 +197,27 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
Update();
}
+ private void ApplyDataBindingMode()
+ {
+ if (_updating)
+ return;
+
+ if (DataBinding != null && SelectedDataBindingMode == DataBindingModeType.None)
+ {
+ RemoveDataBinding();
+ CreateDataBindingModeModeViewModel();
+ return;
+ }
+
+ if (DataBinding == null && SelectedDataBindingMode != DataBindingModeType.None)
+ EnableDataBinding();
+
+ DataBinding.ChangeDataBindingMode(SelectedDataBindingMode);
+ CreateDataBindingModeModeViewModel();
+
+ _profileEditorService.UpdateSelectedProfileElement();
+ }
+
private void UpdateTestResult()
{
if (DataBinding == null)
@@ -247,10 +227,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
return;
}
- var currentValue = TargetSelectionViewModel.SelectedPropertyViewModel?.GetCurrentValue();
- if (currentValue == null)
- currentValue = default(TProperty);
-
+ var currentValue = ActiveItem?.GetTestValue() ?? default(TProperty);
+
TestInputValue = Registration.Converter.ConvertFromObject(currentValue);
if (DataBinding != null)
TestResultValue = DataBinding.GetValue(TestInputValue);
@@ -258,49 +236,31 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
TestInputValue = default;
}
- private void UpdateModifierViewModels()
+ private void EnableDataBinding()
{
- foreach (var dataBindingModifierViewModel in ModifierViewModels)
- dataBindingModifierViewModel.Dispose();
- ModifierViewModels.Clear();
+ if (DataBinding != null)
+ return;
+ DataBinding = Registration.LayerProperty.EnableDataBinding(Registration);
+ _profileEditorService.UpdateSelectedProfileElement();
+ }
+
+ private void RemoveDataBinding()
+ {
if (DataBinding == null)
return;
- foreach (var dataBindingModifier in DataBinding.Modifiers)
- ModifierViewModels.Add(_dataBindingsVmFactory.DataBindingModifierViewModel(dataBindingModifier));
- }
-
- private void ProfileEditorServiceOnProfilePreviewUpdated(object sender, EventArgs e)
- {
- UpdateTestResult();
- }
-
- private void DataBindingOnModifiersUpdated(object sender, EventArgs e)
- {
- UpdateModifierViewModels();
- }
-
- private void TargetSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
- {
- DataBinding.UpdateSource(e.DataModelVisualizationViewModel.DataModel, e.DataModelVisualizationViewModel.PropertyPath);
+ var toDisable = DataBinding;
+ DataBinding = null;
+ Registration.LayerProperty.DisableDataBinding(toDisable);
Update();
_profileEditorService.UpdateSelectedProfileElement();
}
- public void Dispose()
+ private void ProfileEditorServiceOnProfilePreviewUpdated(object sender, EventArgs e)
{
- _profileEditorService.ProfilePreviewUpdated -= ProfileEditorServiceOnProfilePreviewUpdated;
- TargetSelectionViewModel.PropertySelected -= TargetSelectionViewModelOnPropertySelected;
- TargetSelectionViewModel.Dispose();
- if (DataBinding != null)
- DataBinding.ModifiersUpdated -= DataBindingOnModifiersUpdated;
-
- foreach (var dataBindingModifierViewModel in ModifierViewModels)
- dataBindingModifierViewModel.Dispose();
- ModifierViewModels.Clear();
-
+ UpdateTestResult();
}
}
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierView.xaml
similarity index 98%
rename from src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierView.xaml
rename to src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierView.xaml
index 48f6007e6..554ed1a01 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierView.xaml
@@ -1,4 +1,4 @@
-
/// Interaction logic for DataBindingModifierView.xaml
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierViewModel.cs
similarity index 95%
rename from src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierViewModel.cs
rename to src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierViewModel.cs
index 431185848..73e129427 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierViewModel.cs
@@ -7,7 +7,7 @@ using Artemis.UI.Shared.Input;
using Artemis.UI.Shared.Services;
using Stylet;
-namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
+namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding
{
public class DataBindingModifierViewModel : PropertyChangedBase, IDisposable
{
@@ -63,13 +63,13 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
public void Delete()
{
- Modifier.DataBinding.RemoveModifier(Modifier);
+ Modifier.DirectDataBinding.RemoveModifier(Modifier);
}
public void SwapType()
{
if (Modifier.ParameterType == ProfileRightSideType.Dynamic)
- Modifier.UpdateParameter(Modifier.DataBinding.GetSourceType().GetDefault());
+ Modifier.UpdateParameter(Modifier.DirectDataBinding.GetSourceType().GetDefault());
else
Modifier.UpdateParameter(null, null);
@@ -88,7 +88,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
private void Update()
{
- var sourceType = Modifier.DataBinding.GetSourceType();
+ var sourceType = Modifier.DirectDataBinding.GetSourceType();
if (sourceType == null)
throw new ArtemisUIException("Cannot use a data binding modifier VM for a data binding without a source");
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DirectDataBindingModeView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DirectDataBindingModeView.xaml
new file mode 100644
index 000000000..c71e0d2a9
--- /dev/null
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DirectDataBindingModeView.xaml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DirectDataBindingModeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DirectDataBindingModeViewModel.cs
new file mode 100644
index 000000000..e20f2c33d
--- /dev/null
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DirectDataBindingModeViewModel.cs
@@ -0,0 +1,118 @@
+using System;
+using Artemis.Core;
+using Artemis.UI.Ninject.Factories;
+using Artemis.UI.Shared;
+using Artemis.UI.Shared.Input;
+using Artemis.UI.Shared.Services;
+using Stylet;
+
+namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding
+{
+ public class DirectDataBindingModeViewModel : Screen, IDataBindingModeViewModel
+ {
+ private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
+ private readonly IDataModelUIService _dataModelUIService;
+ private readonly IProfileEditorService _profileEditorService;
+ private DataModelDynamicViewModel _targetSelectionViewModel;
+
+ public DirectDataBindingModeViewModel(DirectDataBinding directDataBinding,
+ IProfileEditorService profileEditorService,
+ IDataModelUIService dataModelUIService,
+ IDataBindingsVmFactory dataBindingsVmFactory)
+ {
+ _profileEditorService = profileEditorService;
+ _dataModelUIService = dataModelUIService;
+ _dataBindingsVmFactory = dataBindingsVmFactory;
+
+ DirectDataBinding = directDataBinding;
+ ModifierViewModels = new BindableCollection>();
+
+ Initialize();
+ }
+
+
+ public DirectDataBinding DirectDataBinding { get; }
+ public BindableCollection> ModifierViewModels { get; }
+
+ public DataModelDynamicViewModel TargetSelectionViewModel
+ {
+ get => _targetSelectionViewModel;
+ private set => SetAndNotify(ref _targetSelectionViewModel, value);
+ }
+
+ public void Update()
+ {
+ TargetSelectionViewModel.PopulateSelectedPropertyViewModel(DirectDataBinding.SourceDataModel, DirectDataBinding.SourcePropertyPath);
+ TargetSelectionViewModel.FilterTypes = new[] {DirectDataBinding.DataBinding.GetTargetType()};
+
+ UpdateModifierViewModels();
+ }
+
+ public object GetTestValue()
+ {
+ return TargetSelectionViewModel.SelectedPropertyViewModel?.GetCurrentValue();
+ }
+
+ private void Initialize()
+ {
+ DirectDataBinding.ModifiersUpdated += DirectDataBindingOnModifiersUpdated;
+ TargetSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
+ TargetSelectionViewModel.PropertySelected += TargetSelectionViewModelOnPropertySelected;
+
+ Update();
+ }
+
+ #region Target
+
+ private void TargetSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
+ {
+ DirectDataBinding.UpdateSource(e.DataModelVisualizationViewModel.DataModel, e.DataModelVisualizationViewModel.PropertyPath);
+ Update();
+
+ _profileEditorService.UpdateSelectedProfileElement();
+ }
+
+ #endregion
+
+ #region Modifiers
+
+ public void AddModifier()
+ {
+ DirectDataBinding.AddModifier(ProfileRightSideType.Dynamic);
+ _profileEditorService.UpdateSelectedProfileElement();
+ }
+
+
+ private void UpdateModifierViewModels()
+ {
+ foreach (var dataBindingModifierViewModel in ModifierViewModels)
+ dataBindingModifierViewModel.Dispose();
+ ModifierViewModels.Clear();
+
+ foreach (var dataBindingModifier in DirectDataBinding.Modifiers)
+ ModifierViewModels.Add(_dataBindingsVmFactory.DataBindingModifierViewModel(dataBindingModifier));
+ }
+
+ private void DirectDataBindingOnModifiersUpdated(object sender, EventArgs e)
+ {
+ UpdateModifierViewModels();
+ }
+
+ #endregion
+
+ #region IDisposable
+
+ public void Dispose()
+ {
+ TargetSelectionViewModel.PropertySelected -= TargetSelectionViewModelOnPropertySelected;
+ TargetSelectionViewModel.Dispose();
+ DirectDataBinding.ModifiersUpdated -= DirectDataBindingOnModifiersUpdated;
+
+ foreach (var dataBindingModifierViewModel in ModifierViewModels)
+ dataBindingModifierViewModel.Dispose();
+ ModifierViewModels.Clear();
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/IDataBindingModeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/IDataBindingModeViewModel.cs
new file mode 100644
index 000000000..7add83036
--- /dev/null
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/IDataBindingModeViewModel.cs
@@ -0,0 +1,11 @@
+using System;
+using Stylet;
+
+namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
+{
+ public interface IDataBindingModeViewModel : IScreen, IDisposable
+ {
+ void Update();
+ object GetTestValue();
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesView.xaml
index ae4d3544a..3908cac1c 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesView.xaml
@@ -78,7 +78,7 @@
-
+
@@ -173,7 +173,7 @@
-
+
@@ -208,7 +208,7 @@
-
-
+
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs
index 0d7b3e9b2..1e5993039 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertyViewModel.cs
@@ -29,6 +29,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
set => SetAndNotify(ref _isVisible, value);
}
+ public bool IsExpanded => false;
+
public void Dispose()
{
TreePropertyViewModel?.Dispose();
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/Controls/PropertyTimelineHeader.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/Controls/PropertyTimelineHeader.cs
index 5eb3cbf83..8fbc466ee 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/Controls/PropertyTimelineHeader.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/Controls/PropertyTimelineHeader.cs
@@ -129,9 +129,9 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline.Controls
var typeFace = new Typeface(FontFamily, new FontStyle(), new FontWeight(), new FontStretch());
var formattedText = new FormattedText(text, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, typeFace, 9, Fill, null, VisualTreeHelper.GetDpi(this).PixelsPerDip);
if (x == 0 && OffsetFirstValue)
- drawingContext.DrawText(formattedText, new Point(2, 2));
+ drawingContext.DrawText(formattedText, new Point(2, 5));
else
- drawingContext.DrawText(formattedText, new Point(x - formattedText.Width / 2, 2));
+ drawingContext.DrawText(formattedText, new Point(x - formattedText.Width / 2, 5));
}
private void UpdateTimeScale()
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreePropertyViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreePropertyViewModel.cs
index 45c429033..bfc7950b0 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreePropertyViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreePropertyViewModel.cs
@@ -1,4 +1,5 @@
using System;
+using System.ComponentModel;
using System.Linq;
using Artemis.Core;
using Artemis.UI.Shared;
@@ -58,7 +59,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
}
#endregion
-
+
private void ApplyKeyframesEnabled(bool enable)
{
// If enabling keyframes for the first time, add a keyframe with the current value at the current position
@@ -95,8 +96,9 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
#endregion
}
- public interface ITreePropertyViewModel : IScreen, IDisposable
+ public interface ITreePropertyViewModel : IScreen, INotifyPropertyChanged, IDisposable
{
bool HasPropertyInputViewModel { get; }
+ bool DataBindingsOpen { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreeView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreeView.xaml
index 6e1f553b6..006b38186 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreeView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreeView.xaml
@@ -95,6 +95,11 @@