瀏覽代碼

Create new vector layer on shift

Krzysztof Krysiński 4 月之前
父節點
當前提交
72c9861690

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

@@ -783,7 +783,7 @@
   "PATH_TOOL_TOOLTIP": "Create vector paths and curves ({0}).",
   "PATH_TOOL_ACTION_DISPLAY": "Click to add a point.",
   "PATH_TOOL_ACTION_DISPLAY_CTRL": "Click on existing point and drag to make it a curve. Tap on a control point to select it.",
-  "PATH_TOOL_ACTION_DISPLAY_SHIFT": "Click on a path to insert a point.",
+  "PATH_TOOL_ACTION_DISPLAY_SHIFT": "Click to create a new layer.",
   "PATH_TOOL_ACTION_DISPLAY_CTRL_SHIFT": "Tap on a control point to add it to the selection.",
   "PATH_TOOL_ACTION_DISPLAY_ALT": "Click on a control point and move to adjust only one side of the curve.",
   "DEFAULT_PATH_LAYER_NAME": "Path",

+ 7 - 21
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/VectorPathToolExecutor.cs

@@ -137,18 +137,14 @@ internal class VectorPathToolExecutor : UpdateableChangeExecutor, IPathExecutorF
 
     public override void OnLeftMouseButtonDown(MouseOnCanvasEventArgs args)
     {
-        bool allClosed = WholePathClosed();
-        if (!isValidPathLayer || allClosed)
+        if (args.KeyModifiers.HasFlag(KeyModifiers.Shift))
         {
-            if (NeedsNewLayer(document.SelectedStructureMember, document.AnimationHandler.ActiveFrameTime))
-            {
-                Guid? created =
-                    document.Operations.CreateStructureMember(typeof(VectorLayerNode), ActionSource.Automated);
+            Guid? created =
+                document.Operations.CreateStructureMember(typeof(VectorLayerNode), ActionSource.Automated);
 
-                if (created is null) return;
+            if (created is null) return;
 
-                document.Operations.SetSelectedMember(created.Value);
-            }
+            document.Operations.SetSelectedMember(created.Value);
         }
     }
 
@@ -205,7 +201,8 @@ internal class VectorPathToolExecutor : UpdateableChangeExecutor, IPathExecutorF
     private void AddToUndo(VectorPath path)
     {
         internals.ActionAccumulator.AddFinishedActions(new EndSetShapeGeometry_Action(),
-            new SetShapeGeometry_Action(member.Id, ConstructShapeData(path), VectorShapeChangeType.GeometryData), new EndSetShapeGeometry_Action());
+            new SetShapeGeometry_Action(member.Id, ConstructShapeData(path), VectorShapeChangeType.GeometryData),
+            new EndSetShapeGeometry_Action());
     }
 
     private PathVectorData ConstructShapeData(VectorPath? path)
@@ -259,17 +256,6 @@ internal class VectorPathToolExecutor : UpdateableChangeExecutor, IPathExecutorF
         document.SnappingHandler.SnappingController.HighlightedPoint = null;
     }
 
-    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;
-    }
-
     private void ApplySettings(PathVectorData pathData)
     {
         toolbar.ToolSize = pathData.StrokeWidth;

+ 19 - 3
src/PixiEditor/Views/Overlays/PathOverlay/EditableVectorPath.cs

@@ -65,7 +65,7 @@ public class EditableVectorPath
         {
             newPath = new VectorPath();
         }
-        
+
         newPath.FillType = FillType;
 
         foreach (var subShape in subShapes)
@@ -307,7 +307,7 @@ public class EditableVectorPath
         return closest;
     }
 
-    public void AddPointAt(VecD point)
+    public int? AddPointAt(VecD point)
     {
         SubShape targetSubShape = null;
         Verb verb = null;
@@ -321,9 +321,25 @@ public class EditableVectorPath
             }
         }
 
-        targetSubShape?.InsertPointAt((VecF)point, verb);
+        if (targetSubShape != null)
+        {
+            int localIndex = targetSubShape.InsertPointAt((VecF)point, verb);
+            int globalIndex = GetGlobalIndex(targetSubShape, localIndex);
+            return globalIndex;
+        }
+
+        return null;
     }
 
