1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-12 13:28:33 +00:00

UI - Add PropertyChanged.SourceGenerator and use it in the profile editor

This commit is contained in:
Robert 2023-10-18 22:50:28 +02:00
parent fb6845be5d
commit 6921561317
24 changed files with 139 additions and 311 deletions

View File

@ -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
/// <inheritdoc />
public ViewModelActivator Activator { get; } = new();
/// <summary>
/// Raises the property changed event for the provided property.
/// </summary>
/// <param name="args">The event arguments containing the name of the property that changed.</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
{
this.RaisePropertyChanged(args.PropertyName);
}
/// <summary>
/// Raises the property changing event for the provided property.
/// </summary>
/// <param name="args">The event arguments containing the name of the property that is changing.</param>
protected virtual void OnPropertyChanging(PropertyChangingEventArgs args)
{
this.RaisePropertyChanging(args.PropertyName);
}
}
/// <summary>
@ -153,4 +172,22 @@ public abstract class ViewModelBase : ReactiveObject
this.RaisePropertyChanged(propertyName);
return newValue;
}
/// <summary>
/// Raises the property changed event for the provided property.
/// </summary>
/// <param name="args">The event arguments containing the name of the property that changed.</param>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
{
this.RaisePropertyChanged(args.PropertyName);
}
/// <summary>
/// Raises the property changing event for the provided property.
/// </summary>
/// <param name="args">The event arguments containing the name of the property that is changing.</param>
protected virtual void OnPropertyChanging(PropertyChangingEventArgs args)
{
this.RaisePropertyChanging(args.PropertyName);
}
}

View File

@ -9,17 +9,19 @@ namespace Artemis.UI.Windows.Providers;
public class ProtocolProvider : IProtocolProvider
{
/// <inheritdoc />
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;
}
/// <inheritdoc />
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;
}
}

View File

@ -37,6 +37,10 @@
<PackageReference Include="Markdown.Avalonia.Tight" Version="11.0.2" />
<PackageReference Include="Material.Icons.Avalonia" Version="2.0.1" />
<PackageReference Include="Octopus.Octodiff" Version="2.0.468" />
<PackageReference Include="PropertyChanged.SourceGenerator" Version="1.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="ReactiveUI" Version="19.5.1" />
<PackageReference Include="ReactiveUI.Validation" Version="3.1.7" />
<PackageReference Include="RGB.NET.Core" Version="$(RGBDotNetVersion)" />

View File

@ -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<bool>? _focusFolder;
private ObservableAsPropertyHelper<bool>? _focusNone;
private ObservableAsPropertyHelper<bool>? _focusSelection;
private ProfileEditorHistory? _history;
private ObservableAsPropertyHelper<bool>? _isSuspended;
private ObservableAsPropertyHelper<bool>? _keyBindingsEnabled;
private ObservableAsPropertyHelper<ProfileConfiguration?>? _profileConfiguration;
private ObservableAsPropertyHelper<RenderProfileElement?>? _profileElement;
private ObservableAsPropertyHelper<bool>? _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<bool> AlwaysApplyDataBindings => _settingsService.GetSetting("ProfileEditor.AlwaysApplyDataBindings", false);
public PluginSetting<ProfileEditorFocusMode> FocusMode => _settingsService.GetSetting("ProfileEditor.FocusMode", ProfileEditorFocusMode.Folder);
public ProfileEditorHistory? History
{
get => _history;
set => RaiseAndSetIfChanged(ref _history, value);
}
private void ExecuteAddFolder()
{
if (ProfileConfiguration?.Profile == null)

View File

@ -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<bool>? _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<Unit, Unit> PlayFromStart { get; }
public ReactiveCommand<Unit, Unit> TogglePlay { get; }
public ReactiveCommand<Unit, Unit> GoToStart { get; }

View File

@ -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<Unit, Unit> Confirm { get; }
private void ExecuteConfirm()

View File

@ -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<AdaptionLed> _adaptionLeds;
private AdaptionLed? _selectedLed;
[Notify] private List<AdaptionLed> _adaptionLeds;
[Notify] private AdaptionLed? _selectedLed;
public SingleLedAdaptionHintViewModel(Layer layer, SingleLedAdaptionHint adaptionHint) : base(layer, adaptionHint)
{
@ -25,18 +26,6 @@ public class SingleLedAdaptionHintViewModel : AdaptionHintViewModelBase
});
}
public List<AdaptionLed> AdaptionLeds
{
get => _adaptionLeds;
set => RaiseAndSetIfChanged(ref _adaptionLeds, value);
}
public AdaptionLed? SelectedLed
{
get => _selectedLed;
set => RaiseAndSetIfChanged(ref _selectedLed, value);
}
public SingleLedAdaptionHint SingleLedAdaptionHint { get; }
}

