1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2026-01-01 02:03:32 +00:00

Databinding modifiers - Redesigned API to leverage generics

Databinding modifiers - Updated default modifiers to use new API
This commit is contained in:
SpoinkyNL 2020-10-20 19:00:41 +02:00
parent 2bb663db15
commit fd9f3afef5
50 changed files with 487 additions and 407 deletions

View File

@ -0,0 +1,60 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cmodes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cmodes_005Cconditional/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cmodes_005Cdirect/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes_005Cconditions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes_005Cconditions_005Coperators/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes_005Cdatabindings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes_005Cdatabindings_005Cconditions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes_005Cdatabindings_005Cconditions_005Coperators/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes_005Cdatabindings_005Cconverters/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes_005Cdatabindings_005Cmodifiers/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes_005Cdatabindings_005Cmodifiers_005Ccolors/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes_005Cdatabindings_005Cmodifiers_005Cnumbers/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes_005Cdatabindings_005Cmodifiers_005Cnumbers_005Crounding/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes_005Cdatabindings_005Cmodifiers_005Cnumbers_005Ctrigonometric/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes_005Cdatabindings_005Cmodifiers_005Cnumbers_005Ctrigonometry/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes_005Cproperties/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=events/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=events_005Cplugins/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=events_005Cprofiles/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=events_005Cstores/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=exceptions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=extensions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Ccolors/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cconditions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cconditions_005Cabstract/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cconditions_005Coperators/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cconverters/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cconverters_005Cinternal/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cdatabindingproperties/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cdatabindingproperties_005Cabstract/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cmodes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cmodifiers/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cmodifiers_005Cabstract/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatamodel/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Clayerproperties/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Clayerproperties_005Cattributes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Clayerproperties_005Ctypes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Clayershapes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Csurface/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=placeholders/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Cdatamodelexpansions_005Cattributes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Cdatamodelexpansions_005Cinternal/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Clayerbrushes_005Cinternal/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Clayereffects_005Cinternal/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Cmodules_005Cactivationrequirements/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Csettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=rgb_002Enet/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cinterfaces/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cregistration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cregistration_005Cinterfaces/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cstorage/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cstorage_005Cinterfaces/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=stores/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=stores_005Cregistrations/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=utilities/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -1,23 +1,17 @@
using System; using SkiaSharp;
using System.Collections.Generic;
using SkiaSharp;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class SKColorBrightenModifierType : DataBindingModifierType internal class SKColorBrightenModifierType : DataBindingModifierType<SKColor, float>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => new List<Type> {typeof(SKColor)};
public override Type ParameterType => typeof(float);
public override string Name => "Brighten by"; public override string Name => "Brighten by";
public override string Icon => "CarLightHigh"; public override string Icon => "CarLightHigh";
public override string Description => "Brightens the color by the amount in percent"; public override string Description => "Brightens the color by the amount in percent";
public override object Apply(object currentValue, object parameterValue) public override SKColor Apply(SKColor currentValue, float parameterValue)
{ {
((SKColor) currentValue).ToHsl(out float h, out float s, out float l); currentValue.ToHsl(out float h, out float s, out float l);
l *= (Convert.ToSingle(parameterValue) + 100f) / 100f; l *= (parameterValue + 100f) / 100f;
return SKColor.FromHsl(h, s, l); return SKColor.FromHsl(h, s, l);
} }
} }

View File

@ -1,22 +1,17 @@
using System; using SkiaSharp;
using System.Collections.Generic;
using SkiaSharp;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class SKColorDarkenModifierType : DataBindingModifierType internal class SKColorDarkenModifierType : DataBindingModifierType<SKColor, float>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => new List<Type> {typeof(SKColor)};
public override Type ParameterType => typeof(float);
public override string Name => "Darken by"; public override string Name => "Darken by";
public override string Icon => "CarLightDimmed"; public override string Icon => "CarLightDimmed";
public override string Description => "Darkens the color by the amount in percent"; public override string Description => "Darkens the color by the amount in percent";
public override object Apply(object currentValue, object parameterValue) public override SKColor Apply(SKColor currentValue, float parameterValue)
{ {
((SKColor) currentValue).ToHsl(out float h, out float s, out float l); currentValue.ToHsl(out float h, out float s, out float l);
l *= (Convert.ToSingle(parameterValue) * -1 + 100f) / 100f; l *= (parameterValue * -1 + 100f) / 100f;
return SKColor.FromHsl(h, s, l); return SKColor.FromHsl(h, s, l);
} }
} }

View File

@ -1,24 +1,17 @@
using System; using SkiaSharp;
using System.Collections.Generic;
using SkiaSharp;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class SKColorRotateHueModifierType : DataBindingModifierType internal class SKColorRotateHueModifierType : DataBindingModifierType<SKColor, float>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => new List<Type> {typeof(SKColor)};
public override Type ParameterType => typeof(float);
public override string Name => "Rotate Hue by"; public override string Name => "Rotate Hue by";
public override string Icon => "RotateRight"; public override string Icon => "RotateRight";
public override string Description => "Rotates the hue of the color by the amount in degrees"; public override string Description => "Rotates the hue of the color by the amount in degrees";
public override object Apply(object currentValue, object parameterValue) public override SKColor Apply(SKColor currentValue, float parameterValue)
{ {
((SKColor) currentValue).ToHsl(out float h, out float s, out float l); currentValue.ToHsl(out float h, out float s, out float l);
h += parameterValue;
h += (float)parameterValue;
return SKColor.FromHsl(h % 360, s, l); return SKColor.FromHsl(h % 360, s, l);
} }
} }

View File

@ -1,20 +1,16 @@
using System; using SkiaSharp;
using System.Collections.Generic;
using SkiaSharp;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class SKColorSumModifierType : DataBindingModifierType internal class SKColorSumModifierType : DataBindingModifierType<SKColor, SKColor>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => new List<Type> {typeof(SKColor)};
public override string Name => "Combine with"; public override string Name => "Combine with";
public override string Icon => "FormatColorFill"; public override string Icon => "FormatColorFill";
public override string Description => "Adds the two colors together"; public override string Description => "Adds the two colors together";
public override object Apply(object currentValue, object parameterValue) public override SKColor Apply(SKColor currentValue, SKColor parameterValue)
{ {
return ((SKColor) currentValue).Sum((SKColor) parameterValue); return currentValue.Sum(parameterValue);
} }
} }
} }

View File

@ -1,21 +1,17 @@
using System; using System;
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class AbsoluteModifierType : DataBindingModifierType internal class AbsoluteModifierType : DataBindingModifierType<double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override bool SupportsParameter => false;
public override string Name => "Absolute"; public override string Name => "Absolute";
public override string Icon => "NumericPositive1"; public override string Icon => "NumericPositive1";
public override string Category => "Advanced"; public override string Category => "Advanced";
public override string Description => "Converts the input value to an absolute value"; public override string Description => "Converts the input value to an absolute value";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue)
{ {
return Math.Abs(Convert.ToSingle(currentValue)); return Math.Abs(currentValue);
} }
} }
} }

View File

@ -1,24 +1,17 @@
using System; namespace Artemis.Core.DefaultTypes
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes
{ {
internal class DivideModifierType : DataBindingModifierType internal class DivideModifierType : DataBindingModifierType<double, double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override Type ParameterType => typeof(float);
public override string Name => "Divide by"; public override string Name => "Divide by";
public override string Icon => "Divide"; public override string Icon => "Divide";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue, double parameterValue)
{ {
float parameter = Convert.ToSingle(parameterValue);
// Ye ye none of that // Ye ye none of that
if (parameter == 0) if (parameterValue == 0)
return 0; return 0;
return Convert.ToSingle(currentValue) / parameter; return currentValue / parameterValue;
} }
} }
} }

View File

@ -1,20 +1,17 @@
using System; using System;
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class MaxModifierType : DataBindingModifierType internal class MaxModifierType : DataBindingModifierType<double, double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override string Name => "Max"; public override string Name => "Max";
public override string Icon => "ChevronUpBoxOutline"; public override string Icon => "ChevronUpBoxOutline";
public override string Category => "Advanced"; public override string Category => "Advanced";
public override string Description => "Keeps only the largest of input value and parameter"; public override string Description => "Keeps only the largest of input value and parameter";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue, double parameterValue)
{ {
return Math.Max(Convert.ToSingle(currentValue), Convert.ToSingle(parameterValue)); return Math.Max(currentValue, parameterValue);
} }
} }
} }

