diff --git a/src/Artemis.Core/Artemis.Core.csproj.DotSettings b/src/Artemis.Core/Artemis.Core.csproj.DotSettings
index babfa2469..77021d436 100644
--- a/src/Artemis.Core/Artemis.Core.csproj.DotSettings
+++ b/src/Artemis.Core/Artemis.Core.csproj.DotSettings
@@ -9,7 +9,12 @@
True
True
True
+ True
+ True
+ True
+ True
True
+ True
True
True
True
diff --git a/src/Artemis.Core/Events/DataBindingPropertyUpdatedEvent.cs b/src/Artemis.Core/Events/DataBindingPropertyUpdatedEvent.cs
new file mode 100644
index 000000000..52c8a99fa
--- /dev/null
+++ b/src/Artemis.Core/Events/DataBindingPropertyUpdatedEvent.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace Artemis.Core
+{
+ public class DataBindingPropertyUpdatedEvent : EventArgs
+ {
+ public DataBindingPropertyUpdatedEvent(T value)
+ {
+ Value = value;
+ }
+
+ ///
+ /// The updated value that should be applied to the layer property
+ ///
+ public T Value { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Extensions/TypeExtensions.cs b/src/Artemis.Core/Extensions/TypeExtensions.cs
index 027610874..9b82bf445 100644
--- a/src/Artemis.Core/Extensions/TypeExtensions.cs
+++ b/src/Artemis.Core/Extensions/TypeExtensions.cs
@@ -86,5 +86,13 @@ namespace Artemis.Core
);
return castable;
}
+
+ ///
+ /// Returns the default value of the given type
+ ///
+ public static object GetDefault(this Type type)
+ {
+ return type.IsValueType ? Activator.CreateInstance(type) : null;
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Converters/FloatDataBindingConverter.cs b/src/Artemis.Core/Models/Profile/DataBindings/Converters/FloatDataBindingConverter.cs
new file mode 100644
index 000000000..eb337ba54
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Converters/FloatDataBindingConverter.cs
@@ -0,0 +1,48 @@
+using System;
+
+namespace Artemis.Core
+{
+ ///
+ public class FloatDataBindingConverter : DataBindingConverter
+ {
+ public FloatDataBindingConverter()
+ {
+ SupportedType = typeof(float);
+ SupportsSum = true;
+ SupportsInterpolate = true;
+ }
+
+ ///
+ public override object Sum(object a, object b)
+ {
+ return Convert.ToSingle(a) + Convert.ToSingle(b);
+ }
+
+ ///
+ public override object Interpolate(object a, object b, double progress)
+ {
+ var floatA = Convert.ToSingle(a);
+ var floatB = Convert.ToSingle(b);
+ var diff = floatB - floatA;
+ return floatA + diff * progress;
+ }
+
+ ///
+ public override void ApplyValue(object value)
+ {
+ var floatValue = Convert.ToSingle(value);
+ if (DataBinding.LayerProperty.PropertyDescription.MaxInputValue is float max)
+ floatValue = Math.Min(floatValue, max);
+ if (DataBinding.LayerProperty.PropertyDescription.MinInputValue is float min)
+ floatValue = Math.Max(floatValue, min);
+
+ ValueSetter?.Invoke(floatValue);
+ }
+
+ ///
+ public override object GetValue()
+ {
+ return ValueGetter?.Invoke();
+ }
+ }
+}
\ 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
new file mode 100644
index 000000000..561ef8784
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Converters/GeneralDataBindingConverter.cs
@@ -0,0 +1,39 @@
+using System;
+
+namespace Artemis.Core
+{
+ ///
+ public class GeneralDataBindingConverter : DataBindingConverter
+ {
+ public GeneralDataBindingConverter()
+ {
+ SupportedType = typeof(object);
+ SupportsSum = false;
+ SupportsInterpolate = false;
+ }
+
+ ///
+ public override object Sum(object a, object b)
+ {
+ throw new NotSupportedException();
+ }
+
+ ///
+ public override object Interpolate(object a, object b, double progress)
+ {
+ throw new NotSupportedException();
+ }
+
+ ///
+ public override void ApplyValue(object value)
+ {
+ ValueSetter?.Invoke(value);
+ }
+
+ ///
+ public override object GetValue()
+ {
+ return ValueGetter?.Invoke();
+ }
+ }
+}
\ 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
new file mode 100644
index 000000000..c3466a43f
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Converters/IntDataBindingConverter.cs
@@ -0,0 +1,48 @@
+using System;
+
+namespace Artemis.Core
+{
+ ///
+ public class IntDataBindingConverter : DataBindingConverter
+ {
+ public IntDataBindingConverter()
+ {
+ SupportedType = typeof(int);
+ SupportsSum = true;
+ SupportsInterpolate = true;
+ }
+
+ ///
+ /// Gets or sets the mode used for rounding during interpolation. Defaults to
+ ///
+ ///
+ public MidpointRounding InterpolationRoundingMode { get; set; } = MidpointRounding.AwayFromZero;
+
+ ///
+ public override object Sum(object a, object b)
+ {
+ return (int) a + (int) b;
+ }
+
+ ///
+ public override object Interpolate(object a, object b, double progress)
+ {
+ var intA = (int) a;
+ var intB = (int) b;
+ var diff = intB - intA;
+ return (int) Math.Round(intA + diff * progress, InterpolationRoundingMode);
+ }
+
+ ///
+ public override void ApplyValue(object value)
+ {
+ ValueSetter?.Invoke(value);
+ }
+
+ ///
+ public override object GetValue()
+ {
+ return ValueGetter?.Invoke();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Converters/Internal/SKColorPartDataBindingConverter.cs b/src/Artemis.Core/Models/Profile/DataBindings/Converters/Internal/SKColorPartDataBindingConverter.cs
new file mode 100644
index 000000000..3073a9721
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Converters/Internal/SKColorPartDataBindingConverter.cs
@@ -0,0 +1,95 @@
+using System;
+using SkiaSharp;
+
+namespace Artemis.Core
+{
+ // This is internal because it's mainly a proof-of-concept
+ internal class SKColorPartDataBindingConverter : DataBindingConverter
+ {
+ private readonly Channel _channel;
+
+ public SKColorPartDataBindingConverter(Channel channel)
+ {
+ _channel = channel;
+
+ SupportsSum = true;
+ SupportsInterpolate = true;
+ SupportedType = _channel switch
+ {
+ Channel.Alpha => typeof(byte),
+ Channel.Red => typeof(byte),
+ Channel.Green => typeof(byte),
+ Channel.Blue => typeof(byte),
+ Channel.Hue => typeof(float),
+ _ => throw new ArgumentOutOfRangeException()
+ };
+ }
+
+ public override object Sum(object a, object b)
+ {
+ return (float) a + (float) b;
+ }
+
+ public override object Interpolate(object a, object b, double progress)
+ {
+ var diff = (float) b - (float) a;
+ return diff * progress;
+ }
+
+ public override void ApplyValue(object value)
+ {
+ var property = (SKColorLayerProperty) DataBinding.LayerProperty;
+ switch (_channel)
+ {
+ case Channel.Alpha:
+ property.CurrentValue = property.CurrentValue.WithAlpha((byte) value);
+ break;
+ case Channel.Red:
+ property.CurrentValue = property.CurrentValue.WithRed((byte) value);
+ break;
+ case Channel.Green:
+ property.CurrentValue = property.CurrentValue.WithGreen((byte) value);
+ break;
+ case Channel.Blue:
+ property.CurrentValue = property.CurrentValue.WithBlue((byte) value);
+ break;
+ case Channel.Hue:
+ property.CurrentValue.ToHsv(out var h, out var s, out var v);
+ property.CurrentValue = SKColor.FromHsv((float) value, s, v);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ public override object GetValue()
+ {
+ var property = (SKColorLayerProperty) DataBinding.LayerProperty;
+ switch (_channel)
+ {
+ case Channel.Alpha:
+ return property.CurrentValue.Alpha;
+ case Channel.Red:
+ return property.CurrentValue.Red;
+ case Channel.Green:
+ return property.CurrentValue.Green;
+ case Channel.Blue:
+ return property.CurrentValue.Blue;
+ case Channel.Hue:
+ property.CurrentValue.ToHsv(out var h, out _, out _);
+ return h;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ public enum Channel
+ {
+ Alpha,
+ Red,
+ Green,
+ Blue,
+ Hue
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
index 9442c07b9..f28a911f5 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
@@ -15,14 +15,17 @@ namespace Artemis.Core
public class DataBinding
{
private readonly List _modifiers = new List();
- private bool _isInitialized;
- internal DataBinding(BaseLayerProperty layerProperty, PropertyInfo targetProperty)
+ private object _currentValue;
+ private object _previousValue;
+ private TimeSpan _easingProgress;
+
+ internal DataBinding(DataBindingRegistration dataBindingRegistration)
{
- LayerProperty = layerProperty;
- TargetProperty = targetProperty;
+ LayerProperty = dataBindingRegistration.LayerProperty;
Entity = new DataBindingEntity();
+ ApplyRegistration(dataBindingRegistration);
ApplyToEntity();
}
@@ -40,7 +43,17 @@ namespace Artemis.Core
public BaseLayerProperty LayerProperty { get; }
///
- /// Gets the inner property this data binding targets
+ /// Gets the data binding registration this data binding is based upon
+ ///
+ public DataBindingRegistration Registration { get; private set; }
+
+ ///
+ /// Gets the converter used to apply this data binding to the
+ ///
+ public DataBindingConverter Converter { get; private set; }
+
+ ///
+ /// Gets the property on the this data binding targets
///
public PropertyInfo TargetProperty { get; private set; }
@@ -87,6 +100,8 @@ namespace Artemis.Core
{
modifier.DataBinding = this;
_modifiers.Add(modifier);
+
+ OnModifiersUpdated();
}
}
@@ -99,6 +114,8 @@ namespace Artemis.Core
{
modifier.DataBinding = null;
_modifiers.Remove(modifier);
+
+ OnModifiersUpdated();
}
}
@@ -132,26 +149,74 @@ namespace Artemis.Core
///
public object GetValue(object baseValue)
{
- // Validating this is kinda expensive, it'll fail on ChangeType later anyway ^^
- // var targetType = TargetProperty.PropertyType;
- // if (!targetType.IsCastableFrom(baseValue.GetType()))
- // {
- // throw new ArtemisCoreException($"The provided current value type ({baseValue.GetType().Name}) not match the " +
- // $"target property type ({targetType.Name})");
- // }
-
- if (CompiledTargetAccessor == null)
+ if (CompiledTargetAccessor == null || Converter == null)
return baseValue;
var dataBindingValue = CompiledTargetAccessor(SourceDataModel);
foreach (var dataBindingModifier in Modifiers)
dataBindingValue = dataBindingModifier.Apply(dataBindingValue);
- return Convert.ChangeType(dataBindingValue, TargetProperty.PropertyType);
+ var value = Convert.ChangeType(dataBindingValue, TargetProperty.PropertyType);
+
+ // If no easing is to be applied simple return whatever the current value is
+ if (EasingTime == TimeSpan.Zero || !Converter.SupportsInterpolate)
+ return value;
+
+ // If the value changed, update the current and previous values used for easing
+ if (!Equals(value, _currentValue))
+ ResetEasing(value);
+
+ // Apply interpolation between the previous and current value
+ return GetInterpolatedValue();
}
- internal void Update(double deltaTime)
+ private void ResetEasing(object value)
{
+ _previousValue = GetInterpolatedValue();
+ _currentValue = value;
+ _easingProgress = TimeSpan.Zero;
+ }
+
+ ///
+ /// Returns the type of the target property of this data binding
+ ///
+ public Type GetTargetType()
+ {
+ return TargetProperty.PropertyType;
+ }
+
+ ///
+ /// Returns the type of the source property of this data binding
+ ///
+ public Type GetSourceType()
+ {
+ return SourceDataModel?.GetTypeAtPath(SourcePropertyPath);
+ }
+
+ ///
+ /// Updates the smoothing progress of the data binding
+ ///
+ /// The time in seconds that passed since the last update
+ public void Update(double deltaTime)
+ {
+ // Data bindings cannot go back in time like brushes
+ deltaTime = Math.Max(0, deltaTime);
+
+ _easingProgress = _easingProgress.Add(TimeSpan.FromSeconds(deltaTime));
+ if (_easingProgress > EasingTime)
+ _easingProgress = EasingTime;
+ }
+
+ ///
+ /// Updates the value on the according to the data binding
+ ///
+ public void ApplyToProperty()
+ {
+ if (Converter == null)
+ return;
+
+ var value = GetValue(Converter.GetValue());
+ Converter.ApplyValue(GetValue(value));
}
internal void ApplyToEntity()
@@ -178,7 +243,8 @@ namespace Artemis.Core
internal void ApplyToDataBinding()
{
// General
- TargetProperty = LayerProperty.GetDataBindingProperties()?.FirstOrDefault(p => p.Name == Entity.TargetProperty);
+ ApplyRegistration(LayerProperty.DataBindingRegistrations.FirstOrDefault(p => p.Property.Name == Entity.TargetProperty));
+
Mode = (DataBindingMode) Entity.DataBindingMode;
EasingTime = Entity.EasingTime;
EasingFunction = (Easings.Functions) Entity.EasingFunction;
@@ -192,11 +258,8 @@ namespace Artemis.Core
internal void Initialize(IDataModelService dataModelService, IDataBindingService dataBindingService)
{
- if (_isInitialized)
- throw new ArtemisCoreException("Data binding is already initialized");
-
// Source
- if (Entity.SourceDataModelGuid != null)
+ if (Entity.SourceDataModelGuid != null && SourceDataModel == null)
{
var dataModel = dataModelService.GetPluginDataModelByGuid(Entity.SourceDataModelGuid.Value);
if (dataModel != null && dataModel.ContainsPath(Entity.SourcePropertyPath))
@@ -206,8 +269,35 @@ namespace Artemis.Core
// Modifiers
foreach (var dataBindingModifier in Modifiers)
dataBindingModifier.Initialize(dataModelService, dataBindingService);
+ }
- _isInitialized = true;
+ private void ApplyRegistration(DataBindingRegistration dataBindingRegistration)
+ {
+ if (dataBindingRegistration != null)
+ dataBindingRegistration.DataBinding = this;
+
+ Converter = dataBindingRegistration?.Converter;
+ Registration = dataBindingRegistration;
+ TargetProperty = dataBindingRegistration?.Property;
+
+ if (GetTargetType().IsValueType)
+ {
+ if (_currentValue == null)
+ _currentValue = GetTargetType().GetDefault();
+ if (_previousValue == null)
+ _previousValue = _currentValue;
+ }
+
+ Converter?.Initialize(this);
+ }
+
+ private object GetInterpolatedValue()
+ {
+ if (_easingProgress == EasingTime || !Converter.SupportsInterpolate)
+ return _currentValue;
+
+ var easingAmount = _easingProgress.TotalSeconds / EasingTime.TotalSeconds;
+ return Converter.Interpolate(_previousValue, _currentValue, Easings.Interpolate(easingAmount, EasingFunction));
}
private void CreateExpression()
@@ -227,6 +317,20 @@ namespace Artemis.Core
var lambda = Expression.Lambda>(returnValue, parameter);
CompiledTargetAccessor = lambda.Compile();
}
+
+ #region Events
+
+ ///
+ /// Occurs when a modifier is added or removed
+ ///
+ public event EventHandler ModifiersUpdated;
+
+ protected virtual void OnModifiersUpdated()
+ {
+ ModifiersUpdated?.Invoke(this, EventArgs.Empty);
+ }
+
+ #endregion
}
///
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/DataBindingConverter.cs b/src/Artemis.Core/Models/Profile/DataBindings/DataBindingConverter.cs
new file mode 100644
index 000000000..3ee8756d2
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/DataBindings/DataBindingConverter.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+
+namespace Artemis.Core
+{
+ ///
+ /// A data binding converter that acts as the bridge between a and a
+ ///
+ ///
+ public abstract class DataBindingConverter
+ {
+ internal Func
public abstract class BaseLayerProperty
{
+ protected readonly List _dataBindingRegistrations = new List();
protected readonly List _dataBindings = new List();
+
+ private object _baseValue;
+ private object _currentValue;
+ private object _defaultValue;
private bool _isHidden;
private bool _keyframesEnabled;
@@ -18,6 +24,59 @@ namespace Artemis.Core
{
}
+ ///
+ /// Gets or sets the base value of this layer property without any keyframes applied
+ ///
+ public object BaseValue
+ {
+ get => _baseValue;
+ set
+ {
+ if (value != null && value.GetType() != GetPropertyType())
+ throw new ArtemisCoreException("Cannot update base value because of a type mismatch");
+ _baseValue = value;
+ }
+ }
+
+ ///
+ /// Gets the current value of this property as it is affected by it's keyframes, updated once every frame
+ ///
+ public object CurrentValue
+ {
+ get => _currentValue;
+ set
+ {
+ if (value != null && value.GetType() != GetPropertyType())
+ throw new ArtemisCoreException("Cannot update current value because of a type mismatch");
+ _currentValue = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the default value of this layer property. If set, this value is automatically applied if the property
+ /// has no value in storage
+ ///
+ public object DefaultValue
+ {
+ get => _defaultValue;
+ set
+ {
+ if (value != null && value.GetType() != GetPropertyType())
+ throw new ArtemisCoreException("Cannot update default value because of a type mismatch");
+ _defaultValue = value;
+ }
+ }
+
+ ///
+ /// Gets a list containing the active data bindings
+ ///
+ public IReadOnlyList DataBindings => _dataBindings.AsReadOnly();
+
+ ///
+ /// Gets a list containing all the data binding registrations
+ ///
+ public IReadOnlyList DataBindingRegistrations => _dataBindingRegistrations.AsReadOnly();
+
///
/// Gets the profile element (such as layer or folder) this effect is applied to
///
@@ -38,11 +97,6 @@ namespace Artemis.Core
///
public bool DataBindingsSupported { get; protected internal set; } = true;
- ///
- /// Gets a read-only collection of the currently applied data bindings
- ///
- public IReadOnlyCollection DataBindings => _dataBindings.AsReadOnly();
-
///
/// Gets or sets whether keyframes are enabled on this property, has no effect if is
/// False
@@ -104,18 +158,6 @@ namespace Artemis.Core
///
public abstract Type GetPropertyType();
- ///
- /// Returns a list of properties to which data bindings can be applied
- ///
- ///
- public abstract List GetDataBindingProperties();
-
- ///
- /// Called when the provided data binding must be applied to a property
- ///
- ///
- protected abstract void ApplyDataBinding(DataBinding dataBinding);
-
///
/// Applies the provided property entity to the layer property by deserializing the JSON base value and keyframe values
///
@@ -132,23 +174,22 @@ namespace Artemis.Core
#region Data bindings
- ///
- /// Applies the current to the layer property
- ///
- public void ApplyDataBindings()
+ internal void InitializeDataBindings(IDataModelService dataModelService, IDataBindingService dataBindingService)
{
foreach (var dataBinding in DataBindings)
- ApplyDataBinding(dataBinding);
+ dataBinding.Initialize(dataModelService, dataBindingService);
}
///
/// Adds a new data binding targeting the given property to the collection
///
- /// The property the new data binding should target
/// The newly created data binding
- public DataBinding AddDataBinding(PropertyInfo targetProperty)
+ public DataBinding EnableDataBinding(DataBindingRegistration dataBindingRegistration)
{
- var dataBinding = new DataBinding(this, targetProperty);
+ if (dataBindingRegistration.LayerProperty != this)
+ throw new ArtemisCoreException("Cannot enable a data binding using a data binding registration of a different layer property");
+
+ var dataBinding = new DataBinding(dataBindingRegistration);
_dataBindings.Add(dataBinding);
return dataBinding;
@@ -158,13 +199,11 @@ namespace Artemis.Core
/// Removes the provided data binding from the collection
///
/// The data binding to remove
- public void RemoveDataBinding(DataBinding dataBinding)
+ public void DisableDataBinding(DataBinding dataBinding)
{
_dataBindings.Remove(dataBinding);
}
-
-
#endregion
#region Events
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs
index 59a2af329..ec44b97d3 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
+using System.Linq.Expressions;
using System.Reflection;
using Artemis.Storage.Entities.Profile;
using Newtonsoft.Json;
@@ -16,9 +17,8 @@ namespace Artemis.Core
///
///
/// The type of property encapsulated in this layer property
- public class LayerProperty : BaseLayerProperty
+ public abstract class LayerProperty : BaseLayerProperty
{
- private T _baseValue;
private bool _isInitialized;
private List> _keyframes;
@@ -30,30 +30,38 @@ namespace Artemis.Core
///
/// Gets or sets the base value of this layer property without any keyframes applied
///
- public T BaseValue
+ public new T BaseValue
{
- get => _baseValue;
+ get => base.BaseValue != null ? (T) base.BaseValue : default;
set
{
- if (_baseValue != null && !_baseValue.Equals(value) || _baseValue == null && value != null)
- {
- _baseValue = value;
- OnBaseValueChanged();
- }
+ if (Equals(base.BaseValue, value))
+ return;
+
+ base.BaseValue = value;
+ Update();
+ OnBaseValueChanged();
}
}
///
/// Gets the current value of this property as it is affected by it's keyframes, updated once every frame
///
- public T CurrentValue { get; set; }
+ public new T CurrentValue
+ {
+ get => base.CurrentValue != null ? (T) base.CurrentValue : default;
+ set => base.CurrentValue = value;
+ }
///
/// Gets or sets the default value of this layer property. If set, this value is automatically applied if the property
- /// has no
- /// value in storage
+ /// has no value in storage
///
- public T DefaultValue { get; set; }
+ public new T DefaultValue
+ {
+ get => base.DefaultValue != null ? (T) base.DefaultValue : default;
+ set => base.DefaultValue = value;
+ }
///
/// Gets a read-only list of all the keyframes on this layer property
@@ -97,7 +105,7 @@ namespace Artemis.Core
// Force an update so that the base value is applied to the current value and
// keyframes/data bindings are applied using the new base value
- Update(0);
+ Update();
}
///
@@ -188,7 +196,7 @@ namespace Artemis.Core
///
/// Updates the property, applying keyframes and data bindings to the current value
///
- internal void Update(double deltaTime)
+ internal void Update(double deltaTime = 0)
{
CurrentValue = BaseValue;
@@ -198,41 +206,6 @@ namespace Artemis.Core
OnUpdated();
}
- private void UpdateKeyframes()
- {
- if (!KeyframesSupported || !KeyframesEnabled)
- return;
-
- // The current keyframe is the last keyframe before the current time
- CurrentKeyframe = _keyframes.LastOrDefault(k => k.Position <= ProfileElement.TimelinePosition);
- // Keyframes are sorted by position so we can safely assume the next keyframe's position is after the current
- var nextIndex = _keyframes.IndexOf(CurrentKeyframe) + 1;
- NextKeyframe = _keyframes.Count > nextIndex ? _keyframes[nextIndex] : null;
-
- // No need to update the current value if either of the keyframes are null
- if (CurrentKeyframe == null)
- CurrentValue = _keyframes.Any() ? _keyframes[0].Value : BaseValue;
- else if (NextKeyframe == null)
- CurrentValue = CurrentKeyframe.Value;
- // Only determine progress and current value if both keyframes are present
- else
- {
- var timeDiff = NextKeyframe.Position - CurrentKeyframe.Position;
- var keyframeProgress = (float) ((ProfileElement.TimelinePosition - CurrentKeyframe.Position).TotalMilliseconds / timeDiff.TotalMilliseconds);
- var keyframeProgressEased = (float) Easings.Interpolate(keyframeProgress, CurrentKeyframe.EasingFunction);
- UpdateCurrentValue(keyframeProgress, keyframeProgressEased);
- }
- }
-
- private void UpdateDataBindings(double deltaTime)
- {
- foreach (var dataBinding in DataBindings)
- {
- dataBinding.Update(deltaTime);
- ApplyDataBinding(dataBinding);
- }
- }
-
///
/// Sorts the keyframes in ascending order by position
///
@@ -303,20 +276,81 @@ namespace Artemis.Core
Position = k.Position,
EasingFunction = (int) k.EasingFunction
}));
+
+ PropertyEntity.DataBindingEntities.Clear();
+ foreach (var dataBinding in DataBindings)
+ {
+ dataBinding.ApplyToEntity();
+ PropertyEntity.DataBindingEntities.Add(dataBinding.Entity);
+ }
+ }
+
+ private void UpdateKeyframes()
+ {
+ if (!KeyframesSupported || !KeyframesEnabled)
+ return;
+
+ // The current keyframe is the last keyframe before the current time
+ CurrentKeyframe = _keyframes.LastOrDefault(k => k.Position <= ProfileElement.TimelinePosition);
+ // Keyframes are sorted by position so we can safely assume the next keyframe's position is after the current
+ var nextIndex = _keyframes.IndexOf(CurrentKeyframe) + 1;
+ NextKeyframe = _keyframes.Count > nextIndex ? _keyframes[nextIndex] : null;
+
+ // No need to update the current value if either of the keyframes are null
+ if (CurrentKeyframe == null)
+ CurrentValue = _keyframes.Any() ? _keyframes[0].Value : BaseValue;
+ else if (NextKeyframe == null)
+ CurrentValue = CurrentKeyframe.Value;
+ // Only determine progress and current value if both keyframes are present
+ else
+ {
+ var timeDiff = NextKeyframe.Position - CurrentKeyframe.Position;
+ var keyframeProgress = (float) ((ProfileElement.TimelinePosition - CurrentKeyframe.Position).TotalMilliseconds / timeDiff.TotalMilliseconds);
+ var keyframeProgressEased = (float) Easings.Interpolate(keyframeProgress, CurrentKeyframe.EasingFunction);
+ UpdateCurrentValue(keyframeProgress, keyframeProgressEased);
+ }
}
#region Data bindings
- ///
- public override List GetDataBindingProperties()
+ public void RegisterDataBindingProperty(Expression> propertyLambda, DataBindingConverter converter)
{
- return new List {GetType().GetProperty(nameof(CurrentValue))};
+ // If the lambda references to itself, use the property info of public new T CurrentValue
+ PropertyInfo propertyInfo;
+ string path = null;
+ if (propertyLambda.Parameters[0] == propertyLambda.Body)
+ {
+ propertyInfo = GetType().GetProperties().FirstOrDefault(p => p.Name == nameof(CurrentValue) && p.PropertyType == typeof(T));
+ }
+ else
+ {
+ propertyInfo = ReflectionUtilities.GetPropertyInfo(CurrentValue, propertyLambda);
+ // Deconstruct the lambda
+ var current = (MemberExpression) propertyLambda.Body;
+ path = current.Member.Name;
+ while (current.Expression is MemberExpression memberExpression)
+ {
+ path = current.Member.Name + "." + path;
+ current = memberExpression;
+ }
+ }
+
+ if (converter.SupportedType != propertyInfo.PropertyType)
+ {
+ throw new ArtemisCoreException($"Cannot register data binding property for property {propertyInfo.Name} " +
+ "because the provided converter does not support the property's type");
+ }
+
+ _dataBindingRegistrations.Add(new DataBindingRegistration(this, propertyInfo, converter, path));
}
- ///
- protected override void ApplyDataBinding(DataBinding dataBinding)
+ private void UpdateDataBindings(double deltaTime)
{
- CurrentValue = (T) dataBinding.GetValue(CurrentValue);
+ foreach (var dataBinding in DataBindings)
+ {
+ dataBinding.Update(deltaTime);
+ dataBinding.ApplyToProperty();
+ }
}
#endregion
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/Types/ColorGradientLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/Types/ColorGradientLayerProperty.cs
index 073f17462..ab5d5a91c 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/Types/ColorGradientLayerProperty.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/Types/ColorGradientLayerProperty.cs
@@ -11,11 +11,15 @@ namespace Artemis.Core
DataBindingsSupported = false;
}
+ ///
+ /// Implicitly converts an to a
+ ///
public static implicit operator ColorGradient(ColorGradientLayerProperty p)
{
return p.CurrentValue;
}
+ ///
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
{
throw new ArtemisCoreException("Color Gradients do not support keyframes.");
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/Types/EnumLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/Types/EnumLayerProperty.cs
index 97b8ff3d5..eb99a3b3e 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/Types/EnumLayerProperty.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/Types/EnumLayerProperty.cs
@@ -5,22 +5,29 @@ namespace Artemis.Core
///
public class EnumLayerProperty : LayerProperty where T : Enum
{
- public EnumLayerProperty()
+ internal EnumLayerProperty()
{
KeyframesSupported = false;
DataBindingsSupported = false;
}
+ ///
+ /// Implicitly converts an to a
+ ///
public static implicit operator T(EnumLayerProperty p)
{
return p.CurrentValue;
}
+ ///
+ /// Implicitly converts an to an
+ ///
public static implicit operator int(EnumLayerProperty p)
{
return Convert.ToInt32(p.CurrentValue);
}
+ ///
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
{
throw new ArtemisCoreException("Enum properties do not support keyframes.");
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/Types/FloatLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/Types/FloatLayerProperty.cs
index 3ec2efd90..e425154cd 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/Types/FloatLayerProperty.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/Types/FloatLayerProperty.cs
@@ -5,18 +5,26 @@
{
internal FloatLayerProperty()
{
+ RegisterDataBindingProperty(value => value, new FloatDataBindingConverter());
}
+ ///
+ /// Implicitly converts an to a
+ ///
public static implicit operator float(FloatLayerProperty p)
{
return p.CurrentValue;
}
+ ///
+ /// Implicitly converts an to a
+ ///
public static implicit operator double(FloatLayerProperty p)
{
return p.CurrentValue;
}
+ ///
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
{
var diff = NextKeyframe.Value - CurrentKeyframe.Value;
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/Types/IntLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/Types/IntLayerProperty.cs
index 16600970b..db567e619 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/Types/IntLayerProperty.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/Types/IntLayerProperty.cs
@@ -7,23 +7,34 @@ namespace Artemis.Core
{
internal IntLayerProperty()
{
+ RegisterDataBindingProperty(value => value, new IntDataBindingConverter());
}
+ ///
+ /// Implicitly converts an to an
+ ///
public static implicit operator int(IntLayerProperty p)
{
return p.CurrentValue;
}
+ ///
+ /// Implicitly converts an to a
+ ///
public static implicit operator float(IntLayerProperty p)
{
return p.CurrentValue;
}
+ ///
+ /// Implicitly converts an to a
+ ///
public static implicit operator double(IntLayerProperty p)
{
return p.CurrentValue;
}
+ ///
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
{
var diff = NextKeyframe.Value - CurrentKeyframe.Value;
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/Types/LayerBrushReferenceLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/Types/LayerBrushReferenceLayerProperty.cs
index cebc0b1d7..04eb19730 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/Types/LayerBrushReferenceLayerProperty.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/Types/LayerBrushReferenceLayerProperty.cs
@@ -11,11 +11,15 @@
DataBindingsSupported = false;
}
+ ///
+ /// Implicitly converts an to an
+ ///
public static implicit operator LayerBrushReference(LayerBrushReferenceLayerProperty p)
{
return p.CurrentValue;
}
+ ///
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
{
throw new ArtemisCoreException("Layer brush references do not support keyframes.");
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKColorLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKColorLayerProperty.cs
index fbe8968ac..dc9032d9a 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKColorLayerProperty.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKColorLayerProperty.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using SkiaSharp;
+using SkiaSharp;
namespace Artemis.Core
{
@@ -11,10 +7,15 @@ namespace Artemis.Core
{
internal SKColorLayerProperty()
{
+ RegisterDataBindingProperty(color => color.Alpha, new SKColorPartDataBindingConverter(SKColorPartDataBindingConverter.Channel.Alpha));
+ RegisterDataBindingProperty(color => color.Red, new SKColorPartDataBindingConverter(SKColorPartDataBindingConverter.Channel.Red));
+ RegisterDataBindingProperty(color => color.Green, new SKColorPartDataBindingConverter(SKColorPartDataBindingConverter.Channel.Green));
+ RegisterDataBindingProperty(color => color.Blue, new SKColorPartDataBindingConverter(SKColorPartDataBindingConverter.Channel.Blue));
+ RegisterDataBindingProperty(color => color.Hue, new SKColorPartDataBindingConverter(SKColorPartDataBindingConverter.Channel.Hue));
}
///
- /// Implicitly converts an to an
+ /// Implicitly converts an to an ¶
///
///
///
@@ -28,29 +29,5 @@ namespace Artemis.Core
{
CurrentValue = CurrentKeyframe.Value.Interpolate(NextKeyframe.Value, keyframeProgressEased);
}
-
- ///
- public override List GetDataBindingProperties()
- {
- return typeof(SKColor).GetProperties().ToList();
- }
-
- ///
- protected override void ApplyDataBinding(DataBinding dataBinding)
- {
- if (dataBinding.TargetProperty.Name == nameof(CurrentValue.Alpha))
- CurrentValue = CurrentValue.WithAlpha((byte) dataBinding.GetValue(BaseValue.Alpha));
- else if (dataBinding.TargetProperty.Name == nameof(CurrentValue.Red))
- CurrentValue = CurrentValue.WithRed((byte) dataBinding.GetValue(BaseValue.Red));
- else if (dataBinding.TargetProperty.Name == nameof(CurrentValue.Green))
- CurrentValue = CurrentValue.WithGreen((byte) dataBinding.GetValue(BaseValue.Green));
- else if (dataBinding.TargetProperty.Name == nameof(CurrentValue.Blue))
- CurrentValue = CurrentValue.WithBlue((byte) dataBinding.GetValue(BaseValue.Blue));
- else if (dataBinding.TargetProperty.Name == nameof(CurrentValue.Hue))
- {
- CurrentValue.ToHsv(out var h, out var s, out var v);
- CurrentValue = SKColor.FromHsv((float) dataBinding.GetValue(h), s, v);
- }
- }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKPointLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKPointLayerProperty.cs
index e69eac535..30194bfac 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKPointLayerProperty.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKPointLayerProperty.cs
@@ -1,7 +1,4 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using SkiaSharp;
+using SkiaSharp;
namespace Artemis.Core
{
@@ -10,8 +7,10 @@ namespace Artemis.Core
{
internal SKPointLayerProperty()
{
+ RegisterDataBindingProperty(point => point.X, new FloatDataBindingConverter());
+ RegisterDataBindingProperty(point => point.Y, new FloatDataBindingConverter());
}
-
+
///
/// Implicitly converts an to an
///
@@ -27,20 +26,5 @@ namespace Artemis.Core
var yDiff = NextKeyframe.Value.Y - CurrentKeyframe.Value.Y;
CurrentValue = new SKPoint(CurrentKeyframe.Value.X + xDiff * keyframeProgressEased, CurrentKeyframe.Value.Y + yDiff * keyframeProgressEased);
}
-
- ///
- public override List GetDataBindingProperties()
- {
- return typeof(SKPoint).GetProperties().Where(p => p.CanWrite).ToList();
- }
-
- ///
- protected override void ApplyDataBinding(DataBinding dataBinding)
- {
- if (dataBinding.TargetProperty.Name == nameof(CurrentValue.X))
- CurrentValue = new SKPoint((float) dataBinding.GetValue(BaseValue), CurrentValue.Y);
- else if (dataBinding.TargetProperty.Name == nameof(CurrentValue.Y))
- CurrentValue = new SKPoint(CurrentValue.X, (float) dataBinding.GetValue(BaseValue));
- }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKSizeLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKSizeLayerProperty.cs
index 326f74527..59504ca18 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKSizeLayerProperty.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKSizeLayerProperty.cs
@@ -1,7 +1,4 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using SkiaSharp;
+using SkiaSharp;
namespace Artemis.Core
{
@@ -10,6 +7,8 @@ namespace Artemis.Core
{
internal SKSizeLayerProperty()
{
+ RegisterDataBindingProperty(size => size.Width, new FloatDataBindingConverter());
+ RegisterDataBindingProperty(size => size.Height, new FloatDataBindingConverter());
}
///
@@ -27,20 +26,5 @@ namespace Artemis.Core
var heightDiff = NextKeyframe.Value.Height - CurrentKeyframe.Value.Height;
CurrentValue = new SKSize(CurrentKeyframe.Value.Width + widthDiff * keyframeProgressEased, CurrentKeyframe.Value.Height + heightDiff * keyframeProgressEased);
}
-
- ///
- public override List GetDataBindingProperties()
- {
- return typeof(SKSize).GetProperties().Where(p => p.CanWrite).ToList();
- }
-
- ///
- protected override void ApplyDataBinding(DataBinding dataBinding)
- {
- if (dataBinding.TargetProperty.Name == nameof(CurrentValue.Height))
- CurrentValue = new SKSize(CurrentValue.Width, (float) dataBinding.GetValue(BaseValue));
- else if (dataBinding.TargetProperty.Name == nameof(CurrentValue.Width))
- CurrentValue = new SKSize((float) dataBinding.GetValue(BaseValue), CurrentValue.Width);
- }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs
index c3d5b01f3..34aac49d9 100644
--- a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs
+++ b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs
@@ -311,5 +311,17 @@ namespace Artemis.Core
}
#endregion
+
+ ///
+ /// Returns all the layer properties of this profile element
+ ///
+ public virtual List GetAllLayerProperties()
+ {
+ var result = new List();
+ foreach (var baseLayerEffect in LayerEffects)
+ result.AddRange(baseLayerEffect.BaseProperties.GetAllLayerProperties());
+
+ return result;
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/DataBindingService.cs b/src/Artemis.Core/Services/DataBindingService.cs
index 8a82ae864..199408fa2 100644
--- a/src/Artemis.Core/Services/DataBindingService.cs
+++ b/src/Artemis.Core/Services/DataBindingService.cs
@@ -15,6 +15,8 @@ namespace Artemis.Core.Services
{
_logger = logger;
_registeredDataBindingModifierTypes = new List();
+
+ RegisterBuiltInModifiers();
}
public IReadOnlyCollection RegisteredDataBindingModifierTypes
@@ -98,5 +100,12 @@ namespace Artemis.Core.Services
dataBindingModifier.Entity.ModifierType
);
}
+
+ private void RegisterBuiltInModifiers()
+ {
+ RegisterModifierType(Constants.CorePluginInfo, new MultiplicationModifierType());
+ RegisterModifierType(Constants.CorePluginInfo, new DivideModifierType());
+ RegisterModifierType(Constants.CorePluginInfo, new FloorModifierType());
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Interfaces/IRenderElementService.cs b/src/Artemis.Core/Services/Interfaces/IRenderElementService.cs
index bbb760dcf..79319f578 100644
--- a/src/Artemis.Core/Services/Interfaces/IRenderElementService.cs
+++ b/src/Artemis.Core/Services/Interfaces/IRenderElementService.cs
@@ -54,5 +54,6 @@ namespace Artemis.Core.Services
void RemoveLayerEffect(BaseLayerEffect layerEffect);
void InstantiateDisplayConditions(RenderProfileElement renderElement);
+ void InstantiateDataBindings(RenderProfileElement renderElement);
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/RenderElementService.cs b/src/Artemis.Core/Services/RenderElementService.cs
index ec6901764..6b26c94de 100644
--- a/src/Artemis.Core/Services/RenderElementService.cs
+++ b/src/Artemis.Core/Services/RenderElementService.cs
@@ -10,16 +10,18 @@ namespace Artemis.Core.Services
internal class RenderElementService : IRenderElementService
{
private readonly IDataModelService _dataModelService;
+ private readonly IDataBindingService _dataBindingService;
private readonly IKernel _kernel;
private readonly ILogger _logger;
private readonly IPluginService _pluginService;
- public RenderElementService(IKernel kernel, ILogger logger, IPluginService pluginService, IDataModelService dataModelService)
+ public RenderElementService(IKernel kernel, ILogger logger, IPluginService pluginService, IDataModelService dataModelService, IDataBindingService dataBindingService)
{
_kernel = kernel;
_logger = logger;
_pluginService = pluginService;
_dataModelService = dataModelService;
+ _dataBindingService = dataBindingService;
}
public Layer CreateLayer(Profile profile, ProfileElement parent, string name)
@@ -35,6 +37,7 @@ namespace Artemis.Core.Services
InstantiateLayerBrush(layer);
InstantiateLayerEffects(layer);
InstantiateDisplayConditions(layer);
+ InstantiateDataBindings(layer);
return layer;
}
@@ -156,5 +159,11 @@ namespace Artemis.Core.Services
_logger.Warning(e, $"Failed to init display conditions for {renderElement}");
}
}
+
+ public void InstantiateDataBindings(RenderProfileElement renderElement)
+ {
+ foreach (var baseLayerProperty in renderElement.GetAllLayerProperties())
+ baseLayerProperty.InitializeDataBindings(_dataModelService, _dataBindingService);
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Storage/ProfileService.cs b/src/Artemis.Core/Services/Storage/ProfileService.cs
index 78a9e7155..f66031fca 100644
--- a/src/Artemis.Core/Services/Storage/ProfileService.cs
+++ b/src/Artemis.Core/Services/Storage/ProfileService.cs
@@ -299,6 +299,7 @@ namespace Artemis.Core.Services
_renderElementService.RemoveLayerEffect(layerLayerEffect);
_renderElementService.InstantiateDisplayConditions(folder);
+ _renderElementService.InstantiateDataBindings(folder);
}
}
@@ -324,6 +325,7 @@ namespace Artemis.Core.Services
_renderElementService.RemoveLayerEffect(layerLayerEffect);
_renderElementService.InstantiateDisplayConditions(layer);
+ _renderElementService.InstantiateDataBindings(layer);
}
}
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/DataModelInputViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/DataModelInputViewModel.cs
index b25dd3614..f0b2b2a02 100644
--- a/src/Artemis.UI.Shared/DataModelVisualization/DataModelInputViewModel.cs
+++ b/src/Artemis.UI.Shared/DataModelVisualization/DataModelInputViewModel.cs
@@ -14,9 +14,9 @@ namespace Artemis.UI.Shared
private bool _closed;
private T _inputValue;
- protected DataModelInputViewModel(DataModelPropertyAttribute description, T initialValue)
+ protected DataModelInputViewModel(DataModelPropertyAttribute targetDescription, T initialValue)
{
- Description = description;
+ TargetDescription = targetDescription;
InputValue = initialValue;
}
@@ -26,7 +26,7 @@ namespace Artemis.UI.Shared
set => SetAndNotify(ref _inputValue, value);
}
- public DataModelPropertyAttribute Description { get; }
+ public DataModelPropertyAttribute TargetDescription { get; }
internal override object InternalGuard { get; } = null;
///
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml b/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml
deleted file mode 100644
index f74af0f0b..000000000
--- a/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml
new file mode 100644
index 000000000..ca1dbb905
--- /dev/null
+++ b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml.cs b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml.cs
similarity index 75%
rename from src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml.cs
rename to src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml.cs
index fc0034294..8a45bde5d 100644
--- a/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml.cs
+++ b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml.cs
@@ -1,14 +1,14 @@
using System.Windows;
using System.Windows.Controls;
-namespace Artemis.UI.Shared
+namespace Artemis.UI.Shared.Input
{
///
- /// Interaction logic for DataModelSelectionView.xaml
+ /// Interaction logic for DataModelDynamicView.xaml
///
- public partial class DataModelSelectionView : UserControl
+ public partial class DataModelDynamicView : UserControl
{
- public DataModelSelectionView()
+ public DataModelDynamicView()
{
InitializeComponent();
}
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs
similarity index 89%
rename from src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionViewModel.cs
rename to src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs
index 029290827..bc718153d 100644
--- a/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionViewModel.cs
+++ b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs
@@ -11,22 +11,21 @@ using Stylet;
// Remove, annoying while working on it
#pragma warning disable 1591
-namespace Artemis.UI.Shared
+namespace Artemis.UI.Shared.Input
{
- public class DataModelSelectionViewModel : PropertyChangedBase
+ public class DataModelDynamicViewModel : PropertyChangedBase
{
private readonly IDataModelUIService _dataModelUIService;
private readonly Module _module;
private readonly Timer _updateTimer;
private Brush _buttonBrush = new SolidColorBrush(Color.FromRgb(171, 71, 188));
-
private DataModelPropertiesViewModel _dataModelViewModel;
private bool _isDataModelViewModelOpen;
- private bool _isEnabled;
+ private bool _isEnabled = true;
private string _placeholder = "Select a property";
private DataModelVisualizationViewModel _selectedPropertyViewModel;
- public DataModelSelectionViewModel(Module module, ISettingsService settingsService, IDataModelUIService dataModelUIService)
+ internal DataModelDynamicViewModel(Module module, ISettingsService settingsService, IDataModelUIService dataModelUIService)
{
_module = module;
_dataModelUIService = dataModelUIService;
@@ -38,22 +37,18 @@ namespace Artemis.UI.Shared
Initialize();
}
- public string Placeholder
- {
- get => _placeholder;
- set => SetAndNotify(ref _placeholder, value);
- }
-
public Brush ButtonBrush
{
get => _buttonBrush;
set => SetAndNotify(ref _buttonBrush, value);
}
- public DelegateCommand SelectPropertyCommand { get; }
- public Type[] FilterTypes { get; set; }
- public PluginSetting ShowDataModelValues { get; }
+ public string Placeholder
+ {
+ get => _placeholder;
+ set => SetAndNotify(ref _placeholder, value);
+ }
public bool IsEnabled
{
@@ -61,6 +56,10 @@ namespace Artemis.UI.Shared
set => SetAndNotify(ref _isEnabled, value);
}
+ public Type[] FilterTypes { get; set; }
+ public DelegateCommand SelectPropertyCommand { get; }
+ public PluginSetting ShowDataModelValues { get; }
+
public DataModelPropertiesViewModel DataModelViewModel
{
get => _dataModelViewModel;
@@ -117,14 +116,15 @@ namespace Artemis.UI.Shared
return;
SelectedPropertyViewModel = selected;
- OnPropertySelected(new DataModelPropertySelectedEventArgs(selected));
+ OnPropertySelected(new DataModelInputDynamicEventArgs(selected));
}
+
#region Events
- public event EventHandler PropertySelected;
+ public event EventHandler PropertySelected;
- protected virtual void OnPropertySelected(DataModelPropertySelectedEventArgs e)
+ protected virtual void OnPropertySelected(DataModelInputDynamicEventArgs e)
{
PropertySelected?.Invoke(this, e);
}
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticView.xaml b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticView.xaml
new file mode 100644
index 000000000..6afe0edba
--- /dev/null
+++ b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticView.xaml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticView.xaml.cs b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticView.xaml.cs
new file mode 100644
index 000000000..5aacbb841
--- /dev/null
+++ b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticView.xaml.cs
@@ -0,0 +1,15 @@
+using System.Windows.Controls;
+
+namespace Artemis.UI.Shared.Input
+{
+ ///
+ /// Interaction logic for DataModelStaticView.xaml
+ ///
+ public partial class DataModelStaticView : UserControl
+ {
+ public DataModelStaticView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticViewModel.cs
new file mode 100644
index 000000000..7d4e23214
--- /dev/null
+++ b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticViewModel.cs
@@ -0,0 +1,116 @@
+using System;
+using System.Windows.Media;
+using Artemis.Core;
+using Artemis.Core.DataModelExpansions;
+using Artemis.UI.Shared.Services;
+using Stylet;
+
+// Remove, annoying while working on it
+#pragma warning disable 1591
+
+namespace Artemis.UI.Shared.Input
+{
+ public class DataModelStaticViewModel : PropertyChangedBase
+ {
+ private readonly IDataModelUIService _dataModelUIService;
+ private Brush _buttonBrush = new SolidColorBrush(Color.FromRgb(171, 71, 188));
+ private DataModelInputViewModel _inputViewModel;
+ private string _placeholder = "Enter a value";
+ private DataModelPropertyAttribute _targetDescription;
+ private Type _targetType;
+ private int _transitionIndex;
+ private object _value;
+
+ internal DataModelStaticViewModel(Type targetType, IDataModelUIService dataModelUIService)
+ {
+ TargetType = targetType;
+ _dataModelUIService = dataModelUIService;
+ }
+
+ public Brush ButtonBrush
+ {
+ get => _buttonBrush;
+ set => SetAndNotify(ref _buttonBrush, value);
+ }
+
+ public int TransitionIndex
+ {
+ get => _transitionIndex;
+ set => SetAndNotify(ref _transitionIndex, value);
+ }
+
+ public DataModelInputViewModel InputViewModel
+ {
+ get => _inputViewModel;
+ private set => SetAndNotify(ref _inputViewModel, value);
+ }
+
+ public Type TargetType
+ {
+ get => _targetType;
+ set => SetAndNotify(ref _targetType, value);
+ }
+
+ public DataModelPropertyAttribute TargetDescription
+ {
+ get => _targetDescription;
+ set => SetAndNotify(ref _targetDescription, value);
+ }
+
+ public object Value
+ {
+ get => _value;
+ set => SetAndNotify(ref _value, value);
+ }
+
+ public string Placeholder
+ {
+ get => _placeholder;
+ set => SetAndNotify(ref _placeholder, value);
+ }
+
+ public void ActivateInputViewModel()
+ {
+ TransitionIndex = 1;
+ InputViewModel = _dataModelUIService.GetDataModelInputViewModel(
+ TargetType,
+ TargetDescription,
+ Value,
+ ApplyFreeInput
+ );
+ }
+
+ public void UpdateTargetType(Type target)
+ {
+ TargetType = target ?? throw new ArgumentNullException(nameof(target));
+
+ // If the type changed, reset to the default type
+ if (!target.IsCastableFrom(Value.GetType()))
+ {
+ // Force the VM to close if it was open and apply the new value
+ ApplyFreeInput(target.GetDefault(), true);
+ }
+ }
+
+ private void ApplyFreeInput(object value, bool submitted)
+ {
+ if (submitted)
+ OnValueUpdated(new DataModelInputStaticEventArgs(value));
+
+ TransitionIndex = 0;
+ InputViewModel = null;
+ Value = value;
+ }
+
+ #region Events
+
+ public event EventHandler ValueUpdated;
+
+ protected virtual void OnValueUpdated(DataModelInputStaticEventArgs e)
+ {
+ ValueUpdated?.Invoke(this, e);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Events/DataModelPropertySelectedEventArgs.cs b/src/Artemis.UI.Shared/Events/DataModelInputDynamicEventArgs.cs
similarity index 58%
rename from src/Artemis.UI.Shared/Events/DataModelPropertySelectedEventArgs.cs
rename to src/Artemis.UI.Shared/Events/DataModelInputDynamicEventArgs.cs
index 81bb38629..9f7649dbb 100644
--- a/src/Artemis.UI.Shared/Events/DataModelPropertySelectedEventArgs.cs
+++ b/src/Artemis.UI.Shared/Events/DataModelInputDynamicEventArgs.cs
@@ -2,11 +2,11 @@
namespace Artemis.UI.Shared
{
- public class DataModelPropertySelectedEventArgs : EventArgs
+ public class DataModelInputDynamicEventArgs : EventArgs
{
public DataModelVisualizationViewModel DataModelVisualizationViewModel { get; }
- public DataModelPropertySelectedEventArgs(DataModelVisualizationViewModel dataModelVisualizationViewModel)
+ public DataModelInputDynamicEventArgs(DataModelVisualizationViewModel dataModelVisualizationViewModel)
{
DataModelVisualizationViewModel = dataModelVisualizationViewModel;
}
diff --git a/src/Artemis.UI.Shared/Events/DataModelInputStaticEventArgs.cs b/src/Artemis.UI.Shared/Events/DataModelInputStaticEventArgs.cs
new file mode 100644
index 000000000..278681dd6
--- /dev/null
+++ b/src/Artemis.UI.Shared/Events/DataModelInputStaticEventArgs.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace Artemis.UI.Shared
+{
+ public class DataModelInputStaticEventArgs : EventArgs
+ {
+ public object Value { get; }
+
+ public DataModelInputStaticEventArgs(object value)
+ {
+ Value = value;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Services/DataModelUIService.cs b/src/Artemis.UI.Shared/Services/DataModelUIService.cs
index b8ead4820..73e34e9e6 100644
--- a/src/Artemis.UI.Shared/Services/DataModelUIService.cs
+++ b/src/Artemis.UI.Shared/Services/DataModelUIService.cs
@@ -5,6 +5,7 @@ using Artemis.Core;
using Artemis.Core.DataModelExpansions;
using Artemis.Core.Modules;
using Artemis.Core.Services;
+using Artemis.UI.Shared.Input;
using Ninject;
using Ninject.Parameters;
@@ -179,9 +180,15 @@ namespace Artemis.UI.Shared.Services
}
}
- public DataModelSelectionViewModel GetDataModelSelectionViewModel(Module module)
+ public DataModelDynamicViewModel GetDynamicSelectionViewModel(Module module)
{
- return _kernel.Get(new ConstructorArgument("module", module));
+ return _kernel.Get(new ConstructorArgument("module", module));
+ }
+
+ public DataModelStaticViewModel GetStaticInputViewModel(Type targetType)
+ {
+ if (targetType == null) throw new ArgumentNullException(nameof(targetType));
+ return _kernel.Get(new ConstructorArgument("targetType", targetType));
}
private DataModelInputViewModel InstantiateDataModelInputViewModel(DataModelVisualizationRegistration registration, DataModelPropertyAttribute description, object initialValue)
diff --git a/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs b/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs
index f4ee8cc13..049a1bf11 100644
--- a/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs
+++ b/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using Artemis.Core;
using Artemis.Core.DataModelExpansions;
using Artemis.Core.Modules;
+using Artemis.UI.Shared.Input;
namespace Artemis.UI.Shared.Services
{
@@ -28,6 +29,7 @@ namespace Artemis.UI.Shared.Services
DataModelDisplayViewModel GetDataModelDisplayViewModel(Type propertyType);
DataModelInputViewModel GetDataModelInputViewModel(Type propertyType, DataModelPropertyAttribute description, object initialValue, Action updateCallback);
- DataModelSelectionViewModel GetDataModelSelectionViewModel(Module module);
+ DataModelDynamicViewModel GetDynamicSelectionViewModel(Module module);
+ DataModelStaticViewModel GetStaticInputViewModel(Type targetType);
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Services/ProfileEditorService.cs b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs
index 5c2395661..ac437396b 100644
--- a/src/Artemis.UI.Shared/Services/ProfileEditorService.cs
+++ b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs
@@ -111,6 +111,8 @@ namespace Artemis.UI.Shared.Services
var profileElementEvent = new RenderProfileElementEventArgs(profileElement, SelectedProfileElement);
SelectedProfileElement = profileElement;
OnSelectedProfileElementChanged(profileElementEvent);
+
+ ChangeSelectedDataBinding(null);
}
}
diff --git a/src/Artemis.UI/DataModelVisualization/Input/DoubleDataModelInputViewModel.cs b/src/Artemis.UI/DataModelVisualization/Input/DoubleDataModelInputViewModel.cs
index f4953e318..9099ea2c6 100644
--- a/src/Artemis.UI/DataModelVisualization/Input/DoubleDataModelInputViewModel.cs
+++ b/src/Artemis.UI/DataModelVisualization/Input/DoubleDataModelInputViewModel.cs
@@ -8,7 +8,7 @@ namespace Artemis.UI.DataModelVisualization.Input
{
public class DoubleDataModelInputViewModel : DataModelInputViewModel
{
- public DoubleDataModelInputViewModel(DataModelPropertyAttribute description, double initialValue) : base(description, initialValue)
+ public DoubleDataModelInputViewModel(DataModelPropertyAttribute targetDescription, double initialValue) : base(targetDescription, initialValue)
{
}
diff --git a/src/Artemis.UI/DataModelVisualization/Input/IntDataModelInputViewModel.cs b/src/Artemis.UI/DataModelVisualization/Input/IntDataModelInputViewModel.cs
index 9317f38e3..f4fce549f 100644
--- a/src/Artemis.UI/DataModelVisualization/Input/IntDataModelInputViewModel.cs
+++ b/src/Artemis.UI/DataModelVisualization/Input/IntDataModelInputViewModel.cs
@@ -7,7 +7,7 @@ namespace Artemis.UI.DataModelVisualization.Input
{
public class IntDataModelInputViewModel : DataModelInputViewModel
{
- public IntDataModelInputViewModel(DataModelPropertyAttribute description, int initialValue) : base(description, initialValue)
+ public IntDataModelInputViewModel(DataModelPropertyAttribute targetDescription, int initialValue) : base(targetDescription, initialValue)
{
}
diff --git a/src/Artemis.UI/DataModelVisualization/Input/StringDataModelInputViewModel.cs b/src/Artemis.UI/DataModelVisualization/Input/StringDataModelInputViewModel.cs
index f7a42f01a..4f8818eca 100644
--- a/src/Artemis.UI/DataModelVisualization/Input/StringDataModelInputViewModel.cs
+++ b/src/Artemis.UI/DataModelVisualization/Input/StringDataModelInputViewModel.cs
@@ -5,7 +5,7 @@ namespace Artemis.UI.DataModelVisualization.Input
{
public class StringDataModelInputViewModel : DataModelInputViewModel
{
- public StringDataModelInputViewModel(DataModelPropertyAttribute description, string initialValue) : base(description, initialValue)
+ public StringDataModelInputViewModel(DataModelPropertyAttribute targetDescription, string initialValue) : base(targetDescription, initialValue)
{
}
diff --git a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
index 137a6d77d..68df7dd44 100644
--- a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
+++ b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
@@ -81,7 +81,7 @@ namespace Artemis.UI.Ninject.Factories
public interface IDataBindingsVmFactory : IVmFactory
{
DataBindingsViewModel DataBindingsViewModel(BaseLayerProperty layerProperty);
- DataBindingViewModel DataBindingViewModel(BaseLayerProperty layerProperty, PropertyInfo targetProperty);
+ DataBindingViewModel DataBindingViewModel(DataBindingRegistration registration);
DataBindingModifierViewModel DataBindingModifierViewModel(DataBindingModifier modifier);
}
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierView.xaml
index f8edd20cf..a3aaf5c56 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierView.xaml
@@ -62,8 +62,8 @@
Style="{StaticResource DisplayConditionButtonLeftClickMenu}"
Background="#7B7B7B"
BorderBrush="#7B7B7B"
- Content="{Binding SelectedModifierType.Description}">
-
+ Content="{Binding SelectedModifierType.Description}"
+ Click="PropertyButton_OnClick">
@@ -85,34 +85,7 @@
-
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierView.xaml.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierView.xaml.cs
index ab48662ff..53ba23175 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierView.xaml.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierView.xaml.cs
@@ -22,5 +22,15 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
{
InitializeComponent();
}
+
+ private void PropertyButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ // DataContext is not set when using left button, I don't know why but there it is
+ if (sender is Button button && button.ContextMenu != null)
+ {
+ button.ContextMenu.DataContext = button.DataContext;
+ button.ContextMenu.IsOpen = true;
+ }
+ }
}
}
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierViewModel.cs
index 3b76ea7e4..58849824e 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierViewModel.cs
@@ -1,7 +1,10 @@
-using System.Threading.Tasks;
+using System;
+using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.Services;
+using Artemis.UI.Exceptions;
using Artemis.UI.Shared;
+using Artemis.UI.Shared.Input;
using Artemis.UI.Shared.Services;
using Stylet;
@@ -13,6 +16,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
private readonly IDataModelUIService _dataModelUIService;
private readonly IProfileEditorService _profileEditorService;
private DataBindingModifierType _selectedModifierType;
+ private DataModelDynamicViewModel _dynamicSelectionViewModel;
+ private DataModelStaticViewModel _staticInputViewModel;
public DataBindingModifierViewModel(DataBindingModifier modifier,
IDataBindingService dataBindingService,
@@ -32,11 +37,10 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
SelectModifierTypeCommand = new DelegateCommand(ExecuteSelectModifierTypeCommand);
// Initialize async, no need to wait for it
- Task.Run(Initialize);
+ Execute.PostToUIThread(Update);
}
- public DelegateCommand SelectModifierTypeCommand { get; set; }
-
+ public DelegateCommand SelectModifierTypeCommand { get; }
public PluginSetting ShowDataModelValues { get; }
public DataBindingModifier Modifier { get; }
public BindableCollection ModifierTypes { get; }
@@ -47,30 +51,63 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
set => SetAndNotify(ref _selectedModifierType, value);
}
- public DataModelSelectionViewModel ParameterSelectionViewModel { get; private set; }
-
- private void Initialize()
+ public DataModelDynamicViewModel DynamicSelectionViewModel
{
- ParameterSelectionViewModel = _dataModelUIService.GetDataModelSelectionViewModel(_profileEditorService.GetCurrentModule());
- ParameterSelectionViewModel.PropertySelected += ParameterSelectionViewModelOnPropertySelected;
- ParameterSelectionViewModel.FilterTypes = new[] {Modifier.DataBinding.TargetProperty.PropertyType};
-
- Update();
+ get => _dynamicSelectionViewModel;
+ private set => SetAndNotify(ref _dynamicSelectionViewModel, value);
}
- private void ParameterSelectionViewModelOnPropertySelected(object sender, DataModelPropertySelectedEventArgs e)
+ public DataModelStaticViewModel StaticInputViewModel
+ {
+ get => _staticInputViewModel;
+ private set => SetAndNotify(ref _staticInputViewModel, value);
+ }
+
+ private void ParameterSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
{
Modifier.UpdateParameter(e.DataModelVisualizationViewModel.DataModel, e.DataModelVisualizationViewModel.PropertyPath);
}
+ private void StaticInputViewModelOnValueUpdated(object sender, DataModelInputStaticEventArgs e)
+ {
+ Modifier.UpdateParameter(e.Value);
+ }
+
private void Update()
{
+ var sourceType = Modifier.DataBinding.GetSourceType();
+ if (sourceType == null)
+ throw new ArtemisUIException("Cannot use a data binding modifier VM for a data binding without a source");
+
+ if (Modifier.ModifierType == null || !Modifier.ModifierType.SupportsParameter)
+ {
+ StaticInputViewModel = null;
+ DynamicSelectionViewModel = null;
+ }
+ else if (Modifier.ParameterType == ProfileRightSideType.Dynamic)
+ {
+ StaticInputViewModel = null;
+ DynamicSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
+ DynamicSelectionViewModel.PropertySelected += ParameterSelectionViewModelOnPropertySelected;
+ DynamicSelectionViewModel.FilterTypes = new[] { sourceType };
+ }
+ else
+ {
+ DynamicSelectionViewModel = null;
+ StaticInputViewModel = _dataModelUIService.GetStaticInputViewModel(sourceType);
+ StaticInputViewModel.ValueUpdated += StaticInputViewModelOnValueUpdated;
+ }
+
// Modifier type
ModifierTypes.Clear();
- ModifierTypes.AddRange(_dataBindingService.GetCompatibleModifierTypes(Modifier.DataBinding.TargetProperty.PropertyType));
+ ModifierTypes.AddRange(_dataBindingService.GetCompatibleModifierTypes(sourceType));
SelectedModifierType = Modifier.ModifierType;
- ParameterSelectionViewModel.PopulateSelectedPropertyViewModel(Modifier.ParameterDataModel, Modifier.ParameterPropertyPath);
+ // Parameter
+ if (DynamicSelectionViewModel != null)
+ DynamicSelectionViewModel?.PopulateSelectedPropertyViewModel(Modifier.ParameterDataModel, Modifier.ParameterPropertyPath);
+ else if (StaticInputViewModel != null)
+ StaticInputViewModel.Value = Modifier.ParameterStaticValue;
}
private void ExecuteSelectModifierTypeCommand(object context)
@@ -83,5 +120,20 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
Update();
}
+
+ public void Delete()
+ {
+ Modifier.DataBinding.RemoveModifier(Modifier);
+ }
+
+ public void SwapType()
+ {
+ if (Modifier.ParameterType == ProfileRightSideType.Dynamic)
+ Modifier.UpdateParameter(Modifier.DataBinding.GetSourceType().GetDefault());
+ else
+ Modifier.UpdateParameter(null, null);
+
+ Update();
+ }
}
}
\ 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 38e7f3806..0afdbd491 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml
@@ -42,43 +42,46 @@
-
- Replace value
-
-
- Add to value
-
-
- Subtract from value
-
+ SelectedValue="{Binding SelectedDataBindingMode}" ItemsSource="{Binding DataBindingModes}" SelectedValuePath="Value" DisplayMemberPath="Description" >
-
- Ease in
-
-
- Ease out
-
-
- Ease in and out
-
+ IsEnabled="{Binding IsEasingTimeEnabled}"
+ SelectedItem="{Binding SelectedEasingViewModel}"
+ ItemsSource="{Binding EasingViewModels}">
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -102,10 +105,10 @@
Input
-
+
Output
-
+
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml.cs
index 24e8655ff..61f02ab77 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml.cs
@@ -12,15 +12,5 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
{
InitializeComponent();
}
-
- private void PropertyButton_OnClick(object sender, RoutedEventArgs e)
- {
- // DataContext is not set when using left button, I don't know why but there it is
- if (sender is Button button && button.ContextMenu != null)
- {
- button.ContextMenu.DataContext = button.DataContext;
- button.ContextMenu.IsOpen = true;
- }
- }
}
}
\ 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 f3e99961d..6397b9437 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs
@@ -1,65 +1,101 @@
using System;
-using System.Collections.Generic;
using System.Linq;
-using System.Reflection;
-using System.Threading.Tasks;
-using System.Timers;
using Artemis.Core;
-using Artemis.Core.Services;
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 Artemis.UI.Utilities;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
{
- public class DataBindingViewModel : PropertyChangedBase
+ public class DataBindingViewModel : PropertyChangedBase, IDisposable
{
- private readonly IDataModelUIService _dataModelUIService;
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
+ private readonly IDataModelUIService _dataModelUIService;
private readonly IProfileEditorService _profileEditorService;
- private readonly Timer _updateTimer;
private DataBinding _dataBinding;
+ private int _easingTime;
private bool _isDataBindingEnabled;
- private DataModelPropertiesViewModel _sourceDataModel;
- private DataModelVisualizationViewModel _selectedSourceProperty;
- private bool _sourceDataModelOpen;
+ private bool _isEasingTimeEnabled;
+ private DataBindingMode _selectedDataBindingMode;
+ private TimelineEasingViewModel _selectedEasingViewModel;
+ private DataModelDynamicViewModel _targetSelectionViewModel;
private object _testInputValue;
private object _testResultValue;
- private DataModelSelectionViewModel _targetSelectionViewModel;
+ private bool _updating;
- public DataBindingViewModel(BaseLayerProperty layerProperty,
- PropertyInfo targetProperty,
+ public DataBindingViewModel(DataBindingRegistration registration,
IProfileEditorService profileEditorService,
IDataModelUIService dataModelUIService,
IDataBindingsVmFactory dataBindingsVmFactory)
{
+ Registration = registration;
_profileEditorService = profileEditorService;
_dataModelUIService = dataModelUIService;
_dataBindingsVmFactory = dataBindingsVmFactory;
- _updateTimer = new Timer(500);
- DisplayName = targetProperty.Name.ToUpper();
-
- LayerProperty = layerProperty;
- TargetProperty = targetProperty;
- DataBinding = layerProperty.DataBindings.FirstOrDefault(d => d.TargetProperty == targetProperty);
+ DisplayName = Registration.Property.Name.ToUpper();
+ DataBindingModes = new BindableCollection(EnumUtilities.GetAllValuesAndDescriptions(typeof(DataBindingMode)));
+ EasingViewModels = new BindableCollection();
ModifierViewModels = new BindableCollection();
+ DataBinding = Registration.DataBinding;
+ if (DataBinding != null)
+ DataBinding.ModifiersUpdated += DataBindingOnModifiersUpdated;
+
_isDataBindingEnabled = DataBinding != null;
// Initialize async, no need to wait for it
Execute.PostToUIThread(Initialize);
}
- public BaseLayerProperty LayerProperty { get; }
- public PropertyInfo TargetProperty { get; }
+ public DataBindingRegistration Registration { get; }
public string DisplayName { get; }
+
+ public BindableCollection DataBindingModes { get; }
+ public BindableCollection EasingViewModels { get; }
public BindableCollection ModifierViewModels { get; }
- public DataModelSelectionViewModel TargetSelectionViewModel
+ public DataBindingMode SelectedDataBindingMode
+ {
+ get => _selectedDataBindingMode;
+ set => SetAndNotify(ref _selectedDataBindingMode, value);
+ }
+
+ public TimelineEasingViewModel SelectedEasingViewModel
+ {
+ get => _selectedEasingViewModel;
+ set
+ {
+ if (!SetAndNotify(ref _selectedEasingViewModel, value)) return;
+ ApplyChanges();
+ }
+ }
+
+ public int EasingTime
+ {
+ get => _easingTime;
+ set
+ {
+ if (!SetAndNotify(ref _easingTime, value)) return;
+ ApplyChanges();
+ }
+ }
+
+ public bool IsEasingTimeEnabled
+ {
+ get => _isEasingTimeEnabled;
+ set
+ {
+ if (!SetAndNotify(ref _isEasingTimeEnabled, value)) return;
+ ApplyChanges();
+ }
+ }
+
+ public DataModelDynamicViewModel TargetSelectionViewModel
{
get => _targetSelectionViewModel;
private set => SetAndNotify(ref _targetSelectionViewModel, value);
@@ -105,8 +141,11 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
if (DataBinding != null)
return;
- DataBinding = LayerProperty.AddDataBinding(TargetProperty);
+ DataBinding = Registration.LayerProperty.EnableDataBinding(Registration);
+ DataBinding.ModifiersUpdated += DataBindingOnModifiersUpdated;
Update();
+
+ _profileEditorService.UpdateSelectedProfileElement();
}
public void RemoveDataBinding()
@@ -114,10 +153,13 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
if (DataBinding == null)
return;
- var toRemove = DataBinding;
+ var toDisable = DataBinding;
DataBinding = null;
- LayerProperty.RemoveDataBinding(toRemove);
+ Registration.LayerProperty.DisableDataBinding(toDisable);
+ toDisable.ModifiersUpdated -= DataBindingOnModifiersUpdated;
Update();
+
+ _profileEditorService.UpdateSelectedProfileElement();
}
public void AddModifier()
@@ -128,50 +170,67 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
var modifier = new DataBindingModifier(ProfileRightSideType.Dynamic);
DataBinding.AddModifier(modifier);
- ModifierViewModels.Add(_dataBindingsVmFactory.DataBindingModifierViewModel(modifier));
+ _profileEditorService.UpdateSelectedProfileElement();
}
private void Initialize()
{
- TargetSelectionViewModel = _dataModelUIService.GetDataModelSelectionViewModel(_profileEditorService.GetCurrentModule());
+ EasingViewModels.AddRange(Enum.GetValues(typeof(Easings.Functions)).Cast().Select(v => new TimelineEasingViewModel(null, v)));
+ TargetSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
TargetSelectionViewModel.PropertySelected += TargetSelectionViewModelOnPropertySelected;
+ _profileEditorService.ProfilePreviewUpdated += ProfileEditorServiceOnProfilePreviewUpdated;
Update();
-
- _updateTimer.Start();
- _updateTimer.Elapsed += OnUpdateTimerOnElapsed;
}
private void Update()
{
+ if (_updating)
+ return;
+
if (DataBinding == null)
{
TargetSelectionViewModel.IsEnabled = false;
+ IsEasingTimeEnabled = false;
return;
}
+ _updating = true;
+
+ SelectedDataBindingMode = DataBinding.Mode;
+ EasingTime = (int) DataBinding.EasingTime.TotalMilliseconds;
+ SelectedEasingViewModel = EasingViewModels.First(vm => vm.EasingFunction == DataBinding.EasingFunction);
+ IsEasingTimeEnabled = EasingTime > 0;
+
TargetSelectionViewModel.IsEnabled = true;
TargetSelectionViewModel.PopulateSelectedPropertyViewModel(DataBinding.SourceDataModel, DataBinding.SourcePropertyPath);
TargetSelectionViewModel.FilterTypes = new[] {DataBinding.TargetProperty.PropertyType};
+
+ UpdateModifierViewModels();
+
+ _updating = false;
}
- private void TargetSelectionViewModelOnPropertySelected(object sender, DataModelPropertySelectedEventArgs e)
+ private void ApplyChanges()
{
- DataBinding.UpdateSource(e.DataModelVisualizationViewModel.DataModel, e.DataModelVisualizationViewModel.PropertyPath);
- }
+ if (_updating)
+ return;
- private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
- {
- UpdateTestResult();
+ DataBinding.Mode = SelectedDataBindingMode;
+ DataBinding.EasingTime = TimeSpan.FromMilliseconds(EasingTime);
+ DataBinding.EasingFunction = SelectedEasingViewModel?.EasingFunction ?? Easings.Functions.Linear;
+
+ _profileEditorService.UpdateSelectedProfileElement();
+ Update();
}
private void UpdateTestResult()
{
var currentValue = TargetSelectionViewModel.SelectedPropertyViewModel?.GetCurrentValue();
- if (currentValue == null && TargetProperty.PropertyType.IsValueType)
- currentValue = Activator.CreateInstance(TargetProperty.PropertyType);
+ if (currentValue == null && Registration.Property.PropertyType.IsValueType)
+ currentValue = Activator.CreateInstance(Registration.Property.PropertyType);
- TestInputValue = Convert.ChangeType(currentValue, TargetProperty.PropertyType);
+ TestInputValue = Convert.ChangeType(currentValue, Registration.Property.PropertyType);
TestResultValue = DataBinding?.GetValue(TestInputValue);
}
@@ -185,5 +244,28 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
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);
+ _profileEditorService.UpdateSelectedProfileElement();
+ }
+
+ public void Dispose()
+ {
+ _profileEditorService.ProfilePreviewUpdated -= ProfileEditorServiceOnProfilePreviewUpdated;
+ TargetSelectionViewModel.PropertySelected -= TargetSelectionViewModelOnPropertySelected;
+ if (DataBinding != null)
+ DataBinding.ModifiersUpdated -= DataBindingOnModifiersUpdated;
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingsViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingsViewModel.cs
index 0f58e2313..585abf21f 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingsViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingsViewModel.cs
@@ -1,11 +1,12 @@
-using System.Linq;
+using System;
+using System.Linq;
using Artemis.Core;
using Artemis.UI.Ninject.Factories;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
{
- public class DataBindingsViewModel : PropertyChangedBase
+ public class DataBindingsViewModel : PropertyChangedBase, IDisposable
{
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
private DataBindingsTabsViewModel _dataBindingsTabsViewModel;
@@ -34,23 +35,29 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
private void Initialise()
{
+ DataBindingViewModel?.Dispose();
DataBindingViewModel = null;
DataBindingsTabsViewModel = null;
- var properties = LayerProperty.GetDataBindingProperties();
- if (properties == null || properties.Count == 0)
+ var registrations = LayerProperty.DataBindingRegistrations;
+ if (registrations == null || registrations.Count == 0)
return;
// Create a data binding VM for each data bindable property. These VMs will be responsible for retrieving
// and creating the actual data bindings
- if (properties.Count == 1)
- DataBindingViewModel = _dataBindingsVmFactory.DataBindingViewModel(LayerProperty, properties.First());
+ if (registrations.Count == 1)
+ DataBindingViewModel = _dataBindingsVmFactory.DataBindingViewModel(registrations.First());
else
{
DataBindingsTabsViewModel = new DataBindingsTabsViewModel();
- foreach (var dataBindingProperty in properties)
- DataBindingsTabsViewModel.Tabs.Add(_dataBindingsVmFactory.DataBindingViewModel(LayerProperty, dataBindingProperty));
+ foreach (var registration in registrations)
+ DataBindingsTabsViewModel.Tabs.Add(_dataBindingsVmFactory.DataBindingViewModel(registration));
}
}
+
+ public void Dispose()
+ {
+ DataBindingViewModel?.Dispose();
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs
index a2f45e84f..4aebe4602 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs
@@ -204,6 +204,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
MainTimelineSegmentViewModel = null;
EndTimelineSegmentViewModel?.Dispose();
EndTimelineSegmentViewModel = null;
+ DataBindingsViewModel?.Dispose();
+ DataBindingsViewModel = null;
base.OnClose();
}
@@ -241,6 +243,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
if (ProfileEditorService.SelectedDataBinding != null)
{
RightSideIndex = 1;
+ DataBindingsViewModel?.Dispose();
DataBindingsViewModel = _dataBindingsVmFactory.DataBindingsViewModel(ProfileEditorService.SelectedDataBinding);
}
else
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelineEasingViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelineEasingViewModel.cs
index 4459ac59b..a89e161cb 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelineEasingViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelineEasingViewModel.cs
@@ -12,8 +12,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline
public TimelineEasingViewModel(TimelineKeyframeViewModel keyframeViewModel, Easings.Functions easingFunction)
{
- _keyframeViewModel = keyframeViewModel;
- _isEasingModeSelected = keyframeViewModel.BaseLayerPropertyKeyframe.EasingFunction == easingFunction;
+ // Can be null if used by DataBindingViewModel because I'm lazy
+ if (keyframeViewModel != null)
+ {
+ _keyframeViewModel = keyframeViewModel;
+ _isEasingModeSelected = keyframeViewModel.BaseLayerPropertyKeyframe.EasingFunction == easingFunction;
+ }
EasingFunction = easingFunction;
Description = easingFunction.Humanize();
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelinePropertyView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelinePropertyView.xaml
index 93b1a3a3d..5fcb44d45 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelinePropertyView.xaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Timeline/TimelinePropertyView.xaml
@@ -102,11 +102,6 @@
-
-
-
-
-
diff --git a/src/Plugins/Artemis.Plugins.Modules.General/DataModels/GeneralDataModel.cs b/src/Plugins/Artemis.Plugins.Modules.General/DataModels/GeneralDataModel.cs
index 3c678439a..da72828a4 100644
--- a/src/Plugins/Artemis.Plugins.Modules.General/DataModels/GeneralDataModel.cs
+++ b/src/Plugins/Artemis.Plugins.Modules.General/DataModels/GeneralDataModel.cs
@@ -28,7 +28,7 @@ namespace Artemis.Plugins.Modules.General.DataModels
public class TimeDataModel : DataModel
{
- public DateTime CurrentTime { get; set; }
- public DateTime CurrentTimeUTC { get; set; }
+ public DateTimeOffset CurrentTime { get; set; }
+ public TimeSpan TimeSinceMidnight { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs b/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs
index 92b7ae2f8..e6bfecda7 100644
--- a/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs
+++ b/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs
@@ -20,10 +20,10 @@ namespace Artemis.Plugins.Modules.General
ExpandsDataModel = true;
ModuleTabs = new List {new ModuleTab("General")};
- DataModel.TestTimeList.Add(new TimeDataModel {CurrentTime = DateTime.Now.AddDays(1), CurrentTimeUTC = DateTime.UtcNow.AddDays(1)});
- DataModel.TestTimeList.Add(new TimeDataModel {CurrentTime = DateTime.Now.AddDays(2), CurrentTimeUTC = DateTime.UtcNow.AddDays(2)});
- DataModel.TestTimeList.Add(new TimeDataModel {CurrentTime = DateTime.Now.AddDays(3), CurrentTimeUTC = DateTime.UtcNow.AddDays(3)});
- DataModel.TestTimeList.Add(new TimeDataModel {CurrentTime = DateTime.Now.AddDays(4), CurrentTimeUTC = DateTime.UtcNow.AddDays(4)});
+ DataModel.TestTimeList.Add(new TimeDataModel {CurrentTime = DateTimeOffset.Now.AddDays(1)});
+ DataModel.TestTimeList.Add(new TimeDataModel {CurrentTime = DateTimeOffset.Now.AddDays(2)});
+ DataModel.TestTimeList.Add(new TimeDataModel {CurrentTime = DateTimeOffset.Now.AddDays(3)});
+ DataModel.TestTimeList.Add(new TimeDataModel {CurrentTime = DateTimeOffset.Now.AddDays(4)});
}
public override void DisablePlugin()
@@ -40,9 +40,8 @@ namespace Artemis.Plugins.Modules.General
public override void Update(double deltaTime)
{
- DataModel.TimeDataModel.CurrentTime = DateTime.Now;
- DataModel.TimeDataModel.CurrentTimeUTC = DateTime.UtcNow;
-
+ DataModel.TimeDataModel.CurrentTime = DateTimeOffset.Now;
+ DataModel.TimeDataModel.TimeSinceMidnight = DateTimeOffset.Now - DateTimeOffset.Now.Date;
UpdateCurrentWindow();
}
diff --git a/src/Plugins/Artemis.Plugins.Modules.General/ViewModels/GeneralViewModel.cs b/src/Plugins/Artemis.Plugins.Modules.General/ViewModels/GeneralViewModel.cs
index 5f03501c0..6c8788095 100644
--- a/src/Plugins/Artemis.Plugins.Modules.General/ViewModels/GeneralViewModel.cs
+++ b/src/Plugins/Artemis.Plugins.Modules.General/ViewModels/GeneralViewModel.cs
@@ -11,14 +11,14 @@ namespace Artemis.Plugins.Modules.General.ViewModels
public GeneralModule GeneralModule { get; }
- public void ShowUTCTimeInDataModel()
+ public void ShowTimeInDataModel()
{
- GeneralModule.ShowProperty(model => model.TimeDataModel.CurrentTimeUTC);
+ GeneralModule.ShowProperty(model => model.TimeDataModel.CurrentTime);
}
- public void HideUTCTimeInDataModel()
+ public void HideTimeInDataModel()
{
- GeneralModule.HideProperty(model => model.TimeDataModel.CurrentTimeUTC);
+ GeneralModule.HideProperty(model => model.TimeDataModel.CurrentTime);
}
}
}
\ No newline at end of file
diff --git a/src/Plugins/Artemis.Plugins.Modules.General/Views/GeneralView.xaml b/src/Plugins/Artemis.Plugins.Modules.General/Views/GeneralView.xaml
index 414fe8ccc..228bbe4c3 100644
--- a/src/Plugins/Artemis.Plugins.Modules.General/Views/GeneralView.xaml
+++ b/src/Plugins/Artemis.Plugins.Modules.General/Views/GeneralView.xaml
@@ -11,12 +11,12 @@
-