Browse Source

Vector Path Overlay wip

flabbet 9 months ago
parent
commit
a88f60a3f0
54 changed files with 304 additions and 140 deletions
  1. 1 1
      src/ChunkyImageLib/ChunkyImage.cs
  2. 1 1
      src/ChunkyImageLib/Operations/ClearPathOperation.cs
  3. 1 1
      src/ChunkyImageLib/Operations/EllipseHelper.cs
  4. 1 1
      src/ChunkyImageLib/Operations/EllipseOperation.cs
  5. 1 1
      src/ChunkyImageLib/Operations/PathOperation.cs
  6. 1 1
      src/Drawie
  7. 1 1
      src/PixiEditor.ChangeableDocument/ChangeInfos/Drawing/Selection_ChangeInfo.cs
  8. 1 1
      src/PixiEditor.ChangeableDocument/Changeables/Graph/Interfaces/Shapes/IReadOnlyPathData.cs
  9. 0 1
      src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/EllipseVectorData.cs
  10. 1 1
      src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/PathVectorData.cs
  11. 0 1
      src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/RectangleVectorData.cs
  12. 6 0
      src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/VectorLayerNode.cs
  13. 1 1
      src/PixiEditor.ChangeableDocument/Changeables/Interfaces/IReadOnlySelection.cs
  14. 1 1
      src/PixiEditor.ChangeableDocument/Changeables/Selection.cs
  15. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Drawing/FloodFill/FloodFillHelper.cs
  16. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Drawing/FloodFill/FloodFill_Change.cs
  17. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Drawing/PathBasedPen_UpdateableChange.cs
  18. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Drawing/SelectionToMask_Change.cs
  19. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Drawing/TransformSelected_UpdateableChange.cs
  20. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Selection/ClearSelection_Change.cs
  21. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Selection/MagicWand/MagicWandHelper.cs
  22. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Selection/MagicWand/MagicWand_Change.cs
  23. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Selection/SelectEllipse_UpdateableChange.cs
  24. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Selection/SelectLasso_UpdateableChange.cs
  25. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Selection/SelectRectangle_UpdateableChange.cs
  26. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Selection/SelectionChangeHelper.cs
  27. 2 2
      src/PixiEditor.ChangeableDocument/Changes/Selection/SetSelection_Change.cs
  28. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Selection/TransformSelectionPath_UpdateableChange.cs
  29. 1 1
      src/PixiEditor.ChangeableDocument/Enums/SelectionModeEx.cs
  30. 0 1
      src/PixiEditor/Animation/Animators.cs
  31. 1 1
      src/PixiEditor/Animation/IDashPathEffect.cs
  32. 0 1
      src/PixiEditor/Animation/SelectionDashAnimator.cs
  33. 1 1
      src/PixiEditor/Helpers/Converters/VectorPathToVisibleConverter.cs
  34. 1 1
      src/PixiEditor/Models/DocumentModels/Public/DocumentOperationsModule.cs
  35. 0 1
      src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/PasteImageExecutor.cs
  36. 0 1
      src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/TransformSelectedExecutor.cs
  37. 17 16
      src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/VectorPathToolExecutor.cs
  38. 2 1
      src/PixiEditor/Models/Handlers/IDocument.cs
  39. 8 0
      src/PixiEditor/Models/Handlers/IPathOverlayHandler.cs
  40. 6 2
      src/PixiEditor/ViewModels/Document/DocumentViewModel.cs
  41. 31 0
      src/PixiEditor/ViewModels/Document/TransformOverlays/PathOverlayViewModel.cs
  42. 1 1
      src/PixiEditor/ViewModels/Tools/ToolSettings/Toolbars/Toolbar.cs
  43. 0 1
      src/PixiEditor/ViewModels/Tools/Tools/MoveToolViewModel.cs
  44. 10 0
      src/PixiEditor/ViewModels/Tools/Tools/VectorPathToolViewModel.cs
  45. 16 19
      src/PixiEditor/Views/Main/ViewportControls/ViewportOverlays.cs
  46. 1 1
      src/PixiEditor/Views/Overlays/BrushShapeOverlay/BrushShapeOverlay.cs
  47. 52 0
      src/PixiEditor/Views/Overlays/Drawables/DashedStroke.cs
  48. 1 1
      src/PixiEditor/Views/Overlays/Handles/Handle.cs
  49. 40 51
      src/PixiEditor/Views/Overlays/LineToolOverlay/LineToolOverlay.cs
  50. 5 8
      src/PixiEditor/Views/Overlays/Overlay.cs
  51. 75 0
      src/PixiEditor/Views/Overlays/PathOverlay/VectorPathOverlay.cs
  52. 1 1
      src/PixiEditor/Views/Overlays/SelectionOverlay/SelectionOverlay.cs
  53. 1 1
      src/PixiEditor/Views/Overlays/SymmetryOverlay/SymmetryOverlay.cs
  54. 1 1
      src/PixiEditor/Views/Overlays/TransformOverlay/TransformOverlay.cs

+ 1 - 1
src/ChunkyImageLib/ChunkyImage.cs

@@ -11,7 +11,7 @@ using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.ImageData;
 using Drawie.Backend.Core.Surfaces.ImageData;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 [assembly: InternalsVisibleTo("ChunkyImageLibTest")]
 [assembly: InternalsVisibleTo("ChunkyImageLibTest")]

+ 1 - 1
src/ChunkyImageLib/Operations/ClearPathOperation.cs

@@ -1,6 +1,6 @@
 using ChunkyImageLib.DataHolders;
 using ChunkyImageLib.DataHolders;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace ChunkyImageLib.Operations;
 namespace ChunkyImageLib.Operations;

+ 1 - 1
src/ChunkyImageLib/Operations/EllipseHelper.cs

@@ -1,6 +1,6 @@
 using ChunkyImageLib.DataHolders;
 using ChunkyImageLib.DataHolders;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace ChunkyImageLib.Operations;
 namespace ChunkyImageLib.Operations;

+ 1 - 1
src/ChunkyImageLib/Operations/EllipseOperation.cs

@@ -3,7 +3,7 @@ using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace ChunkyImageLib.Operations;
 namespace ChunkyImageLib.Operations;

+ 1 - 1
src/ChunkyImageLib/Operations/PathOperation.cs

@@ -3,7 +3,7 @@ using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace ChunkyImageLib.Operations;
 namespace ChunkyImageLib.Operations;

+ 1 - 1
src/Drawie

@@ -1 +1 @@
-Subproject commit e95540d2b9d4636824dc55e3c9f65f14381dbcdc
+Subproject commit 29fd7c99a39b8b24b8c9f601856fe839febbb4e7

+ 1 - 1
src/PixiEditor.ChangeableDocument/ChangeInfos/Drawing/Selection_ChangeInfo.cs

@@ -1,4 +1,4 @@
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 
 
 namespace PixiEditor.ChangeableDocument.ChangeInfos.Drawing;
 namespace PixiEditor.ChangeableDocument.ChangeInfos.Drawing;
 
 

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Interfaces/Shapes/IReadOnlyPathData.cs

@@ -1,4 +1,4 @@
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces.Shapes;
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces.Shapes;
 
 

+ 0 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/EllipseVectorData.cs

@@ -3,7 +3,6 @@ using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/PathVectorData.cs

@@ -1,7 +1,7 @@
 using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces.Shapes;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces.Shapes;
 
 

+ 0 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Shapes/Data/RectangleVectorData.cs

@@ -3,7 +3,6 @@ using Drawie.Backend.Core;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;

