From ef665115648015d018d061d9ec6f021bd13890b4 Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 4 Mar 2021 19:17:17 +0100 Subject: [PATCH] Data bindings - Update UI on registration changes Data bindings - Tweaked UI tabs to handle a large amount of properties better Color gradient property - Update data binding properties on stop add/remove --- .../Properties/ColorGradientLayerProperty.cs | 19 ++++++- .../Profile/LayerProperties/ILayerProperty.cs | 10 ++++ .../Profile/LayerProperties/LayerProperty.cs | 25 +++++++++ .../DataBindings/DataBindingViewModel.cs | 2 +- .../DataBindings/DataBindingsView.xaml | 9 +++- .../DataBindings/DataBindingsViewModel.cs | 54 +++++++++++++++++-- 6 files changed, 111 insertions(+), 8 deletions(-) diff --git a/src/Artemis.Core/DefaultTypes/Properties/ColorGradientLayerProperty.cs b/src/Artemis.Core/DefaultTypes/Properties/ColorGradientLayerProperty.cs index 931e4d03d..6eb4bdda2 100644 --- a/src/Artemis.Core/DefaultTypes/Properties/ColorGradientLayerProperty.cs +++ b/src/Artemis.Core/DefaultTypes/Properties/ColorGradientLayerProperty.cs @@ -1,10 +1,13 @@ -using SkiaSharp; +using System.ComponentModel; +using SkiaSharp; namespace Artemis.Core { /// public class ColorGradientLayerProperty : LayerProperty { + private ColorGradient? _subscribedGradient; + internal ColorGradientLayerProperty() { KeyframesSupported = false; @@ -53,9 +56,23 @@ namespace Artemis.Core if (BaseValue == null) BaseValue = DefaultValue ?? new ColorGradient(); + if (_subscribedGradient != BaseValue) + { + if (_subscribedGradient != null) + _subscribedGradient.PropertyChanged -= SubscribedGradientOnPropertyChanged; + _subscribedGradient = BaseValue; + _subscribedGradient.PropertyChanged += SubscribedGradientOnPropertyChanged; + } + CreateDataBindingRegistrations(); } + private void SubscribedGradientOnPropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (CurrentValue.Stops.Count != GetAllDataBindingRegistrations().Count) + CreateDataBindingRegistrations(); + } + #region Overrides of LayerProperty /// diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/ILayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/ILayerProperty.cs index 33153f4ef..c42b1f74c 100644 --- a/src/Artemis.Core/Models/Profile/LayerProperties/ILayerProperty.cs +++ b/src/Artemis.Core/Models/Profile/LayerProperties/ILayerProperty.cs @@ -97,6 +97,16 @@ namespace Artemis.Core /// public event EventHandler? KeyframeRemoved; + /// + /// Occurs when a data binding property has been added + /// + public event EventHandler? DataBindingPropertyRegistered; + + /// + /// Occurs when all data binding properties have been removed + /// + public event EventHandler? DataBindingPropertiesCleared; + /// /// Occurs when a data binding has been enabled /// diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs index fe93cbcb3..61f38c428 100644 --- a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs +++ b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs @@ -419,6 +419,8 @@ namespace Artemis.Core DataBindingRegistration registration = new(this, converter, getter, setter, displayName); _dataBindingRegistrations.Add(registration); + + OnDataBindingPropertyRegistered(); return registration; } @@ -431,6 +433,7 @@ namespace Artemis.Core throw new ObjectDisposedException("LayerProperty"); _dataBindingRegistrations.Clear(); + OnDataBindingPropertiesCleared(); } /// @@ -667,6 +670,12 @@ namespace Artemis.Core /// public event EventHandler? KeyframeRemoved; + /// + public event EventHandler? DataBindingPropertyRegistered; + + /// + public event EventHandler? DataBindingPropertiesCleared; + /// public event EventHandler? DataBindingEnabled; @@ -722,6 +731,22 @@ namespace Artemis.Core KeyframeRemoved?.Invoke(this, new LayerPropertyEventArgs(this)); } + /// + /// Invokes the event + /// + protected virtual void OnDataBindingPropertyRegistered() + { + DataBindingPropertyRegistered?.Invoke(this, new LayerPropertyEventArgs(this)); + } + + /// + /// Invokes the event + /// + protected virtual void OnDataBindingPropertiesCleared() + { + DataBindingPropertiesCleared?.Invoke(this, new LayerPropertyEventArgs(this)); + } + /// /// Invokes the event /// diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs index 105af6c65..b25710928 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingViewModel.cs @@ -102,8 +102,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings protected override void OnInitialActivate() { - base.OnInitialActivate(); Initialize(); + base.OnInitialActivate(); } private void Initialize() diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingsView.xaml b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingsView.xaml index 35e1c740c..164f28796 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingsView.xaml +++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingsView.xaml @@ -6,11 +6,18 @@ xmlns:s="https://github.com/canton7/Stylet" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> - + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingsViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingsViewModel.cs index 23e73dcd1..00c72fc34 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingsViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/DataBindingsViewModel.cs @@ -1,5 +1,8 @@ using System; using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Artemis.Core; using Artemis.UI.Ninject.Factories; using Artemis.UI.Shared.Services; @@ -11,7 +14,9 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings { private readonly IDataBindingsVmFactory _dataBindingsVmFactory; private readonly IProfileEditorService _profileEditorService; + private ILayerProperty? _selectedDataBinding; private int _selectedItemIndex; + private bool _updating; public DataBindingsViewModel(IProfileEditorService profileEditorService, IDataBindingsVmFactory dataBindingsVmFactory) { @@ -24,9 +29,10 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings get => _selectedItemIndex; set => SetAndNotify(ref _selectedItemIndex, value); } - + private void CreateDataBindingViewModels() { + int oldIndex = SelectedItemIndex; Items.Clear(); ILayerProperty layerProperty = _profileEditorService.SelectedDataBinding; @@ -37,26 +43,64 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings // Create a data binding VM for each data bindable property. These VMs will be responsible for retrieving // and creating the actual data bindings - foreach (IDataBindingRegistration registration in registrations) - Items.Add(_dataBindingsVmFactory.DataBindingViewModel(registration)); + Items.AddRange(registrations.Select(registration => _dataBindingsVmFactory.DataBindingViewModel(registration))); - SelectedItemIndex = 0; + SelectedItemIndex = Items.Count < oldIndex ? 0 : oldIndex; } private void ProfileEditorServiceOnSelectedDataBindingChanged(object sender, EventArgs e) { CreateDataBindingViewModels(); + SubscribeToSelectedDataBinding(); + + SelectedItemIndex = 0; + } + + private void SubscribeToSelectedDataBinding() + { + if (_selectedDataBinding != null) + { + _selectedDataBinding.DataBindingPropertyRegistered -= DataBindingRegistrationsChanged; + _selectedDataBinding.DataBindingPropertiesCleared -= DataBindingRegistrationsChanged; + } + + _selectedDataBinding = _profileEditorService.SelectedDataBinding; + if (_selectedDataBinding != null) + { + _selectedDataBinding.DataBindingPropertyRegistered += DataBindingRegistrationsChanged; + _selectedDataBinding.DataBindingPropertiesCleared += DataBindingRegistrationsChanged; + } + } + + private void DataBindingRegistrationsChanged(object sender, LayerPropertyEventArgs e) + { + if (_updating) + return; + + _updating = true; + Execute.PostToUIThread(async () => + { + await Task.Delay(200); + CreateDataBindingViewModels(); + _updating = false; + }); } #region Overrides of Screen - /// protected override void OnInitialActivate() { _profileEditorService.SelectedDataBindingChanged += ProfileEditorServiceOnSelectedDataBindingChanged; CreateDataBindingViewModels(); + SubscribeToSelectedDataBinding(); base.OnInitialActivate(); } + + protected override void OnActivate() + { + SelectedItemIndex = 0; + base.OnActivate(); + } protected override void OnClose() {