mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Data bindings - Added binding apply logic to the layer properties
Data bindings - Expanded to support inner layer properties
This commit is contained in:
parent
5f34c8afac
commit
ea98c6114a
@ -1,4 +1,8 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Reflection;
|
||||||
using Artemis.Core.DataModelExpansions;
|
using Artemis.Core.DataModelExpansions;
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
@ -11,9 +15,14 @@ namespace Artemis.Core
|
|||||||
private readonly List<DataBindingModifier> _modifiers = new List<DataBindingModifier>();
|
private readonly List<DataBindingModifier> _modifiers = new List<DataBindingModifier>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="BaseLayerProperty" /> that the data binding targets
|
/// Gets the layer property this data binding targets
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BaseLayerProperty Target { get; set; } // BIG FAT TODO: Take into account X and Y of SkPosition etc., forgot about it again :>
|
public BaseLayerProperty LayerProperty { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the inner property this data binding targets
|
||||||
|
/// </summary>
|
||||||
|
public PropertyInfo TargetProperty { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the currently used instance of the data model that contains the source of the data binding
|
/// Gets the currently used instance of the data model that contains the source of the data binding
|
||||||
@ -30,6 +39,8 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyList<DataBindingModifier> Modifiers => _modifiers.AsReadOnly();
|
public IReadOnlyList<DataBindingModifier> Modifiers => _modifiers.AsReadOnly();
|
||||||
|
|
||||||
|
public Func<DataModel, object> CompiledTargetAccessor { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a modifier to the data binding's <see cref="Modifiers" /> collection
|
/// Adds a modifier to the data binding's <see cref="Modifiers" /> collection
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -55,5 +66,44 @@ namespace Artemis.Core
|
|||||||
_modifiers.Remove(modifier);
|
_modifiers.Remove(modifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current value of the data binding
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="baseValue">The base value of the property the data binding is applied to</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public object GetValue(object baseValue)
|
||||||
|
{
|
||||||
|
if (baseValue.GetType() != TargetProperty.PropertyType)
|
||||||
|
{
|
||||||
|
throw new ArtemisCoreException($"The provided current value type ({baseValue.GetType().Name}) not match the " +
|
||||||
|
$"target property type ({TargetProperty.PropertyType.Name})");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CompiledTargetAccessor == null)
|
||||||
|
return baseValue;
|
||||||
|
|
||||||
|
var dataBindingValue = CompiledTargetAccessor(SourceDataModel);
|
||||||
|
foreach (var dataBindingModifier in Modifiers)
|
||||||
|
dataBindingValue = dataBindingModifier.Apply(dataBindingValue);
|
||||||
|
|
||||||
|
return dataBindingValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
var listType = SourceDataModel.GetListTypeInPath(SourcePropertyPath);
|
||||||
|
if (listType != null)
|
||||||
|
throw new ArtemisCoreException($"Cannot create a regular accessor at path {SourcePropertyPath} because the path contains a list");
|
||||||
|
|
||||||
|
var parameter = Expression.Parameter(typeof(object), "targetDataModel");
|
||||||
|
var accessor = SourcePropertyPath.Split('.').Aggregate<string, Expression>(
|
||||||
|
Expression.Convert(parameter, SourceDataModel.GetType()), // Cast to the appropriate type
|
||||||
|
Expression.Property
|
||||||
|
);
|
||||||
|
|
||||||
|
var lambda = Expression.Lambda<Func<DataModel, object>>(accessor);
|
||||||
|
CompiledTargetAccessor = lambda.Compile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ namespace Artemis.Core
|
|||||||
/// <returns>The modified value</returns>
|
/// <returns>The modified value</returns>
|
||||||
public object Apply(object currentValue)
|
public object Apply(object currentValue)
|
||||||
{
|
{
|
||||||
var targetType = DataBinding.Target.GetPropertyType();
|
var targetType = DataBinding.LayerProperty.GetPropertyType();
|
||||||
if (currentValue.GetType() != targetType)
|
if (currentValue.GetType() != targetType)
|
||||||
{
|
{
|
||||||
throw new ArtemisCoreException("The current value of the data binding does not match the type of the target property." +
|
throw new ArtemisCoreException("The current value of the data binding does not match the type of the target property." +
|
||||||
@ -118,7 +118,7 @@ namespace Artemis.Core
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var targetType = DataBinding.Target.GetPropertyType();
|
var targetType = DataBinding.LayerProperty.GetPropertyType();
|
||||||
if (!modifierType.SupportsType(targetType))
|
if (!modifierType.SupportsType(targetType))
|
||||||
{
|
{
|
||||||
throw new ArtemisCoreException($"Cannot apply modifier type {modifierType.GetType().Name} to this modifier because " +
|
throw new ArtemisCoreException($"Cannot apply modifier type {modifierType.GetType().Name} to this modifier because " +
|
||||||
@ -164,7 +164,7 @@ namespace Artemis.Core
|
|||||||
ParameterDataModel = null;
|
ParameterDataModel = null;
|
||||||
ParameterPropertyPath = null;
|
ParameterPropertyPath = null;
|
||||||
|
|
||||||
var targetType = DataBinding.Target.GetPropertyType();
|
var targetType = DataBinding.LayerProperty.GetPropertyType();
|
||||||
|
|
||||||
// If not null ensure the types match and if not, convert it
|
// If not null ensure the types match and if not, convert it
|
||||||
if (staticValue != null && staticValue.GetType() == targetType)
|
if (staticValue != null && staticValue.GetType() == targetType)
|
||||||
@ -200,7 +200,7 @@ namespace Artemis.Core
|
|||||||
else if (ParameterType == ProfileRightSideType.Static && Entity.ParameterStaticValue != null)
|
else if (ParameterType == ProfileRightSideType.Static && Entity.ParameterStaticValue != null)
|
||||||
{
|
{
|
||||||
// Use the target type so JSON.NET has a better idea what to do
|
// Use the target type so JSON.NET has a better idea what to do
|
||||||
var targetType = DataBinding.Target.GetPropertyType();
|
var targetType = DataBinding.LayerProperty.GetPropertyType();
|
||||||
object staticValue;
|
object staticValue;
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -240,15 +240,15 @@ namespace Artemis.Core
|
|||||||
if (ParameterDataModel == null)
|
if (ParameterDataModel == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var currentValueParameter = Expression.Parameter(DataBinding.Target.GetPropertyType());
|
var currentValueParameter = Expression.Parameter(DataBinding.LayerProperty.GetPropertyType());
|
||||||
|
|
||||||
// If the right side value is null, the constant type cannot be inferred and must be provided based on the data binding target
|
// If the right side value is null, the constant type cannot be inferred and must be provided based on the data binding target
|
||||||
var rightSideAccessor = CreateAccessor(ParameterDataModel, ParameterPropertyPath, "right", out var rightSideParameter);
|
var rightSideAccessor = CreateAccessor(ParameterDataModel, ParameterPropertyPath, "right", out var rightSideParameter);
|
||||||
|
|
||||||
// A conversion may be required if the types differ
|
// A conversion may be required if the types differ
|
||||||
// This can cause issues if the DisplayConditionOperator wasn't accurate in it's supported types but that is not a concern here
|
// This can cause issues if the DisplayConditionOperator wasn't accurate in it's supported types but that is not a concern here
|
||||||
if (rightSideAccessor.Type != DataBinding.Target.GetPropertyType())
|
if (rightSideAccessor.Type != DataBinding.LayerProperty.GetPropertyType())
|
||||||
rightSideAccessor = Expression.Convert(rightSideAccessor, DataBinding.Target.GetPropertyType());
|
rightSideAccessor = Expression.Convert(rightSideAccessor, DataBinding.LayerProperty.GetPropertyType());
|
||||||
|
|
||||||
var modifierExpression = ModifierType.CreateExpression(currentValueParameter, rightSideAccessor);
|
var modifierExpression = ModifierType.CreateExpression(currentValueParameter, rightSideAccessor);
|
||||||
var lambda = Expression.Lambda<Func<object, DataModel, object>>(modifierExpression, currentValueParameter, rightSideParameter);
|
var lambda = Expression.Lambda<Func<object, DataModel, object>>(modifierExpression, currentValueParameter, rightSideParameter);
|
||||||
@ -257,12 +257,12 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private void CreateStaticExpression()
|
private void CreateStaticExpression()
|
||||||
{
|
{
|
||||||
var currentValueParameter = Expression.Parameter(DataBinding.Target.GetPropertyType());
|
var currentValueParameter = Expression.Parameter(DataBinding.LayerProperty.GetPropertyType());
|
||||||
|
|
||||||
// If the right side value is null, the constant type cannot be inferred and must be provided based on the data binding target
|
// If the right side value is null, the constant type cannot be inferred and must be provided based on the data binding target
|
||||||
var rightSideConstant = ParameterStaticValue != null
|
var rightSideConstant = ParameterStaticValue != null
|
||||||
? Expression.Constant(ParameterStaticValue)
|
? Expression.Constant(ParameterStaticValue)
|
||||||
: Expression.Constant(null, DataBinding.Target.GetPropertyType());
|
: Expression.Constant(null, DataBinding.LayerProperty.GetPropertyType());
|
||||||
|
|
||||||
var modifierExpression = ModifierType.CreateExpression(currentValueParameter, rightSideConstant);
|
var modifierExpression = ModifierType.CreateExpression(currentValueParameter, rightSideConstant);
|
||||||
var lambda = Expression.Lambda<Func<object, object>>(modifierExpression, currentValueParameter);
|
var lambda = Expression.Lambda<Func<object, object>>(modifierExpression, currentValueParameter);
|
||||||
|
|||||||
@ -10,6 +10,7 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class BaseLayerProperty
|
public abstract class BaseLayerProperty
|
||||||
{
|
{
|
||||||
|
private readonly List<DataBinding> _dataBindings = new List<DataBinding>();
|
||||||
private bool _isHidden;
|
private bool _isHidden;
|
||||||
private bool _keyframesEnabled;
|
private bool _keyframesEnabled;
|
||||||
|
|
||||||
@ -32,6 +33,16 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool KeyframesSupported { get; protected internal set; } = true;
|
public bool KeyframesSupported { get; protected internal set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets whether data bindings are supported on this type of property
|
||||||
|
/// </summary>
|
||||||
|
public bool DataBindingsSupported { get; protected internal set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a read-only collection of the currently applied data bindings
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyCollection<DataBinding> DataBindings => _dataBindings.AsReadOnly();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets whether keyframes are enabled on this property, has no effect if <see cref="KeyframesSupported" /> is
|
/// Gets or sets whether keyframes are enabled on this property, has no effect if <see cref="KeyframesSupported" /> is
|
||||||
/// False
|
/// False
|
||||||
@ -99,6 +110,12 @@ namespace Artemis.Core
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public abstract List<PropertyInfo> GetDataBindingProperties();
|
public abstract List<PropertyInfo> GetDataBindingProperties();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the provided data binding must be applied to a property
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dataBinding"></param>
|
||||||
|
protected abstract void ApplyDataBinding(DataBinding dataBinding);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Applies the provided property entity to the layer property by deserializing the JSON base value and keyframe values
|
/// Applies the provided property entity to the layer property by deserializing the JSON base value and keyframe values
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -113,6 +130,19 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal abstract void ApplyToEntity();
|
internal abstract void ApplyToEntity();
|
||||||
|
|
||||||
|
#region Data bindings
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies the current <see cref="DataBindings" /> to the layer property
|
||||||
|
/// </summary>
|
||||||
|
public void ApplyDataBindings()
|
||||||
|
{
|
||||||
|
foreach (var dataBinding in DataBindings)
|
||||||
|
ApplyDataBinding(dataBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -178,12 +178,6 @@ namespace Artemis.Core
|
|||||||
return typeof(T);
|
return typeof(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override List<PropertyInfo> GetDataBindingProperties()
|
|
||||||
{
|
|
||||||
return new List<PropertyInfo> {GetType().GetProperty(nameof(CurrentValue))};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called every update (if keyframes are both supported and enabled) to determine the new <see cref="CurrentValue" />
|
/// Called every update (if keyframes are both supported and enabled) to determine the new <see cref="CurrentValue" />
|
||||||
/// based on the provided progress
|
/// based on the provided progress
|
||||||
@ -234,6 +228,7 @@ namespace Artemis.Core
|
|||||||
_keyframes = _keyframes.OrderBy(k => k.Position).ToList();
|
_keyframes = _keyframes.OrderBy(k => k.Position).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal override void ApplyToLayerProperty(PropertyEntity entity, LayerPropertyGroup layerPropertyGroup, bool fromStorage)
|
internal override void ApplyToLayerProperty(PropertyEntity entity, LayerPropertyGroup layerPropertyGroup, bool fromStorage)
|
||||||
{
|
{
|
||||||
// Doubt this will happen but let's make sure
|
// Doubt this will happen but let's make sure
|
||||||
@ -289,5 +284,23 @@ namespace Artemis.Core
|
|||||||
EasingFunction = (int) k.EasingFunction
|
EasingFunction = (int) k.EasingFunction
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Data bindings
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override List<PropertyInfo> GetDataBindingProperties()
|
||||||
|
{
|
||||||
|
return new List<PropertyInfo> {GetType().GetProperty(nameof(CurrentValue))};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void ApplyDataBinding(DataBinding dataBinding)
|
||||||
|
{
|
||||||
|
// The default implementation only supports simple types
|
||||||
|
if (dataBinding.TargetProperty.DeclaringType == GetType())
|
||||||
|
CurrentValue = (T) dataBinding.GetValue(CurrentValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8,6 +8,7 @@ namespace Artemis.Core
|
|||||||
internal ColorGradientLayerProperty()
|
internal ColorGradientLayerProperty()
|
||||||
{
|
{
|
||||||
KeyframesSupported = false;
|
KeyframesSupported = false;
|
||||||
|
DataBindingsSupported = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator ColorGradient(ColorGradientLayerProperty p)
|
public static implicit operator ColorGradient(ColorGradientLayerProperty p)
|
||||||
|
|||||||
@ -8,6 +8,7 @@ namespace Artemis.Core
|
|||||||
public EnumLayerProperty()
|
public EnumLayerProperty()
|
||||||
{
|
{
|
||||||
KeyframesSupported = false;
|
KeyframesSupported = false;
|
||||||
|
DataBindingsSupported = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator T(EnumLayerProperty<T> p)
|
public static implicit operator T(EnumLayerProperty<T> p)
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
internal LayerBrushReferenceLayerProperty()
|
internal LayerBrushReferenceLayerProperty()
|
||||||
{
|
{
|
||||||
KeyframesSupported = false;
|
KeyframesSupported = false;
|
||||||
|
DataBindingsSupported = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator LayerBrushReference(LayerBrushReferenceLayerProperty p)
|
public static implicit operator LayerBrushReference(LayerBrushReferenceLayerProperty p)
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
@ -10,19 +13,44 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Implicitly converts an <see cref="SKColorLayerProperty" /> to an <see cref="SKColor" />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="p"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static implicit operator SKColor(SKColorLayerProperty p)
|
public static implicit operator SKColor(SKColorLayerProperty p)
|
||||||
{
|
{
|
||||||
return p.CurrentValue;
|
return p.CurrentValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
|
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
|
||||||
{
|
{
|
||||||
CurrentValue = CurrentKeyframe.Value.Interpolate(NextKeyframe.Value, keyframeProgressEased);
|
CurrentValue = CurrentKeyframe.Value.Interpolate(NextKeyframe.Value, keyframeProgressEased);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte ClampToByte(float value)
|
/// <inheritdoc />
|
||||||
|
public override List<PropertyInfo> GetDataBindingProperties()
|
||||||
{
|
{
|
||||||
return (byte) Math.Max(0, Math.Min(255, value));
|
return typeof(SKColor).GetProperties().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,7 @@
|
|||||||
using SkiaSharp;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using SkiaSharp;
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
@ -9,16 +12,35 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Implicitly converts an <see cref="SKPointLayerProperty" /> to an <see cref="SKPoint" />
|
||||||
|
/// </summary>
|
||||||
public static implicit operator SKPoint(SKPointLayerProperty p)
|
public static implicit operator SKPoint(SKPointLayerProperty p)
|
||||||
{
|
{
|
||||||
return p.CurrentValue;
|
return p.CurrentValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
|
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
|
||||||
{
|
{
|
||||||
var xDiff = NextKeyframe.Value.X - CurrentKeyframe.Value.X;
|
var xDiff = NextKeyframe.Value.X - CurrentKeyframe.Value.X;
|
||||||
var yDiff = NextKeyframe.Value.Y - CurrentKeyframe.Value.Y;
|
var yDiff = NextKeyframe.Value.Y - CurrentKeyframe.Value.Y;
|
||||||
CurrentValue = new SKPoint(CurrentKeyframe.Value.X + xDiff * keyframeProgressEased, CurrentKeyframe.Value.Y + yDiff * keyframeProgressEased);
|
CurrentValue = new SKPoint(CurrentKeyframe.Value.X + xDiff * keyframeProgressEased, CurrentKeyframe.Value.Y + yDiff * keyframeProgressEased);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override List<PropertyInfo> GetDataBindingProperties()
|
||||||
|
{
|
||||||
|
return typeof(SKPoint).GetProperties().Where(p => p.CanWrite).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -12,21 +12,35 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Implicitly converts an <see cref="SKSizeLayerProperty" /> to an <see cref="SKSize" />
|
||||||
|
/// </summary>
|
||||||
public static implicit operator SKSize(SKSizeLayerProperty p)
|
public static implicit operator SKSize(SKSizeLayerProperty p)
|
||||||
{
|
{
|
||||||
return p.CurrentValue;
|
return p.CurrentValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<PropertyInfo> GetDataBindingProperties()
|
/// <inheritdoc />
|
||||||
{
|
|
||||||
return typeof(SKSize).GetProperties().Where(p => p.CanWrite).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
|
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
|
||||||
{
|
{
|
||||||
var widthDiff = NextKeyframe.Value.Width - CurrentKeyframe.Value.Width;
|
var widthDiff = NextKeyframe.Value.Width - CurrentKeyframe.Value.Width;
|
||||||
var heightDiff = NextKeyframe.Value.Height - CurrentKeyframe.Value.Height;
|
var heightDiff = NextKeyframe.Value.Height - CurrentKeyframe.Value.Height;
|
||||||
CurrentValue = new SKSize(CurrentKeyframe.Value.Width + widthDiff * keyframeProgressEased, CurrentKeyframe.Value.Height + heightDiff * keyframeProgressEased);
|
CurrentValue = new SKSize(CurrentKeyframe.Value.Width + widthDiff * keyframeProgressEased, CurrentKeyframe.Value.Height + heightDiff * keyframeProgressEased);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override List<PropertyInfo> GetDataBindingProperties()
|
||||||
|
{
|
||||||
|
return typeof(SKSize).GetProperties().Where(p => p.CanWrite).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using RGB.NET.Core;
|
using RGB.NET.Core;
|
||||||
using RGB.NET.Groups;
|
using RGB.NET.Groups;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
@ -57,7 +58,7 @@ namespace Artemis.Core.Services
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deviceProvider.Devices == null)
|
if (deviceProvider.Devices == null || !deviceProvider.Devices.Any())
|
||||||
{
|
{
|
||||||
_logger.Warning("Device provider {deviceProvider} has no devices", deviceProvider.GetType().Name);
|
_logger.Warning("Device provider {deviceProvider} has no devices", deviceProvider.GetType().Name);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -51,6 +51,7 @@
|
|||||||
Width="20"
|
Width="20"
|
||||||
Height="20"
|
Height="20"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
|
IsEnabled="{Binding LayerPropertyViewModel.LayerProperty.DataBindingsSupported}"
|
||||||
IsChecked="{Binding DataBindingsOpen}">
|
IsChecked="{Binding DataBindingsOpen}">
|
||||||
<materialDesign:PackIcon Kind="VectorLink" Height="13" Width="13" />
|
<materialDesign:PackIcon Kind="VectorLink" Height="13" Width="13" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user