From b8fa8779d9b509a9e0e7e1936afe53ad870eabd1 Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Thu, 22 Oct 2020 19:36:24 +0200 Subject: [PATCH] Data model events - Improved condition conversion code --- .../Conditions/DataModelConditionGroup.cs | 2 + .../Shared/DataModelVisualizationViewModel.cs | 3 +- .../Ninject/Factories/IVMFactory.cs | 1 + .../Abstract/DataModelConditionViewModel.cs | 50 ++++++++++++++++++- .../DataModelConditionEventView.xaml | 47 +++++++++++++++++ .../DataModelConditionEventViewModel.cs | 43 +++++++--------- .../DataModelConditionGroupViewModel.cs | 27 +++++----- .../DataModelConditionListView.xaml | 2 +- .../DataModelConditionListViewModel.cs | 47 +++++++---------- .../DataModelConditionPredicateViewModel.cs | 15 ++---- 10 files changed, 157 insertions(+), 80 deletions(-) create mode 100644 src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventView.xaml diff --git a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionGroup.cs b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionGroup.cs index c731176ca..3c6cf18b9 100644 --- a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionGroup.cs +++ b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionGroup.cs @@ -40,6 +40,8 @@ namespace Artemis.Core 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 DataModelConditionPredicateEntity predicateEntity) AddChild(new DataModelConditionPredicate(this, predicateEntity)); else if (childEntity is DataModelConditionListPredicateEntity listPredicateEntity) diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs index 292db909f..6892a1c33 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs @@ -235,7 +235,6 @@ namespace Artemis.UI.Shared if (toRemoveDynamic.Any()) Children.RemoveRange(toRemoveDynamic); } - private DataModelVisualizationViewModel CreateChild(IDataModelUIService dataModelUIService, string path, int depth) { if (depth > MaxDepth) @@ -265,7 +264,7 @@ namespace Artemis.UI.Shared if (propertyType.IsGenericEnumerable()) return new DataModelListViewModel(DataModel, this, dataModelPath) {Depth = depth}; if (propertyType == typeof(DataModelEvent) || propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(DataModelEvent<>)) - return new DataModelEventViewModel(DataModel, this, dataModelPath) { Depth = depth }; + return new DataModelEventViewModel(DataModel, this, dataModelPath) {Depth = depth}; // For other value types create a child view model if (propertyType.IsClass || propertyType.IsStruct()) return new DataModelPropertiesViewModel(DataModel, this, dataModelPath) {Depth = depth}; diff --git a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs index 8a2d0871a..374948a90 100644 --- a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs +++ b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs @@ -67,6 +67,7 @@ namespace Artemis.UI.Ninject.Factories { DataModelConditionGroupViewModel DataModelConditionGroupViewModel(DataModelConditionGroup dataModelConditionGroup, bool isListGroup); DataModelConditionListViewModel DataModelConditionListViewModel(DataModelConditionList dataModelConditionList); + DataModelConditionEventViewModel DataModelConditionEventViewModel(DataModelConditionEvent dataModelConditionEvent); DataModelConditionPredicateViewModel DataModelConditionPredicateViewModel(DataModelConditionPredicate dataModelConditionPredicate); DataModelConditionListPredicateViewModel DataModelConditionListPredicateViewModel(DataModelConditionListPredicate dataModelConditionListPredicate); } diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionViewModel.cs index 5d8908b86..7a88e8b5b 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionViewModel.cs @@ -1,10 +1,14 @@ -using Artemis.Core; +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; + protected DataModelConditionViewModel(DataModelConditionPart model) { Model = model; @@ -12,6 +16,12 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions.Abstract public DataModelConditionPart Model { get; } + public DataModelDynamicViewModel LeftSideSelectionViewModel + { + get => _leftSideSelectionViewModel; + set => SetAndNotify(ref _leftSideSelectionViewModel, value); + } + public abstract void Update(); public virtual void Delete() @@ -19,5 +29,43 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions.Abstract 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; + } + + // Event + if (IsEvent(newType)) + { + if (this is DataModelConditionEventViewModel) + return false; + groupViewModel.ConvertToConditionEvent(this); + return true; + } + + // Predicate + if (this is DataModelConditionPredicateViewModel) + return false; + groupViewModel.ConvertToPredicate(this); + return true; + } + + protected bool IsEvent(Type type) + { + return type == typeof(DataModelEvent) || type.IsGenericType && type.GetGenericTypeDefinition() == typeof(DataModelEvent<>); + } } } \ 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 new file mode 100644 index 000000000..6c33a5b79 --- /dev/null +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventView.xaml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + \ 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 index 62d7d267e..71d34c67c 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventViewModel.cs @@ -1,13 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Windows.Media; using Artemis.Core; using Artemis.UI.Ninject.Factories; using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract; using Artemis.UI.Shared; -using Artemis.UI.Shared.Input; using Artemis.UI.Shared.Services; namespace Artemis.UI.Screens.ProfileEditor.Conditions @@ -17,12 +15,11 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory; private readonly IDataModelUIService _dataModelUIService; private readonly IProfileEditorService _profileEditorService; - private DataModelDynamicViewModel _targetSelectionViewModel; - public DataModelConditionEventViewModel(DataModelConditionEvent model, + public DataModelConditionEventViewModel(DataModelConditionEvent dataModelConditionEvent, IProfileEditorService profileEditorService, IDataModelUIService dataModelUIService, - IDataModelConditionsVmFactory dataModelConditionsVmFactory) : base(model) + IDataModelConditionsVmFactory dataModelConditionsVmFactory) : base(dataModelConditionEvent) { _profileEditorService = profileEditorService; _dataModelUIService = dataModelUIService; @@ -33,39 +30,37 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions public DataModelConditionEvent DataModelConditionEvent => (DataModelConditionEvent) Model; - public DataModelDynamicViewModel TargetSelectionViewModel - { - get => _targetSelectionViewModel; - set => SetAndNotify(ref _targetSelectionViewModel, value); - } public void Initialize() { - TargetSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule()); - TargetSelectionViewModel.PropertySelected += TargetSelectionViewModelOnPropertySelected; + LeftSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule()); + 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<>)); - TargetSelectionViewModel.FilterTypes = supportedInputTypes.ToArray(); + LeftSideSelectionViewModel.FilterTypes = supportedInputTypes.ToArray(); - TargetSelectionViewModel.ButtonBrush = new SolidColorBrush(Color.FromRgb(188, 174, 71)); - TargetSelectionViewModel.Placeholder = "Select a list"; + LeftSideSelectionViewModel.ButtonBrush = new SolidColorBrush(Color.FromRgb(185, 164, 10)); + LeftSideSelectionViewModel.Placeholder = "Select an event"; Update(); } + public override void Update() + { + LeftSideSelectionViewModel.ChangeDataModelPath(DataModelConditionEvent.EventPath); + } + public void ApplyEvent() { - if (!TargetSelectionViewModel.DataModelPath.GetPropertyType().IsGenericEnumerable()) - { - if (Parent is DataModelConditionGroupViewModel groupViewModel) - groupViewModel.ConvertToPredicate(this); + Type newType = LeftSideSelectionViewModel.DataModelPath.GetPropertyType(); + bool converted = ConvertIfRequired(newType); + if (converted) return; - } - DataModelConditionEvent.UpdateEvent(TargetSelectionViewModel.DataModelPath); + DataModelConditionEvent.UpdateEvent(LeftSideSelectionViewModel.DataModelPath); _profileEditorService.UpdateSelectedProfileElement(); Update(); @@ -73,7 +68,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions #region Event handlers - private void TargetSelectionViewModelOnPropertySelected(object? sender, DataModelInputDynamicEventArgs e) + private void LeftSideSelectionViewModelOnPropertySelected(object? sender, DataModelInputDynamicEventArgs e) { ApplyEvent(); } @@ -84,8 +79,8 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions public void Dispose() { - TargetSelectionViewModel.Dispose(); - TargetSelectionViewModel.PropertySelected -= TargetSelectionViewModelOnPropertySelected; + LeftSideSelectionViewModel.Dispose(); + LeftSideSelectionViewModel.PropertySelected -= LeftSideSelectionViewModelOnPropertySelected; } #endregion diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs index 805208232..b5f3bad1f 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs @@ -100,19 +100,22 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions switch (childModel) { - case DataModelConditionGroup DataModelConditionGroup: - viewModels.Add(_dataModelConditionsVmFactory.DataModelConditionGroupViewModel(DataModelConditionGroup, IsListGroup)); + case DataModelConditionGroup dataModelConditionGroup: + viewModels.Add(_dataModelConditionsVmFactory.DataModelConditionGroupViewModel(dataModelConditionGroup, IsListGroup)); break; - case DataModelConditionList DataModelConditionListPredicate: - viewModels.Add(_dataModelConditionsVmFactory.DataModelConditionListViewModel(DataModelConditionListPredicate)); + case DataModelConditionList dataModelConditionList: + viewModels.Add(_dataModelConditionsVmFactory.DataModelConditionListViewModel(dataModelConditionList)); break; - case DataModelConditionPredicate DataModelConditionPredicate: + case DataModelConditionEvent dataModelConditionEvent: + viewModels.Add(_dataModelConditionsVmFactory.DataModelConditionEventViewModel(dataModelConditionEvent)); + break; + case DataModelConditionPredicate dataModelConditionPredicate: if (!IsListGroup) - viewModels.Add(_dataModelConditionsVmFactory.DataModelConditionPredicateViewModel(DataModelConditionPredicate)); + viewModels.Add(_dataModelConditionsVmFactory.DataModelConditionPredicateViewModel(dataModelConditionPredicate)); break; - case DataModelConditionListPredicate DataModelConditionListPredicate: + case DataModelConditionListPredicate dataModelConditionListPredicate: if (IsListGroup) - viewModels.Add(_dataModelConditionsVmFactory.DataModelConditionListPredicateViewModel(DataModelConditionListPredicate)); + viewModels.Add(_dataModelConditionsVmFactory.DataModelConditionListPredicateViewModel(dataModelConditionListPredicate)); break; } } @@ -132,7 +135,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions OnUpdated(); } - public void ConvertToConditionList(DataModelConditionPredicateViewModel predicateViewModel) + public void ConvertToConditionList(DataModelConditionViewModel predicateViewModel) { // Store the old index and remove the old predicate int index = DataModelConditionGroup.Children.IndexOf(predicateViewModel.Model); @@ -147,7 +150,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions Update(); } - public void ConvertToConditionEvent(DataModelConditionPredicateViewModel predicateViewModel) + public void ConvertToConditionEvent(DataModelConditionViewModel predicateViewModel) { // Remove the old child DataModelConditionGroup.RemoveChild(predicateViewModel.Model); @@ -165,7 +168,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions Update(); } - public void ConvertToPredicate(DataModelConditionListViewModel listViewModel) + public void ConvertToPredicate(DataModelConditionViewModel listViewModel) { // Store the old index and remove the old predicate int index = DataModelConditionGroup.Children.IndexOf(listViewModel.Model); @@ -173,7 +176,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions // Insert a list in the same position DataModelConditionPredicate predicate = new DataModelConditionPredicate(DataModelConditionGroup, ProfileRightSideType.Dynamic); - predicate.UpdateLeftSide(listViewModel.TargetSelectionViewModel.DataModelPath); + predicate.UpdateLeftSide(listViewModel.LeftSideSelectionViewModel.DataModelPath); DataModelConditionGroup.AddChild(predicate, index); // Update to switch the VMs diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml index 7ad1e3265..667a15b2f 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml @@ -41,7 +41,7 @@ diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListViewModel.cs index ba875de53..7990bd83a 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListViewModel.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Linq; using System.Windows.Media; @@ -7,7 +6,6 @@ using Artemis.Core; using Artemis.UI.Ninject.Factories; using Artemis.UI.Screens.ProfileEditor.Conditions.Abstract; using Artemis.UI.Shared; -using Artemis.UI.Shared.Input; using Artemis.UI.Shared.Services; using Humanizer; @@ -18,7 +16,6 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory; private readonly IDataModelUIService _dataModelUIService; private readonly IProfileEditorService _profileEditorService; - private DataModelDynamicViewModel _targetSelectionViewModel; public DataModelConditionListViewModel( DataModelConditionList dataModelConditionList, @@ -33,22 +30,10 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions Initialize(); } - public DataModelDynamicViewModel TargetSelectionViewModel - { - get => _targetSelectionViewModel; - set => SetAndNotify(ref _targetSelectionViewModel, value); - } - public DataModelConditionList DataModelConditionList => (DataModelConditionList) Model; public string SelectedListOperator => DataModelConditionList.ListOperator.Humanize(); - public void Dispose() - { - TargetSelectionViewModel.Dispose(); - TargetSelectionViewModel.PropertySelected -= TargetSelectionViewModelOnPropertySelected; - } - public void SelectListOperator(string type) { ListOperator enumValue = Enum.Parse(type); @@ -82,38 +67,38 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions public void Initialize() { - TargetSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule()); - TargetSelectionViewModel.PropertySelected += TargetSelectionViewModelOnPropertySelected; + LeftSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule()); + 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<>)); - TargetSelectionViewModel.FilterTypes = supportedInputTypes.ToArray(); + LeftSideSelectionViewModel.FilterTypes = supportedInputTypes.ToArray(); - TargetSelectionViewModel.ButtonBrush = new SolidColorBrush(Color.FromRgb(71, 108, 188)); - TargetSelectionViewModel.Placeholder = "Select a list"; + LeftSideSelectionViewModel.ButtonBrush = new SolidColorBrush(Color.FromRgb(71, 108, 188)); + LeftSideSelectionViewModel.Placeholder = "Select a list"; Update(); } public void ApplyList() { - if (!TargetSelectionViewModel.DataModelPath.GetPropertyType().IsGenericEnumerable()) - { - if (Parent is DataModelConditionGroupViewModel groupViewModel) - groupViewModel.ConvertToPredicate(this); + Type newType = LeftSideSelectionViewModel.DataModelPath.GetPropertyType(); + bool converted = ConvertIfRequired(newType); + if (converted) return; - } - DataModelConditionList.UpdateList(TargetSelectionViewModel.DataModelPath); + + DataModelConditionList.UpdateList(LeftSideSelectionViewModel.DataModelPath); _profileEditorService.UpdateSelectedProfileElement(); Update(); } + public override void Update() { - TargetSelectionViewModel.ChangeDataModelPath(DataModelConditionList.ListPath); + LeftSideSelectionViewModel.ChangeDataModelPath(DataModelConditionList.ListPath); NotifyOfPropertyChange(nameof(SelectedListOperator)); // Remove VMs of effects no longer applied on the layer @@ -142,9 +127,15 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions childViewModel.Update(); } - private void TargetSelectionViewModelOnPropertySelected(object? sender, DataModelInputDynamicEventArgs e) + private void LeftSideSelectionViewModelOnPropertySelected(object? sender, DataModelInputDynamicEventArgs e) { ApplyList(); } + + public void Dispose() + { + LeftSideSelectionViewModel.Dispose(); + LeftSideSelectionViewModel.PropertySelected -= LeftSideSelectionViewModelOnPropertySelected; + } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionPredicateViewModel.cs index 11c7a36c7..a67214d63 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionPredicateViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionPredicateViewModel.cs @@ -18,7 +18,6 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions private readonly IConditionOperatorService _conditionOperatorService; private readonly IDataModelUIService _dataModelUIService; private readonly IProfileEditorService _profileEditorService; - private DataModelDynamicViewModel _leftSideSelectionViewModel; private BindableCollection _operators; private DataModelStaticViewModel _rightSideInputViewModel; private DataModelDynamicViewModel _rightSideSelectionViewModel; @@ -56,12 +55,6 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions set => SetAndNotify(ref _operators, value); } - public DataModelDynamicViewModel LeftSideSelectionViewModel - { - get => _leftSideSelectionViewModel; - set => SetAndNotify(ref _leftSideSelectionViewModel, value); - } - public BaseConditionOperator SelectedOperator { get => _selectedOperator; @@ -151,12 +144,10 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions public void ApplyLeftSide() { - if (LeftSideSelectionViewModel.DataModelPath.GetPropertyType().IsGenericEnumerable()) - { - if (Parent is DataModelConditionGroupViewModel groupViewModel) - groupViewModel.ConvertToConditionList(this); + Type newType = LeftSideSelectionViewModel.DataModelPath.GetPropertyType(); + bool converted = ConvertIfRequired(newType); + if (converted) return; - } DataModelConditionPredicate.UpdateLeftSide(LeftSideSelectionViewModel.DataModelPath); _profileEditorService.UpdateSelectedProfileElement();