View File

@ -1,20 +1,17 @@
using System; using System;
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class MinModifierType : DataBindingModifierType internal class MinModifierType : DataBindingModifierType<double, double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override string Name => "Min"; public override string Name => "Min";
public override string Icon => "ChevronDownBoxOutline"; public override string Icon => "ChevronDownBoxOutline";
public override string Category => "Advanced"; public override string Category => "Advanced";
public override string Description => "Keeps only the smallest of input value and parameter"; public override string Description => "Keeps only the smallest of input value and parameter";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue, double parameterValue)
{ {
return Math.Min(Convert.ToSingle(currentValue), Convert.ToSingle(parameterValue)); return Math.Min(currentValue, parameterValue);
} }
} }
} }

View File

@ -1,20 +1,15 @@
using System; namespace Artemis.Core.DefaultTypes
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes
{ {
internal class ModuloModifierType : DataBindingModifierType internal class ModuloModifierType : DataBindingModifierType<double, double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override string Name => "Modulo"; public override string Name => "Modulo";
public override string Icon => "Stairs"; public override string Icon => "Stairs";
public override string Category => "Advanced"; public override string Category => "Advanced";
public override string Description => "Calculates the remained of the division between the input value and the parameter"; public override string Description => "Calculates the remained of the division between the input value and the parameter";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue, double parameterValue)
{ {
return Convert.ToSingle(currentValue) % Convert.ToSingle(parameterValue); return currentValue % parameterValue;
} }
} }
} }

View File

@ -1,19 +1,13 @@
using System; namespace Artemis.Core.DefaultTypes
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes
{ {
internal class MultiplicationModifierType : DataBindingModifierType internal class MultiplicationModifierType : DataBindingModifierType<double, double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override Type ParameterType => typeof(float);
public override string Name => "Multiply by"; public override string Name => "Multiply by";
public override string Icon => "Close"; public override string Icon => "Close";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue, double parameterValue)
{ {
return Convert.ToSingle(currentValue) * Convert.ToSingle(parameterValue); return currentValue * parameterValue;
} }
} }
} }

View File

@ -1,25 +1,18 @@
using System; namespace Artemis.Core.DefaultTypes
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes
{ {
internal class PercentageOfModifierType : DataBindingModifierType internal class PercentageOfModifierType : DataBindingModifierType<double, double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override Type ParameterType => typeof(float);
public override string Name => "Percentage of"; public override string Name => "Percentage of";
public override string Icon => "Percent"; public override string Icon => "Percent";
public override string Description => "Calculates how much percent the parameter value is of the current value"; public override string Description => "Calculates how much percent the parameter value is of the current value";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue, double parameterValue)
{ {
float parameter = Convert.ToSingle(parameterValue);
// Ye ye none of that // Ye ye none of that
if (parameter == 0f) if (parameterValue == 0d)
return 100f; return 100d;
return 100f / Convert.ToSingle(parameterValue) * Convert.ToSingle(currentValue); return 100d / parameterValue * currentValue;
} }
} }
} }

View File

@ -1,20 +1,17 @@
using System; using System;
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class PowerModifierType : DataBindingModifierType internal class PowerModifierType : DataBindingModifierType<double, double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override string Name => "Power"; public override string Name => "Power";
public override string Icon => "Exponent"; public override string Icon => "Exponent";
public override string Category => "Advanced"; public override string Category => "Advanced";
public override string Description => "Raises the input value to the power of the parameter value"; public override string Description => "Raises the input value to the power of the parameter value";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue, double parameterValue)
{ {
return Math.Pow(Convert.ToSingle(currentValue), Convert.ToSingle(parameterValue)); return Math.Pow(currentValue, parameterValue);
} }
} }
} }

View File

@ -1,22 +1,17 @@
using System; using System;
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class CeilingModifierType : DataBindingModifierType internal class CeilingModifierType : DataBindingModifierType<double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override bool SupportsParameter => false;
public override string Name => "Round up"; public override string Name => "Round up";
public override string Icon => "ArrowUp"; public override string Icon => "ArrowUp";
public override string Category => "Rounding"; public override string Category => "Rounding";
public override string Description => "Ceils the input, rounding it up to the nearest whole number"; public override string Description => "Ceils the input, rounding it up to the nearest whole number";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue)
{ {
float floatValue = Convert.ToSingle(currentValue); return Math.Ceiling(currentValue);
return Math.Ceiling(floatValue);
} }
} }
} }

View File

@ -1,22 +1,17 @@
using System; using System;
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class FloorModifierType : DataBindingModifierType internal class FloorModifierType : DataBindingModifierType<double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override bool SupportsParameter => false;
public override string Name => "Round down"; public override string Name => "Round down";
public override string Icon => "ArrowDown"; public override string Icon => "ArrowDown";
public override string Category => "Rounding"; public override string Category => "Rounding";
public override string Description => "Floors the input, rounding it down to the nearest whole number"; public override string Description => "Floors the input, rounding it down to the nearest whole number";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue)
{ {
float floatValue = Convert.ToSingle(currentValue); return Math.Floor(currentValue);
return Math.Floor(floatValue);
} }
} }
} }

View File

@ -1,22 +1,17 @@
using System; using System;
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class RoundModifierType : DataBindingModifierType internal class RoundModifierType : DataBindingModifierType<double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override bool SupportsParameter => false;
public override string Name => "Round"; public override string Name => "Round";
public override string Icon => "ArrowCollapse"; public override string Icon => "ArrowCollapse";
public override string Category => "Rounding"; public override string Category => "Rounding";
public override string Description => "Rounds the input to the nearest whole number"; public override string Description => "Rounds the input to the nearest whole number";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue)
{ {
float floatValue = Convert.ToSingle(currentValue); return Math.Round(currentValue, MidpointRounding.AwayFromZero);
return Math.Round(floatValue, MidpointRounding.AwayFromZero);
} }
} }
} }

View File

@ -1,21 +1,17 @@
using System; using System;
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class SquareRootModifierType : DataBindingModifierType internal class SquareRootModifierType : DataBindingModifierType<double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override bool SupportsParameter => false;
public override string Name => "Square root"; public override string Name => "Square root";
public override string Icon => "SquareRoot"; public override string Icon => "SquareRoot";
public override string Category => "Advanced"; public override string Category => "Advanced";
public override string Description => "Calculates square root of the input value"; public override string Description => "Calculates square root of the input value";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue)
{ {
return Math.Sqrt(Convert.ToSingle(currentValue)); return Math.Sqrt(currentValue);
} }
} }
} }

View File

@ -1,18 +1,13 @@
using System; namespace Artemis.Core.DefaultTypes
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes
{ {
internal class SubtractModifierType : DataBindingModifierType internal class SubtractModifierType : DataBindingModifierType<double, double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override string Name => "Subtract"; public override string Name => "Subtract";
public override string Icon => "Minus"; public override string Icon => "Minus";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue, double parameterValue)
{ {
return Convert.ToSingle(currentValue) - Convert.ToSingle(parameterValue); return currentValue - parameterValue;
} }
} }
} }

View File

@ -1,18 +1,13 @@
using System; namespace Artemis.Core.DefaultTypes
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes
{ {
internal class SumModifierType : DataBindingModifierType internal class SumModifierType : DataBindingModifierType<double, double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override string Name => "Sum"; public override string Name => "Sum";
public override string Icon => "Plus"; public override string Icon => "Plus";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue, double parameterValue)
{ {
return Convert.ToSingle(currentValue) + Convert.ToSingle(parameterValue); return currentValue + parameterValue;
} }
} }
} }

View File

@ -1,21 +1,17 @@
using System; using System;
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class CosecantModifierType : DataBindingModifierType internal class CosecantModifierType : DataBindingModifierType<double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override bool SupportsParameter => false;
public override string Name => "Cosecant"; public override string Name => "Cosecant";
public override string Icon => null; public override string Icon => null;
public override string Category => "Trigonometry"; public override string Category => "Trigonometry";
public override string Description => "Treats the input as an angle and calculates the cosecant"; public override string Description => "Treats the input as an angle and calculates the cosecant";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue)
{ {
return 1f / Math.Sin(Convert.ToSingle(currentValue)); return 1d / Math.Sin(currentValue);
} }
} }
} }

View File