View File

@ -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<bool>? _focusFolder;
private ObservableAsPropertyHelper<bool>? _focusNone;
private ObservableAsPropertyHelper<bool>? _focusSelection;
private ObservableAsPropertyHelper<bool>? _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<Unit, Unit> ClearSelection { get; }
public ReactiveCommand<Unit, Unit> RenameSelected { get; }

View File

@ -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<bool>? _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<TreeItemViewModel> Children { get; } = new();

View File

@ -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<LayerEffectDescriptor> LayerEffectDescriptors { get; }
public string? SearchText
{
get => _searchText;
set => RaiseAndSetIfChanged(ref _searchText, value);
}
public void AddLayerEffect(LayerEffectDescriptor descriptor)
{
BaseLayerEffect layerEffect = descriptor.CreateInstance(_renderProfileElement, null);

View File

@ -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<LayerPropertyGroup, PropertyGroupViewModel> _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<ILayerProperty?>? _layerProperty;
private ObservableAsPropertyHelper<int>? _pixelsPerSecond;
private ObservableAsPropertyHelper<RenderProfileElement?>? _profileElement;
private ObservableAsPropertyHelper<bool>? _suspendedEditing;
[Notify] private DataBindingViewModel? _dataBindingViewModel;
/// <inheritdoc />
public PropertiesViewModel(IProfileEditorService profileEditorService,
@ -103,13 +104,7 @@ public class PropertiesViewModel : ActivatableViewModelBase
public PlaybackViewModel PlaybackViewModel { get; }
public TimelineViewModel TimelineViewModel { get; }
public ReactiveCommand<Unit, Unit> 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;

View File

@ -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<ILayerPropertyKeyframe> _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<ILayerPropertyKeyframe> Keyframes => _keyframes;
public List<ILayerPropertyKeyframe> GetAllKeyframes(bool expandedOnly)

View File

@ -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<ILayerPropertyKeyframe> _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<ILayerPropertyKeyframe> 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;

View File

@ -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<ILayerPropertyKeyframe, TimeSpan> _originalKeyframePositions = new();
@ -25,10 +26,10 @@ public abstract class TimelineSegmentViewModel : ActivatableViewModelBase
private TimeSpan _initialLength;
private int _pixelsPerSecond;
private RenderProfileElement? _profileElement;
private ReactiveCommand<Unit, Unit>? _removeSegment;
private ObservableAsPropertyHelper<bool>? _showAddEnd;
private ObservableAsPropertyHelper<bool>? _showAddMain;
private ObservableAsPropertyHelper<bool>? _showAddStart;
[Notify] private ReactiveCommand<Unit, Unit>? _removeSegment;
protected TimelineSegmentViewModel(IProfileEditorService profileEditorService, IWindowService windowService)
{
@ -96,12 +97,6 @@ public abstract class TimelineSegmentViewModel : ActivatableViewModelBase
public ReactiveCommand<Unit, Unit> EditTime { get; }
public ReactiveCommand<Unit, Unit>? RemoveSegment
{
get => _removeSegment;
set => RaiseAndSetIfChanged(ref _removeSegment, value);
}
public void AddStartSegment()
{
if (_profileElement == null)

View File

@ -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<double> _keyframePositions;
private int _pixelsPerSecond;
[Notify] private ReadOnlyObservableCollection<double> _keyframePositions;
public TimelineGroupViewModel(PropertyGroupViewModel propertyGroupViewModel, IProfileEditorService profileEditorService)
{
@ -39,10 +40,4 @@ public class TimelineGroupViewModel : ActivatableViewModelBase
public PropertyGroupViewModel PropertyGroupViewModel { get; }
public ObservableCollection<PropertyViewModelBase>? Children => PropertyGroupViewModel.IsExpanded ? PropertyGroupViewModel.Children : null;
public ReadOnlyObservableCollection<double> KeyframePositions
{
get => _keyframePositions;
set => RaiseAndSetIfChanged(ref _keyframePositions, value);
}
}

View File

@ -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<Unit, Unit> Confirm { get; }
private void ExecuteConfirm()

View File

@ -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<ILayerBrushPreset> Presets { get; }
public string? SearchText
{
get => _searchText;
set => RaiseAndSetIfChanged(ref _searchText, value);
}
public void SelectPreset(ILayerBrushPreset preset)
{
_layerBrush.BaseProperties?.ResetAllLayerProperties();

View File

@ -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<ProfileEditorHistory?>? _history;
private ObservableAsPropertyHelper<int>? _pixelsPerSecond;
private ObservableAsPropertyHelper<RenderProfileElement?>? _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);
}
}

View File

@ -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<bool> _isEnabled;
private readonly IProfileEditorService _profileEditorService;
private Point _anchor;
private ObservableAsPropertyHelper<Layer?>? _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;
/// <inheritdoc />
public TransformToolViewModel(IProfileEditorService profileEditorService)
@ -106,31 +107,7 @@ public class TransformToolViewModel : ToolViewModel
/// <inheritdoc />
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);
}
/// <inheritdoc />
protected override void Dispose(bool disposing)
{

View File

@ -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<IVisualizerViewModel> _visualizers;
private readonly IProfileEditorVmFactory _vmFactory;
private ObservableAsPropertyHelper<ProfileConfiguration?>? _profileConfiguration;
private ObservableAsPropertyHelper<bool>? _suspendedEditing;
private ReadOnlyObservableCollection<IToolViewModel>? _tools;
[Notify] private ReadOnlyObservableCollection<IToolViewModel>? _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<IToolViewModel>? Tools
{
get => _tools;
set => RaiseAndSetIfChanged(ref _tools, value);
}
public ReadOnlyObservableCollection<IVisualizerViewModel> Visualizers { get; }
public ObservableCollection<ArtemisDevice> Devices { get; }

View File

@ -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<bool>? _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;
}