+ 6 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/VectorLayerNode.cs

@@ -124,6 +124,12 @@ public class VectorLayerNode : LayerNode, ITransformableObject, IReadOnlyVectorN
     {
     {
         base.DeserializeAdditionalData(target, data);
         base.DeserializeAdditionalData(target, data);
         ShapeData = (ShapeVectorData)data["ShapeData"];
         ShapeData = (ShapeVectorData)data["ShapeData"];
+
+        if (ShapeData == null)
+        {
+            return new None();
+        }
+        
         var affected = new AffectedArea(OperationHelper.FindChunksTouchingRectangle(
         var affected = new AffectedArea(OperationHelper.FindChunksTouchingRectangle(
             (RectI)ShapeData.TransformedAABB, ChunkyImage.FullChunkSize));
             (RectI)ShapeData.TransformedAABB, ChunkyImage.FullChunkSize));
 
 

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Interfaces/IReadOnlySelection.cs

@@ -1,4 +1,4 @@
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 
 
 namespace PixiEditor.ChangeableDocument.Changeables.Interfaces;
 namespace PixiEditor.ChangeableDocument.Changeables.Interfaces;
 
 

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Selection.cs

@@ -1,6 +1,6 @@
 using PixiEditor.ChangeableDocument.Changeables.Interfaces;
 using PixiEditor.ChangeableDocument.Changeables.Interfaces;
 using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.ColorsImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 
 
 namespace PixiEditor.ChangeableDocument.Changeables;
 namespace PixiEditor.ChangeableDocument.Changeables;
 
 

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Drawing/FloodFill/FloodFillHelper.cs

@@ -6,7 +6,7 @@ using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.ImageData;
 using Drawie.Backend.Core.Surfaces.ImageData;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Drawing.FloodFill;
 namespace PixiEditor.ChangeableDocument.Changes.Drawing.FloodFill;

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Drawing/FloodFill/FloodFill_Change.cs

@@ -1,6 +1,6 @@
 using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Drawing.FloodFill;
 namespace PixiEditor.ChangeableDocument.Changes.Drawing.FloodFill;

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Drawing/PathBasedPen_UpdateableChange.cs

@@ -2,7 +2,7 @@
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Drawing;
 namespace PixiEditor.ChangeableDocument.Changes.Drawing;

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Drawing/SelectionToMask_Change.cs

@@ -3,7 +3,7 @@ using PixiEditor.ChangeableDocument.Changes.Drawing.FloodFill;
 using PixiEditor.ChangeableDocument.Enums;
 using PixiEditor.ChangeableDocument.Enums;
 using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 using BlendMode = Drawie.Backend.Core.Surfaces.BlendMode;
 using BlendMode = Drawie.Backend.Core.Surfaces.BlendMode;
 
 

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Drawing/TransformSelected_UpdateableChange.cs

@@ -7,7 +7,7 @@ using Drawie.Backend.Core;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Drawing;
 namespace PixiEditor.ChangeableDocument.Changes.Drawing;

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Selection/ClearSelection_Change.cs

@@ -1,4 +1,4 @@
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Selection;
 namespace PixiEditor.ChangeableDocument.Changes.Selection;
 
 

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Selection/MagicWand/MagicWandHelper.cs

@@ -4,7 +4,7 @@ using PixiEditor.ChangeableDocument.Changeables.Interfaces;
 using PixiEditor.ChangeableDocument.Changes.Drawing.FloodFill;
 using PixiEditor.ChangeableDocument.Changes.Drawing.FloodFill;
 using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Selection.MagicWand;
 namespace PixiEditor.ChangeableDocument.Changes.Selection.MagicWand;

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Selection/MagicWand/MagicWand_Change.cs

@@ -1,7 +1,7 @@
 using PixiEditor.ChangeableDocument.Changes.Drawing;
 using PixiEditor.ChangeableDocument.Changes.Drawing;
 using PixiEditor.ChangeableDocument.Enums;
 using PixiEditor.ChangeableDocument.Enums;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Selection.MagicWand;
 namespace PixiEditor.ChangeableDocument.Changes.Selection.MagicWand;

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Selection/SelectEllipse_UpdateableChange.cs

@@ -1,6 +1,6 @@
 using PixiEditor.ChangeableDocument.Enums;
 using PixiEditor.ChangeableDocument.Enums;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Selection;
 namespace PixiEditor.ChangeableDocument.Changes.Selection;

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Selection/SelectLasso_UpdateableChange.cs

@@ -1,6 +1,6 @@
 using PixiEditor.ChangeableDocument.Enums;
 using PixiEditor.ChangeableDocument.Enums;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Selection;
 namespace PixiEditor.ChangeableDocument.Changes.Selection;

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Selection/SelectRectangle_UpdateableChange.cs

@@ -1,6 +1,6 @@
 using PixiEditor.ChangeableDocument.Enums;
 using PixiEditor.ChangeableDocument.Enums;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Selection;
 namespace PixiEditor.ChangeableDocument.Changes.Selection;

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Selection/SelectionChangeHelper.cs

@@ -1,6 +1,6 @@
 using ChunkyImageLib.Operations;
 using ChunkyImageLib.Operations;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Selection;
 namespace PixiEditor.ChangeableDocument.Changes.Selection;

+ 2 - 2
src/PixiEditor.ChangeableDocument/Changes/Selection/SetSelection_Change.cs

@@ -1,5 +1,5 @@
-using PixiEditor.ChangeableDocument.Changeables.Interfaces;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
+using PixiEditor.ChangeableDocument.Changeables.Interfaces;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Selection;
 namespace PixiEditor.ChangeableDocument.Changes.Selection;
 internal class SetSelection_Change : Change
 internal class SetSelection_Change : Change

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Selection/TransformSelectionPath_UpdateableChange.cs

@@ -1,5 +1,5 @@
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Selection;
 namespace PixiEditor.ChangeableDocument.Changes.Selection;

+ 1 - 1
src/PixiEditor.ChangeableDocument/Enums/SelectionModeEx.cs

@@ -1,4 +1,4 @@
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 
 
 namespace PixiEditor.ChangeableDocument.Enums;
 namespace PixiEditor.ChangeableDocument.Enums;
 internal static class SelectionModeEx
 internal static class SelectionModeEx

+ 0 - 1
src/PixiEditor/Animation/Animators.cs

@@ -1,6 +1,5 @@
 using Avalonia.Media;
 using Avalonia.Media;
 using Avalonia.Styling;
 using Avalonia.Styling;
-using Drawie.Backend.Core.Surfaces.Vector;
 
 
 namespace PixiEditor.Animation;
 namespace PixiEditor.Animation;
 
 

+ 1 - 1
src/PixiEditor/Animation/IDashPathEffect.cs

@@ -1,4 +1,4 @@
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 
 
 namespace PixiEditor.Animation;
 namespace PixiEditor.Animation;
 
 

+ 0 - 1
src/PixiEditor/Animation/SelectionDashAnimator.cs

@@ -1,6 +1,5 @@
 using Avalonia.Animation;
 using Avalonia.Animation;
 using Avalonia.Media;
 using Avalonia.Media;
-using Drawie.Backend.Core.Surfaces.Vector;
 
 
 namespace PixiEditor.Animation;
 namespace PixiEditor.Animation;
 
 

+ 1 - 1
src/PixiEditor/Helpers/Converters/VectorPathToVisibleConverter.cs

@@ -1,6 +1,6 @@
 using System.Globalization;
 using System.Globalization;
 using Avalonia.Data.Converters;
 using Avalonia.Data.Converters;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 
 
 namespace PixiEditor.Helpers.Converters;
 namespace PixiEditor.Helpers.Converters;
 
 

+ 1 - 1
src/PixiEditor/Models/DocumentModels/Public/DocumentOperationsModule.cs

@@ -8,7 +8,7 @@ using PixiEditor.ChangeableDocument.Actions.Undo;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 using PixiEditor.ChangeableDocument.Enums;
 using PixiEditor.ChangeableDocument.Enums;
 using Drawie.Backend.Core;
 using Drawie.Backend.Core;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Models.Clipboard;
 using PixiEditor.Models.Clipboard;
 using PixiEditor.Models.DocumentModels.UpdateableChangeExecutors;
 using PixiEditor.Models.DocumentModels.UpdateableChangeExecutors;

+ 0 - 1
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/PasteImageExecutor.cs

@@ -3,7 +3,6 @@ using ChunkyImageLib.DataHolders;
 using PixiEditor.ChangeableDocument.Actions.Generated;
 using PixiEditor.ChangeableDocument.Actions.Generated;
 using Drawie.Backend.Core;
 using Drawie.Backend.Core;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
-using Drawie.Backend.Core.Surfaces.Vector;
 using PixiEditor.Models.DocumentModels.UpdateableChangeExecutors.Features;
 using PixiEditor.Models.DocumentModels.UpdateableChangeExecutors.Features;
 using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Tools;
 using PixiEditor.Models.Tools;

+ 0 - 1
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/TransformSelectedExecutor.cs

@@ -4,7 +4,6 @@ using Avalonia.Input;
 using ChunkyImageLib.DataHolders;
 using ChunkyImageLib.DataHolders;
 using PixiEditor.ChangeableDocument.Actions.Generated;
 using PixiEditor.ChangeableDocument.Actions.Generated;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
-using Drawie.Backend.Core.Surfaces.Vector;
 using PixiEditor.Models.DocumentModels.Public;
 using PixiEditor.Models.DocumentModels.Public;
 using PixiEditor.Models.DocumentModels.UpdateableChangeExecutors.Features;
 using PixiEditor.Models.DocumentModels.UpdateableChangeExecutors.Features;
 using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Handlers;

+ 17 - 16
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/VectorPathToolExecutor.cs

@@ -1,5 +1,5 @@
 using Avalonia.Media;
 using Avalonia.Media;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;
 using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Handlers;
@@ -51,8 +51,9 @@ internal class VectorPathToolExecutor : UpdateableChangeExecutor
             }
             }
 
 
             startingPath.MoveTo((VecF)controller.LastPrecisePosition);
             startingPath.MoveTo((VecF)controller.LastPrecisePosition);