@ -1,21 +1,17 @@
using System; using System;
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class CosineModifierType : DataBindingModifierType internal class CosineModifierType : DataBindingModifierType<double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override bool SupportsParameter => false;
public override string Name => "Cosine"; public override string Name => "Cosine";
public override string Icon => "MathCos"; public override string Icon => "MathCos";
public override string Category => "Trigonometry"; public override string Category => "Trigonometry";
public override string Description => "Treats the input as an angle and calculates the cosine"; public override string Description => "Treats the input as an angle and calculates the cosine";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue)
{ {
return Math.Cos(Convert.ToSingle(currentValue)); return Math.Cos(currentValue);
} }
} }
} }

View File

@ -1,21 +1,17 @@
using System; using System;
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class CotangentModifierType : DataBindingModifierType internal class CotangentModifierType : DataBindingModifierType<double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override bool SupportsParameter => false;
public override string Name => "Cotangent"; public override string Name => "Cotangent";
public override string Icon => null; public override string Icon => null;
public override string Category => "Trigonometry"; public override string Category => "Trigonometry";
public override string Description => "Treats the input as an angle and calculates the cotangent"; public override string Description => "Treats the input as an angle and calculates the cotangent";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue)
{ {
return 1f / Math.Tan(Convert.ToSingle(currentValue)); return 1d / Math.Tan(currentValue);
} }
} }
} }

View File

@ -1,21 +1,17 @@
using System; using System;
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class SecantModifierType : DataBindingModifierType internal class SecantModifierType : DataBindingModifierType<double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override bool SupportsParameter => false;
public override string Name => "Secant"; public override string Name => "Secant";
public override string Icon => null; public override string Icon => null;
public override string Category => "Trigonometry"; public override string Category => "Trigonometry";
public override string Description => "Treats the input as an angle and calculates the secant"; public override string Description => "Treats the input as an angle and calculates the secant";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue)
{ {
return 1f / Math.Cos(Convert.ToSingle(currentValue)); return 1d / Math.Cos(currentValue);
} }
} }
} }

View File

@ -1,21 +1,17 @@
using System; using System;
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class SineModifierType : DataBindingModifierType internal class SineModifierType : DataBindingModifierType<double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override bool SupportsParameter => false;
public override string Name => "Sine"; public override string Name => "Sine";
public override string Icon => "MathSin"; public override string Icon => "MathSin";
public override string Category => "Trigonometry"; public override string Category => "Trigonometry";
public override string Description => "Treats the input as an angle and calculates the sine"; public override string Description => "Treats the input as an angle and calculates the sine";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue)
{ {
return Math.Sin(Convert.ToSingle(currentValue)); return Math.Sin(currentValue);
} }
} }
} }

View File

@ -1,21 +1,17 @@
using System; using System;
using System.Collections.Generic;
namespace Artemis.Core.DefaultTypes namespace Artemis.Core.DefaultTypes
{ {
internal class TangentModifierType : DataBindingModifierType internal class TangentModifierType : DataBindingModifierType<double>
{ {
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override bool SupportsParameter => false;
public override string Name => "Tangent"; public override string Name => "Tangent";
public override string Icon => "MathTan"; public override string Icon => "MathTan";
public override string Category => "Trigonometry"; public override string Category => "Trigonometry";
public override string Description => "Treats the input as an angle and calculates the tangent"; public override string Description => "Treats the input as an angle and calculates the tangent";
public override object Apply(object currentValue, object parameterValue) public override double Apply(double currentValue)
{ {
return Math.Tan(Convert.ToSingle(currentValue)); return Math.Tan(currentValue);
} }
} }
} }

View File

@ -33,7 +33,7 @@ namespace Artemis.Core
public abstract Type LeftSideType { get; } public abstract Type LeftSideType { get; }
/// <summary> /// <summary>
/// Gets the right side type of this condition operator. May be null if the operator does not support a left side type /// Gets the right side type of this condition operator. May be null if the operator does not support a right side
/// </summary> /// </summary>
public abstract Type? RightSideType { get; } public abstract Type? RightSideType { get; }
@ -42,7 +42,14 @@ namespace Artemis.Core
/// </summary> /// </summary>
/// <param name="type">The type to check for, must be either the same or be castable to the target type</param> /// <param name="type">The type to check for, must be either the same or be castable to the target type</param>
/// <param name="side">Which side of the operator to check, left or right</param> /// <param name="side">Which side of the operator to check, left or right</param>
public abstract bool SupportsType(Type type, ConditionParameterSide side); public bool SupportsType(Type type, ConditionParameterSide side)
{
if (type == null)
return true;
if (side == ConditionParameterSide.Left)
return LeftSideType.IsCastableFrom(type);
return RightSideType != null && RightSideType.IsCastableFrom(type);
}
/// <summary> /// <summary>
/// Evaluates the condition with the input types being provided as objects /// Evaluates the condition with the input types being provided as objects

View File

@ -13,17 +13,7 @@ namespace Artemis.Core
/// <param name="a">The parameter on the left side of the expression</param> /// <param name="a">The parameter on the left side of the expression</param>
/// <param name="b">The parameter on the right side of the expression</param> /// <param name="b">The parameter on the right side of the expression</param>
public abstract bool Evaluate(TLeftSide a, TRightSide b); public abstract bool Evaluate(TLeftSide a, TRightSide b);
/// <inheritdoc />
public override bool SupportsType(Type type, ConditionParameterSide side)
{
if (type == null)
return true;
if (side == ConditionParameterSide.Left)
return LeftSideType.IsCastableFrom(type);
return RightSideType.IsCastableFrom(type);
}
/// <inheritdoc /> /// <inheritdoc />
internal override bool InternalEvaluate(object? leftSideValue, object? rightSideValue) internal override bool InternalEvaluate(object? leftSideValue, object? rightSideValue)
{ {
@ -40,7 +30,7 @@ namespace Artemis.Core
else else
rightSide = default; rightSide = default;
return Evaluate(leftSide, rightSide); return Evaluate(leftSide!, rightSide!);
} }
/// <inheritdoc /> /// <inheritdoc />
@ -61,16 +51,6 @@ namespace Artemis.Core
/// <param name="a">The parameter on the left side of the expression</param> /// <param name="a">The parameter on the left side of the expression</param>
public abstract bool Evaluate(TLeftSide a); public abstract bool Evaluate(TLeftSide a);
/// <inheritdoc />
public override bool SupportsType(Type type, ConditionParameterSide side)
{
if (type == null)
return true;
if (side == ConditionParameterSide.Left)
return LeftSideType.IsCastableFrom(type);
return false;
}
/// <inheritdoc /> /// <inheritdoc />
internal override bool InternalEvaluate(object? leftSideValue, object? rightSideValue) internal override bool InternalEvaluate(object? leftSideValue, object? rightSideValue)
{ {
@ -81,7 +61,7 @@ namespace Artemis.Core
else else
leftSide = default; leftSide = default;
return Evaluate(leftSide); return Evaluate(leftSide!);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@ -388,7 +388,7 @@ namespace Artemis.Core
return; return;
if (!Operator.SupportsType(RightStaticValue.GetType(), ConditionParameterSide.Right)) if (!Operator.SupportsType(RightStaticValue.GetType(), ConditionParameterSide.Right))
UpdateRightSideDynamic(null); UpdateRightSideStatic(null);
} }
} }

View File

@ -144,7 +144,7 @@ namespace Artemis.Core
return; return;
} }
// No need to clear compiled expressions, without a left data model they are already null // No need to check for compatibility without a left side, when left site does get set it will be checked again
if (LeftPath == null || !LeftPath.IsValid) if (LeftPath == null || !LeftPath.IsValid)
{ {
Operator = conditionOperator; Operator = conditionOperator;
@ -323,7 +323,7 @@ namespace Artemis.Core
return; return;
if (!Operator.SupportsType(RightStaticValue.GetType(), ConditionParameterSide.Right)) if (!Operator.SupportsType(RightStaticValue.GetType(), ConditionParameterSide.Right))
UpdateRightSideDynamic(null); UpdateRightSideStatic(null);
} }
} }

View File

