From 5675d1895bac7934635f979c1baa5819772ee900 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 18 Aug 2021 23:47:14 +0200 Subject: [PATCH] Conditions - Removed old systems Data bindings - Removed old systems Data bindings - Implemented node system --- .../EnumContainsConditionOperator.cs | 15 - .../EnumNotContainsConditionOperator.cs | 15 - .../Operators/EqualsConditionOperator.cs | 13 - .../Operators/GreaterThanConditionOperator.cs | 13 - .../GreaterThanOrEqualConditionOperator.cs | 13 - .../Operators/LessThanConditionOperator.cs | 13 - .../LessThanOrEqualConditionOperator.cs | 13 - .../Operators/NotEqualConditionOperator.cs | 13 - .../Operators/NotNullConditionOperator.cs | 13 - .../Operators/NullConditionOperator.cs | 13 - .../NumberEqualsConditionOperator.cs | 16 - .../NumberNotEqualConditionOperator.cs | 16 - .../StringContainsConditionOperator.cs | 15 - .../StringEndsWithConditionOperator.cs | 15 - .../StringEqualsConditionOperator.cs | 15 - .../StringMatchesRegexConditionOperator.cs | 20 - .../StringNotContainsConditionOperator.cs | 15 - .../StringNotEqualConditionOperator.cs | 15 - .../StringNotNullConditionOperator.cs | 13 - .../Operators/StringNullConditionOperator.cs | 13 - .../StringStartsWithConditionOperator.cs | 15 - .../Colors/SKColorBrightenModifierType.cs | 18 - .../Colors/SKColorDarkenModifierType.cs | 18 - .../Colors/SKColorDesaturateModifierType.cs | 21 - .../Colors/SKColorInvertModifierType.cs | 18 - .../Colors/SKColorRotateHueModifierType.cs | 18 - .../Colors/SKColorSaturateModifierType.cs | 21 - .../Colors/SKColorSumModifierType.cs | 16 - .../Modifiers/Numbers/AbsoluteModifierType.cs | 17 - .../Modifiers/Numbers/DivideModifierType.cs | 17 - .../Modifiers/Numbers/MaxModifierType.cs | 17 - .../Modifiers/Numbers/MinModifierType.cs | 17 - .../Modifiers/Numbers/ModuloModifierType.cs | 15 - .../Numbers/MultiplicationModifier.cs | 13 - .../Numbers/PercentageOfModifierType.cs | 18 - .../Modifiers/Numbers/PowerModifierType.cs | 17 - .../Numbers/Rounding/CeilingModifierType.cs | 17 - .../Numbers/Rounding/FloorModifierType.cs | 17 - .../Numbers/Rounding/RoundModifierType.cs | 17 - .../Numbers/SquareRootModifierType.cs | 17 - .../Modifiers/Numbers/SubtractModifierType.cs | 13 - .../Modifiers/Numbers/SumModifierType.cs | 13 - .../Trigonometry/CosecantModifierType.cs | 17 - .../Trigonometry/CosineModifierType.cs | 17 - .../Trigonometry/CotangentModifierType.cs | 17 - .../Trigonometry/SecantModifierType.cs | 17 - .../Numbers/Trigonometry/SineModifierType.cs | 17 - .../Trigonometry/TangentModifierType.cs | 17 - .../Stores/ConditionOperatorStoreEvent.cs | 12 - .../DataBindingModifierTypeStoreEvent.cs | 12 - .../Abstract/BaseConditionOperator.cs | 82 ---- .../Conditions/Abstract/ConditionOperator.cs | 96 ---- .../Abstract/DataModelConditionPart.cs | 135 ------ .../Abstract/DataModelConditionPredicate.cs | 411 ------------------ .../Conditions/DataModelConditionEvent.cs | 257 ----------- .../DataModelConditionEventPredicate.cs | 163 ------- .../DataModelConditionGeneralPredicate.cs | 65 --- .../Conditions/DataModelConditionGroup.cs | 190 -------- .../Conditions/DataModelConditionList.cs | 276 ------------ .../DataModelConditionListPredicate.cs | 165 ------- .../EventPredicateWrapperDataModel.cs | 40 -- .../Wrappers/ListPredicateWrapperDataModel.cs | 59 --- .../Profile/DataBindings/DataBinding.cs | 103 +---- .../Conditional/ConditionalDataBinding.cs | 167 ------- .../Modes/Conditional/DataBindingCondition.cs | 121 ------ .../Conditional/IDataBindingCondition.cs | 15 - .../Direct/BaseDataBindingModifierType.cs | 94 ---- .../Modes/Direct/DataBindingModifier.cs | 324 -------------- .../Modes/Direct/DataBindingModifierType.cs | 81 ---- .../Modes/Direct/IDataBindingModifier.cs | 11 - .../DataBindings/Modes/DirectDataBinding.cs | 217 --------- .../DataBindings/Modes/IDataBindingMode.cs | 22 - .../Models/Profile/DataModel/DataModelPath.cs | 7 - .../Models/Profile/RenderProfileElement.cs | 7 +- .../ProfileConfiguration.cs | 13 +- src/Artemis.Core/Services/CoreService.cs | 2 - .../Registration/ConditionOperatorService.cs | 77 ---- .../Registration/DataBindingService.cs | 82 ---- .../Interfaces/IConditionOperatorService.cs | 37 -- .../Interfaces/IDataBindingService.cs | 38 -- .../Services/Storage/ProfileService.cs | 3 - .../Stores/ConditionOperatorStore.cs | 95 ---- .../Stores/DataBindingModifierTypeStore.cs | 95 ---- .../ConditionOperatorRegistration.cs | 40 -- .../DataBindingModifierTypeRegistration.cs | 40 -- .../Utilities/DeserializationLogger.cs | 32 -- .../ConditionalDataBindingEntity.cs | 14 - .../DataBindingConditionEntity.cs | 11 - .../Profile/DataBindings/DataBindingEntity.cs | 5 +- .../DataBindings/DataBindingModifierEntity.cs | 18 - .../DataBindings/DirectDataBindingEntity.cs | 15 - .../DataBindings/IDataBindingModeEntity.cs | 6 - .../Entities/Profile/DataModelPathEntity.cs | 9 - .../Profile/ProfileConfigurationEntity.cs | 3 +- .../Artemis.UI.Shared.csproj | 3 + src/Artemis.UI.Shared/Bootstrapper.cs | 9 +- .../Controls/DataModelPicker.xaml | 75 ++++ .../Controls/DataModelPicker.xaml.cs | 303 +++++++++++++ .../Converters/IntToVisibilityConverter.cs | 39 ++ .../Input/DataModelDynamicView.xaml | 109 ----- .../Input/DataModelDynamicView.xaml.cs | 29 -- .../Input/DataModelDynamicViewModel.cs | 387 ----------------- .../Input/DataModelStaticView.xaml | 80 ---- .../Input/DataModelStaticViewModel.cs | 285 ------------ .../DataModelListPropertiesViewModel.cs | 5 - .../Shared/DataModelListPropertyViewModel.cs | 7 - .../Events/DataModelInputStaticEventArgs.cs | 21 - ...tArgs.cs => DataModelSelectedEventArgs.cs} | 18 +- .../Extensions/DataModelWrapperExtensions.cs | 46 -- .../Ninject/Factories/ISharedVMFactory.cs | 28 +- .../Services/DataModelUIService.cs | 22 +- .../Interfaces/IDataModelUIService.cs | 23 - .../Ninject/Factories/IVMFactory.cs | 25 +- .../DataModelConditionPredicateViewModel.cs | 337 -------------- .../Abstract/DataModelConditionViewModel.cs | 69 --- .../DataModelConditionEventView.xaml | 101 ----- .../DataModelConditionEventViewModel.cs | 147 ------- .../DataModelConditionGroupView.xaml | 165 ------- .../DataModelConditionGroupViewModel.cs | 259 ----------- .../DataModelConditionListView.xaml | 110 ----- .../DataModelConditionListView.xaml.cs | 26 -- .../DataModelConditionListViewModel.cs | 165 ------- .../DataModelConditionEventPredicateView.xaml | 95 ---- ...taModelConditionEventPredicateView.xaml.cs | 26 -- ...taModelConditionEventPredicateViewModel.cs | 82 ---- ...ataModelConditionGeneralPredicateView.xaml | 115 ----- ...ModelConditionGeneralPredicateView.xaml.cs | 26 -- ...ModelConditionGeneralPredicateViewModel.cs | 53 --- .../DataModelConditionListPredicateView.xaml | 95 ---- ...ataModelConditionListPredicateView.xaml.cs | 26 -- ...ataModelConditionListPredicateViewModel.cs | 97 ----- .../DisplayConditionsViewModel.cs | 9 +- .../ConditionalDataBindingModeView.xaml | 55 --- .../ConditionalDataBindingModeViewModel.cs | 131 ------ .../DataBindingConditionView.xaml | 66 --- .../DataBindingConditionViewModel.cs | 86 ---- .../DataBindings/DataBindingView.xaml | 20 +- .../DataBindings/DataBindingViewModel.cs | 316 ++++++-------- .../DataBindingModifierView.xaml | 97 ----- .../DataBindingModifierView.xaml.cs | 26 -- .../DataBindingModifierViewModel.cs | 212 --------- .../DirectDataBindingModeView.xaml | 55 --- .../DirectDataBindingModeViewModel.cs | 169 ------- .../ModifierTypes/IModifierTypeViewModel.cs | 6 - .../ModifierTypeCategoryViewModel.cs | 19 - .../ModifierTypes/ModifierTypeViewModel.cs | 14 - .../DataBindings/IDataBindingModeViewModel.cs | 12 - .../ProfileEdit/ProfileEditViewModel.cs | 19 +- .../Artemis.VisualScripting.csproj | 3 + .../Controls/VisualScriptCablePresenter.cs | 33 +- .../Styles/VisualScriptCablePresenter.xaml | 7 +- .../Editor/Styles/VisualScriptPresenter.xaml | 42 +- .../DataModelNodeCustomViewModel.cs | 42 +- .../CustomViews/DataModelNodeCustomView.xaml | 3 +- .../Nodes/DataModelNode.cs | 1 - .../DataModelConditions.xaml | 108 +++++ src/Artemis.sln.DotSettings | 1 + 157 files changed, 784 insertions(+), 8802 deletions(-) delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/EnumContainsConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/EnumNotContainsConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/EqualsConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/GreaterThanConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/GreaterThanOrEqualConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/LessThanConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/LessThanOrEqualConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/NotEqualConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/NotNullConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/NullConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/NumberEqualsConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/NumberNotEqualConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/StringContainsConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/StringEndsWithConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/StringEqualsConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/StringMatchesRegexConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNotContainsConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNotEqualConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNotNullConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNullConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/Conditions/Operators/StringStartsWithConditionOperator.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorBrightenModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorDarkenModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorDesaturateModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorInvertModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorRotateHueModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorSaturateModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorSumModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/AbsoluteModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/DivideModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/MaxModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/MinModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/ModuloModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/MultiplicationModifier.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/PercentageOfModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/PowerModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Rounding/CeilingModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Rounding/FloorModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Rounding/RoundModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/SquareRootModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/SubtractModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/SumModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/CosecantModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/CosineModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/CotangentModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/SecantModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/SineModifierType.cs delete mode 100644 src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/TangentModifierType.cs delete mode 100644 src/Artemis.Core/Events/Stores/ConditionOperatorStoreEvent.cs delete mode 100644 src/Artemis.Core/Events/Stores/DataBindingModifierTypeStoreEvent.cs delete mode 100644 src/Artemis.Core/Models/Profile/Conditions/Abstract/BaseConditionOperator.cs delete mode 100644 src/Artemis.Core/Models/Profile/Conditions/Abstract/ConditionOperator.cs delete mode 100644 src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPart.cs delete mode 100644 src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPredicate.cs delete mode 100644 src/Artemis.Core/Models/Profile/Conditions/DataModelConditionEvent.cs delete mode 100644 src/Artemis.Core/Models/Profile/Conditions/DataModelConditionEventPredicate.cs delete mode 100644 src/Artemis.Core/Models/Profile/Conditions/DataModelConditionGeneralPredicate.cs delete mode 100644 src/Artemis.Core/Models/Profile/Conditions/DataModelConditionGroup.cs delete mode 100644 src/Artemis.Core/Models/Profile/Conditions/DataModelConditionList.cs delete mode 100644 src/Artemis.Core/Models/Profile/Conditions/DataModelConditionListPredicate.cs delete mode 100644 src/Artemis.Core/Models/Profile/Conditions/Wrappers/EventPredicateWrapperDataModel.cs delete mode 100644 src/Artemis.Core/Models/Profile/Conditions/Wrappers/ListPredicateWrapperDataModel.cs delete mode 100644 src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/ConditionalDataBinding.cs delete mode 100644 src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/DataBindingCondition.cs delete mode 100644 src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/IDataBindingCondition.cs delete mode 100644 src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/BaseDataBindingModifierType.cs delete mode 100644 src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/DataBindingModifier.cs delete mode 100644 src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/DataBindingModifierType.cs delete mode 100644 src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/IDataBindingModifier.cs delete mode 100644 src/Artemis.Core/Models/Profile/DataBindings/Modes/DirectDataBinding.cs delete mode 100644 src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingMode.cs delete mode 100644 src/Artemis.Core/Services/Registration/ConditionOperatorService.cs delete mode 100644 src/Artemis.Core/Services/Registration/DataBindingService.cs delete mode 100644 src/Artemis.Core/Services/Registration/Interfaces/IConditionOperatorService.cs delete mode 100644 src/Artemis.Core/Services/Registration/Interfaces/IDataBindingService.cs delete mode 100644 src/Artemis.Core/Stores/ConditionOperatorStore.cs delete mode 100644 src/Artemis.Core/Stores/DataBindingModifierTypeStore.cs delete mode 100644 src/Artemis.Core/Stores/Registrations/ConditionOperatorRegistration.cs delete mode 100644 src/Artemis.Core/Stores/Registrations/DataBindingModifierTypeRegistration.cs delete mode 100644 src/Artemis.Core/Utilities/DeserializationLogger.cs delete mode 100644 src/Artemis.Storage/Entities/Profile/DataBindings/ConditionalDataBindingEntity.cs delete mode 100644 src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingConditionEntity.cs delete mode 100644 src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingModifierEntity.cs delete mode 100644 src/Artemis.Storage/Entities/Profile/DataBindings/DirectDataBindingEntity.cs delete mode 100644 src/Artemis.Storage/Entities/Profile/DataBindings/IDataBindingModeEntity.cs create mode 100644 src/Artemis.UI.Shared/Controls/DataModelPicker.xaml create mode 100644 src/Artemis.UI.Shared/Controls/DataModelPicker.xaml.cs create mode 100644 src/Artemis.UI.Shared/Converters/IntToVisibilityConverter.cs delete mode 100644 src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml delete mode 100644 src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml.cs delete mode 100644 src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs delete mode 100644 src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticView.xaml delete mode 100644 src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticViewModel.cs delete mode 100644 src/Artemis.UI.Shared/Events/DataModelInputStaticEventArgs.cs rename src/Artemis.UI.Shared/Events/{DataModelInputDynamicEventArgs.cs => DataModelSelectedEventArgs.cs} (50%) delete mode 100644 src/Artemis.UI.Shared/Extensions/DataModelWrapperExtensions.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionPredicateViewModel.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionViewModel.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventView.xaml delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventViewModel.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupView.xaml delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListViewModel.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateView.xaml delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateView.xaml.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateViewModel.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateView.xaml delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateView.xaml.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateViewModel.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateView.xaml delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateView.xaml.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateViewModel.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/ConditionalDataBindingModeView.xaml delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/ConditionalDataBindingModeViewModel.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/DataBindingConditionView.xaml delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/DataBindingConditionViewModel.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierView.xaml delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierView.xaml.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierViewModel.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DirectDataBindingModeView.xaml delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DirectDataBindingModeViewModel.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/ModifierTypes/IModifierTypeViewModel.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/ModifierTypes/ModifierTypeCategoryViewModel.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/ModifierTypes/ModifierTypeViewModel.cs delete mode 100644 src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/IDataBindingModeViewModel.cs create mode 100644 src/Artemis.VisualScripting/ResourceDictionaries/DataModelConditions.xaml diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/EnumContainsConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/EnumContainsConditionOperator.cs deleted file mode 100644 index dd79f14cb..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/EnumContainsConditionOperator.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class EnumContainsConditionOperator : ConditionOperator - { - public override string Description => "Contains"; - public override string Icon => "Contain"; - - public override bool Evaluate(Enum a, Enum b) - { - return a != null && b != null && a.HasFlag(b); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/EnumNotContainsConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/EnumNotContainsConditionOperator.cs deleted file mode 100644 index ef78b8470..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/EnumNotContainsConditionOperator.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class EnumNotContainsConditionOperator : ConditionOperator - { - public override string Description => "Does not contain"; - public override string Icon => "FormatStrikethrough"; - - public override bool Evaluate(Enum a, Enum b) - { - return a != null && (b == null || !a.HasFlag(b)); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/EqualsConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/EqualsConditionOperator.cs deleted file mode 100644 index 789f86d63..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/EqualsConditionOperator.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Artemis.Core -{ - internal class EqualsConditionOperator : ConditionOperator - { - public override string Description => "Equals"; - public override string Icon => "Equal"; - - public override bool Evaluate(object a, object b) - { - return Equals(a, b); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/GreaterThanConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/GreaterThanConditionOperator.cs deleted file mode 100644 index f9a898107..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/GreaterThanConditionOperator.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Artemis.Core -{ - internal class GreaterThanConditionOperator : ConditionOperator - { - public override string Description => "Is greater than"; - public override string Icon => "GreaterThan"; - - public override bool Evaluate(double a, double b) - { - return a > b; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/GreaterThanOrEqualConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/GreaterThanOrEqualConditionOperator.cs deleted file mode 100644 index f0a1bf2b9..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/GreaterThanOrEqualConditionOperator.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Artemis.Core -{ - internal class GreaterThanOrEqualConditionOperator : ConditionOperator - { - public override string Description => "Is greater than or equal to"; - public override string Icon => "GreaterThanOrEqual"; - - public override bool Evaluate(double a, double b) - { - return a >= b; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/LessThanConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/LessThanConditionOperator.cs deleted file mode 100644 index 720cd7c2c..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/LessThanConditionOperator.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Artemis.Core -{ - internal class LessThanConditionOperator : ConditionOperator - { - public override string Description => "Is less than"; - public override string Icon => "LessThan"; - - public override bool Evaluate(double a, double b) - { - return a < b; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/LessThanOrEqualConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/LessThanOrEqualConditionOperator.cs deleted file mode 100644 index 925a4afaa..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/LessThanOrEqualConditionOperator.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Artemis.Core -{ - internal class LessThanOrEqualConditionOperator : ConditionOperator - { - public override string Description => "Is less than or equal to"; - public override string Icon => "LessThanOrEqual"; - - public override bool Evaluate(double a, double b) - { - return a <= b; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/NotEqualConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/NotEqualConditionOperator.cs deleted file mode 100644 index 4eeb8441a..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/NotEqualConditionOperator.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Artemis.Core -{ - internal class NotEqualConditionOperator : ConditionOperator - { - public override string Description => "Does not equal"; - public override string Icon => "NotEqualVariant"; - - public override bool Evaluate(object a, object b) - { - return !Equals(a, b); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/NotNullConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/NotNullConditionOperator.cs deleted file mode 100644 index 0d8599df7..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/NotNullConditionOperator.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Artemis.Core -{ - internal class NotNullConditionOperator : ConditionOperator - { - public override string Description => "Is not null"; - public override string Icon => "CheckboxMarkedCircleOutline"; - - public override bool Evaluate(object a) - { - return a != null; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/NullConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/NullConditionOperator.cs deleted file mode 100644 index 46302a5ff..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/NullConditionOperator.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Artemis.Core -{ - internal class NullConditionOperator : ConditionOperator - { - public override string Description => "Is null"; - public override string Icon => "Null"; - - public override bool Evaluate(object a) - { - return a == null; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/NumberEqualsConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/NumberEqualsConditionOperator.cs deleted file mode 100644 index d32104262..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/NumberEqualsConditionOperator.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class NumberEqualsConditionOperator : ConditionOperator - { - public override string Description => "Equals"; - public override string Icon => "Equal"; - - public override bool Evaluate(double a, double b) - { - // Numbers can be tricky, an epsilon like this is close enough - return Math.Abs(a - b) < 0.000001; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/NumberNotEqualConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/NumberNotEqualConditionOperator.cs deleted file mode 100644 index c0c29bb7a..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/NumberNotEqualConditionOperator.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class NumberNotEqualConditionOperator : ConditionOperator - { - public override string Description => "Does not equal"; - public override string Icon => "NotEqualVariant"; - - public override bool Evaluate(double a, double b) - { - // Numbers can be tricky, an epsilon like this is close enough - return Math.Abs(a - b) > 0.000001; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringContainsConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringContainsConditionOperator.cs deleted file mode 100644 index 7df8eb9dc..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringContainsConditionOperator.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class StringContainsConditionOperator : ConditionOperator - { - public override string Description => "Contains"; - public override string Icon => "Contain"; - - public override bool Evaluate(string a, string b) - { - return a != null && b != null && a.Contains(b, StringComparison.InvariantCultureIgnoreCase); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringEndsWithConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringEndsWithConditionOperator.cs deleted file mode 100644 index b8f5f91d0..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringEndsWithConditionOperator.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class StringEndsWithConditionOperator : ConditionOperator - { - public override string Description => "Ends with"; - public override string Icon => "ContainEnd"; - - public override bool Evaluate(string a, string b) - { - return a != null && b != null && a.EndsWith(b, StringComparison.InvariantCultureIgnoreCase); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringEqualsConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringEqualsConditionOperator.cs deleted file mode 100644 index 970f96806..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringEqualsConditionOperator.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class StringEqualsConditionOperator : ConditionOperator - { - public override string Description => "Equals"; - public override string Icon => "Equal"; - - public override bool Evaluate(string a, string b) - { - return string.Equals(a, b, StringComparison.InvariantCultureIgnoreCase); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringMatchesRegexConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringMatchesRegexConditionOperator.cs deleted file mode 100644 index ada76f5f0..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringMatchesRegexConditionOperator.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Text.RegularExpressions; - -namespace Artemis.Core { - internal class StringMatchesRegexConditionOperator : ConditionOperator - { - public override string Description => "Matches Regex"; - public override string Icon => "Regex"; - - public override bool Evaluate(string text, string regex) - { - // Ensures full match - if (!regex.StartsWith("^")) - regex = "^" + regex; - if (!regex.EndsWith("$")) - regex += "$"; - - return Regex.IsMatch(text, regex); - } - } -} diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNotContainsConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNotContainsConditionOperator.cs deleted file mode 100644 index 1b683710b..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNotContainsConditionOperator.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class StringNotContainsConditionOperator : ConditionOperator - { - public override string Description => "Does not contain"; - public override string Icon => "FormatStrikethrough"; - - public override bool Evaluate(string a, string b) - { - return a != null && (b == null || !a.Contains(b, StringComparison.InvariantCultureIgnoreCase)); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNotEqualConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNotEqualConditionOperator.cs deleted file mode 100644 index f51b63c4b..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNotEqualConditionOperator.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class StringNotEqualConditionOperator : ConditionOperator - { - public override string Description => "Does not equal"; - public override string Icon => "NotEqualVariant"; - - public override bool Evaluate(string a, string b) - { - return !string.Equals(a, b, StringComparison.InvariantCultureIgnoreCase); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNotNullConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNotNullConditionOperator.cs deleted file mode 100644 index 3b7c7ac7a..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNotNullConditionOperator.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Artemis.Core -{ - internal class StringNotNullConditionOperator : ConditionOperator - { - public override string Description => "Is not null"; - public override string Icon => "CheckboxMarkedCircleOutline"; - - public override bool Evaluate(string a) - { - return !string.IsNullOrWhiteSpace(a); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNullConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNullConditionOperator.cs deleted file mode 100644 index 84d1f6775..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringNullConditionOperator.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Artemis.Core -{ - internal class StringNullConditionOperator : ConditionOperator - { - public override string Description => "Is null"; - public override string Icon => "Null"; - - public override bool Evaluate(string a) - { - return string.IsNullOrWhiteSpace(a); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringStartsWithConditionOperator.cs b/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringStartsWithConditionOperator.cs deleted file mode 100644 index d43b6af20..000000000 --- a/src/Artemis.Core/DefaultTypes/Conditions/Operators/StringStartsWithConditionOperator.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class StringStartsWithConditionOperator : ConditionOperator - { - public override string Description => "Starts with"; - public override string Icon => "ContainStart"; - - public override bool Evaluate(string a, string b) - { - return a != null && b != null && a.StartsWith(b, StringComparison.InvariantCultureIgnoreCase); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorBrightenModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorBrightenModifierType.cs deleted file mode 100644 index 32c4255ca..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorBrightenModifierType.cs +++ /dev/null @@ -1,18 +0,0 @@ -using SkiaSharp; - -namespace Artemis.Core -{ - internal class SKColorBrightenModifierType : DataBindingModifierType - { - public override string Name => "Brighten by"; - public override string Icon => "CarLightHigh"; - public override string Description => "Brightens the color by the amount in percent"; - - public override SKColor Apply(SKColor currentValue, float parameterValue) - { - currentValue.ToHsl(out float h, out float s, out float l); - l *= (parameterValue + 100f) / 100f; - return SKColor.FromHsl(h, s, l); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorDarkenModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorDarkenModifierType.cs deleted file mode 100644 index d26993e58..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorDarkenModifierType.cs +++ /dev/null @@ -1,18 +0,0 @@ -using SkiaSharp; - -namespace Artemis.Core -{ - internal class SKColorDarkenModifierType : DataBindingModifierType - { - public override string Name => "Darken by"; - public override string Icon => "CarLightDimmed"; - public override string Description => "Darkens the color by the amount in percent"; - - public override SKColor Apply(SKColor currentValue, float parameterValue) - { - currentValue.ToHsl(out float h, out float s, out float l); - l *= (parameterValue * -1 + 100f) / 100f; - return SKColor.FromHsl(h, s, l); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorDesaturateModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorDesaturateModifierType.cs deleted file mode 100644 index e3d370ebd..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorDesaturateModifierType.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using SkiaSharp; - -namespace Artemis.Core -{ - internal class SKColorDesaturateModifierType : DataBindingModifierType - { - public override string Name => "Desaturate"; - public override string Icon => "ImageMinus"; - public override string Description => "Desaturates the color by the amount in percent"; - - public override SKColor Apply(SKColor currentValue, float parameterValue) - { - currentValue.ToHsl(out float h, out float s, out float l); - s -= parameterValue; - s = Math.Clamp(s, 0, 100); - - return SKColor.FromHsl(h, s, l, currentValue.Alpha); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorInvertModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorInvertModifierType.cs deleted file mode 100644 index bc46a053d..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorInvertModifierType.cs +++ /dev/null @@ -1,18 +0,0 @@ -using SkiaSharp; - -namespace Artemis.Core -{ - internal class SKColorInvertModifierType : DataBindingModifierType - { - public override string Name => "Invert color"; - public override string Icon => "InvertColors"; - public override string Description => "Inverts the color by rotating its hue by a 180°"; - - public override SKColor Apply(SKColor currentValue) - { - currentValue.ToHsl(out float h, out float s, out float l); - h += 180; - return SKColor.FromHsl(h % 360, s, l); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorRotateHueModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorRotateHueModifierType.cs deleted file mode 100644 index 45781ce48..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorRotateHueModifierType.cs +++ /dev/null @@ -1,18 +0,0 @@ -using SkiaSharp; - -namespace Artemis.Core -{ - internal class SKColorRotateHueModifierType : DataBindingModifierType - { - public override string Name => "Rotate Hue by"; - public override string Icon => "RotateRight"; - public override string Description => "Rotates the hue of the color by the amount in degrees"; - - public override SKColor Apply(SKColor currentValue, float parameterValue) - { - currentValue.ToHsl(out float h, out float s, out float l); - h += parameterValue; - return SKColor.FromHsl(h % 360, s, l); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorSaturateModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorSaturateModifierType.cs deleted file mode 100644 index 751f96c24..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorSaturateModifierType.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using SkiaSharp; - -namespace Artemis.Core -{ - internal class SKColorSaturateModifierType : DataBindingModifierType - { - public override string Name => "Saturate"; - public override string Icon => "ImagePlus"; - public override string Description => "Saturates the color by the amount in percent"; - - public override SKColor Apply(SKColor currentValue, float parameterValue) - { - currentValue.ToHsv(out float h, out float s, out float v); - s += parameterValue; - s = Math.Clamp(s, 0, 100); - - return SKColor.FromHsv(h, s, v, currentValue.Alpha); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorSumModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorSumModifierType.cs deleted file mode 100644 index 9c45436df..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Colors/SKColorSumModifierType.cs +++ /dev/null @@ -1,16 +0,0 @@ -using SkiaSharp; - -namespace Artemis.Core -{ - internal class SKColorSumModifierType : DataBindingModifierType - { - public override string Name => "Combine with"; - public override string Icon => "FormatColorFill"; - public override string Description => "Adds the two colors together"; - - public override SKColor Apply(SKColor currentValue, SKColor parameterValue) - { - return currentValue.Sum(parameterValue); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/AbsoluteModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/AbsoluteModifierType.cs deleted file mode 100644 index c58bfd3b8..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/AbsoluteModifierType.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class AbsoluteModifierType : DataBindingModifierType - { - public override string Name => "Absolute"; - public override string Icon => "NumericPositive1"; - public override string Category => "Advanced"; - public override string Description => "Converts the input value to an absolute value"; - - public override double Apply(double currentValue) - { - return Math.Abs(currentValue); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/DivideModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/DivideModifierType.cs deleted file mode 100644 index 215952095..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/DivideModifierType.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Artemis.Core -{ - internal class DivideModifierType : DataBindingModifierType - { - public override string Name => "Divide by"; - public override string Icon => "Divide"; - - public override double Apply(double currentValue, double parameterValue) - { - // Ye ye none of that - if (parameterValue == 0) - return 0; - - return currentValue / parameterValue; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/MaxModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/MaxModifierType.cs deleted file mode 100644 index f8da7936e..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/MaxModifierType.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class MaxModifierType : DataBindingModifierType - { - public override string Name => "Max"; - public override string Icon => "ChevronUpBoxOutline"; - public override string Category => "Advanced"; - public override string Description => "Keeps only the largest of input value and parameter"; - - public override double Apply(double currentValue, double parameterValue) - { - return Math.Max(currentValue, parameterValue); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/MinModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/MinModifierType.cs deleted file mode 100644 index 5ab519e01..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/MinModifierType.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class MinModifierType : DataBindingModifierType - { - public override string Name => "Min"; - public override string Icon => "ChevronDownBoxOutline"; - public override string Category => "Advanced"; - public override string Description => "Keeps only the smallest of input value and parameter"; - - public override double Apply(double currentValue, double parameterValue) - { - return Math.Min(currentValue, parameterValue); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/ModuloModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/ModuloModifierType.cs deleted file mode 100644 index 8b710d3bf..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/ModuloModifierType.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Artemis.Core -{ - internal class ModuloModifierType : DataBindingModifierType - { - public override string Name => "Modulo"; - public override string Icon => "Stairs"; - public override string Category => "Advanced"; - public override string Description => "Calculates the remained of the division between the input value and the parameter"; - - public override double Apply(double currentValue, double parameterValue) - { - return currentValue % parameterValue; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/MultiplicationModifier.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/MultiplicationModifier.cs deleted file mode 100644 index 3198777cc..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/MultiplicationModifier.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Artemis.Core -{ - internal class MultiplicationModifierType : DataBindingModifierType - { - public override string Name => "Multiply by"; - public override string Icon => "Close"; - - public override double Apply(double currentValue, double parameterValue) - { - return currentValue * parameterValue; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/PercentageOfModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/PercentageOfModifierType.cs deleted file mode 100644 index 298d26e30..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/PercentageOfModifierType.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Artemis.Core -{ - internal class PercentageOfModifierType : DataBindingModifierType - { - public override string Name => "Percentage of"; - public override string Icon => "Percent"; - public override string Description => "Calculates how much percent the parameter value is of the current value"; - - public override double Apply(double currentValue, double parameterValue) - { - // Ye ye none of that - if (parameterValue == 0d) - return 100d; - - return 100d / parameterValue * currentValue; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/PowerModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/PowerModifierType.cs deleted file mode 100644 index 2ea1a0709..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/PowerModifierType.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class PowerModifierType : DataBindingModifierType - { - public override string Name => "Power"; - public override string Icon => "Exponent"; - public override string Category => "Advanced"; - public override string Description => "Raises the input value to the power of the parameter value"; - - public override double Apply(double currentValue, double parameterValue) - { - return Math.Pow(currentValue, parameterValue); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Rounding/CeilingModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Rounding/CeilingModifierType.cs deleted file mode 100644 index c4ca8f021..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Rounding/CeilingModifierType.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class CeilingModifierType : DataBindingModifierType - { - public override string Name => "Round up"; - public override string Icon => "ArrowUp"; - public override string Category => "Rounding"; - public override string Description => "Ceils the input, rounding it up to the nearest whole number"; - - public override double Apply(double currentValue) - { - return Math.Ceiling(currentValue); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Rounding/FloorModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Rounding/FloorModifierType.cs deleted file mode 100644 index e26173049..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Rounding/FloorModifierType.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class FloorModifierType : DataBindingModifierType - { - public override string Name => "Round down"; - public override string Icon => "ArrowDown"; - public override string Category => "Rounding"; - public override string Description => "Floors the input, rounding it down to the nearest whole number"; - - public override double Apply(double currentValue) - { - return Math.Floor(currentValue); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Rounding/RoundModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Rounding/RoundModifierType.cs deleted file mode 100644 index 3b3283396..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Rounding/RoundModifierType.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class RoundModifierType : DataBindingModifierType - { - public override string Name => "Round"; - public override string Icon => "ArrowCollapse"; - public override string Category => "Rounding"; - public override string Description => "Rounds the input to the nearest whole number"; - - public override double Apply(double currentValue) - { - return Math.Round(currentValue, MidpointRounding.AwayFromZero); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/SquareRootModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/SquareRootModifierType.cs deleted file mode 100644 index 72dfa3f55..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/SquareRootModifierType.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class SquareRootModifierType : DataBindingModifierType - { - public override string Name => "Square root"; - public override string Icon => "SquareRoot"; - public override string Category => "Advanced"; - public override string Description => "Calculates square root of the input value"; - - public override double Apply(double currentValue) - { - return Math.Sqrt(currentValue); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/SubtractModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/SubtractModifierType.cs deleted file mode 100644 index 0dcda285a..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/SubtractModifierType.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Artemis.Core -{ - internal class SubtractModifierType : DataBindingModifierType - { - public override string Name => "Subtract"; - public override string Icon => "Minus"; - - public override double Apply(double currentValue, double parameterValue) - { - return currentValue - parameterValue; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/SumModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/SumModifierType.cs deleted file mode 100644 index 3c2a816a6..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/SumModifierType.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Artemis.Core -{ - internal class SumModifierType : DataBindingModifierType - { - public override string Name => "Sum"; - public override string Icon => "Plus"; - - public override double Apply(double currentValue, double parameterValue) - { - return currentValue + parameterValue; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/CosecantModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/CosecantModifierType.cs deleted file mode 100644 index bc79c9b79..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/CosecantModifierType.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class CosecantModifierType : DataBindingModifierType - { - public override string Name => "Cosecant"; - public override string? Icon => null; - public override string Category => "Trigonometry"; - public override string Description => "Treats the input as an angle and calculates the cosecant"; - - public override double Apply(double currentValue) - { - return 1d / Math.Sin(currentValue); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/CosineModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/CosineModifierType.cs deleted file mode 100644 index 3b4090654..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/CosineModifierType.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class CosineModifierType : DataBindingModifierType - { - public override string Name => "Cosine"; - public override string Icon => "MathCos"; - public override string Category => "Trigonometry"; - public override string Description => "Treats the input as an angle and calculates the cosine"; - - public override double Apply(double currentValue) - { - return Math.Cos(currentValue); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/CotangentModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/CotangentModifierType.cs deleted file mode 100644 index 39e514aa3..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/CotangentModifierType.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class CotangentModifierType : DataBindingModifierType - { - public override string Name => "Cotangent"; - public override string? Icon => null; - public override string Category => "Trigonometry"; - public override string Description => "Treats the input as an angle and calculates the cotangent"; - - public override double Apply(double currentValue) - { - return 1d / Math.Tan(currentValue); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/SecantModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/SecantModifierType.cs deleted file mode 100644 index c4790f2dd..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/SecantModifierType.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class SecantModifierType : DataBindingModifierType - { - public override string Name => "Secant"; - public override string? Icon => null; - public override string Category => "Trigonometry"; - public override string Description => "Treats the input as an angle and calculates the secant"; - - public override double Apply(double currentValue) - { - return 1d / Math.Cos(currentValue); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/SineModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/SineModifierType.cs deleted file mode 100644 index 5a315b316..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/SineModifierType.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class SineModifierType : DataBindingModifierType - { - public override string Name => "Sine"; - public override string Icon => "MathSin"; - public override string Category => "Trigonometry"; - public override string Description => "Treats the input as an angle and calculates the sine"; - - public override double Apply(double currentValue) - { - return Math.Sin(currentValue); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/TangentModifierType.cs b/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/TangentModifierType.cs deleted file mode 100644 index 7a2b7c4ea..000000000 --- a/src/Artemis.Core/DefaultTypes/DataBindings/Modifiers/Numbers/Trigonometry/TangentModifierType.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Artemis.Core -{ - internal class TangentModifierType : DataBindingModifierType - { - public override string Name => "Tangent"; - public override string Icon => "MathTan"; - public override string Category => "Trigonometry"; - public override string Description => "Treats the input as an angle and calculates the tangent"; - - public override double Apply(double currentValue) - { - return Math.Tan(currentValue); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Events/Stores/ConditionOperatorStoreEvent.cs b/src/Artemis.Core/Events/Stores/ConditionOperatorStoreEvent.cs deleted file mode 100644 index fb81fa23f..000000000 --- a/src/Artemis.Core/Events/Stores/ConditionOperatorStoreEvent.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Artemis.Core -{ - internal class ConditionOperatorStoreEvent - { - public ConditionOperatorStoreEvent(ConditionOperatorRegistration registration) - { - Registration = registration; - } - - public ConditionOperatorRegistration Registration { get; } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Events/Stores/DataBindingModifierTypeStoreEvent.cs b/src/Artemis.Core/Events/Stores/DataBindingModifierTypeStoreEvent.cs deleted file mode 100644 index c954a7f60..000000000 --- a/src/Artemis.Core/Events/Stores/DataBindingModifierTypeStoreEvent.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Artemis.Core -{ - internal class DataBindingModifierTypeStoreEvent - { - public DataBindingModifierTypeStoreEvent(DataBindingModifierTypeRegistration typeRegistration) - { - TypeRegistration = typeRegistration; - } - - public DataBindingModifierTypeRegistration TypeRegistration { get; } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Conditions/Abstract/BaseConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Abstract/BaseConditionOperator.cs deleted file mode 100644 index 4214e14de..000000000 --- a/src/Artemis.Core/Models/Profile/Conditions/Abstract/BaseConditionOperator.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; - -namespace Artemis.Core -{ - /// - /// Represents a condition operator that performs a boolean operation - /// - /// To implement your own condition operator, inherit or - /// - /// - /// - public abstract class BaseConditionOperator - { - /// - /// Gets or sets the description of this logical operator - /// - public abstract string Description { get; } - - /// - /// Gets or sets the icon of this logical operator - /// - public abstract string Icon { get; } - - /// - /// Gets the plugin this condition operator belongs to - /// Note: Not set until after registering - /// - public Plugin? Plugin { get; internal set; } - - /// - /// Gets the left side type of this condition operator - /// - public abstract Type LeftSideType { get; } - - /// - /// Gets the right side type of this condition operator. May be null if the operator does not support a right side - /// - public abstract Type? RightSideType { get; } - - /// - /// Returns whether the given type is supported by the operator - /// - /// The type to check for, must be either the same or be castable to the target type - /// Which side of the operator to check, left or right - 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); - } - - /// - /// Evaluates the condition with the input types being provided as objects - /// - /// This leaves the caller responsible for the types matching and - /// - /// - /// - /// The left side value, type should match - /// The right side value, type should match - /// The result of the boolean condition's evaluation - internal abstract bool InternalEvaluate(object? leftSideValue, object? rightSideValue); - } - - /// - /// Represents a side of a condition parameter - /// - public enum ConditionParameterSide - { - /// - /// The left side of a condition parameter - /// - Left, - - /// - /// The right side of a condition parameter - /// - Right - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Conditions/Abstract/ConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Abstract/ConditionOperator.cs deleted file mode 100644 index 2134cbaf9..000000000 --- a/src/Artemis.Core/Models/Profile/Conditions/Abstract/ConditionOperator.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; - -namespace Artemis.Core -{ - /// - /// Represents a condition operator that performs a boolean operation using a left- and right-side - /// - public abstract class ConditionOperator : BaseConditionOperator - { - /// - public override Type LeftSideType => typeof(TLeftSide); - - /// - public override Type RightSideType => typeof(TRightSide); - - /// - /// Evaluates the operator on a and b - /// - /// The parameter on the left side of the expression - /// The parameter on the right side of the expression - public abstract bool Evaluate(TLeftSide a, TRightSide b); - - /// - internal override bool InternalEvaluate(object? leftSideValue, object? rightSideValue) - { - // TODO: Can we avoid boxing/unboxing? - TLeftSide leftSide; - if (leftSideValue != null) - { - if (leftSideValue.GetType() != typeof(TLeftSide) && leftSideValue is IConvertible) - leftSide = (TLeftSide) Convert.ChangeType(leftSideValue, typeof(TLeftSide)); - else - leftSide = (TLeftSide) leftSideValue; - } - else - { - leftSide = default; - } - - TRightSide rightSide; - if (rightSideValue != null) - { - if (rightSideValue.GetType() != typeof(TRightSide) && leftSideValue is IConvertible) - rightSide = (TRightSide) Convert.ChangeType(rightSideValue, typeof(TRightSide)); - else - rightSide = (TRightSide) rightSideValue; - } - else - { - rightSide = default; - } - - return Evaluate(leftSide!, rightSide!); - } - } - - /// - /// Represents a condition operator that performs a boolean operation using only a left side - /// - public abstract class ConditionOperator : BaseConditionOperator - { - /// - public override Type LeftSideType => typeof(TLeftSide); - - /// - /// Always null, not applicable to this type of condition operator - /// - public override Type? RightSideType => null; - - /// - /// Evaluates the operator on a and b - /// - /// The parameter on the left side of the expression - public abstract bool Evaluate(TLeftSide a); - - /// - internal override bool InternalEvaluate(object? leftSideValue, object? rightSideValue) - { - // TODO: Can we avoid boxing/unboxing? - TLeftSide leftSide; - if (leftSideValue != null) - { - if (leftSideValue.GetType() != typeof(TLeftSide) && leftSideValue is IConvertible) - leftSide = (TLeftSide) Convert.ChangeType(leftSideValue, typeof(TLeftSide)); - else - leftSide = (TLeftSide) leftSideValue; - } - else - { - leftSide = default; - } - - return Evaluate(leftSide!); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPart.cs b/src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPart.cs deleted file mode 100644 index abbdfb519..000000000 --- a/src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPart.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using Artemis.Storage.Entities.Profile.Abstract; - -namespace Artemis.Core -{ - /// - /// An abstract class for display condition parts - /// - public abstract class DataModelConditionPart : IDisposable - { - private readonly List _children = new(); - - /// - /// Gets the parent of this part - /// - public DataModelConditionPart? Parent { get; internal set; } - - /// - /// Gets the children of this part - /// - public ReadOnlyCollection Children => _children.AsReadOnly(); - - /// - /// Adds a child to the display condition part's collection - /// - /// - /// An optional index at which to insert the condition - public void AddChild(DataModelConditionPart dataModelConditionPart, int? index = null) - { - if (!_children.Contains(dataModelConditionPart)) - { - dataModelConditionPart.Parent = this; - if (index != null) - _children.Insert(index.Value, dataModelConditionPart); - else - _children.Add(dataModelConditionPart); - - OnChildAdded(); - } - } - - /// - /// Removes a child from the display condition part's collection - /// - /// The child to remove - public void RemoveChild(DataModelConditionPart dataModelConditionPart) - { - if (_children.Contains(dataModelConditionPart)) - { - dataModelConditionPart.Parent = null; - _children.Remove(dataModelConditionPart); - OnChildRemoved(); - } - } - - /// - /// Removes all children. You monster. - /// - public void ClearChildren() - { - while (Children.Any()) - RemoveChild(Children[0]); - } - - /// - /// Evaluates the condition part on the data model - /// - /// - public abstract bool Evaluate(); - - /// - /// Evaluates the condition part on the given target (currently only for lists) - /// - /// - /// - internal abstract bool EvaluateObject(object? target); - - internal abstract void Save(); - internal abstract DataModelConditionPartEntity GetEntity(); - - #region IDisposable - - /// - /// Disposed the condition part - /// - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - } - } - - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - #endregion - - #region Events - - /// - /// Occurs when a child-condition was added - /// - public event EventHandler? ChildAdded; - - /// - /// Occurs when a child-condition was removed - /// - public event EventHandler? ChildRemoved; - - /// - /// Invokers the event - /// - protected virtual void OnChildAdded() - { - ChildAdded?.Invoke(this, EventArgs.Empty); - } - - /// - /// Invokers the event - /// - protected virtual void OnChildRemoved() - { - ChildRemoved?.Invoke(this, EventArgs.Empty); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPredicate.cs b/src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPredicate.cs deleted file mode 100644 index f836d9157..000000000 --- a/src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPredicate.cs +++ /dev/null @@ -1,411 +0,0 @@ -using System; -using Artemis.Storage.Entities.Profile.Abstract; -using Artemis.Storage.Entities.Profile.Conditions; -using Newtonsoft.Json; - -namespace Artemis.Core -{ - /// - /// A predicate in a data model condition using either two data model values or one data model value and a - /// static value - /// - public abstract class DataModelConditionPredicate : DataModelConditionPart - { - /// - /// Creates a new instance of the class - /// - /// - /// - /// A new empty entity - protected DataModelConditionPredicate(DataModelConditionPart parent, ProfileRightSideType predicateType, DataModelConditionPredicateEntity entity) - { - Parent = parent; - Entity = entity; - PredicateType = predicateType; - } - - internal DataModelConditionPredicate(DataModelConditionPart parent, DataModelConditionPredicateEntity entity) - { - Parent = parent; - Entity = entity; - PredicateType = (ProfileRightSideType) entity.PredicateType; - } - - /// - /// Gets or sets the predicate type - /// - public ProfileRightSideType PredicateType { get; set; } - - /// - /// Gets the operator - /// - public BaseConditionOperator? Operator { get; protected set; } - - /// - /// Gets the path of the left property - /// - public DataModelPath? LeftPath { get; protected set; } - - /// - /// Gets the path of the right property - /// - public DataModelPath? RightPath { get; protected set; } - - /// - /// Gets the right static value, only used it is - /// - /// - public object? RightStaticValue { get; protected set; } - - internal DataModelConditionPredicateEntity Entity { get; set; } - - /// - public override string ToString() - { - if (PredicateType == ProfileRightSideType.Dynamic) - return $"[Dynamic] {LeftPath} {Operator?.Description} {RightPath}"; - return $"[Static] {LeftPath} {Operator?.Description} {RightStaticValue}"; - } - - #region IDisposable - - /// - protected override void Dispose(bool disposing) - { - ConditionOperatorStore.ConditionOperatorAdded -= ConditionOperatorStoreOnConditionOperatorAdded; - ConditionOperatorStore.ConditionOperatorRemoved -= ConditionOperatorStoreOnConditionOperatorRemoved; - - LeftPath?.Dispose(); - RightPath?.Dispose(); - - base.Dispose(disposing); - } - - #endregion - - #region Initialization - - internal void Initialize() - { - ConditionOperatorStore.ConditionOperatorAdded += ConditionOperatorStoreOnConditionOperatorAdded; - ConditionOperatorStore.ConditionOperatorRemoved += ConditionOperatorStoreOnConditionOperatorRemoved; - - InitializeLeftPath(); - - // Operator - if (Entity.OperatorPluginGuid != null) - { - BaseConditionOperator? conditionOperator = ConditionOperatorStore.Get(Entity.OperatorPluginGuid.Value, Entity.OperatorType)?.ConditionOperator; - if (conditionOperator != null) - UpdateOperator(conditionOperator); - } - - // Right side dynamic - if (PredicateType == ProfileRightSideType.Dynamic) - InitializeRightPath(); - // Right side static - else if (PredicateType == ProfileRightSideType.Static && Entity.RightStaticValue != null) - { - try - { - // If the left path is not valid we cannot reliably set up the right side because the type is unknown - // Because of that wait for it to validate first - if (LeftPath != null && !LeftPath.IsValid) - { - LeftPath.PathValidated += InitializeRightSideStatic; - return; - } - if (LeftPath == null) - return; - - // Use the left side type so JSON.NET has a better idea what to do - Type leftSideType = LeftPath.GetPropertyType()!; - object? rightSideValue; - - try - { - rightSideValue = CoreJson.DeserializeObject(Entity.RightStaticValue, leftSideType); - } - // If deserialization fails, use the type's default - catch (JsonSerializationException e) - { - DeserializationLogger.LogPredicateDeserializationFailure(this, e); - rightSideValue = Activator.CreateInstance(leftSideType); - } - - UpdateRightSideStatic(rightSideValue); - } - catch (JsonReaderException e) - { - DeserializationLogger.LogPredicateDeserializationFailure(this, e); - } - } - } - - private void InitializeRightSideStatic(object? sender, EventArgs args) - { - if (LeftPath == null) - return; - - LeftPath.PathValidated -= InitializeRightSideStatic; - - // Use the left side type so JSON.NET has a better idea what to do - Type leftSideType = LeftPath.GetPropertyType()!; - object? rightSideValue; - - try - { - rightSideValue = CoreJson.DeserializeObject(Entity.RightStaticValue, leftSideType); - } - // If deserialization fails, use the type's default - catch (JsonSerializationException e) - { - DeserializationLogger.LogPredicateDeserializationFailure(this, e); - rightSideValue = Activator.CreateInstance(leftSideType); - } - - UpdateRightSideStatic(rightSideValue); - } - - /// - /// Initializes the left path of this condition predicate - /// - protected abstract void InitializeLeftPath(); - - /// - /// Initializes the right path of this condition predicate - /// - protected abstract void InitializeRightPath(); - - #endregion - - #region Modification - - /// - /// Updates the left side of the predicate - /// - /// The path pointing to the left side value inside the data model - public virtual void UpdateLeftSide(DataModelPath? path) - { - if (path != null && !path.IsValid) - throw new ArtemisCoreException("Cannot update left side of predicate to an invalid path"); - - LeftPath?.Dispose(); - LeftPath = path != null ? new DataModelPath(path) : null; - - ValidateOperator(); - ValidateRightSide(); - } - - /// - /// Updates the right side of the predicate, makes the predicate dynamic and re-compiles the expression - /// - /// The path pointing to the right side value inside the data model - public void UpdateRightSideDynamic(DataModelPath? path) - { - if (path != null && !path.IsValid) - throw new ArtemisCoreException("Cannot update right side of predicate to an invalid path"); - if (Operator != null && path != null && !Operator.SupportsType(path.GetPropertyType()!, ConditionParameterSide.Right)) - throw new ArtemisCoreException($"Selected operator does not support right side of type {path.GetPropertyType()!.Name}"); - - RightPath?.Dispose(); - RightPath = path != null ? new DataModelPath(path) : null; - - PredicateType = ProfileRightSideType.Dynamic; - } - - /// - /// Updates the right side of the predicate, makes the predicate static and re-compiles the expression - /// - /// The right side value to use - public void UpdateRightSideStatic(object? staticValue) - { - PredicateType = ProfileRightSideType.Static; - RightPath?.Dispose(); - RightPath = null; - - // If the operator is null simply apply the value, any validation will wait - if (Operator == null) - { - RightStaticValue = staticValue; - return; - } - - // If the operator does not support a right side, always set it to null - if (Operator.RightSideType == null) - { - RightStaticValue = null; - return; - } - - // If not null ensure the types match and if not, convert it - Type? preferredType = GetPreferredRightSideType(); - if (staticValue != null && staticValue.GetType() == preferredType || preferredType == null) - RightStaticValue = staticValue; - else if (staticValue != null) - RightStaticValue = Convert.ChangeType(staticValue, preferredType); - // If null create a default instance for value types or simply make it null for reference types - else if (preferredType.IsValueType) - RightStaticValue = Activator.CreateInstance(preferredType); - else - RightStaticValue = null; - } - - /// - /// Updates the operator of the predicate and re-compiles the expression - /// - /// - public void UpdateOperator(BaseConditionOperator? conditionOperator) - { - if (conditionOperator == null) - { - Operator = null; - return; - } - - // 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) - { - Operator = conditionOperator; - return; - } - - Type leftType = LeftPath.GetPropertyType()!; - // Left side can't go empty so enforce a match - if (!conditionOperator.SupportsType(leftType, ConditionParameterSide.Left)) - throw new ArtemisCoreException($"Cannot apply operator {conditionOperator.GetType().Name} to this predicate because " + - $"it does not support left side type {leftType.Name}"); - - Operator = conditionOperator; - ValidateRightSide(); - } - - /// - /// Determines the best type to use for the right side op this predicate - /// - public abstract Type? GetPreferredRightSideType(); - - private void ValidateOperator() - { - if (LeftPath == null || !LeftPath.IsValid || Operator == null) - return; - - Type leftType = LeftPath.GetPropertyType()!; - if (!Operator.SupportsType(leftType, ConditionParameterSide.Left)) - Operator = null; - } - - private void ValidateRightSide() - { - if (Operator == null) - return; - - if (PredicateType == ProfileRightSideType.Dynamic) - { - if (RightPath == null || !RightPath.IsValid) - return; - - Type rightSideType = RightPath.GetPropertyType()!; - if (!Operator.SupportsType(rightSideType, ConditionParameterSide.Right)) - UpdateRightSideDynamic(null); - } - else - { - if (RightStaticValue == null) - return; - - if (!Operator.SupportsType(RightStaticValue.GetType(), ConditionParameterSide.Right)) - UpdateRightSideStatic(null); - } - } - - #endregion - - #region Evaluation - - /// - public override bool Evaluate() - { - if (Operator == null || LeftPath == null || !LeftPath.IsValid) - return false; - - // If the operator does not support a right side, immediately evaluate with null - if (Operator.RightSideType == null) - return Operator.InternalEvaluate(LeftPath.GetValue(), null); - - // Compare with a static value - if (PredicateType == ProfileRightSideType.Static) - { - object? leftSideValue = LeftPath.GetValue(); - if (leftSideValue != null && leftSideValue.GetType().IsValueType && RightStaticValue == null) - return false; - - return Operator.InternalEvaluate(leftSideValue, RightStaticValue); - } - - if (RightPath == null || !RightPath.IsValid) - return false; - - // Compare with dynamic values - return Operator.InternalEvaluate(LeftPath.GetValue(), RightPath.GetValue()); - } - - /// - internal override bool EvaluateObject(object? target) - { - return false; - } - - #endregion - - #region Storage - - internal override DataModelConditionPartEntity GetEntity() - { - return Entity; - } - - internal override void Save() - { - // Don't save an invalid state - if (LeftPath != null && !LeftPath.IsValid || RightPath != null && !RightPath.IsValid) - return; - - Entity.PredicateType = (int) PredicateType; - - LeftPath?.Save(); - Entity.LeftPath = LeftPath?.Entity; - RightPath?.Save(); - Entity.RightPath = RightPath?.Entity; - - Entity.RightStaticValue = CoreJson.SerializeObject(RightStaticValue); - - if (Operator?.Plugin != null) - { - Entity.OperatorPluginGuid = Operator.Plugin.Guid; - Entity.OperatorType = Operator.GetType().Name; - } - } - - #endregion - - #region Event handlers - - private void ConditionOperatorStoreOnConditionOperatorAdded(object? sender, ConditionOperatorStoreEvent e) - { - BaseConditionOperator conditionOperator = e.Registration.ConditionOperator; - if (Entity.OperatorPluginGuid == conditionOperator.Plugin!.Guid && Entity.OperatorType == conditionOperator.GetType().Name) - UpdateOperator(conditionOperator); - } - - private void ConditionOperatorStoreOnConditionOperatorRemoved(object? sender, ConditionOperatorStoreEvent e) - { - if (e.Registration.ConditionOperator != Operator) - return; - - Operator = null; - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionEvent.cs b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionEvent.cs deleted file mode 100644 index 0ff661385..000000000 --- a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionEvent.cs +++ /dev/null @@ -1,257 +0,0 @@ -using System; -using System.Linq; -using Artemis.Storage.Entities.Profile.Abstract; -using Artemis.Storage.Entities.Profile.Conditions; - -namespace Artemis.Core -{ - /// - /// A condition that evaluates to true when an event is triggered - /// - public class DataModelConditionEvent : DataModelConditionPart - { - private bool _disposed; - private bool _reinitializing; - private IDataModelEvent? _valueChangedEvent; - - /// - /// Creates a new instance of the class - /// - /// - public DataModelConditionEvent(DataModelConditionPart parent) - { - Parent = parent; - Entity = new DataModelConditionEventEntity(); - - Initialize(); - } - - internal DataModelConditionEvent(DataModelConditionPart parent, DataModelConditionEventEntity entity) - { - Parent = parent; - Entity = entity; - - Initialize(); - } - - /// - /// Gets the path of the event property - /// - public DataModelPath? EventPath { get; private set; } - - /// - /// Gets the last time the event this condition is applied to was triggered - /// - public DateTime LastTrigger { get; private set; } - - /// - /// Gets or sets the type of argument the event provides - /// - public Type? EventArgumentType { get; private set; } - - internal DataModelConditionEventEntity Entity { get; set; } - - /// - public override bool Evaluate() - { - if (_disposed) - throw new ObjectDisposedException("DataModelConditionEvent"); - - IDataModelEvent? dataModelEvent = GetDataModelEvent(); - if (dataModelEvent == null) - return false; - dataModelEvent.Update(); - - // Only evaluate to true once every time the event has been triggered since the last evaluation - if (dataModelEvent.LastTrigger <= LastTrigger) - return false; - - LastTrigger = DateTime.Now; - - // If there is a child (root group), it must evaluate to true whenever the event triggered - if (Children.Any()) - return Children[0].EvaluateObject(dataModelEvent.LastEventArgumentsUntyped); - - // If there are no children, we always evaluate to true whenever the event triggered - return true; - } - - /// - /// Updates the event the condition is triggered by - /// - public void UpdateEvent(DataModelPath? path) - { - if (_disposed) - throw new ObjectDisposedException("DataModelConditionEvent"); - - if (path != null && !path.IsValid) - throw new ArtemisCoreException("Cannot update event to an invalid path"); - - EventPath?.Dispose(); - EventPath = path != null ? new DataModelPath(path) : null; - SubscribeToEventPath(); - CreateValueChangedEventIfNeeded(); - - // Remove the old root group that was tied to the old data model - ClearChildren(); - - if (EventPath != null) - { - EventArgumentType = GetEventArgumentType(); - // Create a new root group - AddChild(new DataModelConditionGroup(this)); - } - else - { - EventArgumentType = null; - } - - LastTrigger = GetDataModelEvent()?.LastTrigger ?? DateTime.Now; - } - - /// - /// Returns the this is triggered by - /// - /// The this is triggered by - public IDataModelEvent? GetDataModelEvent() - { - if (_valueChangedEvent != null) - return _valueChangedEvent; - return EventPath?.GetValue() as IDataModelEvent; - } - - #region IDisposable - - /// - protected override void Dispose(bool disposing) - { - _disposed = true; - - EventPath?.Dispose(); - - foreach (DataModelConditionPart child in Children) - child.Dispose(); - - base.Dispose(disposing); - } - - #endregion - - internal override bool EvaluateObject(object? target) - { - return false; - } - - internal override void Save() - { - // Don't save an invalid state - if (EventPath != null && !EventPath.IsValid) - return; - - // Target list - EventPath?.Save(); - Entity.EventPath = EventPath?.Entity; - - // Children - Entity.Children.Clear(); - Entity.Children.AddRange(Children.Select(c => c.GetEntity())); - foreach (DataModelConditionPart child in Children) - child.Save(); - } - - internal override DataModelConditionPartEntity GetEntity() - { - return Entity; - } - - internal void Initialize() - { - ClearChildren(); - - if (Entity.EventPath == null) - return; - - DataModelPath eventPath = new(null, Entity.EventPath); - EventPath = eventPath; - SubscribeToEventPath(); - CreateValueChangedEventIfNeeded(); - - EventArgumentType = GetEventArgumentType(); - // There should only be one child and it should be a group - if (Entity.Children.FirstOrDefault() is DataModelConditionGroupEntity rootGroup) - { - AddChild(new DataModelConditionGroup(this, rootGroup)); - } - else - { - Entity.Children.Clear(); - AddChild(new DataModelConditionGroup(this)); - } - - LastTrigger = GetDataModelEvent()?.LastTrigger ?? DateTime.Now; - } - - private Type? GetEventArgumentType() - { - if (EventPath == null || !EventPath.IsValid) - return null; - - if (_valueChangedEvent != null) - return _valueChangedEvent.ArgumentsType; - - // Cannot rely on EventPath.GetValue() because part of the path might be null - Type eventType = EventPath.GetPropertyType()!; - return eventType.IsGenericType ? eventType.GetGenericArguments()[0] : typeof(DataModelEventArgs); - } - - private void SubscribeToEventPath() - { - if (EventPath == null) return; - EventPath.PathValidated += EventPathOnPathValidated; - EventPath.PathInvalidated += EventPathOnPathInvalidated; - } - - private void CreateValueChangedEventIfNeeded() - { - Type? propertyType = EventPath?.GetPropertyType(); - if (propertyType == null) - return; - - if (!typeof(IDataModelEvent).IsAssignableFrom(propertyType)) - { - IDataModelEvent? instance = (IDataModelEvent?) Activator.CreateInstance(typeof(DataModelValueChangedEvent<>).MakeGenericType(propertyType), EventPath); - _valueChangedEvent = instance ?? throw new ArtemisCoreException("Failed to create a DataModelValueChangedEvent for a property changed data model event"); - } - else - { - _valueChangedEvent = null; - } - } - - #region Event handlers - - private void EventPathOnPathValidated(object? sender, EventArgs e) - { - if (_reinitializing) - return; - - _reinitializing = true; - EventPath?.Dispose(); - Initialize(); - _reinitializing = false; - } - - private void EventPathOnPathInvalidated(object? sender, EventArgs e) - { - if (_reinitializing) - return; - - _reinitializing = true; - EventPath?.Dispose(); - Initialize(); - _reinitializing = false; - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionEventPredicate.cs b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionEventPredicate.cs deleted file mode 100644 index c6477ba65..000000000 --- a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionEventPredicate.cs +++ /dev/null @@ -1,163 +0,0 @@ -using System; -using Artemis.Storage.Entities.Profile; -using Artemis.Storage.Entities.Profile.Conditions; - -namespace Artemis.Core -{ - /// - /// A predicate like evaluated inside a - /// - public class DataModelConditionEventPredicate : DataModelConditionPredicate - { - /// - /// Creates a new instance of the class - /// - /// - /// - public DataModelConditionEventPredicate(DataModelConditionPart parent, ProfileRightSideType predicateType) - : base(parent, predicateType, new DataModelConditionEventPredicateEntity()) - { - DataModelConditionEvent = null!; - ApplyParentEvent(); - Initialize(); - } - - internal DataModelConditionEventPredicate(DataModelConditionPart parent, DataModelConditionEventPredicateEntity entity) - : base(parent, entity) - { - DataModelConditionEvent = null!; - ApplyParentEvent(); - Initialize(); - } - - /// - /// Gets the data model condition event this predicate belongs to - /// - public DataModelConditionEvent DataModelConditionEvent { get; private set; } - - private void ApplyParentEvent() - { - DataModelConditionPart? current = Parent; - while (current != null) - { - if (current is DataModelConditionEvent parentEvent) - { - DataModelConditionEvent = parentEvent; - return; - } - - current = current.Parent; - } - - if (DataModelConditionEvent == null) - throw new ArtemisCoreException("This data model condition event predicate does not belong to a data model condition event"); - } - - private object? GetEventPathValue(DataModelPath path, object? target) - { - lock (path) - { - if (!(path.Target is EventPredicateWrapperDataModel wrapper)) - throw new ArtemisCoreException("Data model condition event predicate has a path with an invalid target"); - - wrapper.UntypedArguments = target; - return path.GetValue(); - } - } - - #region Initialization - - /// - protected override void InitializeLeftPath() - { - if (Entity.LeftPath != null) - LeftPath = DataModelConditionEvent.EventArgumentType != null - ? new DataModelPath(EventPredicateWrapperDataModel.Create(DataModelConditionEvent.EventArgumentType), Entity.LeftPath) - : null; - } - - /// - protected override void InitializeRightPath() - { - if (PredicateType == ProfileRightSideType.Dynamic && Entity.RightPath != null) - { - // Right side dynamic using event arguments - if (Entity.RightPath.WrapperType == PathWrapperType.Event) - { - RightPath = DataModelConditionEvent.EventArgumentType != null - ? new DataModelPath(EventPredicateWrapperDataModel.Create(DataModelConditionEvent.EventArgumentType), Entity.RightPath) - : null; - } - // Right side dynamic - else - RightPath = new DataModelPath(null, Entity.RightPath); - } - } - - #endregion - - #region Modification - - /// - public override Type? GetPreferredRightSideType() - { - Type? preferredType = Operator?.RightSideType; - Type? leftSideType = LeftPath?.GetPropertyType(); - if (preferredType == null) - return null; - - if (leftSideType != null && preferredType.IsAssignableFrom(leftSideType)) - preferredType = leftSideType; - - return preferredType; - } - - #endregion - - #region Evaluation - - /// - /// Not supported for event predicates, always returns false - /// - public override bool Evaluate() - { - return false; - } - - internal override bool EvaluateObject(object? target) - { - if (Operator == null || LeftPath == null || !LeftPath.IsValid) - return false; - - // If the operator does not support a right side, immediately evaluate with null - if (Operator.RightSideType == null) - return Operator.InternalEvaluate(GetEventPathValue(LeftPath, target), null); - - // Compare with a static value - if (PredicateType == ProfileRightSideType.Static) - { - object? leftSideValue = GetEventPathValue(LeftPath, target); - if (leftSideValue != null && leftSideValue.GetType().IsValueType && RightStaticValue == null) - return false; - - return Operator.InternalEvaluate(leftSideValue, RightStaticValue); - } - - if (RightPath == null || !RightPath.IsValid) - return false; - - // Compare with dynamic values - if (PredicateType == ProfileRightSideType.Dynamic) - { - // If the path targets a property inside the event, evaluate on the event path value instead of the right path value - if (RightPath.Target is EventPredicateWrapperDataModel) - return Operator.InternalEvaluate(GetEventPathValue(LeftPath, target), GetEventPathValue(RightPath, target)); - return Operator.InternalEvaluate(GetEventPathValue(LeftPath, target), RightPath.GetValue()); - } - - return false; - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionGeneralPredicate.cs b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionGeneralPredicate.cs deleted file mode 100644 index e65030a7a..000000000 --- a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionGeneralPredicate.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using Artemis.Storage.Entities.Profile.Conditions; - -namespace Artemis.Core -{ - /// - /// A predicate in a data model condition using either two data model values or one data model value and a - /// static value - /// - public class DataModelConditionGeneralPredicate : DataModelConditionPredicate - { - /// - /// Creates a new instance of the class - /// - /// - /// - public DataModelConditionGeneralPredicate(DataModelConditionPart parent, ProfileRightSideType predicateType) - : base(parent, predicateType, new DataModelConditionGeneralPredicateEntity()) - { - Initialize(); - } - - internal DataModelConditionGeneralPredicate(DataModelConditionPart parent, DataModelConditionGeneralPredicateEntity entity) - : base(parent, entity) - { - Initialize(); - } - - #region Modification - - /// - public override Type? GetPreferredRightSideType() - { - Type? preferredType = Operator?.RightSideType; - Type? leftSideType = LeftPath?.GetPropertyType(); - if (preferredType == null) - return null; - - if (leftSideType != null && preferredType.IsAssignableFrom(leftSideType)) - preferredType = leftSideType; - - return preferredType; - } - - #endregion - - #region Initialization - - /// - protected override void InitializeLeftPath() - { - if (Entity.LeftPath != null) - LeftPath = new DataModelPath(null, Entity.LeftPath); - } - - /// - protected override void InitializeRightPath() - { - if (PredicateType == ProfileRightSideType.Dynamic && Entity.RightPath != null) - RightPath = new DataModelPath(null, Entity.RightPath); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionGroup.cs b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionGroup.cs deleted file mode 100644 index 53dcaa0bd..000000000 --- a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionGroup.cs +++ /dev/null @@ -1,190 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using Artemis.Storage.Entities.Profile.Abstract; -using Artemis.Storage.Entities.Profile.Conditions; - -namespace Artemis.Core -{ - /// - /// A group containing zero to many s which it evaluates using a boolean specific - /// operator - /// - public class DataModelConditionGroup : DataModelConditionPart - { - private bool _disposed; - - /// - /// Creates a new instance of the class - /// - /// - public DataModelConditionGroup(DataModelConditionPart? parent) - { - Parent = parent; - Entity = new DataModelConditionGroupEntity(); - ChildAdded += OnChildrenChanged; - ChildRemoved += OnChildrenChanged; - } - - /// - /// Creates a new instance of the class - /// - /// - /// - public DataModelConditionGroup(DataModelConditionPart? parent, DataModelConditionGroupEntity entity) - { - Parent = parent; - Entity = entity; - BooleanOperator = (BooleanOperator) Entity.BooleanOperator; - - foreach (DataModelConditionPartEntity childEntity in Entity.Children) - { - if (childEntity is DataModelConditionGroupEntity groupEntity) - AddChild(new DataModelConditionGroup(this, groupEntity)); - else if (childEntity is DataModelConditionListEntity listEntity) - AddChild(new DataModelConditionList(this, listEntity)); - else if (childEntity is DataModelConditionEventEntity eventEntity) - AddChild(new DataModelConditionEvent(this, eventEntity)); - else if (childEntity is DataModelConditionGeneralPredicateEntity predicateEntity) - AddChild(new DataModelConditionGeneralPredicate(this, predicateEntity)); - else if (childEntity is DataModelConditionListPredicateEntity listPredicateEntity) - AddChild(new DataModelConditionListPredicate(this, listPredicateEntity)); - else if (childEntity is DataModelConditionEventPredicateEntity eventPredicateEntity) - AddChild(new DataModelConditionEventPredicate(this, eventPredicateEntity)); - } - - ContainsEvents = Children.Any(c => c is DataModelConditionEvent); - ChildAdded += OnChildrenChanged; - ChildRemoved += OnChildrenChanged; - } - - /// - /// Gets or sets the boolean operator of this group - /// - public BooleanOperator BooleanOperator { get; set; } - - /// - /// Gets whether this group contains any events - /// - public bool ContainsEvents { get; private set; } - - internal DataModelConditionGroupEntity Entity { get; set; } - - /// - public override bool Evaluate() - { - if (_disposed) - throw new ObjectDisposedException("DataModelConditionGroup"); - - // Empty groups are always true - if (Children.Count == 0) - return true; - // Groups with only one child ignore the boolean operator - if (Children.Count == 1) - return Children[0].Evaluate(); - - if (ContainsEvents) - { - bool eventTriggered = Children.Where(c => c is DataModelConditionEvent).Any(c => c.Evaluate()); - return eventTriggered && EvaluateWithOperator(Children.Where(c => !(c is DataModelConditionEvent))); - } - return EvaluateWithOperator(Children); - } - - private bool EvaluateWithOperator(IEnumerable targets) - { - return BooleanOperator switch - { - BooleanOperator.And => targets.All(c => c.Evaluate()), - BooleanOperator.Or => targets.Any(c => c.Evaluate()), - BooleanOperator.AndNot => targets.All(c => !c.Evaluate()), - BooleanOperator.OrNot => targets.Any(c => !c.Evaluate()), - _ => throw new ArgumentOutOfRangeException() - }; - } - - #region IDisposable - - /// - protected override void Dispose(bool disposing) - { - _disposed = true; - foreach (DataModelConditionPart child in Children) - child.Dispose(); - - base.Dispose(disposing); - } - - #endregion - - /// - internal override bool EvaluateObject(object? target) - { - if (_disposed) - throw new ObjectDisposedException("DataModelConditionGroup"); - - // Empty groups are always true - if (Children.Count == 0) - return true; - // Groups with only one child ignore the boolean operator - if (Children.Count == 1) - return Children[0].EvaluateObject(target); - - return BooleanOperator switch - { - BooleanOperator.And => Children.All(c => c.EvaluateObject(target)), - BooleanOperator.Or => Children.Any(c => c.EvaluateObject(target)), - BooleanOperator.AndNot => Children.All(c => !c.EvaluateObject(target)), - BooleanOperator.OrNot => Children.Any(c => !c.EvaluateObject(target)), - _ => throw new ArgumentOutOfRangeException() - }; - } - - internal override void Save() - { - Entity.BooleanOperator = (int) BooleanOperator; - - Entity.Children.Clear(); - Entity.Children.AddRange(Children.Select(c => c.GetEntity())); - foreach (DataModelConditionPart child in Children) - child.Save(); - } - - internal override DataModelConditionPartEntity GetEntity() - { - return Entity; - } - - private void OnChildrenChanged(object? sender, EventArgs e) - { - ContainsEvents = Children.Any(c => c is DataModelConditionEvent); - } - } - - /// - /// Represents a boolean operator - /// - public enum BooleanOperator - { - /// - /// All the conditions in the group should evaluate to true - /// - And, - - /// - /// Any of the conditions in the group should evaluate to true - /// - Or, - - /// - /// All the conditions in the group should evaluate to false - /// - AndNot, - - /// - /// Any of the conditions in the group should evaluate to false - /// - OrNot - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionList.cs b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionList.cs deleted file mode 100644 index 9dd05a5e8..000000000 --- a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionList.cs +++ /dev/null @@ -1,276 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using Artemis.Storage.Entities.Profile.Abstract; -using Artemis.Storage.Entities.Profile.Conditions; - -namespace Artemis.Core -{ - /// - /// A condition that evaluates one or more predicates inside a list - /// - public class DataModelConditionList : DataModelConditionPart - { - private bool _disposed; - private bool _reinitializing; - - /// - /// Creates a new instance of the class - /// - /// - public DataModelConditionList(DataModelConditionPart parent) - { - Parent = parent; - Entity = new DataModelConditionListEntity(); - - Initialize(); - } - - internal DataModelConditionList(DataModelConditionPart parent, DataModelConditionListEntity entity) - { - Parent = parent; - Entity = entity; - ListOperator = (ListOperator) entity.ListOperator; - - Initialize(); - } - - /// - /// Gets or sets the list operator - /// - public ListOperator ListOperator { get; set; } - - /// - /// Gets the path of the list property - /// - public DataModelPath? ListPath { get; private set; } - - /// - /// Gets the type of the content of the list this predicate is evaluated on - /// - public Type? ListType { get; set; } - - /// - /// Gets whether the list contains primitives - /// - public bool IsPrimitiveList { get; set; } - - internal DataModelConditionListEntity Entity { get; set; } - - /// - public override bool Evaluate() - { - if (_disposed) - throw new ObjectDisposedException("DataModelConditionList"); - - if (ListPath == null || !ListPath.IsValid) - return false; - - return EvaluateObject(ListPath.GetValue()); - } - - /// - /// Updates the list the predicate is evaluated on - /// - /// The path pointing to the list inside the list - public void UpdateList(DataModelPath? path) - { - if (_disposed) - throw new ObjectDisposedException("DataModelConditionList"); - - if (path != null && !path.IsValid) - throw new ArtemisCoreException("Cannot update list to an invalid path"); - - ListPath?.Dispose(); - ListPath = path != null ? new DataModelPath(path) : null; - SubscribeToListPath(); - - // Remove the old root group that was tied to the old data model - while (Children.Any()) - RemoveChild(Children[0]); - - if (ListPath != null) - { - Type listType = ListPath.GetPropertyType()!; - ListType = listType.GetGenericEnumerableType(); - IsPrimitiveList = ListType == null || ListType.IsPrimitive || ListType.IsEnum || ListType == typeof(string); - - // Create a new root group - AddChild(new DataModelConditionGroup(this)); - } - else - { - ListType = null; - } - } - - #region IDisposable - - /// - protected override void Dispose(bool disposing) - { - _disposed = true; - - ListPath?.Dispose(); - - foreach (DataModelConditionPart child in Children) - child.Dispose(); - - base.Dispose(disposing); - } - - #endregion - - internal override bool EvaluateObject(object? target) - { - if (_disposed) - throw new ObjectDisposedException("DataModelConditionList"); - - if (!Children.Any()) - return false; - if (!(target is IEnumerable enumerable)) - return false; - - IEnumerable objectList = enumerable.Cast(); - return ListOperator switch - { - ListOperator.Any => objectList.Any(o => Children[0].EvaluateObject(o)), - ListOperator.All => objectList.All(o => Children[0].EvaluateObject(o)), - ListOperator.None => objectList.Any(o => !Children[0].EvaluateObject(o)), - ListOperator.Count => false, - _ => throw new ArgumentOutOfRangeException() - }; - } - - internal override void Save() - { - // Don't save an invalid state - if (ListPath != null && !ListPath.IsValid) - return; - - // Target list - ListPath?.Save(); - Entity.ListPath = ListPath?.Entity; - - // Operator - Entity.ListOperator = (int) ListOperator; - - // Children - Entity.Children.Clear(); - Entity.Children.AddRange(Children.Select(c => c.GetEntity())); - foreach (DataModelConditionPart child in Children) - child.Save(); - } - - internal override DataModelConditionPartEntity GetEntity() - { - return Entity; - } - - internal void Initialize() - { - while (Children.Any()) - RemoveChild(Children[0]); - - if (Entity.ListPath == null) - return; - - // Ensure the list path is valid and points to a list - DataModelPath listPath = new(null, Entity.ListPath); - Type listType = listPath.GetPropertyType()!; - // Can't check this on an invalid list, if it becomes valid later lets hope for the best - if (listPath.IsValid && !PointsToList(listPath)) - return; - - ListPath = listPath; - SubscribeToListPath(); - if (ListPath.IsValid) - { - ListType = listType.GetGenericEnumerableType(); - IsPrimitiveList = ListType == null || ListType.IsPrimitive || ListType.IsEnum || ListType == typeof(string); - } - else - { - ListType = null; - IsPrimitiveList = false; - } - - // There should only be one child and it should be a group - if (Entity.Children.FirstOrDefault() is DataModelConditionGroupEntity rootGroup) - { - AddChild(new DataModelConditionGroup(this, rootGroup)); - } - else - { - Entity.Children.Clear(); - AddChild(new DataModelConditionGroup(this)); - } - } - - private bool PointsToList(DataModelPath dataModelPath) - { - Type? type = dataModelPath.GetPropertyType(); - return type?.IsGenericEnumerable() ?? false; - } - - private void SubscribeToListPath() - { - if (ListPath == null) return; - ListPath.PathValidated += ListPathOnPathValidated; - ListPath.PathInvalidated += ListPathOnPathInvalidated; - } - - #region Event handlers - - private void ListPathOnPathValidated(object? sender, EventArgs e) - { - if (_reinitializing) - return; - - _reinitializing = true; - ListPath?.Dispose(); - Initialize(); - _reinitializing = false; - } - - private void ListPathOnPathInvalidated(object? sender, EventArgs e) - { - if (_reinitializing) - return; - - _reinitializing = true; - ListPath?.Dispose(); - Initialize(); - _reinitializing = false; - } - - #endregion - } - - /// - /// Represents a list operator - /// - public enum ListOperator - { - /// - /// Any of the list items should evaluate to true - /// - Any, - - /// - /// All of the list items should evaluate to true - /// - All, - - /// - /// None of the list items should evaluate to true - /// - None, - - /// - /// A specific amount of the list items should evaluate to true - /// - Count - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionListPredicate.cs b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionListPredicate.cs deleted file mode 100644 index 5fdc3a8d8..000000000 --- a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionListPredicate.cs +++ /dev/null @@ -1,165 +0,0 @@ -using System; -using Artemis.Core.Modules; -using Artemis.Storage.Entities.Profile; -using Artemis.Storage.Entities.Profile.Conditions; - -namespace Artemis.Core -{ - /// - /// A predicate like evaluated inside a - /// - public class DataModelConditionListPredicate : DataModelConditionPredicate - { - /// - /// Creates a new instance of the class - /// - /// - /// - public DataModelConditionListPredicate(DataModelConditionPart parent, ProfileRightSideType predicateType) - : base(parent, predicateType, new DataModelConditionListPredicateEntity()) - { - DataModelConditionList = null!; - ApplyParentList(); - Initialize(); - } - - internal DataModelConditionListPredicate(DataModelConditionPart parent, DataModelConditionListPredicateEntity entity) - : base(parent, entity) - { - DataModelConditionList = null!; - ApplyParentList(); - Initialize(); - } - - /// - /// Gets the data model condition list this predicate belongs to - /// - public DataModelConditionList DataModelConditionList { get; private set; } - - private void ApplyParentList() - { - DataModelConditionPart? current = Parent; - while (current != null) - { - if (current is DataModelConditionList parentList) - { - DataModelConditionList = parentList; - return; - } - - current = current.Parent; - } - - if (DataModelConditionList == null) - throw new ArtemisCoreException("This data model condition list predicate does not belong to a data model condition list"); - } - - private object? GetListPathValue(DataModelPath path, object? target) - { - if (!(path.Target is ListPredicateWrapperDataModel wrapper)) - throw new ArtemisCoreException("Data model condition list predicate has a path with an invalid target"); - - wrapper.UntypedValue = target; - return path.GetValue(); - } - - #region Initialization - - /// - protected override void InitializeLeftPath() - { - if (Entity.LeftPath != null) - LeftPath = DataModelConditionList.ListType != null - ? new DataModelPath(ListPredicateWrapperDataModel.Create( - DataModelConditionList.ListType, - DataModelConditionList.ListPath?.GetPropertyDescription()?.ListItemName - ), Entity.LeftPath) - : null; - } - - /// - protected override void InitializeRightPath() - { - if (PredicateType == ProfileRightSideType.Dynamic && Entity.RightPath != null) - { - // Right side dynamic inside the list - if (Entity.RightPath.WrapperType == PathWrapperType.List) - { - RightPath = DataModelConditionList.ListType != null - ? new DataModelPath(ListPredicateWrapperDataModel.Create( - DataModelConditionList.ListType, - DataModelConditionList.ListPath?.GetPropertyDescription()?.ListItemName - ), Entity.RightPath) - : null; - } - // Right side dynamic - else - RightPath = new DataModelPath(null, Entity.RightPath); - } - } - - #endregion - - #region Modification - - /// - public override Type? GetPreferredRightSideType() - { - Type? preferredType = Operator?.RightSideType; - Type? leftSideType = DataModelConditionList.IsPrimitiveList - ? DataModelConditionList.ListType - : LeftPath?.GetPropertyType(); - if (preferredType == null) - return null; - - if (leftSideType != null && preferredType.IsAssignableFrom(leftSideType)) - preferredType = leftSideType; - - return preferredType; - } - - #endregion - - #region Evaluation - - /// - /// Not supported for list predicates, always returns false - /// - public override bool Evaluate() - { - return false; - } - - internal override bool EvaluateObject(object? target) - { - if (Operator == null || LeftPath == null || !LeftPath.IsValid) - return false; - - // Compare with a static value - if (PredicateType == ProfileRightSideType.Static) - { - object? leftSideValue = GetListPathValue(LeftPath, target); - if (leftSideValue != null && leftSideValue.GetType().IsValueType && RightStaticValue == null) - return false; - - return Operator.InternalEvaluate(leftSideValue, RightStaticValue); - } - - if (RightPath == null || !RightPath.IsValid) - return false; - - // Compare with dynamic values - if (PredicateType == ProfileRightSideType.Dynamic) - { - // If the path targets a property inside the list, evaluate on the list path value instead of the right path value - if (RightPath.Target is ListPredicateWrapperDataModel) - return Operator.InternalEvaluate(GetListPathValue(LeftPath, target), GetListPathValue(RightPath, target)); - return Operator.InternalEvaluate(GetListPathValue(LeftPath, target), RightPath.GetValue()); - } - - return false; - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Conditions/Wrappers/EventPredicateWrapperDataModel.cs b/src/Artemis.Core/Models/Profile/Conditions/Wrappers/EventPredicateWrapperDataModel.cs deleted file mode 100644 index 7b30c20f9..000000000 --- a/src/Artemis.Core/Models/Profile/Conditions/Wrappers/EventPredicateWrapperDataModel.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using Artemis.Core.Modules; - -namespace Artemis.Core -{ - internal class EventPredicateWrapperDataModel : EventPredicateWrapperDataModel - { - [DataModelProperty(Name = "Event arguments", Description = "The arguments provided when the event triggers")] - public T Arguments => (UntypedArguments is T typedArguments ? typedArguments : default)!; - } - - /// - /// Represents a datamodel that wraps the event arguments of an event - /// - public abstract class EventPredicateWrapperDataModel : DataModel - { - internal EventPredicateWrapperDataModel() - { - Module = Constants.CorePluginFeature; - } - - /// - /// Gets the last arguments of this event as an object - /// - [DataModelIgnore] - public object? UntypedArguments { get; internal set; } - - /// - /// Creates a new instance of the class - /// - public static EventPredicateWrapperDataModel Create(Type type) - { - object? instance = Activator.CreateInstance(typeof(EventPredicateWrapperDataModel<>).MakeGenericType(type)); - if (instance == null) - throw new ArtemisCoreException($"Failed to create an instance of EventPredicateWrapperDataModel for type {type.Name}"); - - return (EventPredicateWrapperDataModel) instance; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Conditions/Wrappers/ListPredicateWrapperDataModel.cs b/src/Artemis.Core/Models/Profile/Conditions/Wrappers/ListPredicateWrapperDataModel.cs deleted file mode 100644 index 69a2fe087..000000000 --- a/src/Artemis.Core/Models/Profile/Conditions/Wrappers/ListPredicateWrapperDataModel.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Reflection; -using Artemis.Core.Modules; - -namespace Artemis.Core -{ - internal class ListPredicateWrapperDataModel : ListPredicateWrapperDataModel - { - public T Value => (UntypedValue is T typedValue ? typedValue : default)!; - } - - /// - /// Represents a datamodel that wraps a value in a list - /// - public abstract class ListPredicateWrapperDataModel : DataModel - { - internal ListPredicateWrapperDataModel() - { - Module = Constants.CorePluginFeature; - } - - /// - /// Gets or sets the value of this list as an object - /// - [DataModelIgnore] - public object? UntypedValue { get; set; } - - /// - /// Gets or sets the name of the list item - /// - [DataModelIgnore] - public string? ItemName { get; set; } - - #region Overrides of DataModel - - /// - public override DataModelPropertyAttribute? GetPropertyDescription(PropertyInfo propertyInfo) - { - if (!string.IsNullOrWhiteSpace(ItemName)) - return new DataModelPropertyAttribute {Name = ItemName}; - return base.GetPropertyDescription(propertyInfo); - } - - #endregion - - /// - /// Creates a new instance of the class - /// - public static ListPredicateWrapperDataModel Create(Type type, string? name = null) - { - ListPredicateWrapperDataModel? instance = Activator.CreateInstance(typeof(ListPredicateWrapperDataModel<>).MakeGenericType(type)) as ListPredicateWrapperDataModel; - if (instance == null) - throw new ArtemisCoreException($"Failed to create an instance of ListPredicateWrapperDataModel for type {type.Name}"); - - instance.ItemName = name; - return instance; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs index 6b560ee52..62fcaea73 100644 --- a/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs +++ b/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs @@ -17,20 +17,20 @@ namespace Artemis.Core { LayerProperty = dataBindingRegistration.LayerProperty; Entity = new DataBindingEntity(); + Script = new NodeScript(LayerProperty.PropertyDescription.Name ?? LayerProperty.Path, ""); ApplyRegistration(dataBindingRegistration); Save(); - ApplyDataBindingMode(); } internal DataBinding(LayerProperty layerProperty, DataBindingEntity entity) { LayerProperty = layerProperty; Entity = entity; + Script = new NodeScript(LayerProperty.PropertyDescription.Name ?? LayerProperty.Path, ""); // Load will add children so be initialized before that Load(); - ApplyDataBindingMode(); } /// @@ -48,10 +48,7 @@ namespace Artemis.Core /// public DataBindingConverter? Converter { get; private set; } - /// - /// Gets the data binding mode - /// - public IDataBindingMode? DataBindingMode { get; private set; } + public NodeScript Script { get; private set; } /// /// Gets or sets the easing time of the data binding @@ -78,18 +75,18 @@ namespace Artemis.Core if (_disposed) throw new ObjectDisposedException("DataBinding"); - if (Converter == null || DataBindingMode == null) + if (Converter == null) return baseValue; - TProperty value = DataBindingMode.GetValue(baseValue); + Script.Run(); // If no easing is to be applied simple return whatever the current value is if (EasingTime == TimeSpan.Zero || !Converter.SupportsInterpolate) - return value; + return Script.Result; // If the value changed, update the current and previous values used for easing - if (!Equals(value, _currentValue)) - ResetEasing(value); + if (!Equals(Script.Result, _currentValue)) + ResetEasing(Script.Result); // Apply interpolation between the previous and current value return GetInterpolatedValue(); @@ -118,7 +115,9 @@ namespace Artemis.Core if (Registration != null) Registration.DataBinding = null; - DataBindingMode?.Dispose(); + + Script?.Dispose(); + Script = null; } } @@ -221,57 +220,6 @@ namespace Artemis.Core GC.SuppressFinalize(this); } - #region Mode management - - /// - /// Changes the data binding mode of the data binding to the specified - /// - public void ChangeDataBindingMode(DataBindingModeType dataBindingMode) - { - switch (dataBindingMode) - { - case DataBindingModeType.Direct: - Entity.DataBindingMode = new DirectDataBindingEntity(); - break; - case DataBindingModeType.Conditional: - Entity.DataBindingMode = new ConditionalDataBindingEntity(); - break; - default: - Entity.DataBindingMode = null; - break; - } - - ApplyDataBindingMode(); - } - - /// - /// Replaces the current data binding mode with one based on the provided data binding mode entity - /// - /// The data binding mode entity to base the new data binding mode upon - public void ApplyDataBindingEntity(IDataBindingModeEntity dataBindingModeEntity) - { - Entity.DataBindingMode = dataBindingModeEntity; - ApplyDataBindingMode(); - } - - private void ApplyDataBindingMode() - { - DataBindingMode?.Dispose(); - DataBindingMode = null; - - switch (Entity.DataBindingMode) - { - case DirectDataBindingEntity directDataBindingEntity: - DataBindingMode = new DirectDataBinding(this, directDataBindingEntity); - break; - case ConditionalDataBindingEntity conditionalDataBindingEntity: - DataBindingMode = new ConditionalDataBinding(this, conditionalDataBindingEntity); - break; - } - } - - #endregion - #region Storage /// @@ -288,7 +236,10 @@ namespace Artemis.Core EasingTime = Entity.EasingTime; EasingFunction = (Easings.Functions) Entity.EasingFunction; - DataBindingMode?.Load(); + Script.Dispose(); + Script = Entity.NodeScript != null + ? new NodeScript(Entity.NodeScript) + : new NodeScript(LayerProperty.PropertyDescription.Name ?? LayerProperty.Path, ""); } /// @@ -307,30 +258,10 @@ namespace Artemis.Core Entity.EasingTime = EasingTime; Entity.EasingFunction = (int) EasingFunction; - DataBindingMode?.Save(); + Script?.Save(); + Entity.NodeScript = Script?.Entity; } #endregion } - - /// - /// A mode that determines how the data binding is applied to the layer property - /// - public enum DataBindingModeType - { - /// - /// Disables the data binding - /// - None, - - /// - /// Replaces the layer property value with the data binding value - /// - Direct, - - /// - /// Replaces the layer property value with the data binding value - /// - Conditional - } } \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/ConditionalDataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/ConditionalDataBinding.cs deleted file mode 100644 index 96a8a5450..000000000 --- a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/ConditionalDataBinding.cs +++ /dev/null @@ -1,167 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using Artemis.Storage.Entities.Profile.DataBindings; - -namespace Artemis.Core -{ - /// - /// Represents a data binding mode that applies a value depending on conditions - /// - public class ConditionalDataBinding : IDataBindingMode - { - private readonly List> _conditions = new(); - private bool _disposed; - - internal ConditionalDataBinding(DataBinding dataBinding, ConditionalDataBindingEntity entity) - { - DataBinding = dataBinding; - Entity = entity; - Load(); - } - - /// - /// Gets a list of conditions applied to this data binding - /// - public ReadOnlyCollection> Conditions => _conditions.AsReadOnly(); - - internal ConditionalDataBindingEntity Entity { get; } - - /// - public DataBinding DataBinding { get; } - - /// - public TProperty GetValue(TProperty baseValue) - { - if (_disposed) - throw new ObjectDisposedException("ConditionalDataBinding"); - - DataBindingCondition? condition = Conditions.FirstOrDefault(c => c.Evaluate()); - return condition == null ? baseValue : condition.Value; - } - - #region IDisposable - - /// - /// Releases the unmanaged resources used by the object and optionally releases the managed resources. - /// - /// - /// to release both managed and unmanaged resources; - /// to release only unmanaged resources. - /// - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - _disposed = true; - - foreach (DataBindingCondition dataBindingCondition in Conditions) - dataBindingCondition.Dispose(); - } - } - - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - #endregion - - #region Values - - /// - /// Adds a condition to the conditional data binding's collection - /// - /// The newly created - public DataBindingCondition AddCondition() - { - if (_disposed) - throw new ObjectDisposedException("ConditionalDataBinding"); - - DataBindingCondition condition = new(this); - _conditions.Add(condition); - - ApplyOrder(); - OnConditionsUpdated(); - - return condition; - } - - /// - /// Removes a condition from the conditional data binding's collection and disposes it - /// - /// - public void RemoveCondition(DataBindingCondition condition) - { - if (_disposed) - throw new ObjectDisposedException("ConditionalDataBinding"); - if (!_conditions.Contains(condition)) - return; - - _conditions.Remove(condition); - condition.Dispose(); - - ApplyOrder(); - OnConditionsUpdated(); - } - - /// - /// Applies the current order of conditions to the collection - /// - public void ApplyOrder() - { - if (_disposed) - throw new ObjectDisposedException("ConditionalDataBinding"); - - _conditions.Sort((a, b) => a.Order.CompareTo(b.Order)); - for (int index = 0; index < _conditions.Count; index++) - { - DataBindingCondition condition = _conditions[index]; - condition.Order = index + 1; - } - } - - #endregion - - #region Storage - - /// - public void Load() - { - foreach (DataBindingConditionEntity dataBindingConditionEntity in Entity.Values) - _conditions.Add(new DataBindingCondition(this, dataBindingConditionEntity)); - - ApplyOrder(); - } - - /// - public void Save() - { - Entity.Values.Clear(); - foreach (DataBindingCondition dataBindingCondition in Conditions) - dataBindingCondition.Save(); - } - - #endregion - - #region Events - - /// - /// Occurs when a condition is added or removed - /// - public event EventHandler? ConditionsUpdated; - - /// - /// Invokes the event - /// - protected virtual void OnConditionsUpdated() - { - ConditionsUpdated?.Invoke(this, EventArgs.Empty); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/DataBindingCondition.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/DataBindingCondition.cs deleted file mode 100644 index daa22c4fa..000000000 --- a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/DataBindingCondition.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using Artemis.Storage.Entities.Profile.DataBindings; - -namespace Artemis.Core -{ - /// - public class DataBindingCondition : IDataBindingCondition - { - private bool _disposed; - - /// - /// Creates a new instance of the class - /// - /// The conditional data binding this condition is applied too - internal DataBindingCondition(ConditionalDataBinding conditionalDataBinding) - { - ConditionalDataBinding = conditionalDataBinding ?? throw new ArgumentNullException(nameof(conditionalDataBinding)); - Order = conditionalDataBinding.Conditions.Count + 1; - Condition = new DataModelConditionGroup(null); - Value = default!; - - Entity = new DataBindingConditionEntity(); - Save(); - } - - internal DataBindingCondition(ConditionalDataBinding conditionalDataBinding, DataBindingConditionEntity entity) - { - ConditionalDataBinding = conditionalDataBinding ?? throw new ArgumentNullException(nameof(conditionalDataBinding)); - Entity = entity; - Condition = null!; - Value = default!; - - Load(); - } - - /// - /// Gets the conditional data binding this condition is applied to - /// - public ConditionalDataBinding ConditionalDataBinding { get; } - - /// - /// Gets or sets the position at which the modifier appears on the data binding - /// - public int Order { get; set; } - - /// - /// Gets or sets the value to be applied when the condition is met - /// - public TProperty Value { get; set; } - - /// - /// Gets the root group of the condition that must be met - /// - public DataModelConditionGroup Condition { get; private set; } - - internal DataBindingConditionEntity Entity { get; set; } - - /// - public bool Evaluate() - { - return Condition.Evaluate(); - } - - /// - public void Save() - { - if (_disposed) - throw new ObjectDisposedException("DataBindingCondition"); - - if (!ConditionalDataBinding.Entity.Values.Contains(Entity)) - ConditionalDataBinding.Entity.Values.Add(Entity); - - Entity.Condition = Condition.Entity; - Condition.Save(); - - Entity.Value = CoreJson.SerializeObject(Value); - Entity.Order = Order; - } - - /// - public void Load() - { - if (_disposed) - throw new ObjectDisposedException("DataBindingCondition"); - - Condition = Entity.Condition != null - ? new DataModelConditionGroup(null, Entity.Condition) - : new DataModelConditionGroup(null); - - Value = (Entity.Value == null ? default : CoreJson.DeserializeObject(Entity.Value))!; - Order = Entity.Order; - } - - #region IDisposable - - /// - /// Releases the unmanaged resources used by the object and optionally releases the managed resources. - /// - /// - /// to release both managed and unmanaged resources; - /// to release only unmanaged resources. - /// - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - _disposed = true; - Condition.Dispose(); - } - } - - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/IDataBindingCondition.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/IDataBindingCondition.cs deleted file mode 100644 index 26ad9a9f2..000000000 --- a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/IDataBindingCondition.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Artemis.Core -{ - /// - /// Represents a condition and a value inside a - /// - public interface IDataBindingCondition : IStorageModel, IDisposable - { - /// - /// Evaluates the condition - /// - bool Evaluate(); - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/BaseDataBindingModifierType.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/BaseDataBindingModifierType.cs deleted file mode 100644 index 2d85efb96..000000000 --- a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/BaseDataBindingModifierType.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; - -namespace Artemis.Core -{ - /// - /// A modifier that changes the source value of a data binding in some way - /// - /// To implement your own condition operator, inherit or - /// - /// - /// - public abstract class BaseDataBindingModifierType - { - /// - /// Gets the plugin this data binding modifier belongs to - /// Note: Not set until after registering - /// - public Plugin? Plugin { get; internal set; } - - /// - /// Gets the value type of this modifier type - /// - public abstract Type ValueType { get; } - - /// - /// Gets the parameter type of this modifier type. May be null if the modifier type does not support a parameter - /// - public abstract Type? ParameterType { get; } - - /// - /// Gets the name of this modifier - /// - public abstract string Name { get; } - - /// - /// Gets or sets the icon of this modifier - /// - public abstract string? Icon { get; } - - /// - /// Gets the description of this modifier - /// - public virtual string? Description => null; - - /// - /// Gets the category of this modifier - /// - public virtual string? Category => null; - - /// - /// Returns whether the given type is supported by the modifier - /// - /// The type to check for, must be either the same or be castable to the target type - /// Which part of the modifier to check, the value or the parameter - 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); - } - - /// - /// Applies the modifier to the provided current value - /// - /// This leaves the caller responsible for the types matching and - /// - /// - /// - /// The current value before modification, type should match - /// - /// The parameter to use for the modification, type should match - /// - /// The modified value, with a type of - internal abstract object? InternalApply(object? currentValue, object? parameterValue); - } - - /// - /// Represents a part of a modifier type - /// - public enum ModifierTypePart - { - /// - /// The value part of a modifier, backed by - /// - Value, - - /// - /// The parameter part of a modifier, backed by - /// - Parameter - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/DataBindingModifier.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/DataBindingModifier.cs deleted file mode 100644 index 1b11249c9..000000000 --- a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/DataBindingModifier.cs +++ /dev/null @@ -1,324 +0,0 @@ -using System; -using Artemis.Storage.Entities.Profile.DataBindings; -using Newtonsoft.Json; - -namespace Artemis.Core -{ - /// - public class DataBindingModifier : IDataBindingModifier - { - private bool _disposed; - - internal DataBindingModifier(DirectDataBinding directDataBinding, ProfileRightSideType parameterType) - { - DirectDataBinding = directDataBinding ?? throw new ArgumentNullException(nameof(directDataBinding)); - Order = directDataBinding.Modifiers.Count + 1; - ParameterType = parameterType; - Entity = new DataBindingModifierEntity(); - Initialize(); - Save(); - } - - internal DataBindingModifier(DirectDataBinding directDataBinding, DataBindingModifierEntity entity) - { - DirectDataBinding = directDataBinding ?? throw new ArgumentNullException(nameof(directDataBinding)); - Entity = entity; - Load(); - Initialize(); - } - - /// - /// Gets the type of modifier that is being applied - /// - public BaseDataBindingModifierType? ModifierType { get; private set; } - - /// - /// Gets the direct data binding this modifier is applied to - /// - public DirectDataBinding DirectDataBinding { get; } - - /// - /// Gets the type of the parameter, can either be dynamic (based on a data model value) or static - /// - public ProfileRightSideType ParameterType { get; set; } - - /// - /// Gets or sets the position at which the modifier appears on the data binding - /// - public int Order { get; set; } - - /// - /// Gets the path of the parameter property - /// - public DataModelPath? ParameterPath { get; set; } - - /// - /// Gets the parameter static value, only used it is - /// - /// - public object? ParameterStaticValue { get; private set; } - - internal DataBindingModifierEntity Entity { get; set; } - - /// - /// Applies the modifier to the provided value - /// - /// The value to apply the modifier to, should be of the same type as the data binding target - /// The modified value - public object? Apply(object? currentValue) - { - if (_disposed) - throw new ObjectDisposedException("DataBindingModifier"); - - if (ModifierType == null) - return currentValue; - - if (ModifierType.ParameterType == null) - return ModifierType.InternalApply(currentValue, null); - - if (ParameterType == ProfileRightSideType.Dynamic && ParameterPath != null && ParameterPath.IsValid) - { - object? value = ParameterPath.GetValue(); - return ModifierType.InternalApply(currentValue, value); - } - - if (ParameterType == ProfileRightSideType.Static) - return ModifierType.InternalApply(currentValue, ParameterStaticValue); - - return currentValue; - } - - /// - /// Updates the modifier type of the modifier and re-compiles the expression - /// - /// - public void UpdateModifierType(BaseDataBindingModifierType? modifierType) - { - if (_disposed) - throw new ObjectDisposedException("DataBindingModifier"); - - if (modifierType == null) - { - ModifierType = null; - return; - } - - Type? targetType = DirectDataBinding.DataBinding.GetTargetType(); - if (targetType != null && !modifierType.SupportsType(targetType, ModifierTypePart.Value)) - 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}"); - - ModifierType = modifierType; - ValidateParameter(); - } - - /// - /// Updates the parameter of the modifier and makes the modifier dynamic - /// - /// The path pointing to the parameter - public void UpdateParameterDynamic(DataModelPath? path) - { - if (_disposed) - throw new ObjectDisposedException("DataBindingModifier"); - - if (path != null && !path.IsValid) - throw new ArtemisCoreException("Cannot update parameter of data binding modifier to an invalid path"); - - ParameterPath?.Dispose(); - ParameterPath = path != null ? new DataModelPath(path) : null; - - ParameterType = ProfileRightSideType.Dynamic; - } - - /// - /// Updates the parameter of the modifier, makes the modifier static and re-compiles the expression - /// - /// The static value to use as a parameter - public void UpdateParameterStatic(object? staticValue) - { - if (_disposed) - throw new ObjectDisposedException("DataBindingModifier"); - - ParameterType = ProfileRightSideType.Static; - ParameterPath?.Dispose(); - ParameterPath = null; - - Type? parameterType = ModifierType?.ParameterType ?? DirectDataBinding.DataBinding.GetTargetType(); - - // If not null ensure the types match and if not, convert it - if (parameterType == null || staticValue != null && staticValue.GetType() == parameterType) - ParameterStaticValue = staticValue; - else if (staticValue != null) - ParameterStaticValue = Convert.ChangeType(staticValue, parameterType); - // If null create a default instance for value types or simply make it null for reference types - else if (parameterType.IsValueType) - ParameterStaticValue = Activator.CreateInstance(parameterType); - else - ParameterStaticValue = null; - } - - 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); - } - } - - private void Initialize() - { - DataBindingModifierTypeStore.DataBindingModifierAdded += DataBindingModifierTypeStoreOnDataBindingModifierAdded; - DataBindingModifierTypeStore.DataBindingModifierRemoved += DataBindingModifierTypeStoreOnDataBindingModifierRemoved; - - // Modifier type - if (Entity.ModifierTypePluginGuid != null && ModifierType == null) - { - BaseDataBindingModifierType? modifierType = DataBindingModifierTypeStore.Get(Entity.ModifierTypePluginGuid.Value, Entity.ModifierType)?.DataBindingModifierType; - if (modifierType != null) - UpdateModifierType(modifierType); - } - - // Dynamic parameter - if (ParameterType == ProfileRightSideType.Dynamic && Entity.ParameterPath != null) - { - ParameterPath = new DataModelPath(null, Entity.ParameterPath); - } - // Static parameter - else if (ParameterType == ProfileRightSideType.Static && Entity.ParameterStaticValue != null) - { - // Use the target type so JSON.NET has a better idea what to do - Type? parameterType = ModifierType?.ParameterType ?? DirectDataBinding.DataBinding.GetTargetType(); - object? staticValue = null; - - try - { - staticValue = parameterType != null - ? CoreJson.DeserializeObject(Entity.ParameterStaticValue, parameterType) - : CoreJson.DeserializeObject(Entity.ParameterStaticValue); - } - // If deserialization fails, use the type's default - catch (JsonSerializationException e) - { - DeserializationLogger.LogModifierDeserializationFailure(GetType().Name, e); - if (parameterType != null) - staticValue = Activator.CreateInstance(parameterType); - } - - UpdateParameterStatic(staticValue); - } - } - - /// - public void Save() - { - if (_disposed) - throw new ObjectDisposedException("DataBindingModifier"); - - // Don't save an invalid state - if (ParameterPath != null && !ParameterPath.IsValid) - return; - - if (!DirectDataBinding.Entity.Modifiers.Contains(Entity)) - DirectDataBinding.Entity.Modifiers.Add(Entity); - - // Modifier - if (ModifierType?.Plugin != null) - { - Entity.ModifierType = ModifierType.GetType().Name; - Entity.ModifierTypePluginGuid = ModifierType.Plugin.Guid; - } - - // General - Entity.Order = Order; - Entity.ParameterType = (int) ParameterType; - - // Parameter - ParameterPath?.Save(); - Entity.ParameterPath = ParameterPath?.Entity; - - Entity.ParameterStaticValue = CoreJson.SerializeObject(ParameterStaticValue); - } - - /// - public void Load() - { - if (_disposed) - throw new ObjectDisposedException("DataBindingModifier"); - - // Modifier type is done during Initialize - - // General - Order = Entity.Order; - ParameterType = (ProfileRightSideType) Entity.ParameterType; - - // Parameter is done during initialize - } - - #region IDisposable - - /// - /// Releases the unmanaged resources used by the object and optionally releases the managed resources. - /// - /// - /// to release both managed and unmanaged resources; - /// to release only unmanaged resources. - /// - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - _disposed = true; - - DataBindingModifierTypeStore.DataBindingModifierAdded -= DataBindingModifierTypeStoreOnDataBindingModifierAdded; - DataBindingModifierTypeStore.DataBindingModifierRemoved -= DataBindingModifierTypeStoreOnDataBindingModifierRemoved; - - ParameterPath?.Dispose(); - } - } - - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - #endregion - - #region Event handlers - - private void DataBindingModifierTypeStoreOnDataBindingModifierAdded(object? sender, DataBindingModifierTypeStoreEvent e) - { - if (ModifierType != null) - return; - - BaseDataBindingModifierType modifierType = e.TypeRegistration.DataBindingModifierType; - if (modifierType.Plugin!.Guid == Entity.ModifierTypePluginGuid && modifierType.GetType().Name == Entity.ModifierType) - UpdateModifierType(modifierType); - } - - private void DataBindingModifierTypeStoreOnDataBindingModifierRemoved(object? sender, DataBindingModifierTypeStoreEvent e) - { - if (e.TypeRegistration.DataBindingModifierType == ModifierType) - UpdateModifierType(null); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/DataBindingModifierType.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/DataBindingModifierType.cs deleted file mode 100644 index c09cd8fcc..000000000 --- a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/DataBindingModifierType.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System; - -namespace Artemis.Core -{ - /// - /// A modifier that changes the source value of a data binding in some way using a parameter - /// - public abstract class DataBindingModifierType : BaseDataBindingModifierType - { - /// - public override Type ValueType => typeof(TValue); - - /// - public override Type ParameterType => typeof(TParameter); - - /// - /// Called whenever the modifier must apply to a specific value - /// - /// - /// The current value before modification - /// - /// - /// The parameter to use for the modification - /// - /// The modified value> - public abstract TValue Apply(TValue currentValue, TParameter parameterValue); - - /// - 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!); - } - } - - /// - /// A modifier that changes the source value of a data binding in some way - /// - public abstract class DataBindingModifierType : BaseDataBindingModifierType - { - /// - public override Type ValueType => typeof(TValue); - - /// - public override Type? ParameterType => null; - - /// - /// Called whenever the modifier must apply to a specific value - /// - /// - /// The current value before modification - /// - /// The modified value - public abstract TValue Apply(TValue currentValue); - - /// - 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!); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/IDataBindingModifier.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/IDataBindingModifier.cs deleted file mode 100644 index 6f920c0a1..000000000 --- a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/IDataBindingModifier.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Artemis.Core -{ - /// - /// Modifies a data model value in a way defined by the modifier type - /// - public interface IDataBindingModifier : IStorageModel, IDisposable - { - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/DirectDataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/DirectDataBinding.cs deleted file mode 100644 index 0dba4bd45..000000000 --- a/src/Artemis.Core/Models/Profile/DataBindings/Modes/DirectDataBinding.cs +++ /dev/null @@ -1,217 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using Artemis.Storage.Entities.Profile.DataBindings; - -namespace Artemis.Core -{ - /// - /// Represents a data binding mode that directly applies a data model value to a data binding - /// - public class DirectDataBinding : IDataBindingMode - { - private readonly List> _modifiers = new(); - private bool _disposed; - - internal DirectDataBinding(DataBinding dataBinding, DirectDataBindingEntity entity) - { - DataBinding = dataBinding; - Entity = entity; - - Load(); - } - - /// - /// Gets the path of the source property - /// - public DataModelPath? SourcePath { get; private set; } - - /// - /// Gets a list of modifiers applied to this data binding - /// - public ReadOnlyCollection> Modifiers => _modifiers.AsReadOnly(); - - internal DirectDataBindingEntity Entity { get; } - - /// - public DataBinding DataBinding { get; } - - /// - public TProperty GetValue(TProperty baseValue) - { - if (_disposed) - throw new ObjectDisposedException("DirectDataBinding"); - - if (SourcePath == null || !SourcePath.IsValid || DataBinding.Converter == null) - return baseValue; - - object? dataBindingValue = SourcePath.GetValue(); - foreach (DataBindingModifier dataBindingModifier in Modifiers) - dataBindingValue = dataBindingModifier.Apply(dataBindingValue); - - return DataBinding.Converter.ConvertFromObject(dataBindingValue); - } - - #region IDisposable - - /// - /// Releases the unmanaged resources used by the object and optionally releases the managed resources. - /// - /// - /// to release both managed and unmanaged resources; - /// to release only unmanaged resources. - /// - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - _disposed = true; - - foreach (DataBindingModifier dataBindingModifier in Modifiers) - dataBindingModifier.Dispose(); - - SourcePath?.Dispose(); - } - } - - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - #endregion - - #region Storage - - /// - public void Load() - { - // Source - if (Entity.SourcePath != null) - SourcePath = new DataModelPath(null, Entity.SourcePath); - - // Modifiers - foreach (DataBindingModifierEntity dataBindingModifierEntity in Entity.Modifiers) - _modifiers.Add(new DataBindingModifier(this, dataBindingModifierEntity)); - - ApplyOrder(); - } - - /// - public void Save() - { - // Don't save an invalid state - if (SourcePath != null && !SourcePath.IsValid) - return; - - SourcePath?.Save(); - Entity.SourcePath = SourcePath?.Entity; - - // Modifiers - Entity.Modifiers.Clear(); - foreach (DataBindingModifier dataBindingModifier in Modifiers) - dataBindingModifier.Save(); - } - - #endregion - - #region Source - - /// - /// Returns the type of the source property of this data binding - /// - public Type? GetSourceType() - { - return SourcePath?.GetPropertyType(); - } - - /// - /// Updates the source of the data binding - /// - /// The path pointing to the source - public void UpdateSource(DataModelPath? path) - { - if (_disposed) - throw new ObjectDisposedException("DirectDataBinding"); - - if (path != null && !path.IsValid) - throw new ArtemisCoreException("Cannot update source of data binding to an invalid path"); - - SourcePath?.Dispose(); - SourcePath = path != null ? new DataModelPath(path) : null; - } - - #endregion - - #region Modifiers - - /// - /// Adds a modifier to the direct data binding's collection - /// - /// The type of the parameter, can either be dynamic (based on a data model value) or static - public DataBindingModifier AddModifier(ProfileRightSideType type) - { - if (_disposed) - throw new ObjectDisposedException("DirectDataBinding"); - - DataBindingModifier modifier = new(this, type); - _modifiers.Add(modifier); - - ApplyOrder(); - OnModifiersUpdated(); - - return modifier; - } - - /// - /// Removes a modifier from the direct data binding's collection and disposes it - /// - public void RemoveModifier(DataBindingModifier modifier) - { - if (_disposed) - throw new ObjectDisposedException("DirectDataBinding"); - if (!_modifiers.Contains(modifier)) - return; - - _modifiers.Remove(modifier); - modifier.Dispose(); - - ApplyOrder(); - OnModifiersUpdated(); - } - - /// - /// Applies the current order of conditions to the collection - /// - public void ApplyOrder() - { - _modifiers.Sort((a, b) => a.Order.CompareTo(b.Order)); - for (int index = 0; index < _modifiers.Count; index++) - { - DataBindingModifier modifier = _modifiers[index]; - modifier.Order = index + 1; - } - } - - #endregion - - #region Events - - /// - /// Occurs when a modifier is added or removed - /// - public event EventHandler? ModifiersUpdated; - - /// - /// Invokes the event - /// - protected virtual void OnModifiersUpdated() - { - ModifiersUpdated?.Invoke(this, EventArgs.Empty); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingMode.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingMode.cs deleted file mode 100644 index e46a2aee9..000000000 --- a/src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingMode.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -namespace Artemis.Core -{ - /// - /// Represents a data binding mode - /// - public interface IDataBindingMode : IStorageModel, IDisposable - { - /// - /// Gets the data binding this mode is applied to - /// - DataBinding DataBinding { get; } - - /// - /// Gets the current value of the data binding - /// - /// The base value of the property the data binding is applied to - /// - TProperty GetValue(TProperty baseValue); - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs b/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs index 8dc7c9723..59dc7bc70 100644 --- a/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs +++ b/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs @@ -363,13 +363,6 @@ namespace Artemis.Core Entity.Path = Path; Entity.DataModelId = DataModelId; - - Entity.WrapperType = Target switch - { - ListPredicateWrapperDataModel _ => PathWrapperType.List, - EventPredicateWrapperDataModel _ => PathWrapperType.Event, - _ => PathWrapperType.None - }; } #endregion diff --git a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs index b72c5f9d0..8d69a0980 100644 --- a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs +++ b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs @@ -7,7 +7,6 @@ using Artemis.Core.LayerEffects.Placeholder; using Artemis.Core.Properties; using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile.Abstract; -using Newtonsoft.Json; using SkiaSharp; namespace Artemis.Core @@ -68,11 +67,7 @@ namespace Artemis.Core internal void LoadRenderElement() { DisplayCondition = RenderElementEntity.NodeScript != null ? new NodeScript(RenderElementEntity.NodeScript) : null; - - // DisplayCondition = RenderElementEntity.DisplayCondition != null - // ? new DataModelConditionGroup(null, RenderElementEntity.DisplayCondition) - // : new DataModelConditionGroup(null); - + Timeline = RenderElementEntity.Timeline != null ? new Timeline(RenderElementEntity.Timeline) : new Timeline(); diff --git a/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfiguration.cs b/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfiguration.cs index 21e1a3157..162567ab7 100644 --- a/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfiguration.cs +++ b/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfiguration.cs @@ -130,7 +130,7 @@ namespace Artemis.Core /// Gets the data model condition that must evaluate to for this profile to be activated /// alongside any activation requirements of the , if set /// - public DataModelConditionGroup? ActivationCondition { get; set; } + public NodeScript? ActivationCondition { get; set; } /// /// Gets or sets the module this profile uses @@ -168,7 +168,13 @@ namespace Artemis.Core if (_disposed) throw new ObjectDisposedException("ProfileConfiguration"); - ActivationConditionMet = ActivationCondition == null || ActivationCondition.Evaluate(); + if (ActivationCondition == null) + ActivationConditionMet = true; + else + { + ActivationCondition.Run(); + ActivationConditionMet = ActivationCondition.Result; + } } /// @@ -231,7 +237,8 @@ namespace Artemis.Core Icon.Load(); - ActivationCondition = Entity.ActivationCondition != null ? new DataModelConditionGroup(null, Entity.ActivationCondition) : null; + ActivationCondition?.Dispose(); + ActivationCondition = Entity.ActivationCondition != null ? new NodeScript(Entity.ActivationCondition) : null; EnableHotkey = Entity.EnableHotkey != null ? new ProfileConfigurationHotkey(Entity.EnableHotkey) : null; DisableHotkey = Entity.DisableHotkey != null ? new ProfileConfigurationHotkey(Entity.DisableHotkey) : null; diff --git a/src/Artemis.Core/Services/CoreService.cs b/src/Artemis.Core/Services/CoreService.cs index a9fc7a45e..7d9575166 100644 --- a/src/Artemis.Core/Services/CoreService.cs +++ b/src/Artemis.Core/Services/CoreService.cs @@ -210,8 +210,6 @@ namespace Artemis.Core.Services Version? hidSharpVersion = Assembly.GetAssembly(typeof(HidDevice))!.GetName().Version; _logger.Debug("Forcing plugins to use HidSharp {hidSharpVersion}", hidSharpVersion); - DeserializationLogger.Initialize(Kernel!); - // Initialize the services _pluginManagementService.CopyBuiltInPlugins(); _pluginManagementService.LoadPlugins(StartupArguments, IsElevated); diff --git a/src/Artemis.Core/Services/Registration/ConditionOperatorService.cs b/src/Artemis.Core/Services/Registration/ConditionOperatorService.cs deleted file mode 100644 index 3c0cbe854..000000000 --- a/src/Artemis.Core/Services/Registration/ConditionOperatorService.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Artemis.Core.Services -{ - internal class ConditionOperatorService : IConditionOperatorService - { - public ConditionOperatorService() - { - RegisterBuiltInConditionOperators(); - } - - public ConditionOperatorRegistration RegisterConditionOperator(Plugin plugin, BaseConditionOperator conditionOperator) - { - if (plugin == null) - throw new ArgumentNullException(nameof(plugin)); - if (conditionOperator == null) - throw new ArgumentNullException(nameof(conditionOperator)); - - conditionOperator.Plugin = plugin; - return ConditionOperatorStore.Add(conditionOperator); - } - - public void RemoveConditionOperator(ConditionOperatorRegistration registration) - { - if (registration == null) - throw new ArgumentNullException(nameof(registration)); - ConditionOperatorStore.Remove(registration); - } - - public List GetConditionOperatorsForType(Type type, ConditionParameterSide side) - { - return ConditionOperatorStore.GetForType(type, side).Select(r => r.ConditionOperator).ToList(); - } - - public BaseConditionOperator? GetConditionOperator(Guid operatorPluginGuid, string operatorType) - { - return ConditionOperatorStore.Get(operatorPluginGuid, operatorType)?.ConditionOperator; - } - - private void RegisterBuiltInConditionOperators() - { - // General usage for any type - RegisterConditionOperator(Constants.CorePlugin, new EqualsConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new NotEqualConditionOperator()); - - // Numeric operators - RegisterConditionOperator(Constants.CorePlugin, new NumberEqualsConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new NumberNotEqualConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new LessThanConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new GreaterThanConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new LessThanOrEqualConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new GreaterThanOrEqualConditionOperator()); - - // String operators - RegisterConditionOperator(Constants.CorePlugin, new StringEqualsConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new StringNotEqualConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new StringContainsConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new StringNotContainsConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new StringStartsWithConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new StringEndsWithConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new StringMatchesRegexConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new StringNullConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new StringNotNullConditionOperator()); - - // Enum operators - RegisterConditionOperator(Constants.CorePlugin, new EnumContainsConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new EnumNotContainsConditionOperator()); - - // Null checks, at the bottom - // TODO: Implement a priority mechanism - RegisterConditionOperator(Constants.CorePlugin, new NullConditionOperator()); - RegisterConditionOperator(Constants.CorePlugin, new NotNullConditionOperator()); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Services/Registration/DataBindingService.cs b/src/Artemis.Core/Services/Registration/DataBindingService.cs deleted file mode 100644 index 6cf789fbc..000000000 --- a/src/Artemis.Core/Services/Registration/DataBindingService.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Artemis.Core.Services -{ - internal class DataBindingService : IDataBindingService - { - public DataBindingService() - { - RegisterBuiltInModifiers(); - } - - public DataBindingModifierTypeRegistration RegisterModifierType(Plugin plugin, BaseDataBindingModifierType dataBindingModifierType) - { - if (plugin == null) - throw new ArgumentNullException(nameof(plugin)); - if (dataBindingModifierType == null) - throw new ArgumentNullException(nameof(dataBindingModifierType)); - - dataBindingModifierType.Plugin = plugin; - return DataBindingModifierTypeStore.Add(dataBindingModifierType); - } - - public void RemoveModifierType(DataBindingModifierTypeRegistration registration) - { - if (registration == null) - throw new ArgumentNullException(nameof(registration)); - DataBindingModifierTypeStore.Remove(registration); - } - - public List GetCompatibleModifierTypes(Type type, ModifierTypePart part) - { - return DataBindingModifierTypeStore.GetForType(type, part).Select(r => r.DataBindingModifierType).ToList(); - } - - public BaseDataBindingModifierType? GetModifierType(Guid modifierTypePluginGuid, string modifierType) - { - return DataBindingModifierTypeStore.Get(modifierTypePluginGuid, modifierType)?.DataBindingModifierType; - } - - private void RegisterBuiltInModifiers() - { - // Numbers - General - RegisterModifierType(Constants.CorePlugin, new SumModifierType()); - RegisterModifierType(Constants.CorePlugin, new SubtractModifierType()); - RegisterModifierType(Constants.CorePlugin, new MultiplicationModifierType()); - RegisterModifierType(Constants.CorePlugin, new DivideModifierType()); - RegisterModifierType(Constants.CorePlugin, new PercentageOfModifierType()); - - // Numbers - Advanced - RegisterModifierType(Constants.CorePlugin, new MaxModifierType()); - RegisterModifierType(Constants.CorePlugin, new MinModifierType()); - RegisterModifierType(Constants.CorePlugin, new ModuloModifierType()); - RegisterModifierType(Constants.CorePlugin, new AbsoluteModifierType()); - RegisterModifierType(Constants.CorePlugin, new PowerModifierType()); - RegisterModifierType(Constants.CorePlugin, new SquareRootModifierType()); - - // Numbers - Rounding - RegisterModifierType(Constants.CorePlugin, new FloorModifierType()); - RegisterModifierType(Constants.CorePlugin, new RoundModifierType()); - RegisterModifierType(Constants.CorePlugin, new CeilingModifierType()); - - // Numbers - Trigonometric - RegisterModifierType(Constants.CorePlugin, new SineModifierType()); - RegisterModifierType(Constants.CorePlugin, new CosineModifierType()); - RegisterModifierType(Constants.CorePlugin, new TangentModifierType()); - RegisterModifierType(Constants.CorePlugin, new CotangentModifierType()); - RegisterModifierType(Constants.CorePlugin, new SecantModifierType()); - RegisterModifierType(Constants.CorePlugin, new CosecantModifierType()); - - // Colors - RegisterModifierType(Constants.CorePlugin, new SKColorSumModifierType()); - RegisterModifierType(Constants.CorePlugin, new SKColorSaturateModifierType()); - RegisterModifierType(Constants.CorePlugin, new SKColorDesaturateModifierType()); - RegisterModifierType(Constants.CorePlugin, new SKColorBrightenModifierType()); - RegisterModifierType(Constants.CorePlugin, new SKColorDarkenModifierType()); - RegisterModifierType(Constants.CorePlugin, new SKColorRotateHueModifierType()); - RegisterModifierType(Constants.CorePlugin, new SKColorInvertModifierType()); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Services/Registration/Interfaces/IConditionOperatorService.cs b/src/Artemis.Core/Services/Registration/Interfaces/IConditionOperatorService.cs deleted file mode 100644 index 9b32ecc3f..000000000 --- a/src/Artemis.Core/Services/Registration/Interfaces/IConditionOperatorService.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; -using Artemis.Core.Properties; - -namespace Artemis.Core.Services -{ - /// - /// A service that allows you to register and retrieve conditions operators used by display conditions - /// - public interface IConditionOperatorService : IArtemisService - { - /// - /// Registers a new condition operator for use in layer conditions - /// - /// The plugin this condition operator belongs to - /// The condition operator to register - ConditionOperatorRegistration RegisterConditionOperator([NotNull] Plugin plugin, [NotNull] BaseConditionOperator conditionOperator); - - /// - /// Removes a condition operator so it is no longer available for use in layer conditions - /// - /// The registration of the condition operator to remove - void RemoveConditionOperator([NotNull] ConditionOperatorRegistration registration); - - /// - /// Returns all the condition operators compatible with the provided type - /// - List GetConditionOperatorsForType(Type type, ConditionParameterSide side); - - /// - /// Gets a condition operator by its plugin GUID and type name - /// - /// The operator's plugin GUID - /// The type name of the operator - BaseConditionOperator? GetConditionOperator(Guid operatorPluginGuid, string operatorType); - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Services/Registration/Interfaces/IDataBindingService.cs b/src/Artemis.Core/Services/Registration/Interfaces/IDataBindingService.cs deleted file mode 100644 index 36b73dcaf..000000000 --- a/src/Artemis.Core/Services/Registration/Interfaces/IDataBindingService.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Collections.Generic; -using Artemis.Core.Properties; - -namespace Artemis.Core.Services -{ - /// - /// A service that allows you to register and retrieve data binding modifiers used by the data bindings system - /// - public interface IDataBindingService : IArtemisService - { - /// - /// Registers a new modifier type for use in data bindings - /// - /// The plugin this modifier type belongs to - /// The modifier type to register - DataBindingModifierTypeRegistration RegisterModifierType([NotNull] Plugin plugin, [NotNull] BaseDataBindingModifierType dataBindingModifierType); - - /// - /// Removes a modifier type so it is no longer available for use in data bindings - /// - /// The registration of the modifier type to remove - void RemoveModifierType([NotNull] DataBindingModifierTypeRegistration dataBindingModifierType); - - /// - /// Returns all the data binding modifier types compatible with the provided type - /// - List GetCompatibleModifierTypes(Type type, ModifierTypePart part); - - /// - /// Gets a modifier type by its plugin GUID and type name - /// - /// The modifier type's plugin GUID - /// The type name of the modifier type - /// - BaseDataBindingModifierType? GetModifierType(Guid modifierTypePluginGuid, string modifierType); - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Services/Storage/ProfileService.cs b/src/Artemis.Core/Services/Storage/ProfileService.cs index 16e737689..3f532faf3 100644 --- a/src/Artemis.Core/Services/Storage/ProfileService.cs +++ b/src/Artemis.Core/Services/Storage/ProfileService.cs @@ -29,9 +29,6 @@ namespace Artemis.Core.Services public ProfileService(ILogger logger, IRgbService rgbService, - // TODO: Move these two - IConditionOperatorService conditionOperatorService, - IDataBindingService dataBindingService, IProfileCategoryRepository profileCategoryRepository, IPluginManagementService pluginManagementService, IInputService inputService, diff --git a/src/Artemis.Core/Stores/ConditionOperatorStore.cs b/src/Artemis.Core/Stores/ConditionOperatorStore.cs deleted file mode 100644 index 8fe8d7e6e..000000000 --- a/src/Artemis.Core/Stores/ConditionOperatorStore.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Artemis.Core -{ - internal class ConditionOperatorStore - { - private static readonly List Registrations = new(); - - public static ConditionOperatorRegistration Add(BaseConditionOperator conditionOperator) - { - if (conditionOperator.Plugin == null) - throw new ArtemisCoreException("Cannot add a condition operator to the store that is not related to a plugin"); - - ConditionOperatorRegistration registration; - lock (Registrations) - { - if (Registrations.Any(r => r.ConditionOperator == conditionOperator)) - throw new ArtemisCoreException($"Condition operator store store already contains operator '{conditionOperator.Description}'"); - - registration = new ConditionOperatorRegistration(conditionOperator, conditionOperator.Plugin) {IsInStore = true}; - Registrations.Add(registration); - } - - OnConditionOperatorAdded(new ConditionOperatorStoreEvent(registration)); - return registration; - } - - public static void Remove(ConditionOperatorRegistration registration) - { - lock (Registrations) - { - if (!Registrations.Contains(registration)) - throw new ArtemisCoreException($"Condition operator store does not contain operator '{registration.ConditionOperator.Description}'"); - - Registrations.Remove(registration); - registration.IsInStore = false; - } - - OnConditionOperatorRemoved(new ConditionOperatorStoreEvent(registration)); - } - - public static ConditionOperatorRegistration? Get(Guid pluginGuid, string type) - { - lock (Registrations) - { - return Registrations.FirstOrDefault(r => r.Plugin.Guid == pluginGuid && r.ConditionOperator.GetType().Name == type); - } - } - - public static List GetForType(Type type, ConditionParameterSide side) - { - lock (Registrations) - { - if (type == null) - return new List(Registrations); - - List candidates = Registrations.Where(r => r.ConditionOperator.SupportsType(type, side)).ToList(); - - // If there are multiple operators with the same description, use the closest match - foreach (IGrouping candidate in candidates.GroupBy(r => r.ConditionOperator.Description).Where(g => g.Count() > 1).ToList()) - { - ConditionOperatorRegistration closest = side == ConditionParameterSide.Left - ? candidate.OrderByDescending(r => r.ConditionOperator.LeftSideType.ScoreCastability(type)).First() - : candidate.OrderByDescending(r => r.ConditionOperator.RightSideType!.ScoreCastability(type)).First(); - foreach (ConditionOperatorRegistration conditionOperator in candidate) - { - if (conditionOperator != closest) - candidates.Remove(conditionOperator); - } - } - - return candidates; - } - } - - #region Events - - public static event EventHandler? ConditionOperatorAdded; - public static event EventHandler? ConditionOperatorRemoved; - - private static void OnConditionOperatorAdded(ConditionOperatorStoreEvent e) - { - ConditionOperatorAdded?.Invoke(null, e); - } - - private static void OnConditionOperatorRemoved(ConditionOperatorStoreEvent e) - { - ConditionOperatorRemoved?.Invoke(null, e); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Stores/DataBindingModifierTypeStore.cs b/src/Artemis.Core/Stores/DataBindingModifierTypeStore.cs deleted file mode 100644 index 86708450f..000000000 --- a/src/Artemis.Core/Stores/DataBindingModifierTypeStore.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Artemis.Core -{ - internal class DataBindingModifierTypeStore - { - private static readonly List Registrations = new(); - - public static DataBindingModifierTypeRegistration Add(BaseDataBindingModifierType modifierType) - { - if (modifierType.Plugin == null) - throw new ArtemisCoreException("Cannot add a data binding modifier type that is not associated with a plugin"); - - DataBindingModifierTypeRegistration typeRegistration; - lock (Registrations) - { - if (Registrations.Any(r => r.DataBindingModifierType == modifierType)) - throw new ArtemisCoreException($"Data binding modifier type store already contains modifier '{modifierType.Name}'"); - - typeRegistration = new DataBindingModifierTypeRegistration(modifierType, modifierType.Plugin) { IsInStore = true }; - Registrations.Add(typeRegistration); - } - - OnDataBindingModifierAdded(new DataBindingModifierTypeStoreEvent(typeRegistration)); - return typeRegistration; - } - - public static void Remove(DataBindingModifierTypeRegistration typeRegistration) - { - lock (Registrations) - { - if (!Registrations.Contains(typeRegistration)) - throw new ArtemisCoreException($"Data binding modifier type store does not contain modifier type '{typeRegistration.DataBindingModifierType.Name}'"); - - Registrations.Remove(typeRegistration); - typeRegistration.IsInStore = false; - } - - OnDataBindingModifierRemoved(new DataBindingModifierTypeStoreEvent(typeRegistration)); - } - - public static DataBindingModifierTypeRegistration? Get(Guid pluginGuid, string type) - { - lock (Registrations) - { - return Registrations.FirstOrDefault(r => r.Plugin.Guid == pluginGuid && r.DataBindingModifierType.GetType().Name == type); - } - } - - public static List GetForType(Type type, ModifierTypePart part) - { - lock (Registrations) - { - if (type == null) - return new List(Registrations); - - List candidates = Registrations.Where(r => r.DataBindingModifierType.SupportsType(type, part)).ToList(); - - // If there are multiple modifiers with the same description, use the closest match - foreach (IGrouping displayDataBindingModifiers in candidates.GroupBy(r => r.DataBindingModifierType.Name).Where(g => g.Count() > 1).ToList()) - { - 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) - { - if (displayDataBindingModifier != closest) - candidates.Remove(displayDataBindingModifier); - } - } - - return candidates; - } - } - - #region Events - - public static event EventHandler? DataBindingModifierAdded; - public static event EventHandler? DataBindingModifierRemoved; - - private static void OnDataBindingModifierAdded(DataBindingModifierTypeStoreEvent e) - { - DataBindingModifierAdded?.Invoke(null, e); - } - - private static void OnDataBindingModifierRemoved(DataBindingModifierTypeStoreEvent e) - { - DataBindingModifierRemoved?.Invoke(null, e); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Stores/Registrations/ConditionOperatorRegistration.cs b/src/Artemis.Core/Stores/Registrations/ConditionOperatorRegistration.cs deleted file mode 100644 index 2691ee1ec..000000000 --- a/src/Artemis.Core/Stores/Registrations/ConditionOperatorRegistration.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; - -namespace Artemis.Core -{ - /// - /// Represents a data model registration - /// - public class ConditionOperatorRegistration - { - internal ConditionOperatorRegistration(BaseConditionOperator conditionOperator, Plugin plugin) - { - ConditionOperator = conditionOperator; - Plugin = plugin; - - Plugin.Disabled += OnDisabled; - } - - /// - /// Gets the condition operator that has been registered - /// - public BaseConditionOperator ConditionOperator { get; } - - /// - /// Gets the plugin the condition operator is associated with - /// - public Plugin Plugin { get; } - - /// - /// Gets a boolean indicating whether the registration is in the internal Core store - /// - public bool IsInStore { get; internal set; } - - private void OnDisabled(object? sender, EventArgs e) - { - Plugin.Disabled -= OnDisabled; - if (IsInStore) - ConditionOperatorStore.Remove(this); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Stores/Registrations/DataBindingModifierTypeRegistration.cs b/src/Artemis.Core/Stores/Registrations/DataBindingModifierTypeRegistration.cs deleted file mode 100644 index ddab462bd..000000000 --- a/src/Artemis.Core/Stores/Registrations/DataBindingModifierTypeRegistration.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; - -namespace Artemis.Core -{ - /// - /// Represents a data model registration - /// - public class DataBindingModifierTypeRegistration - { - internal DataBindingModifierTypeRegistration(BaseDataBindingModifierType dataBindingModifierType, Plugin plugin) - { - DataBindingModifierType = dataBindingModifierType; - Plugin = plugin; - - Plugin.Disabled += OnDisabled; - } - - /// - /// Gets the data binding modifier that has been registered - /// - public BaseDataBindingModifierType DataBindingModifierType { get; } - - /// - /// Gets the plugin the data binding modifier is associated with - /// - public Plugin Plugin { get; } - - /// - /// Gets a boolean indicating whether the registration is in the internal Core store - /// - public bool IsInStore { get; internal set; } - - private void OnDisabled(object? sender, EventArgs e) - { - Plugin.Disabled -= OnDisabled; - if (IsInStore) - DataBindingModifierTypeStore.Remove(this); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Utilities/DeserializationLogger.cs b/src/Artemis.Core/Utilities/DeserializationLogger.cs deleted file mode 100644 index f75542c87..000000000 --- a/src/Artemis.Core/Utilities/DeserializationLogger.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Newtonsoft.Json; -using Ninject; -using Serilog; - -namespace Artemis.Core -{ - internal static class DeserializationLogger - { - private static ILogger? _logger; - - public static void Initialize(IKernel kernel) - { - _logger = kernel.Get(); - } - - public static void LogPredicateDeserializationFailure(DataModelConditionPredicate dataModelConditionPredicate, JsonException exception) - { - _logger?.Warning( - exception, - "Failed to deserialize display condition predicate {left} {operator} {right}", - dataModelConditionPredicate.Entity.LeftPath?.Path, - dataModelConditionPredicate.Entity.OperatorType, - dataModelConditionPredicate.Entity.RightPath?.Path - ); - } - - public static void LogModifierDeserializationFailure(string modifierName, JsonSerializationException exception) - { - _logger?.Warning(exception, "Failed to deserialize static parameter for modifier {modifierName}", modifierName); - } - } -} diff --git a/src/Artemis.Storage/Entities/Profile/DataBindings/ConditionalDataBindingEntity.cs b/src/Artemis.Storage/Entities/Profile/DataBindings/ConditionalDataBindingEntity.cs deleted file mode 100644 index c7fffcf19..000000000 --- a/src/Artemis.Storage/Entities/Profile/DataBindings/ConditionalDataBindingEntity.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.Generic; - -namespace Artemis.Storage.Entities.Profile.DataBindings -{ - public class ConditionalDataBindingEntity : IDataBindingModeEntity - { - public ConditionalDataBindingEntity() - { - Values = new List(); - } - - public List Values { get; set; } - } -} \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingConditionEntity.cs b/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingConditionEntity.cs deleted file mode 100644 index 7fb0fc611..000000000 --- a/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingConditionEntity.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Artemis.Storage.Entities.Profile.Conditions; - -namespace Artemis.Storage.Entities.Profile.DataBindings -{ - public class DataBindingConditionEntity - { - public string Value { get; set; } - public DataModelConditionGroupEntity Condition { get; set; } - public int Order { get; set; } - } -} \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingEntity.cs b/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingEntity.cs index 6dd27b85a..92a38fb1a 100644 --- a/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingEntity.cs @@ -1,4 +1,5 @@ using System; +using Artemis.Storage.Entities.Profile.Nodes; namespace Artemis.Storage.Entities.Profile.DataBindings { @@ -7,7 +8,7 @@ namespace Artemis.Storage.Entities.Profile.DataBindings public string Identifier { get; set; } public TimeSpan EasingTime { get; set; } public int EasingFunction { get; set; } - - public IDataBindingModeEntity DataBindingMode { get; set; } + + public NodeScriptEntity NodeScript { get; set; } } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingModifierEntity.cs b/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingModifierEntity.cs deleted file mode 100644 index c4139737c..000000000 --- a/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingModifierEntity.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; - -namespace Artemis.Storage.Entities.Profile.DataBindings -{ - public class DataBindingModifierEntity - { - public string ModifierType { get; set; } - public Guid? ModifierTypePluginGuid { get; set; } - - public int Order { get; set; } - public int ParameterType { get; set; } - - public DataModelPathEntity ParameterPath { get; set; } - - // Stored as a string to be able to control serialization and deserialization ourselves - public string ParameterStaticValue { get; set; } - } -} \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/DataBindings/DirectDataBindingEntity.cs b/src/Artemis.Storage/Entities/Profile/DataBindings/DirectDataBindingEntity.cs deleted file mode 100644 index e8a14cb9f..000000000 --- a/src/Artemis.Storage/Entities/Profile/DataBindings/DirectDataBindingEntity.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; - -namespace Artemis.Storage.Entities.Profile.DataBindings -{ - public class DirectDataBindingEntity : IDataBindingModeEntity - { - public DirectDataBindingEntity() - { - Modifiers = new List(); - } - - public DataModelPathEntity SourcePath { get; set; } - public List Modifiers { get; set; } - } -} \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/DataBindings/IDataBindingModeEntity.cs b/src/Artemis.Storage/Entities/Profile/DataBindings/IDataBindingModeEntity.cs deleted file mode 100644 index d1d189588..000000000 --- a/src/Artemis.Storage/Entities/Profile/DataBindings/IDataBindingModeEntity.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Artemis.Storage.Entities.Profile.DataBindings -{ - public interface IDataBindingModeEntity - { - } -} \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/DataModelPathEntity.cs b/src/Artemis.Storage/Entities/Profile/DataModelPathEntity.cs index 7ab2806db..2e13396b9 100644 --- a/src/Artemis.Storage/Entities/Profile/DataModelPathEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/DataModelPathEntity.cs @@ -6,14 +6,5 @@ namespace Artemis.Storage.Entities.Profile { public string Path { get; set; } public string DataModelId { get; set; } - - public PathWrapperType WrapperType { get; set; } - } - - public enum PathWrapperType - { - None, - List, - Event } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/ProfileConfigurationEntity.cs b/src/Artemis.Storage/Entities/Profile/ProfileConfigurationEntity.cs index 8b9f08dd8..8c98eb726 100644 --- a/src/Artemis.Storage/Entities/Profile/ProfileConfigurationEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/ProfileConfigurationEntity.cs @@ -1,5 +1,6 @@ using System; using Artemis.Storage.Entities.Profile.Conditions; +using Artemis.Storage.Entities.Profile.Nodes; namespace Artemis.Storage.Entities.Profile { @@ -13,7 +14,7 @@ namespace Artemis.Storage.Entities.Profile public bool IsSuspended { get; set; } public int ActivationBehaviour { get; set; } - public DataModelConditionGroupEntity ActivationCondition { get; set; } + public NodeScriptEntity ActivationCondition { get; set; } public int HotkeyMode { get; set; } public ProfileConfigurationHotkeyEntity EnableHotkey { get; set; } diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj index 33e955e6c..857718991 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -77,4 +77,7 @@ + + + \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Bootstrapper.cs b/src/Artemis.UI.Shared/Bootstrapper.cs index 9f081c871..c253012f8 100644 --- a/src/Artemis.UI.Shared/Bootstrapper.cs +++ b/src/Artemis.UI.Shared/Bootstrapper.cs @@ -1,4 +1,5 @@ -using Artemis.UI.Shared.Services; +using Artemis.UI.Shared.Controls; +using Artemis.UI.Shared.Services; using Ninject; namespace Artemis.UI.Shared @@ -23,9 +24,9 @@ namespace Artemis.UI.Shared if (Initialized) return; - IColorPickerService colorPickerService = kernel.Get(); - GradientPicker.ColorPickerService = colorPickerService; - ColorPicker.ColorPickerService = colorPickerService; + GradientPicker.ColorPickerService = kernel.Get(); + ColorPicker.ColorPickerService = kernel.Get(); + DataModelPicker.DataModelUIService = kernel.Get(); Initialized = true; } diff --git a/src/Artemis.UI.Shared/Controls/DataModelPicker.xaml b/src/Artemis.UI.Shared/Controls/DataModelPicker.xaml new file mode 100644 index 000000000..725091f24 --- /dev/null +++ b/src/Artemis.UI.Shared/Controls/DataModelPicker.xaml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Controls/DataModelPicker.xaml.cs b/src/Artemis.UI.Shared/Controls/DataModelPicker.xaml.cs new file mode 100644 index 000000000..036031368 --- /dev/null +++ b/src/Artemis.UI.Shared/Controls/DataModelPicker.xaml.cs @@ -0,0 +1,303 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; +using Artemis.Core; +using Artemis.Core.Modules; +using Artemis.UI.Shared.Services; +using Stylet; + +namespace Artemis.UI.Shared.Controls +{ + /// + /// Interaction logic for DataModelPicker.xaml + /// + public partial class DataModelPicker : INotifyPropertyChanged + { + private static IDataModelUIService _dataModelUIService; + + /// + /// Gets or sets data model path + /// + public static readonly DependencyProperty DataModelPathProperty = DependencyProperty.Register( + nameof(DataModelPath), typeof(DataModelPath), typeof(DataModelPicker), + new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, DataModelPathPropertyChangedCallback) + ); + + /// + /// Gets or sets the brush to use when drawing the button + /// + public static readonly DependencyProperty PlaceholderProperty = DependencyProperty.Register( + nameof(Placeholder), typeof(string), typeof(DataModelPicker), + new FrameworkPropertyMetadata("Click to select") + ); + + /// + /// Gets or sets the brush to use when drawing the button + /// + public static readonly DependencyProperty ShowDataModelValuesProperty = DependencyProperty.Register(nameof(ShowDataModelValues), typeof(bool), typeof(DataModelPicker)); + + /// + /// Gets or sets the brush to use when drawing the button + /// + public static readonly DependencyProperty ShowFullPathProperty = DependencyProperty.Register(nameof(ShowFullPath), typeof(bool), typeof(DataModelPicker)); + + /// + /// Gets or sets the brush to use when drawing the button + /// + public static readonly DependencyProperty ButtonBrushProperty = DependencyProperty.Register(nameof(ButtonBrush), typeof(Brush), typeof(DataModelPicker)); + + /// + /// A list of extra modules to show data models of + /// + public static readonly DependencyProperty ModulesProperty = DependencyProperty.Register( + nameof(Modules), typeof(BindableCollection), typeof(DataModelPicker), + new FrameworkPropertyMetadata(new BindableCollection(), FrameworkPropertyMetadataOptions.None, ModulesPropertyChangedCallback) + ); + + /// + /// The data model view model to show, if not provided one will be retrieved by the control + /// + public static readonly DependencyProperty DataModelViewModelProperty = DependencyProperty.Register( + nameof(DataModelViewModel), typeof(DataModelPropertiesViewModel), typeof(DataModelPicker), + new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None, DataModelViewModelPropertyChangedCallback) + ); + + /// + /// A list of data model view models to show + /// + public static readonly DependencyProperty ExtraDataModelViewModelsProperty = DependencyProperty.Register( + nameof(ExtraDataModelViewModels), typeof(BindableCollection), typeof(DataModelPicker), + new FrameworkPropertyMetadata(new BindableCollection(), FrameworkPropertyMetadataOptions.None, ExtraDataModelViewModelsPropertyChangedCallback) + ); + + /// + /// A list of data model view models to show + /// + public static readonly DependencyProperty FilterTypesProperty = DependencyProperty.Register( + nameof(FilterTypes), typeof(BindableCollection), typeof(DataModelPicker), + new FrameworkPropertyMetadata(new BindableCollection()) + ); + + public DataModelPicker() + { + SelectPropertyCommand = new DelegateCommand(ExecuteSelectPropertyCommand); + + InitializeComponent(); + GetDataModel(); + UpdateValueDisplay(); + } + + /// + /// Gets or sets the brush to use when drawing the button + /// + public DataModelPath? DataModelPath + { + get => (DataModelPath) GetValue(DataModelPathProperty); + set => SetValue(DataModelPathProperty, value); + } + + /// + /// Gets or sets the brush to use when drawing the button + /// + public string Placeholder + { + get => (string) GetValue(PlaceholderProperty); + set => SetValue(PlaceholderProperty, value); + } + + /// + /// Gets or sets the brush to use when drawing the button + /// + public bool ShowDataModelValues + { + get => (bool) GetValue(ShowDataModelValuesProperty); + set => SetValue(ShowDataModelValuesProperty, value); + } + + /// + /// Gets or sets the brush to use when drawing the button + /// + public bool ShowFullPath + { + get => (bool) GetValue(ShowFullPathProperty); + set => SetValue(ShowFullPathProperty, value); + } + + /// + /// Gets or sets the brush to use when drawing the button + /// + public Brush ButtonBrush + { + get => (Brush) GetValue(ButtonBrushProperty); + set => SetValue(ButtonBrushProperty, value); + } + + /// + /// Gets or sets a list of extra modules to show data models of + /// + public BindableCollection? Modules + { + get => (BindableCollection) GetValue(ModulesProperty); + set => SetValue(ModulesProperty, value); + } + + /// + /// Gets or sets the data model view model to show + /// + public DataModelPropertiesViewModel? DataModelViewModel + { + get => (DataModelPropertiesViewModel) GetValue(DataModelViewModelProperty); + set => SetValue(DataModelViewModelProperty, value); + } + + /// + /// Gets or sets a list of data model view models to show + /// + public BindableCollection? ExtraDataModelViewModels + { + get => (BindableCollection) GetValue(ExtraDataModelViewModelsProperty); + set => SetValue(ExtraDataModelViewModelsProperty, value); + } + + /// + /// Gets or sets the types of properties this view model will allow to be selected + /// + public BindableCollection? FilterTypes + { + get => (BindableCollection) GetValue(FilterTypesProperty); + set => SetValue(FilterTypesProperty, value); + } + + /// + /// Command used by view + /// + public DelegateCommand SelectPropertyCommand { get; } + + internal static IDataModelUIService DataModelUIService + { + set + { + if (_dataModelUIService != null) + throw new AccessViolationException("This is not for you to touch"); + _dataModelUIService = value; + } + } + + /// + /// Occurs when a new path has been selected + /// + public event EventHandler? DataModelPathSelected; + + /// + /// Invokes the event + /// + /// + protected virtual void OnDataModelPathSelected(DataModelSelectedEventArgs e) + { + DataModelPathSelected?.Invoke(this, e); + } + + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + private void GetDataModel() + { + ChangeDataModel(_dataModelUIService.GetPluginDataModelVisualization(Modules?.ToList() ?? new List(), true)); + } + + private void ChangeDataModel(DataModelPropertiesViewModel? dataModel) + { + if (DataModelViewModel != null) + { + DataModelViewModel.Dispose(); + DataModelViewModel.UpdateRequested -= DataModelOnUpdateRequested; + } + + DataModelViewModel = dataModel; + if (DataModelViewModel != null) + DataModelViewModel.UpdateRequested += DataModelOnUpdateRequested; + } + + private void UpdateValueDisplay() + { + ValueDisplay.Visibility = DataModelPath == null || DataModelPath.IsValid ? Visibility.Visible : Visibility.Collapsed; + ValuePlaceholder.Visibility = DataModelPath == null || DataModelPath.IsValid ? Visibility.Collapsed : Visibility.Visible; + + string? formattedPath = null; + if (DataModelPath != null && DataModelPath.IsValid) + formattedPath = string.Join(" › ", DataModelPath.Segments.Where(s => s.GetPropertyDescription() != null).Select(s => s.GetPropertyDescription()!.Name)); + + DataModelButton.ToolTip = formattedPath; + ValueDisplayTextBlock.Text = ShowFullPath + ? formattedPath + : DataModelPath?.Segments.LastOrDefault()?.GetPropertyDescription()?.Name ?? DataModelPath?.Segments.LastOrDefault()?.Identifier; + } + + private void DataModelOnUpdateRequested(object? sender, EventArgs e) + { + DataModelViewModel?.ApplyTypeFilter(true, FilterTypes?.ToArray() ?? Type.EmptyTypes); + if (ExtraDataModelViewModels == null) return; + foreach (DataModelPropertiesViewModel extraDataModelViewModel in ExtraDataModelViewModels) + extraDataModelViewModel.ApplyTypeFilter(true, FilterTypes?.ToArray() ?? Type.EmptyTypes); + } + + private void ExecuteSelectPropertyCommand(object? context) + { + if (context is not DataModelVisualizationViewModel selected) + return; + + DataModelPath = selected.DataModelPath; + OnDataModelPathSelected(new DataModelSelectedEventArgs(DataModelPath)); + } + + private void PropertyButton_OnClick(object sender, RoutedEventArgs e) + { + // DataContext is not set when using left button, I don't know why but there it is + if (sender is Button button && button.ContextMenu != null) + { + button.ContextMenu.DataContext = button.DataContext; + button.ContextMenu.IsOpen = true; + } + } + + private static void DataModelPathPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is not DataModelPicker dataModelPicker) + return; + + if (e.OldValue is DataModelPath oldPath) + oldPath.Dispose(); + + dataModelPicker.UpdateValueDisplay(); + } + + private static void ModulesPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is not DataModelPicker dataModelPicker) + return; + + dataModelPicker.GetDataModel(); + } + + private static void DataModelViewModelPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is not DataModelPicker dataModelPicker) + return; + } + + private static void ExtraDataModelViewModelsPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is not DataModelPicker dataModelPicker) + return; + } + + public event PropertyChangedEventHandler? PropertyChanged; + } +} \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Converters/IntToVisibilityConverter.cs b/src/Artemis.UI.Shared/Converters/IntToVisibilityConverter.cs new file mode 100644 index 000000000..2db2cd50a --- /dev/null +++ b/src/Artemis.UI.Shared/Converters/IntToVisibilityConverter.cs @@ -0,0 +1,39 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace Artemis.UI.Shared +{ + /// + /// Converts to + /// + public class IntToVisibilityConverter : IValueConverter + { + /// + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + Parameters direction; + if (parameter == null) + direction = Parameters.Normal; + else + direction = (Parameters) Enum.Parse(typeof(Parameters), (string) parameter); + + return direction == Parameters.Normal + ? value is > 1 ? Visibility.Visible : Visibility.Collapsed + : value is > 1 ? Visibility.Collapsed : Visibility.Visible; + } + + /// + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + + private enum Parameters + { + Normal, + Inverted + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml deleted file mode 100644 index 6ebda995f..000000000 --- a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml.cs b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml.cs deleted file mode 100644 index a487bdfea..000000000 --- a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Windows; -using System.Windows.Controls; - -namespace Artemis.UI.Shared.Input -{ - /// - /// Interaction logic for DataModelDynamicView.xaml - /// - public partial class DataModelDynamicView : UserControl - { - /// - /// Creates a new instance of the class - /// - public DataModelDynamicView() - { - InitializeComponent(); - } - - private void PropertyButton_OnClick(object sender, RoutedEventArgs e) - { - // DataContext is not set when using left button, I don't know why but there it is - if (sender is Button button && button.ContextMenu != null) - { - button.ContextMenu.DataContext = button.DataContext; - button.ContextMenu.IsOpen = true; - } - } - } -} \ No newline at end of file diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs deleted file mode 100644 index ad9b65584..000000000 --- a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs +++ /dev/null @@ -1,387 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Linq; -using System.Timers; -using System.Windows.Media; -using Artemis.Core; -using Artemis.Core.Modules; -using Artemis.Core.Services; -using Artemis.UI.Shared.Services; -using MaterialDesignColors.ColorManipulation; -using Stylet; - -namespace Artemis.UI.Shared.Input -{ - /// - /// Represents a view model that allows selecting a data model property used by boolean operations on a certain data - /// model property - /// - public class DataModelDynamicViewModel : PropertyChangedBase, IDisposable - { - private readonly List _modules; - private readonly IDataModelUIService _dataModelUIService; - private readonly Timer _updateTimer; - private SolidColorBrush _buttonBrush = new(Color.FromRgb(171, 71, 188)); - private DataModelPath? _dataModelPath; - private DataModelPropertiesViewModel? _dataModelViewModel; - private bool _displaySwitchButton; - private Type[] _filterTypes = Array.Empty(); - private bool _isDataModelViewModelOpen; - private bool _isEnabled = true; - private string _placeholder = "Select a property"; - private readonly PluginSetting _showFullPath; - - internal DataModelDynamicViewModel(List modules, ISettingsService settingsService, IDataModelUIService dataModelUIService) - { - _modules = modules; - _dataModelUIService = dataModelUIService; - _updateTimer = new Timer(500); - _showFullPath = settingsService.GetSetting("ProfileEditor.ShowFullPaths", true); - - ExtraDataModelViewModels = new BindableCollection(); - ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues"); - SelectPropertyCommand = new DelegateCommand(ExecuteSelectPropertyCommand); - - Initialize(); - } - - /// - /// Gets or sets the brush to use for the input button - /// - public SolidColorBrush ButtonBrush - { - get => _buttonBrush; - set - { - if (!SetAndNotify(ref _buttonBrush, value)) return; - NotifyOfPropertyChange(nameof(SwitchButtonBrush)); - } - } - - /// - /// Gets the brush to use for the switch button - /// - public SolidColorBrush SwitchButtonBrush => new(ButtonBrush.Color.Darken()); - - /// - /// Gets or sets the placeholder text when no value is entered - /// - public string Placeholder - { - get => _placeholder; - set => SetAndNotify(ref _placeholder, value); - } - - /// - /// Gets or sets the enabled state of the input - /// - public bool IsEnabled - { - get => _isEnabled; - set => SetAndNotify(ref _isEnabled, value); - } - - /// - /// Gets or sets whether the switch button should be displayed - /// - public bool DisplaySwitchButton - { - get => _displaySwitchButton; - set => SetAndNotify(ref _displaySwitchButton, value); - } - - /// - /// Gets or sets the types of properties this view model will allow to be selected - /// - public Type[] FilterTypes - { - get => _filterTypes; - set - { - if (!SetAndNotify(ref _filterTypes, value)) return; - DataModelViewModel?.ApplyTypeFilter(true, FilterTypes); - } - } - - /// - /// Gets a bindable collection of extra data model view models to show - /// - public BindableCollection ExtraDataModelViewModels { get; } - - /// - /// Gets a boolean indicating whether there are any modules providing data models - /// - public bool HasNoModules => (DataModelViewModel == null || !DataModelViewModel.Children.Any()) && !HasExtraDataModels; - - /// - /// Gets a boolean indicating whether there are any extra data models - /// - public bool HasExtraDataModels => ExtraDataModelViewModels.Any(); - - /// - /// Command used by view - /// - public DelegateCommand SelectPropertyCommand { get; } - - /// - /// Setting used by view - /// - public PluginSetting ShowDataModelValues { get; } - - public PluginSetting ShowFullPath { get; } - - /// - /// Gets or sets root the data model view model - /// - public DataModelPropertiesViewModel? DataModelViewModel - { - get => _dataModelViewModel; - private set => SetAndNotify(ref _dataModelViewModel, value); - } - - /// - /// Gets or sets a boolean indicating whether the data model is open - /// - public bool IsDataModelViewModelOpen - { - get => _isDataModelViewModelOpen; - set - { - if (!SetAndNotify(ref _isDataModelViewModelOpen, value)) return; - if (value) - { - UpdateDataModelVisualization(); - if (DataModelViewModel != null) - OpenSelectedValue(DataModelViewModel); - } - } - } - - /// - /// Gets or sets the data model path of the currently selected data model property - /// - public DataModelPath? DataModelPath - { - get => _dataModelPath; - private set - { - if (!SetAndNotify(ref _dataModelPath, value)) return; - NotifyOfPropertyChange(nameof(IsValid)); - NotifyOfPropertyChange(nameof(DisplayValue)); - NotifyOfPropertyChange(nameof(DisplayPath)); - } - } - - /// - /// Gets a boolean indicating whether the current selection is valid - /// - public bool IsValid => DataModelPath?.IsValid ?? true; - - /// - /// Gets the display name of the currently selected property - /// - public string? DisplayValue - { - get - { - if (_showFullPath.Value) - return DisplayPath; - return DataModelPath?.GetPropertyDescription()?.Name ?? DataModelPath?.Segments.LastOrDefault()?.Identifier; - } - } - - /// - /// Gets the human readable path of the currently selected property - /// - public string DisplayPath - { - get - { - if (DataModelPath == null) - return "Click to select a property"; - if (!DataModelPath.IsValid) - return "Invalid path"; - - return string.Join(" › ", DataModelPath.Segments.Where(s => s.GetPropertyDescription()!= null).Select(s => s.GetPropertyDescription()!.Name)); - } - } - - /// - /// Gets or sets a boolean indicating whether event child VMs should be loaded, defaults to - /// - public bool LoadEventChildren { get; set; } = true; - - /// - /// Changes the root data model VM stored in to the provided - /// - /// - /// The data model VM to set the new root data model to - public void ChangeDataModel(DataModelPropertiesViewModel dataModel) - { - if (DataModelViewModel != null) - DataModelViewModel.UpdateRequested -= DataModelOnUpdateRequested; - - DataModelViewModel = dataModel; - - if (DataModelViewModel != null) - DataModelViewModel.UpdateRequested += DataModelOnUpdateRequested; - } - - /// - /// Changes the currently selected property by its path - /// - /// The path of the property to set the selection to - public void ChangeDataModelPath(DataModelPath? dataModelPath) - { - DataModelPath?.Dispose(); - DataModelPath = dataModelPath != null ? new DataModelPath(dataModelPath) : null; - } - - /// - /// Requests switching the input type to static using a - /// - public void SwitchToStatic() - { - ChangeDataModelPath(null); - OnPropertySelected(new DataModelInputDynamicEventArgs(null)); - OnSwitchToStaticRequested(); - } - - private void Initialize() - { - // Get the data models - DataModelViewModel = _dataModelUIService.GetPluginDataModelVisualization(_modules, true); - if (DataModelViewModel != null) - DataModelViewModel.UpdateRequested += DataModelOnUpdateRequested; - ExtraDataModelViewModels.CollectionChanged += ExtraDataModelViewModelsOnCollectionChanged; - _updateTimer.Start(); - _updateTimer.Elapsed += OnUpdateTimerOnElapsed; - _showFullPath.SettingChanged += ShowFullPathOnSettingChanged; - } - - - private void ExecuteSelectPropertyCommand(object? context) - { - if (context is not DataModelVisualizationViewModel selected) - return; - - ChangeDataModelPath(selected.DataModelPath); - OnPropertySelected(new DataModelInputDynamicEventArgs(DataModelPath)); - } - - #region IDisposable - - /// - /// Releases the unmanaged resources used by the object and optionally releases the managed resources. - /// - /// - /// to release both managed and unmanaged resources; - /// to release only unmanaged resources. - /// - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - _updateTimer.Stop(); - _updateTimer.Dispose(); - _updateTimer.Elapsed -= OnUpdateTimerOnElapsed; - _showFullPath.SettingChanged -= ShowFullPathOnSettingChanged; - - DataModelViewModel?.Dispose(); - DataModelPath?.Dispose(); - } - } - - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - #endregion - - #region Event handlers - - private void DataModelOnUpdateRequested(object? sender, EventArgs e) - { - DataModelViewModel?.ApplyTypeFilter(true, FilterTypes); - foreach (DataModelPropertiesViewModel extraDataModelViewModel in ExtraDataModelViewModels) - extraDataModelViewModel.ApplyTypeFilter(true, FilterTypes); - } - - private void ExtraDataModelViewModelsOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) - { - NotifyOfPropertyChange(nameof(HasExtraDataModels)); - } - - private void OnUpdateTimerOnElapsed(object? sender, ElapsedEventArgs e) - { - if (!IsDataModelViewModelOpen) - return; - - UpdateDataModelVisualization(); - } - - private void UpdateDataModelVisualization() - { - DataModelViewModel?.Update(_dataModelUIService, new DataModelUpdateConfiguration(LoadEventChildren)); - foreach (DataModelPropertiesViewModel extraDataModelViewModel in ExtraDataModelViewModels) - extraDataModelViewModel.Update(_dataModelUIService, new DataModelUpdateConfiguration(LoadEventChildren)); - } - - private void OpenSelectedValue(DataModelVisualizationViewModel dataModelPropertiesViewModel) - { - if (DataModelPath == null) - return; - - if (dataModelPropertiesViewModel.Children.Any(c => c.DataModelPath != null && DataModelPath.Path.StartsWith(c.DataModelPath.Path))) - { - dataModelPropertiesViewModel.IsVisualizationExpanded = true; - foreach (DataModelVisualizationViewModel dataModelVisualizationViewModel in dataModelPropertiesViewModel.Children) - { - OpenSelectedValue(dataModelVisualizationViewModel); - } - } - } - - private void ShowFullPathOnSettingChanged(object? sender, EventArgs e) - { - NotifyOfPropertyChange(nameof(DisplayValue)); - } - - #endregion - - #region Events - - /// - /// Occurs when anew property has been selected - /// - public event EventHandler? PropertySelected; - - /// - /// Occurs when a switch to static input has been requested - /// - public event EventHandler? SwitchToStaticRequested; - - /// - /// Invokes the event - /// - /// - protected virtual void OnPropertySelected(DataModelInputDynamicEventArgs e) - { - PropertySelected?.Invoke(this, e); - } - - /// - /// Invokes the event - /// - protected virtual void OnSwitchToStaticRequested() - { - SwitchToStaticRequested?.Invoke(this, EventArgs.Empty); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticView.xaml b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticView.xaml deleted file mode 100644 index a069d383a..000000000 --- a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticView.xaml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticViewModel.cs deleted file mode 100644 index 2ef06ec9a..000000000 --- a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticViewModel.cs +++ /dev/null @@ -1,285 +0,0 @@ -using System; -using System.Linq; -using System.Windows; -using System.Windows.Input; -using System.Windows.Media; -using Artemis.Core; -using Artemis.Core.Modules; -using Artemis.UI.Shared.Services; -using MaterialDesignColors.ColorManipulation; -using Stylet; - -namespace Artemis.UI.Shared.Input -{ - /// - /// Represents a view model that allows inputting a static value used by boolean operations on a certain data model - /// property - /// - public class DataModelStaticViewModel : PropertyChangedBase, IDisposable - { - private readonly IDataModelUIService _dataModelUIService; - private readonly Window? _rootView; - private SolidColorBrush _buttonBrush = new(Color.FromRgb(171, 71, 188)); - private bool _displaySwitchButton; - private DataModelDisplayViewModel? _displayViewModel; - private DataModelInputViewModel? _inputViewModel; - private bool _isEnabled; - private string _placeholder = "Enter a value"; - private DataModelPropertyAttribute _targetDescription; - private Type _targetType; - private object? _value; - - internal DataModelStaticViewModel(Type targetType, DataModelPropertyAttribute targetDescription, IDataModelUIService dataModelUIService) - { - _dataModelUIService = dataModelUIService; - _rootView = Application.Current.Windows.OfType().SingleOrDefault(x => x.IsActive); - - _targetType = targetType; - _targetDescription = targetDescription; - _isEnabled = TargetType != null; - _displayViewModel = _dataModelUIService.GetDataModelDisplayViewModel(TargetType ?? typeof(object), TargetDescription, true); - - if (_rootView != null) - { - _rootView.MouseUp += RootViewOnMouseUp; - _rootView.KeyUp += RootViewOnKeyUp; - } - } - - /// - /// Gets or sets the brush to use for the input button - /// - public SolidColorBrush ButtonBrush - { - get => _buttonBrush; - set - { - if (!SetAndNotify(ref _buttonBrush, value)) return; - NotifyOfPropertyChange(nameof(SwitchButtonBrush)); - } - } - - /// - /// Gets the brush to use for the switch button - /// - public SolidColorBrush SwitchButtonBrush => new(ButtonBrush.Color.Darken()); - - /// - /// Gets the view model used to display the value - /// - public DataModelDisplayViewModel? DisplayViewModel - { - get => _displayViewModel; - private set => SetAndNotify(ref _displayViewModel, value); - } - - /// - /// Gets the view model used to edit the value - /// - public DataModelInputViewModel? InputViewModel - { - get => _inputViewModel; - private set => SetAndNotify(ref _inputViewModel, value); - } - - /// - /// Gets the type of the target property - /// - public Type TargetType - { - get => _targetType; - private set => SetAndNotify(ref _targetType, value); - } - - /// - /// Gets the description of the target property - /// - public DataModelPropertyAttribute TargetDescription - { - get => _targetDescription; - set => SetAndNotify(ref _targetDescription, value); - } - - /// - /// Gets or sets the value of the target - /// - public object? Value - { - get => _value; - set - { - if (!SetAndNotify(ref _value, value)) return; - DisplayViewModel?.UpdateValue(_value); - } - } - - /// - /// Gets or sets the placeholder text when no value is entered - /// - public string Placeholder - { - get => _placeholder; - set => SetAndNotify(ref _placeholder, value); - } - - /// - /// Gets or sets the enabled state of the input - /// - public bool IsEnabled - { - get => _isEnabled; - private set => SetAndNotify(ref _isEnabled, value); - } - - /// - /// Gets or sets whether the switch button should be displayed - /// - public bool DisplaySwitchButton - { - get => _displaySwitchButton; - set => SetAndNotify(ref _displaySwitchButton, value); - } - - /// - /// Activates the input view model - /// - public void ActivateInputViewModel() - { - InputViewModel = _dataModelUIService.GetDataModelInputViewModel( - TargetType, - TargetDescription, - Value, - ApplyFreeInput - ); - } - - /// - /// Updates the target type - /// - /// The new target type - public void UpdateTargetType(Type target) - { - TargetType = target; - DisplayViewModel = _dataModelUIService.GetDataModelDisplayViewModel(TargetType ?? typeof(object), TargetDescription, true); - IsEnabled = TargetType != null; - - // If null, clear the input - if (TargetType == null) - { - ApplyFreeInput(null, true); - return; - } - - // If the type changed, reset to the default type - if (Value == null || !TargetType.IsCastableFrom(Value.GetType())) - // Force the VM to close if it was open and apply the new value - ApplyFreeInput(TargetType.GetDefault(), true); - } - - /// - /// Requests switching the input type to dynamic using a - /// - public void SwitchToDynamic() - { - InputViewModel?.Cancel(); - ApplyFreeInput(TargetType.GetDefault(), true); - - OnSwitchToDynamicRequested(); - } - - private void ApplyFreeInput(object? value, bool submitted) - { - if (submitted) - OnValueUpdated(new DataModelInputStaticEventArgs(value)); - - InputViewModel = null; - Value = value; - } - - #region IDisposable - - /// - /// Releases the unmanaged resources used by the object and optionally releases the managed resources. - /// - /// - /// to release both managed and unmanaged resources; - /// to release only unmanaged resources. - /// - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - if (_rootView != null) - { - _rootView.MouseUp -= RootViewOnMouseUp; - _rootView.KeyUp -= RootViewOnKeyUp; - } - } - } - - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - #endregion - - - #region Event handlers - - private void RootViewOnKeyUp(object sender, KeyEventArgs e) - { - if (InputViewModel == null) - return; - - if (e.Key == Key.Escape) - InputViewModel.Cancel(); - else if (e.Key == Key.Enter) - InputViewModel.Submit(); - } - - private void RootViewOnMouseUp(object sender, MouseButtonEventArgs e) - { - if (InputViewModel == null) - return; - - if (sender is FrameworkElement frameworkElement && !frameworkElement.IsDescendantOf(InputViewModel.View)) - InputViewModel.Submit(); - } - - #endregion - - #region Events - - /// - /// Occurs when the value of the property has been updated - /// - public event EventHandler? ValueUpdated; - - /// - /// Occurs when a switch to dynamic input has been requested - /// - public event EventHandler? SwitchToDynamicRequested; - - /// - /// Invokes the event - /// - /// - protected virtual void OnValueUpdated(DataModelInputStaticEventArgs e) - { - ValueUpdated?.Invoke(this, e); - } - - /// - /// Invokes the event - /// - protected virtual void OnSwitchToDynamicRequested() - { - SwitchToDynamicRequested?.Invoke(this, EventArgs.Empty); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertiesViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertiesViewModel.cs index bbc85258a..d9060f943 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertiesViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertiesViewModel.cs @@ -11,15 +11,12 @@ namespace Artemis.UI.Shared /// public class DataModelListPropertiesViewModel : DataModelPropertiesViewModel { - private readonly ListPredicateWrapperDataModel _listPredicateWrapper; private object? _displayValue; private int _index; private Type? _listType; internal DataModelListPropertiesViewModel(Type listType, string? name) : base(null, null, null) { - _listPredicateWrapper = ListPredicateWrapperDataModel.Create(listType, name); - DataModel = _listPredicateWrapper; ListType = listType; } @@ -61,8 +58,6 @@ namespace Artemis.UI.Shared /// public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration? configuration) { - _listPredicateWrapper.UntypedValue = DisplayValue; - PopulateProperties(dataModelUIService, configuration); if (DisplayViewModel == null) return; diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertyViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertyViewModel.cs index 2e3c7fe32..29bdeb259 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertyViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertyViewModel.cs @@ -10,22 +10,17 @@ namespace Artemis.UI.Shared /// public class DataModelListPropertyViewModel : DataModelPropertyViewModel { - private readonly ListPredicateWrapperDataModel _listPredicateWrapper; private int _index; private Type? _listType; internal DataModelListPropertyViewModel(Type listType, DataModelDisplayViewModel displayViewModel, string? name) : base(null, null, null) { - _listPredicateWrapper = ListPredicateWrapperDataModel.Create(listType, name); - DataModel = _listPredicateWrapper; ListType = listType; DisplayViewModel = displayViewModel; } internal DataModelListPropertyViewModel(Type listType, string? name) : base(null, null, null) { - _listPredicateWrapper = ListPredicateWrapperDataModel.Create(listType, name); - DataModel = _listPredicateWrapper; ListType = listType; } @@ -60,8 +55,6 @@ namespace Artemis.UI.Shared if (DisplayValue == null) return; - _listPredicateWrapper.UntypedValue = DisplayValue; - if (DisplayViewModel == null) DisplayViewModel = dataModelUIService.GetDataModelDisplayViewModel(DisplayValue.GetType(), PropertyDescription, true); diff --git a/src/Artemis.UI.Shared/Events/DataModelInputStaticEventArgs.cs b/src/Artemis.UI.Shared/Events/DataModelInputStaticEventArgs.cs deleted file mode 100644 index 650b558b8..000000000 --- a/src/Artemis.UI.Shared/Events/DataModelInputStaticEventArgs.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using Artemis.UI.Shared.Input; - -namespace Artemis.UI.Shared -{ - /// - /// Provides data about submit events raised by - /// - public class DataModelInputStaticEventArgs : EventArgs - { - internal DataModelInputStaticEventArgs(object? value) - { - Value = value; - } - - /// - /// The value that was submitted - /// - public object? Value { get; } - } -} \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Events/DataModelInputDynamicEventArgs.cs b/src/Artemis.UI.Shared/Events/DataModelSelectedEventArgs.cs similarity index 50% rename from src/Artemis.UI.Shared/Events/DataModelInputDynamicEventArgs.cs rename to src/Artemis.UI.Shared/Events/DataModelSelectedEventArgs.cs index e5a9806de..9306237ed 100644 --- a/src/Artemis.UI.Shared/Events/DataModelInputDynamicEventArgs.cs +++ b/src/Artemis.UI.Shared/Events/DataModelSelectedEventArgs.cs @@ -1,22 +1,22 @@ using System; using Artemis.Core; -using Artemis.UI.Shared.Input; +using Artemis.UI.Shared.Controls; namespace Artemis.UI.Shared { /// - /// Provides data about selection events raised by + /// Provides data about selection events raised by /// - public class DataModelInputDynamicEventArgs : EventArgs + public class DataModelSelectedEventArgs : EventArgs { - internal DataModelInputDynamicEventArgs(DataModelPath? dataModelPath) - { - DataModelPath = dataModelPath; - } - /// /// Gets the data model path that was selected /// - public DataModelPath? DataModelPath { get; } + public DataModelPath? Path { get; } + + internal DataModelSelectedEventArgs(DataModelPath? path) + { + Path = path; + } } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Extensions/DataModelWrapperExtensions.cs b/src/Artemis.UI.Shared/Extensions/DataModelWrapperExtensions.cs deleted file mode 100644 index d21024543..000000000 --- a/src/Artemis.UI.Shared/Extensions/DataModelWrapperExtensions.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.Linq; -using Artemis.Core; -using Artemis.UI.Shared.Services; - -namespace Artemis.UI.Shared -{ - /// - /// Provides extensions for special data model wrappers used by events and list conditions - /// - public static class DataModelWrapperExtensions - { - /// - /// Creates a view model for a - /// - /// The wrapper to create the view model for - /// The data model UI service to be used by the view model - /// The update configuration to be used by the view model - /// The created view model - public static DataModelPropertiesViewModel CreateViewModel(this EventPredicateWrapperDataModel wrapper, IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration) - { - DataModelPropertiesViewModel viewModel = new(wrapper, null, new DataModelPath(wrapper)); - viewModel.Update(dataModelUIService, configuration); - viewModel.UpdateRequested += (sender, args) => viewModel.Update(dataModelUIService, configuration); - viewModel.Children.First().IsVisualizationExpanded = true; - - return viewModel; - } - - /// - /// Creates a view model for a - /// - /// The wrapper to create the view model for - /// The data model UI service to be used by the view model - /// The update configuration to be used by the view model - /// The created view model - public static DataModelPropertiesViewModel CreateViewModel(this ListPredicateWrapperDataModel wrapper, IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration) - { - DataModelPropertiesViewModel viewModel = new(wrapper, null, new DataModelPath(wrapper)); - viewModel.Update(dataModelUIService, configuration); - viewModel.UpdateRequested += (sender, args) => viewModel.Update(dataModelUIService, configuration); - viewModel.Children.First().IsVisualizationExpanded = true; - - return viewModel; - } - } -} \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Ninject/Factories/ISharedVMFactory.cs b/src/Artemis.UI.Shared/Ninject/Factories/ISharedVMFactory.cs index 21cce1e60..228b34c6e 100644 --- a/src/Artemis.UI.Shared/Ninject/Factories/ISharedVMFactory.cs +++ b/src/Artemis.UI.Shared/Ninject/Factories/ISharedVMFactory.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using Artemis.Core.Modules; -using Artemis.UI.Shared.Input; - -namespace Artemis.UI.Shared +namespace Artemis.UI.Shared { /// /// Represents a factory for view models provided by the Artemis Shared UI library @@ -11,25 +6,4 @@ namespace Artemis.UI.Shared public interface ISharedVmFactory { } - - /// - /// A factory that allows the creation of data model view models - /// - public interface IDataModelVmFactory : ISharedVmFactory - { - /// - /// Creates a new instance of the class - /// - /// The modules to associate the dynamic view model with - /// A new instance of the class - DataModelDynamicViewModel DataModelDynamicViewModel(List modules); - - /// - /// Creates a new instance of the class - /// - /// The type of property that is expected in this input - /// The description of the property that this input is for - /// A new instance of the class - DataModelStaticViewModel DataModelStaticViewModel(Type targetType, DataModelPropertyAttribute targetDescription); - } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Services/DataModelUIService.cs b/src/Artemis.UI.Shared/Services/DataModelUIService.cs index dc8e5ca7e..db4c0d8bd 100644 --- a/src/Artemis.UI.Shared/Services/DataModelUIService.cs +++ b/src/Artemis.UI.Shared/Services/DataModelUIService.cs @@ -5,7 +5,6 @@ using Artemis.Core; using Artemis.Core.Modules; using Artemis.Core.Services; using Artemis.UI.Shared.DefaultTypes.DataModel.Display; -using Artemis.UI.Shared.Input; using Ninject; using Ninject.Parameters; @@ -14,15 +13,13 @@ namespace Artemis.UI.Shared.Services internal class DataModelUIService : IDataModelUIService { private readonly IDataModelService _dataModelService; - private readonly IDataModelVmFactory _dataModelVmFactory; private readonly IKernel _kernel; private readonly List _registeredDataModelDisplays; private readonly List _registeredDataModelEditors; - public DataModelUIService(IDataModelService dataModelService, IDataModelVmFactory dataModelVmFactory, IKernel kernel) + public DataModelUIService(IDataModelService dataModelService, IKernel kernel) { _dataModelService = dataModelService; - _dataModelVmFactory = dataModelVmFactory; _kernel = kernel; _registeredDataModelEditors = new List(); _registeredDataModelDisplays = new List(); @@ -223,22 +220,7 @@ namespace Artemis.UI.Shared.Services return null; } } - - public DataModelDynamicViewModel GetDynamicSelectionViewModel(Module? module) - { - return _dataModelVmFactory.DataModelDynamicViewModel(module == null ? new List() : new List {module}); - } - - public DataModelDynamicViewModel GetDynamicSelectionViewModel(List modules) - { - return _dataModelVmFactory.DataModelDynamicViewModel(modules); - } - - public DataModelStaticViewModel GetStaticInputViewModel(Type targetType, DataModelPropertyAttribute targetDescription) - { - return _dataModelVmFactory.DataModelStaticViewModel(targetType, targetDescription); - } - + private DataModelInputViewModel InstantiateDataModelInputViewModel(DataModelVisualizationRegistration registration, DataModelPropertyAttribute? description, object? initialValue) { // This assumes the type can be converted, that has been checked when the VM was created diff --git a/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs b/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs index 2c3f6efdb..962da118d 100644 --- a/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs +++ b/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using Artemis.Core; using Artemis.Core.Modules; -using Artemis.UI.Shared.Input; namespace Artemis.UI.Shared.Services { @@ -103,27 +102,5 @@ namespace Artemis.UI.Shared.Services /// A function to call whenever the input was updated (submitted or not) /// The most appropriate input view model for the provided DataModelInputViewModel? GetDataModelInputViewModel(Type propertyType, DataModelPropertyAttribute? description, object? initialValue, Action updateCallback); - - /// - /// Creates a view model that allows selecting a value from the data model - /// - /// An extra non-always active module to include - /// - DataModelDynamicViewModel GetDynamicSelectionViewModel(Module? module); - - /// - /// Creates a view model that allows selecting a value from the data model - /// - /// A list of extra extra non-always active modules to include - /// A view model that allows selecting a value from the data model - DataModelDynamicViewModel GetDynamicSelectionViewModel(List modules); - - /// - /// Creates a view model that allows entering a value matching the target data model type - /// - /// The type of data model property to allow input for - /// The description of the target data model property - /// A view model that allows entering a value matching the target data model type - DataModelStaticViewModel GetStaticInputViewModel(Type targetType, DataModelPropertyAttribute targetDescription); } } \ No newline at end of file diff --git a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs index 375efa7f4..7d1c85aa3 100644 --- a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs +++ b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs @@ -1,15 +1,10 @@ -using System.Collections.Generic; -using Artemis.Core; +using Artemis.Core; using Artemis.Core.Modules; using Artemis.Core.ScriptingProviders; using Artemis.UI.Screens.Header; using Artemis.UI.Screens.Plugins; -using Artemis.UI.Screens.ProfileEditor.Conditions; -using Artemis.UI.Screens.ProfileEditor.DisplayConditions; using Artemis.UI.Screens.ProfileEditor.LayerProperties; using Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings; -using Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.ConditionalDataBinding; -using Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding; using Artemis.UI.Screens.ProfileEditor.LayerProperties.LayerEffects; using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline; using Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree; @@ -83,16 +78,6 @@ namespace Artemis.UI.Ninject.Factories SelectionRemoveToolViewModel SelectionRemoveToolViewModel(PanZoomViewModel panZoomViewModel); } - public interface IDataModelConditionsVmFactory : IVmFactory - { - DataModelConditionGroupViewModel DataModelConditionGroupViewModel(DataModelConditionGroup dataModelConditionGroup, ConditionGroupType groupType, List modules); - DataModelConditionListViewModel DataModelConditionListViewModel(DataModelConditionList dataModelConditionList, List modules); - DataModelConditionEventViewModel DataModelConditionEventViewModel(DataModelConditionEvent dataModelConditionEvent, List modules); - DataModelConditionGeneralPredicateViewModel DataModelConditionGeneralPredicateViewModel(DataModelConditionGeneralPredicate dataModelConditionGeneralPredicate, List modules); - DataModelConditionListPredicateViewModel DataModelConditionListPredicateViewModel(DataModelConditionListPredicate dataModelConditionListPredicate, List modules); - DataModelConditionEventPredicateViewModel DataModelConditionEventPredicateViewModel(DataModelConditionEventPredicate dataModelConditionEventPredicate, List modules); - } - public interface ILayerPropertyVmFactory : IVmFactory { LayerPropertyViewModel LayerPropertyViewModel(ILayerProperty layerProperty); @@ -131,17 +116,9 @@ namespace Artemis.UI.Ninject.Factories NodeScriptWindowViewModel NodeScriptWindowViewModel(NodeScript nodeScript); } - // TODO: Move these two public interface IDataBindingsVmFactory { IDataBindingViewModel DataBindingViewModel(IDataBindingRegistration registration); - DirectDataBindingModeViewModel DirectDataBindingModeViewModel(DirectDataBinding directDataBinding); - DataBindingModifierViewModel DataBindingModifierViewModel(DataBindingModifier modifier); - - ConditionalDataBindingModeViewModel ConditionalDataBindingModeViewModel( - ConditionalDataBinding conditionalDataBinding); - - DataBindingConditionViewModel DataBindingConditionViewModel(DataBindingCondition dataBindingCondition); } public interface IPropertyVmFactory diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionPredicateViewModel.cs deleted file mode 100644 index 9995cd02f..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionPredicateViewModel.cs +++ /dev/null @@ -1,337 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows; -using System.Windows.Media; -using Artemis.Core; -using Artemis.Core.Modules; -using Artemis.Core.Services; -using Artemis.UI.Shared; -using Artemis.UI.Shared.Input; -using Artemis.UI.Shared.Services; -using Stylet; - -namespace Artemis.UI.Screens.ProfileEditor.Conditions.Abstract -{ - public abstract class DataModelConditionPredicateViewModel : DataModelConditionViewModel, IDisposable - { - private readonly IConditionOperatorService _conditionOperatorService; - private readonly IDataModelUIService _dataModelUIService; - private readonly List _modules; - private readonly IProfileEditorService _profileEditorService; - private DataModelStaticViewModel _rightSideInputViewModel; - private DataModelDynamicViewModel _rightSideSelectionViewModel; - private BaseConditionOperator _selectedOperator; - - private List _supportedInputTypes; - - protected DataModelConditionPredicateViewModel( - DataModelConditionPredicate dataModelConditionPredicate, - List modules, - IProfileEditorService profileEditorService, - IDataModelUIService dataModelUIService, - IConditionOperatorService conditionOperatorService, - ISettingsService settingsService) : base(dataModelConditionPredicate) - { - _modules = modules; - _profileEditorService = profileEditorService; - _dataModelUIService = dataModelUIService; - _conditionOperatorService = conditionOperatorService; - _supportedInputTypes = new List(); - - SelectOperatorCommand = new DelegateCommand(ExecuteSelectOperatorCommand); - Operators = new BindableCollection(); - - ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues"); - } - - public DataModelConditionPredicate DataModelConditionPredicate => (DataModelConditionPredicate) Model; - public PluginSetting ShowDataModelValues { get; } - - public bool CanSelectOperator => DataModelConditionPredicate.LeftPath is {IsValid: true}; - - public BaseConditionOperator SelectedOperator - { - get => _selectedOperator; - set => SetAndNotify(ref _selectedOperator, value); - } - - public DataModelDynamicViewModel RightSideSelectionViewModel - { - get => _rightSideSelectionViewModel; - set => SetAndNotify(ref _rightSideSelectionViewModel, value); - } - - public DataModelStaticViewModel RightSideInputViewModel - { - get => _rightSideInputViewModel; - set => SetAndNotify(ref _rightSideInputViewModel, value); - } - - public DelegateCommand SelectOperatorCommand { get; } - public BindableCollection Operators { get; } - - protected SolidColorBrush LeftSideColor { get; set; } - - public override void Evaluate() - { - IsConditionMet = DataModelConditionPredicate.Evaluate(); - } - - public override void Delete() - { - base.Delete(); - _profileEditorService.SaveSelectedProfileElement(); - } - - public virtual void Initialize() - { - LeftSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_modules); - LeftSideSelectionViewModel.PropertySelected += LeftSideOnPropertySelected; - if (LeftSideColor != null) - LeftSideSelectionViewModel.ButtonBrush = LeftSideColor; - - // Determine which types are currently supported - _supportedInputTypes = GetSupportedInputTypes(); - - Update(); - } - - public override void Update() - { - LeftSideSelectionViewModel.FilterTypes = _supportedInputTypes.ToArray(); - LeftSideSelectionViewModel.ChangeDataModelPath(DataModelConditionPredicate.LeftPath); - - Type leftSideType = GetLeftSideType(); - - // Get the supported operators - Operators.Clear(); - Operators.AddRange(_conditionOperatorService.GetConditionOperatorsForType(leftSideType ?? typeof(object), ConditionParameterSide.Left)); - if (DataModelConditionPredicate.Operator == null) - DataModelConditionPredicate.UpdateOperator(Operators.FirstOrDefault()); - // The core doesn't care about best matches so if there is a new preferred operator, use that instead - else if (!Operators.Contains(DataModelConditionPredicate.Operator)) - DataModelConditionPredicate.UpdateOperator(Operators.FirstOrDefault(o => o.Description == DataModelConditionPredicate.Operator.Description) ?? Operators.FirstOrDefault()); - - NotifyOfPropertyChange(nameof(CanSelectOperator)); - SelectedOperator = DataModelConditionPredicate.Operator; - - // Without a selected operator or one that supports a right side, leave the right side input empty - if (SelectedOperator?.RightSideType == null) - { - DisposeRightSideStaticViewModel(); - DisposeRightSideDynamicViewModel(); - return; - } - - // Ensure the right side has the proper VM - if (DataModelConditionPredicate.PredicateType == ProfileRightSideType.Dynamic) - { - DisposeRightSideStaticViewModel(); - if (RightSideSelectionViewModel == null) - CreateRightSideSelectionViewModel(); - - RightSideSelectionViewModel.ChangeDataModelPath(DataModelConditionPredicate.RightPath); - RightSideSelectionViewModel.FilterTypes = new[] {SelectedOperator.RightSideType}; - } - else - { - DisposeRightSideDynamicViewModel(); - if (RightSideInputViewModel == null) - CreateRightSideInputViewModel(); - - Type preferredType = DataModelConditionPredicate.GetPreferredRightSideType(); - if (preferredType != null && RightSideInputViewModel.TargetType != preferredType) - RightSideInputViewModel.UpdateTargetType(preferredType); - - RightSideInputViewModel.Value = DataModelConditionPredicate.RightStaticValue; - } - } - - public void ApplyLeftSide() - { - Type newType = LeftSideSelectionViewModel.DataModelPath.GetPropertyType(); - bool converted = ConvertIfRequired(newType); - if (converted) - return; - - DataModelConditionPredicate.UpdateLeftSide(LeftSideSelectionViewModel.DataModelPath); - _profileEditorService.SaveSelectedProfileElement(); - - SelectedOperator = DataModelConditionPredicate.Operator; - Update(); - } - - public void ApplyRightSideDynamic() - { - DataModelConditionPredicate.UpdateRightSideDynamic(RightSideSelectionViewModel.DataModelPath); - _profileEditorService.SaveSelectedProfileElement(); - - Update(); - } - - public void ApplyRightSideStatic(object value) - { - DataModelConditionPredicate.UpdateRightSideStatic(value); - _profileEditorService.SaveSelectedProfileElement(); - - Update(); - } - - public void ApplyOperator() - { - DataModelConditionPredicate.UpdateOperator(SelectedOperator); - _profileEditorService.SaveSelectedProfileElement(); - - Update(); - } - - protected abstract List GetSupportedInputTypes(); - protected abstract Type GetLeftSideType(); - - protected virtual List GetExtraRightSideDataModelViewModels() - { - return null; - } - - private void ExecuteSelectOperatorCommand(object context) - { - if (!(context is BaseConditionOperator dataModelConditionOperator)) - return; - - SelectedOperator = dataModelConditionOperator; - ApplyOperator(); - } - - public override void UpdateModules() - { - if (LeftSideSelectionViewModel != null) - { - LeftSideSelectionViewModel.PropertySelected -= LeftSideOnPropertySelected; - LeftSideSelectionViewModel.Dispose(); - LeftSideSelectionViewModel = null; - } - DisposeRightSideStaticViewModel(); - DisposeRightSideDynamicViewModel(); - - // If the modules changed the paths may no longer be valid if they targeted a module no longer available, in that case clear the path - if (DataModelConditionPredicate.LeftPath?.Target != null && !DataModelConditionPredicate.LeftPath.Target.IsExpansion && !_modules.Contains(DataModelConditionPredicate.LeftPath.Target.Module)) - DataModelConditionPredicate.UpdateLeftSide(null); - if (DataModelConditionPredicate.RightPath?.Target != null && !DataModelConditionPredicate.RightPath.Target.IsExpansion && !_modules.Contains(DataModelConditionPredicate.RightPath.Target.Module)) - DataModelConditionPredicate.UpdateRightSideDynamic(null); - - Initialize(); - } - - #region IDisposable - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - if (LeftSideSelectionViewModel != null) - { - LeftSideSelectionViewModel.PropertySelected -= LeftSideOnPropertySelected; - LeftSideSelectionViewModel.Dispose(); - LeftSideSelectionViewModel = null; - } - - DisposeRightSideStaticViewModel(); - DisposeRightSideDynamicViewModel(); - } - } - - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - #endregion - - #region View model creation - - private void CreateRightSideSelectionViewModel() - { - RightSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_modules); - RightSideSelectionViewModel.ButtonBrush = (SolidColorBrush) Application.Current.FindResource("PrimaryHueMidBrush"); - RightSideSelectionViewModel.DisplaySwitchButton = true; - RightSideSelectionViewModel.PropertySelected += RightSideOnPropertySelected; - RightSideSelectionViewModel.SwitchToStaticRequested += RightSideSelectionViewModelOnSwitchToStaticRequested; - - List extra = GetExtraRightSideDataModelViewModels(); - if (extra != null) - RightSideSelectionViewModel.ExtraDataModelViewModels.AddRange(extra); - } - - private void CreateRightSideInputViewModel() - { - Type preferredType = DataModelConditionPredicate.GetPreferredRightSideType(); - RightSideInputViewModel = _dataModelUIService.GetStaticInputViewModel(preferredType, LeftSideSelectionViewModel.DataModelPath?.GetPropertyDescription()); - RightSideInputViewModel.ButtonBrush = (SolidColorBrush) Application.Current.FindResource("PrimaryHueMidBrush"); - RightSideInputViewModel.DisplaySwitchButton = true; - RightSideInputViewModel.ValueUpdated += RightSideOnValueEntered; - RightSideInputViewModel.SwitchToDynamicRequested += RightSideInputViewModelOnSwitchToDynamicRequested; - } - - private void DisposeRightSideStaticViewModel() - { - if (RightSideInputViewModel == null) - return; - RightSideInputViewModel.ValueUpdated -= RightSideOnValueEntered; - RightSideInputViewModel.SwitchToDynamicRequested -= RightSideInputViewModelOnSwitchToDynamicRequested; - RightSideInputViewModel.Dispose(); - RightSideInputViewModel = null; - } - - private void DisposeRightSideDynamicViewModel() - { - if (RightSideSelectionViewModel == null) - return; - RightSideSelectionViewModel.PropertySelected -= RightSideOnPropertySelected; - RightSideSelectionViewModel.SwitchToStaticRequested -= RightSideSelectionViewModelOnSwitchToStaticRequested; - RightSideSelectionViewModel.Dispose(); - RightSideSelectionViewModel = null; - } - - #endregion - - #region Event handlers - - private void LeftSideOnPropertySelected(object sender, DataModelInputDynamicEventArgs e) - { - ApplyLeftSide(); - } - - private void RightSideOnPropertySelected(object sender, DataModelInputDynamicEventArgs e) - { - ApplyRightSideDynamic(); - } - - private void RightSideOnValueEntered(object sender, DataModelInputStaticEventArgs e) - { - ApplyRightSideStatic(e.Value); - } - - private void RightSideSelectionViewModelOnSwitchToStaticRequested(object sender, EventArgs e) - { - DataModelConditionPredicate.PredicateType = ProfileRightSideType.Static; - - // Ensure the right static value is never null when the preferred type is a value type - Type preferredType = DataModelConditionPredicate.GetPreferredRightSideType(); - if (DataModelConditionPredicate.RightStaticValue == null && preferredType != null && preferredType.IsValueType) - DataModelConditionPredicate.UpdateRightSideStatic(preferredType.GetDefault()); - - Update(); - } - - private void RightSideInputViewModelOnSwitchToDynamicRequested(object sender, EventArgs e) - { - DataModelConditionPredicate.PredicateType = ProfileRightSideType.Dynamic; - Update(); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionViewModel.cs deleted file mode 100644 index 9f7db7a2d..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionViewModel.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using Artemis.Core; -using Artemis.UI.Shared.Input; -using Stylet; - -namespace Artemis.UI.Screens.ProfileEditor.Conditions.Abstract -{ - public abstract class DataModelConditionViewModel : Conductor.Collection.AllActive - { - private DataModelDynamicViewModel _leftSideSelectionViewModel; - private bool _isConditionMet; - - protected DataModelConditionViewModel(DataModelConditionPart model) - { - Model = model; - } - - public DataModelConditionPart Model { get; } - - public DataModelDynamicViewModel LeftSideSelectionViewModel - { - get => _leftSideSelectionViewModel; - set => SetAndNotify(ref _leftSideSelectionViewModel, value); - } - - public bool IsConditionMet - { - get => _isConditionMet; - set => SetAndNotify(ref _isConditionMet, value); - } - - - public abstract void Update(); - - public abstract void Evaluate(); - - public virtual void Delete() - { - Model.Parent.RemoveChild(Model); - ((DataModelConditionViewModel) Parent).Update(); - } - - protected bool ConvertIfRequired(Type newType) - { - if (newType == null) - return false; - - if (!(Parent is DataModelConditionGroupViewModel groupViewModel)) - return false; - - // List - if (newType.IsGenericEnumerable()) - { - if (this is DataModelConditionListViewModel) - return false; - groupViewModel.ConvertToConditionList(this); - return true; - } - - // Predicate - if (this is DataModelConditionPredicateViewModel) - return false; - groupViewModel.ConvertToPredicate(this); - return true; - } - - public abstract void UpdateModules(); - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventView.xaml deleted file mode 100644 index 0c93f64b5..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventView.xaml +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventViewModel.cs deleted file mode 100644 index d50edbbc9..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventViewModel.cs +++ /dev/null @@ -1,147 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows.Media; -using Artemis.Core; -using Artemis.Core.Modules; -using Artemis.UI.Ninject.Factories; -using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract; -using Artemis.UI.Shared; -using Artemis.UI.Shared.Services; - -namespace Artemis.UI.Screens.ProfileEditor.Conditions -{ - public sealed class DataModelConditionEventViewModel : DataModelConditionViewModel, IDisposable - { - private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory; - private readonly IDataModelUIService _dataModelUIService; - private readonly List _modules; - private readonly IProfileEditorService _profileEditorService; - private DateTime _lastTrigger; - private string _triggerPastParticiple; - - public DataModelConditionEventViewModel(DataModelConditionEvent dataModelConditionEvent, - List modules, - IProfileEditorService profileEditorService, - IDataModelUIService dataModelUIService, - IDataModelConditionsVmFactory dataModelConditionsVmFactory) : base(dataModelConditionEvent) - { - _modules = modules; - _profileEditorService = profileEditorService; - _dataModelUIService = dataModelUIService; - _dataModelConditionsVmFactory = dataModelConditionsVmFactory; - - _lastTrigger = DataModelConditionEvent.LastTrigger; - } - - public DataModelConditionEvent DataModelConditionEvent => (DataModelConditionEvent) Model; - - public DateTime LastTrigger - { - get => _lastTrigger; - set => SetAndNotify(ref _lastTrigger, value); - } - - public string TriggerPastParticiple - { - get => _triggerPastParticiple; - set => SetAndNotify(ref _triggerPastParticiple, value); - } - - public void Initialize() - { - LeftSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_modules); - LeftSideSelectionViewModel.PropertySelected += LeftSideSelectionViewModelOnPropertySelected; - LeftSideSelectionViewModel.LoadEventChildren = false; - - IReadOnlyCollection editors = _dataModelUIService.RegisteredDataModelEditors; - List supportedInputTypes = editors.Select(e => e.SupportedType).ToList(); - supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes)); - supportedInputTypes.Add(typeof(DataModelEvent)); - supportedInputTypes.Add(typeof(DataModelEvent<>)); - - LeftSideSelectionViewModel.FilterTypes = supportedInputTypes.ToArray(); - LeftSideSelectionViewModel.ButtonBrush = new SolidColorBrush(Color.FromRgb(185, 164, 10)); - LeftSideSelectionViewModel.Placeholder = "Select an event"; - - Update(); - } - - public override void Update() - { - LeftSideSelectionViewModel.ChangeDataModelPath(DataModelConditionEvent.EventPath); - - // Remove VMs of effects no longer applied on the layer - Items.RemoveRange(Items.Where(c => !DataModelConditionEvent.Children.Contains(c.Model)).ToList()); - - if (DataModelConditionEvent.EventPath == null || !DataModelConditionEvent.EventPath.IsValid) - return; - - TriggerPastParticiple = DataModelConditionEvent.GetDataModelEvent()?.TriggerPastParticiple; - List viewModels = new(); - foreach (DataModelConditionPart childModel in Model.Children) - { - if (Items.Any(c => c.Model == childModel)) - continue; - if (!(childModel is DataModelConditionGroup dataModelConditionGroup)) - continue; - - DataModelConditionGroupViewModel viewModel = _dataModelConditionsVmFactory.DataModelConditionGroupViewModel(dataModelConditionGroup, ConditionGroupType.Event, _modules); - viewModel.IsRootGroup = true; - viewModels.Add(viewModel); - } - - if (viewModels.Any()) - Items.AddRange(viewModels); - - foreach (DataModelConditionViewModel childViewModel in Items) - childViewModel.Update(); - } - - public override void Evaluate() - { - LastTrigger = DataModelConditionEvent.LastTrigger; - IsConditionMet = DataModelConditionEvent.Evaluate(); - } - - public void ApplyEvent() - { - DataModelConditionEvent.UpdateEvent(LeftSideSelectionViewModel.DataModelPath); - _profileEditorService.SaveSelectedProfileElement(); - - Update(); - } - - public override void UpdateModules() - { - LeftSideSelectionViewModel.Dispose(); - LeftSideSelectionViewModel.PropertySelected -= LeftSideSelectionViewModelOnPropertySelected; - Initialize(); - } - - protected override void OnInitialActivate() - { - Initialize(); - base.OnInitialActivate(); - } - - #region Event handlers - - private void LeftSideSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e) - { - ApplyEvent(); - } - - #endregion - - #region IDisposable - - public void Dispose() - { - LeftSideSelectionViewModel.Dispose(); - LeftSideSelectionViewModel.PropertySelected -= LeftSideSelectionViewModelOnPropertySelected; - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupView.xaml deleted file mode 100644 index 7afa0ef9a..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupView.xaml +++ /dev/null @@ -1,165 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs deleted file mode 100644 index 6b0e8c1ab..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs +++ /dev/null @@ -1,259 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Artemis.Core; -using Artemis.Core.Modules; -using Artemis.Core.Services; -using Artemis.UI.Extensions; -using Artemis.UI.Ninject.Factories; -using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract; -using Artemis.UI.Shared.Services; -using Humanizer; -using Stylet; - -namespace Artemis.UI.Screens.ProfileEditor.Conditions -{ - public class DataModelConditionGroupViewModel : DataModelConditionViewModel - { - private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory; - private readonly List _modules; - private readonly ICoreService _coreService; - private readonly IProfileEditorService _profileEditorService; - private bool _isEventGroup; - private bool _isRootGroup; - - public DataModelConditionGroupViewModel(DataModelConditionGroup dataModelConditionGroup, - ConditionGroupType groupType, - List modules, - ICoreService coreService, - IProfileEditorService profileEditorService, - IDataModelConditionsVmFactory dataModelConditionsVmFactory) - : base(dataModelConditionGroup) - { - GroupType = groupType; - _modules = modules; - _coreService = coreService; - _profileEditorService = profileEditorService; - _dataModelConditionsVmFactory = dataModelConditionsVmFactory; - - Items.CollectionChanged += (_, _) => NotifyOfPropertyChange(nameof(DisplayBooleanOperator)); - } - - public ConditionGroupType GroupType { get; } - public DataModelConditionGroup DataModelConditionGroup => (DataModelConditionGroup) Model; - - public bool IsRootGroup - { - get => _isRootGroup; - set - { - if (!SetAndNotify(ref _isRootGroup, value)) return; - NotifyOfPropertyChange(nameof(CanAddEventCondition)); - } - } - - public bool CanAddEventCondition => IsRootGroup && GroupType == ConditionGroupType.General; - - public bool IsEventGroup - { - get => _isEventGroup; - set - { - SetAndNotify(ref _isEventGroup, value); - NotifyOfPropertyChange(nameof(DisplayEvaluationResult)); - } - } - - public bool DisplayBooleanOperator => Items.Count > 1; - public bool DisplayEvaluationResult => GroupType == ConditionGroupType.General && !IsEventGroup; - public string SelectedBooleanOperator => DataModelConditionGroup.BooleanOperator.Humanize(); - - public void SelectBooleanOperator(string type) - { - BooleanOperator enumValue = Enum.Parse(type); - DataModelConditionGroup.BooleanOperator = enumValue; - NotifyOfPropertyChange(nameof(SelectedBooleanOperator)); - - _profileEditorService.SaveSelectedProfileElement(); - } - - public void AddCondition() - { - switch (GroupType) - { - case ConditionGroupType.General: - DataModelConditionGroup.AddChild(new DataModelConditionGeneralPredicate(DataModelConditionGroup, ProfileRightSideType.Dynamic)); - break; - case ConditionGroupType.List: - DataModelConditionGroup.AddChild(new DataModelConditionListPredicate(DataModelConditionGroup, ProfileRightSideType.Dynamic)); - break; - case ConditionGroupType.Event: - DataModelConditionGroup.AddChild(new DataModelConditionEventPredicate(DataModelConditionGroup, ProfileRightSideType.Dynamic)); - break; - default: - throw new ArgumentOutOfRangeException(); - } - - Update(); - _profileEditorService.SaveSelectedProfileElement(); - } - - public void AddEventCondition() - { - if (!CanAddEventCondition) - return; - - // Find a good spot for the event, behind the last existing event - int index = 0; - DataModelConditionPart existing = DataModelConditionGroup.Children.LastOrDefault(c => c is DataModelConditionEvent); - if (existing != null) - index = DataModelConditionGroup.Children.IndexOf(existing) + 1; - - DataModelConditionGroup.AddChild(new DataModelConditionEvent(DataModelConditionGroup), index); - - Update(); - _profileEditorService.SaveSelectedProfileElement(); - } - - public void AddGroup() - { - DataModelConditionGroup.AddChild(new DataModelConditionGroup(DataModelConditionGroup)); - - Update(); - _profileEditorService.SaveSelectedProfileElement(); - } - - public override void Update() - { - NotifyOfPropertyChange(nameof(SelectedBooleanOperator)); - // Remove VMs of effects no longer applied on the layer - List toRemove = Items.Where(c => !DataModelConditionGroup.Children.Contains(c.Model)).ToList(); - if (toRemove.Any()) - Items.RemoveRange(toRemove); - - foreach (DataModelConditionPart childModel in Model.Children) - { - if (Items.Any(c => c.Model == childModel)) - continue; - - switch (childModel) - { - case DataModelConditionGroup dataModelConditionGroup: - Items.Add(_dataModelConditionsVmFactory.DataModelConditionGroupViewModel(dataModelConditionGroup, GroupType, _modules)); - break; - case DataModelConditionList dataModelConditionList: - Items.Add(_dataModelConditionsVmFactory.DataModelConditionListViewModel(dataModelConditionList, _modules)); - break; - case DataModelConditionEvent dataModelConditionEvent: - Items.Add(_dataModelConditionsVmFactory.DataModelConditionEventViewModel(dataModelConditionEvent, _modules)); - break; - case DataModelConditionGeneralPredicate dataModelConditionGeneralPredicate: - Items.Add(_dataModelConditionsVmFactory.DataModelConditionGeneralPredicateViewModel(dataModelConditionGeneralPredicate, _modules)); - break; - case DataModelConditionListPredicate dataModelConditionListPredicate: - Items.Add(_dataModelConditionsVmFactory.DataModelConditionListPredicateViewModel(dataModelConditionListPredicate, _modules)); - break; - case DataModelConditionEventPredicate dataModelConditionEventPredicate: - Items.Add(_dataModelConditionsVmFactory.DataModelConditionEventPredicateViewModel(dataModelConditionEventPredicate, _modules)); - break; - } - } - - // Ensure the items are in the same order as on the model - ((BindableCollection) Items).Sort(i => Model.Children.IndexOf(i.Model)); - foreach (DataModelConditionViewModel childViewModel in Items) - childViewModel.Update(); - - IsEventGroup = Items.Any(i => i is DataModelConditionEventViewModel); - if (IsEventGroup) - { - if (DataModelConditionGroup.BooleanOperator != BooleanOperator.And) - SelectBooleanOperator("And"); - } - - OnUpdated(); - } - - public override void Evaluate() - { - IsConditionMet = DataModelConditionGroup.Evaluate(); - foreach (DataModelConditionViewModel dataModelConditionViewModel in Items) - dataModelConditionViewModel.Evaluate(); - } - - public override void UpdateModules() - { - foreach (DataModelConditionViewModel dataModelConditionViewModel in Items) - dataModelConditionViewModel.UpdateModules(); - } - - public void ConvertToConditionList(DataModelConditionViewModel predicateViewModel) - { - // Store the old index and remove the old predicate - int index = DataModelConditionGroup.Children.IndexOf(predicateViewModel.Model); - DataModelConditionGroup.RemoveChild(predicateViewModel.Model); - - // Insert a list in the same position - DataModelConditionList list = new(DataModelConditionGroup); - list.UpdateList(predicateViewModel.LeftSideSelectionViewModel.DataModelPath); - DataModelConditionGroup.AddChild(list, index); - - // Update to switch the VMs - Update(); - } - - public void ConvertToPredicate(DataModelConditionViewModel listViewModel) - { - // Store the old index and remove the old predicate - int index = DataModelConditionGroup.Children.IndexOf(listViewModel.Model); - DataModelConditionGroup.RemoveChild(listViewModel.Model); - - // Insert a list in the same position - DataModelConditionGeneralPredicate predicate = new(DataModelConditionGroup, ProfileRightSideType.Dynamic); - predicate.UpdateLeftSide(listViewModel.LeftSideSelectionViewModel.DataModelPath); - DataModelConditionGroup.AddChild(predicate, index); - - // Update to switch the VMs - Update(); - } - - private void CoreServiceOnFrameRendered(object sender, FrameRenderedEventArgs e) - { - if (IsRootGroup) - Evaluate(); - } - - public event EventHandler Updated; - - #region Overrides of Screen - - /// - protected override void OnInitialActivate() - { - base.OnInitialActivate(); - Update(); - _coreService.FrameRendered += CoreServiceOnFrameRendered; - } - - /// - protected override void OnClose() - { - _coreService.FrameRendered -= CoreServiceOnFrameRendered; - base.OnClose(); - } - - #endregion - - protected virtual void OnUpdated() - { - Updated?.Invoke(this, EventArgs.Empty); - } - } - - public enum ConditionGroupType - { - General, - List, - Event - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml deleted file mode 100644 index ac405354f..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml.cs deleted file mode 100644 index 23a1fe9e6..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Windows; -using System.Windows.Controls; - -namespace Artemis.UI.Screens.ProfileEditor.Conditions -{ - /// - /// Interaction logic for DataModelConditionListView.xaml - /// - public partial class DataModelConditionListView : UserControl - { - public DataModelConditionListView() - { - InitializeComponent(); - } - - private void PropertyButton_OnClick(object sender, RoutedEventArgs e) - { - // DataContext is not set when using left button, I don't know why but there it is - if (sender is Button button && button.ContextMenu != null) - { - button.ContextMenu.DataContext = button.DataContext; - button.ContextMenu.IsOpen = true; - } - } - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListViewModel.cs deleted file mode 100644 index c4e244b66..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListViewModel.cs +++ /dev/null @@ -1,165 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows.Media; -using Artemis.Core; -using Artemis.Core.Modules; -using Artemis.UI.Ninject.Factories; -using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract; -using Artemis.UI.Shared; -using Artemis.UI.Shared.Services; -using Humanizer; - -namespace Artemis.UI.Screens.ProfileEditor.Conditions -{ - public sealed class DataModelConditionListViewModel : DataModelConditionViewModel, IDisposable - { - private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory; - private readonly IDataModelUIService _dataModelUIService; - private readonly List _modules; - private readonly IProfileEditorService _profileEditorService; - - public DataModelConditionListViewModel(DataModelConditionList dataModelConditionList, - List modules, - IProfileEditorService profileEditorService, - IDataModelUIService dataModelUIService, - IDataModelConditionsVmFactory dataModelConditionsVmFactory) : base(dataModelConditionList) - { - _modules = modules; - _profileEditorService = profileEditorService; - _dataModelUIService = dataModelUIService; - _dataModelConditionsVmFactory = dataModelConditionsVmFactory; - } - - public DataModelConditionList DataModelConditionList => (DataModelConditionList) Model; - - public string SelectedListOperator => DataModelConditionList.ListOperator.Humanize(); - - public void SelectListOperator(string type) - { - ListOperator enumValue = Enum.Parse(type); - DataModelConditionList.ListOperator = enumValue; - NotifyOfPropertyChange(nameof(SelectedListOperator)); - - _profileEditorService.SaveSelectedProfileElement(); - } - - public void AddCondition() - { - DataModelConditionList.AddChild(new DataModelConditionGeneralPredicate(DataModelConditionList, ProfileRightSideType.Dynamic)); - - Update(); - _profileEditorService.SaveSelectedProfileElement(); - } - - public void AddGroup() - { - DataModelConditionList.AddChild(new DataModelConditionGroup(DataModelConditionList)); - - Update(); - _profileEditorService.SaveSelectedProfileElement(); - } - - public override void Evaluate() - { - IsConditionMet = DataModelConditionList.Evaluate(); - foreach (DataModelConditionViewModel dataModelConditionViewModel in Items) - dataModelConditionViewModel.Evaluate(); - } - - public override void Delete() - { - base.Delete(); - _profileEditorService.SaveSelectedProfileElement(); - } - - /// - public override void UpdateModules() - { - foreach (DataModelConditionViewModel dataModelConditionViewModel in Items) - dataModelConditionViewModel.UpdateModules(); - } - - public void Initialize() - { - LeftSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_modules); - LeftSideSelectionViewModel.PropertySelected += LeftSideSelectionViewModelOnPropertySelected; - - IReadOnlyCollection editors = _dataModelUIService.RegisteredDataModelEditors; - List supportedInputTypes = editors.Select(e => e.SupportedType).ToList(); - supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes)); - supportedInputTypes.Add(typeof(IEnumerable<>)); - - LeftSideSelectionViewModel.FilterTypes = supportedInputTypes.ToArray(); - LeftSideSelectionViewModel.ButtonBrush = new SolidColorBrush(Color.FromRgb(71, 108, 188)); - LeftSideSelectionViewModel.Placeholder = "Select a list"; - - Update(); - } - - public void ApplyList() - { - Type newType = LeftSideSelectionViewModel.DataModelPath.GetPropertyType(); - bool converted = ConvertIfRequired(newType); - if (converted) - return; - - DataModelConditionList.UpdateList(LeftSideSelectionViewModel.DataModelPath); - _profileEditorService.SaveSelectedProfileElement(); - - Update(); - } - - public override void Update() - { - LeftSideSelectionViewModel.ChangeDataModelPath(DataModelConditionList.ListPath); - NotifyOfPropertyChange(nameof(SelectedListOperator)); - - // Remove VMs of effects no longer applied on the layer - Items.RemoveRange(Items.Where(c => !DataModelConditionList.Children.Contains(c.Model)).ToList()); - - if (DataModelConditionList.ListPath == null || !DataModelConditionList.ListPath.IsValid) - return; - - List viewModels = new(); - foreach (DataModelConditionPart childModel in Model.Children) - { - if (Items.Any(c => c.Model == childModel)) - continue; - if (!(childModel is DataModelConditionGroup dataModelConditionGroup)) - continue; - - DataModelConditionGroupViewModel viewModel = _dataModelConditionsVmFactory.DataModelConditionGroupViewModel(dataModelConditionGroup, ConditionGroupType.List, _modules); - viewModel.IsRootGroup = true; - viewModels.Add(viewModel); - } - - if (viewModels.Any()) - Items.AddRange(viewModels); - - foreach (DataModelConditionViewModel childViewModel in Items) - childViewModel.Update(); - } - - protected override void OnInitialActivate() - { - Initialize(); - base.OnInitialActivate(); - } - - private void LeftSideSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e) - { - ApplyList(); - } - - #region IDisposable - - public void Dispose() - { - LeftSideSelectionViewModel.Dispose(); - LeftSideSelectionViewModel.PropertySelected -= LeftSideSelectionViewModelOnPropertySelected; - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateView.xaml deleted file mode 100644 index a90fc0b13..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateView.xaml +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateView.xaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateView.xaml.cs deleted file mode 100644 index 5ce43cf28..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateView.xaml.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Windows; -using System.Windows.Controls; - -namespace Artemis.UI.Screens.ProfileEditor.Conditions -{ - /// - /// Interaction logic for DataModelConditionEventPredicateView.xaml - /// - public partial class DataModelConditionEventPredicateView : UserControl - { - public DataModelConditionEventPredicateView() - { - InitializeComponent(); - } - - private void PropertyButton_OnClick(object sender, RoutedEventArgs e) - { - // DataContext is not set when using left button, I don't know why but there it is - if (sender is Button button && button.ContextMenu != null) - { - button.ContextMenu.DataContext = button.DataContext; - button.ContextMenu.IsOpen = true; - } - } - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateViewModel.cs deleted file mode 100644 index 78bd7b625..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateViewModel.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows.Media; -using Artemis.Core; -using Artemis.Core.Modules; -using Artemis.Core.Services; -using Artemis.UI.Extensions; -using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract; -using Artemis.UI.Shared; -using Artemis.UI.Shared.Services; -using Stylet; - -namespace Artemis.UI.Screens.ProfileEditor.Conditions -{ - public class DataModelConditionEventPredicateViewModel : DataModelConditionPredicateViewModel - { - private readonly IDataModelUIService _dataModelUIService; - - public DataModelConditionEventPredicateViewModel(DataModelConditionEventPredicate dataModelConditionEventPredicate, - List modules, - IProfileEditorService profileEditorService, - IDataModelUIService dataModelUIService, - IConditionOperatorService conditionOperatorService, - ISettingsService settingsService) - : base(dataModelConditionEventPredicate, modules, profileEditorService, dataModelUIService, conditionOperatorService, settingsService) - { - _dataModelUIService = dataModelUIService; - - LeftSideColor = new SolidColorBrush(Color.FromRgb(185, 164, 10)); - } - - public DataModelConditionEventPredicate DataModelConditionEventPredicate => (DataModelConditionEventPredicate) Model; - - public override void Initialize() - { - base.Initialize(); - - DataModelPropertiesViewModel eventDataModel = GetEventDataModel(); - LeftSideSelectionViewModel.ChangeDataModel(eventDataModel); - } - - protected override void OnInitialActivate() - { - base.OnInitialActivate(); - Initialize(); - } - - protected override List GetSupportedInputTypes() - { - IReadOnlyCollection editors = _dataModelUIService.RegisteredDataModelEditors; - List supportedInputTypes = editors.Select(e => e.SupportedType).ToList(); - supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes)); - - return supportedInputTypes; - } - - protected override Type GetLeftSideType() - { - return LeftSideSelectionViewModel.DataModelPath?.GetPropertyType(); - } - - protected override List GetExtraRightSideDataModelViewModels() - { - // Only the VM housing the event arguments is expected here which is a DataModelPropertiesViewModel - return GetEventDataModel().Children.Cast().ToList(); - } - - private DataModelPropertiesViewModel GetEventDataModel() - { - EventPredicateWrapperDataModel wrapper = EventPredicateWrapperDataModel.Create( - DataModelConditionEventPredicate.DataModelConditionEvent.EventArgumentType - ); - - return wrapper.CreateViewModel(_dataModelUIService, new DataModelUpdateConfiguration(false)); - } - - public override void Evaluate() - { - } - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateView.xaml deleted file mode 100644 index eab1e69d3..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateView.xaml +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateView.xaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateView.xaml.cs deleted file mode 100644 index 22411462b..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateView.xaml.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Windows; -using System.Windows.Controls; - -namespace Artemis.UI.Screens.ProfileEditor.Conditions -{ - /// - /// Interaction logic for DataModelConditionGeneralPredicateView.xaml - /// - public partial class DataModelConditionGeneralPredicateView : UserControl - { - public DataModelConditionGeneralPredicateView() - { - InitializeComponent(); - } - - private void PropertyButton_OnClick(object sender, RoutedEventArgs e) - { - // DataContext is not set when using left button, I don't know why but there it is - if (sender is Button button && button.ContextMenu != null) - { - button.ContextMenu.DataContext = button.DataContext; - button.ContextMenu.IsOpen = true; - } - } - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateViewModel.cs deleted file mode 100644 index f02494b7f..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateViewModel.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Artemis.Core; -using Artemis.Core.Modules; -using Artemis.Core.Services; -using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract; -using Artemis.UI.Shared; -using Artemis.UI.Shared.Services; - -namespace Artemis.UI.Screens.ProfileEditor.Conditions -{ - public class DataModelConditionGeneralPredicateViewModel : DataModelConditionPredicateViewModel - { - private readonly IDataModelUIService _dataModelUIService; - - public DataModelConditionGeneralPredicateViewModel(DataModelConditionGeneralPredicate dataModelConditionGeneralPredicate, - List modules, - IProfileEditorService profileEditorService, - IDataModelUIService dataModelUIService, - IConditionOperatorService conditionOperatorService, - ISettingsService settingsService) - : base(dataModelConditionGeneralPredicate, modules, profileEditorService, dataModelUIService, conditionOperatorService, settingsService) - { - _dataModelUIService = dataModelUIService; - } - - protected override void OnInitialActivate() - { - Initialize(); - } - - protected override List GetSupportedInputTypes() - { - IReadOnlyCollection editors = _dataModelUIService.RegisteredDataModelEditors; - List supportedInputTypes = editors.Select(e => e.SupportedType).ToList(); - supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes)); - supportedInputTypes.Add(typeof(IEnumerable<>)); - - return supportedInputTypes; - } - - protected override Type GetLeftSideType() - { - return LeftSideSelectionViewModel.DataModelPath?.GetPropertyType(); - } - - public override void Evaluate() - { - IsConditionMet = DataModelConditionPredicate.Evaluate(); - } - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateView.xaml deleted file mode 100644 index 5a273a099..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateView.xaml +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateView.xaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateView.xaml.cs deleted file mode 100644 index 44c02f06b..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateView.xaml.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Windows; -using System.Windows.Controls; - -namespace Artemis.UI.Screens.ProfileEditor.Conditions -{ - /// - /// Interaction logic for DataModelConditionListPredicateView.xaml - /// - public partial class DataModelConditionListPredicateView : UserControl - { - public DataModelConditionListPredicateView() - { - InitializeComponent(); - } - - private void PropertyButton_OnClick(object sender, RoutedEventArgs e) - { - // DataContext is not set when using left button, I don't know why but there it is - if (sender is Button button && button.ContextMenu != null) - { - button.ContextMenu.DataContext = button.DataContext; - button.ContextMenu.IsOpen = true; - } - } - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateViewModel.cs deleted file mode 100644 index 411e8f735..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateViewModel.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows.Media; -using Artemis.Core; -using Artemis.Core.Modules; -using Artemis.Core.Services; -using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract; -using Artemis.UI.Shared; -using Artemis.UI.Shared.Services; - -namespace Artemis.UI.Screens.ProfileEditor.Conditions -{ - public class DataModelConditionListPredicateViewModel : DataModelConditionPredicateViewModel - { - private readonly IDataModelUIService _dataModelUIService; - - public DataModelConditionListPredicateViewModel(DataModelConditionListPredicate dataModelConditionListPredicate, - List modules, - IProfileEditorService profileEditorService, - IDataModelUIService dataModelUIService, - IConditionOperatorService conditionOperatorService, - ISettingsService settingsService) - : base(dataModelConditionListPredicate, modules, profileEditorService, dataModelUIService, conditionOperatorService, settingsService) - { - _dataModelUIService = dataModelUIService; - LeftSideColor = new SolidColorBrush(Color.FromRgb(71, 108, 188)); - } - - public DataModelConditionListPredicate DataModelConditionListPredicate => (DataModelConditionListPredicate) Model; - - public override void Initialize() - { - base.Initialize(); - - DataModelPropertiesViewModel listDataModel = GetListDataModel(); - LeftSideSelectionViewModel.ChangeDataModel(listDataModel); - - // If this is a primitive list the user doesn't have much to choose, so preselect the list item for them - if (DataModelConditionListPredicate.DataModelConditionList.IsPrimitiveList && DataModelConditionListPredicate.LeftPath == null) - { - DataModelConditionListPredicate.UpdateLeftSide(listDataModel.Children.FirstOrDefault()?.DataModelPath); - Update(); - } - } - - public override void Evaluate() - { - - } - - public override void UpdateModules() - { - foreach (DataModelConditionViewModel dataModelConditionViewModel in Items) - dataModelConditionViewModel.UpdateModules(); - } - - protected override void OnInitialActivate() - { - base.OnInitialActivate(); - Initialize(); - } - - protected override List GetSupportedInputTypes() - { - IReadOnlyCollection editors = _dataModelUIService.RegisteredDataModelEditors; - List supportedInputTypes = editors.Select(e => e.SupportedType).ToList(); - supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes)); - - return supportedInputTypes; - } - - protected override Type GetLeftSideType() - { - return DataModelConditionListPredicate.DataModelConditionList.IsPrimitiveList - ? DataModelConditionListPredicate.DataModelConditionList.ListType - : LeftSideSelectionViewModel.DataModelPath?.GetPropertyType(); - } - - protected override List GetExtraRightSideDataModelViewModels() - { - if (GetListDataModel()?.Children?.FirstOrDefault() is DataModelPropertiesViewModel listValue) - return new List {listValue}; - return null; - } - - private DataModelPropertiesViewModel GetListDataModel() - { - ListPredicateWrapperDataModel wrapper = ListPredicateWrapperDataModel.Create( - DataModelConditionListPredicate.DataModelConditionList.ListType!, - DataModelConditionListPredicate.DataModelConditionList.ListPath?.GetPropertyDescription()?.ListItemName - ); - - return wrapper.CreateViewModel(_dataModelUIService, new DataModelUpdateConfiguration(true)); - } - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsViewModel.cs index 4fe3a8c9b..a587da7cc 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsViewModel.cs @@ -2,14 +2,13 @@ using System.Windows.Input; using Artemis.Core; using Artemis.UI.Ninject.Factories; -using Artemis.UI.Screens.ProfileEditor.Conditions; using Artemis.UI.Shared; using Artemis.UI.Shared.Services; using Stylet; namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions { - public class DisplayConditionsViewModel : Conductor, IProfileEditorPanelViewModel + public class DisplayConditionsViewModel : Screen, IProfileEditorPanelViewModel { private readonly INodeVmFactory _nodeVmFactory; private readonly IProfileEditorService _profileEditorService; @@ -103,12 +102,6 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions NotifyOfPropertyChange(nameof(AlwaysFinishTimeline)); NotifyOfPropertyChange(nameof(ConditionBehaviourEnabled)); - if (renderProfileElement == null) - { - ActiveItem = null; - return; - } - RenderProfileElement.Timeline.PropertyChanged += TimelineOnPropertyChanged; } diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/ConditionalDataBindingModeView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/ConditionalDataBindingModeView.xaml deleted file mode 100644 index 7fded19b2..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/ConditionalDataBindingModeView.xaml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/ConditionalDataBindingModeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/ConditionalDataBindingModeViewModel.cs deleted file mode 100644 index 0b6d1eeef..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/ConditionalDataBindingModeViewModel.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Linq; -using Artemis.Core; -using Artemis.UI.Extensions; -using Artemis.UI.Ninject.Factories; -using Artemis.UI.Shared.Services; -using Stylet; - -namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.ConditionalDataBinding -{ - public sealed class ConditionalDataBindingModeViewModel : Conductor>.Collection.AllActive, - IDataBindingModeViewModel - { - private readonly IDataBindingsVmFactory _dataBindingsVmFactory; - private readonly IProfileEditorService _profileEditorService; - private bool _updating; - - public ConditionalDataBindingModeViewModel(ConditionalDataBinding conditionalDataBinding, - IProfileEditorService profileEditorService, - IDataBindingsVmFactory dataBindingsVmFactory) - { - _profileEditorService = profileEditorService; - _dataBindingsVmFactory = dataBindingsVmFactory; - - ConditionalDataBinding = conditionalDataBinding; - } - - public ConditionalDataBinding ConditionalDataBinding { get; } - - public void AddCondition() - { - DataBindingCondition condition = ConditionalDataBinding.AddCondition(); - - // Find the VM of the new condition - DataBindingConditionViewModel viewModel = Items.First(c => c.DataBindingCondition == condition); - viewModel.ActiveItem.AddCondition(); - - _profileEditorService.SaveSelectedProfileElement(); - } - - public void RemoveCondition(DataBindingCondition dataBindingCondition) - { - ConditionalDataBinding.RemoveCondition(dataBindingCondition); - } - - protected override void OnInitialActivate() - { - Initialize(); - base.OnInitialActivate(); - } - - private void UpdateItems() - { - _updating = true; - - // Remove old VMs - List> toRemove = Items.Where(c => !ConditionalDataBinding.Conditions.Contains(c.DataBindingCondition)).ToList(); - foreach (DataBindingConditionViewModel dataBindingConditionViewModel in toRemove) - { - Items.Remove(dataBindingConditionViewModel); - dataBindingConditionViewModel.Dispose(); - } - - // Add missing VMs - foreach (DataBindingCondition condition in ConditionalDataBinding.Conditions) - if (Items.All(c => c.DataBindingCondition != condition)) - Items.Add(_dataBindingsVmFactory.DataBindingConditionViewModel(condition)); - - // Fix order - ((BindableCollection>) Items).Sort(c => c.DataBindingCondition.Order); - - _updating = false; - } - - private void Initialize() - { - ConditionalDataBinding.ConditionsUpdated += ConditionalDataBindingOnConditionsUpdated; - Items.CollectionChanged += ItemsOnCollectionChanged; - UpdateItems(); - } - - private void ItemsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) - { - if (_updating || e.Action != NotifyCollectionChangedAction.Add) - return; - - for (int index = 0; index < Items.Count; index++) - { - DataBindingConditionViewModel conditionViewModel = Items[index]; - conditionViewModel.DataBindingCondition.Order = index + 1; - } - - ConditionalDataBinding.ApplyOrder(); - - _profileEditorService.SaveSelectedProfileElement(); - } - - private void ConditionalDataBindingOnConditionsUpdated(object sender, EventArgs e) - { - UpdateItems(); - } - - public bool SupportsTestValue => false; - - public void Update() - { - UpdateItems(); - } - - public object GetTestValue() - { - throw new NotSupportedException(); - } - - #region IDisposable - - /// - public void Dispose() - { - ConditionalDataBinding.ConditionsUpdated -= ConditionalDataBindingOnConditionsUpdated; - - foreach (DataBindingConditionViewModel conditionViewModel in Items) - conditionViewModel.Dispose(); - Items.Clear(); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/DataBindingConditionView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/DataBindingConditionView.xaml deleted file mode 100644 index 6ae8e1eeb..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/DataBindingConditionView.xaml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/DataBindingConditionViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/DataBindingConditionViewModel.cs deleted file mode 100644 index e9f620f21..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/DataBindingConditionViewModel.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Artemis.Core; -using Artemis.Core.Modules; -using Artemis.UI.Ninject.Factories; -using Artemis.UI.Screens.ProfileEditor.Conditions; -using Artemis.UI.Shared; -using Artemis.UI.Shared.Input; -using Artemis.UI.Shared.Services; -using Stylet; - -namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.ConditionalDataBinding -{ - public sealed class DataBindingConditionViewModel : Conductor, IDisposable - { - private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory; - private readonly IDataModelUIService _dataModelUIService; - private readonly IProfileEditorService _profileEditorService; - - public DataBindingConditionViewModel(DataBindingCondition dataBindingCondition, - IProfileEditorService profileEditorService, - IDataModelConditionsVmFactory dataModelConditionsVmFactory, - IDataModelUIService dataModelUIService) - { - _profileEditorService = profileEditorService; - _dataModelConditionsVmFactory = dataModelConditionsVmFactory; - _dataModelUIService = dataModelUIService; - DataBindingCondition = dataBindingCondition; - } - - public DataBindingCondition DataBindingCondition { get; } - - public DataModelStaticViewModel ValueViewModel { get; set; } - - protected override void OnInitialActivate() - { - base.OnInitialActivate(); - List modules = new(); - if (_profileEditorService.SelectedProfileConfiguration?.Module != null) - modules.Add(_profileEditorService.SelectedProfileConfiguration.Module); - ActiveItem = _dataModelConditionsVmFactory.DataModelConditionGroupViewModel(DataBindingCondition.Condition, ConditionGroupType.General, modules); - ActiveItem.IsRootGroup = true; - - ActiveItem.Update(); - ActiveItem.Updated += ActiveItemOnUpdated; - - ValueViewModel = _dataModelUIService.GetStaticInputViewModel(typeof(TProperty), null); - ValueViewModel.ValueUpdated += ValueViewModelOnValueUpdated; - ValueViewModel.Value = DataBindingCondition.Value; - } - - private void ActiveItemOnUpdated(object sender, EventArgs e) - { - if (!ActiveItem.GetChildren().Any()) - DataBindingCondition.ConditionalDataBinding.RemoveCondition(DataBindingCondition); - } - - private void ValueViewModelOnValueUpdated(object sender, DataModelInputStaticEventArgs e) - { - DataBindingCondition.Value = (TProperty) Convert.ChangeType(e.Value, typeof(TProperty)); - _profileEditorService.SaveSelectedProfileElement(); - } - - public void AddCondition() - { - ((ConditionalDataBindingModeViewModel) Parent).AddCondition(); - } - - public void RemoveCondition() - { - ((ConditionalDataBindingModeViewModel)Parent).RemoveCondition(DataBindingCondition); - - } - - #region IDisposable - - /// - public void Dispose() - { - ValueViewModel?.Dispose(); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml index 34fe61836..be5b8b20e 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml +++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml @@ -5,6 +5,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:s="https://github.com/canton7/Stylet" + xmlns:controls="clr-namespace:Artemis.VisualScripting.Editor.Controls;assembly=Artemis.VisualScripting" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> @@ -36,16 +37,8 @@ - - + Enable data binding + - - - + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs index 49b3040e9..9b0a82562 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs @@ -1,11 +1,10 @@ using System; +using System.Collections.Generic; using System.Linq; -using System.Timers; using Artemis.Core; using Artemis.Core.Services; using Artemis.Storage.Entities.Profile.DataBindings; using Artemis.UI.Exceptions; -using Artemis.UI.Ninject.Factories; using Artemis.UI.Screens.ProfileEditor.LayerProperties.Timeline; using Artemis.UI.Shared; using Artemis.UI.Shared.Services; @@ -13,63 +12,62 @@ using Stylet; namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings { - public sealed class DataBindingViewModel : Conductor, IDataBindingViewModel + public sealed class DataBindingViewModel : Screen, IDataBindingViewModel { - private readonly IDataBindingsVmFactory _dataBindingsVmFactory; private readonly ICoreService _coreService; private readonly IProfileEditorService _profileEditorService; private int _easingTime; private bool _isDataBindingEnabled; private bool _isEasingTimeEnabled; - private DataBindingModeType _selectedDataBindingMode; + private DateTime _lastUpdate; private TimelineEasingViewModel _selectedEasingViewModel; private bool _updating; private bool _updatingTestResult; - private DateTime _lastUpdate; public DataBindingViewModel(DataBindingRegistration registration, ICoreService coreService, ISettingsService settingsService, IProfileEditorService profileEditorService, IDataModelUIService dataModelUIService, - IDataBindingsVmFactory dataBindingsVmFactory) + INodeService nodeService) { Registration = registration; _coreService = coreService; _profileEditorService = profileEditorService; - _dataBindingsVmFactory = dataBindingsVmFactory; DisplayName = Registration.DisplayName.ToUpper(); AlwaysApplyDataBindings = settingsService.GetSetting("ProfileEditor.AlwaysApplyDataBindings", true); - DataBindingModes = new BindableCollection(EnumUtilities.GetAllValuesAndDescriptions(typeof(DataBindingModeType))); EasingViewModels = new BindableCollection(); + AvailableNodes = nodeService.AvailableNodes; TestInputValue = dataModelUIService.GetDataModelDisplayViewModel(typeof(TProperty), null, true); TestResultValue = dataModelUIService.GetDataModelDisplayViewModel(typeof(TProperty), null, true); } public DataBindingRegistration Registration { get; } + public NodeScript Script => Registration.DataBinding?.Script; + public PluginSetting AlwaysApplyDataBindings { get; } - public BindableCollection DataBindingModes { get; } public BindableCollection EasingViewModels { get; } + public IEnumerable AvailableNodes { get; } public DataModelDisplayViewModel TestInputValue { get; } public DataModelDisplayViewModel TestResultValue { get; } - public DataBindingModeType SelectedDataBindingMode - { - get => _selectedDataBindingMode; - set - { - if (!SetAndNotify(ref _selectedDataBindingMode, value)) return; - ApplyDataBindingMode(); - Update(); - } - } public bool IsDataBindingEnabled { get => _isDataBindingEnabled; - set => SetAndNotify(ref _isDataBindingEnabled, value); + set + { + SetAndNotify(ref _isDataBindingEnabled, value); + if (_updating) + return; + + if (value) + EnableDataBinding(); + else + DisableDataBinding(); + } } public TimelineEasingViewModel SelectedEasingViewModel @@ -102,162 +100,6 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings } } - protected override void OnInitialActivate() - { - Initialize(); - base.OnInitialActivate(); - } - - private void Initialize() - { - EasingViewModels.AddRange(Enum.GetValues(typeof(Easings.Functions)).Cast().Select(v => new TimelineEasingViewModel(v, false))); - - _lastUpdate = DateTime.Now; - _coreService.FrameRendered += OnFrameRendered; - CreateDataBindingModeModeViewModel(); - Update(); - } - - private void CreateDataBindingModeModeViewModel() - { - if (Registration.DataBinding?.DataBindingMode == null) - { - ActiveItem = null; - return; - } - - switch (Registration.DataBinding.DataBindingMode) - { - case DirectDataBinding directDataBinding: - ActiveItem = _dataBindingsVmFactory.DirectDataBindingModeViewModel(directDataBinding); - break; - case ConditionalDataBinding conditionalDataBinding: - ActiveItem = _dataBindingsVmFactory.ConditionalDataBindingModeViewModel(conditionalDataBinding); - break; - } - } - - private void Update() - { - if (_updating) - return; - - if (Registration.DataBinding == null) - { - IsDataBindingEnabled = false; - IsEasingTimeEnabled = false; - return; - } - - _updating = true; - - IsDataBindingEnabled = ActiveItem != null; - EasingTime = (int) Registration.DataBinding.EasingTime.TotalMilliseconds; - SelectedEasingViewModel = EasingViewModels.First(vm => vm.EasingFunction == Registration.DataBinding.EasingFunction); - IsEasingTimeEnabled = EasingTime > 0; - SelectedDataBindingMode = Registration.DataBinding.DataBindingMode switch - { - DirectDataBinding _ => DataBindingModeType.Direct, - ConditionalDataBinding _ => DataBindingModeType.Conditional, - _ => DataBindingModeType.None - }; - - ActiveItem?.Update(); - - _updating = false; - } - - private void ApplyChanges() - { - if (_updating) - return; - - if (Registration.DataBinding != null) - { - Registration.DataBinding.EasingTime = TimeSpan.FromMilliseconds(EasingTime); - Registration.DataBinding.EasingFunction = SelectedEasingViewModel?.EasingFunction ?? Easings.Functions.Linear; - } - - _profileEditorService.SaveSelectedProfileElement(); - Update(); - } - - private void ApplyDataBindingMode() - { - if (_updating) - return; - - if (Registration.DataBinding != null && SelectedDataBindingMode == DataBindingModeType.None) - RemoveDataBinding(); - else - { - if (Registration.DataBinding == null && SelectedDataBindingMode != DataBindingModeType.None) - EnableDataBinding(); - - Registration.DataBinding!.ChangeDataBindingMode(SelectedDataBindingMode); - } - - CreateDataBindingModeModeViewModel(); - _profileEditorService.SaveSelectedProfileElement(); - } - - private void UpdateTestResult() - { - if (_updating || _updatingTestResult) - return; - - _updatingTestResult = true; - if (Registration.DataBinding == null || ActiveItem == null) - { - TestInputValue.UpdateValue(default); - TestResultValue.UpdateValue(default); - _updatingTestResult = false; - return; - } - - // If always update is disabled, do constantly update the data binding as long as the view model is open - // If always update is enabled, this is done for all data bindings in ProfileViewModel - if (!AlwaysApplyDataBindings.Value) - { - Registration.DataBinding.UpdateWithDelta(DateTime.Now - _lastUpdate); - _profileEditorService.UpdateProfilePreview(); - } - - if (ActiveItem.SupportsTestValue) - { - TProperty currentValue = Registration.Converter.ConvertFromObject(ActiveItem?.GetTestValue() ?? default(TProperty)); - TestInputValue.UpdateValue(currentValue); - TestResultValue.UpdateValue(Registration.DataBinding != null ? Registration.DataBinding.GetValue(currentValue) : default); - } - else - { - TestResultValue.UpdateValue(Registration.DataBinding != null ? Registration.DataBinding.GetValue(default) : default); - } - - _updatingTestResult = false; - } - - private void EnableDataBinding() - { - if (Registration.DataBinding != null) - return; - - Registration.LayerProperty.EnableDataBinding(Registration); - _profileEditorService.SaveSelectedProfileElement(); - } - - private void RemoveDataBinding() - { - if (Registration.DataBinding == null) - return; - - ActiveItem = null; - Registration.LayerProperty.DisableDataBinding(Registration.DataBinding); - Update(); - - _profileEditorService.SaveSelectedProfileElement(); - } - public void CopyDataBinding() { if (Registration.DataBinding != null) @@ -277,10 +119,115 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings Registration.DataBinding.EasingTime = dataBindingEntity.EasingTime; Registration.DataBinding.EasingFunction = (Easings.Functions) dataBindingEntity.EasingFunction; - Registration.DataBinding.ApplyDataBindingEntity(dataBindingEntity.DataBindingMode); - CreateDataBindingModeModeViewModel(); + + // TODO - Paste visual script + + Update(); + + _profileEditorService.SaveSelectedProfileElement(); + } + + protected override void OnInitialActivate() + { + Initialize(); + base.OnInitialActivate(); + } + + private void Initialize() + { + EasingViewModels.AddRange(Enum.GetValues(typeof(Easings.Functions)).Cast().Select(v => new TimelineEasingViewModel(v, false))); + + _lastUpdate = DateTime.Now; + _coreService.FrameRendered += OnFrameRendered; + Update(); + } + + private void Update() + { + if (_updating) + return; + + if (Registration.DataBinding == null) + { + IsDataBindingEnabled = false; + IsEasingTimeEnabled = false; + return; + } + + _updating = true; + + EasingTime = (int) Registration.DataBinding.EasingTime.TotalMilliseconds; + SelectedEasingViewModel = EasingViewModels.First(vm => vm.EasingFunction == Registration.DataBinding.EasingFunction); + IsDataBindingEnabled = true; + IsEasingTimeEnabled = EasingTime > 0; + + _updating = false; + } + + private void ApplyChanges() + { + if (_updating) + return; + + if (Registration.DataBinding != null) + { + Registration.DataBinding.EasingTime = TimeSpan.FromMilliseconds(EasingTime); + Registration.DataBinding.EasingFunction = SelectedEasingViewModel?.EasingFunction ?? Easings.Functions.Linear; + } + + _profileEditorService.SaveSelectedProfileElement(); + Update(); + } + + private void UpdateTestResult() + { + if (_updating || _updatingTestResult) + return; + + _updatingTestResult = true; + + if (Registration.DataBinding == null) + { + TestInputValue.UpdateValue(default); + TestResultValue.UpdateValue(default); + _updatingTestResult = false; + return; + } + + // If always update is disabled, do constantly update the data binding as long as the view model is open + // If always update is enabled, this is done for all data bindings in ProfileViewModel + if (!AlwaysApplyDataBindings.Value) + { + Registration.DataBinding.UpdateWithDelta(DateTime.Now - _lastUpdate); + _profileEditorService.UpdateProfilePreview(); + } + + TProperty currentValue = Registration.Converter.ConvertFromObject(Registration.DataBinding.Script.Result ?? default(TProperty)); + TestInputValue.UpdateValue(currentValue); + TestResultValue.UpdateValue(Registration.DataBinding != null ? Registration.DataBinding.GetValue(currentValue) : default); + + _updatingTestResult = false; + } + + private void EnableDataBinding() + { + if (Registration.DataBinding != null) + return; + + Registration.LayerProperty.EnableDataBinding(Registration); + NotifyOfPropertyChange(nameof(Script)); + + _profileEditorService.SaveSelectedProfileElement(); + } + + private void DisableDataBinding() + { + if (Registration.DataBinding == null) + return; + + Registration.LayerProperty.DisableDataBinding(Registration.DataBinding); + NotifyOfPropertyChange(nameof(Script)); Update(); - _profileEditorService.SaveSelectedProfileElement(); } @@ -291,20 +238,11 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings _lastUpdate = DateTime.Now; } - private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e) - { - UpdateTestResult(); - } - - #region IDisposable - /// public void Dispose() { _coreService.FrameRendered -= OnFrameRendered; } - - #endregion } public interface IDataBindingViewModel : IScreen, IDisposable diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierView.xaml deleted file mode 100644 index 4d0635574..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierView.xaml +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierView.xaml.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierView.xaml.cs deleted file mode 100644 index 86d341696..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierView.xaml.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Windows; -using System.Windows.Controls; - -namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding -{ - /// - /// Interaction logic for DataBindingModifierView.xaml - /// - public partial class DataBindingModifierView : UserControl - { - public DataBindingModifierView() - { - InitializeComponent(); - } - - private void PropertyButton_OnClick(object sender, RoutedEventArgs e) - { - // DataContext is not set when using left button, I don't know why but there it is - if (sender is Button button && button.ContextMenu != null) - { - button.ContextMenu.DataContext = button.DataContext; - button.ContextMenu.IsOpen = true; - } - } - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierViewModel.cs deleted file mode 100644 index f6811db6f..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DataBindingModifierViewModel.cs +++ /dev/null @@ -1,212 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Artemis.Core; -using Artemis.Core.Services; -using Artemis.UI.Exceptions; -using Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding.ModifierTypes; -using Artemis.UI.Shared; -using Artemis.UI.Shared.Input; -using Artemis.UI.Shared.Services; -using Stylet; - -namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding -{ - public sealed class DataBindingModifierViewModel : PropertyChangedBase, IDisposable - { - private readonly IDataBindingService _dataBindingService; - private readonly IDataModelUIService _dataModelUIService; - private readonly IProfileEditorService _profileEditorService; - private DataModelDynamicViewModel _dynamicSelectionViewModel; - private ModifierTypeCategoryViewModel _modifierTypeViewModels; - private BaseDataBindingModifierType _selectedModifierType; - private DataModelStaticViewModel _staticInputViewModel; - - public DataBindingModifierViewModel(DataBindingModifier modifier, - IDataBindingService dataBindingService, - ISettingsService settingsService, - IDataModelUIService dataModelUIService, - IProfileEditorService profileEditorService) - { - _dataBindingService = dataBindingService; - _dataModelUIService = dataModelUIService; - _profileEditorService = profileEditorService; - - ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues"); - - Modifier = modifier; - SelectModifierTypeCommand = new DelegateCommand(ExecuteSelectModifierTypeCommand); - - Update(); - } - - public DelegateCommand SelectModifierTypeCommand { get; } - public PluginSetting ShowDataModelValues { get; } - public DataBindingModifier Modifier { get; } - - public ModifierTypeCategoryViewModel ModifierTypeViewModels - { - get => _modifierTypeViewModels; - set => SetAndNotify(ref _modifierTypeViewModels, value); - } - - public BaseDataBindingModifierType SelectedModifierType - { - get => _selectedModifierType; - set => SetAndNotify(ref _selectedModifierType, value); - } - - public DataModelDynamicViewModel DynamicSelectionViewModel - { - get => _dynamicSelectionViewModel; - private set => SetAndNotify(ref _dynamicSelectionViewModel, value); - } - - public DataModelStaticViewModel StaticInputViewModel - { - get => _staticInputViewModel; - private set => SetAndNotify(ref _staticInputViewModel, value); - } - - public void Delete() - { - Modifier.DirectDataBinding.RemoveModifier(Modifier); - _profileEditorService.SaveSelectedProfileElement(); - } - - private void ParameterSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e) - { - Modifier.UpdateParameterDynamic(e.DataModelPath); - _profileEditorService.SaveSelectedProfileElement(); - } - - private void StaticInputViewModelOnValueUpdated(object sender, DataModelInputStaticEventArgs e) - { - Modifier.UpdateParameterStatic(e.Value); - _profileEditorService.SaveSelectedProfileElement(); - } - - private void Update() - { - Type sourceType = Modifier.DirectDataBinding.GetSourceType(); - if (sourceType == null) - throw new ArtemisUIException("Cannot use a data binding modifier VM for a data binding without a source"); - - if (Modifier.ModifierType == null || Modifier.ModifierType.ParameterType == null) - { - DisposeDynamicSelectionViewModel(); - DisposeStaticInputViewModel(); - } - else if (Modifier.ParameterType == ProfileRightSideType.Dynamic) - { - DisposeStaticInputViewModel(); - DynamicSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.SelectedProfileConfiguration.Module); - if (DynamicSelectionViewModel != null) - { - DynamicSelectionViewModel.DisplaySwitchButton = true; - DynamicSelectionViewModel.PropertySelected += ParameterSelectionViewModelOnPropertySelected; - DynamicSelectionViewModel.SwitchToStaticRequested += DynamicSelectionViewModelOnSwitchToStaticRequested; - DynamicSelectionViewModel.FilterTypes = new[] {Modifier.ModifierType.ParameterType ?? sourceType}; - } - } - else - { - DisposeDynamicSelectionViewModel(); - StaticInputViewModel = _dataModelUIService.GetStaticInputViewModel(Modifier.ModifierType.ParameterType ?? sourceType, null); - if (StaticInputViewModel != null) - { - StaticInputViewModel.DisplaySwitchButton = true; - StaticInputViewModel.ValueUpdated += StaticInputViewModelOnValueUpdated; - StaticInputViewModel.SwitchToDynamicRequested += StaticInputViewModelOnSwitchToDynamicRequested; - } - } - - // Modifier type - ModifierTypeCategoryViewModel root = new(null, null); - IEnumerable> modifierTypes = _dataBindingService.GetCompatibleModifierTypes(sourceType, ModifierTypePart.Value).GroupBy(t => t.Category); - foreach (IGrouping dataBindingModifierTypes in modifierTypes) - { - IEnumerable viewModels = dataBindingModifierTypes.Select(t => new ModifierTypeViewModel(t)); - if (dataBindingModifierTypes.Key == null) - root.Children.AddRange(viewModels); - else - root.Children.Add(new ModifierTypeCategoryViewModel(dataBindingModifierTypes.Key, viewModels)); - } - - ModifierTypeViewModels = root; - SelectedModifierType = Modifier.ModifierType; - - // Parameter - if (DynamicSelectionViewModel != null) - DynamicSelectionViewModel.ChangeDataModelPath(Modifier.ParameterPath); - else if (StaticInputViewModel != null) - StaticInputViewModel.Value = Modifier.ParameterStaticValue; - } - - private void ExecuteSelectModifierTypeCommand(object context) - { - if (!(context is ModifierTypeViewModel modifierTypeViewModel)) - return; - - Modifier.UpdateModifierType(modifierTypeViewModel.ModifierType); - _profileEditorService.SaveSelectedProfileElement(); - - 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; - - // Ensure the right static value is never null when the preferred type is a value type - if (SelectedModifierType.ParameterType != null && - SelectedModifierType.ParameterType.IsValueType && Modifier.ParameterStaticValue == null) - Modifier.UpdateParameterStatic(SelectedModifierType.ParameterType.GetDefault()); - - Update(); - } - - private void StaticInputViewModelOnSwitchToDynamicRequested(object sender, EventArgs e) - { - Modifier.ParameterType = ProfileRightSideType.Dynamic; - Update(); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DirectDataBindingModeView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DirectDataBindingModeView.xaml deleted file mode 100644 index d33ce960e..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DirectDataBindingModeView.xaml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DirectDataBindingModeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DirectDataBindingModeViewModel.cs deleted file mode 100644 index 40479a351..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/DirectDataBindingModeViewModel.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Linq; -using Artemis.Core; -using Artemis.Core.Modules; -using Artemis.UI.Extensions; -using Artemis.UI.Ninject.Factories; -using Artemis.UI.Shared; -using Artemis.UI.Shared.Input; -using Artemis.UI.Shared.Services; -using Stylet; - -namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding -{ - public sealed class DirectDataBindingModeViewModel : Screen, IDataBindingModeViewModel - { - private readonly IDataBindingsVmFactory _dataBindingsVmFactory; - private readonly IDataModelUIService _dataModelUIService; - private readonly IProfileEditorService _profileEditorService; - private bool _canAddModifier; - private DataModelDynamicViewModel _targetSelectionViewModel; - private bool _updating; - - public DirectDataBindingModeViewModel(DirectDataBinding directDataBinding, - IProfileEditorService profileEditorService, - IDataModelUIService dataModelUIService, - IDataBindingsVmFactory dataBindingsVmFactory) - { - _profileEditorService = profileEditorService; - _dataModelUIService = dataModelUIService; - _dataBindingsVmFactory = dataBindingsVmFactory; - - DirectDataBinding = directDataBinding; - ModifierViewModels = new BindableCollection>(); - - Initialize(); - } - - - public DirectDataBinding DirectDataBinding { get; } - public BindableCollection> ModifierViewModels { get; } - - public bool CanAddModifier - { - get => _canAddModifier; - set => SetAndNotify(ref _canAddModifier, value); - } - - public DataModelDynamicViewModel TargetSelectionViewModel - { - get => _targetSelectionViewModel; - private set => SetAndNotify(ref _targetSelectionViewModel, value); - } - - public bool SupportsTestValue => true; - - public void Update() - { - TargetSelectionViewModel.ChangeDataModelPath(DirectDataBinding.SourcePath); - TargetSelectionViewModel.FilterTypes = new[] {DirectDataBinding.DataBinding.GetTargetType()}; - - CanAddModifier = DirectDataBinding.SourcePath != null && DirectDataBinding.SourcePath.IsValid; - UpdateModifierViewModels(); - } - - public object GetTestValue() - { - return DirectDataBinding.SourcePath?.GetValue(); - } - - #region IDisposable - - /// - public void Dispose() - { - TargetSelectionViewModel.PropertySelected -= TargetSelectionViewModelOnPropertySelected; - TargetSelectionViewModel.Dispose(); - DirectDataBinding.ModifiersUpdated -= DirectDataBindingOnModifiersUpdated; - - foreach (DataBindingModifierViewModel dataBindingModifierViewModel in ModifierViewModels) - dataBindingModifierViewModel.Dispose(); - ModifierViewModels.Clear(); - } - - #endregion - - private void Initialize() - { - DirectDataBinding.ModifiersUpdated += DirectDataBindingOnModifiersUpdated; - TargetSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.SelectedProfileConfiguration.Module); - TargetSelectionViewModel.PropertySelected += TargetSelectionViewModelOnPropertySelected; - ModifierViewModels.CollectionChanged += ModifierViewModelsOnCollectionChanged; - Update(); - } - - private void ModifierViewModelsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) - { - if (_updating || e.Action != NotifyCollectionChangedAction.Add) - return; - - for (int index = 0; index < ModifierViewModels.Count; index++) - { - DataBindingModifierViewModel dataBindingModifierViewModel = ModifierViewModels[index]; - dataBindingModifierViewModel.Modifier.Order = index + 1; - } - - DirectDataBinding.ApplyOrder(); - - _profileEditorService.SaveSelectedProfileElement(); - } - - #region Target - - private void TargetSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e) - { - DirectDataBinding.UpdateSource(e.DataModelPath); - Update(); - - _profileEditorService.SaveSelectedProfileElement(); - } - - #endregion - - #region Modifiers - - public void AddModifier() - { - DirectDataBinding.AddModifier(ProfileRightSideType.Dynamic); - _profileEditorService.SaveSelectedProfileElement(); - } - - private void UpdateModifierViewModels() - { - _updating = true; - - // Remove old VMs - List> toRemove = ModifierViewModels.Where(m => !DirectDataBinding.Modifiers.Contains(m.Modifier)).ToList(); - foreach (DataBindingModifierViewModel modifierViewModel in toRemove) - { - ModifierViewModels.Remove(modifierViewModel); - modifierViewModel.Dispose(); - } - - // Don't create children without a source or with an invalid source - if (DirectDataBinding.SourcePath == null || !DirectDataBinding.SourcePath.IsValid) - return; - - // Add missing VMs - foreach (DataBindingModifier modifier in DirectDataBinding.Modifiers) - { - if (ModifierViewModels.All(m => m.Modifier != modifier)) - ModifierViewModels.Add(_dataBindingsVmFactory.DataBindingModifierViewModel(modifier)); - } - - // Fix order - ModifierViewModels.Sort(m => m.Modifier.Order); - - _updating = false; - } - - private void DirectDataBindingOnModifiersUpdated(object sender, EventArgs e) - { - UpdateModifierViewModels(); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/ModifierTypes/IModifierTypeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/ModifierTypes/IModifierTypeViewModel.cs deleted file mode 100644 index baa398a12..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/ModifierTypes/IModifierTypeViewModel.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding.ModifierTypes -{ - public interface IModifierTypeViewModel - { - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/ModifierTypes/ModifierTypeCategoryViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/ModifierTypes/ModifierTypeCategoryViewModel.cs deleted file mode 100644 index e1d5e3966..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/ModifierTypes/ModifierTypeCategoryViewModel.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; -using Stylet; - -namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding.ModifierTypes -{ - public class ModifierTypeCategoryViewModel : IModifierTypeViewModel - { - public ModifierTypeCategoryViewModel(string category, IEnumerable children) - { - Category = category; - Children = children == null - ? new BindableCollection() - : new BindableCollection(children); - } - - public string Category { get; set; } - public BindableCollection Children { get; set; } - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/ModifierTypes/ModifierTypeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/ModifierTypes/ModifierTypeViewModel.cs deleted file mode 100644 index af7eb7daf..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DirectDataBinding/ModifierTypes/ModifierTypeViewModel.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Artemis.Core; - -namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDataBinding.ModifierTypes -{ - public class ModifierTypeViewModel : IModifierTypeViewModel - { - public ModifierTypeViewModel(BaseDataBindingModifierType modifierType) - { - ModifierType = modifierType; - } - - public BaseDataBindingModifierType ModifierType { get; set; } - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/IDataBindingModeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/IDataBindingModeViewModel.cs deleted file mode 100644 index 09db1fe3f..000000000 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/IDataBindingModeViewModel.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using Stylet; - -namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings -{ - public interface IDataBindingModeViewModel : IScreen, IDisposable - { - bool SupportsTestValue { get; } - void Update(); - object GetTestValue(); - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Sidebar/Dialogs/ProfileEdit/ProfileEditViewModel.cs b/src/Artemis.UI/Screens/Sidebar/Dialogs/ProfileEdit/ProfileEditViewModel.cs index bbfb771cd..dc27af8a1 100644 --- a/src/Artemis.UI/Screens/Sidebar/Dialogs/ProfileEdit/ProfileEditViewModel.cs +++ b/src/Artemis.UI/Screens/Sidebar/Dialogs/ProfileEdit/ProfileEditViewModel.cs @@ -3,14 +3,10 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; -using System.Windows; -using System.Windows.Media; -using System.Windows.Media.Imaging; using Artemis.Core; using Artemis.Core.Modules; using Artemis.Core.Services; using Artemis.UI.Ninject.Factories; -using Artemis.UI.Screens.ProfileEditor.Conditions; using Artemis.UI.Shared; using Artemis.UI.Shared.Services; using FluentValidation; @@ -22,7 +18,6 @@ namespace Artemis.UI.Screens.Sidebar.Dialogs.ProfileEdit { public class ProfileEditViewModel : DialogViewModelBase { - private readonly DataModelConditionGroup _dataModelConditionGroup; private readonly List _modules; private readonly IProfileService _profileService; private bool _changedImage; @@ -37,14 +32,12 @@ namespace Artemis.UI.Screens.Sidebar.Dialogs.ProfileEdit IProfileService profileService, IPluginManagementService pluginManagementService, ISidebarVmFactory sidebarVmFactory, - IDataModelConditionsVmFactory dataModelConditionsVmFactory, IModelValidator validator) : base(validator) { ProfileConfiguration = profileConfiguration; IsNew = isNew; _profileService = profileService; - _dataModelConditionGroup = ProfileConfiguration.ActivationCondition ?? new DataModelConditionGroup(null); _modules = ProfileConfiguration.Module != null ? new List {ProfileConfiguration.Module} : new List(); IconTypes = new BindableCollection(EnumUtilities.GetAllValuesAndDescriptions(typeof(ProfileConfigurationIconType))); @@ -54,10 +47,7 @@ namespace Artemis.UI.Screens.Sidebar.Dialogs.ProfileEdit pluginManagementService.GetFeaturesOfType().Where(m => !m.IsAlwaysAvailable).Select(m => new ProfileModuleViewModel(m)) ); Initializing = true; - - ActivationConditionViewModel = dataModelConditionsVmFactory.DataModelConditionGroupViewModel(_dataModelConditionGroup, ConditionGroupType.General, _modules); - ActivationConditionViewModel.ConductWith(this); - ActivationConditionViewModel.IsRootGroup = true; + ModuleActivationRequirementsViewModel = new ModuleActivationRequirementsViewModel(sidebarVmFactory); ModuleActivationRequirementsViewModel.ConductWith(this); ModuleActivationRequirementsViewModel.SetModule(ProfileConfiguration.Module); @@ -84,8 +74,7 @@ namespace Artemis.UI.Screens.Sidebar.Dialogs.ProfileEdit Initializing = false; }); } - - public DataModelConditionGroupViewModel ActivationConditionViewModel { get; } + public ModuleActivationRequirementsViewModel ModuleActivationRequirementsViewModel { get; } public ProfileConfigurationHotkeyViewModel EnableHotkeyViewModel { get; } public ProfileConfigurationHotkeyViewModel DisableHotkeyViewModel { get; } @@ -160,7 +149,6 @@ namespace Artemis.UI.Screens.Sidebar.Dialogs.ProfileEdit if (value != null) _modules.Add(value.Module); - ActivationConditionViewModel.UpdateModules(); ModuleActivationRequirementsViewModel.SetModule(value?.Module); } } @@ -184,9 +172,6 @@ namespace Artemis.UI.Screens.Sidebar.Dialogs.ProfileEdit ProfileConfiguration.Module = SelectedModule?.Module; - if (_dataModelConditionGroup.Children.Any()) - ProfileConfiguration.ActivationCondition = _dataModelConditionGroup; - if (_changedImage) { ProfileConfiguration.Icon.FileIcon = SelectedImage; diff --git a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj index bf5de01e7..93f3b3450 100644 --- a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj +++ b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj @@ -50,5 +50,8 @@ $(DefaultXamlRuntime) Designer + + $(DefaultXamlRuntime) + \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Editor/Controls/VisualScriptCablePresenter.cs b/src/Artemis.VisualScripting/Editor/Controls/VisualScriptCablePresenter.cs index 4487ba42c..85f6a8a7c 100644 --- a/src/Artemis.VisualScripting/Editor/Controls/VisualScriptCablePresenter.cs +++ b/src/Artemis.VisualScripting/Editor/Controls/VisualScriptCablePresenter.cs @@ -1,9 +1,12 @@ using System; +using System.Collections; using System.ComponentModel; using System.Windows; using System.Windows.Controls; using System.Windows.Input; +using System.Windows.Media; using System.Windows.Shapes; +using Artemis.Core; using Artemis.VisualScripting.Editor.Controls.Wrapper; namespace Artemis.VisualScripting.Editor.Controls @@ -48,7 +51,7 @@ namespace Artemis.VisualScripting.Editor.Controls public Point ValuePosition { - get => (Point) GetValue(ValuePositionProperty); + get => (Point)GetValue(ValuePositionProperty); set => SetValue(ValuePositionProperty, value); } @@ -60,7 +63,7 @@ namespace Artemis.VisualScripting.Editor.Controls { _path = GetTemplateChild(PART_PATH) as Path ?? throw new NullReferenceException($"The Path '{PART_PATH}' is missing."); _path.MouseDown += OnPathMouseDown; - + Unloaded += OnUnloaded; } @@ -104,25 +107,31 @@ namespace Artemis.VisualScripting.Editor.Controls newCable.To.PropertyChanged += OnPinPropertyChanged; } + UpdateBorderBrush(); UpdateValuePosition(); } - + private void OnPinPropertyChanged(object sender, PropertyChangedEventArgs e) { - UpdateValuePosition(); + if (e.PropertyName == nameof(VisualScriptPin.AbsolutePosition)) + UpdateValuePosition(); + } + + private void UpdateBorderBrush() + { + // if (Cable.From.Pin.Type.IsAssignableTo(typeof(IList))) + // BorderBrush = new SolidColorBrush(Colors.MediumPurple); } private void UpdateValuePosition() { if (Cable.From == null || Cable.To == null) - ValuePosition = new Point(); - else - { - ValuePosition = new Point( - Cable.From.AbsolutePosition.X + ((Cable.To.AbsolutePosition.X - Cable.From.AbsolutePosition.X) / 2), - Cable.From.AbsolutePosition.Y + ((Cable.To.AbsolutePosition.Y - Cable.From.AbsolutePosition.Y) / 2) - ); - } + return; + + ValuePosition = new Point( + Cable.From.AbsolutePosition.X + ((Cable.To.AbsolutePosition.X - Cable.From.AbsolutePosition.X) / 2), + Cable.From.AbsolutePosition.Y + ((Cable.To.AbsolutePosition.Y - Cable.From.AbsolutePosition.Y) / 2) + ); } #endregion diff --git a/src/Artemis.VisualScripting/Editor/Styles/VisualScriptCablePresenter.xaml b/src/Artemis.VisualScripting/Editor/Styles/VisualScriptCablePresenter.xaml index e5cb83c06..0a507021d 100644 --- a/src/Artemis.VisualScripting/Editor/Styles/VisualScriptCablePresenter.xaml +++ b/src/Artemis.VisualScripting/Editor/Styles/VisualScriptCablePresenter.xaml @@ -2,7 +2,8 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System;assembly=System.Runtime" xmlns:controls="clr-namespace:Artemis.VisualScripting.Editor.Controls" - xmlns:converters="clr-namespace:Artemis.VisualScripting.Converters"> + xmlns:converters="clr-namespace:Artemis.VisualScripting.Converters" + xmlns:collections="clr-namespace:System.Collections;assembly=System.Runtime"> + + + + diff --git a/src/Artemis.VisualScripting/Editor/Styles/VisualScriptPresenter.xaml b/src/Artemis.VisualScripting/Editor/Styles/VisualScriptPresenter.xaml index 506619a99..afa908aa7 100644 --- a/src/Artemis.VisualScripting/Editor/Styles/VisualScriptPresenter.xaml +++ b/src/Artemis.VisualScripting/Editor/Styles/VisualScriptPresenter.xaml @@ -7,14 +7,14 @@ - @@ -27,14 +27,14 @@ Height="{Binding SurfaceSize, RelativeSource={RelativeSource TemplatedParent}}" Background="{TemplateBinding Background}"> - - @@ -50,10 +50,10 @@ @@ -79,7 +79,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.sln.DotSettings b/src/Artemis.sln.DotSettings index c899abc86..7af04acad 100644 --- a/src/Artemis.sln.DotSettings +++ b/src/Artemis.sln.DotSettings @@ -2,6 +2,7 @@ Inherit True True + True ERROR ERROR Built-in: Full Cleanup