-            internals.ActionAccumulator.AddActions(new SetShapeGeometry_Action(member.Id,
-                new PathVectorData(new VectorPath(startingPath))));
+            internals.ActionAccumulator.AddActions(new SetShapeGeometry_Action(member.Id, ConstructShapeData()));
+
+            document.PathOverlayHandler.Show(startingPath);
         }
         }
 
 
         return ExecutionState.Success;
         return ExecutionState.Success;
@@ -61,16 +62,12 @@ internal class VectorPathToolExecutor : UpdateableChangeExecutor
     public override void OnLeftMouseButtonDown(MouseOnCanvasEventArgs args)
     public override void OnLeftMouseButtonDown(MouseOnCanvasEventArgs args)
     {
     {
         startingPath.LineTo((VecF)args.PositionOnCanvas);
         startingPath.LineTo((VecF)args.PositionOnCanvas);
-        PathVectorData vectorData = new PathVectorData(new VectorPath(startingPath))
-        {
-            StrokeWidth = toolbar.ToolSize,
-            StrokeColor = toolbar.StrokeColor.ToColor(),
-            FillColor = toolbar.Fill ? toolbar.FillColor.ToColor() : Colors.Transparent,
-        };
+        PathVectorData vectorData = ConstructShapeData();
 
 
         internals.ActionAccumulator.AddActions(new SetShapeGeometry_Action(member.Id, vectorData));
         internals.ActionAccumulator.AddActions(new SetShapeGeometry_Action(member.Id, vectorData));
     }
     }
 
 
+
     public override void OnColorChanged(Color color, bool primary)
     public override void OnColorChanged(Color color, bool primary)
     {
     {
         if (primary && toolbar.SyncWithPrimaryColor)
         if (primary && toolbar.SyncWithPrimaryColor)
@@ -82,17 +79,21 @@ internal class VectorPathToolExecutor : UpdateableChangeExecutor
 
 
     public override void OnSettingsChanged(string name, object value)
     public override void OnSettingsChanged(string name, object value)
     {
     {
-        internals.ActionAccumulator.AddActions(new SetShapeGeometry_Action(member.Id,
-            new PathVectorData(new VectorPath(startingPath))
-            {
-                StrokeWidth = toolbar.ToolSize,
-                StrokeColor = toolbar.StrokeColor.ToColor(),
-                FillColor = toolbar.Fill ? toolbar.FillColor.ToColor() : Colors.Transparent,
-            }));
+        internals.ActionAccumulator.AddActions(new SetShapeGeometry_Action(member.Id, ConstructShapeData()));
     }
     }
 
 
     public override void ForceStop()
     public override void ForceStop()
     {
     {
         internals.ActionAccumulator.AddActions(new EndSetShapeGeometry_Action());
         internals.ActionAccumulator.AddActions(new EndSetShapeGeometry_Action());
     }
     }
+
+    private PathVectorData ConstructShapeData()
+    {
+        return new PathVectorData(new VectorPath(startingPath))
+        {
+            StrokeWidth = toolbar.ToolSize,
+            StrokeColor = toolbar.StrokeColor.ToColor(),
+            FillColor = toolbar.Fill ? toolbar.FillColor.ToColor() : Colors.Transparent,
+        };
+    }
 }
 }

+ 2 - 1
src/PixiEditor/Models/Handlers/IDocument.cs

@@ -6,7 +6,7 @@ using PixiEditor.ChangeableDocument.Rendering;
 using Drawie.Backend.Core;
 using Drawie.Backend.Core;
 using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Helpers;
 using PixiEditor.Helpers;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.Controllers;
@@ -34,6 +34,7 @@ internal interface IDocument : IHandler
     public string CoordinatesString { get; set; }
     public string CoordinatesString { get; set; }
     public IReadOnlyCollection<IStructureMemberHandler> SoftSelectedStructureMembers { get; }
     public IReadOnlyCollection<IStructureMemberHandler> SoftSelectedStructureMembers { get; }
     public ITransformHandler TransformHandler { get; }
     public ITransformHandler TransformHandler { get; }
+    public IPathOverlayHandler PathOverlayHandler { get; }
     public bool Busy { get; set; }
     public bool Busy { get; set; }
     public ILineOverlayHandler LineToolOverlayHandler { get; }
     public ILineOverlayHandler LineToolOverlayHandler { get; }
     public bool HorizontalSymmetryAxisEnabledBindable { get; }
     public bool HorizontalSymmetryAxisEnabledBindable { get; }

+ 8 - 0
src/PixiEditor/Models/Handlers/IPathOverlayHandler.cs

@@ -0,0 +1,8 @@
+using Drawie.Backend.Core.Vector;
+
+namespace PixiEditor.Models.Handlers;
+
+public interface IPathOverlayHandler : IHandler
+{
+    public void Show(VectorPath path);
+}

+ 6 - 2
src/PixiEditor/ViewModels/Document/DocumentViewModel.cs

