Browse Source

Added convert to curve commnad

flabbet 7 months ago
parent
commit
55c4de13b2

+ 67 - 0
src/PixiEditor.ChangeableDocument/Changes/Vectors/ConvertToCurve_Change.cs

@@ -0,0 +1,67 @@
+using ChunkyImageLib.Operations;
+using Drawie.Numerics;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;
+using PixiEditor.ChangeableDocument.ChangeInfos.Vectors;
+
+namespace PixiEditor.ChangeableDocument.Changes.Vectors;
+
+internal class ConvertToCurve_Change : Change
+{
+    public readonly Guid memberId;
+
+    private ShapeVectorData originalData;
+
+    [GenerateMakeChangeAction]
+    public ConvertToCurve_Change(Guid memberId)
+    {
+        this.memberId = memberId;
+    }
+
+    public override bool InitializeAndValidate(Document target)
+    {
+        if (target.TryFindNode(memberId, out VectorLayerNode? node))
+        {
+            return node.ShapeData != null && node.ShapeData is not PathVectorData;
+        }
+
+        return false;
+    }
+
+    public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply,
+        out bool ignoreInUndo)
+    {
+        VectorLayerNode node = target.FindNodeOrThrow<VectorLayerNode>(memberId);
+        originalData = node.ShapeData;
+
+        node.ShapeData = new PathVectorData(originalData.ToPath())
+        {
+            Fill = originalData.Fill,
+            FillColor = originalData.FillColor,
+            StrokeColor = originalData.StrokeColor,
+            StrokeWidth = originalData.StrokeWidth,
+            TransformationMatrix = originalData.TransformationMatrix
+        };
+
+        ignoreInUndo = false;
+
+        var aabb = node.ShapeData.TransformedVisualAABB;
+        var affected = new AffectedArea(OperationHelper.FindChunksTouchingRectangle(
+            (RectI)aabb, ChunkyImage.FullChunkSize));
+
+        return new VectorShape_ChangeInfo(memberId, affected);
+    }
+
+    public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
+    {
+        VectorLayerNode node = target.FindNodeOrThrow<VectorLayerNode>(memberId);
+        node.ShapeData = originalData;
+
+        var aabb = node.ShapeData.TransformedVisualAABB;
+        var affected = new AffectedArea(OperationHelper.FindChunksTouchingRectangle(
+            (RectI)aabb, ChunkyImage.FullChunkSize));
+
+        return new VectorShape_ChangeInfo(memberId, affected);
+    }
+}

+ 3 - 1
src/PixiEditor/Data/Localization/Languages/en.json

@@ -834,5 +834,7 @@
   "BLUR_FILTER_NODE": "Gaussian Blur Filter",
   "LENGTH": "Length",
   "GREATER_THAN_OR_EQUAL": "Greater than or equal",
-  "COLOR_NODE": "Color"
+  "COLOR_NODE": "Color",
+  "CONVERT_TO_CURVE": "Convert to curve",
+  "CONVERT_TO_CURVE_DESCRIPTIVE": "Convert selected vector layer to a curve/path"
 }

+ 10 - 0
src/PixiEditor/Models/DocumentModels/Public/DocumentOperationsModule.cs

@@ -906,4 +906,14 @@ internal class DocumentOperationsModule : IDocumentOperations
 
         Internals.ActionAccumulator.AddFinishedActions(actions.ToArray());
     }
+
+    public void ConvertToCurve(Guid memberId)
+    {
+        if (Internals.ChangeController.IsBlockingChangeActive)
+            return;
+
+        Internals.ChangeController.TryStopActiveExecutor();
+
+        Internals.ActionAccumulator.AddFinishedActions(new ConvertToCurve_Action(memberId));
+    }
 }

+ 19 - 0
src/PixiEditor/ViewModels/SubViewModels/LayersViewModel.cs

@@ -206,6 +206,13 @@ internal class LayersViewModel : SubViewModel<ViewModelMain>
         var member = Owner.DocumentManagerSubViewModel.ActiveDocument?.SelectedStructureMember;
         return member is ILayerHandler && member is not IRasterLayerHandler;
     }
+    
+    [Evaluator.CanExecute("PixiEditor.Layer.SelectedMemberIsVectorLayer")]
+    public bool SelectedMemberIsVectorLayer(object property)
+    {
+        var member = Owner.DocumentManagerSubViewModel.ActiveDocument?.SelectedStructureMember;
+        return member is IVectorLayerHandler;
+    }
 
     private bool HasSelectedMember(bool above)
     {
@@ -500,6 +507,18 @@ internal class LayersViewModel : SubViewModel<ViewModelMain>
 
         doc!.Operations.Rasterize(member.Id);
     }
+    
+    [Command.Basic("PixiEditor.Layer.ConvertToCurve", "CONVERT_TO_CURVE", "CONVERT_TO_CURVE_DESCRIPTIVE",
+        CanExecute = "PixiEditor.Layer.SelectedMemberIsVectorLayer")]
+    public void ConvertActiveLayerToCurve()
+    {
+        var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;
+        var member = doc?.SelectedStructureMember;
+        if (member is null)
+            return;
+
+        doc!.Operations.ConvertToCurve(member.Id);
+    }
 
     [Evaluator.Icon("PixiEditor.Layer.ToggleReferenceLayerTopMostIcon")]
     public IImage GetAboveEverythingReferenceLayerIcon()