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);
});