@@ -31,7 +31,7 @@ using Drawie.Backend.Core.Bridge;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces.ImageData;
 using Drawie.Backend.Core.Surfaces.ImageData;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Helpers;
 using PixiEditor.Helpers;
@@ -201,6 +201,7 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
     ISnappingHandler IDocument.SnappingHandler => SnappingViewModel;
     ISnappingHandler IDocument.SnappingHandler => SnappingViewModel;
     public IReadOnlyCollection<Guid> SelectedMembers => GetSelectedMembers().AsReadOnly();
     public IReadOnlyCollection<Guid> SelectedMembers => GetSelectedMembers().AsReadOnly();
     public DocumentTransformViewModel TransformViewModel { get; }
     public DocumentTransformViewModel TransformViewModel { get; }
+    public PathOverlayViewModel PathOverlayViewModel { get; }
     public ReferenceLayerViewModel ReferenceLayerViewModel { get; }
     public ReferenceLayerViewModel ReferenceLayerViewModel { get; }
     public LineToolOverlayViewModel LineToolOverlayViewModel { get; }
     public LineToolOverlayViewModel LineToolOverlayViewModel { get; }
     public AnimationDataViewModel AnimationDataViewModel { get; }
     public AnimationDataViewModel AnimationDataViewModel { get; }
@@ -210,6 +211,7 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
     INodeGraphHandler IDocument.NodeGraphHandler => NodeGraph;
     INodeGraphHandler IDocument.NodeGraphHandler => NodeGraph;
     IDocumentOperations IDocument.Operations => Operations;
     IDocumentOperations IDocument.Operations => Operations;
     ITransformHandler IDocument.TransformHandler => TransformViewModel;
     ITransformHandler IDocument.TransformHandler => TransformViewModel;
+    IPathOverlayHandler IDocument.PathOverlayHandler => PathOverlayViewModel;
     ILineOverlayHandler IDocument.LineToolOverlayHandler => LineToolOverlayViewModel;
     ILineOverlayHandler IDocument.LineToolOverlayHandler => LineToolOverlayViewModel;
     IReferenceLayerHandler IDocument.ReferenceLayerHandler => ReferenceLayerViewModel;
     IReferenceLayerHandler IDocument.ReferenceLayerHandler => ReferenceLayerViewModel;
     IAnimationHandler IDocument.AnimationHandler => AnimationDataViewModel;
     IAnimationHandler IDocument.AnimationHandler => AnimationDataViewModel;
@@ -232,7 +234,9 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
 
 
         TransformViewModel = new(this);
         TransformViewModel = new(this);
         TransformViewModel.TransformMoved += (_, args) => Internals.ChangeController.TransformMovedInlet(args);
         TransformViewModel.TransformMoved += (_, args) => Internals.ChangeController.TransformMovedInlet(args);
-
+        
+        PathOverlayViewModel = new(this, Internals);
+        
         LineToolOverlayViewModel = new();
         LineToolOverlayViewModel = new();
         LineToolOverlayViewModel.LineMoved += (_, args) =>
         LineToolOverlayViewModel.LineMoved += (_, args) =>
             Internals.ChangeController.LineOverlayMovedInlet(args.Item1, args.Item2);
             Internals.ChangeController.LineOverlayMovedInlet(args.Item1, args.Item2);

+ 31 - 0
src/PixiEditor/ViewModels/Document/TransformOverlays/PathOverlayViewModel.cs

@@ -0,0 +1,31 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using Drawie.Backend.Core.Vector;
+using PixiEditor.Models.DocumentModels;
+using PixiEditor.Models.Handlers;
+
+namespace PixiEditor.ViewModels.Document.TransformOverlays;
+
+internal class PathOverlayViewModel : ObservableObject, IPathOverlayHandler
+{
+    private DocumentViewModel documentViewModel;
+    private DocumentInternalParts internals;
+    
+    private VectorPath path;
+    public VectorPath Path
+    {
+        get => path;
+        set => SetProperty(ref path, value);
+    }
+    
+    public PathOverlayViewModel(DocumentViewModel documentViewModel, DocumentInternalParts internals)
+    {
+        this.documentViewModel = documentViewModel;
+        this.internals = internals;
+    }
+
+
+    public void Show(VectorPath path)
+    {
+        Path = path;        
+    }
+}

+ 1 - 1
src/PixiEditor/ViewModels/Tools/ToolSettings/Toolbars/Toolbar.cs

@@ -29,7 +29,7 @@ internal abstract class Toolbar : ObservableObject, IToolbar
     /// </summary>
     /// </summary>
     /// <param name="name">Setting name, non case sensitive.</param>
     /// <param name="name">Setting name, non case sensitive.</param>
     /// <returns>Generic Setting.</returns>
     /// <returns>Generic Setting.</returns>
-    public virtual Setting GetSetting(string name)
+    public virtual Setting? GetSetting(string name)
     {
     {
         return Settings.FirstOrDefault(x => string.Equals(x.Name, name, StringComparison.CurrentCultureIgnoreCase));
         return Settings.FirstOrDefault(x => string.Equals(x.Name, name, StringComparison.CurrentCultureIgnoreCase));
     }
     }

+ 0 - 1
src/PixiEditor/ViewModels/Tools/Tools/MoveToolViewModel.cs

@@ -3,7 +3,6 @@ using ChunkyImageLib.DataHolders;
 using PixiEditor.Models.DocumentModels;
 using PixiEditor.Models.DocumentModels;
 using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Handlers;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
-using Drawie.Backend.Core.Surfaces.Vector;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Models.Commands.Attributes.Commands;
 using PixiEditor.Models.Commands.Attributes.Commands;
 using PixiEditor.Models.Handlers.Tools;
 using PixiEditor.Models.Handlers.Tools;

+ 10 - 0
src/PixiEditor/ViewModels/Tools/Tools/VectorPathToolViewModel.cs

@@ -3,6 +3,7 @@ using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Handlers.Tools;
 using PixiEditor.Models.Handlers.Tools;
+using PixiEditor.ViewModels.Tools.ToolSettings.Toolbars;
 
 
 namespace PixiEditor.ViewModels.Tools.Tools;
 namespace PixiEditor.ViewModels.Tools.Tools;
 
 
@@ -13,6 +14,15 @@ internal class VectorPathToolViewModel : ShapeTool, IVectorPathToolHandler
     public override Type LayerTypeToCreateOnEmptyUse { get; } = typeof(VectorLayerNode);
     public override Type LayerTypeToCreateOnEmptyUse { get; } = typeof(VectorLayerNode);
     public override LocalizedString Tooltip => new LocalizedString("PATH_TOOL_TOOLTIP", Shortcut);
     public override LocalizedString Tooltip => new LocalizedString("PATH_TOOL_TOOLTIP", Shortcut);
 
 
