Browse Source

Added deleting

flabbet 8 months ago
parent
commit
ad5dd2ff86

+ 1 - 0
src/PixiEditor.Extensions/UI/Overlays/IOverlay.cs

@@ -4,6 +4,7 @@ using Drawie.Numerics;
 namespace PixiEditor.Extensions.UI.Overlays;
 namespace PixiEditor.Extensions.UI.Overlays;
 
 
 public delegate void PointerEvent(OverlayPointerArgs args);
 public delegate void PointerEvent(OverlayPointerArgs args);
+public delegate void KeyEvent(Key key, KeyModifiers modifiers);
 public interface IOverlay
 public interface IOverlay
 {
 {
     public void EnterPointer(OverlayPointerArgs args);
     public void EnterPointer(OverlayPointerArgs args);

+ 1 - 1
src/PixiEditor/Views/Main/ViewportControls/Viewport.axaml

@@ -169,7 +169,7 @@
                                SwitchToolSetCommand="{xaml:Command Name=PixiEditor.Tools.SwitchToolSet, UseProvided=True}" />
                                SwitchToolSetCommand="{xaml:Command Name=PixiEditor.Tools.SwitchToolSet, UseProvided=True}" />
         </Grid>
         </Grid>
         <rendering:Scene
         <rendering:Scene
-            Focusable="False" Name="scene"
+            Focusable="True" Name="scene"
             ZIndex="1"
             ZIndex="1"
             SceneRenderer="{Binding Source={viewModels:MainVM DocumentManagerSVM}, Path=ActiveDocument.SceneRenderer}"
             SceneRenderer="{Binding Source={viewModels:MainVM DocumentManagerSVM}, Path=ActiveDocument.SceneRenderer}"
             Document="{Binding Document, ElementName=vpUc, Mode=OneWay}"
             Document="{Binding Document, ElementName=vpUc, Mode=OneWay}"

+ 22 - 0
src/PixiEditor/Views/Overlays/Overlay.cs

@@ -50,6 +50,8 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
     public event PointerEvent? PointerMovedOverlay;
     public event PointerEvent? PointerMovedOverlay;
     public event PointerEvent? PointerPressedOverlay;
     public event PointerEvent? PointerPressedOverlay;
     public event PointerEvent? PointerReleasedOverlay;
     public event PointerEvent? PointerReleasedOverlay;
+    public event KeyEvent? KeyPressedOverlay;
+    public event KeyEvent? KeyReleasedOverlay;
 
 
     public Handle? CapturedHandle { get; set; } = null!;
     public Handle? CapturedHandle { get; set; } = null!;
 
 
@@ -141,6 +143,18 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
 
 
         PointerReleasedOverlay?.Invoke(args);
         PointerReleasedOverlay?.Invoke(args);
     }
     }
+    
+    public void KeyPressed(KeyEventArgs args)
+    {
+        OnKeyPressed(args.Key, args.KeyModifiers);
+        KeyPressedOverlay?.Invoke(args.Key, args.KeyModifiers);
+    }
+
+    public void KeyReleased(KeyEventArgs keyEventArgs)
+    {
+        OnKeyReleased(keyEventArgs.Key, keyEventArgs.KeyModifiers);
+        KeyReleasedOverlay?.Invoke(keyEventArgs.Key, keyEventArgs.KeyModifiers);
+    }
 
 
     public virtual bool TestHit(VecD point)
     public virtual bool TestHit(VecD point)
     {
     {
@@ -261,6 +275,14 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
     protected virtual void OnOverlayPointerReleased(OverlayPointerArgs args)
     protected virtual void OnOverlayPointerReleased(OverlayPointerArgs args)
     {
     {
     }
     }
+    
+    protected virtual void OnKeyPressed(Key key, KeyModifiers keyModifiers)
+    {
+    }
+    
+    protected virtual void OnKeyReleased(Key key, KeyModifiers keyModifiers)
+    {
+    }
 
 
     protected virtual void OnOverlayPointerPressed(OverlayPointerArgs args)
     protected virtual void OnOverlayPointerPressed(OverlayPointerArgs args)
     {
     {

+ 8 - 0
src/PixiEditor/Views/Overlays/PathOverlay/EditableVectorPath.cs

@@ -302,4 +302,12 @@ public class EditableVectorPath
 
 
         targetSubShape?.InsertPointAt((VecF)point, verb);
         targetSubShape?.InsertPointAt((VecF)point, verb);
     }
     }
+
+    public void RemoveSubShape(SubShape subShapeContainingIndex)
+    {
+        if (subShapes.Contains(subShapeContainingIndex))
+        {
+            subShapes.Remove(subShapeContainingIndex);
+        }
+    }
 }
 }

+ 42 - 3
src/PixiEditor/Views/Overlays/PathOverlay/SubShape.cs

