diff --git a/src/Artemis.Core/Models/BreakableModel.cs b/src/Artemis.Core/Models/BreakableModel.cs
index 1910cc2cc..f0338cd0f 100644
--- a/src/Artemis.Core/Models/BreakableModel.cs
+++ b/src/Artemis.Core/Models/BreakableModel.cs
@@ -59,7 +59,7 @@ public abstract class BreakableModel : CorePropertyChanged, IBreakableModel
}
///
- public void SetBrokenState(string state, Exception? exception)
+ public void SetBrokenState(string state, Exception? exception = null)
{
BrokenState = state ?? throw new ArgumentNullException(nameof(state));
BrokenStateException = exception;
diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs
index a92aabc35..85683eb49 100644
--- a/src/Artemis.Core/Models/Profile/Layer.cs
+++ b/src/Artemis.Core/Models/Profile/Layer.cs
@@ -16,6 +16,9 @@ namespace Artemis.Core;
///
public sealed class Layer : RenderProfileElement
{
+ private const string BROKEN_STATE_BRUSH_NOT_FOUND = "Failed to load layer brush, ensure the plugin is enabled";
+ private const string BROKEN_STATE_INIT_FAILED = "Failed to initialize layer brush";
+
private readonly List _renderCopies = new();
private LayerGeneralProperties _general = new();
private LayerTransformProperties _transform = new();
@@ -261,7 +264,10 @@ public sealed class Layer : RenderProfileElement
private void LayerBrushStoreOnLayerBrushRemoved(object? sender, LayerBrushStoreEvent e)
{
if (LayerBrush?.Descriptor == e.Registration.LayerBrushDescriptor)
+ {
DeactivateLayerBrush();
+ SetBrokenState(BROKEN_STATE_BRUSH_NOT_FOUND);
+ }
}
private void LayerBrushStoreOnLayerBrushAdded(object? sender, LayerBrushStoreEvent e)
@@ -807,33 +813,46 @@ public sealed class Layer : RenderProfileElement
///
/// Changes the current layer brush to the provided layer brush and activates it
///
- public void ChangeLayerBrush(BaseLayerBrush? layerBrush)
+ public void ChangeLayerBrush(BaseLayerBrush layerBrush)
{
- BaseLayerBrush? oldLayerBrush = LayerBrush;
+ if (layerBrush == null)
+ throw new ArgumentNullException(nameof(layerBrush));
- General.BrushReference.SetCurrentValue(layerBrush != null ? new LayerBrushReference(layerBrush.Descriptor) : null);
+ BaseLayerBrush? oldLayerBrush = LayerBrush;
+ General.BrushReference.SetCurrentValue(new LayerBrushReference(layerBrush.Descriptor));
LayerBrush = layerBrush;
+ // Don't dispose the brush, only disable it
+ // That way an undo-action does not need to worry about disposed brushes
oldLayerBrush?.InternalDisable();
-
- if (LayerBrush != null)
- ActivateLayerBrush();
- else
- OnLayerBrushUpdated();
+ ActivateLayerBrush();
}
- internal void ActivateLayerBrush()
+ private void ActivateLayerBrush()
{
try
{
+ // If the brush is null, try to instantiate it
if (LayerBrush == null)
{
- // If the brush is null, try to instantiate it
+ // Ensure the provider is loaded and still provides the expected brush
LayerBrushReference? brushReference = General.BrushReference.CurrentValue;
if (brushReference?.LayerBrushProviderId != null && brushReference.BrushType != null)
- ChangeLayerBrush(LayerBrushStore.Get(brushReference.LayerBrushProviderId, brushReference.BrushType)?.LayerBrushDescriptor.CreateInstance(this, LayerEntity.LayerBrush));
- // If that's not possible there's nothing to do
- return;
+ {
+ // Only apply the brush if it is successfully retrieved from the store and instantiated
+ BaseLayerBrush? layerBrush = LayerBrushStore.Get(brushReference.LayerBrushProviderId, brushReference.BrushType)?.LayerBrushDescriptor.CreateInstance(this, LayerEntity.LayerBrush);
+ if (layerBrush != null)
+ {
+ ClearBrokenState(BROKEN_STATE_BRUSH_NOT_FOUND);
+ ChangeLayerBrush(layerBrush);
+ }
+ // If that's not possible there's nothing to do
+ else
+ {
+ SetBrokenState(BROKEN_STATE_BRUSH_NOT_FOUND);
+ return;
+ }
+ }
}
General.ShapeType.IsHidden = LayerBrush != null && !LayerBrush.SupportsTransformation;
@@ -846,15 +865,15 @@ public sealed class Layer : RenderProfileElement
}
OnLayerBrushUpdated();
- ClearBrokenState("Failed to initialize layer brush");
+ ClearBrokenState(BROKEN_STATE_INIT_FAILED);
}
catch (Exception e)
{
- SetBrokenState("Failed to initialize layer brush", e);
+ SetBrokenState(BROKEN_STATE_INIT_FAILED, e);
}
}
- internal void DeactivateLayerBrush()
+ private void DeactivateLayerBrush()
{
if (LayerBrush == null)
return;
diff --git a/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/ChangeLayerBrush.cs b/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/ChangeLayerBrush.cs
index 1c9a508c2..ce92133d6 100644
--- a/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/ChangeLayerBrush.cs
+++ b/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/ChangeLayerBrush.cs
@@ -54,7 +54,8 @@ public class ChangeLayerBrush : IProfileEditorCommand, IDisposable
///
public void Undo()
{
- _layer.ChangeLayerBrush(_previousBrush);
+ if (_previousBrush != null)
+ _layer.ChangeLayerBrush(_previousBrush);
_executed = false;
}
diff --git a/src/Artemis.UI.Shared/Styles/Artemis.axaml b/src/Artemis.UI.Shared/Styles/Artemis.axaml
index 9907a4b20..988213ad4 100644
--- a/src/Artemis.UI.Shared/Styles/Artemis.axaml
+++ b/src/Artemis.UI.Shared/Styles/Artemis.axaml
@@ -21,6 +21,7 @@
+
diff --git a/src/Artemis.UI.Shared/Styles/BrokenState.axaml b/src/Artemis.UI.Shared/Styles/BrokenState.axaml
new file mode 100644
index 000000000..65ef465c0
--- /dev/null
+++ b/src/Artemis.UI.Shared/Styles/BrokenState.axaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml
index b9301627e..60f0456da 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml
@@ -4,21 +4,19 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:profileTree="clr-namespace:Artemis.UI.Screens.ProfileEditor.ProfileTree"
+ xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.FolderTreeItemView"
x:DataType="profileTree:FolderTreeItemViewModel">
-
+
-
+
-
+
+
+
-