+    public VectorPathToolViewModel()
+    {
+        var fillSetting = Toolbar.GetSetting(nameof(BasicShapeToolbar.Fill));
+        if (fillSetting != null)
+        {
+            fillSetting.Value = false;
+        }
+    }
+
     public override void UseTool(VecD pos)
     public override void UseTool(VecD pos)
     {
     {
         ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument?.Tools.UseVectorPathTool();
         ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument?.Tools.UseVectorPathTool();

+ 16 - 19
src/PixiEditor/Views/Main/ViewportControls/ViewportOverlays.cs

@@ -10,6 +10,7 @@ using PixiEditor.ViewModels;
 using PixiEditor.Views.Overlays;
 using PixiEditor.Views.Overlays;
 using PixiEditor.Views.Overlays.BrushShapeOverlay;
 using PixiEditor.Views.Overlays.BrushShapeOverlay;
 using PixiEditor.Views.Overlays.LineToolOverlay;
 using PixiEditor.Views.Overlays.LineToolOverlay;
+using PixiEditor.Views.Overlays.PathOverlay;
 using PixiEditor.Views.Overlays.Pointers;
 using PixiEditor.Views.Overlays.Pointers;
 using PixiEditor.Views.Overlays.SelectionOverlay;
 using PixiEditor.Views.Overlays.SelectionOverlay;
 using PixiEditor.Views.Overlays.SymmetryOverlay;
 using PixiEditor.Views.Overlays.SymmetryOverlay;
@@ -29,6 +30,7 @@ internal class ViewportOverlays
     private ReferenceLayerOverlay referenceLayerOverlay;
     private ReferenceLayerOverlay referenceLayerOverlay;
     private SnappingOverlay snappingOverlay;
     private SnappingOverlay snappingOverlay;
     private BrushShapeOverlay brushShapeOverlay;
     private BrushShapeOverlay brushShapeOverlay;
+    private VectorPathOverlay vectorPathOverlay;
 
 
     public void Init(Viewport viewport)
     public void Init(Viewport viewport)
     {
     {
@@ -56,6 +58,9 @@ internal class ViewportOverlays
 
 
         brushShapeOverlay = new BrushShapeOverlay();
         brushShapeOverlay = new BrushShapeOverlay();
         BindMouseOverlayPointer();
         BindMouseOverlayPointer();
+        
+        vectorPathOverlay = new VectorPathOverlay();
+        BindVectorPathOverlay();
 
 
         Viewport.ActiveOverlays.Add(gridLinesOverlay);
         Viewport.ActiveOverlays.Add(gridLinesOverlay);
         Viewport.ActiveOverlays.Add(referenceLayerOverlay);
         Viewport.ActiveOverlays.Add(referenceLayerOverlay);
@@ -63,6 +68,7 @@ internal class ViewportOverlays
         Viewport.ActiveOverlays.Add(symmetryOverlay);
         Viewport.ActiveOverlays.Add(symmetryOverlay);
         Viewport.ActiveOverlays.Add(lineToolOverlay);
         Viewport.ActiveOverlays.Add(lineToolOverlay);
         Viewport.ActiveOverlays.Add(transformOverlay);
         Viewport.ActiveOverlays.Add(transformOverlay);
+        Viewport.ActiveOverlays.Add(vectorPathOverlay);
         Viewport.ActiveOverlays.Add(snappingOverlay);
         Viewport.ActiveOverlays.Add(snappingOverlay);
         Viewport.ActiveOverlays.Add(brushShapeOverlay);
         Viewport.ActiveOverlays.Add(brushShapeOverlay);
     }
     }
@@ -333,6 +339,16 @@ internal class ViewportOverlays
         transformOverlay.Bind(TransformOverlay.ShowHandlesProperty, showHandlesBinding);
         transformOverlay.Bind(TransformOverlay.ShowHandlesProperty, showHandlesBinding);
         transformOverlay.Bind(TransformOverlay.IsSizeBoxEnabledProperty, isSizeBoxEnabledBinding);
         transformOverlay.Bind(TransformOverlay.IsSizeBoxEnabledProperty, isSizeBoxEnabledBinding);
     }
     }
+    
+    private void BindVectorPathOverlay()
+    {
+        Binding pathBinding = new()
+        {
+            Source = Viewport, Path = "Document.PathOverlayViewModel.Path", Mode = BindingMode.OneWay
+        };
+
+        vectorPathOverlay.Bind(VectorPathOverlay.PathProperty, pathBinding);
+    }
 
 
     private void BindSnappingOverlay()
     private void BindSnappingOverlay()
     {
     {
@@ -344,25 +360,6 @@ internal class ViewportOverlays
         snappingOverlay.Bind(SnappingOverlay.SnappingControllerProperty, snappingControllerBinding);
         snappingOverlay.Bind(SnappingOverlay.SnappingControllerProperty, snappingControllerBinding);
     }
     }
 
 