View File

@ -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<bool>? _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;
}

View File

@ -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<ProfileEditorViewModelParameters>, IMainScreenViewModel
public partial class ProfileEditorViewModel : RoutableScreen<ProfileEditorViewModelParameters>, IMainScreenViewModel
{
private readonly IProfileEditorService _profileEditorService;
private readonly IProfileService _profileService;
@ -31,8 +32,9 @@ public class ProfileEditorViewModel : RoutableScreen<ProfileEditorViewModelParam
private readonly IMainWindowService _mainWindowService;
private readonly SourceList<IToolViewModel> _tools;
private ObservableAsPropertyHelper<ProfileEditorHistory?>? _history;
private ProfileConfiguration? _profileConfiguration;
private ObservableAsPropertyHelper<bool>? _suspendedEditing;
[Notify] private ProfileConfiguration? _profileConfiguration;
/// <inheritdoc />
public ProfileEditorViewModel(IProfileService profileService,
@ -94,12 +96,6 @@ public class ProfileEditorViewModel : RoutableScreen<ProfileEditorViewModelParam
ToggleAutoSuspend = ReactiveCommand.Create(ExecuteToggleAutoSuspend);
}
public ProfileConfiguration? ProfileConfiguration
{
get => _profileConfiguration;
set => RaiseAndSetIfChanged(ref _profileConfiguration, value);
}
public VisualEditorViewModel? VisualEditorViewModel { get; }
public ProfileTreeViewModel? ProfileTreeViewModel { get; }
public PropertiesViewModel? PropertiesViewModel { get; }

View File

@ -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<RoutableScreen>, IMainScreenViewModel
public partial class SettingsViewModel : RoutableHostScreen<RoutableScreen>, IMainScreenViewModel
{
private readonly IRouter _router;
private RouteViewModel? _selectedTab;
[Notify] private RouteViewModel? _selectedTab;
public SettingsViewModel(IRouter router)
{
@ -37,12 +38,6 @@ public class SettingsViewModel : RoutableHostScreen<RoutableScreen>, IMainScreen
public ObservableCollection<RouteViewModel> SettingTabs { get; }
public RouteViewModel? SelectedTab
{
get => _selectedTab;
set => RaiseAndSetIfChanged(ref _selectedTab, value);
}
public ViewModelBase? TitleBarViewModel => null;
/// <inheritdoc />