From e38516520048d48cfa04bc58ea765552b9bf8d78 Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 17 Jul 2022 23:22:45 +0200 Subject: [PATCH] Core - Made FloatRange and IntRange readonly structs ColorGradient - Fixed missing subscribtions when using object list manipulation API ColorGradient - Fixed editor VM going out of sync --- src/Artemis.Core/Artemis.Core.csproj | 152 +++++++++--------- .../Properties/ColorGradientLayerProperty.cs | 151 ++++++++--------- .../Properties/FloatRangeLayerProperty.cs | 20 +-- .../Properties/IntRangeLayerProperty.cs | 16 +- .../Models/Profile/Colors/ColorGradient.cs | 21 ++- src/Artemis.Core/Models/Profile/Layer.cs | 18 ++- .../Profile/LayerProperties/FloatRange.cs | 18 +-- .../Profile/LayerProperties/ILayerProperty.cs | 2 +- .../Profile/LayerProperties/IntRange.cs | 20 +-- .../Profile/LayerProperties/LayerProperty.cs | 2 +- .../Internal/PropertiesLayerBrush.cs | 2 - .../Artemis.UI.Shared.csproj | 28 ++-- .../GradientPicker/GradientPickerButton.cs | 5 +- .../Commands/UpdateColorGradient.cs | 49 ++++++ src/Artemis.UI/Artemis.UI.csproj | 60 +++---- .../ColorGradientPropertyInputView.axaml | 2 +- .../ColorGradientPropertyInputViewModel.cs | 66 ++++---- .../FloatRangePropertyInputViewModel.cs | 16 +- .../IntRangePropertyInputViewModel.cs | 16 +- 19 files changed, 337 insertions(+), 327 deletions(-) create mode 100644 src/Artemis.UI.Shared/Services/ProfileEditor/Commands/UpdateColorGradient.cs diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index 975a8aac0..24e200124 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -1,83 +1,79 @@  - - net6.0 - false - false - Artemis.Core - Artemis Core - Copyright © Robert Beekman - 2020 - bin\ - x64 - - - x64 - bin\Artemis.Core.xml - - 5 - + + net6.0 + false + false + Artemis.Core + Artemis Core + Copyright © Robert Beekman - 2020 + bin\ + x64 + + + x64 + bin\Artemis.Core.xml + + 5 + - - 1.0-{chash:6} - true - true - true - v[0-9]* - true - git - true - enable - latest - + + 1.0-{chash:6} + true + true + true + v[0-9]* + true + git + true + enable + latest + - - bin\Artemis.Core.xml - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - PreserveNewest - - + + bin\Artemis.Core.xml + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + PreserveNewest + + - - - PreserveNewest - - - - - - + + + PreserveNewest + + \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Properties/ColorGradientLayerProperty.cs b/src/Artemis.Core/DefaultTypes/Properties/ColorGradientLayerProperty.cs index fa786e7c3..c88cbd625 100644 --- a/src/Artemis.Core/DefaultTypes/Properties/ColorGradientLayerProperty.cs +++ b/src/Artemis.Core/DefaultTypes/Properties/ColorGradientLayerProperty.cs @@ -1,91 +1,92 @@ using System.Collections.Specialized; -using System.ComponentModel; using SkiaSharp; -namespace Artemis.Core +namespace Artemis.Core; + +/// +public class ColorGradientLayerProperty : LayerProperty { - /// - public class ColorGradientLayerProperty : LayerProperty + private ColorGradient? _subscribedGradient; + + internal ColorGradientLayerProperty() { - private ColorGradient? _subscribedGradient; + KeyframesSupported = false; + DefaultValue = new ColorGradient(); + } - internal ColorGradientLayerProperty() + /// + /// Implicitly converts an to a + /// + public static implicit operator ColorGradient(ColorGradientLayerProperty p) + { + return p.CurrentValue; + } + + #region Overrides of LayerProperty + + /// + protected override void OnCurrentValueSet() + { + // Don't allow color gradients to be null + if (BaseValue == null!) + BaseValue = new ColorGradient(DefaultValue); + + if (!ReferenceEquals(_subscribedGradient, BaseValue)) { - KeyframesSupported = false; - DefaultValue = new ColorGradient(); - - CurrentValueSet += OnCurrentValueSet; + if (_subscribedGradient != null) + _subscribedGradient.CollectionChanged -= SubscribedGradientOnPropertyChanged; + _subscribedGradient = BaseValue; + _subscribedGradient.CollectionChanged += SubscribedGradientOnPropertyChanged; } - private void CreateDataBindingRegistrations() - { - DataBinding.ClearDataBindingProperties(); - if (CurrentValue == null!) - return; + CreateDataBindingRegistrations(); + base.OnCurrentValueSet(); + } - for (int index = 0; index < CurrentValue.Count; index++) + #endregion + + /// + protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased) + { + throw new ArtemisCoreException("Color Gradients do not support keyframes."); + } + + #region Overrides of LayerProperty + + /// + protected override void OnInitialize() + { + // Don't allow color gradients to be null + if (BaseValue == null!) + BaseValue = new ColorGradient(DefaultValue); + + base.OnInitialize(); + } + + #endregion + + private void CreateDataBindingRegistrations() + { + DataBinding.ClearDataBindingProperties(); + if (CurrentValue == null!) + return; + + for (int index = 0; index < CurrentValue.Count; index++) + { + int stopIndex = index; + + void Setter(SKColor value) { - int stopIndex = index; - - void Setter(SKColor value) - { - CurrentValue[stopIndex].Color = value; - } - - DataBinding.RegisterDataBindingProperty(() => CurrentValue[stopIndex].Color, Setter, $"Color #{stopIndex + 1}"); - } - } - - - /// - /// Implicitly converts an to a - /// - public static implicit operator ColorGradient(ColorGradientLayerProperty p) - { - return p.CurrentValue; - } - - /// - protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased) - { - throw new ArtemisCoreException("Color Gradients do not support keyframes."); - } - - private void OnCurrentValueSet(object? sender, LayerPropertyEventArgs e) - { - // Don't allow color gradients to be null - if (BaseValue == null!) - BaseValue = new ColorGradient(DefaultValue); - - if (!ReferenceEquals(_subscribedGradient, BaseValue)) - { - if (_subscribedGradient != null) - _subscribedGradient.CollectionChanged -= SubscribedGradientOnPropertyChanged; - _subscribedGradient = BaseValue; - _subscribedGradient.CollectionChanged += SubscribedGradientOnPropertyChanged; + CurrentValue[stopIndex].Color = value; } + DataBinding.RegisterDataBindingProperty(() => CurrentValue[stopIndex].Color, Setter, $"Color #{stopIndex + 1}"); + } + } + + private void SubscribedGradientOnPropertyChanged(object? sender, NotifyCollectionChangedEventArgs args) + { + if (CurrentValue.Count != DataBinding.Properties.Count) CreateDataBindingRegistrations(); - } - - private void SubscribedGradientOnPropertyChanged(object? sender, NotifyCollectionChangedEventArgs args) - { - if (CurrentValue.Count != DataBinding.Properties.Count) - CreateDataBindingRegistrations(); - } - - #region Overrides of LayerProperty - - /// - protected override void OnInitialize() - { - // Don't allow color gradients to be null - if (BaseValue == null!) - BaseValue = new ColorGradient(DefaultValue); - - base.OnInitialize(); - } - - #endregion } } \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Properties/FloatRangeLayerProperty.cs b/src/Artemis.Core/DefaultTypes/Properties/FloatRangeLayerProperty.cs index d43dbf705..56408b59a 100644 --- a/src/Artemis.Core/DefaultTypes/Properties/FloatRangeLayerProperty.cs +++ b/src/Artemis.Core/DefaultTypes/Properties/FloatRangeLayerProperty.cs @@ -3,17 +3,11 @@ /// public class FloatRangeLayerProperty : LayerProperty { - internal FloatRangeLayerProperty() - { - CurrentValueSet += OnCurrentValueSet; - DefaultValue = new FloatRange(); - } - /// protected override void OnInitialize() { - DataBinding.RegisterDataBindingProperty(() => CurrentValue.Start, value => CurrentValue.Start = value, "Start"); - DataBinding.RegisterDataBindingProperty(() => CurrentValue.End, value => CurrentValue.End = value, "End"); + DataBinding.RegisterDataBindingProperty(() => CurrentValue.Start, value => CurrentValue = new FloatRange(value, CurrentValue.End), "Start"); + DataBinding.RegisterDataBindingProperty(() => CurrentValue.End, value => CurrentValue = new FloatRange(CurrentValue.Start, value), "End"); } /// @@ -22,15 +16,9 @@ float startDiff = NextKeyframe!.Value.Start - CurrentKeyframe!.Value.Start; float endDiff = NextKeyframe!.Value.End - CurrentKeyframe!.Value.End; CurrentValue = new FloatRange( - (int) (CurrentKeyframe!.Value.Start + startDiff * keyframeProgressEased), - (int) (CurrentKeyframe!.Value.End + endDiff * keyframeProgressEased) + (float) (CurrentKeyframe!.Value.Start + startDiff * keyframeProgressEased), + (float) (CurrentKeyframe!.Value.End + endDiff * keyframeProgressEased) ); } - - private void OnCurrentValueSet(object? sender, LayerPropertyEventArgs e) - { - // Don't allow the int range to be null - BaseValue ??= DefaultValue ?? new FloatRange(); - } } } \ No newline at end of file diff --git a/src/Artemis.Core/DefaultTypes/Properties/IntRangeLayerProperty.cs b/src/Artemis.Core/DefaultTypes/Properties/IntRangeLayerProperty.cs index fea761b8e..481c8f721 100644 --- a/src/Artemis.Core/DefaultTypes/Properties/IntRangeLayerProperty.cs +++ b/src/Artemis.Core/DefaultTypes/Properties/IntRangeLayerProperty.cs @@ -3,17 +3,11 @@ /// public class IntRangeLayerProperty : LayerProperty { - internal IntRangeLayerProperty() - { - CurrentValueSet += OnCurrentValueSet; - DefaultValue = new IntRange(); - } - /// protected override void OnInitialize() { - DataBinding.RegisterDataBindingProperty(() => CurrentValue.Start, value => CurrentValue.Start = value, "Start"); - DataBinding.RegisterDataBindingProperty(() => CurrentValue.End, value => CurrentValue.End = value, "End"); + DataBinding.RegisterDataBindingProperty(() => CurrentValue.Start, value => CurrentValue = new IntRange(value, CurrentValue.End), "Start"); + DataBinding.RegisterDataBindingProperty(() => CurrentValue.End, value => CurrentValue = new IntRange(CurrentValue.Start, value), "End"); } /// @@ -26,11 +20,5 @@ (int) (CurrentKeyframe!.Value.End + endDiff * keyframeProgressEased) ); } - - private void OnCurrentValueSet(object? sender, LayerPropertyEventArgs e) - { - // Don't allow the int range to be null - BaseValue ??= DefaultValue ?? new IntRange(); - } } } \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs b/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs index 35fbb444b..1e34d5348 100644 --- a/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs +++ b/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs @@ -55,6 +55,21 @@ public class ColorGradient : IList, IList, INotifyCollectionC } } + /// + /// Creates a new instance of the class + /// + /// The stops to copy + public ColorGradient(List stops) + { + _stops = new List(); + foreach (ColorGradientStop colorGradientStop in stops) + { + ColorGradientStop stop = new(colorGradientStop.Color, colorGradientStop.Position); + stop.PropertyChanged += ItemOnPropertyChanged; + _stops.Add(stop); + } + } + /// /// Gets all the colors in the color gradient /// @@ -462,7 +477,7 @@ public class ColorGradient : IList, IList, INotifyCollectionC public int Add(object? value) { if (value is ColorGradientStop stop) - _stops.Add(stop); + Add(stop); return IndexOf(value); } @@ -492,14 +507,14 @@ public class ColorGradient : IList, IList, INotifyCollectionC public void Insert(int index, object? value) { if (value is ColorGradientStop stop) - _stops.Insert(index, stop); + Insert(index, stop); } /// public void Remove(object? value) { if (value is ColorGradientStop stop) - _stops.Remove(stop); + Remove(stop); } /// diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs index fc5bcb991..3fcc54155 100644 --- a/src/Artemis.Core/Models/Profile/Layer.cs +++ b/src/Artemis.Core/Models/Profile/Layer.cs @@ -379,7 +379,7 @@ namespace Artemis.Core UpdateDisplayCondition(); UpdateTimeline(deltaTime); - + if (ShouldBeEnabled) Enable(); else if (Timeline.IsFinished && !_renderCopies.Any()) @@ -514,7 +514,7 @@ namespace Artemis.Core }, "Failed to enable one or more effects"); if (!tryOrBreak) return; - + Enabled = true; } @@ -633,6 +633,7 @@ namespace Artemis.Core if (!baseLayerEffect.Suspended) baseLayerEffect.InternalPreProcess(canvas, bounds, layerPaint); } + canvas.ClipPath(renderPath); // Restore the blend mode before doing the actual render @@ -788,10 +789,14 @@ namespace Artemis.Core /// public void ChangeLayerBrush(BaseLayerBrush? layerBrush) { + BaseLayerBrush? oldLayerBrush = LayerBrush; + General.BrushReference.SetCurrentValue(layerBrush != null ? new LayerBrushReference(layerBrush.Descriptor) : null, null); LayerBrush = layerBrush; LayerEntity.LayerBrush = new LayerBrushEntity(); - + + oldLayerBrush?.InternalDisable(); + if (LayerBrush != null) ActivateLayerBrush(); else @@ -815,7 +820,12 @@ namespace Artemis.Core General.ShapeType.IsHidden = LayerBrush != null && !LayerBrush.SupportsTransformation; General.BlendMode.IsHidden = LayerBrush != null && !LayerBrush.SupportsTransformation; Transform.IsHidden = LayerBrush != null && !LayerBrush.SupportsTransformation; - LayerBrush?.Update(0); + if (LayerBrush != null) + { + if (!LayerBrush.Enabled) + LayerBrush.InternalEnable(); + LayerBrush?.Update(0); + } OnLayerBrushUpdated(); ClearBrokenState("Failed to initialize layer brush"); diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/FloatRange.cs b/src/Artemis.Core/Models/Profile/LayerProperties/FloatRange.cs index 2e696d7af..3a990297c 100644 --- a/src/Artemis.Core/Models/Profile/LayerProperties/FloatRange.cs +++ b/src/Artemis.Core/Models/Profile/LayerProperties/FloatRange.cs @@ -5,18 +5,10 @@ namespace Artemis.Core /// /// Represents a range between two single-precision floating point numbers /// - public class FloatRange + public readonly struct FloatRange { private readonly Random _rand; - /// - /// Creates a new instance of the class - /// - public FloatRange() - { - _rand = new Random(); - } - /// /// Creates a new instance of the class /// @@ -31,14 +23,14 @@ namespace Artemis.Core } /// - /// Gets or sets the start value of the range + /// Gets the start value of the range /// - public float Start { get; set; } + public float Start { get; } /// - /// Gets or sets the end value of the range + /// Gets the end value of the range /// - public float End { get; set; } + public float End { get; } /// /// Determines whether the given value is in this range diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/ILayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/ILayerProperty.cs index 2f36515f8..4ad645a94 100644 --- a/src/Artemis.Core/Models/Profile/LayerProperties/ILayerProperty.cs +++ b/src/Artemis.Core/Models/Profile/LayerProperties/ILayerProperty.cs @@ -47,7 +47,7 @@ namespace Artemis.Core /// Gets a boolean indicating whether data bindings are supported on this type of property /// public bool DataBindingsSupported { get; } - + /// /// Gets the unique path of the property on the render element /// diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/IntRange.cs b/src/Artemis.Core/Models/Profile/LayerProperties/IntRange.cs index e93e6a349..8fe97c53d 100644 --- a/src/Artemis.Core/Models/Profile/LayerProperties/IntRange.cs +++ b/src/Artemis.Core/Models/Profile/LayerProperties/IntRange.cs @@ -5,18 +5,10 @@ namespace Artemis.Core /// /// Represents a range between two signed integers /// - public class IntRange + public readonly struct IntRange { private readonly Random _rand; - - /// - /// Creates a new instance of the class - /// - public IntRange() - { - _rand = new Random(); - } - + /// /// Creates a new instance of the class /// @@ -31,14 +23,14 @@ namespace Artemis.Core } /// - /// Gets or sets the start value of the range + /// Gets the start value of the range /// - public int Start { get; set; } + public int Start { get; } /// - /// Gets or sets the end value of the range + /// Gets the end value of the range /// - public int End { get; set; } + public int End { get; } /// /// Determines whether the given value is in this range diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs index 8c16c3b93..ea94d24b1 100644 --- a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs +++ b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs @@ -261,7 +261,7 @@ namespace Artemis.Core /// /// Gets whether keyframes are supported on this type of property /// - public bool KeyframesSupported { get; protected internal set; } = true; + public bool KeyframesSupported { get; protected set; } = true; /// /// Gets or sets whether keyframes are enabled on this property, has no effect if is diff --git a/src/Artemis.Core/Plugins/LayerBrushes/Internal/PropertiesLayerBrush.cs b/src/Artemis.Core/Plugins/LayerBrushes/Internal/PropertiesLayerBrush.cs index 48dc97915..258b16220 100644 --- a/src/Artemis.Core/Plugins/LayerBrushes/Internal/PropertiesLayerBrush.cs +++ b/src/Artemis.Core/Plugins/LayerBrushes/Internal/PropertiesLayerBrush.cs @@ -39,8 +39,6 @@ namespace Artemis.Core.LayerBrushes PropertyGroupDescriptionAttribute groupDescription = new() {Identifier = "Brush", Name = Descriptor.DisplayName, Description = Descriptor.Description}; Properties.Initialize(Layer, null, groupDescription, propertyGroupEntity); PropertiesInitialized = true; - - EnableLayerBrush(); } } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj index a034b7833..88ec4b2c3 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -3,8 +3,8 @@ Library net6.0 enable - - + + bin\ x64 x64 @@ -15,20 +15,20 @@ - - - - - - - - - - - + + + + + + + + + + + - + diff --git a/src/Artemis.UI.Shared/Controls/GradientPicker/GradientPickerButton.cs b/src/Artemis.UI.Shared/Controls/GradientPicker/GradientPickerButton.cs index f1a439ea5..1b30c6707 100644 --- a/src/Artemis.UI.Shared/Controls/GradientPicker/GradientPickerButton.cs +++ b/src/Artemis.UI.Shared/Controls/GradientPicker/GradientPickerButton.cs @@ -24,7 +24,7 @@ public class GradientPickerButton : TemplatedControl /// Gets or sets the color gradient. /// public static readonly StyledProperty ColorGradientProperty = - AvaloniaProperty.Register(nameof(ColorGradient), notifying: ColorGradientChanged, defaultValue: ColorGradient.GetUnicornBarf()); + AvaloniaProperty.Register(nameof(ColorGradient), notifying: ColorGradientChanged); /// /// Gets or sets a boolean indicating whether the gradient picker should be in compact mode or not. @@ -108,7 +108,8 @@ public class GradientPickerButton : TemplatedControl private static void ColorGradientChanged(IAvaloniaObject sender, bool before) { - (sender as GradientPickerButton)?.Subscribe(); + if (!before) + (sender as GradientPickerButton)?.Subscribe(); } private void Subscribe() diff --git a/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/UpdateColorGradient.cs b/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/UpdateColorGradient.cs new file mode 100644 index 000000000..d39b011be --- /dev/null +++ b/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/UpdateColorGradient.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Artemis.Core; + +namespace Artemis.UI.Shared.Services.ProfileEditor.Commands; + +/// +/// Represents a profile editor command that can be used to update a layer property of type . +/// +public class UpdateColorGradient : IProfileEditorCommand +{ + private readonly ColorGradient _colorGradient; + private readonly List _stops; + private readonly List _originalStops; + + /// + /// Creates a new instance of the class. + /// + public UpdateColorGradient(ColorGradient colorGradient, List stops, List? originalStops) + { + _colorGradient = colorGradient; + _stops = stops; + _originalStops = originalStops ?? _colorGradient.Select(s => new ColorGradientStop(s.Color, s.Position)).ToList(); + } + + #region Implementation of IProfileEditorCommand + + /// + public string DisplayName => "Update color gradient"; + + /// + public void Execute() + { + _colorGradient.Clear(); + foreach (ColorGradientStop colorGradientStop in _stops) + _colorGradient.Add(colorGradientStop); + } + + /// + public void Undo() + { + _colorGradient.Clear(); + foreach (ColorGradientStop colorGradientStop in _originalStops) + _colorGradient.Add(colorGradientStop); + } + + #endregion +} \ No newline at end of file diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index 3dda6fdaf..92065dd99 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -8,44 +8,44 @@ x64 - + - - - + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - + + + - - + + - - + + @@ -72,8 +72,8 @@ Code - ScriptConfigurationEditView.axaml - Code + ScriptConfigurationEditView.axaml + Code diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/ColorGradientPropertyInputView.axaml b/src/Artemis.UI/DefaultTypes/PropertyInput/ColorGradientPropertyInputView.axaml index e3394db0a..02fb4b16f 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/ColorGradientPropertyInputView.axaml +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/ColorGradientPropertyInputView.axaml @@ -9,7 +9,7 @@ x:DataType="propertyInput:ColorGradientPropertyInputViewModel"> diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/ColorGradientPropertyInputViewModel.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/ColorGradientPropertyInputViewModel.cs index f14e50b7b..2b451b791 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/ColorGradientPropertyInputViewModel.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/ColorGradientPropertyInputViewModel.cs @@ -1,4 +1,6 @@ -using Artemis.Core; +using System.Collections.Generic; +using System.Linq; +using Artemis.Core; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; using Artemis.UI.Shared.Services.PropertyInput; @@ -9,37 +11,19 @@ namespace Artemis.UI.DefaultTypes.PropertyInput; public class ColorGradientPropertyInputViewModel : PropertyInputViewModel { private ColorGradient _colorGradient = null!; - private ColorGradient? _originalGradient; + private List? _originalStops; public ColorGradientPropertyInputViewModel(LayerProperty layerProperty, IProfileEditorService profileEditorService, IPropertyInputService propertyInputService) : base(layerProperty, profileEditorService, propertyInputService) { } - - public ColorGradient ColorGradient - { - get => _colorGradient; - set => this.RaiseAndSetIfChanged(ref _colorGradient, value); - } - - protected override void OnInputValueChanged() - { - ColorGradient = new ColorGradient(InputValue); - } - + #region Overrides of PropertyInputViewModel /// public override void StartPreview() { - _originalGradient = LayerProperty.CurrentValue; - - // Set the property value to the gradient being edited by the picker, this will cause any updates to show right away because - // ColorGradient is a reference type - LayerProperty.CurrentValue = ColorGradient; - - // This won't fly if we ever support keyframes but at that point ColorGradient would have to be a value type anyway and this - // whole VM no longer makes sense + _originalStops = InputValue?.Select(s => new ColorGradientStop(s.Color, s.Position)).ToList(); } /// @@ -51,29 +35,41 @@ public class ColorGradientPropertyInputViewModel : PropertyInputViewModel public override void ApplyPreview() { - if (_originalGradient == null) + // If the new stops are equal to the old ones, nothing changes + if (InputValue == null || _originalStops == null || !HasPreviewChanges()) return; - - // Make sure something actually changed - if (Equals(ColorGradient, _originalGradient)) - LayerProperty.CurrentValue = _originalGradient; - else - // Update the gradient for realsies, giving the command a reference to the old gradient - ProfileEditorService.ExecuteCommand(new UpdateLayerProperty(LayerProperty, ColorGradient, _originalGradient, Time)); - - _originalGradient = null; + + ProfileEditorService.ExecuteCommand(new UpdateColorGradient(InputValue, InputValue.ToList(), _originalStops)); + _originalStops = null; } /// public override void DiscardPreview() { - if (_originalGradient == null) + if (InputValue == null || _originalStops == null) return; // Put the old gradient back - InputValue = _originalGradient; - ColorGradient = new ColorGradient(InputValue); + InputValue.Clear(); + foreach (ColorGradientStop colorGradientStop in _originalStops) + InputValue.Add(colorGradientStop); + _originalStops = null; } + private bool HasPreviewChanges() + { + if (InputValue == null || _originalStops == null) + return false; + + if (InputValue.Count != _originalStops.Count) + return true; + + for (int i = 0; i < InputValue.Count; i++) + if (!Equals(InputValue[i], _originalStops[i])) + return true; + + return false; + } + #endregion } \ No newline at end of file diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/FloatRangePropertyInputViewModel.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/FloatRangePropertyInputViewModel.cs index 52fb5ad67..9ef2c23a1 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/FloatRangePropertyInputViewModel.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/FloatRangePropertyInputViewModel.cs @@ -30,28 +30,20 @@ public class FloatRangePropertyInputViewModel : PropertyInputViewModel InputValue?.Start ?? 0; + get => InputValue.Start; set { - if (InputValue == null) - InputValue = new FloatRange(value, value + 1); - else - InputValue.Start = value; - + InputValue = new FloatRange(value, InputValue.End); this.RaisePropertyChanged(nameof(Start)); } } public float End { - get => InputValue?.End ?? 0; + get => InputValue.End; set { - if (InputValue == null) - InputValue = new FloatRange(value - 1, value); - else - InputValue.End = value; - + InputValue = new FloatRange(InputValue.Start, value); this.RaisePropertyChanged(nameof(End)); } } diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/IntRangePropertyInputViewModel.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/IntRangePropertyInputViewModel.cs index 94004713e..507271c37 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/IntRangePropertyInputViewModel.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/IntRangePropertyInputViewModel.cs @@ -30,28 +30,20 @@ public class IntRangePropertyInputViewModel : PropertyInputViewModel public int Start { - get => InputValue?.Start ?? 0; + get => InputValue.Start; set { - if (InputValue == null) - InputValue = new IntRange(value, value + 1); - else - InputValue.Start = value; - + InputValue = new IntRange(value, InputValue.End); this.RaisePropertyChanged(nameof(Start)); } } public int End { - get => InputValue?.End ?? 0; + get => InputValue.End; set { - if (InputValue == null) - InputValue = new IntRange(value - 1, value); - else - InputValue.End = value; - + InputValue = new IntRange(InputValue.Start, value); this.RaisePropertyChanged(nameof(End)); } }