From 692156131795b529d9cca30222a43d46a92b5d26 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 18 Oct 2023 22:50:28 +0200 Subject: [PATCH] UI - Add PropertyChanged.SourceGenerator and use it in the profile editor --- src/Artemis.UI.Shared/ViewModelBase.cs | 37 ++++++++++++++++++ .../Providers/ProtocolProvider.cs | 8 +++- src/Artemis.UI/Artemis.UI.csproj | 4 ++ .../Panels/MenuBar/MenuBarViewModel.cs | 11 ++---- .../Panels/Playback/PlaybackViewModel.cs | 27 +++---------- .../ProfileElementRenameViewModel.cs | 12 ++---- .../SingleLedAdaptionHintViewModel.cs | 19 ++------- .../ProfileTree/ProfileTreeViewModel.cs | 12 ++---- .../Panels/ProfileTree/TreeItemViewModel.cs | 36 ++++------------- .../Properties/Dialogs/AddEffectViewModel.cs | 11 ++---- .../Panels/Properties/PropertiesViewModel.cs | 13 ++----- .../Properties/PropertyGroupViewModel.cs | 29 +++----------- .../Panels/Properties/PropertyViewModel.cs | 27 +++---------- .../Segments/TimelineSegmentViewModel.cs | 11 ++---- .../Timeline/TimelineGroupViewModel.cs | 11 ++---- .../LayerEffectRenameViewModel.cs | 11 ++---- .../Tree/Dialogs/LayerBrushPresetViewModel.cs | 11 ++---- .../Panels/StatusBar/StatusBarViewModel.cs | 19 ++------- .../Tools/TransformToolViewModel.cs | 37 ++++-------------- .../VisualEditor/VisualEditorViewModel.cs | 11 ++---- .../LayerShapeVisualizerViewModel.cs | 39 ++++--------------- .../Visualizers/LayerVisualizerViewModel.cs | 31 ++++----------- .../ProfileEditor/ProfileEditorViewModel.cs | 12 ++---- .../Screens/Settings/SettingsViewModel.cs | 11 ++---- 24 files changed, 139 insertions(+), 311 deletions(-) diff --git a/src/Artemis.UI.Shared/ViewModelBase.cs b/src/Artemis.UI.Shared/ViewModelBase.cs index 52058fb2c..72ad3bc80 100644 --- a/src/Artemis.UI.Shared/ViewModelBase.cs +++ b/src/Artemis.UI.Shared/ViewModelBase.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Runtime.CompilerServices; using Artemis.UI.Shared.Events; using FluentAvalonia.UI.Controls; @@ -100,6 +101,24 @@ public abstract class ValidatableViewModelBase : ReactiveValidationObject, IActi /// public ViewModelActivator Activator { get; } = new(); + + /// + /// Raises the property changed event for the provided property. + /// + /// The event arguments containing the name of the property that changed. + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + this.RaisePropertyChanged(args.PropertyName); + } + + /// + /// Raises the property changing event for the provided property. + /// + /// The event arguments containing the name of the property that is changing. + protected virtual void OnPropertyChanging(PropertyChangingEventArgs args) + { + this.RaisePropertyChanging(args.PropertyName); + } } /// @@ -153,4 +172,22 @@ public abstract class ViewModelBase : ReactiveObject this.RaisePropertyChanged(propertyName); return newValue; } + + /// + /// Raises the property changed event for the provided property. + /// + /// The event arguments containing the name of the property that changed. + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + this.RaisePropertyChanged(args.PropertyName); + } + + /// + /// Raises the property changing event for the provided property. + /// + /// The event arguments containing the name of the property that is changing. + protected virtual void OnPropertyChanging(PropertyChangingEventArgs args) + { + this.RaisePropertyChanging(args.PropertyName); + } } \ No newline at end of file diff --git a/src/Artemis.UI.Windows/Providers/ProtocolProvider.cs b/src/Artemis.UI.Windows/Providers/ProtocolProvider.cs index c3ec1622f..6e6bb7445 100644 --- a/src/Artemis.UI.Windows/Providers/ProtocolProvider.cs +++ b/src/Artemis.UI.Windows/Providers/ProtocolProvider.cs @@ -9,17 +9,19 @@ namespace Artemis.UI.Windows.Providers; public class ProtocolProvider : IProtocolProvider { /// - public async Task AssociateWithProtocol(string protocol) + public Task AssociateWithProtocol(string protocol) { string key = $"HKEY_CURRENT_USER\\Software\\Classes\\{protocol}"; Registry.SetValue($"{key}", null, "URL:artemis protocol"); Registry.SetValue($"{key}", "URL Protocol", ""); Registry.SetValue($"{key}\\DefaultIcon", null, $"\"{Constants.ExecutablePath}\",1"); Registry.SetValue($"{key}\\shell\\open\\command", null, $"\"{Constants.ExecutablePath}\", \"--route=%1\""); + + return Task.CompletedTask; } /// - public async Task DisassociateWithProtocol(string protocol) + public Task DisassociateWithProtocol(string protocol) { try { @@ -30,5 +32,7 @@ public class ProtocolProvider : IProtocolProvider { // Ignore errors (which means that the protocol wasn't associated before) } + + return Task.CompletedTask; } } \ No newline at end of file diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index 655a40d29..0c9471912 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -37,6 +37,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarViewModel.cs index 7b323ab6e..3faad62e1 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarViewModel.cs @@ -15,11 +15,12 @@ using Artemis.UI.Shared.Routing; using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.ProfileEditor; using Newtonsoft.Json; +using PropertyChanged.SourceGenerator; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.MenuBar; -public class MenuBarViewModel : ActivatableViewModelBase +public partial class MenuBarViewModel : ActivatableViewModelBase { private readonly IRouter _router; private readonly IProfileEditorService _profileEditorService; @@ -29,12 +30,12 @@ public class MenuBarViewModel : ActivatableViewModelBase private ObservableAsPropertyHelper? _focusFolder; private ObservableAsPropertyHelper? _focusNone; private ObservableAsPropertyHelper? _focusSelection; - private ProfileEditorHistory? _history; private ObservableAsPropertyHelper? _isSuspended; private ObservableAsPropertyHelper? _keyBindingsEnabled; private ObservableAsPropertyHelper? _profileConfiguration; private ObservableAsPropertyHelper? _profileElement; private ObservableAsPropertyHelper? _suspendedEditing; + [Notify] private ProfileEditorHistory? _history; public MenuBarViewModel(IRouter router, IProfileEditorService profileEditorService, IProfileService profileService, ISettingsService settingsService, IWindowService windowService) { @@ -108,12 +109,6 @@ public class MenuBarViewModel : ActivatableViewModelBase public PluginSetting AlwaysApplyDataBindings => _settingsService.GetSetting("ProfileEditor.AlwaysApplyDataBindings", false); public PluginSetting FocusMode => _settingsService.GetSetting("ProfileEditor.FocusMode", ProfileEditorFocusMode.Folder); - public ProfileEditorHistory? History - { - get => _history; - set => RaiseAndSetIfChanged(ref _history, value); - } - private void ExecuteAddFolder() { if (ProfileConfiguration?.Profile == null) diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackViewModel.cs index d7fc9516e..51aeecec0 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackViewModel.cs @@ -8,11 +8,12 @@ using Artemis.Core.Services; using Artemis.UI.Shared; using Artemis.UI.Shared.Services.ProfileEditor; using Avalonia.Threading; +using PropertyChanged.SourceGenerator; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Playback; -public class PlaybackViewModel : ActivatableViewModelBase +public partial class PlaybackViewModel : ActivatableViewModelBase { private readonly IProfileEditorService _profileEditorService; private readonly ISettingsService _settingsService; @@ -22,9 +23,9 @@ public class PlaybackViewModel : ActivatableViewModelBase private DateTime _lastUpdate; private ObservableAsPropertyHelper? _playing; private RenderProfileElement? _profileElement; - private bool _repeating; - private bool _repeatSegment; - private bool _repeatTimeline; + [Notify] private bool _repeating; + [Notify] private bool _repeatSegment; + [Notify] private bool _repeatTimeline; public PlaybackViewModel(IProfileEditorService profileEditorService, ISettingsService settingsService) { @@ -84,24 +85,6 @@ public class PlaybackViewModel : ActivatableViewModelBase public bool Playing => _playing?.Value ?? false; public bool KeyBindingsEnabled => _keyBindingsEnabled?.Value ?? false; - public bool Repeating - { - get => _repeating; - set => RaiseAndSetIfChanged(ref _repeating, value); - } - - public bool RepeatTimeline - { - get => _repeatTimeline; - set => RaiseAndSetIfChanged(ref _repeatTimeline, value); - } - - public bool RepeatSegment - { - get => _repeatSegment; - set => RaiseAndSetIfChanged(ref _repeatSegment, value); - } - public ReactiveCommand PlayFromStart { get; } public ReactiveCommand TogglePlay { get; } public ReactiveCommand GoToStart { get; } diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ContentDialogs/ProfileElementRenameViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ContentDialogs/ProfileElementRenameViewModel.cs index de2b72860..280175c29 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ContentDialogs/ProfileElementRenameViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ContentDialogs/ProfileElementRenameViewModel.cs @@ -4,16 +4,17 @@ using Artemis.UI.Shared; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; using FluentAvalonia.UI.Controls; +using PropertyChanged.SourceGenerator; using ReactiveUI; using ReactiveUI.Validation.Extensions; namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.ContentDialogs; -public class ProfileElementRenameViewModel : ContentDialogViewModelBase +public partial class ProfileElementRenameViewModel : ContentDialogViewModelBase { private readonly IProfileEditorService _profileEditorService; private readonly ProfileElement _profileElement; - private string? _profileElementName; + [Notify] private string? _profileElementName; public ProfileElementRenameViewModel(IProfileEditorService profileEditorService, ProfileElement profileElement) { @@ -25,13 +26,6 @@ public class ProfileElementRenameViewModel : ContentDialogViewModelBase this.ValidationRule(vm => vm.ProfileElementName, name => !string.IsNullOrWhiteSpace(name), "You must specify a valid name"); } - public string? ProfileElementName - { - get => _profileElementName; - set => RaiseAndSetIfChanged(ref _profileElementName, value); - } - - public ReactiveCommand Confirm { get; } private void ExecuteConfirm() diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/SingleLedAdaptionHintViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/SingleLedAdaptionHintViewModel.cs index 4264a2d55..cf2dc07c3 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/SingleLedAdaptionHintViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/SingleLedAdaptionHintViewModel.cs @@ -3,15 +3,16 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Artemis.Core; +using PropertyChanged.SourceGenerator; using ReactiveUI; using RGB.NET.Core; namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints; -public class SingleLedAdaptionHintViewModel : AdaptionHintViewModelBase +public partial class SingleLedAdaptionHintViewModel : AdaptionHintViewModelBase { - private List _adaptionLeds; - private AdaptionLed? _selectedLed; + [Notify] private List _adaptionLeds; + [Notify] private AdaptionLed? _selectedLed; public SingleLedAdaptionHintViewModel(Layer layer, SingleLedAdaptionHint adaptionHint) : base(layer, adaptionHint) { @@ -25,18 +26,6 @@ public class SingleLedAdaptionHintViewModel : AdaptionHintViewModelBase }); } - public List AdaptionLeds - { - get => _adaptionLeds; - set => RaiseAndSetIfChanged(ref _adaptionLeds, value); - } - - public AdaptionLed? SelectedLed - { - get => _selectedLed; - set => RaiseAndSetIfChanged(ref _selectedLed, value); - } - public SingleLedAdaptionHint SingleLedAdaptionHint { get; } } diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeViewModel.cs index 82c559e98..38f8c6856 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeViewModel.cs @@ -11,17 +11,18 @@ using Artemis.Core.Services; using Artemis.UI.DryIoc.Factories; using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.ProfileEditor; +using PropertyChanged.SourceGenerator; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.ProfileTree; -public class ProfileTreeViewModel : TreeItemViewModel +public partial class ProfileTreeViewModel : TreeItemViewModel { private ObservableAsPropertyHelper? _focusFolder; private ObservableAsPropertyHelper? _focusNone; private ObservableAsPropertyHelper? _focusSelection; private ObservableAsPropertyHelper? _keyBindingsEnabled; - private TreeItemViewModel? _selectedChild; + [Notify] private TreeItemViewModel? _selectedChild; public ProfileTreeViewModel(IWindowService windowService, IDeviceService deviceService, IProfileEditorService profileEditorService, IProfileEditorVmFactory profileEditorVmFactory) : base(null, null, windowService, deviceService, profileEditorService, profileEditorVmFactory) @@ -67,12 +68,7 @@ public class ProfileTreeViewModel : TreeItemViewModel public bool FocusFolder => _focusFolder?.Value ?? false; public bool FocusSelection => _focusSelection?.Value ?? false; public bool KeyBindingsEnabled => _keyBindingsEnabled?.Value ?? false; - - public TreeItemViewModel? SelectedChild - { - get => _selectedChild; - set => RaiseAndSetIfChanged(ref _selectedChild, value); - } + public ReactiveCommand ClearSelection { get; } public ReactiveCommand RenameSelected { get; } diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs index 16594700a..c19e68726 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs @@ -20,23 +20,25 @@ using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; using Avalonia; using Avalonia.ReactiveUI; +using PropertyChanged.SourceGenerator; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.ProfileTree; -public abstract class TreeItemViewModel : ActivatableViewModelBase +public abstract partial class TreeItemViewModel : ActivatableViewModelBase { private readonly IProfileEditorVmFactory _profileEditorVmFactory; private readonly IWindowService _windowService; private readonly IDeviceService _deviceService; protected readonly IProfileEditorService ProfileEditorService; - private bool _canPaste; private RenderProfileElement? _currentProfileElement; - private bool _isExpanded; - private bool _isFlyoutOpen; private ObservableAsPropertyHelper? _isFocused; - private ProfileElement? _profileElement; private TimeSpan _time; + + [Notify] private bool _canPaste; + [Notify] private bool _isExpanded; + [Notify] private bool _isFlyoutOpen; + [Notify] private ProfileElement? _profileElement; protected TreeItemViewModel(TreeItemViewModel? parent, ProfileElement? profileElement, @@ -85,30 +87,6 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase public bool IsFocused => _isFocused?.Value ?? false; - public ProfileElement? ProfileElement - { - get => _profileElement; - set => RaiseAndSetIfChanged(ref _profileElement, value); - } - - public bool IsExpanded - { - get => _isExpanded; - set => RaiseAndSetIfChanged(ref _isExpanded, value); - } - - public bool IsFlyoutOpen - { - get => _isFlyoutOpen; - set => RaiseAndSetIfChanged(ref _isFlyoutOpen, value); - } - - public bool CanPaste - { - get => _canPaste; - set => RaiseAndSetIfChanged(ref _canPaste, value); - } - public TreeItemViewModel? Parent { get; set; } public ObservableCollection Children { get; } = new(); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Dialogs/AddEffectViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Dialogs/AddEffectViewModel.cs index 0f5c844e4..748c18cbd 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Dialogs/AddEffectViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Dialogs/AddEffectViewModel.cs @@ -8,15 +8,16 @@ using Artemis.UI.Shared; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; using DynamicData; +using PropertyChanged.SourceGenerator; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Dialogs; -public class AddEffectViewModel : ContentDialogViewModelBase +public partial class AddEffectViewModel : ContentDialogViewModelBase { private readonly IProfileEditorService _profileEditorService; private readonly RenderProfileElement _renderProfileElement; - private string? _searchText; + [Notify] private string? _searchText; public AddEffectViewModel(RenderProfileElement renderProfileElement, IProfileEditorService profileEditorService, ILayerEffectService layerEffectService) { @@ -36,12 +37,6 @@ public class AddEffectViewModel : ContentDialogViewModelBase public ReadOnlyObservableCollection LayerEffectDescriptors { get; } - public string? SearchText - { - get => _searchText; - set => RaiseAndSetIfChanged(ref _searchText, value); - } - public void AddLayerEffect(LayerEffectDescriptor descriptor) { BaseLayerEffect layerEffect = descriptor.CreateInstance(_renderProfileElement, null); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertiesViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertiesViewModel.cs index 9ed832d8c..de049688f 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertiesViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertiesViewModel.cs @@ -18,11 +18,12 @@ using Artemis.UI.Screens.ProfileEditor.Properties.Timeline; using Artemis.UI.Shared; using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.ProfileEditor; +using PropertyChanged.SourceGenerator; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties; -public class PropertiesViewModel : ActivatableViewModelBase +public partial class PropertiesViewModel : ActivatableViewModelBase { private readonly Dictionary _cachedPropertyViewModels; private readonly IDataBindingVmFactory _dataBindingVmFactory; @@ -32,11 +33,11 @@ public class PropertiesViewModel : ActivatableViewModelBase private readonly ISettingsService _settingsService; private readonly IWindowService _windowService; private DataBindingViewModel? _backgroundDataBindingViewModel; - private DataBindingViewModel? _dataBindingViewModel; private ObservableAsPropertyHelper? _layerProperty; private ObservableAsPropertyHelper? _pixelsPerSecond; private ObservableAsPropertyHelper? _profileElement; private ObservableAsPropertyHelper? _suspendedEditing; + [Notify] private DataBindingViewModel? _dataBindingViewModel; /// public PropertiesViewModel(IProfileEditorService profileEditorService, @@ -103,13 +104,7 @@ public class PropertiesViewModel : ActivatableViewModelBase public PlaybackViewModel PlaybackViewModel { get; } public TimelineViewModel TimelineViewModel { get; } public ReactiveCommand AddEffect { get; } - - public DataBindingViewModel? DataBindingViewModel - { - get => _dataBindingViewModel; - set => RaiseAndSetIfChanged(ref _dataBindingViewModel, value); - } - + public RenderProfileElement? ProfileElement => _profileElement?.Value; public ILayerProperty? LayerProperty => _layerProperty?.Value; public bool SuspendedEditing => _suspendedEditing?.Value ?? false; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyGroupViewModel.cs index 7427545ab..3503ba360 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyGroupViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyGroupViewModel.cs @@ -14,18 +14,19 @@ using Artemis.UI.Shared; using Artemis.UI.Shared.Services.PropertyInput; using DynamicData; using DynamicData.Binding; +using PropertyChanged.SourceGenerator; namespace Artemis.UI.Screens.ProfileEditor.Properties; -public class PropertyGroupViewModel : PropertyViewModelBase, IDisposable +public partial class PropertyGroupViewModel : PropertyViewModelBase, IDisposable { private readonly ILayerPropertyVmFactory _layerPropertyVmFactory; private readonly IPropertyInputService _propertyInputService; - private bool _hasChildren; - private bool _isExpanded; - private bool _isVisible; private ReadOnlyObservableCollection _keyframes = null!; private IDisposable _keyframeSubscription = null!; + [Notify] private bool _hasChildren; + [Notify] private bool _isExpanded; + [Notify] private bool _isVisible; public PropertyGroupViewModel(LayerPropertyGroup layerPropertyGroup, ILayerPropertyVmFactory layerPropertyVmFactory, IPropertyInputService propertyInputService) { @@ -78,25 +79,7 @@ public class PropertyGroupViewModel : PropertyViewModelBase, IDisposable public TreeGroupViewModel TreeGroupViewModel { get; } public TimelineGroupViewModel TimelineGroupViewModel { get; } - - public bool IsVisible - { - get => _isVisible; - set => RaiseAndSetIfChanged(ref _isVisible, value); - } - - public bool IsExpanded - { - get => _isExpanded; - set => RaiseAndSetIfChanged(ref _isExpanded, value); - } - - public bool HasChildren - { - get => _hasChildren; - set => RaiseAndSetIfChanged(ref _hasChildren, value); - } - + public override ReadOnlyObservableCollection Keyframes => _keyframes; public List GetAllKeyframes(bool expandedOnly) diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyViewModel.cs index 2caf34931..8d2ebcf07 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyViewModel.cs @@ -5,15 +5,16 @@ using Artemis.UI.DryIoc.Factories; using Artemis.UI.Screens.ProfileEditor.Properties.Timeline; using Artemis.UI.Screens.ProfileEditor.Properties.Tree; using DynamicData; +using PropertyChanged.SourceGenerator; namespace Artemis.UI.Screens.ProfileEditor.Properties; -public class PropertyViewModel : PropertyViewModelBase, IDisposable +public partial class PropertyViewModel : PropertyViewModelBase, IDisposable { private readonly SourceList _keyframes; - private bool _isExpanded; - private bool _isHighlighted; - private bool _isVisible; + [Notify] private bool _isExpanded; + [Notify] private bool _isHighlighted; + [Notify] private bool _isVisible; public PropertyViewModel(ILayerProperty layerProperty, IPropertyVmFactory propertyVmFactory) { @@ -38,24 +39,6 @@ public class PropertyViewModel : PropertyViewModelBase, IDisposable public ITimelinePropertyViewModel TimelinePropertyViewModel { get; } public override ReadOnlyObservableCollection Keyframes { get; } - public bool IsVisible - { - get => _isVisible; - set => RaiseAndSetIfChanged(ref _isVisible, value); - } - - public bool IsHighlighted - { - get => _isHighlighted; - set => RaiseAndSetIfChanged(ref _isHighlighted, value); - } - - public bool IsExpanded - { - get => _isExpanded; - set => RaiseAndSetIfChanged(ref _isExpanded, value); - } - private void LayerPropertyOnVisibilityChanged(object? sender, LayerPropertyEventArgs e) { IsVisible = !LayerProperty.IsHidden; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/TimelineSegmentViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/TimelineSegmentViewModel.cs index be9c471d4..04397ef25 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/TimelineSegmentViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/TimelineSegmentViewModel.cs @@ -12,11 +12,12 @@ using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.Builders; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; +using PropertyChanged.SourceGenerator; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Timeline.Segments; -public abstract class TimelineSegmentViewModel : ActivatableViewModelBase +public abstract partial class TimelineSegmentViewModel : ActivatableViewModelBase { private static readonly TimeSpan NewSegmentLength = TimeSpan.FromSeconds(2); private readonly Dictionary _originalKeyframePositions = new(); @@ -25,10 +26,10 @@ public abstract class TimelineSegmentViewModel : ActivatableViewModelBase private TimeSpan _initialLength; private int _pixelsPerSecond; private RenderProfileElement? _profileElement; - private ReactiveCommand? _removeSegment; private ObservableAsPropertyHelper? _showAddEnd; private ObservableAsPropertyHelper? _showAddMain; private ObservableAsPropertyHelper? _showAddStart; + [Notify] private ReactiveCommand? _removeSegment; protected TimelineSegmentViewModel(IProfileEditorService profileEditorService, IWindowService windowService) { @@ -96,12 +97,6 @@ public abstract class TimelineSegmentViewModel : ActivatableViewModelBase public ReactiveCommand EditTime { get; } - public ReactiveCommand? RemoveSegment - { - get => _removeSegment; - set => RaiseAndSetIfChanged(ref _removeSegment, value); - } - public void AddStartSegment() { if (_profileElement == null) diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupViewModel.cs index 620be7f41..b3876c952 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupViewModel.cs @@ -5,14 +5,15 @@ using Artemis.UI.Shared; using Artemis.UI.Shared.Services.ProfileEditor; using DynamicData; using DynamicData.Binding; +using PropertyChanged.SourceGenerator; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Timeline; -public class TimelineGroupViewModel : ActivatableViewModelBase +public partial class TimelineGroupViewModel : ActivatableViewModelBase { - private ReadOnlyObservableCollection _keyframePositions; private int _pixelsPerSecond; + [Notify] private ReadOnlyObservableCollection _keyframePositions; public TimelineGroupViewModel(PropertyGroupViewModel propertyGroupViewModel, IProfileEditorService profileEditorService) { @@ -39,10 +40,4 @@ public class TimelineGroupViewModel : ActivatableViewModelBase public PropertyGroupViewModel PropertyGroupViewModel { get; } public ObservableCollection? Children => PropertyGroupViewModel.IsExpanded ? PropertyGroupViewModel.Children : null; - - public ReadOnlyObservableCollection KeyframePositions - { - get => _keyframePositions; - set => RaiseAndSetIfChanged(ref _keyframePositions, value); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/ContentDialogs/LayerEffectRenameViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/ContentDialogs/LayerEffectRenameViewModel.cs index 776928ce5..9924dc746 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/ContentDialogs/LayerEffectRenameViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/ContentDialogs/LayerEffectRenameViewModel.cs @@ -4,16 +4,17 @@ using Artemis.UI.Shared; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; using FluentAvalonia.UI.Controls; +using PropertyChanged.SourceGenerator; using ReactiveUI; using ReactiveUI.Validation.Extensions; namespace Artemis.UI.Screens.ProfileEditor.Properties.Tree.ContentDialogs; -public class LayerEffectRenameViewModel : ContentDialogViewModelBase +public partial class LayerEffectRenameViewModel : ContentDialogViewModelBase { private readonly BaseLayerEffect _layerEffect; private readonly IProfileEditorService _profileEditorService; - private string? _layerEffectName; + [Notify] private string? _layerEffectName; public LayerEffectRenameViewModel(IProfileEditorService profileEditorService, BaseLayerEffect layerEffect) { @@ -25,12 +26,6 @@ public class LayerEffectRenameViewModel : ContentDialogViewModelBase this.ValidationRule(vm => vm.LayerEffectName, categoryName => !string.IsNullOrWhiteSpace(categoryName), "You must specify a valid name"); } - public string? LayerEffectName - { - get => _layerEffectName; - set => RaiseAndSetIfChanged(ref _layerEffectName, value); - } - public ReactiveCommand Confirm { get; } private void ExecuteConfirm() diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/Dialogs/LayerBrushPresetViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/Dialogs/LayerBrushPresetViewModel.cs index 347cad2cb..2577aa1b5 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/Dialogs/LayerBrushPresetViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/Dialogs/LayerBrushPresetViewModel.cs @@ -4,14 +4,15 @@ using System.Reactive.Linq; using Artemis.Core.LayerBrushes; using Artemis.UI.Shared; using DynamicData; +using PropertyChanged.SourceGenerator; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Tree.Dialogs; -public class LayerBrushPresetViewModel : ContentDialogViewModelBase +public partial class LayerBrushPresetViewModel : ContentDialogViewModelBase { private readonly BaseLayerBrush _layerBrush; - private string? _searchText; + [Notify] private string? _searchText; public LayerBrushPresetViewModel(BaseLayerBrush layerBrush) { @@ -31,12 +32,6 @@ public class LayerBrushPresetViewModel : ContentDialogViewModelBase public ReadOnlyObservableCollection Presets { get; } - public string? SearchText - { - get => _searchText; - set => RaiseAndSetIfChanged(ref _searchText, value); - } - public void SelectPreset(ILayerBrushPreset preset) { _layerBrush.BaseProperties?.ResetAllLayerProperties(); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarViewModel.cs index 73327e70a..389935810 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarViewModel.cs @@ -4,18 +4,19 @@ using System.Reactive.Linq; using Artemis.Core; using Artemis.UI.Shared; using Artemis.UI.Shared.Services.ProfileEditor; +using PropertyChanged.SourceGenerator; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.StatusBar; -public class StatusBarViewModel : ActivatableViewModelBase +public partial class StatusBarViewModel : ActivatableViewModelBase { private readonly IProfileEditorService _profileEditorService; private ObservableAsPropertyHelper? _history; private ObservableAsPropertyHelper? _pixelsPerSecond; private ObservableAsPropertyHelper? _profileElement; - private bool _showStatusMessage; - private string? _statusMessage; + [Notify] private bool _showStatusMessage; + [Notify] private string? _statusMessage; public StatusBarViewModel(IProfileEditorService profileEditorService) { @@ -55,16 +56,4 @@ public class StatusBarViewModel : ActivatableViewModelBase get => _pixelsPerSecond?.Value ?? 0; set => _profileEditorService.ChangePixelsPerSecond(value); } - - public string? StatusMessage - { - get => _statusMessage; - set => RaiseAndSetIfChanged(ref _statusMessage, value); - } - - public bool ShowStatusMessage - { - get => _showStatusMessage; - set => RaiseAndSetIfChanged(ref _showStatusMessage, value); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/TransformToolViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/TransformToolViewModel.cs index dbb5c75bf..98ed7fe40 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/TransformToolViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/TransformToolViewModel.cs @@ -11,21 +11,22 @@ using Artemis.UI.Shared.Services.ProfileEditor.Commands; using Avalonia; using Avalonia.Input; using Material.Icons; +using PropertyChanged.SourceGenerator; using ReactiveUI; using SkiaSharp; namespace Artemis.UI.Screens.ProfileEditor.VisualEditor.Tools; -public class TransformToolViewModel : ToolViewModel +public partial class TransformToolViewModel : ToolViewModel { private readonly ObservableAsPropertyHelper _isEnabled; private readonly IProfileEditorService _profileEditorService; - private Point _anchor; private ObservableAsPropertyHelper? _layer; - private RelativePoint _relativeAnchor; - private double _rotation; - private Rect _shapeBounds; private TimeSpan _time; + [Notify] private Point _anchor; + [Notify] private RelativePoint _relativeAnchor; + [Notify] private double _rotation; + [Notify] private Rect _shapeBounds; /// public TransformToolViewModel(IProfileEditorService profileEditorService) @@ -106,31 +107,7 @@ public class TransformToolViewModel : ToolViewModel /// public override string ToolTip => "Transform the shape of the current layer (Ctrl+T)"; - - public Rect ShapeBounds - { - get => _shapeBounds; - set => RaiseAndSetIfChanged(ref _shapeBounds, value); - } - - public double Rotation - { - get => _rotation; - set => RaiseAndSetIfChanged(ref _rotation, value); - } - - public RelativePoint RelativeAnchor - { - get => _relativeAnchor; - set => RaiseAndSetIfChanged(ref _relativeAnchor, value); - } - - public Point Anchor - { - get => _anchor; - set => RaiseAndSetIfChanged(ref _anchor, value); - } - + /// protected override void Dispose(bool disposing) { diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorViewModel.cs index 140548d88..a5246024b 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorViewModel.cs @@ -13,17 +13,18 @@ using Artemis.UI.Shared; using Artemis.UI.Shared.Services.ProfileEditor; using DynamicData; using DynamicData.Binding; +using PropertyChanged.SourceGenerator; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.VisualEditor; -public class VisualEditorViewModel : ActivatableViewModelBase +public partial class VisualEditorViewModel : ActivatableViewModelBase { private readonly SourceList _visualizers; private readonly IProfileEditorVmFactory _vmFactory; private ObservableAsPropertyHelper? _profileConfiguration; private ObservableAsPropertyHelper? _suspendedEditing; - private ReadOnlyObservableCollection? _tools; + [Notify] private ReadOnlyObservableCollection? _tools; public VisualEditorViewModel(IProfileEditorService profileEditorService, IDeviceService deviceService, IProfileEditorVmFactory vmFactory) { @@ -65,12 +66,6 @@ public class VisualEditorViewModel : ActivatableViewModelBase public ProfileConfiguration? ProfileConfiguration => _profileConfiguration?.Value; public bool SuspendedEditing => _suspendedEditing?.Value ?? false; - public ReadOnlyObservableCollection? Tools - { - get => _tools; - set => RaiseAndSetIfChanged(ref _tools, value); - } - public ReadOnlyObservableCollection Visualizers { get; } public ObservableCollection Devices { get; } diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerViewModel.cs index 6593054e4..6a4a4dca0 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerViewModel.cs @@ -9,18 +9,19 @@ using Avalonia; using Avalonia.Media; using Avalonia.Skia; using Avalonia.Threading; +using PropertyChanged.SourceGenerator; using ReactiveUI; using SkiaSharp; namespace Artemis.UI.Screens.ProfileEditor.VisualEditor.Visualizers; -public class LayerShapeVisualizerViewModel : ActivatableViewModelBase, IVisualizerViewModel +public partial class LayerShapeVisualizerViewModel : ActivatableViewModelBase, IVisualizerViewModel { - private Rect _layerBounds; private ObservableAsPropertyHelper? _selected; - private Geometry? _shapeGeometry; - private double _x; - private double _y; + [Notify] private Rect _layerBounds; + [Notify] private Geometry? _shapeGeometry; + [Notify] private double _x; + [Notify] private double _y; public LayerShapeVisualizerViewModel(Layer layer, IProfileEditorService profileEditorService) { @@ -51,19 +52,7 @@ public class LayerShapeVisualizerViewModel : ActivatableViewModelBase, IVisualiz public Layer Layer { get; } public bool Selected => _selected?.Value ?? false; - - public Rect LayerBounds - { - get => _layerBounds; - private set => RaiseAndSetIfChanged(ref _layerBounds, value); - } - - public Geometry? ShapeGeometry - { - get => _shapeGeometry; - set => RaiseAndSetIfChanged(ref _shapeGeometry, value); - } - + private void Update() { UpdateLayerBounds(); @@ -91,18 +80,6 @@ public class LayerShapeVisualizerViewModel : ActivatableViewModelBase, IVisualiz } public ProfileElement ProfileElement => Layer; - - public double X - { - get => _x; - set => RaiseAndSetIfChanged(ref _x, value); - } - - public double Y - { - get => _y; - set => RaiseAndSetIfChanged(ref _y, value); - } - + public int Order => 2; } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerViewModel.cs index fd6044730..c570fbdff 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerViewModel.cs @@ -6,17 +6,18 @@ using Artemis.UI.Shared; using Artemis.UI.Shared.Extensions; using Artemis.UI.Shared.Services.ProfileEditor; using Avalonia; +using PropertyChanged.SourceGenerator; using ReactiveUI; using SkiaSharp; namespace Artemis.UI.Screens.ProfileEditor.VisualEditor.Visualizers; -public class LayerVisualizerViewModel : ActivatableViewModelBase, IVisualizerViewModel +public partial class LayerVisualizerViewModel : ActivatableViewModelBase, IVisualizerViewModel { - private Rect _layerBounds; private ObservableAsPropertyHelper? _selected; - private double _x; - private double _y; + [Notify] private Rect _layerBounds; + [Notify] private double _x; + [Notify] private double _y; public LayerVisualizerViewModel(Layer layer, IProfileEditorService profileEditorService) { @@ -37,13 +38,7 @@ public class LayerVisualizerViewModel : ActivatableViewModelBase, IVisualizerVie public Layer Layer { get; } public bool Selected => _selected?.Value ?? false; - - public Rect LayerBounds - { - get => _layerBounds; - private set => RaiseAndSetIfChanged(ref _layerBounds, value); - } - + private void Update() { SKRect bounds = Layer.GetLayerBounds(); @@ -53,18 +48,6 @@ public class LayerVisualizerViewModel : ActivatableViewModelBase, IVisualizerVie } public ProfileElement ProfileElement => Layer; - - public double X - { - get => _x; - set => RaiseAndSetIfChanged(ref _x, value); - } - - public double Y - { - get => _y; - set => RaiseAndSetIfChanged(ref _y, value); - } - + public int Order => 1; } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs index e5a865ffa..1b6af5381 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs @@ -19,11 +19,12 @@ using Artemis.UI.Shared.Services.MainWindow; using Artemis.UI.Shared.Services.ProfileEditor; using DynamicData; using DynamicData.Binding; +using PropertyChanged.SourceGenerator; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor; -public class ProfileEditorViewModel : RoutableScreen, IMainScreenViewModel +public partial class ProfileEditorViewModel : RoutableScreen, IMainScreenViewModel { private readonly IProfileEditorService _profileEditorService; private readonly IProfileService _profileService; @@ -31,8 +32,9 @@ public class ProfileEditorViewModel : RoutableScreen _tools; private ObservableAsPropertyHelper? _history; - private ProfileConfiguration? _profileConfiguration; private ObservableAsPropertyHelper? _suspendedEditing; + + [Notify] private ProfileConfiguration? _profileConfiguration; /// public ProfileEditorViewModel(IProfileService profileService, @@ -94,12 +96,6 @@ public class ProfileEditorViewModel : RoutableScreen _profileConfiguration; - set => RaiseAndSetIfChanged(ref _profileConfiguration, value); - } - public VisualEditorViewModel? VisualEditorViewModel { get; } public ProfileTreeViewModel? ProfileTreeViewModel { get; } public PropertiesViewModel? PropertiesViewModel { get; } diff --git a/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs b/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs index 3391aeab8..166fcfe63 100644 --- a/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs @@ -7,14 +7,15 @@ using System.Threading.Tasks; using Artemis.UI.Routing; using Artemis.UI.Shared; using Artemis.UI.Shared.Routing; +using PropertyChanged.SourceGenerator; using ReactiveUI; namespace Artemis.UI.Screens.Settings; -public class SettingsViewModel : RoutableHostScreen, IMainScreenViewModel +public partial class SettingsViewModel : RoutableHostScreen, IMainScreenViewModel { private readonly IRouter _router; - private RouteViewModel? _selectedTab; + [Notify] private RouteViewModel? _selectedTab; public SettingsViewModel(IRouter router) { @@ -37,12 +38,6 @@ public class SettingsViewModel : RoutableHostScreen, IMainScreen public ObservableCollection SettingTabs { get; } - public RouteViewModel? SelectedTab - { - get => _selectedTab; - set => RaiseAndSetIfChanged(ref _selectedTab, value); - } - public ViewModelBase? TitleBarViewModel => null; ///