@ -1,79 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Artemis.Core
{
/// <summary>
/// A modifier that changes the source value of a data binding in some way
/// </summary>
public abstract class DataBindingModifierType
{
/// <summary>
/// Gets the plugin info this data binding modifier belongs to
/// <para>Note: Not set until after registering</para>
/// </summary>
public PluginInfo PluginInfo { get; internal set; }
/// <summary>
/// Gets the types this modifier supports
/// </summary>
public abstract IReadOnlyCollection<Type> CompatibleTypes { get; }
/// <summary>
/// Gets the supported parameter type
/// <para>If <c>null</c>, the parameter type will match the source property</para>
/// </summary>
public virtual Type ParameterType => null;
/// <summary>
/// Gets or sets whether this modifier supports a parameter, defaults to <c>true</c>
/// </summary>
public virtual bool SupportsParameter => true;
/// <summary>
/// Gets the name of this modifier
/// </summary>
public abstract string Name { get; }
/// <summary>
/// Gets or sets the icon of this modifier
/// </summary>
public abstract string Icon { get; }
/// <summary>
/// Gets the description of this modifier
/// </summary>
public virtual string Description => null;
/// <summary>
/// Gets the category of this modifier
/// </summary>
public virtual string Category => null;
/// <summary>
/// Returns whether the given type is supported by the modifier
/// </summary>
public bool SupportsType(Type type)
{
if (type == null)
return true;
return CompatibleTypes.Any(t => t.IsCastableFrom(type));
}
/// <summary>
/// Called whenever the modifier must apply to a specific value, must be a value of a type contained in
/// <see cref="CompatibleTypes" />
/// </summary>
/// <param name="currentValue">
/// The current value before modification, is always of a type contained in
/// <see cref="CompatibleTypes" />
/// </param>
/// <param name="parameterValue">
/// The parameter to use for the modification, is always of a type contained in
/// <see cref="CompatibleTypes" />
/// </param>
/// <returns>The modified value, must be a value of a type contained in <see cref="CompatibleTypes" /></returns>
public abstract object Apply(object currentValue, object parameterValue);
}
}

View File

@ -0,0 +1,82 @@
using System;
namespace Artemis.Core
{
/// <summary>
/// A modifier that changes the source value of a data binding in some way
/// <para>
/// To implement your own condition operator, inherit <see cref="DataBindingModifierType{TValue, TParameter}" /> or
/// <see cref="DataBindingModifierType{TValue}" />
/// </para>
/// </summary>
public abstract class BaseDataBindingModifierType
{
/// <summary>
/// Gets the plugin info this data binding modifier belongs to
/// <para>Note: Not set until after registering</para>
/// </summary>
public PluginInfo PluginInfo { get; internal set; }
/// <summary>
/// Gets the value type of this modifier type
/// </summary>
public abstract Type ValueType { get; }
/// <summary>
/// Gets the parameter type of this modifier type. May be null if the modifier type does not support a parameter
/// </summary>
public abstract Type? ParameterType { get; }
/// <summary>
/// Gets the name of this modifier
/// </summary>
public abstract string Name { get; }
/// <summary>
/// Gets or sets the icon of this modifier
/// </summary>
public abstract string Icon { get; }
/// <summary>
/// Gets the description of this modifier
/// </summary>
public virtual string Description => null;
/// <summary>
/// Gets the category of this modifier
/// </summary>
public virtual string Category => null;
/// <summary>
/// Returns whether the given type is supported by the modifier
/// </summary>
/// <param name="type">The type to check for, must be either the same or be castable to the target type</param>
/// <param name="part">Which part of the modifier to check, the value or the parameter</param>
public bool SupportsType(Type type, ModifierTypePart part)
{
if (type == null)
return true;
if (part == ModifierTypePart.Value)
return ValueType.IsCastableFrom(type);
return ParameterType != null && ParameterType.IsCastableFrom(type);
}
/// <summary>
/// Applies the modifier to the provided current value
/// <para>
/// This leaves the caller responsible for the types matching <see cref="ValueType" /> and
/// <see cref="ParameterType" />
/// </para>
/// </summary>
/// <param name="currentValue">The current value before modification, type should match <see cref="ValueType" /></param>
/// <param name="parameterValue">The parameter to use for the modification, type should match <see cref="ParameterType" /></param>
/// <returns>The modified value, with a type of <see cref="ValueType" /></returns>
internal abstract object? InternalApply(object? currentValue, object? parameterValue);
}
public enum ModifierTypePart
{
Value,
Parameter
}
}

View File

@ -30,7 +30,7 @@ namespace Artemis.Core
/// <summary> /// <summary>
/// Gets the type of modifier that is being applied /// Gets the type of modifier that is being applied
/// </summary> /// </summary>
public DataBindingModifierType ModifierType { get; private set; } public BaseDataBindingModifierType? ModifierType { get; private set; }
/// <summary> /// <summary>
/// Gets the direct data binding this modifier is applied to /// Gets the direct data binding this modifier is applied to
@ -40,7 +40,7 @@ namespace Artemis.Core
/// <summary> /// <summary>
/// Gets the type of the parameter, can either be dynamic (based on a data model value) or static /// Gets the type of the parameter, can either be dynamic (based on a data model value) or static
/// </summary> /// </summary>
public ProfileRightSideType ParameterType { get; private set; } public ProfileRightSideType ParameterType { get; set; }
/// <summary> /// <summary>
/// Gets or sets the position at which the modifier appears on the data binding /// Gets or sets the position at which the modifier appears on the data binding
@ -56,7 +56,7 @@ namespace Artemis.Core
/// Gets the parameter static value, only used it <see cref="ParameterType" /> is /// Gets the parameter static value, only used it <see cref="ParameterType" /> is
/// <see cref="ProfileRightSideType.Static" /> /// <see cref="ProfileRightSideType.Static" />
/// </summary> /// </summary>
public object ParameterStaticValue { get; private set; } public object? ParameterStaticValue { get; private set; }
internal DataBindingModifierEntity Entity { get; set; } internal DataBindingModifierEntity Entity { get; set; }
@ -65,7 +65,7 @@ namespace Artemis.Core
/// </summary> /// </summary>
/// <param name="currentValue">The value to apply the modifier to, should be of the same type as the data binding target</param> /// <param name="currentValue">The value to apply the modifier to, should be of the same type as the data binding target</param>
/// <returns>The modified value</returns> /// <returns>The modified value</returns>
public object Apply(object? currentValue) public object? Apply(object? currentValue)
{ {
if (_disposed) if (_disposed)
throw new ObjectDisposedException("DataBindingModifier"); throw new ObjectDisposedException("DataBindingModifier");
@ -73,17 +73,17 @@ namespace Artemis.Core
if (ModifierType == null) if (ModifierType == null)
return currentValue; return currentValue;
if (!ModifierType.SupportsParameter) if (ModifierType.ParameterType == null)
return ModifierType.Apply(currentValue, null); return ModifierType.InternalApply(currentValue, null);
if (ParameterType == ProfileRightSideType.Dynamic && ParameterPath != null && ParameterPath.IsValid) if (ParameterType == ProfileRightSideType.Dynamic && ParameterPath != null && ParameterPath.IsValid)
{ {
object? value = ParameterPath.GetValue(); object? value = ParameterPath.GetValue();
return ModifierType.Apply(currentValue, value); return ModifierType.InternalApply(currentValue, value);
} }
if (ParameterType == ProfileRightSideType.Static) if (ParameterType == ProfileRightSideType.Static)
return ModifierType.Apply(currentValue, ParameterStaticValue); return ModifierType.InternalApply(currentValue, ParameterStaticValue);
return currentValue; return currentValue;
} }
@ -92,12 +92,11 @@ namespace Artemis.Core
/// Updates the modifier type of the modifier and re-compiles the expression /// Updates the modifier type of the modifier and re-compiles the expression
/// </summary> /// </summary>
/// <param name="modifierType"></param> /// <param name="modifierType"></param>
public void UpdateModifierType(DataBindingModifierType modifierType) public void UpdateModifierType(BaseDataBindingModifierType? modifierType)
{ {
if (_disposed) if (_disposed)
throw new ObjectDisposedException("DataBindingModifier"); throw new ObjectDisposedException("DataBindingModifier");
// Calling CreateExpression will clear compiled expressions
if (modifierType == null) if (modifierType == null)
{ {
ModifierType = null; ModifierType = null;
@ -105,11 +104,36 @@ namespace Artemis.Core
} }
Type targetType = DirectDataBinding.DataBinding.GetTargetType(); Type targetType = DirectDataBinding.DataBinding.GetTargetType();
if (!modifierType.SupportsType(targetType)) if (!modifierType.SupportsType(targetType, ModifierTypePart.Value))
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 " +
$"it does not support this data binding's type {targetType.Name}"); $"it does not support this data binding's type {targetType.Name}");
ModifierType = modifierType; ModifierType = modifierType;
ValidateParameter();
}
private void ValidateParameter()
{
if (ModifierType == null)
return;
if (ParameterType == ProfileRightSideType.Dynamic)
{
if (ParameterPath == null || !ParameterPath.IsValid)
return;
Type parameterType = ParameterPath.GetPropertyType()!;
if (!ModifierType.SupportsType(parameterType, ModifierTypePart.Parameter))
UpdateParameterDynamic(null);
}
else
{
if (ParameterStaticValue == null)
return;
if (!ModifierType.SupportsType(ParameterStaticValue.GetType(), ModifierTypePart.Parameter))
UpdateParameterStatic(null);
}
} }
/// <summary> /// <summary>
@ -165,7 +189,7 @@ namespace Artemis.Core
// Modifier type // Modifier type
if (Entity.ModifierTypePluginGuid != null && ModifierType == null) if (Entity.ModifierTypePluginGuid != null && ModifierType == null)
{ {
DataBindingModifierType modifierType = DataBindingModifierTypeStore.Get(Entity.ModifierTypePluginGuid.Value, Entity.ModifierType)?.DataBindingModifierType; BaseDataBindingModifierType modifierType = DataBindingModifierTypeStore.Get(Entity.ModifierTypePluginGuid.Value, Entity.ModifierType)?.DataBindingModifierType;
if (modifierType != null) if (modifierType != null)
UpdateModifierType(modifierType); UpdateModifierType(modifierType);
} }
@ -261,7 +285,7 @@ namespace Artemis.Core
if (ModifierType != null) if (ModifierType != null)
return; return;
DataBindingModifierType modifierType = e.TypeRegistration.DataBindingModifierType; BaseDataBindingModifierType modifierType = e.TypeRegistration.DataBindingModifierType;
if (modifierType.PluginInfo.Guid == Entity.ModifierTypePluginGuid && modifierType.GetType().Name == Entity.ModifierType) if (modifierType.PluginInfo.Guid == Entity.ModifierTypePluginGuid && modifierType.GetType().Name == Entity.ModifierType)
UpdateModifierType(modifierType); UpdateModifierType(modifierType);
} }

