diff --git a/src/.idea/.idea.Artemis/.idea/avalonia.xml b/src/.idea/.idea.Artemis/.idea/avalonia.xml
index 663884d07..2097abb8a 100644
--- a/src/.idea/.idea.Artemis/.idea/avalonia.xml
+++ b/src/.idea/.idea.Artemis/.idea/avalonia.xml
@@ -18,9 +18,12 @@
+
+
+
diff --git a/src/Artemis.Core/Constants.cs b/src/Artemis.Core/Constants.cs
index b63d493c2..69208acb3 100644
--- a/src/Artemis.Core/Constants.cs
+++ b/src/Artemis.Core/Constants.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Reflection;
using Artemis.Core.JsonConverters;
using Artemis.Core.Services;
using Artemis.Core.Services.Core;
@@ -14,6 +15,11 @@ namespace Artemis.Core
///
public static class Constants
{
+ ///
+ /// The Artemis.Core assembly
+ ///
+ public static readonly Assembly CoreAssembly = typeof(Constants).Assembly;
+
///
/// The full path to the Artemis application folder
///
diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs
index 4153c6cd8..67493f42b 100644
--- a/src/Artemis.Core/Models/Profile/Layer.cs
+++ b/src/Artemis.Core/Models/Profile/Layer.cs
@@ -627,13 +627,12 @@ namespace Artemis.Core
if (LayerBrush == null)
throw new ArtemisCoreException("The layer is not yet ready for rendering");
+ using SKAutoCanvasRestore _ = new(canvas);
foreach (BaseLayerEffect baseLayerEffect in LayerEffects)
{
if (!baseLayerEffect.Suspended)
baseLayerEffect.InternalPreProcess(canvas, bounds, layerPaint);
}
-
- using SKAutoCanvasRestore _ = new(canvas);
canvas.ClipPath(renderPath);
// Restore the blend mode before doing the actual render
diff --git a/src/Artemis.Core/Plugins/LayerBrushes/PerLedLayerBrush.cs b/src/Artemis.Core/Plugins/LayerBrushes/PerLedLayerBrush.cs
index a60db4405..a4296b7aa 100644
--- a/src/Artemis.Core/Plugins/LayerBrushes/PerLedLayerBrush.cs
+++ b/src/Artemis.Core/Plugins/LayerBrushes/PerLedLayerBrush.cs
@@ -35,7 +35,6 @@ namespace Artemis.Core.LayerBrushes
canvas.SetMatrix(canvas.TotalMatrix.PreConcat(Layer.GetTransformMatrix(true, false, false, true).Invert()));
using SKPath pointsPath = new();
- using SKPaint ledPaint = new();
foreach (ArtemisLed artemisLed in Layer.Leds)
{
pointsPath.AddPoly(new[]
@@ -61,7 +60,7 @@ namespace Artemis.Core.LayerBrushes
continue;
// Let the brush determine the color
- ledPaint.Color = GetColor(artemisLed, renderPoint);
+ paint.Color = GetColor(artemisLed, renderPoint);
SKRect ledRectangle = SKRect.Create(
artemisLed.AbsoluteRectangle.Left - Layer.Bounds.Left,
@@ -70,7 +69,7 @@ namespace Artemis.Core.LayerBrushes
artemisLed.AbsoluteRectangle.Height
);
- canvas.DrawRect(ledRectangle, ledPaint);
+ canvas.DrawRect(ledRectangle, paint);
}
}, "Failed to render");
}
diff --git a/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs b/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs
index 495f24dba..9692ac27c 100644
--- a/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs
+++ b/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs
@@ -222,8 +222,8 @@ namespace Artemis.Core.LayerEffects
///
public void Load()
{
- Name = LayerEffectEntity.Name;
HasBeenRenamed = LayerEffectEntity.HasBeenRenamed;
+ Name = HasBeenRenamed ? LayerEffectEntity.Name : Descriptor.DisplayName;
Order = LayerEffectEntity.Order;
}
diff --git a/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs b/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs
index 59fa31b5c..5c605de8d 100644
--- a/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs
+++ b/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs
@@ -87,6 +87,7 @@ public class LayerEffectDescriptor
else
{
effect.LayerEffectEntity = new LayerEffectEntity();
+ effect.Name = DisplayName;
effect.Initialize();
effect.Save();
}
diff --git a/src/Artemis.Core/Stores/LayerEffectStore.cs b/src/Artemis.Core/Stores/LayerEffectStore.cs
index 9793e2021..863da5043 100644
--- a/src/Artemis.Core/Stores/LayerEffectStore.cs
+++ b/src/Artemis.Core/Stores/LayerEffectStore.cs
@@ -51,7 +51,7 @@ namespace Artemis.Core
{
lock (Registrations)
{
- return Registrations.FirstOrDefault(d => d.PluginFeature.Id == providerId && d.LayerEffectDescriptor.LayerEffectType?.Name == typeName);
+ return Registrations.FirstOrDefault(d => d.PluginFeature.Id == providerId && d.LayerEffectDescriptor.LayerEffectType?.FullName == typeName);
}
}
diff --git a/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/RemoveLayerEffect.cs b/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/RemoveLayerEffect.cs
new file mode 100644
index 000000000..e7d284c72
--- /dev/null
+++ b/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/RemoveLayerEffect.cs
@@ -0,0 +1,48 @@
+using System;
+using Artemis.Core;
+using Artemis.Core.LayerEffects;
+
+namespace Artemis.UI.Shared.Services.ProfileEditor.Commands;
+
+///
+/// Represents a profile editor command that can be used to remove a layer effect from a profile element.
+///
+public class RemoveLayerEffect : IProfileEditorCommand, IDisposable
+{
+ private readonly RenderProfileElement _renderProfileElement;
+ private readonly BaseLayerEffect _layerEffect;
+ private bool _executed;
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ public RemoveLayerEffect(BaseLayerEffect layerEffect)
+ {
+ _renderProfileElement = layerEffect.ProfileElement;
+ _layerEffect = layerEffect;
+ }
+
+ ///
+ public string DisplayName => "Remove layer effect";
+
+ ///
+ public void Execute()
+ {
+ _renderProfileElement.RemoveLayerEffect(_layerEffect);
+ _executed = true;
+ }
+
+ ///
+ public void Undo()
+ {
+ _renderProfileElement.AddLayerEffect(_layerEffect);
+ _executed = false;
+ }
+
+ ///
+ public void Dispose()
+ {
+ if (_executed)
+ _layerEffect.Dispose();
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/RenameLayerEffect.cs b/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/RenameLayerEffect.cs
new file mode 100644
index 000000000..6cceb5578
--- /dev/null
+++ b/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/RenameLayerEffect.cs
@@ -0,0 +1,44 @@
+using System;
+using Artemis.Core;
+using Artemis.Core.LayerEffects;
+
+namespace Artemis.UI.Shared.Services.ProfileEditor.Commands;
+
+///
+/// Represents a profile editor command that can be used to rename a layer effect
+///
+public class RenameLayerEffect : IProfileEditorCommand
+{
+ private readonly BaseLayerEffect _layerEffect;
+ private readonly string _name;
+ private readonly string _oldName;
+ private readonly bool _wasRenamed;
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ public RenameLayerEffect(BaseLayerEffect layerEffect, string name)
+ {
+ _layerEffect = layerEffect;
+ _name = name;
+ _oldName = layerEffect.Name;
+ _wasRenamed = layerEffect.HasBeenRenamed;
+ }
+
+ ///
+ public string DisplayName => "Rename layer effect";
+
+ ///
+ public void Execute()
+ {
+ _layerEffect.Name = _name;
+ _layerEffect.HasBeenRenamed = true;
+ }
+
+ ///
+ public void Undo()
+ {
+ _layerEffect.Name = _oldName;
+ _layerEffect.HasBeenRenamed = _wasRenamed;
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj
index af2c19e4d..c5a63eca7 100644
--- a/src/Artemis.UI/Artemis.UI.csproj
+++ b/src/Artemis.UI/Artemis.UI.csproj
@@ -68,6 +68,14 @@
NodeScriptWindowView.axaml
+
+ LayerEffectRenameView.axaml
+ Code
+
+
+ SidebarCategoryEditView.axaml
+ Code
+
diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/SKPointPropertyInputViewModel.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/SKPointPropertyInputViewModel.cs
index db5dd9efc..4f711f997 100644
--- a/src/Artemis.UI/DefaultTypes/PropertyInput/SKPointPropertyInputViewModel.cs
+++ b/src/Artemis.UI/DefaultTypes/PropertyInput/SKPointPropertyInputViewModel.cs
@@ -1,4 +1,5 @@
-using Artemis.Core;
+using System;
+using Artemis.Core;
using Artemis.UI.Shared.Services.ProfileEditor;
using Artemis.UI.Shared.Services.PropertyInput;
using ReactiveUI;
@@ -14,17 +15,17 @@ public class SKPointPropertyInputViewModel : PropertyInputViewModel
{
if (LayerProperty.PropertyDescription.MinInputValue.IsNumber())
{
- this.ValidationRule(vm => vm.X, i => i >= (float) LayerProperty.PropertyDescription.MinInputValue,
+ this.ValidationRule(vm => vm.X, i => i >= Convert.ToSingle(LayerProperty.PropertyDescription.MinInputValue),
$"X must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
- this.ValidationRule(vm => vm.Y, i => i >= (float) LayerProperty.PropertyDescription.MinInputValue,
+ this.ValidationRule(vm => vm.Y, i => i >= Convert.ToSingle(LayerProperty.PropertyDescription.MinInputValue),
$"Y must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
}
if (LayerProperty.PropertyDescription.MaxInputValue.IsNumber())
{
- this.ValidationRule(vm => vm.X, i => i <= (float) LayerProperty.PropertyDescription.MaxInputValue,
+ this.ValidationRule(vm => vm.X, i => i <= Convert.ToSingle(LayerProperty.PropertyDescription.MaxInputValue),
$"X must be equal to or smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
- this.ValidationRule(vm => vm.Y, i => i <= (float) LayerProperty.PropertyDescription.MaxInputValue,
+ this.ValidationRule(vm => vm.Y, i => i <= Convert.ToSingle(LayerProperty.PropertyDescription.MaxInputValue),
$"Y must be equal to or smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
}
}
diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/SKSizePropertyInputViewModel.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/SKSizePropertyInputViewModel.cs
index 510d93959..e1c006d32 100644
--- a/src/Artemis.UI/DefaultTypes/PropertyInput/SKSizePropertyInputViewModel.cs
+++ b/src/Artemis.UI/DefaultTypes/PropertyInput/SKSizePropertyInputViewModel.cs
@@ -1,4 +1,5 @@
-using Artemis.Core;
+using System;
+using Artemis.Core;
using Artemis.UI.Shared.Services.ProfileEditor;
using Artemis.UI.Shared.Services.PropertyInput;
using ReactiveUI;
@@ -16,17 +17,17 @@ public class SKSizePropertyInputViewModel : PropertyInputViewModel
{
if (LayerProperty.PropertyDescription.MinInputValue.IsNumber())
{
- this.ValidationRule(vm => vm.Width, i => i >= (float) LayerProperty.PropertyDescription.MinInputValue,
+ this.ValidationRule(vm => vm.Width, i => i >= Convert.ToSingle(LayerProperty.PropertyDescription.MinInputValue),
$"Width must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
- this.ValidationRule(vm => vm.Height, i => i >= (float) LayerProperty.PropertyDescription.MinInputValue,
+ this.ValidationRule(vm => vm.Height, i => i >= Convert.ToSingle(LayerProperty.PropertyDescription.MinInputValue),
$"Height must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
}
if (LayerProperty.PropertyDescription.MaxInputValue.IsNumber())
{
- this.ValidationRule(vm => vm.Width, i => i <= (float) LayerProperty.PropertyDescription.MaxInputValue,
+ this.ValidationRule(vm => vm.Width, i => i <= Convert.ToSingle(LayerProperty.PropertyDescription.MaxInputValue),
$"Width must be equal to or smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
- this.ValidationRule(vm => vm.Height, i => i <= (float) LayerProperty.PropertyDescription.MaxInputValue,
+ this.ValidationRule(vm => vm.Height, i => i <= Convert.ToSingle(LayerProperty.PropertyDescription.MaxInputValue),
$"Height must be equal to or smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
}
}
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyGroupViewModel.cs
index 83da67450..faa1e3841 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyGroupViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyGroupViewModel.cs
@@ -117,7 +117,8 @@ public class PropertyGroupViewModel : ViewModelBase, IDisposable
{
// Get all properties and property groups and create VMs for them
// The group has methods for getting this without reflection but then we lose the order of the properties as they are defined on the group
- foreach (PropertyInfo propertyInfo in LayerPropertyGroup.GetType().GetProperties())
+ // Sorting is done to ensure properties defined by the Core (such as on layers) are always on top.
+ foreach (PropertyInfo propertyInfo in LayerPropertyGroup.GetType().GetProperties().OrderBy(p => p.DeclaringType?.Assembly != Constants.CoreAssembly))
{
if (Attribute.IsDefined(propertyInfo, typeof(LayerPropertyIgnoreAttribute)))
continue;
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/ContentDialogs/LayerEffectRenameView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/ContentDialogs/LayerEffectRenameView.axaml
new file mode 100644
index 000000000..81414eae7
--- /dev/null
+++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/ContentDialogs/LayerEffectRenameView.axaml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/ContentDialogs/LayerEffectRenameView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/ContentDialogs/LayerEffectRenameView.axaml.cs
new file mode 100644
index 000000000..425743459
--- /dev/null
+++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/ContentDialogs/LayerEffectRenameView.axaml.cs
@@ -0,0 +1,35 @@
+using System.Threading.Tasks;
+using Artemis.UI.Shared.Extensions;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using Avalonia.ReactiveUI;
+using Avalonia.Threading;
+using ReactiveUI;
+
+namespace Artemis.UI.Screens.ProfileEditor.Properties.Tree.ContentDialogs;
+
+public class LayerEffectRenameView : ReactiveUserControl
+{
+ public LayerEffectRenameView()
+ {
+ InitializeComponent();
+ this.WhenActivated(_ =>
+ {
+ this.ClearAllDataValidationErrors();
+ Dispatcher.UIThread.Post(DelayedAutoFocus);
+ });
+ }
+
+ private async void DelayedAutoFocus()
+ {
+ // Don't ask
+ await Task.Delay(200);
+ this.Get("NameTextBox").SelectAll();
+ this.Get("NameTextBox").Focus();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+}
\ 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
new file mode 100644
index 000000000..fd180e95c
--- /dev/null
+++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/ContentDialogs/LayerEffectRenameViewModel.cs
@@ -0,0 +1,45 @@
+using System.Reactive;
+using Artemis.Core.LayerEffects;
+using Artemis.UI.Shared;
+using Artemis.UI.Shared.Services.ProfileEditor;
+using Artemis.UI.Shared.Services.ProfileEditor.Commands;
+using FluentAvalonia.UI.Controls;
+using ReactiveUI;
+using ReactiveUI.Validation.Extensions;
+
+namespace Artemis.UI.Screens.ProfileEditor.Properties.Tree.ContentDialogs
+{
+ public class LayerEffectRenameViewModel : ContentDialogViewModelBase
+ {
+ private readonly IProfileEditorService _profileEditorService;
+ private readonly BaseLayerEffect _layerEffect;
+ private string? _layerEffectName;
+
+ public LayerEffectRenameViewModel(IProfileEditorService profileEditorService, BaseLayerEffect layerEffect)
+ {
+ _profileEditorService = profileEditorService;
+ _layerEffect = layerEffect;
+ _layerEffectName = layerEffect.Name;
+
+ Confirm = ReactiveCommand.Create(ExecuteConfirm, ValidationContext.Valid);
+ this.ValidationRule(vm => vm.LayerEffectName, categoryName => !string.IsNullOrWhiteSpace(categoryName), "You must specify a valid name");
+ }
+
+ public string? LayerEffectName
+ {
+ get => _layerEffectName;
+ set => this.RaiseAndSetIfChanged(ref _layerEffectName, value);
+ }
+
+ public ReactiveCommand Confirm { get; }
+
+ private void ExecuteConfirm()
+ {
+ if (LayerEffectName == null)
+ return;
+
+ _profileEditorService.ExecuteCommand(new RenameLayerEffect(_layerEffect, LayerEffectName));
+ ContentDialog?.Hide(ContentDialogResult.Primary);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupView.axaml
index 0d84c6054..71bdfb6e8 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupView.axaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupView.axaml
@@ -9,7 +9,8 @@
xmlns:properties="clr-namespace:Artemis.UI.Screens.ProfileEditor.Properties"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:Class="Artemis.UI.Screens.ProfileEditor.Properties.Tree.TreeGroupView">
+ x:Class="Artemis.UI.Screens.ProfileEditor.Properties.Tree.TreeGroupView"
+ x:DataType="viewModel:TreeGroupViewModel">
@@ -26,8 +27,8 @@
Height="29">
-
-
+ IsVisible="{CompiledBinding GroupType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static viewModel:LayerPropertyGroupType.None}}" />
+ IsVisible="{CompiledBinding GroupType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static viewModel:LayerPropertyGroupType.General}}">
- General
+ General
+ IsVisible="{CompiledBinding GroupType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static viewModel:LayerPropertyGroupType.Transform}}">
- Transform
+ Transform
-
Brush -
+ IsVisible="{CompiledBinding LayerBrush.ConfigurationDialog, Converter={x:Static ObjectConverters.IsNotNull}}">
Extra options available!
-
@@ -102,61 +103,45 @@
-
-
+
Effect
-
+ IsVisible="{CompiledBinding !LayerEffect.HasBeenRenamed}" />
+ IsVisible="{CompiledBinding LayerEffect.HasBeenRenamed}" />
-
-
-
-
-
-
+ Command="{CompiledBinding RenameEffect}">
+ Command="{CompiledBinding OpenEffectSettings}"
+ IsVisible="{CompiledBinding LayerEffect.ConfigurationDialog, Converter={x:Static ObjectConverters.IsNotNull}}">
+ Command="{CompiledBinding DeleteEffect}">
@@ -186,15 +171,15 @@
Do not bind directly to the PropertyGroupViewModel.Children collection
Instead use a reference provided by the VM that is null when collapsed, virtualization for noobs
-->
-
-
+
-
+
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupViewModel.cs
index 48bd28fde..73b57931b 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupViewModel.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
+using System.Reactive;
using System.Reactive.Disposables;
using System.Reflection;
using System.Threading.Tasks;
@@ -8,12 +9,15 @@ using Artemis.Core;
using Artemis.Core.LayerBrushes;
using Artemis.Core.LayerEffects;
using Artemis.UI.Exceptions;
+using Artemis.UI.Screens.ProfileEditor.Properties.Tree.ContentDialogs;
using Artemis.UI.Screens.ProfileEditor.Properties.Windows;
using Artemis.UI.Shared;
using Artemis.UI.Shared.LayerBrushes;
using Artemis.UI.Shared.LayerEffects;
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 Ninject;
using Ninject.Parameters;
using ReactiveUI;
@@ -41,19 +45,25 @@ public class TreeGroupViewModel : ActivatableViewModelBase
});
// TODO: Update ProfileElementPropertyGroupViewModel visibility on change (can remove the sub on line 41 as well then)
+ OpenBrushSettings = ReactiveCommand.CreateFromTask(ExecuteOpenBrushSettings);
+ OpenEffectSettings = ReactiveCommand.CreateFromTask(ExecuteOpenEffectSettings);
+ RenameEffect = ReactiveCommand.CreateFromTask(ExecuteRenameEffect);
+ DeleteEffect = ReactiveCommand.Create(ExecuteDeleteEffect);
}
-
public PropertyGroupViewModel PropertyGroupViewModel { get; }
public LayerPropertyGroup LayerPropertyGroup => PropertyGroupViewModel.LayerPropertyGroup;
public BaseLayerBrush? LayerBrush => PropertyGroupViewModel.LayerBrush;
public BaseLayerEffect? LayerEffect => PropertyGroupViewModel.LayerEffect;
-
- public ObservableCollection? Children => PropertyGroupViewModel.IsExpanded ? PropertyGroupViewModel.Children : null;
-
public LayerPropertyGroupType GroupType { get; private set; }
+ public ObservableCollection? Children => PropertyGroupViewModel.IsExpanded ? PropertyGroupViewModel.Children : null;
+
+ public ReactiveCommand OpenBrushSettings { get; }
+ public ReactiveCommand OpenEffectSettings { get; }
+ public ReactiveCommand RenameEffect { get; }
+ public ReactiveCommand DeleteEffect { get; }
- public async Task OpenBrushSettings()
+ private async Task ExecuteOpenBrushSettings()
{
if (LayerBrush?.ConfigurationDialog is not LayerBrushConfigurationDialog configurationViewModel)
return;
@@ -83,7 +93,7 @@ public class TreeGroupViewModel : ActivatableViewModelBase
}
}
- public async Task OpenEffectSettings()
+ private async Task ExecuteOpenEffectSettings()
{
if (LayerEffect?.ConfigurationDialog is not LayerEffectConfigurationDialog configurationViewModel)
return;
@@ -113,14 +123,26 @@ public class TreeGroupViewModel : ActivatableViewModelBase
}
}
- public async Task RenameEffect()
+ private async Task ExecuteRenameEffect()
{
- await _windowService.ShowConfirmContentDialog("Not yet implemented", "Try again later :p");
+ if (LayerEffect == null)
+ return;
+
+ await _windowService.CreateContentDialog()
+ .WithTitle("Rename layer effect")
+ .WithViewModel(out LayerEffectRenameViewModel vm, ("layerEffect", LayerEffect))
+ .HavingPrimaryButton(b => b.WithText("Confirm").WithCommand(vm.Confirm))
+ .WithCloseButtonText("Cancel")
+ .WithDefaultButton(ContentDialogButton.Primary)
+ .ShowAsync();
}
- public async Task DeleteEffect()
+ private void ExecuteDeleteEffect()
{
- await _windowService.ShowConfirmContentDialog("Not yet implemented", "Try again later :p");
+ if (LayerEffect == null)
+ return;
+
+ _profileEditorService.ExecuteCommand(new RemoveLayerEffect(LayerEffect));
}
public double GetDepth()