-/**  <brushShapeOverlay:BrushShapeOverlay
-               DataContext="{Binding ElementName=vpUc}"
-               RenderTransform="{Binding #scene.CanvasTransform}"
-               RenderTransformOrigin="0, 0"
-               Name="brushShapeOverlay"
-               Focusable="False" ZIndex="6"
-               IsHitTestVisible="False"
-               ZoomScale="{Binding #scene.Scale}"
-               Scene="{Binding #scene, Mode=OneTime}"
-               BrushSize="{Binding ToolsSubViewModel.ActiveBasicToolbar.ToolSize, Source={viewModels:MainVM}}"
-               BrushShape="{Binding ToolsSubViewModel.ActiveTool.BrushShape, Source={viewModels:MainVM}, FallbackValue={x:Static brushShapeOverlay:BrushShape.Hidden}}"
-               FlowDirection="LeftToRight">
-               <brushShapeOverlay:BrushShapeOverlay.IsVisible>
-                   <MultiBinding Converter="{converters:AllTrueConverter}">
-                       <Binding Path="!Document.TransformViewModel.TransformActive" />
-                       <Binding Path="IsOverCanvas" />
-                   </MultiBinding>
-               </brushShapeOverlay:BrushShapeOverlay.IsVisible>
-           </brushShapeOverlay:BrushShapeOverlay>*/
     private void BindMouseOverlayPointer()
     private void BindMouseOverlayPointer()
     {
     {
         Binding isTransformingBinding = new()
         Binding isTransformingBinding = new()

+ 1 - 1
src/PixiEditor/Views/Overlays/BrushShapeOverlay/BrushShapeOverlay.cs

@@ -2,7 +2,7 @@
 using ChunkyImageLib.Operations;
 using ChunkyImageLib.Operations;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using PixiEditor.Extensions.UI.Overlays;
 using PixiEditor.Extensions.UI.Overlays;
 using Drawie.Numerics;
 using Drawie.Numerics;
 using PixiEditor.Views.Rendering;
 using PixiEditor.Views.Rendering;

+ 52 - 0
src/PixiEditor/Views/Overlays/Drawables/DashedStroke.cs

@@ -0,0 +1,52 @@
+using Drawie.Backend.Core.ColorsImpl;
+using Drawie.Backend.Core.Surfaces;
+using Drawie.Backend.Core.Surfaces.PaintImpl;
+using Drawie.Backend.Core.Vector;
+using Drawie.Numerics;
+
+namespace PixiEditor.Views.Overlays.Drawables;
+
+public class DashedStroke
+{
+    private Paint blackPaint = new Paint()
+    {
+        Color = Colors.Black, StrokeWidth = 1, Style = PaintStyle.Stroke, IsAntiAliased = true
+    };
+
+    private Paint whiteDashPaint = new Paint()
+    {
+        Color = Colors.White,
+        StrokeWidth = 1,
+        Style = PaintStyle.Stroke,
+        PathEffect = PathEffect.CreateDash(
+            [2, 2], 2),
+        IsAntiAliased = true
+    };
+
+    public void UpdateZoom(float newZoom)
+    {
+        blackPaint.StrokeWidth = (float)(1.0 / newZoom);
+
+        whiteDashPaint.StrokeWidth = (float)(2.0 / newZoom);
+        whiteDashPaint?.PathEffect?.Dispose();
+
+        float[] dashes = [whiteDashPaint.StrokeWidth * 4, whiteDashPaint.StrokeWidth * 3];
+
+        dashes[0] = whiteDashPaint.StrokeWidth * 4;
+        dashes[1] = whiteDashPaint.StrokeWidth * 3;
+
+        whiteDashPaint.PathEffect = PathEffect.CreateDash(dashes, 2);
+    }
+
+    public void Draw(Canvas canvas, VecD start, VecD end)
+    {
+        canvas.DrawLine(start, end, blackPaint);
+        canvas.DrawLine(start, end, whiteDashPaint);
+    }
+
+    public void Draw(Canvas canvas, VectorPath path)
+    {
+        canvas.DrawPath(path, blackPaint);
+        canvas.DrawPath(path, whiteDashPaint);
+    }
+}

+ 1 - 1
src/PixiEditor/Views/Overlays/Handles/Handle.cs

@@ -6,7 +6,7 @@ using Avalonia.Media;
 using PixiEditor.Helpers;
 using PixiEditor.Helpers;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using PixiEditor.Extensions.UI.Overlays;
 using PixiEditor.Extensions.UI.Overlays;
 using Drawie.Numerics;
 using Drawie.Numerics;
 using PixiEditor.Helpers.Extensions;
 using PixiEditor.Helpers.Extensions;

+ 40 - 51
src/PixiEditor/Views/Overlays/LineToolOverlay/LineToolOverlay.cs

@@ -7,7 +7,6 @@ using PixiEditor.Models.Controllers.InputDevice;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
 using PixiEditor.Extensions.UI.Overlays;
 using PixiEditor.Extensions.UI.Overlays;
 using Drawie.Numerics;
 using Drawie.Numerics;
 using PixiEditor.Views.Overlays.Drawables;
 using PixiEditor.Views.Overlays.Drawables;
@@ -17,6 +16,7 @@ using Colors = Drawie.Backend.Core.ColorsImpl.Colors;
 using Point = Avalonia.Point;
 using Point = Avalonia.Point;
 
 
 namespace PixiEditor.Views.Overlays.LineToolOverlay;
 namespace PixiEditor.Views.Overlays.LineToolOverlay;
+
 internal class LineToolOverlay : Overlay
 internal class LineToolOverlay : Overlay
 {
 {
     public static readonly StyledProperty<VecD> LineStartProperty =
     public static readonly StyledProperty<VecD> LineStartProperty =
@@ -46,8 +46,9 @@ internal class LineToolOverlay : Overlay
         set => SetValue(ActionCompletedProperty, value);
         set => SetValue(ActionCompletedProperty, value);
     }
     }
 
 
-    public static readonly StyledProperty<SnappingController> SnappingControllerProperty = AvaloniaProperty.Register<LineToolOverlay, SnappingController>(
-        nameof(SnappingController));
+    public static readonly StyledProperty<SnappingController> SnappingControllerProperty =
+        AvaloniaProperty.Register<LineToolOverlay, SnappingController>(
+            nameof(SnappingController));
 
 
     public SnappingController SnappingController
     public SnappingController SnappingController
     {
     {
@@ -64,30 +65,34 @@ internal class LineToolOverlay : Overlay
         set => SetValue(ShowHandlesProperty, value);
         set => SetValue(ShowHandlesProperty, value);
     }
     }
 
 
-    public static readonly StyledProperty<bool> IsSizeBoxEnabledProperty = AvaloniaProperty.Register<LineToolOverlay, bool>(
-        nameof(IsSizeBoxEnabled));
+    public static readonly StyledProperty<bool> IsSizeBoxEnabledProperty =
+        AvaloniaProperty.Register<LineToolOverlay, bool>(
+            nameof(IsSizeBoxEnabled));
 
 
     public bool IsSizeBoxEnabled
     public bool IsSizeBoxEnabled
     {
     {
         get => GetValue(IsSizeBoxEnabledProperty);
         get => GetValue(IsSizeBoxEnabledProperty);
         set => SetValue(IsSizeBoxEnabledProperty, value);
         set => SetValue(IsSizeBoxEnabledProperty, value);
     }
     }
-    
+
     static LineToolOverlay()
     static LineToolOverlay()
     {
     {
         LineStartProperty.Changed.Subscribe(RenderAffectingPropertyChanged);
         LineStartProperty.Changed.Subscribe(RenderAffectingPropertyChanged);
         LineEndProperty.Changed.Subscribe(RenderAffectingPropertyChanged);
         LineEndProperty.Changed.Subscribe(RenderAffectingPropertyChanged);
     }
     }
-    
 
 
-    private Paint blackPaint = new Paint() { Color = Colors.Black, StrokeWidth = 1, Style = PaintStyle.Stroke, IsAntiAliased = true };
-    private Paint whiteDashPaint = new Paint() { Color = Colors.White, StrokeWidth = 1, Style = PaintStyle.Stroke, PathEffect = PathEffect.CreateDash(
-        [2, 2], 2), IsAntiAliased = true };
+
+    private DashedStroke dashedStroke = new DashedStroke();
+
+    private Paint blackPaint = new Paint()
+    {
+        Color = Colors.Black, StrokeWidth = 1, Style = PaintStyle.Stroke, IsAntiAliased = true
+    };
 
 
     private VecD mouseDownPos = VecD.Zero;
     private VecD mouseDownPos = VecD.Zero;
     private VecD lineStartOnMouseDown = VecD.Zero;
     private VecD lineStartOnMouseDown = VecD.Zero;
     private VecD lineEndOnMouseDown = VecD.Zero;
     private VecD lineEndOnMouseDown = VecD.Zero;
-    
+
     private VecD lastMousePos = VecD.Zero;
     private VecD lastMousePos = VecD.Zero;
 
 
     private bool movedWhileMouseDown = false;
     private bool movedWhileMouseDown = false;
@@ -95,7 +100,7 @@ internal class LineToolOverlay : Overlay
     private RectangleHandle startHandle;
     private RectangleHandle startHandle;
     private RectangleHandle endHandle;
     private RectangleHandle endHandle;
     private TransformHandle moveHandle;
     private TransformHandle moveHandle;
-    
+
     private bool isDraggingHandle = false;
     private bool isDraggingHandle = false;
     private InfoBox infoBox;
     private InfoBox infoBox;
 
 
@@ -129,7 +134,7 @@ internal class LineToolOverlay : Overlay
         moveHandle.OnHover += handle => Refresh();
         moveHandle.OnHover += handle => Refresh();
         moveHandle.OnRelease += OnHandleRelease;
         moveHandle.OnRelease += OnHandleRelease;
         AddHandle(moveHandle);
         AddHandle(moveHandle);
-        
+
         infoBox = new InfoBox();
         infoBox = new InfoBox();
     }
     }
 
 
@@ -147,25 +152,15 @@ internal class LineToolOverlay : Overlay
             SnappingController.HighlightedYAxis = null;
             SnappingController.HighlightedYAxis = null;
             Refresh();
             Refresh();
         }
         }
-        
+
         isDraggingHandle = false;
         isDraggingHandle = false;
         IsSizeBoxEnabled = false;
         IsSizeBoxEnabled = false;
     }
     }
 
 
     protected override void ZoomChanged(double newZoom)
     protected override void ZoomChanged(double newZoom)
     {
     {
-        blackPaint.StrokeWidth = (float)(1.0 / newZoom);
-        
-        whiteDashPaint.StrokeWidth = (float)(2.0 / newZoom);
-        whiteDashPaint?.PathEffect?.Dispose();
-        
-        float[] dashes = new float[] { whiteDashPaint.StrokeWidth * 4, whiteDashPaint.StrokeWidth * 3 }; 
-
-        dashes[0] = whiteDashPaint.StrokeWidth * 4;
-        dashes[1] = whiteDashPaint.StrokeWidth * 3;
-        
-        whiteDashPaint.PathEffect = PathEffect.CreateDash(dashes, 2);
-        
+        blackPaint.StrokeWidth = 1 / (float)newZoom;
+        dashedStroke.UpdateZoom((float)newZoom);
         infoBox.ZoomScale = newZoom;
         infoBox.ZoomScale = newZoom;
     }
     }
 
 