View File

@ -0,0 +1,81 @@
using System;
namespace Artemis.Core
{
/// <summary>
/// A modifier that changes the source value of a data binding in some way using a parameter
/// </summary>
public abstract class DataBindingModifierType<TValue, TParameter> : BaseDataBindingModifierType
{
/// <inheritdoc />
public override Type ValueType => typeof(TValue);
/// <inheritdoc />
public override Type ParameterType => typeof(TParameter);
/// <summary>
/// Called whenever the modifier must apply to a specific value
/// </summary>
/// <param name="currentValue">
/// The current value before modification
/// </param>
/// <param name="parameterValue">
/// The parameter to use for the modification
/// </param>
/// <returns>The modified value></returns>
public abstract TValue Apply(TValue currentValue, TParameter parameterValue);
/// <inheritdoc />
internal override object? InternalApply(object? currentValue, object? parameterValue)
{
// TODO: Can we avoid boxing/unboxing?
TValue current;
if (currentValue != null)
current = (TValue) Convert.ChangeType(currentValue, typeof(TValue));
else
current = default;
TParameter parameter;
if (parameterValue != null)
parameter = (TParameter) Convert.ChangeType(parameterValue, typeof(TParameter));
else
parameter = default;
return Apply(current!, parameter!);
}
}
/// <summary>
/// A modifier that changes the source value of a data binding in some way
/// </summary>
public abstract class DataBindingModifierType<TValue> : BaseDataBindingModifierType
{
/// <inheritdoc />
public override Type ValueType => typeof(TValue);
/// <inheritdoc />
public override Type? ParameterType => null;
/// <summary>
/// Called whenever the modifier must apply to a specific value
/// </summary>
/// <param name="currentValue">
/// The current value before modification
/// </param>
/// <returns>The modified value</returns>
public abstract TValue Apply(TValue currentValue);
/// <inheritdoc />
internal override object? InternalApply(object? currentValue, object? parameterValue)
{
// TODO: Can we avoid boxing/unboxing?
TValue current;
if (currentValue != null)
current = (TValue) Convert.ChangeType(currentValue, typeof(TValue));
else
current = default;
return Apply(current!);
}
}
}

View File

@ -12,7 +12,7 @@ namespace Artemis.Core.Services
RegisterBuiltInModifiers(); RegisterBuiltInModifiers();
} }
public DataBindingModifierTypeRegistration RegisterModifierType(PluginInfo pluginInfo, DataBindingModifierType dataBindingModifierType) public DataBindingModifierTypeRegistration RegisterModifierType(PluginInfo pluginInfo, BaseDataBindingModifierType dataBindingModifierType)
{ {
if (pluginInfo == null) if (pluginInfo == null)
throw new ArgumentNullException(nameof(pluginInfo)); throw new ArgumentNullException(nameof(pluginInfo));
@ -30,12 +30,12 @@ namespace Artemis.Core.Services
DataBindingModifierTypeStore.Remove(registration); DataBindingModifierTypeStore.Remove(registration);
} }
public List<DataBindingModifierType> GetCompatibleModifierTypes(Type type) public List<BaseDataBindingModifierType> GetCompatibleModifierTypes(Type type, ModifierTypePart part)
{ {
return DataBindingModifierTypeStore.GetForType(type).Select(r => r.DataBindingModifierType).ToList(); return DataBindingModifierTypeStore.GetForType(type, part).Select(r => r.DataBindingModifierType).ToList();
} }
public DataBindingModifierType GetModifierType(Guid modifierTypePluginGuid, string modifierType) public BaseDataBindingModifierType GetModifierType(Guid modifierTypePluginGuid, string modifierType)
{ {
return DataBindingModifierTypeStore.Get(modifierTypePluginGuid, modifierType)?.DataBindingModifierType; return DataBindingModifierTypeStore.Get(modifierTypePluginGuid, modifierType)?.DataBindingModifierType;
} }

View File

@ -14,7 +14,7 @@ namespace Artemis.Core.Services
/// </summary> /// </summary>
/// <param name="pluginInfo">The PluginInfo of the plugin this modifier type belongs to</param> /// <param name="pluginInfo">The PluginInfo of the plugin this modifier type belongs to</param>
/// <param name="dataBindingModifierType">The modifier type to register</param> /// <param name="dataBindingModifierType">The modifier type to register</param>
DataBindingModifierTypeRegistration RegisterModifierType([NotNull] PluginInfo pluginInfo, [NotNull] DataBindingModifierType dataBindingModifierType); DataBindingModifierTypeRegistration RegisterModifierType([NotNull] PluginInfo pluginInfo, [NotNull] BaseDataBindingModifierType dataBindingModifierType);
/// <summary> /// <summary>
/// Removes a modifier type so it is no longer available for use in data bindings /// Removes a modifier type so it is no longer available for use in data bindings
@ -25,7 +25,7 @@ namespace Artemis.Core.Services
/// <summary> /// <summary>
/// Returns all the data binding modifier types compatible with the provided type /// Returns all the data binding modifier types compatible with the provided type
/// </summary> /// </summary>
List<DataBindingModifierType> GetCompatibleModifierTypes(Type type); List<BaseDataBindingModifierType> GetCompatibleModifierTypes(Type type, ModifierTypePart part);
/// <summary> /// <summary>
/// Gets a modifier type by its plugin GUID and type name /// Gets a modifier type by its plugin GUID and type name
@ -33,6 +33,6 @@ namespace Artemis.Core.Services
/// <param name="modifierTypePluginGuid">The modifier type's plugin GUID</param> /// <param name="modifierTypePluginGuid">The modifier type's plugin GUID</param>
/// <param name="modifierType">The type name of the modifier type</param> /// <param name="modifierType">The type name of the modifier type</param>
/// <returns></returns> /// <returns></returns>
DataBindingModifierType GetModifierType(Guid modifierTypePluginGuid, string modifierType); BaseDataBindingModifierType GetModifierType(Guid modifierTypePluginGuid, string modifierType);
} }
} }

View File