@@ -38,6 +38,45 @@ public class SubShape
         IsClosed = isClosed;
         IsClosed = isClosed;
     }
     }
 
 
+    public void RemovePoint(int i)
+    {
+        bool isFirst = i == 0;
+        bool isLast = i == points.Count - 1;
+
+        if (!isFirst)
+        {
+            var previousPoint = GetPreviousPoint(i);
+            var nextPoint = GetNextPoint(i);
+
+            if (previousPoint?.Verb != null && nextPoint?.Verb != null)
+            {
+                previousPoint.Verb.To = nextPoint.Position;
+            }
+            
+            for (int j = i + 1; j < points.Count; j++)
+            {
+                points[j].Index--;
+            }
+        }
+
+        if (isLast)
+        {
+            points[^2].Verb = new Verb();
+        }
+
+        if (isFirst && points.Count > 2)
+        {
+            points[^1].Verb.To = points[1].Position;
+        }
+
+        points.RemoveAt(i);
+        
+        if(points.Count < 3)
+        {
+            IsClosed = false;
+        }
+    }
+
     public void SetPointPosition(int i, VecF newPos, bool updateControlPoints)
     public void SetPointPosition(int i, VecF newPos, bool updateControlPoints)
     {
     {
         var shapePoint = points[i];
         var shapePoint = points[i];
@@ -69,7 +108,7 @@ public class SubShape
             }
             }
         }
         }
     }
     }
-    
+
     public void AppendPoint(VecF point)
     public void AppendPoint(VecF point)
     {
     {
         if (points.Count == 0)
         if (points.Count == 0)
@@ -98,7 +137,7 @@ public class SubShape
         }
         }
 
 
         Verb onVerb = pointVerb;
         Verb onVerb = pointVerb;
-        
+
         if (onVerb.VerbType is PathVerb.Quad or PathVerb.Conic)
         if (onVerb.VerbType is PathVerb.Quad or PathVerb.Conic)
         {
         {
             this.points[indexOfVerb].ConvertVerbToCubic();
             this.points[indexOfVerb].ConvertVerbToCubic();
@@ -187,7 +226,7 @@ public class SubShape
         }
         }
 
 
         IsClosed = true;
         IsClosed = true;
-        
+
         if (points.Count > 1)
         if (points.Count > 1)
         {
         {
             VecF[] data = new VecF[4];
             VecF[] data = new VecF[4];

+ 46 - 19
src/PixiEditor/Views/Overlays/PathOverlay/VectorPathOverlay.cs

@@ -139,7 +139,7 @@ public class VectorPathOverlay : Overlay
                 {
                 {
                     break;
                     break;
                 }
                 }
-                
+
                 var handle = anchorHandles[anchorIndex];
                 var handle = anchorHandles[anchorIndex];
 
 
                 if (point.Verb.ControlPoint1 != null || point.Verb.ControlPoint2 != null)
                 if (point.Verb.ControlPoint1 != null || point.Verb.ControlPoint2 != null)
@@ -357,6 +357,39 @@ public class VectorPathOverlay : Overlay
         args.Handled = true;
         args.Handled = true;
     }
     }
 
 
