From 29463644632f2229770df3bd4d357a088dc26cf6 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 14 Oct 2020 19:04:56 +0200 Subject: [PATCH] Conditions - Implemented self referencing list conditions --- .../ListPredicateWrapperDataModel.cs | 1 + .../Input/DataModelDynamicView.xaml | 13 ++++-- .../Input/DataModelDynamicViewModel.cs | 46 +++++++++++++------ ...ataModelConditionListPredicateViewModel.cs | 11 +++-- 4 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/Artemis.Core/Models/Profile/Conditions/ListPredicateWrapperDataModel.cs b/src/Artemis.Core/Models/Profile/Conditions/ListPredicateWrapperDataModel.cs index 884dd77c0..7c436e8aa 100644 --- a/src/Artemis.Core/Models/Profile/Conditions/ListPredicateWrapperDataModel.cs +++ b/src/Artemis.Core/Models/Profile/Conditions/ListPredicateWrapperDataModel.cs @@ -5,6 +5,7 @@ namespace Artemis.Core { internal class ListPredicateWrapperDataModel : ListPredicateWrapperDataModel { + [DataModelProperty(Name = "List item", Description = "The current item in the list")] public T Value => (UntypedValue is T typedValue ? typedValue : default)!; } diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml index 829f89485..ed33a05da 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml +++ b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicView.xaml @@ -61,8 +61,8 @@ HorizontalAlignment="Left" Click="PropertyButton_OnClick"> - - + + - + + + + + + + + diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs index 8e8b9dadc..521302ee0 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Specialized; using System.Linq; using System.Timers; using System.Windows.Media; @@ -21,11 +22,11 @@ namespace Artemis.UI.Shared.Input private Brush _buttonBrush = new SolidColorBrush(Color.FromRgb(171, 71, 188)); private DataModelPath _dataModelPath; private DataModelPropertiesViewModel _dataModelViewModel; + private bool _displaySwitchButton; private Type[] _filterTypes; private bool _isDataModelViewModelOpen; private bool _isEnabled = true; private string _placeholder = "Select a property"; - private bool _displaySwitchButton; internal DataModelDynamicViewModel(Module module, ISettingsService settingsService, IDataModelUIService dataModelUIService) { @@ -33,6 +34,7 @@ namespace Artemis.UI.Shared.Input _dataModelUIService = dataModelUIService; _updateTimer = new Timer(500); + ExtraDataModelViewModels = new BindableCollection(); ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues"); SelectPropertyCommand = new DelegateCommand(ExecuteSelectPropertyCommand); @@ -73,6 +75,9 @@ namespace Artemis.UI.Shared.Input } } + public BindableCollection ExtraDataModelViewModels { get; } + public bool HasExtraDataModels => ExtraDataModelViewModels.Any(); + public DelegateCommand SelectPropertyCommand { get; } public PluginSetting ShowDataModelValues { get; } @@ -144,22 +149,11 @@ namespace Artemis.UI.Shared.Input // Get the data models DataModelViewModel = _dataModelUIService.GetPluginDataModelVisualization(_module, true); DataModelViewModel.UpdateRequested += DataModelOnUpdateRequested; - + ExtraDataModelViewModels.CollectionChanged += ExtraDataModelViewModelsOnCollectionChanged; _updateTimer.Start(); _updateTimer.Elapsed += OnUpdateTimerOnElapsed; } - private void DataModelOnUpdateRequested(object sender, EventArgs e) - { - DataModelViewModel.ApplyTypeFilter(true, FilterTypes); - } - - private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e) - { - if (IsDataModelViewModelOpen) - DataModelViewModel.Update(_dataModelUIService); - } - private void ExecuteSelectPropertyCommand(object context) { if (!(context is DataModelVisualizationViewModel selected)) @@ -178,6 +172,32 @@ namespace Artemis.UI.Shared.Input DataModelPath?.Dispose(); } + #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; + + DataModelViewModel.Update(_dataModelUIService); + foreach (DataModelPropertiesViewModel extraDataModelViewModel in ExtraDataModelViewModels) + extraDataModelViewModel.Update(_dataModelUIService); + } + + #endregion + #region Events public event EventHandler PropertySelected; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListPredicateViewModel.cs index bb6b3945f..829ddfcca 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListPredicateViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListPredicateViewModel.cs @@ -87,7 +87,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions public void Initialize() { - DataModelVisualizationViewModel listDataModel = GetListDataModel(); + DataModelPropertiesViewModel listDataModel = GetListDataModel(); if (listDataModel.Children.Count == 1 && listDataModel.Children.First() is DataModelListPropertyViewModel) _isPrimitiveList = true; else @@ -97,7 +97,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions if (!_isPrimitiveList) { LeftSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule()); - LeftSideSelectionViewModel.ChangeDataModel((DataModelPropertiesViewModel) listDataModel); + LeftSideSelectionViewModel.ChangeDataModel(listDataModel); LeftSideSelectionViewModel.PropertySelected += LeftSideOnPropertySelected; } @@ -194,7 +194,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions Update(); } - private DataModelVisualizationViewModel GetListDataModel() + private DataModelPropertiesViewModel GetListDataModel() { if (DataModelConditionListPredicate.DataModelConditionList.ListPath?.DataModelGuid == null) throw new ArtemisUIException("Failed to retrieve the list data model VM for this list predicate because it has no list path"); @@ -273,6 +273,11 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions RightSideSelectionViewModel.DisplaySwitchButton = true; RightSideSelectionViewModel.PropertySelected += RightSideOnPropertySelected; RightSideSelectionViewModel.SwitchToStaticRequested += RightSideSelectionViewModelOnSwitchToStaticRequested; + + // Add an extra data model to the selection VM to allow self-referencing the current item + // The safe cast prevents adding this extra VM on primitive lists where they serve no purpose + if (GetListDataModel()?.Children?.FirstOrDefault() is DataModelPropertiesViewModel listValue) + RightSideSelectionViewModel.ExtraDataModelViewModels.Add(listValue); } private void CreateRightSideInputViewModel(Type leftSideType)