@ -8,7 +8,7 @@ namespace Artemis.Core
{ {
private static readonly List<DataBindingModifierTypeRegistration> Registrations = new List<DataBindingModifierTypeRegistration>(); private static readonly List<DataBindingModifierTypeRegistration> Registrations = new List<DataBindingModifierTypeRegistration>();
public static DataBindingModifierTypeRegistration Add(DataBindingModifierType modifierType) public static DataBindingModifierTypeRegistration Add(BaseDataBindingModifierType modifierType)
{ {
DataBindingModifierTypeRegistration typeRegistration; DataBindingModifierTypeRegistration typeRegistration;
lock (Registrations) lock (Registrations)
@ -46,19 +46,21 @@ namespace Artemis.Core
} }
} }
public static List<DataBindingModifierTypeRegistration> GetForType(Type type) public static List<DataBindingModifierTypeRegistration> GetForType(Type type, ModifierTypePart part)
{ {
lock (Registrations) lock (Registrations)
{ {
if (type == null) if (type == null)
return new List<DataBindingModifierTypeRegistration>(Registrations); return new List<DataBindingModifierTypeRegistration>(Registrations);
List<DataBindingModifierTypeRegistration> candidates = Registrations.Where(r => r.DataBindingModifierType.CompatibleTypes.Any(t => t == type)).ToList(); List<DataBindingModifierTypeRegistration> candidates = Registrations.Where(r => r.DataBindingModifierType.SupportsType(type, part)).ToList();
// If there are multiple operators with the same description, use the closest match // If there are multiple modifiers with the same description, use the closest match
foreach (IGrouping<string, DataBindingModifierTypeRegistration> displayDataBindingModifiers in candidates.GroupBy(r => r.DataBindingModifierType.Name).Where(g => g.Count() > 1).ToList()) foreach (IGrouping<string, DataBindingModifierTypeRegistration> displayDataBindingModifiers in candidates.GroupBy(r => r.DataBindingModifierType.Name).Where(g => g.Count() > 1).ToList())
{ {
DataBindingModifierTypeRegistration closest = displayDataBindingModifiers.OrderByDescending(r => r.DataBindingModifierType.CompatibleTypes.Contains(type)).FirstOrDefault(); DataBindingModifierTypeRegistration closest = part == ModifierTypePart.Value
? displayDataBindingModifiers.OrderByDescending(r => r.DataBindingModifierType.ValueType.ScoreCastability(type)).First()
: displayDataBindingModifiers.OrderByDescending(r => r.DataBindingModifierType.ParameterType!.ScoreCastability(type)).First();
foreach (DataBindingModifierTypeRegistration displayDataBindingModifier in displayDataBindingModifiers) foreach (DataBindingModifierTypeRegistration displayDataBindingModifier in displayDataBindingModifiers)
{ {
if (displayDataBindingModifier != closest) if (displayDataBindingModifier != closest)

View File

@ -7,7 +7,7 @@ namespace Artemis.Core
/// </summary> /// </summary>
public class DataBindingModifierTypeRegistration public class DataBindingModifierTypeRegistration
{ {
internal DataBindingModifierTypeRegistration(DataBindingModifierType dataBindingModifierType, Plugin plugin) internal DataBindingModifierTypeRegistration(BaseDataBindingModifierType dataBindingModifierType, Plugin plugin)
{ {
DataBindingModifierType = dataBindingModifierType; DataBindingModifierType = dataBindingModifierType;
Plugin = plugin; Plugin = plugin;
@ -18,7 +18,7 @@ namespace Artemis.Core
/// <summary> /// <summary>
/// Gets the data binding modifier that has been registered /// Gets the data binding modifier that has been registered
/// </summary> /// </summary>
public DataBindingModifierType DataBindingModifierType { get; } public BaseDataBindingModifierType DataBindingModifierType { get; }
/// <summary> /// <summary>
/// Gets the plugin the data binding modifier is associated with /// Gets the plugin the data binding modifier is associated with

View File

@ -41,6 +41,8 @@
</UserControl.Resources> </UserControl.Resources>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Button Style="{StaticResource MaterialDesignFlatDarkBgButton}" <Button Style="{StaticResource MaterialDesignFlatDarkBgButton}"
Background="{Binding SwitchButtonBrush}"
BorderBrush="{Binding SwitchButtonBrush}"
Height="22" Height="22"
Padding="0" Padding="0"
Width="22" Width="22"

View File

@ -7,6 +7,7 @@ using Artemis.Core;
using Artemis.Core.Modules; using Artemis.Core.Modules;
using Artemis.Core.Services; using Artemis.Core.Services;
using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services;
using MaterialDesignColors.ColorManipulation;
using Stylet; using Stylet;
// Remove, annoying while working on it // Remove, annoying while working on it
@ -19,7 +20,7 @@ namespace Artemis.UI.Shared.Input
private readonly IDataModelUIService _dataModelUIService; private readonly IDataModelUIService _dataModelUIService;
private readonly Module _module; private readonly Module _module;
private readonly Timer _updateTimer; private readonly Timer _updateTimer;
private Brush _buttonBrush = new SolidColorBrush(Color.FromRgb(171, 71, 188)); private SolidColorBrush _buttonBrush = new SolidColorBrush(Color.FromRgb(171, 71, 188));
private DataModelPath _dataModelPath; private DataModelPath _dataModelPath;
private DataModelPropertiesViewModel _dataModelViewModel; private DataModelPropertiesViewModel _dataModelViewModel;
private bool _displaySwitchButton; private bool _displaySwitchButton;
@ -41,12 +42,18 @@ namespace Artemis.UI.Shared.Input
Initialize(); Initialize();
} }
public Brush ButtonBrush public SolidColorBrush ButtonBrush
{ {
get => _buttonBrush; get => _buttonBrush;
set => SetAndNotify(ref _buttonBrush, value); set
{
if (!SetAndNotify(ref _buttonBrush, value)) return;
NotifyOfPropertyChange(nameof(SwitchButtonBrush));
}
} }
public SolidColorBrush SwitchButtonBrush => new SolidColorBrush(ButtonBrush.Color.Darken());
public string Placeholder public string Placeholder
{ {
get => _placeholder; get => _placeholder;

View File

@ -24,6 +24,8 @@
<Grid Margin="3 -4"> <Grid Margin="3 -4">
<StackPanel Orientation="Horizontal" Visibility="{Binding InputViewModel, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}"> <StackPanel Orientation="Horizontal" Visibility="{Binding InputViewModel, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}">
<Button Style="{StaticResource MaterialDesignFlatDarkBgButton}" <Button Style="{StaticResource MaterialDesignFlatDarkBgButton}"
Background="{Binding SwitchButtonBrush}"
BorderBrush="{Binding SwitchButtonBrush}"
Height="22" Height="22"
Padding="0" Padding="0"
Width="22" Width="22"
@ -32,7 +34,8 @@
Margin="0 0 -3 0" Margin="0 0 -3 0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
ToolTip="Switch to data model value" ToolTip="Switch to data model value"
Command="{s:Action SwitchToDynamic}"> Command="{s:Action SwitchToDynamic}"
Visibility="{Binding DisplaySwitchButton, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
<materialDesign:PackIcon Kind="SwapHorizontal" /> <materialDesign:PackIcon Kind="SwapHorizontal" />
</Button> </Button>
<Button Style="{StaticResource DataModelConditionButton}" <Button Style="{StaticResource DataModelConditionButton}"

View File

@ -6,6 +6,7 @@ using System.Windows.Media;
using Artemis.Core; using Artemis.Core;
using Artemis.Core.DataModelExpansions; using Artemis.Core.DataModelExpansions;
using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services;
using MaterialDesignColors.ColorManipulation;
using Stylet; using Stylet;
namespace Artemis.UI.Shared.Input namespace Artemis.UI.Shared.Input
@ -14,7 +15,7 @@ namespace Artemis.UI.Shared.Input
{ {
private readonly IDataModelUIService _dataModelUIService; private readonly IDataModelUIService _dataModelUIService;
private readonly Window _rootView; private readonly Window _rootView;
private Brush _buttonBrush = new SolidColorBrush(Color.FromRgb(171, 71, 188)); private SolidColorBrush _buttonBrush = new SolidColorBrush(Color.FromRgb(171, 71, 188));
private DataModelDisplayViewModel _displayViewModel; private DataModelDisplayViewModel _displayViewModel;
private DataModelInputViewModel _inputViewModel; private DataModelInputViewModel _inputViewModel;
private bool _isEnabled; private bool _isEnabled;
@ -22,6 +23,7 @@ namespace Artemis.UI.Shared.Input
private DataModelPropertyAttribute _targetDescription; private DataModelPropertyAttribute _targetDescription;
private Type _targetType; private Type _targetType;
private object _value; private object _value;
private bool _displaySwitchButton;
internal DataModelStaticViewModel(Type targetType, DataModelPropertyAttribute targetDescription, IDataModelUIService dataModelUIService) internal DataModelStaticViewModel(Type targetType, DataModelPropertyAttribute targetDescription, IDataModelUIService dataModelUIService)
{ {
@ -40,12 +42,18 @@ namespace Artemis.UI.Shared.Input
} }
} }
public Brush ButtonBrush public SolidColorBrush ButtonBrush
{ {
get => _buttonBrush; get => _buttonBrush;
set => SetAndNotify(ref _buttonBrush, value); set
{
if (!SetAndNotify(ref _buttonBrush, value)) return;
NotifyOfPropertyChange(nameof(SwitchButtonBrush));
}
} }
public SolidColorBrush SwitchButtonBrush => new SolidColorBrush(ButtonBrush.Color.Darken());
public DataModelDisplayViewModel DisplayViewModel public DataModelDisplayViewModel DisplayViewModel
{ {
get => _displayViewModel; get => _displayViewModel;
@ -92,6 +100,12 @@ namespace Artemis.UI.Shared.Input
private set => SetAndNotify(ref _isEnabled, value); private set => SetAndNotify(ref _isEnabled, value);
} }
public bool DisplaySwitchButton
{
get => _displaySwitchButton;
set => SetAndNotify(ref _displaySwitchButton, value);
}
public void ActivateInputViewModel() public void ActivateInputViewModel()
{ {
InputViewModel = _dataModelUIService.GetDataModelInputViewModel( InputViewModel = _dataModelUIService.GetDataModelInputViewModel(

View File

@ -275,7 +275,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
private void CreateRightSideSelectionViewModel() private void CreateRightSideSelectionViewModel()
{ {
RightSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule()); RightSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
RightSideSelectionViewModel.ButtonBrush = (Brush) Application.Current.FindResource("PrimaryHueMidBrush"); RightSideSelectionViewModel.ButtonBrush = (SolidColorBrush) Application.Current.FindResource("PrimaryHueMidBrush");
RightSideSelectionViewModel.DisplaySwitchButton = true; RightSideSelectionViewModel.DisplaySwitchButton = true;
RightSideSelectionViewModel.PropertySelected += RightSideOnPropertySelected; RightSideSelectionViewModel.PropertySelected += RightSideOnPropertySelected;
RightSideSelectionViewModel.SwitchToStaticRequested += RightSideSelectionViewModelOnSwitchToStaticRequested; RightSideSelectionViewModel.SwitchToStaticRequested += RightSideSelectionViewModelOnSwitchToStaticRequested;
@ -289,7 +289,8 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
private void CreateRightSideInputViewModel(Type leftSideType) private void CreateRightSideInputViewModel(Type leftSideType)
{ {
RightSideInputViewModel = _dataModelUIService.GetStaticInputViewModel(leftSideType, LeftSideSelectionViewModel.DataModelPath?.GetPropertyDescription()); RightSideInputViewModel = _dataModelUIService.GetStaticInputViewModel(leftSideType, LeftSideSelectionViewModel.DataModelPath?.GetPropertyDescription());
RightSideInputViewModel.ButtonBrush = (Brush) Application.Current.FindResource("PrimaryHueMidBrush"); RightSideInputViewModel.ButtonBrush = (SolidColorBrush) Application.Current.FindResource("PrimaryHueMidBrush");
RightSideInputViewModel.DisplaySwitchButton = true;
RightSideInputViewModel.ValueUpdated += RightSideOnValueEntered; RightSideInputViewModel.ValueUpdated += RightSideOnValueEntered;
RightSideInputViewModel.SwitchToDynamicRequested += RightSideInputViewModelOnSwitchToDynamicRequested; RightSideInputViewModel.SwitchToDynamicRequested += RightSideInputViewModelOnSwitchToDynamicRequested;
} }

View File

@ -218,7 +218,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
private void CreateRightSideSelectionViewModel() private void CreateRightSideSelectionViewModel()
{ {
RightSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule()); RightSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
RightSideSelectionViewModel.ButtonBrush = (Brush) Application.Current.FindResource("PrimaryHueMidBrush"); RightSideSelectionViewModel.ButtonBrush = (SolidColorBrush) Application.Current.FindResource("PrimaryHueMidBrush");
RightSideSelectionViewModel.DisplaySwitchButton = true; RightSideSelectionViewModel.DisplaySwitchButton = true;
RightSideSelectionViewModel.PropertySelected += RightSideOnPropertySelected; RightSideSelectionViewModel.PropertySelected += RightSideOnPropertySelected;
RightSideSelectionViewModel.SwitchToStaticRequested += RightSideSelectionViewModelOnSwitchToStaticRequested; RightSideSelectionViewModel.SwitchToStaticRequested += RightSideSelectionViewModelOnSwitchToStaticRequested;
@ -227,7 +227,8 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
private void CreateRightSideInputViewModel(Type leftSideType) private void CreateRightSideInputViewModel(Type leftSideType)
{ {
RightSideInputViewModel = _dataModelUIService.GetStaticInputViewModel(leftSideType, LeftSideSelectionViewModel.DataModelPath?.GetPropertyDescription()); RightSideInputViewModel = _dataModelUIService.GetStaticInputViewModel(leftSideType, LeftSideSelectionViewModel.DataModelPath?.GetPropertyDescription());
RightSideInputViewModel.ButtonBrush = (Brush) Application.Current.FindResource("PrimaryHueMidBrush"); RightSideInputViewModel.ButtonBrush = (SolidColorBrush) Application.Current.FindResource("PrimaryHueMidBrush");
RightSideInputViewModel.DisplaySwitchButton = true;
RightSideInputViewModel.ValueUpdated += RightSideOnValueEntered; RightSideInputViewModel.ValueUpdated += RightSideOnValueEntered;
RightSideInputViewModel.SwitchToDynamicRequested += RightSideInputViewModelOnSwitchToDynamicRequested; RightSideInputViewModel.SwitchToDynamicRequested += RightSideInputViewModelOnSwitchToDynamicRequested;
} }

View File

@ -24,7 +24,6 @@
</UserControl.Resources> </UserControl.Resources>
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
@ -39,18 +38,8 @@
Command="{s:Action Delete}"> Command="{s:Action Delete}">
<materialDesign:PackIcon Kind="Close" Width="18" Height="18" /> <materialDesign:PackIcon Kind="Close" Width="18" Height="18" />
</Button> </Button>
<Button Grid.Column="1" <Button Grid.Column="1"
ToolTip="Swap modifier type to static/dynamic"
Style="{StaticResource MaterialDesignIconForegroundButton}"
HorizontalAlignment="Left"
Foreground="{StaticResource SecondaryAccentBrush}"
Width="25"
Height="25"
Command="{s:Action SwapType}">
<materialDesign:PackIcon Kind="SwapHorizontalVariant" Width="18" Height="18" />
</Button>
<Button Grid.Column="2"
Style="{StaticResource DataModelConditionButtonLeftClickMenu}" Style="{StaticResource DataModelConditionButtonLeftClickMenu}"
Background="#7B7B7B" Background="#7B7B7B"
BorderBrush="#7B7B7B" BorderBrush="#7B7B7B"
@ -101,7 +90,7 @@
</Button> </Button>
<ContentControl Grid.Column="3" s:View.Model="{Binding DynamicSelectionViewModel}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" /> <ContentControl Grid.Column="2" s:View.Model="{Binding DynamicSelectionViewModel}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
<ContentControl Grid.Column="3" s:View.Model="{Binding StaticInputViewModel}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" /> <ContentControl Grid.Column="2" s:View.Model="{Binding StaticInputViewModel}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -19,7 +19,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDa
private readonly IProfileEditorService _profileEditorService; private readonly IProfileEditorService _profileEditorService;
private DataModelDynamicViewModel _dynamicSelectionViewModel; private DataModelDynamicViewModel _dynamicSelectionViewModel;
private ModifierTypeCategoryViewModel _modifierTypeViewModels; private ModifierTypeCategoryViewModel _modifierTypeViewModels;
private DataBindingModifierType _selectedModifierType; private BaseDataBindingModifierType _selectedModifierType;
private DataModelStaticViewModel _staticInputViewModel; private DataModelStaticViewModel _staticInputViewModel;
public DataBindingModifierViewModel(DataBindingModifier<TLayerProperty, TProperty> modifier, public DataBindingModifierViewModel(DataBindingModifier<TLayerProperty, TProperty> modifier,
@ -50,7 +50,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDa
set => SetAndNotify(ref _modifierTypeViewModels, value); set => SetAndNotify(ref _modifierTypeViewModels, value);
} }
public DataBindingModifierType SelectedModifierType public BaseDataBindingModifierType SelectedModifierType
{ {
get => _selectedModifierType; get => _selectedModifierType;
set => SetAndNotify(ref _selectedModifierType, value); set => SetAndNotify(ref _selectedModifierType, value);
@ -68,41 +68,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDa
private set => SetAndNotify(ref _staticInputViewModel, value); private set => SetAndNotify(ref _staticInputViewModel, value);
} }
public void Dispose()
{
if (DynamicSelectionViewModel != null)
{
DynamicSelectionViewModel.Dispose();
DynamicSelectionViewModel.PropertySelected -= ParameterSelectionViewModelOnPropertySelected;
}
if (StaticInputViewModel != null)
{
StaticInputViewModel.Dispose();
StaticInputViewModel.ValueUpdated -= StaticInputViewModelOnValueUpdated;
}
}
public void Delete() public void Delete()
{ {
Modifier.DirectDataBinding.RemoveModifier(Modifier); Modifier.DirectDataBinding.RemoveModifier(Modifier);
_profileEditorService.UpdateSelectedProfileElement(); _profileEditorService.UpdateSelectedProfileElement();
} }
public void SwapType()
{
if (Modifier.ParameterType == ProfileRightSideType.Dynamic)
{
Type sourceType = Modifier.DirectDataBinding.GetSourceType();
Modifier.UpdateParameterStatic((Modifier.ModifierType.ParameterType ?? sourceType).GetDefault());
}
else
Modifier.UpdateParameterDynamic(null);
Update();
_profileEditorService.UpdateSelectedProfileElement();
}
private void ParameterSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e) private void ParameterSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
{ {
Modifier.UpdateParameterDynamic(e.DataModelPath); Modifier.UpdateParameterDynamic(e.DataModelPath);
@ -121,39 +92,39 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDa
if (sourceType == null) if (sourceType == null)
throw new ArtemisUIException("Cannot use a data binding modifier VM for a data binding without a source"); throw new ArtemisUIException("Cannot use a data binding modifier VM for a data binding without a source");
if (DynamicSelectionViewModel != null) if (Modifier.ModifierType == null || Modifier.ModifierType.ParameterType == null)
{ {
DynamicSelectionViewModel.Dispose(); DisposeDynamicSelectionViewModel();
DynamicSelectionViewModel.PropertySelected -= ParameterSelectionViewModelOnPropertySelected; DisposeStaticInputViewModel();
}
if (Modifier.ModifierType == null || !Modifier.ModifierType.SupportsParameter)
{
StaticInputViewModel = null;
DynamicSelectionViewModel = null;
} }
else if (Modifier.ParameterType == ProfileRightSideType.Dynamic) else if (Modifier.ParameterType == ProfileRightSideType.Dynamic)
{ {
StaticInputViewModel = null; DisposeStaticInputViewModel();
DynamicSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule()); DynamicSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule());
if (DynamicSelectionViewModel != null) if (DynamicSelectionViewModel != null)
{ {
DynamicSelectionViewModel.DisplaySwitchButton = true;
DynamicSelectionViewModel.PropertySelected += ParameterSelectionViewModelOnPropertySelected; DynamicSelectionViewModel.PropertySelected += ParameterSelectionViewModelOnPropertySelected;
DynamicSelectionViewModel.SwitchToStaticRequested += DynamicSelectionViewModelOnSwitchToStaticRequested;
DynamicSelectionViewModel.FilterTypes = new[] {Modifier.ModifierType.ParameterType ?? sourceType}; DynamicSelectionViewModel.FilterTypes = new[] {Modifier.ModifierType.ParameterType ?? sourceType};
} }
} }
else else
{ {
DynamicSelectionViewModel = null; DisposeDynamicSelectionViewModel();
StaticInputViewModel = _dataModelUIService.GetStaticInputViewModel(Modifier.ModifierType.ParameterType ?? sourceType, null); StaticInputViewModel = _dataModelUIService.GetStaticInputViewModel(Modifier.ModifierType.ParameterType ?? sourceType, null);
if (StaticInputViewModel != null) if (StaticInputViewModel != null)
{
StaticInputViewModel.DisplaySwitchButton = true;
StaticInputViewModel.ValueUpdated += StaticInputViewModelOnValueUpdated; StaticInputViewModel.ValueUpdated += StaticInputViewModelOnValueUpdated;
StaticInputViewModel.SwitchToDynamicRequested += StaticInputViewModelOnSwitchToDynamicRequested;
}
} }
// Modifier type // Modifier type
ModifierTypeCategoryViewModel root = new ModifierTypeCategoryViewModel(null, null); ModifierTypeCategoryViewModel root = new ModifierTypeCategoryViewModel(null, null);
IEnumerable<IGrouping<string, DataBindingModifierType>> modifierTypes = _dataBindingService.GetCompatibleModifierTypes(sourceType).GroupBy(t => t.Category); IEnumerable<IGrouping<string, BaseDataBindingModifierType>> modifierTypes = _dataBindingService.GetCompatibleModifierTypes(sourceType, ModifierTypePart.Value).GroupBy(t => t.Category);
foreach (IGrouping<string, DataBindingModifierType> dataBindingModifierTypes in modifierTypes) foreach (IGrouping<string, BaseDataBindingModifierType> dataBindingModifierTypes in modifierTypes)
{ {
IEnumerable<ModifierTypeViewModel> viewModels = dataBindingModifierTypes.Select(t => new ModifierTypeViewModel(t)); IEnumerable<ModifierTypeViewModel> viewModels = dataBindingModifierTypes.Select(t => new ModifierTypeViewModel(t));
if (dataBindingModifierTypes.Key == null) if (dataBindingModifierTypes.Key == null)
@ -182,5 +153,53 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDa
Update(); Update();
} }
#region IDisposable
public void Dispose()
{
DisposeDynamicSelectionViewModel();
DisposeStaticInputViewModel();
}
private void DisposeStaticInputViewModel()
{
if (StaticInputViewModel != null)
{
StaticInputViewModel.Dispose();
StaticInputViewModel.ValueUpdated -= StaticInputViewModelOnValueUpdated;
StaticInputViewModel.SwitchToDynamicRequested -= StaticInputViewModelOnSwitchToDynamicRequested;
StaticInputViewModel = null;
}
}
private void DisposeDynamicSelectionViewModel()
{
if (DynamicSelectionViewModel != null)
{
DynamicSelectionViewModel.Dispose();
DynamicSelectionViewModel.PropertySelected -= ParameterSelectionViewModelOnPropertySelected;
DynamicSelectionViewModel.SwitchToStaticRequested -= DynamicSelectionViewModelOnSwitchToStaticRequested;
DynamicSelectionViewModel = null;
}
}
#endregion
#region Event handlers
private void DynamicSelectionViewModelOnSwitchToStaticRequested(object? sender, EventArgs e)
{
Modifier.ParameterType = ProfileRightSideType.Static;
Update();
}
private void StaticInputViewModelOnSwitchToDynamicRequested(object? sender, EventArgs e)
{
Modifier.ParameterType = ProfileRightSideType.Dynamic;
Update();
}
#endregion
} }
} }

View File

@ -4,11 +4,11 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDa
{ {
public class ModifierTypeViewModel : IModifierTypeViewModel public class ModifierTypeViewModel : IModifierTypeViewModel
{ {
public ModifierTypeViewModel(DataBindingModifierType modifierType) public ModifierTypeViewModel(BaseDataBindingModifierType modifierType)
{ {
ModifierType = modifierType; ModifierType = modifierType;
} }
public DataBindingModifierType ModifierType { get; set; } public BaseDataBindingModifierType ModifierType { get; set; }
} }
} }