+    protected override void OnKeyPressed(Key key, KeyModifiers keyModifiers)
+    {
+        if (key == Key.Delete)
+        {
+            DeleteSelectedPoints();
+        }
+    }
+
+    private void DeleteSelectedPoints()
+    {
+        var selectedHandle = anchorHandles.FirstOrDefault(h => h.IsSelected);
+        if (selectedHandle == null)
+        {
+            return;
+        }
+
+        int index = anchorHandles.IndexOf(selectedHandle);
+        SubShape subShapeContainingIndex = editableVectorPath.GetSubShapeContainingIndex(index);
+        int localIndex = editableVectorPath.GetSubShapePointIndex(index, subShapeContainingIndex);
+
+        if (subShapeContainingIndex.Points.Count == 1)
+        {
+            editableVectorPath.RemoveSubShape(subShapeContainingIndex);
+        }
+        else
+        {
+            subShapeContainingIndex.RemovePoint(localIndex);
+        }
+
+        AddToUndoCommand.Execute(Path);
+        Path = editableVectorPath.ToVectorPath();
+    }
+
     private void CreateHandle(int atIndex, bool isControlPoint = false)
     private void CreateHandle(int atIndex, bool isControlPoint = false)
     {
     {
         if (!isControlPoint)
         if (!isControlPoint)
@@ -408,8 +441,8 @@ public class VectorPathOverlay : Overlay
 
 
         SubShape ssOfSelected = editableVectorPath.GetSubShapeContainingIndex(anchorHandles.IndexOf(selectedHandle));
         SubShape ssOfSelected = editableVectorPath.GetSubShapeContainingIndex(anchorHandles.IndexOf(selectedHandle));
         SubShape ssOfTapped = editableVectorPath.GetSubShapeContainingIndex(anchorHandles.IndexOf(anchorHandle));
         SubShape ssOfTapped = editableVectorPath.GetSubShapeContainingIndex(anchorHandles.IndexOf(anchorHandle));
-        
-        if(ssOfTapped == null || ssOfSelected == null)
+
+        if (ssOfTapped == null || ssOfSelected == null)
         {
         {
             return;
             return;
         }
         }
@@ -421,7 +454,7 @@ public class VectorPathOverlay : Overlay
         {
         {
             return;
             return;
         }
         }
-        
+
         if (ssOfSelected == ssOfTapped && !ssOfTapped.IsClosed &&
         if (ssOfSelected == ssOfTapped && !ssOfTapped.IsClosed &&
             (localIndexOfTapped == 0 || localIndexOfTapped == ssOfTapped.Points.Count - 1))
             (localIndexOfTapped == 0 || localIndexOfTapped == ssOfTapped.Points.Count - 1))
         {
         {
@@ -446,11 +479,11 @@ public class VectorPathOverlay : Overlay
 
 
     protected override void OnOverlayPointerPressed(OverlayPointerArgs args)
     protected override void OnOverlayPointerPressed(OverlayPointerArgs args)
     {
     {
-        if(args.PointerButton != MouseButton.Left)
+        if (args.PointerButton != MouseButton.Left)
         {
         {
             return;
             return;
         }
         }
-        
+
         if (args.Modifiers.HasFlag(KeyModifiers.Shift) && IsOverPath(args.Point, out VecD closestPoint))
         if (args.Modifiers.HasFlag(KeyModifiers.Shift) && IsOverPath(args.Point, out VecD closestPoint))
         {
         {
             AddPointAt(closestPoint);
             AddPointAt(closestPoint);
@@ -460,6 +493,8 @@ public class VectorPathOverlay : Overlay
         else if (args.Modifiers == KeyModifiers.None)
         else if (args.Modifiers == KeyModifiers.None)
         {
         {
             AddNewPointFromClick(args.Point);
             AddNewPointFromClick(args.Point);
+            AddToUndoCommand.Execute(Path);
+            args.Handled = true;
         }
         }
     }
     }
 
 
@@ -522,19 +557,6 @@ public class VectorPathOverlay : Overlay
             SelectAnchor(anchorHandle);
             SelectAnchor(anchorHandle);
             CaptureHandle(source);
             CaptureHandle(source);
             args.Handled = true;
             args.Handled = true;
-            
-            if (!args.Modifiers.HasFlag(KeyModifiers.Control)) return;
-
-            var newPath = ConvertTouchingVerbsToCubic(anchorHandle);
-
-            int index = anchorHandles.IndexOf(anchorHandle);
-            SubShape subShapeContainingIndex = editableVectorPath.GetSubShapeContainingIndex(index);
-            int localIndex = editableVectorPath.GetSubShapePointIndex(index, subShapeContainingIndex);
-
-            HandleContinousCubicDrag(anchorHandle.Position, anchorHandle, subShapeContainingIndex, localIndex, true);
-
-            Path = newPath.ToVectorPath();
-
         }
         }
     }
     }
 
 
@@ -581,6 +603,11 @@ public class VectorPathOverlay : Overlay
 
 
         if (isDraggingControlPoints)
         if (isDraggingControlPoints)
         {
         {
+            var newPath = ConvertTouchingVerbsToCubic(handle);
+            
+            subShapeContainingIndex = newPath.GetSubShapeContainingIndex(index);
+            localIndex = newPath.GetSubShapePointIndex(index, subShapeContainingIndex);
+            
             HandleContinousCubicDrag(targetPos, handle, subShapeContainingIndex, localIndex, true);
             HandleContinousCubicDrag(targetPos, handle, subShapeContainingIndex, localIndex, true);
         }
         }
         else
         else

+ 26 - 0
src/PixiEditor/Views/Rendering/Scene.cs

@@ -445,6 +445,32 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
         }
         }
     }
     }
 
 
+    protected override void OnKeyDown(KeyEventArgs e)
+    {
+        base.OnKeyDown(e);
+        if (AllOverlays != null)
+        {
+            foreach (Overlay overlay in AllOverlays)
+            {
+                if (!overlay.IsVisible) continue;
+                overlay.KeyPressed(e);
+            }
+        }
+    }
+    
+    protected override void OnKeyUp(KeyEventArgs e)
+    {
+        base.OnKeyUp(e);
+        if (AllOverlays != null)
+        {
+            foreach (Overlay overlay in AllOverlays)
+            {
+                if (!overlay.IsVisible) continue;
+                overlay.KeyReleased(e);
+            }
+        }
+    }
+
     private OverlayPointerArgs ConstructPointerArgs(PointerEventArgs e)
     private OverlayPointerArgs ConstructPointerArgs(PointerEventArgs e)
     {
     {
         return new OverlayPointerArgs
         return new OverlayPointerArgs