diff --git a/src/Artemis.Core/Artemis.Core.csproj.DotSettings b/src/Artemis.Core/Artemis.Core.csproj.DotSettings index 44ebfc334..77021d436 100644 --- a/src/Artemis.Core/Artemis.Core.csproj.DotSettings +++ b/src/Artemis.Core/Artemis.Core.csproj.DotSettings @@ -10,6 +10,7 @@ True True True + True True True True diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Converters/FloatDataBindingConverter.cs b/src/Artemis.Core/Models/Profile/DataBindings/Converters/FloatDataBindingConverter.cs index c0d8a49be..32879ff29 100644 --- a/src/Artemis.Core/Models/Profile/DataBindings/Converters/FloatDataBindingConverter.cs +++ b/src/Artemis.Core/Models/Profile/DataBindings/Converters/FloatDataBindingConverter.cs @@ -1,30 +1,42 @@ using System; -using System.Collections.Generic; -using System.Text; -namespace Artemis.Core.Models.Profile.DataBindings.Converters +namespace Artemis.Core { - public class FloatDataBindingConverter : IDataBindingConverter + /// + public class FloatDataBindingConverter : IDataBindingConverter { - public BaseLayerProperty BaseLayerProperty { get; set; } - public object Sum(object a, object b) + /// + public Type SupportedType => typeof(float); + + /// + public bool SupportsSum => true; + + /// + public bool SupportsInterpolate => true; + + /// + public object Sum(BaseLayerProperty layerProperty, object a, object b) { return (float) a + (float) b; } - public object Interpolate(object a, object b, float progress) + /// + public object Interpolate(BaseLayerProperty layerProperty, object a, object b, float progress) { - throw new NotImplementedException(); + var diff = (float) b - (float) a; + return diff * progress; } - public void ApplyValue(object value) + /// + public void ApplyValue(BaseLayerProperty layerProperty, object value) { - throw new NotImplementedException(); + layerProperty.CurrentValue = value; } - public object GetValue() + /// + public object GetValue(BaseLayerProperty layerProperty) { - throw new NotImplementedException(); + return layerProperty.CurrentValue; } } -} +} \ 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..637d5f437 --- /dev/null +++ b/src/Artemis.Core/Models/Profile/DataBindings/Converters/GeneralDataBindingConverter.cs @@ -0,0 +1,41 @@ +using System; + +namespace Artemis.Core +{ + /// + public class GeneralDataBindingConverter : IDataBindingConverter + { + /// + public Type SupportedType => typeof(object); + + /// + public bool SupportsSum => false; + + /// + public bool SupportsInterpolate => false; + + /// + public object Sum(BaseLayerProperty layerProperty, object a, object b) + { + throw new NotSupportedException(); + } + + /// + public object Interpolate(BaseLayerProperty layerProperty, object a, object b, float progress) + { + throw new NotSupportedException(); + } + + /// + public void ApplyValue(BaseLayerProperty layerProperty, object value) + { + layerProperty.CurrentValue = value; + } + + /// + public object GetValue(BaseLayerProperty layerProperty) + { + return layerProperty.CurrentValue; + } + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Converters/IntDataBindingConverter.cs b/src/Artemis.Core/Models/Profile/DataBindings/Converters/IntDataBindingConverter.cs new file mode 100644 index 000000000..c34eaf779 --- /dev/null +++ b/src/Artemis.Core/Models/Profile/DataBindings/Converters/IntDataBindingConverter.cs @@ -0,0 +1,42 @@ +using System; + +namespace Artemis.Core +{ + /// + public class IntDataBindingConverter : IDataBindingConverter + { + /// + public Type SupportedType => typeof(int); + + /// + public bool SupportsSum => true; + + /// + public bool SupportsInterpolate => true; + + /// + public object Sum(BaseLayerProperty layerProperty, object a, object b) + { + return (int) a + (int) b; + } + + /// + public object Interpolate(BaseLayerProperty layerProperty, object a, object b, float progress) + { + var diff = (int) b - (int) a; + return diff * progress; + } + + /// + public void ApplyValue(BaseLayerProperty layerProperty, object value) + { + layerProperty.CurrentValue = value; + } + + /// + public object GetValue(BaseLayerProperty layerProperty) + { + return layerProperty.CurrentValue; + } + } +} \ 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..8176e9efc --- /dev/null +++ b/src/Artemis.Core/Models/Profile/DataBindings/Converters/Internal/SKColorPartDataBindingConverter.cs @@ -0,0 +1,106 @@ +using System; +using SkiaSharp; + +namespace Artemis.Core +{ + // This is internal because it's mainly a proof-of-concept + internal class SKColorPartDataBindingConverter : IDataBindingConverter + { + private readonly Channel _channel; + + public SKColorPartDataBindingConverter(Channel channel) + { + _channel = channel; + } + + // This depends on what channel was passed + public Type SupportedType + { + get + { + switch (_channel) + { + case Channel.Alpha: + case Channel.Red: + case Channel.Green: + case Channel.Blue: + return typeof(byte); + case Channel.Hue: + return typeof(float); + default: + throw new ArgumentOutOfRangeException(); + } + } + } + + public bool SupportsSum => true; + public bool SupportsInterpolate => true; + + public object Sum(BaseLayerProperty layerProperty, object a, object b) + { + return (float) a + (float) b; + } + + public object Interpolate(BaseLayerProperty layerProperty, object a, object b, float progress) + { + var diff = (float) b - (float) a; + return diff * progress; + } + + public void ApplyValue(BaseLayerProperty layerProperty, object value) + { + var property = (SKColorLayerProperty) 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 object GetValue(BaseLayerProperty layerProperty) + { + var property = (SKColorLayerProperty) 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 9e34edc09..2d926fea3 100644 --- a/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs +++ b/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs @@ -24,16 +24,12 @@ namespace Artemis.Core internal DataBinding(DataBindingRegistration dataBindingRegistration) { LayerProperty = dataBindingRegistration.LayerProperty; - TargetProperty = dataBindingRegistration.Property; - Registration = dataBindingRegistration; - Entity = new DataBindingEntity(); + ApplyRegistration(dataBindingRegistration); ApplyToEntity(); } - public DataBindingRegistration Registration { get; private set; } - internal DataBinding(BaseLayerProperty layerProperty, DataBindingEntity entity) { LayerProperty = layerProperty; @@ -42,13 +38,30 @@ namespace Artemis.Core ApplyToDataBinding(); } + private void ApplyRegistration(DataBindingRegistration dataBindingRegistration) + { + Converter = dataBindingRegistration.Converter; + Registration = dataBindingRegistration; + TargetProperty = dataBindingRegistration.Property; + } + /// /// Gets the layer property this data binding targets /// 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 IDataBindingConverter Converter { get; private set; } + + /// + /// Gets the property on the this data binding targets /// public PropertyInfo TargetProperty { get; private set; } @@ -144,7 +157,7 @@ namespace Artemis.Core /// public object GetValue(object baseValue) { - if (CompiledTargetAccessor == null) + if (CompiledTargetAccessor == null || Converter == null) return baseValue; var dataBindingValue = CompiledTargetAccessor(SourceDataModel); @@ -154,7 +167,7 @@ namespace Artemis.Core 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) + if (EasingTime == TimeSpan.Zero || Converter.SupportsInterpolate) return value; // If the value changed, update the current and previous values used for easing @@ -183,22 +196,16 @@ namespace Artemis.Core /// public void Update(double deltaTime) { + } /// - /// Applies the data binding to the + /// Updates the value on the according to the data binding /// public void ApplyToProperty() { - - } - - private object GetInterpolatedValue() - { - if (_easingProgress >= 1.0f) - return _currentValue; - - return Registration.Converter.Interpolate(_previousValue, _currentValue, _easingProgress); + var value = GetValue(Converter.GetValue(LayerProperty)); + Converter.ApplyValue(LayerProperty, GetValue(value)); } internal void ApplyToEntity() @@ -225,7 +232,9 @@ namespace Artemis.Core internal void ApplyToDataBinding() { // General - TargetProperty = LayerProperty.GetDataBindingProperties()?.FirstOrDefault(p => p.Name == Entity.TargetProperty); + Registration = LayerProperty.DataBindingRegistrations.FirstOrDefault(p => p.Property.Name == Entity.TargetProperty); + TargetProperty = Registration?.Property; + Mode = (DataBindingMode) Entity.DataBindingMode; EasingTime = Entity.EasingTime; EasingFunction = (Easings.Functions) Entity.EasingFunction; @@ -257,6 +266,16 @@ namespace Artemis.Core _isInitialized = true; } + private object GetInterpolatedValue() + { + if (_easingProgress == 0f) + return _previousValue; + if (_easingProgress == 1f || !Converter.SupportsInterpolate) + return _currentValue; + + return Converter.Interpolate(LayerProperty, _previousValue, _currentValue, _easingProgress); + } + private void CreateExpression() { var listType = SourceDataModel.GetListTypeInPath(SourcePropertyPath); diff --git a/src/Artemis.Core/Models/Profile/DataBindings/IDataBindingConverter.cs b/src/Artemis.Core/Models/Profile/DataBindings/IDataBindingConverter.cs index ffdf55b12..39f147436 100644 --- a/src/Artemis.Core/Models/Profile/DataBindings/IDataBindingConverter.cs +++ b/src/Artemis.Core/Models/Profile/DataBindings/IDataBindingConverter.cs @@ -1,4 +1,6 @@ -namespace Artemis.Core +using System; + +namespace Artemis.Core { /// /// A data binding converter that acts as the bridge between a and a @@ -6,33 +8,50 @@ /// public interface IDataBindingConverter { - public BaseLayerProperty BaseLayerProperty { get; set; } + /// + /// Gets the type this converter supports + /// + Type SupportedType { get; } + + /// + /// Gets whether or not this data binding converter supports the method + /// + bool SupportsSum { get; } + + /// + /// Gets whether or not this data binding converter supports the method + /// + bool SupportsInterpolate { get; } /// /// Returns the sum of and /// - object Sum(object a, object b); + /// The layer property this sum is done for + object Sum(BaseLayerProperty layerProperty, object a, object b); /// /// Returns the the interpolated value between and on a scale (generally) /// between 0.0 and 1.0 defined by the /// Note: The progress may go be negative or go beyond 1.0 depending on the easing method used /// + /// The layer property this interpolation is done for /// The value to interpolate away from /// The value to interpolate towards /// The progress of the interpolation between 0.0 and 1.0 /// - object Interpolate(object a, object b, float progress); + object Interpolate(BaseLayerProperty layerProperty, object a, object b, float progress); /// /// Applies the to the layer property /// + /// The layer property this value is to be applied to /// - void ApplyValue(object value); + void ApplyValue(BaseLayerProperty layerProperty, object value); /// /// Returns the current base value of the data binding /// - object GetValue(); + /// The layer property this value must be retrieved from + object GetValue(BaseLayerProperty layerProperty); } } \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs index 3d5e96a0a..478be6e88 100644 --- a/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs +++ b/src/Artemis.Core/Models/Profile/LayerProperties/BaseLayerProperty.cs @@ -11,8 +11,12 @@ namespace Artemis.Core /// public abstract class BaseLayerProperty { - protected readonly List _dataBindings = new List(); 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; @@ -20,11 +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.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.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.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 /// @@ -122,13 +174,6 @@ namespace Artemis.Core #region Data bindings - internal DataBindingRegistration RegisterDataBindingProperty(PropertyInfo property, IDataBindingConverter converter) - { - var registration = new DataBindingRegistration(this, property, converter); - _dataBindingRegistrations.Add(registration); - return registration; - } - internal void InitializeDataBindings(IDataModelService dataModelService, IDataBindingService dataBindingService) { foreach (var dataBinding in DataBindings) @@ -141,7 +186,7 @@ namespace Artemis.Core /// The newly created data binding public DataBinding EnableDataBinding(DataBindingRegistration dataBindingRegistration) { - var dataBinding = new DataBinding(this, dataBindingProperty); + var dataBinding = new DataBinding(dataBindingRegistration); _dataBindings.Add(dataBinding); return dataBinding; diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs index 3edb15b0f..22546ecd3 100644 --- a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs +++ b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs @@ -3,8 +3,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Linq.Expressions; -using System.Reflection; -using Artemis.Core.DataModelExpansions; using Artemis.Storage.Entities.Profile; using Newtonsoft.Json; @@ -20,7 +18,6 @@ namespace Artemis.Core /// The type of property encapsulated in this layer property public abstract class LayerProperty : BaseLayerProperty { - private T _baseValue; private bool _isInitialized; private List> _keyframes; @@ -32,30 +29,37 @@ 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 => (T) base.BaseValue; set { - if (_baseValue != null && !_baseValue.Equals(value) || _baseValue == null && value != null) - { - _baseValue = value; - OnBaseValueChanged(); - } + if (Equals(base.BaseValue, value)) + return; + + base.BaseValue = value; + 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 => (T) base.CurrentValue; + 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 => (T) base.DefaultValue; + set => base.DefaultValue = value; + } /// /// Gets a read-only list of all the keyframes on this layer property @@ -309,42 +313,14 @@ namespace Artemis.Core public void RegisterDataBindingProperty(Expression> propertyLambda, IDataBindingConverter converter) { - var propertyInfo = ReflectionUtilities.GetPropertyInfo(CurrentValue, propertyLambda); - + 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)); } - /// - /// Registers the provided property to be available for data binding using a data binding property of type - /// - /// - /// The type of data binding property to use - /// The name of the property - /// - public TD RegisterDataBindingProperty(string propertyName, IDataBindingConverter converter) where TD : BaseDataBindingProperty - { - var property = typeof(T).GetProperty(propertyName); - if (property == null) - { - throw new ArtemisCoreException($"Cannot register data binding property for property {propertyName} " + - $"because it does not exist on type {typeof(T).Name}"); - } - - // Create an instance of the converter - var dataBindingOperator = (TD) Activator.CreateInstance(typeof(TD), property); - if (dataBindingOperator == null) - throw new ArtemisCoreException($"Cannot register data binding, failed to create an instance of {typeof(TD).Name}"); - if (dataBindingOperator.PropertyType != property.PropertyType) - { - throw new ArtemisCoreException($"Cannot register data binding property for property {propertyName} using a {typeof(TD).Name} " + - $"because it does not support type {typeof(T).Name}"); - } - - AddDataBindingConverter(dataBindingOperator); - - return dataBindingOperator; - } - private void UpdateDataBindings(double deltaTime) { foreach (var dataBinding in DataBindings) 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 e9c289e75..dc9032d9a 100644 --- a/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKColorLayerProperty.cs +++ b/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKColorLayerProperty.cs @@ -1,5 +1,4 @@ -using System; -using SkiaSharp; +using SkiaSharp; namespace Artemis.Core { @@ -8,11 +7,11 @@ namespace Artemis.Core { internal SKColorLayerProperty() { - RegisterDataBindingProperty(color => color.Alpha, new SKColorDataBindingConverter(SKColorDataBindingConverter.Channel.Alpha)); - RegisterDataBindingProperty(color => color.Red, new SKColorDataBindingConverter(SKColorDataBindingConverter.Channel.Red)); - RegisterDataBindingProperty(color => color.Green, new SKColorDataBindingConverter(SKColorDataBindingConverter.Channel.Green)); - RegisterDataBindingProperty(color => color.Blue, new SKColorDataBindingConverter(SKColorDataBindingConverter.Channel.Blue)); - RegisterDataBindingProperty(color => color.Hue, new SKColorDataBindingConverter(SKColorDataBindingConverter.Channel.Hue)); + 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)); } /// @@ -31,83 +30,4 @@ namespace Artemis.Core CurrentValue = CurrentKeyframe.Value.Interpolate(NextKeyframe.Value, keyframeProgressEased); } } - - internal class SKColorDataBindingConverter : IDataBindingConverter - { - private readonly Channel _channel; - - public SKColorDataBindingConverter(Channel channel) - { - _channel = channel; - } - - public BaseLayerProperty BaseLayerProperty { get; set; } - - public object Sum(object a, object b) - { - return (float) a + (float) b; - } - - public object Interpolate(object a, object b, float progress) - { - var diff = (float) b - (float) a; - return diff * progress; - } - - public void ApplyValue(object value) - { - var property = (SKColorLayerProperty) BaseLayerProperty; - 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 object GetValue() - { - var property = (SKColorLayerProperty) BaseLayerProperty; - 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/LayerProperties/Types/SKPointLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKPointLayerProperty.cs index 75c0a934c..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 /// diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKSizeLayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/Types/SKSizeLayerProperty.cs index 5db8b2a35..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()); } ///