+    /*
+    public void NewSubShape(VecD point)
+    {
+        VecF pointF = (VecF)point;
+        ShapePoint newPoint = new ShapePoint(pointF, 0, new Verb(PathVerb.Move, pointF, pointF, null, null, 0));
+        var newSubShape = new SubShape(new List<ShapePoint>() { newPoint }, false);
+        subShapes.Add(newSubShape);
+    }*/
+
     public void RemoveSubShape(SubShape subShapeContainingIndex)
     {
         if (subShapes.Contains(subShapeContainingIndex))

+ 6 - 4
src/PixiEditor/Views/Overlays/PathOverlay/SubShape.cs

@@ -52,7 +52,7 @@ public class SubShape
             {
                 previousPoint.Verb.To = nextPoint.Position;
             }
-            
+
             for (int j = i + 1; j < points.Count; j++)
             {
                 points[j].Index--;
@@ -70,8 +70,8 @@ public class SubShape
         }
 
         points.RemoveAt(i);
-        
-        if(points.Count < 3)
+
+        if (points.Count < 3)
         {
             IsClosed = false;
         }
@@ -128,7 +128,7 @@ public class SubShape
         }
     }
 
-    public void InsertPointAt(VecF point, Verb pointVerb)
+    public int InsertPointAt(VecF point, Verb pointVerb)
     {
         int indexOfVerb = this.points.FirstOrDefault(x => x.Verb == pointVerb)?.Index ?? -1;
         if (indexOfVerb == -1)
@@ -187,6 +187,8 @@ public class SubShape
         {
             this.points[i].Index++;
         }
+
+        return indexOfVerb + 1;
     }
 
     public VecD? GetClosestPointOnPath(VecD point, float maxDistanceInPixels)

+ 12 - 4
src/PixiEditor/Views/Overlays/PathOverlay/VectorPathOverlay.cs

@@ -515,7 +515,7 @@ public class VectorPathOverlay : Overlay
             return;
         }
 
-        if (args.Modifiers == KeyModifiers.Shift && IsOverPath(args.Point, out VecD closestPoint))
+        if (IsOverPath(args.Point, out VecD closestPoint))
         {
             AddPointAt(closestPoint);
             AddToUndoCommand.Execute(Path);
@@ -530,7 +530,7 @@ public class VectorPathOverlay : Overlay
 
     protected override void OnOverlayPointerMoved(OverlayPointerArgs args)
     {
-        if (args.Modifiers == KeyModifiers.Shift && IsOverPath(args.Point, out VecD closestPoint))
+        if (IsOverPath(args.Point, out VecD closestPoint))
         {
             insertPreviewHandle.Position = closestPoint;
             canInsert = true;
@@ -554,7 +554,13 @@ public class VectorPathOverlay : Overlay
 
         if (subShape.IsClosed)
         {
-            return false;
+            var path = editableVectorPath.ToVectorPath();
+            VectorPath newShape = new VectorPath();
+            newShape.MoveTo((VecF)point);
+            path.AddPath(newShape, AddPathMode.Append);
+            Path = path;
+            SelectAnchor(anchorHandles.Last());
+            return true;
         }
 
         if (Path.IsEmpty)
@@ -575,8 +581,9 @@ public class VectorPathOverlay : Overlay
 
     private void AddPointAt(VecD point)
     {
-        editableVectorPath.AddPointAt(point);
+        int? insertedAt = editableVectorPath.AddPointAt(point);
         Path = editableVectorPath.ToVectorPath();
+        SelectAnchor(insertedAt is > 0 && insertedAt.Value < anchorHandles.Count ? anchorHandles[insertedAt.Value] : anchorHandles.Last());
     }
 
     private bool IsOverPath(VecD point, out VecD closestPoint)
@@ -593,6 +600,7 @@ public class VectorPathOverlay : Overlay
         {
             SnappingController.RemoveAll($"editingPath[{anchorHandles.IndexOf(anchorHandle)}]");
             CaptureHandle(source);
+            canInsert = false;
             args.Handled = true;
         }
     }