浏览代码

New polygon on closed shape

flabbet 9 月之前
父节点
当前提交
919dc580d2

+ 2 - 0
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/VectorPathToolExecutor.cs

@@ -27,6 +27,8 @@ internal class VectorPathToolExecutor : UpdateableChangeExecutor, IPathExecutor,
     public bool CanUndo => document.PathOverlayHandler.HasUndo;
     public bool CanRedo => document.PathOverlayHandler.HasRedo;
 
+    public override bool BlocksOtherActions => false; 
+
     public override ExecutionState Start()
     {
         vectorPathToolHandler = GetHandler<IVectorPathToolHandler>();

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

@@ -1,8 +1,12 @@
 using Drawie.Numerics;
+using PixiEditor.ChangeableDocument;
+using PixiEditor.ChangeableDocument.Changeables.Animations;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces.Shapes;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Handlers.Tools;
+using PixiEditor.ViewModels.Document;
 using PixiEditor.ViewModels.Tools.ToolSettings.Toolbars;
 
 namespace PixiEditor.ViewModels.Tools.Tools;
@@ -31,6 +35,21 @@ internal class VectorPathToolViewModel : ShapeTool, IVectorPathToolHandler
             ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument;
         
         if (doc is null) return;
+        
+        if(NeedsNewLayer(doc.SelectedStructureMember, doc.AnimationDataViewModel.ActiveFrameTime))
+        {
+            Guid? created = doc.Operations.CreateStructureMember(typeof(VectorLayerNode), ActionSource.Automated);
+            
+            if (created is null) return;
+
+            doc.Operations.SetSelectedMember(created.Value);
+            
+            doc.Operations.InvokeCustomAction(() =>
+            {
+                OnDeselecting(false);
+                OnSelected(false);
+            });
+        }
 
         if (!doc.PathOverlayViewModel.IsActive)
         {
@@ -52,4 +71,15 @@ internal class VectorPathToolViewModel : ShapeTool, IVectorPathToolHandler
             ViewModelMain.Current.DocumentManagerSubViewModel.ActiveDocument?.Operations.TryStopToolLinkedExecutor();
         }
     }
+    
+    private bool NeedsNewLayer(IStructureMemberHandler? member, KeyFrameTime frameTime)
+    {
+        var shapeData = (member as IVectorLayerHandler).GetShapeData(frameTime);
+        if (shapeData is null)
+        {
+            return false;
+        }
+        
+        return shapeData is not IReadOnlyPathData pathData || pathData.Path.IsClosed;
+    }
 }

+ 25 - 3
src/PixiEditor/Views/Overlays/PathOverlay/VectorPathOverlay.cs

@@ -55,7 +55,7 @@ public class VectorPathOverlay : Overlay
         dashedStroke.Draw(context, Path);
         var points = Path.Points;
 
-        AdjustHandles(points, Path.IsClosed);
+        AdjustHandles(points);
         RenderHandles(context, points);
     }
 
@@ -70,13 +70,13 @@ public class VectorPathOverlay : Overlay
         }
     }
 
-    private void AdjustHandles(IReadOnlyList<VecF> points, bool isClosed)
+    private void AdjustHandles(IReadOnlyList<VecF> points)
     {
         if (Handles.Count != points.Count)
         {
             if (Handles.Count > points.Count)
             {
-                Handles.RemoveRange(points.Count, Handles.Count - points.Count);
+                RecreateHandles(points);
             }
             else
             {
@@ -93,6 +93,28 @@ public class VectorPathOverlay : Overlay
         }
     }
 
+    private void RecreateHandles(IReadOnlyList<VecF> points)
+    {
+        for (int i = Handles.Count - 1; i >= 0; i--)
+        {
+            Handles[i].OnPress -= OnHandlePress;
+            Handles[i].OnDrag -= OnHandleDrag;
+            Handles[i].OnRelease -= OnHandleRelease;
+            Handles[i].OnTap -= OnHandleTap;
+            Handles.RemoveAt(i);
+        }
+
+        for (int i = 0; i < points.Count; i++)
+        {
+            var handle = new AnchorHandle(this);
+            handle.OnPress += OnHandlePress;
+            handle.OnDrag += OnHandleDrag;
+            handle.OnRelease += OnHandleRelease;
+            handle.OnTap += OnHandleTap;
+            AddHandle(handle);
+        }
+    }
+
     private void OnHandleTap(Handle handle, OverlayPointerArgs args)
     {
         if (Path.IsClosed)