@@ -173,17 +168,16 @@ internal class LineToolOverlay : Overlay
     {
     {
         VecD mappedStart = LineStart;
         VecD mappedStart = LineStart;
         VecD mappedEnd = LineEnd;
         VecD mappedEnd = LineEnd;
-        
+
         startHandle.Position = mappedStart;
         startHandle.Position = mappedStart;
-        endHandle.Position = mappedEnd; 
-        
+        endHandle.Position = mappedEnd;
+
         VecD center = (mappedStart + mappedEnd) / 2;
         VecD center = (mappedStart + mappedEnd) / 2;
         VecD size = mappedEnd - mappedStart;
         VecD size = mappedEnd - mappedStart;
-        
+
         moveHandle.Position = TransformHelper.GetHandlePos(new ShapeCorners(center, size), ZoomScale, moveHandle.Size);
         moveHandle.Position = TransformHelper.GetHandlePos(new ShapeCorners(center, size), ZoomScale, moveHandle.Size);
 
 
-        context.DrawLine(new VecD(mappedStart.X, mappedStart.Y), new VecD(mappedEnd.X, mappedEnd.Y), blackPaint);
-        context.DrawLine(new VecD(mappedStart.X, mappedStart.Y), new VecD(mappedEnd.X, mappedEnd.Y), whiteDashPaint);
+        dashedStroke.Draw(context, mappedStart, mappedEnd);
 
 
         if (ShowHandles)
         if (ShowHandles)
         {
         {
@@ -217,7 +211,7 @@ internal class LineToolOverlay : Overlay
         VecD delta = position - mouseDownPos;
         VecD delta = position - mouseDownPos;
         LineStart = SnapAndHighlight(lineStartOnMouseDown + delta);
         LineStart = SnapAndHighlight(lineStartOnMouseDown + delta);
         movedWhileMouseDown = true;
         movedWhileMouseDown = true;
-        
+
         lastMousePos = position;
         lastMousePos = position;
         isDraggingHandle = true;
         isDraggingHandle = true;
         IsSizeBoxEnabled = true;
         IsSizeBoxEnabled = true;
@@ -227,10 +221,10 @@ internal class LineToolOverlay : Overlay
     {
     {
         VecD delta = position - mouseDownPos;
         VecD delta = position - mouseDownPos;
         VecD final = SnapAndHighlight(lineEndOnMouseDown + delta);
         VecD final = SnapAndHighlight(lineEndOnMouseDown + delta);
-        
+
         LineEnd = final;
         LineEnd = final;
         movedWhileMouseDown = true;
         movedWhileMouseDown = true;
-        
+
         isDraggingHandle = true;
         isDraggingHandle = true;
         lastMousePos = position;
         lastMousePos = position;
         IsSizeBoxEnabled = true;
         IsSizeBoxEnabled = true;
@@ -243,17 +237,17 @@ internal class LineToolOverlay : Overlay
         {
         {
             double? x = SnappingController.SnapToHorizontal(position.X, out string snapAxisX);
             double? x = SnappingController.SnapToHorizontal(position.X, out string snapAxisX);
             double? y = SnappingController.SnapToVertical(position.Y, out string snapAxisY);
             double? y = SnappingController.SnapToVertical(position.Y, out string snapAxisY);
-            
+
             if (x.HasValue)
             if (x.HasValue)
             {
             {
                 final = new VecD(x.Value, final.Y);
                 final = new VecD(x.Value, final.Y);
             }
             }
-            
+
             if (y.HasValue)
             if (y.HasValue)
             {
             {
                 final = new VecD(final.X, y.Value);
                 final = new VecD(final.X, y.Value);
             }
             }
-            
+
             SnappingController.HighlightedXAxis = snapAxisX;
             SnappingController.HighlightedXAxis = snapAxisX;
             SnappingController.HighlightedYAxis = snapAxisY;
             SnappingController.HighlightedYAxis = snapAxisY;
         }
         }
@@ -264,7 +258,7 @@ internal class LineToolOverlay : Overlay
     private void MoveHandleOnDrag(Handle source, VecD position)
     private void MoveHandleOnDrag(Handle source, VecD position)
     {
     {
         var delta = position - mouseDownPos;
         var delta = position - mouseDownPos;
-        
+
         VecD mappedStart = lineStartOnMouseDown;
         VecD mappedStart = lineStartOnMouseDown;
         VecD mappedEnd = lineEndOnMouseDown;
         VecD mappedEnd = lineEndOnMouseDown;
 
 
@@ -275,7 +269,7 @@ internal class LineToolOverlay : Overlay
             SnappingController.HighlightedXAxis = snapDeltaResult.Item1.Item1;
             SnappingController.HighlightedXAxis = snapDeltaResult.Item1.Item1;
             SnappingController.HighlightedYAxis = snapDeltaResult.Item1.Item2;
             SnappingController.HighlightedYAxis = snapDeltaResult.Item1.Item2;
         }
         }
-        
+
         LineStart = lineStartOnMouseDown + delta + snapDeltaResult.Item2;
         LineStart = lineStartOnMouseDown + delta + snapDeltaResult.Item2;
         LineEnd = lineEndOnMouseDown + delta + snapDeltaResult.Item2;
         LineEnd = lineEndOnMouseDown + delta + snapDeltaResult.Item2;
 
 
@@ -289,7 +283,6 @@ internal class LineToolOverlay : Overlay
 
 
         if (movedWhileMouseDown && ActionCompleted is not null && ActionCompleted.CanExecute(null))
         if (movedWhileMouseDown && ActionCompleted is not null && ActionCompleted.CanExecute(null))
             ActionCompleted.Execute(null);
             ActionCompleted.Execute(null);
-        
     }
     }
 
 
     private ((string, string), VecD) TrySnapLine(VecD originalStart, VecD originalEnd, VecD delta)
     private ((string, string), VecD) TrySnapLine(VecD originalStart, VecD originalEnd, VecD delta)
@@ -298,21 +291,17 @@ internal class LineToolOverlay : Overlay
         {
         {
             return ((string.Empty, string.Empty), delta);
             return ((string.Empty, string.Empty), delta);
         }
         }
-        
+
         VecD center = (originalStart + originalEnd) / 2f;
         VecD center = (originalStart + originalEnd) / 2f;
-        VecD[] pointsToTest = new VecD[]
-        {
-            center + delta,
-            originalStart + delta,
-            originalEnd + delta,
-        };
+        VecD[] pointsToTest = new VecD[] { center + delta, originalStart + delta, originalEnd + delta, };
 
 
-        VecD snapDelta = SnappingController.GetSnapDeltaForPoints(pointsToTest, out string snapAxisX, out string snapAxisY);
+        VecD snapDelta =
+            SnappingController.GetSnapDeltaForPoints(pointsToTest, out string snapAxisX, out string snapAxisY);
 
 
         return ((snapAxisX, snapAxisY), snapDelta);
         return ((snapAxisX, snapAxisY), snapDelta);
     }
     }
-    
-    
+
+
     private static void RenderAffectingPropertyChanged(AvaloniaPropertyChangedEventArgs<VecD> e)
     private static void RenderAffectingPropertyChanged(AvaloniaPropertyChangedEventArgs<VecD> e)
     {
     {
         if (e.Sender is LineToolOverlay overlay)
         if (e.Sender is LineToolOverlay overlay)

+ 5 - 8
src/PixiEditor/Views/Overlays/Overlay.cs

@@ -57,7 +57,7 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
     }
     }
 
 
     public virtual bool CanRender() => true;
     public virtual bool CanRender() => true;
-    
+
     public abstract void RenderOverlay(Canvas context, RectD canvasBounds);
     public abstract void RenderOverlay(Canvas context, RectD canvasBounds);
 
 
     public void Refresh()
     public void Refresh()
@@ -106,6 +106,7 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
         if (Handles.Contains(handle)) return;
         if (Handles.Contains(handle)) return;
 
 
         Handles.Add(handle);
         Handles.Add(handle);
+        handle.ZoomScale = ZoomScale; 
     }
     }
 
 
     public void ForAllHandles(Action<Handle> action)
     public void ForAllHandles(Action<Handle> action)
