From d03ca9c84a5377d4ce3897899c72ead2c1e07d61 Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Fri, 4 Sep 2020 20:24:34 +0200 Subject: [PATCH] Profile modules - Encapsulation fixes Data bindings - Abstracted the data model selection --- src/Artemis.Core/Plugins/Modules/Module.cs | 10 ++ .../Plugins/Modules/ProfileModule.cs | 31 +--- src/Artemis.Core/Services/CoreService.cs | 4 +- src/Artemis.Core/Utilities/IntroAnimation.cs | 10 ++ .../Converters/NullToVisibilityConverter.cs | 41 ++++++ .../DataModelSelectionView.xaml | 60 ++++++++ .../DataModelSelectionView.xaml.cs | 26 ++++ .../DataModelSelectionViewModel.cs | 134 ++++++++++++++++++ .../DataModelPropertySelectedEventArgs.cs | 14 ++ .../DisplayConditions.xaml | 99 +++++++++++++ .../Services/DataModelUIService.cs | 6 + .../Interfaces/IDataModelUIService.cs | 3 + .../Services/ProfileEditorService.cs | 2 +- .../Utilities/BindingProxy.cs | 26 ++++ .../Utilities/DelegateCommand.cs | 2 +- .../DataBindingModifierViewModel.cs | 60 ++------ .../DataBindings/DataBindingView.xaml | 43 +----- .../DataBindings/DataBindingViewModel.cs | 102 +++++-------- .../GeneralModule.cs | 8 +- .../OverlayModule.cs | 10 ++ 20 files changed, 502 insertions(+), 189 deletions(-) create mode 100644 src/Artemis.UI.Shared/Converters/NullToVisibilityConverter.cs create mode 100644 src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml create mode 100644 src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml.cs create mode 100644 src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionViewModel.cs create mode 100644 src/Artemis.UI.Shared/Events/DataModelPropertySelectedEventArgs.cs create mode 100644 src/Artemis.UI.Shared/ResourceDictionaries/DisplayConditions.xaml create mode 100644 src/Artemis.UI.Shared/Utilities/BindingProxy.cs rename src/{Artemis.UI => Artemis.UI.Shared}/Utilities/DelegateCommand.cs (96%) diff --git a/src/Artemis.Core/Plugins/Modules/Module.cs b/src/Artemis.Core/Plugins/Modules/Module.cs index 24a1fb3fd..31efee688 100644 --- a/src/Artemis.Core/Plugins/Modules/Module.cs +++ b/src/Artemis.Core/Plugins/Modules/Module.cs @@ -164,6 +164,16 @@ namespace Artemis.Core.Modules /// public abstract void ModuleDeactivated(bool isOverride); + internal virtual void InternalUpdate(double deltaTime) + { + Update(deltaTime); + } + + internal virtual void InternalRender(double deltaTime, ArtemisSurface surface, SKCanvas canvas, SKImageInfo canvasInfo) + { + Render(deltaTime, surface, canvas, canvasInfo); + } + /// /// Evaluates the activation requirements following the and returns the result /// diff --git a/src/Artemis.Core/Plugins/Modules/ProfileModule.cs b/src/Artemis.Core/Plugins/Modules/ProfileModule.cs index 96647abd9..9b7c303ff 100644 --- a/src/Artemis.Core/Plugins/Modules/ProfileModule.cs +++ b/src/Artemis.Core/Plugins/Modules/ProfileModule.cs @@ -118,15 +118,7 @@ namespace Artemis.Core.Modules /// Indicates whether or not a profile change is being animated /// public bool AnimatingProfileChange { get; private set; } - - /// - /// Called before the profile updates, this is the best place to perform data model updates - /// - /// Time in seconds since the last update - public virtual void ProfileUpdate(double deltaTime) - { - } - + /// /// Called after the profile has updated /// @@ -135,17 +127,6 @@ namespace Artemis.Core.Modules { } - /// - /// Called before the profile renders - /// - /// Time since the last render - /// The RGB Surface to render to - /// - /// - public virtual void ProfileRender(double deltaTime, ArtemisSurface surface, SKCanvas canvas, SKImageInfo canvasInfo) - { - } - /// /// Called after the profile has rendered /// @@ -157,10 +138,9 @@ namespace Artemis.Core.Modules { } - /// - public sealed override void Update(double deltaTime) + internal override void InternalUpdate(double deltaTime) { - ProfileUpdate(deltaTime); + Update(deltaTime); lock (this) { @@ -176,10 +156,9 @@ namespace Artemis.Core.Modules ProfileUpdated(deltaTime); } - /// - public sealed override void Render(double deltaTime, ArtemisSurface surface, SKCanvas canvas, SKImageInfo canvasInfo) + internal override void InternalRender(double deltaTime, ArtemisSurface surface, SKCanvas canvas, SKImageInfo canvasInfo) { - ProfileRender(deltaTime, surface, canvas, canvasInfo); + Render(deltaTime, surface, canvas, canvasInfo); lock (this) { diff --git a/src/Artemis.Core/Services/CoreService.cs b/src/Artemis.Core/Services/CoreService.cs index 955a5f12f..1c739c425 100644 --- a/src/Artemis.Core/Services/CoreService.cs +++ b/src/Artemis.Core/Services/CoreService.cs @@ -174,7 +174,7 @@ namespace Artemis.Core.Services // Update all active modules foreach (var module in modules) - module.Update(args.DeltaTime); + module.InternalUpdate(args.DeltaTime); // If there is no ready bitmap brush, skip the frame if (_rgbService.BitmapBrush == null) @@ -192,7 +192,7 @@ namespace Artemis.Core.Services { // While non-activated modules may be updated above if they expand the main data model, they may never render foreach (var module in modules.Where(m => m.IsActivated)) - module.Render(args.DeltaTime, _surfaceService.ActiveSurface, canvas, _rgbService.BitmapBrush.Bitmap.Info); + module.InternalRender(args.DeltaTime, _surfaceService.ActiveSurface, canvas, _rgbService.BitmapBrush.Bitmap.Info); } OnFrameRendering(new FrameRenderingEventArgs(modules, canvas, args.DeltaTime, _rgbService.Surface)); diff --git a/src/Artemis.Core/Utilities/IntroAnimation.cs b/src/Artemis.Core/Utilities/IntroAnimation.cs index 6fd8fff60..745e3a063 100644 --- a/src/Artemis.Core/Utilities/IntroAnimation.cs +++ b/src/Artemis.Core/Utilities/IntroAnimation.cs @@ -77,6 +77,16 @@ namespace Artemis.Core throw new NotImplementedException(); } + public override void Update(double deltaTime) + { + throw new NotImplementedException(); + } + + public override void Render(double deltaTime, ArtemisSurface surface, SKCanvas canvas, SKImageInfo canvasInfo) + { + throw new NotImplementedException(); + } + public override void ModuleActivated(bool isOverride) { throw new NotImplementedException(); diff --git a/src/Artemis.UI.Shared/Converters/NullToVisibilityConverter.cs b/src/Artemis.UI.Shared/Converters/NullToVisibilityConverter.cs new file mode 100644 index 000000000..2d9f9200e --- /dev/null +++ b/src/Artemis.UI.Shared/Converters/NullToVisibilityConverter.cs @@ -0,0 +1,41 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace Artemis.UI.Shared +{ + public class NullToVisibilityConverter : 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); + + if (direction == Parameters.Normal) + { + if (value == null) + return Visibility.Collapsed; + return Visibility.Visible; + } + + if (value == null) + return Visibility.Visible; + return Visibility.Collapsed; + } + + 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/DataModelSelectionView.xaml b/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml new file mode 100644 index 000000000..f74af0f0b --- /dev/null +++ b/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml.cs b/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml.cs new file mode 100644 index 000000000..fc0034294 --- /dev/null +++ b/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionView.xaml.cs @@ -0,0 +1,26 @@ +using System.Windows; +using System.Windows.Controls; + +namespace Artemis.UI.Shared +{ + /// + /// Interaction logic for DataModelSelectionView.xaml + /// + public partial class DataModelSelectionView : UserControl + { + public DataModelSelectionView() + { + 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/DataModelSelectionViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionViewModel.cs new file mode 100644 index 000000000..029290827 --- /dev/null +++ b/src/Artemis.UI.Shared/DataModelVisualization/DataModelSelectionViewModel.cs @@ -0,0 +1,134 @@ +using System; +using System.Timers; +using System.Windows.Media; +using Artemis.Core; +using Artemis.Core.DataModelExpansions; +using Artemis.Core.Modules; +using Artemis.Core.Services; +using Artemis.UI.Shared.Services; +using Stylet; + +// Remove, annoying while working on it +#pragma warning disable 1591 + +namespace Artemis.UI.Shared +{ + public class DataModelSelectionViewModel : PropertyChangedBase + { + private readonly IDataModelUIService _dataModelUIService; + private readonly Module _module; + private readonly Timer _updateTimer; + private Brush _buttonBrush = new SolidColorBrush(Color.FromRgb(171, 71, 188)); + + private DataModelPropertiesViewModel _dataModelViewModel; + private bool _isDataModelViewModelOpen; + private bool _isEnabled; + private string _placeholder = "Select a property"; + private DataModelVisualizationViewModel _selectedPropertyViewModel; + + public DataModelSelectionViewModel(Module module, ISettingsService settingsService, IDataModelUIService dataModelUIService) + { + _module = module; + _dataModelUIService = dataModelUIService; + _updateTimer = new Timer(500); + + ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues"); + SelectPropertyCommand = new DelegateCommand(ExecuteSelectPropertyCommand); + + Initialize(); + } + + public string Placeholder + { + get => _placeholder; + set => SetAndNotify(ref _placeholder, value); + } + + public Brush ButtonBrush + { + get => _buttonBrush; + set => SetAndNotify(ref _buttonBrush, value); + } + + public DelegateCommand SelectPropertyCommand { get; } + public Type[] FilterTypes { get; set; } + + public PluginSetting ShowDataModelValues { get; } + + public bool IsEnabled + { + get => _isEnabled; + set => SetAndNotify(ref _isEnabled, value); + } + + public DataModelPropertiesViewModel DataModelViewModel + { + get => _dataModelViewModel; + private set => SetAndNotify(ref _dataModelViewModel, value); + } + + public bool IsDataModelViewModelOpen + { + get => _isDataModelViewModelOpen; + set => SetAndNotify(ref _isDataModelViewModelOpen, value); + } + + public DataModelVisualizationViewModel SelectedPropertyViewModel + { + get => _selectedPropertyViewModel; + private set => SetAndNotify(ref _selectedPropertyViewModel, value); + } + + public void PopulateSelectedPropertyViewModel(DataModel datamodel, string path) + { + if (datamodel == null) + SelectedPropertyViewModel = null; + else + SelectedPropertyViewModel = DataModelViewModel.GetChildByPath(datamodel.PluginInfo.Guid, path); + } + + private void Initialize() + { + // Get the data models + DataModelViewModel = _dataModelUIService.GetMainDataModelVisualization(); + if (!_dataModelUIService.GetPluginExtendsDataModel(_module)) + DataModelViewModel.Children.Add(_dataModelUIService.GetPluginDataModelVisualization(_module)); + + DataModelViewModel.UpdateRequested += DataModelOnUpdateRequested; + + _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)) + return; + + SelectedPropertyViewModel = selected; + OnPropertySelected(new DataModelPropertySelectedEventArgs(selected)); + } + + #region Events + + public event EventHandler PropertySelected; + + protected virtual void OnPropertySelected(DataModelPropertySelectedEventArgs e) + { + PropertySelected?.Invoke(this, e); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Events/DataModelPropertySelectedEventArgs.cs b/src/Artemis.UI.Shared/Events/DataModelPropertySelectedEventArgs.cs new file mode 100644 index 000000000..81bb38629 --- /dev/null +++ b/src/Artemis.UI.Shared/Events/DataModelPropertySelectedEventArgs.cs @@ -0,0 +1,14 @@ +using System; + +namespace Artemis.UI.Shared +{ + public class DataModelPropertySelectedEventArgs : EventArgs + { + public DataModelVisualizationViewModel DataModelVisualizationViewModel { get; } + + public DataModelPropertySelectedEventArgs(DataModelVisualizationViewModel dataModelVisualizationViewModel) + { + DataModelVisualizationViewModel = dataModelVisualizationViewModel; + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI.Shared/ResourceDictionaries/DisplayConditions.xaml b/src/Artemis.UI.Shared/ResourceDictionaries/DisplayConditions.xaml new file mode 100644 index 000000000..d2834694b --- /dev/null +++ b/src/Artemis.UI.Shared/ResourceDictionaries/DisplayConditions.xaml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 3c64279b5..b8ead4820 100644 --- a/src/Artemis.UI.Shared/Services/DataModelUIService.cs +++ b/src/Artemis.UI.Shared/Services/DataModelUIService.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using Artemis.Core; using Artemis.Core.DataModelExpansions; +using Artemis.Core.Modules; using Artemis.Core.Services; using Ninject; using Ninject.Parameters; @@ -178,6 +179,11 @@ namespace Artemis.UI.Shared.Services } } + public DataModelSelectionViewModel GetDataModelSelectionViewModel(Module module) + { + return _kernel.Get(new ConstructorArgument("module", module)); + } + private DataModelInputViewModel InstantiateDataModelInputViewModel(DataModelVisualizationRegistration registration, DataModelPropertyAttribute description, object initialValue) { // The view models expecting value types shouldn't be given null, avoid that diff --git a/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs b/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs index be41d13e6..f4ee8cc13 100644 --- a/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs +++ b/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Artemis.Core; using Artemis.Core.DataModelExpansions; +using Artemis.Core.Modules; namespace Artemis.UI.Shared.Services { @@ -26,5 +27,7 @@ namespace Artemis.UI.Shared.Services DataModelDisplayViewModel GetDataModelDisplayViewModel(Type propertyType); DataModelInputViewModel GetDataModelInputViewModel(Type propertyType, DataModelPropertyAttribute description, object initialValue, Action updateCallback); + + DataModelSelectionViewModel GetDataModelSelectionViewModel(Module module); } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Services/ProfileEditorService.cs b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs index 41c1dd27c..5c2395661 100644 --- a/src/Artemis.UI.Shared/Services/ProfileEditorService.cs +++ b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs @@ -201,7 +201,7 @@ namespace Artemis.UI.Shared.Services if (existing != null) { if (existing.PluginInfo != pluginInfo) - throw new ArtemisPluginException($"Cannot register property editor for type {supportedType.Name} because an editor was already registered by {pluginInfo.Name}"); + throw new ArtemisPluginException($"Cannot register property editor for type {supportedType.Name} because an editor was already registered by {existing.PluginInfo.Name}"); return existing; } diff --git a/src/Artemis.UI.Shared/Utilities/BindingProxy.cs b/src/Artemis.UI.Shared/Utilities/BindingProxy.cs new file mode 100644 index 000000000..df793d3a7 --- /dev/null +++ b/src/Artemis.UI.Shared/Utilities/BindingProxy.cs @@ -0,0 +1,26 @@ +using System.Windows; + +namespace Artemis.UI.Shared +{ + internal class BindingProxy : Freezable + { + // Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc... + public static readonly DependencyProperty DataProperty = + DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null)); + + public object Data + { + get => GetValue(DataProperty); + set => SetValue(DataProperty, value); + } + + #region Overrides of Freezable + + protected override Freezable CreateInstanceCore() + { + return new BindingProxy(); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Utilities/DelegateCommand.cs b/src/Artemis.UI.Shared/Utilities/DelegateCommand.cs similarity index 96% rename from src/Artemis.UI/Utilities/DelegateCommand.cs rename to src/Artemis.UI.Shared/Utilities/DelegateCommand.cs index a02801494..8d43df606 100644 --- a/src/Artemis.UI/Utilities/DelegateCommand.cs +++ b/src/Artemis.UI.Shared/Utilities/DelegateCommand.cs @@ -1,7 +1,7 @@ using System; using System.Windows.Input; -namespace Artemis.UI.Utilities +namespace Artemis.UI.Shared { public class DelegateCommand : ICommand { diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierViewModel.cs index c913f2aea..3b76ea7e4 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingModifierViewModel.cs @@ -1,11 +1,8 @@ -using System; -using System.Threading.Tasks; -using System.Timers; +using System.Threading.Tasks; using Artemis.Core; using Artemis.Core.Services; using Artemis.UI.Shared; using Artemis.UI.Shared.Services; -using Artemis.UI.Utilities; using Stylet; namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings @@ -15,11 +12,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings private readonly IDataBindingService _dataBindingService; private readonly IDataModelUIService _dataModelUIService; private readonly IProfileEditorService _profileEditorService; - private readonly Timer _updateTimer; - private DataModelPropertiesViewModel _parameterDataModel; - private bool _parameterDataModelOpen; private DataBindingModifierType _selectedModifierType; - private DataModelVisualizationViewModel _selectedParameterProperty; public DataBindingModifierViewModel(DataBindingModifier modifier, IDataBindingService dataBindingService, @@ -30,7 +23,6 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings _dataBindingService = dataBindingService; _dataModelUIService = dataModelUIService; _profileEditorService = profileEditorService; - _updateTimer = new Timer(500); ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues"); @@ -55,37 +47,20 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings set => SetAndNotify(ref _selectedModifierType, value); } - public DataModelPropertiesViewModel ParameterDataModel - { - get => _parameterDataModel; - set => SetAndNotify(ref _parameterDataModel, value); - } - - public bool ParameterDataModelOpen - { - get => _parameterDataModelOpen; - set => SetAndNotify(ref _parameterDataModelOpen, value); - } - - public DataModelVisualizationViewModel SelectedParameterProperty - { - get => _selectedParameterProperty; - set => SetAndNotify(ref _selectedParameterProperty, value); - } + public DataModelSelectionViewModel ParameterSelectionViewModel { get; private set; } private void Initialize() { - // Get the data models - ParameterDataModel = _dataModelUIService.GetMainDataModelVisualization(); - if (!_dataModelUIService.GetPluginExtendsDataModel(_profileEditorService.GetCurrentModule())) - ParameterDataModel.Children.Add(_dataModelUIService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule())); - - ParameterDataModel.UpdateRequested += ParameterDataModelOnUpdateRequested; + ParameterSelectionViewModel = _dataModelUIService.GetDataModelSelectionViewModel(_profileEditorService.GetCurrentModule()); + ParameterSelectionViewModel.PropertySelected += ParameterSelectionViewModelOnPropertySelected; + ParameterSelectionViewModel.FilterTypes = new[] {Modifier.DataBinding.TargetProperty.PropertyType}; Update(); + } - _updateTimer.Start(); - _updateTimer.Elapsed += OnUpdateTimerOnElapsed; + private void ParameterSelectionViewModelOnPropertySelected(object sender, DataModelPropertySelectedEventArgs e) + { + Modifier.UpdateParameter(e.DataModelVisualizationViewModel.DataModel, e.DataModelVisualizationViewModel.PropertyPath); } private void Update() @@ -95,11 +70,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings ModifierTypes.AddRange(_dataBindingService.GetCompatibleModifierTypes(Modifier.DataBinding.TargetProperty.PropertyType)); SelectedModifierType = Modifier.ModifierType; - // Determine the parameter property - if (Modifier.ParameterDataModel == null) - SelectedParameterProperty = null; - else - SelectedParameterProperty = ParameterDataModel.GetChildByPath(Modifier.ParameterDataModel.PluginInfo.Guid, Modifier.ParameterPropertyPath); + ParameterSelectionViewModel.PopulateSelectedPropertyViewModel(Modifier.ParameterDataModel, Modifier.ParameterPropertyPath); } private void ExecuteSelectModifierTypeCommand(object context) @@ -112,16 +83,5 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings Update(); } - - private void ParameterDataModelOnUpdateRequested(object sender, EventArgs e) - { - ParameterDataModel.ApplyTypeFilter(true, Modifier.DataBinding.TargetProperty.PropertyType); - } - - private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e) - { - if (ParameterDataModelOpen) - ParameterDataModel.Update(_dataModelUIService); - } } } \ 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 5fdae3f3d..38e7f3806 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml +++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingView.xaml @@ -16,18 +16,6 @@ - - - - - - - - - - - - @@ -49,36 +37,7 @@ - + (); DataBinding = layerProperty.DataBindings.FirstOrDefault(d => d.TargetProperty == targetProperty); - ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues"); + ModifierViewModels = new BindableCollection(); _isDataBindingEnabled = DataBinding != null; // Initialize async, no need to wait for it - Task.Run(Initialize); + Execute.PostToUIThread(Initialize); } - public DataModelPropertiesViewModel SourceDataModel - { - get => _sourceDataModel; - set => SetAndNotify(ref _sourceDataModel, value); - } - - public bool SourceDataModelOpen - { - get => _sourceDataModelOpen; - set => SetAndNotify(ref _sourceDataModelOpen, value); - } - - public DataModelVisualizationViewModel SelectedSourceProperty - { - get => _selectedSourceProperty; - set => SetAndNotify(ref _selectedSourceProperty, value); - } - - public PluginSetting ShowDataModelValues { get; } public BaseLayerProperty LayerProperty { get; } public PropertyInfo TargetProperty { get; } public string DisplayName { get; } public BindableCollection ModifierViewModels { get; } - public DelegateCommand SelectSourcePropertyCommand { get; } + public DataModelSelectionViewModel TargetSelectionViewModel + { + get => _targetSelectionViewModel; + private set => SetAndNotify(ref _targetSelectionViewModel, value); + } public bool IsDataBindingEnabled { @@ -105,12 +88,25 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings } } + public object TestInputValue + { + get => _testInputValue; + set => SetAndNotify(ref _testInputValue, value); + } + + public object TestResultValue + { + get => _testResultValue; + set => SetAndNotify(ref _testResultValue, value); + } + public void EnableDataBinding() { if (DataBinding != null) return; DataBinding = LayerProperty.AddDataBinding(TargetProperty); + Update(); } public void RemoveDataBinding() @@ -121,6 +117,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings var toRemove = DataBinding; DataBinding = null; LayerProperty.RemoveDataBinding(toRemove); + Update(); } public void AddModifier() @@ -136,12 +133,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings private void Initialize() { - // Get the data models - SourceDataModel = _dataModelUIService.GetMainDataModelVisualization(); - if (!_dataModelUIService.GetPluginExtendsDataModel(_profileEditorService.GetCurrentModule())) - SourceDataModel.Children.Add(_dataModelUIService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule())); - - SourceDataModel.UpdateRequested += SourceDataModelOnUpdateRequested; + TargetSelectionViewModel = _dataModelUIService.GetDataModelSelectionViewModel(_profileEditorService.GetCurrentModule()); + TargetSelectionViewModel.PropertySelected += TargetSelectionViewModelOnPropertySelected; Update(); @@ -151,31 +144,30 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings private void Update() { - if (DataBinding == null || SourceDataModel == null) + if (DataBinding == null) + { + TargetSelectionViewModel.IsEnabled = false; return; + } - // Determine the source property - if (DataBinding.SourceDataModel == null) - SelectedSourceProperty = null; - else - SelectedSourceProperty = SourceDataModel.GetChildByPath(DataBinding.SourceDataModel.PluginInfo.Guid, DataBinding.SourcePropertyPath); + TargetSelectionViewModel.IsEnabled = true; + TargetSelectionViewModel.PopulateSelectedPropertyViewModel(DataBinding.SourceDataModel, DataBinding.SourcePropertyPath); + TargetSelectionViewModel.FilterTypes = new[] {DataBinding.TargetProperty.PropertyType}; } - private void SourceDataModelOnUpdateRequested(object sender, EventArgs e) + private void TargetSelectionViewModelOnPropertySelected(object sender, DataModelPropertySelectedEventArgs e) { - SourceDataModel.ApplyTypeFilter(true, DataBinding.TargetProperty.PropertyType); + DataBinding.UpdateSource(e.DataModelVisualizationViewModel.DataModel, e.DataModelVisualizationViewModel.PropertyPath); } private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e) { UpdateTestResult(); - if (SourceDataModelOpen) - SourceDataModel.Update(_dataModelUIService); } private void UpdateTestResult() { - var currentValue = SelectedSourceProperty?.GetCurrentValue(); + var currentValue = TargetSelectionViewModel.SelectedPropertyViewModel?.GetCurrentValue(); if (currentValue == null && TargetProperty.PropertyType.IsValueType) currentValue = Activator.CreateInstance(TargetProperty.PropertyType); @@ -183,18 +175,6 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings TestResultValue = DataBinding?.GetValue(TestInputValue); } - public object TestInputValue - { - get => _testInputValue; - set => SetAndNotify(ref _testInputValue, value); - } - - public object TestResultValue - { - get => _testResultValue; - set => SetAndNotify(ref _testResultValue, value); - } - private void UpdateModifierViewModels() { ModifierViewModels.Clear(); @@ -205,15 +185,5 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings ModifierViewModels.Add(_dataBindingsVmFactory.DataBindingModifierViewModel(dataBindingModifier)); } - private void ExecuteSelectSourceProperty(object context) - { - if (!(context is DataModelVisualizationViewModel selected)) - return; - - DataBinding.UpdateSource(selected.DataModel, selected.PropertyPath); - _profileEditorService.UpdateSelectedProfileElement(); - - Update(); - } } } \ No newline at end of file diff --git a/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs b/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs index 32f1455fa..92b7ae2f8 100644 --- a/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs +++ b/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using Artemis.Core; using Artemis.Core.Modules; using Artemis.Plugins.Modules.General.DataModels; using Artemis.Plugins.Modules.General.DataModels.Windows; using Artemis.Plugins.Modules.General.Utilities; using Artemis.Plugins.Modules.General.ViewModels; +using SkiaSharp; namespace Artemis.Plugins.Modules.General { @@ -36,7 +38,7 @@ namespace Artemis.Plugins.Modules.General { } - public override void ProfileUpdate(double deltaTime) + public override void Update(double deltaTime) { DataModel.TimeDataModel.CurrentTime = DateTime.Now; DataModel.TimeDataModel.CurrentTimeUTC = DateTime.UtcNow; @@ -44,6 +46,10 @@ namespace Artemis.Plugins.Modules.General UpdateCurrentWindow(); } + public override void Render(double deltaTime, ArtemisSurface surface, SKCanvas canvas, SKImageInfo canvasInfo) + { + } + #region Open windows public void UpdateCurrentWindow() diff --git a/src/Plugins/Artemis.Plugins.Modules.Overlay/OverlayModule.cs b/src/Plugins/Artemis.Plugins.Modules.Overlay/OverlayModule.cs index e4dd3859e..aa9f5f56b 100644 --- a/src/Plugins/Artemis.Plugins.Modules.Overlay/OverlayModule.cs +++ b/src/Plugins/Artemis.Plugins.Modules.Overlay/OverlayModule.cs @@ -1,6 +1,8 @@ using System; using System.IO; +using Artemis.Core; using Artemis.Core.Modules; +using SkiaSharp; namespace Artemis.Plugins.Modules.Overlay { @@ -37,5 +39,13 @@ namespace Artemis.Plugins.Modules.Overlay { // When this gets called your activation requirements are no longer met and your module will stop displaying } + + public override void Update(double deltaTime) + { + } + + public override void Render(double deltaTime, ArtemisSurface surface, SKCanvas canvas, SKImageInfo canvasInfo) + { + } } } \ No newline at end of file