From eac08050bca5e95d3f40d380ec25c536a9b29097 Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 24 Apr 2022 22:05:29 +0200 Subject: [PATCH] UI - Streamlined VM names --- src/.idea/.idea.Artemis/.idea/avalonia.xml | 2 + .../Extensions/LayerPropertyExtensions.cs | 24 +++++ .../BrushConfigurationViewModel.cs | 2 +- .../EffectConfigurationViewModel.cs | 2 +- .../Plugins/PluginConfigurationViewModel.cs | 2 +- src/Artemis.UI.Shared/ViewModelBase.cs | 90 +++++++++---------- .../Extensions/DataBindingExtensions.cs | 2 +- .../DataBinding/DataBindingViewModel.cs | 4 +- .../Properties/Tree/TreePropertyViewModel.cs | 2 +- 9 files changed, 76 insertions(+), 54 deletions(-) create mode 100644 src/Artemis.UI.Shared/Extensions/LayerPropertyExtensions.cs diff --git a/src/.idea/.idea.Artemis/.idea/avalonia.xml b/src/.idea/.idea.Artemis/.idea/avalonia.xml index 2097abb8a..248ae2e68 100644 --- a/src/.idea/.idea.Artemis/.idea/avalonia.xml +++ b/src/.idea/.idea.Artemis/.idea/avalonia.xml @@ -14,8 +14,10 @@ + + diff --git a/src/Artemis.UI.Shared/Extensions/LayerPropertyExtensions.cs b/src/Artemis.UI.Shared/Extensions/LayerPropertyExtensions.cs new file mode 100644 index 000000000..5e9e04932 --- /dev/null +++ b/src/Artemis.UI.Shared/Extensions/LayerPropertyExtensions.cs @@ -0,0 +1,24 @@ +using System; +using System.Reactive.Linq; +using Artemis.Core; + +namespace Artemis.UI.Shared.Extensions; + +/// +/// Provides utilities when working with layer properties in a UI context. +/// +public static class LayerPropertyExtensions +{ + /// + /// Returns an observable sequence of layer property values starting with the current value. + /// + /// The layer property to create the sequence of. + /// The value type of the layer property. + /// An observable sequence of layer property values starting with the current value. + public static IObservable AsObservable(this LayerProperty layerProperty) + { + return Observable.FromEventPattern(x => layerProperty.Updated += x, x => layerProperty.Updated -= x) + .Select(_ => layerProperty.CurrentValue) + .StartWith(layerProperty.CurrentValue); + } +} \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Plugins/LayerBrushes/BrushConfigurationViewModel.cs b/src/Artemis.UI.Shared/Plugins/LayerBrushes/BrushConfigurationViewModel.cs index 73f045f94..14bb2b272 100644 --- a/src/Artemis.UI.Shared/Plugins/LayerBrushes/BrushConfigurationViewModel.cs +++ b/src/Artemis.UI.Shared/Plugins/LayerBrushes/BrushConfigurationViewModel.cs @@ -7,7 +7,7 @@ namespace Artemis.UI.Shared.LayerBrushes /// /// Represents a view model for a brush configuration window /// - public abstract class BrushConfigurationViewModel : ActivatableViewModelBase + public abstract class BrushConfigurationViewModel : ValidatableViewModelBase { /// /// Creates a new instance of the class diff --git a/src/Artemis.UI.Shared/Plugins/LayerEffects/EffectConfigurationViewModel.cs b/src/Artemis.UI.Shared/Plugins/LayerEffects/EffectConfigurationViewModel.cs index 2645faddc..63bb76735 100644 --- a/src/Artemis.UI.Shared/Plugins/LayerEffects/EffectConfigurationViewModel.cs +++ b/src/Artemis.UI.Shared/Plugins/LayerEffects/EffectConfigurationViewModel.cs @@ -8,7 +8,7 @@ namespace Artemis.UI.Shared.LayerEffects; /// /// Represents a view model for an effect configuration window /// -public abstract class EffectConfigurationViewModel : ActivatableViewModelBase +public abstract class EffectConfigurationViewModel : ValidatableViewModelBase { /// /// Creates a new instance of the class diff --git a/src/Artemis.UI.Shared/Plugins/PluginConfigurationViewModel.cs b/src/Artemis.UI.Shared/Plugins/PluginConfigurationViewModel.cs index 4fcfaa4fd..26f3f01a1 100644 --- a/src/Artemis.UI.Shared/Plugins/PluginConfigurationViewModel.cs +++ b/src/Artemis.UI.Shared/Plugins/PluginConfigurationViewModel.cs @@ -6,7 +6,7 @@ namespace Artemis.UI.Shared /// /// Represents a view model for a plugin configuration window /// - public abstract class PluginConfigurationViewModel : ViewModelValidationBase, IPluginConfigurationViewModel + public abstract class PluginConfigurationViewModel : ValidatableViewModelBase, IPluginConfigurationViewModel { /// /// Creates a new instance of the class diff --git a/src/Artemis.UI.Shared/ViewModelBase.cs b/src/Artemis.UI.Shared/ViewModelBase.cs index 6d68c4b9e..7f7a0dca0 100644 --- a/src/Artemis.UI.Shared/ViewModelBase.cs +++ b/src/Artemis.UI.Shared/ViewModelBase.cs @@ -12,7 +12,7 @@ namespace Artemis.UI.Shared; /// /// Represents the base class for Artemis view models /// -public abstract class ContentDialogViewModelBase : ReactiveValidationObject, IActivatableViewModel, IDisposable +public abstract class ContentDialogViewModelBase : ValidatableViewModelBase, IDisposable { /// /// Gets the content dialog that hosts the view model @@ -29,14 +29,7 @@ public abstract class ContentDialogViewModelBase : ReactiveValidationObject, IAc protected virtual void Dispose(bool disposing) { } - - #region Implementation of IActivatableViewModel - - /// - public ViewModelActivator Activator { get; } = new(); - - #endregion - + /// public void Dispose() { @@ -46,9 +39,35 @@ public abstract class ContentDialogViewModelBase : ReactiveValidationObject, IAc } /// -/// Represents the base class for Artemis view models +/// Represents the base class for Artemis view models used to drive dialogs /// -public abstract class ViewModelValidationBase : ReactiveValidationObject +public abstract class DialogViewModelBase : ValidatableViewModelBase +{ + /// + /// Closes the dialog with the given + /// + /// The result of the dialog + public void Close(TResult result) + { + CloseRequested?.Invoke(this, new DialogClosedEventArgs(result)); + } + + /// + /// Closes the dialog without a result + /// + public void Cancel() + { + CancelRequested?.Invoke(this, EventArgs.Empty); + } + + internal event EventHandler>? CloseRequested; + internal event EventHandler? CancelRequested; +} + +/// +/// Represents the base class for Artemis view models that are interested in validation and the activated event +/// +public abstract class ValidatableViewModelBase : ReactiveValidationObject, IActivatableViewModel { private string? _displayName; @@ -60,7 +79,10 @@ public abstract class ViewModelValidationBase : ReactiveValidationObject get => _displayName; set => RaiseAndSetIfChanged(ref _displayName, value); } - + + /// + public ViewModelActivator Activator { get; } = new(); + /// /// RaiseAndSetIfChanged fully implements a Setter for a read-write property on a ReactiveObject, using /// CallerMemberName to raise the notification and the ref to the backing field to set the property. @@ -89,6 +111,15 @@ public abstract class ViewModelValidationBase : ReactiveValidationObject } } +/// +/// Represents the base class for Artemis view models that are interested in the activated event +/// +public abstract class ActivatableViewModelBase : ViewModelBase, IActivatableViewModel +{ + /// + public ViewModelActivator Activator { get; } = new(); +} + /// /// Represents the base class for Artemis view models /// @@ -131,39 +162,4 @@ public abstract class ViewModelBase : ReactiveObject this.RaisePropertyChanged(propertyName); return newValue; } -} - -/// -/// Represents the base class for Artemis view models that are interested in the activated event -/// -public abstract class ActivatableViewModelBase : ViewModelBase, IActivatableViewModel -{ - /// - public ViewModelActivator Activator { get; } = new(); -} - -/// -/// Represents the base class for Artemis view models used to drive dialogs -/// -public abstract class DialogViewModelBase : ActivatableViewModelBase -{ - /// - /// Closes the dialog with the given - /// - /// The result of the dialog - public void Close(TResult result) - { - CloseRequested?.Invoke(this, new DialogClosedEventArgs(result)); - } - - /// - /// Closes the dialog without a result - /// - public void Cancel() - { - CancelRequested?.Invoke(this, EventArgs.Empty); - } - - internal event EventHandler>? CloseRequested; - internal event EventHandler? CancelRequested; } \ No newline at end of file diff --git a/src/Artemis.UI/Extensions/DataBindingExtensions.cs b/src/Artemis.UI/Extensions/DataBindingExtensions.cs index f1fac8eeb..7274fcc8d 100644 --- a/src/Artemis.UI/Extensions/DataBindingExtensions.cs +++ b/src/Artemis.UI/Extensions/DataBindingExtensions.cs @@ -6,7 +6,7 @@ namespace Artemis.UI.Extensions; public static class DataBindingExtensions { - public static IObservable GetObservable(this IDataBinding dataBinding) + public static IObservable AsObservable(this IDataBinding dataBinding) { return Observable.FromEventPattern(x => dataBinding.DataBindingEnabled += x, x => dataBinding.DataBindingEnabled -= x) .Merge(Observable.FromEventPattern(x => dataBinding.DataBindingDisabled += x, x => dataBinding.DataBindingDisabled -= x)) diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingViewModel.cs index 17bacc216..eb3feee92 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingViewModel.cs @@ -30,13 +30,13 @@ public class DataBindingViewModel : ActivatableViewModelBase { _layerProperty = profileEditorService.LayerProperty.ToProperty(this, vm => vm.LayerProperty).DisposeWith(d); _nodeScriptViewModel = profileEditorService.LayerProperty - .Select(p => p != null ? p.BaseDataBinding.GetObservable() : Observable.Never()) + .Select(p => p != null ? p.BaseDataBinding.AsObservable() : Observable.Never()) .Switch() .Select(b => b.IsEnabled ? nodeVmFactory.NodeScriptViewModel((NodeScript) b.Script, false) : null) .ToProperty(this, vm => vm.NodeScriptViewModel) .DisposeWith(d); _dataBindingEnabled = profileEditorService.LayerProperty - .Select(p => p != null ? p.BaseDataBinding.GetObservable() : Observable.Never()) + .Select(p => p != null ? p.BaseDataBinding.AsObservable() : Observable.Never()) .Switch() .Select(b => b.IsEnabled) .ToProperty(this, vm => vm.DataBindingEnabled) diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyViewModel.cs index fe4dd8a60..056a0c146 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyViewModel.cs @@ -31,7 +31,7 @@ internal class TreePropertyViewModel : ActivatableViewModelBase, ITreePropert { _profileEditorService.Time.Subscribe(t => _time = t).DisposeWith(d); _isCurrentlySelected = _profileEditorService.LayerProperty.Select(l => l == LayerProperty).ToProperty(this, vm => vm.IsCurrentlySelected).DisposeWith(d); - _dataBindingEnabled = LayerProperty.BaseDataBinding.GetObservable().Select(b => b.IsEnabled).ToProperty(this, vm => vm.DataBindingEnabled).DisposeWith(d); + _dataBindingEnabled = LayerProperty.BaseDataBinding.AsObservable().Select(b => b.IsEnabled).ToProperty(this, vm => vm.DataBindingEnabled).DisposeWith(d); this.WhenAnyValue(vm => vm.LayerProperty.KeyframesEnabled).Subscribe(_ => this.RaisePropertyChanged(nameof(KeyframesEnabled))).DisposeWith(d); });