@@ -176,29 +177,25 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
     }
     }
 
 
     protected virtual void ZoomChanged(double newZoom) { }
     protected virtual void ZoomChanged(double newZoom) { }
+
     protected virtual void OnOverlayPointerReleased(OverlayPointerArgs args)
     protected virtual void OnOverlayPointerReleased(OverlayPointerArgs args)
     {
     {
-
     }
     }
 
 
     protected virtual void OnOverlayPointerPressed(OverlayPointerArgs args)
     protected virtual void OnOverlayPointerPressed(OverlayPointerArgs args)
     {
     {
-
     }
     }
 
 
     protected virtual void OnOverlayPointerMoved(OverlayPointerArgs args)
     protected virtual void OnOverlayPointerMoved(OverlayPointerArgs args)
     {
     {
-
     }
     }
 
 
     protected virtual void OnOverlayPointerExited(OverlayPointerArgs args)
     protected virtual void OnOverlayPointerExited(OverlayPointerArgs args)
     {
     {
-
     }
     }
 
 
     protected virtual void OnOverlayPointerEntered(OverlayPointerArgs args)
     protected virtual void OnOverlayPointerEntered(OverlayPointerArgs args)
     {
     {
-
     }
     }
 
 
     private static void OnZoomScaleChanged(AvaloniaPropertyChangedEventArgs<double> e)
     private static void OnZoomScaleChanged(AvaloniaPropertyChangedEventArgs<double> e)
@@ -212,7 +209,7 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
             }
             }
         }
         }
     }
     }
-    
+
     private void OnIsVisibleChanged(AvaloniaPropertyChangedEventArgs<bool> e)
     private void OnIsVisibleChanged(AvaloniaPropertyChangedEventArgs<bool> e)
     {
     {
         if (e.NewValue.Value)
         if (e.NewValue.Value)
@@ -220,7 +217,7 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
             Refresh();
             Refresh();
         }
         }
     }
     }
-    
+
     protected static void AffectsOverlayRender(params AvaloniaProperty[] properties)
     protected static void AffectsOverlayRender(params AvaloniaProperty[] properties)
     {
     {
         foreach (var property in properties)
         foreach (var property in properties)

+ 75 - 0
src/PixiEditor/Views/Overlays/PathOverlay/VectorPathOverlay.cs

@@ -0,0 +1,75 @@
+using Avalonia;
+using Drawie.Backend.Core.ColorsImpl;
+using Drawie.Backend.Core.Surfaces.PaintImpl;
+using Drawie.Backend.Core.Vector;
+using Drawie.Numerics;
+using PixiEditor.Views.Overlays.Drawables;
+using PixiEditor.Views.Overlays.Handles;
+using Canvas = Drawie.Backend.Core.Surfaces.Canvas;
+
+namespace PixiEditor.Views.Overlays.PathOverlay;
+
+public class VectorPathOverlay : Overlay
+{
+    public static readonly StyledProperty<VectorPath> PathProperty =
+        AvaloniaProperty.Register<VectorPathOverlay, VectorPath>(
+            nameof(Path));
+
+    public VectorPath Path
+    {
+        get => GetValue(PathProperty);
+        set => SetValue(PathProperty, value);
+    }
+
+    private DashedStroke dashedStroke = new DashedStroke();
+
+    private List<AnchorHandle> pointsHandles = new List<AnchorHandle>();
+
+    protected override void ZoomChanged(double newZoom)
+    {
+        dashedStroke.UpdateZoom((float)newZoom);
+    }
+    
+    public override void RenderOverlay(Canvas context, RectD canvasBounds)
+    {
+        if (Path is null)
+        {
+            return;
+        }
+
+        dashedStroke.Draw(context, Path);
+        var points = Path.Points;
+
+        AdjustHandles(points);
+        RenderHandles(context, points);
+    }
+
+    private void RenderHandles(Canvas context, VecF[] points)
+    {
+        for (int i = 0; i < points.Length; i++)
+        {
+            pointsHandles[i].Position = new VecD(points[i].X, points[i].Y);
+            pointsHandles[i].Draw(context);
+        }
+    }
+
+    private void AdjustHandles(VecF[] points)
+    {
+        if (pointsHandles.Count != points.Length)
+        {
+            if (pointsHandles.Count > points.Length)
+            {
+                pointsHandles.RemoveRange(points.Length, pointsHandles.Count - points.Length);
+                Handles.RemoveRange(points.Length, Handles.Count - points.Length);
+            }
+            else
+            {
+                for (int i = pointsHandles.Count; i < points.Length; i++)
+                {
+                    pointsHandles.Add(new AnchorHandle(this));
+                    AddHandle(pointsHandles[i]);
+                }
+            }
+        }
+    }
+}

+ 1 - 1
src/PixiEditor/Views/Overlays/SelectionOverlay/SelectionOverlay.cs

@@ -8,7 +8,7 @@ using PixiEditor.Animation;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
+using Drawie.Backend.Core.Vector;
 using Drawie.Numerics;
 using Drawie.Numerics;
 using PixiEditor.Helpers.Extensions;
 using PixiEditor.Helpers.Extensions;
 using Color = Drawie.Backend.Core.ColorsImpl.Color;
 using Color = Drawie.Backend.Core.ColorsImpl.Color;

+ 1 - 1
src/PixiEditor/Views/Overlays/SymmetryOverlay/SymmetryOverlay.cs

@@ -5,8 +5,8 @@ using Avalonia.Media;
 using PixiEditor.ChangeableDocument.Enums;
 using PixiEditor.ChangeableDocument.Enums;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
 using Drawie.Backend.Core.Text;
 using Drawie.Backend.Core.Text;
+using Drawie.Backend.Core.Vector;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Extensions.UI.Overlays;
 using PixiEditor.Extensions.UI.Overlays;
 using Drawie.Numerics;
 using Drawie.Numerics;

+ 1 - 1
src/PixiEditor/Views/Overlays/TransformOverlay/TransformOverlay.cs

@@ -12,8 +12,8 @@ using PixiEditor.Helpers.Extensions;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
-using Drawie.Backend.Core.Surfaces.Vector;
 using Drawie.Backend.Core.Text;
 using Drawie.Backend.Core.Text;
+using Drawie.Backend.Core.Vector;
 using PixiEditor.Extensions.UI.Overlays;
 using PixiEditor.Extensions.UI.Overlays;
 using PixiEditor.Helpers.UI;
 using PixiEditor.Helpers.UI;
 using PixiEditor.Models.Controllers.InputDevice;
 using PixiEditor.Models.Controllers.InputDevice;