Browse Source

Minor refactoring and bugfixing

Equbuxu 3 years ago
parent
commit
9283ad2273
18 changed files with 59 additions and 135 deletions
  1. 6 1
      src/ChunkyImageLib/Operations/EllipseHelper.cs
  2. 1 1
      src/ChunkyImageLib/Operations/RectangleOperation.cs
  3. 0 49
      src/PixiEditor.ChangeableDocument/Changes/Drawing/BasicPen_UpdateableChange.cs
  4. 2 7
      src/PixiEditor.ChangeableDocument/Changes/Drawing/ClearSelectedArea_Change.cs
  5. 4 4
      src/PixiEditor.ChangeableDocument/Changes/Drawing/ClearSelection_Change.cs
  6. 2 9
      src/PixiEditor.ChangeableDocument/Changes/Drawing/CombineStructureMembersOnto_Change.cs
  7. 2 7
      src/PixiEditor.ChangeableDocument/Changes/Drawing/DrawEllipse_UpdateableChange.cs
  8. 2 8
      src/PixiEditor.ChangeableDocument/Changes/Drawing/DrawRectangle_UpdateableChange.cs
  9. 18 0
      src/PixiEditor.ChangeableDocument/Changes/Drawing/DrawingChangeHelper.cs
  10. 1 8
      src/PixiEditor.ChangeableDocument/Changes/Drawing/FloodFill/FloodFill_Change.cs
  11. 6 8
      src/PixiEditor.ChangeableDocument/Changes/Drawing/LineBasedPen_UpdateableChange.cs
  12. 6 11
      src/PixiEditor.ChangeableDocument/Changes/Drawing/PasteImage_UpdateableChange.cs
  13. 1 8
      src/PixiEditor.ChangeableDocument/Changes/Drawing/PathBasedPen_UpdateableChange.cs
  14. 1 7
      src/PixiEditor.ChangeableDocument/Changes/Drawing/ShiftLayer_UpdateableChange.cs
  15. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Root/SymmetryAxisPosition_UpdateableChange.cs
  16. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Root/SymmetryAxisState_Change.cs
  17. 2 2
      src/PixiEditor.ChangeableDocument/Changes/Selection/SelectRectangle_UpdateableChange.cs
  18. 3 3
      src/PixiEditorPrototype/ViewModels/DocumentViewModel.cs

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

@@ -21,7 +21,12 @@ public class EllipseHelper
         for (var i = 0; i < ellipse.Count; i++)
         {
             var point = ellipse[i];
-            if (!added[point.Y - ellipseBounds.Top] && i > 0 && ellipse[i - 1].Y == point.Y && point.X - ellipse[i - 1].X > 1)
+            if (!added[point.Y - ellipseBounds.Top] &&
+                i > 0 &&
+                ellipse[i - 1].Y == point.Y &&
+                point.X - ellipse[i - 1].X > 1 &&
+                point.Y > ellipseBounds.Top &&
+                point.Y < ellipseBounds.Bottom - 1)
             {
                 int fromX = ellipse[i - 1].X + 1;
                 int toX = point.X;

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

@@ -20,7 +20,7 @@ internal class RectangleOperation : IDrawOperation
 
         var surf = chunk.Surface.SkiaSurface;
 
-        var rect = RectD.FromCenterAndSize(Data.Center, Data.Size);
+        var rect = RectD.FromCenterAndSize(Data.Center, Data.Size.Abs());
         var innerRect = rect.Inflate(-Data.StrokeWidth);
         if (innerRect.IsZeroOrNegativeArea)
             innerRect = RectD.Empty;

+ 0 - 49
src/PixiEditor.ChangeableDocument/Changes/Drawing/BasicPen_UpdateableChange.cs

@@ -1,49 +0,0 @@
-using SkiaSharp;
-
-namespace PixiEditor.ChangeableDocument.Changes.Drawing;
-internal class BasicPen_UpdateableChange : UpdateableChange
-{
-    private readonly Guid memberGuid;
-    private readonly int strokeWidth;
-    private readonly SKColor color;
-    private readonly bool drawOnMask;
-    private readonly List<VecI> points = new();
-
-    [GenerateUpdateableChangeActions]
-    public BasicPen_UpdateableChange(Guid memberGuid, int strokeWidth, SKColor color, VecI point, bool drawOnMask)
-    {
-        this.memberGuid = memberGuid;
-        this.strokeWidth = strokeWidth;
-        this.color = color;
-        this.drawOnMask = drawOnMask;
-        points.Add(point);
-    }
-
-    [UpdateChangeMethod]
-    public void Update(VecI point)
-    {
-        points.Add(point);
-    }
-
-    public override OneOf<Success, Error> InitializeAndValidate(Document target)
-    {
-        if (!DrawingChangeHelper.IsValidForDrawing(target, memberGuid, drawOnMask))
-            return new Error();
-        return new Success();
-    }
-
-    public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, out bool ignoreInUndo)
-    {
-        throw new NotImplementedException();
-    }
-
-    public override OneOf<None, IChangeInfo, List<IChangeInfo>> ApplyTemporarily(Document target)
-    {
-        throw new NotImplementedException();
-    }
-
-    public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
-    {
-        throw new NotImplementedException();
-    }
-}

+ 2 - 7
src/PixiEditor.ChangeableDocument/Changes/Drawing/ClearSelectedArea_Change.cs

@@ -44,13 +44,8 @@ internal class ClearSelectedArea_Change : Change
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     {
-        var image = DrawingChangeHelper.GetTargetImageOrThrow(target, memberGuid, drawOnMask);
-        savedChunks!.ApplyChunksToImage(image);
-        var affChunks = image.FindAffectedChunks();
-        image.CommitChanges();
-        savedChunks.Dispose();
-        savedChunks = null;
-        return DrawingChangeHelper.CreateChunkChangeInfo(memberGuid, affChunks, drawOnMask);
+        var affectedChunks = DrawingChangeHelper.ApplyStoredChunksDisposeAndSetToNull(target, memberGuid, drawOnMask, ref savedChunks);
+        return DrawingChangeHelper.CreateChunkChangeInfo(memberGuid, affectedChunks, drawOnMask);
     }
 
     public override void Dispose()

+ 4 - 4
src/PixiEditor.ChangeableDocument/Changes/Drawing/ClearSelection_Change.cs

@@ -19,8 +19,8 @@ internal class ClearSelection_Change : Change
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, out bool ignoreInUndo)
     {
-        target.Selection.SelectionPath.Dispose();
-        target.Selection.SelectionPath = new SKPath();
+        (var toDispose, target.Selection.SelectionPath) = (target.Selection.SelectionPath, new SKPath());
+        toDispose.Dispose();
 
         ignoreInUndo = false;
         return new Selection_ChangeInfo(new SKPath());
@@ -28,8 +28,8 @@ internal class ClearSelection_Change : Change
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     {
-        target.Selection.SelectionPath.Dispose();
-        target.Selection.SelectionPath = new SKPath(originalPath);
+        (var toDispose, target.Selection.SelectionPath) = (target.Selection.SelectionPath, new SKPath(originalPath));
+        toDispose.Dispose();
 
         return new Selection_ChangeInfo(new SKPath(originalPath));
     }

+ 2 - 9
src/PixiEditor.ChangeableDocument/Changes/Drawing/CombineStructureMembersOnto_Change.cs

@@ -64,7 +64,7 @@ internal class CombineStructureMembersOnto_Change : Change
             if (combined.IsT0)
             {
                 toDrawOn.LayerImage.EnqueueDrawImage(chunk * ChunkyImage.FullChunkSize, combined.AsT0.Surface);
-                combined.AsT0.Surface.Dispose();
+                combined.AsT0.Dispose();
             }
         }
         var affectedChunks = toDrawOn.LayerImage.FindAffectedChunks();
@@ -78,14 +78,7 @@ internal class CombineStructureMembersOnto_Change : Change
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     {
         Layer toDrawOn = (Layer)target.FindMemberOrThrow(targetLayer);
-
-        originalChunks!.ApplyChunksToImage(toDrawOn.LayerImage);
-        var affectedChunks = toDrawOn.LayerImage.FindAffectedChunks();
-        toDrawOn.LayerImage.CommitChanges();
-
-        originalChunks.Dispose();
-        originalChunks = null;
-
+        var affectedChunks = DrawingChangeHelper.ApplyStoredChunksDisposeAndSetToNull(toDrawOn.LayerImage, ref originalChunks);
         return new LayerImageChunks_ChangeInfo(targetLayer, affectedChunks);
     }
 

+ 2 - 7
src/PixiEditor.ChangeableDocument/Changes/Drawing/DrawEllipse_UpdateableChange.cs

@@ -69,13 +69,8 @@ internal class DrawEllipse_UpdateableChange : UpdateableChange
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     {
-        ChunkyImage targetImage = DrawingChangeHelper.GetTargetImageOrThrow(target, memberGuid, drawOnMask);
-        storedChunks!.ApplyChunksToImage(targetImage);
-        storedChunks.Dispose();
-        storedChunks = null;
-
-        var changes = DrawingChangeHelper.CreateChunkChangeInfo(memberGuid, targetImage.FindAffectedChunks(), drawOnMask);
-        targetImage.CommitChanges();
+        var affectedChunks = DrawingChangeHelper.ApplyStoredChunksDisposeAndSetToNull(target, memberGuid, drawOnMask, ref storedChunks);
+        var changes = DrawingChangeHelper.CreateChunkChangeInfo(memberGuid, affectedChunks, drawOnMask);
         return changes;
     }
 

+ 2 - 8
src/PixiEditor.ChangeableDocument/Changes/Drawing/DrawRectangle_UpdateableChange.cs

@@ -62,14 +62,8 @@ internal class DrawRectangle_UpdateableChange : UpdateableChange
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     {
-        ChunkyImage targetImage = DrawingChangeHelper.GetTargetImageOrThrow(target, memberGuid, drawOnMask);
-        storedChunks!.ApplyChunksToImage(targetImage);
-        storedChunks.Dispose();
-        storedChunks = null;
-
-        var changes = DrawingChangeHelper.CreateChunkChangeInfo(memberGuid, targetImage.FindAffectedChunks(), drawOnMask);
-        targetImage.CommitChanges();
-        return changes;
+        var affectedChunks = DrawingChangeHelper.ApplyStoredChunksDisposeAndSetToNull(target, memberGuid, drawOnMask, ref storedChunks);
+        return DrawingChangeHelper.CreateChunkChangeInfo(memberGuid, affectedChunks, drawOnMask);
     }
 
     public override void Dispose()

+ 18 - 0
src/PixiEditor.ChangeableDocument/Changes/Drawing/DrawingChangeHelper.cs

@@ -1,6 +1,24 @@
 namespace PixiEditor.ChangeableDocument.Changes.Drawing;
 internal static class DrawingChangeHelper
 {
+    public static HashSet<VecI> ApplyStoredChunksDisposeAndSetToNull(Document target, Guid memberGuid, bool drawOnMask, ref CommittedChunkStorage? storage)
+    {
+        var image = GetTargetImageOrThrow(target, memberGuid, drawOnMask);
+        return ApplyStoredChunksDisposeAndSetToNull(image, ref storage);
+    }
+
+    public static HashSet<VecI> ApplyStoredChunksDisposeAndSetToNull(ChunkyImage image, ref CommittedChunkStorage? storage)
+    {
+        if (storage is null)
+            throw new InvalidOperationException("No stored chunks to apply");
+        storage.ApplyChunksToImage(image);
+        var chunks = image.FindAffectedChunks();
+        image.CommitChanges();
+        storage.Dispose();
+        storage = null;
+        return chunks;
+    }
+
     public static ChunkyImage GetTargetImageOrThrow(Document target, Guid memberGuid, bool drawOnMask)
     {
         var member = target.FindMemberOrThrow(memberGuid);

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

@@ -41,14 +41,7 @@ internal class FloodFill_Change : Change
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     {
-        if (chunkStorage is null)
-            throw new InvalidOperationException("No saved chunks to revert to");
-        var image = DrawingChangeHelper.GetTargetImageOrThrow(target, memberGuid, drawOnMask);
-        chunkStorage.ApplyChunksToImage(image);
-        var affectedChunks = image.FindAffectedChunks();
-        image.CommitChanges();
-        chunkStorage.Dispose();
-        chunkStorage = null;
+        var affectedChunks = DrawingChangeHelper.ApplyStoredChunksDisposeAndSetToNull(target, memberGuid, drawOnMask, ref chunkStorage);
         return DrawingChangeHelper.CreateChunkChangeInfo(memberGuid, affectedChunks, drawOnMask);
     }
 

+ 6 - 8
src/PixiEditor.ChangeableDocument/Changes/Drawing/LineBasedPen_UpdateableChange.cs

@@ -108,14 +108,12 @@ internal class LineBasedPen_UpdateableChange : UpdateableChange
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     {
-        if (storedChunks is null)
-            throw new InvalidOperationException("No saved chunks to revert to");
-        var image = DrawingChangeHelper.GetTargetImageOrThrow(target, memberGuid, drawOnMask);
-        storedChunks.ApplyChunksToImage(image);
-        var affected = image.FindAffectedChunks();
-        image.CommitChanges();
-        storedChunks.Dispose();
-        storedChunks = null;
+        var affected = DrawingChangeHelper.ApplyStoredChunksDisposeAndSetToNull(target, memberGuid, drawOnMask, ref storedChunks);
         return DrawingChangeHelper.CreateChunkChangeInfo(memberGuid, affected, drawOnMask);
     }
+
+    public override void Dispose()
+    {
+        storedChunks?.Dispose();
+    }
 }

+ 6 - 11
src/PixiEditor.ChangeableDocument/Changes/Drawing/PasteImage_UpdateableChange.cs

@@ -5,6 +5,7 @@ internal class PasteImage_UpdateableChange : UpdateableChange
 {
     private ShapeCorners corners;
     private readonly Guid memberGuid;
+    private readonly bool ignoreClipsSymmetriesEtc;
     private readonly bool drawOnMask;
     private readonly Surface imageToPaste;
     private CommittedChunkStorage? savedChunks;
@@ -13,10 +14,11 @@ internal class PasteImage_UpdateableChange : UpdateableChange
     private bool hasEnqueudImage = false;
 
     [GenerateUpdateableChangeActions]
-    public PasteImage_UpdateableChange(Surface image, ShapeCorners corners, Guid memberGuid, bool isDrawingOnMask)
+    public PasteImage_UpdateableChange(Surface image, ShapeCorners corners, Guid memberGuid, bool ignoreClipsSymmetriesEtc, bool isDrawingOnMask)
     {
         this.corners = corners;
         this.memberGuid = memberGuid;
+        this.ignoreClipsSymmetriesEtc = ignoreClipsSymmetriesEtc;
         this.drawOnMask = isDrawingOnMask;
         this.imageToPaste = new Surface(image);
     }
@@ -39,7 +41,8 @@ internal class PasteImage_UpdateableChange : UpdateableChange
         var prevChunks = targetImage.FindAffectedChunks();
 
         targetImage.CancelChanges();
-        DrawingChangeHelper.ApplyClipsSymmetriesEtc(target, targetImage, memberGuid, drawOnMask);
+        if (!ignoreClipsSymmetriesEtc)
+            DrawingChangeHelper.ApplyClipsSymmetriesEtc(target, targetImage, memberGuid, drawOnMask);
         targetImage.EnqueueDrawImage(corners, imageToPaste, RegularPaint, false);
         hasEnqueudImage = true;
 
@@ -68,15 +71,7 @@ internal class PasteImage_UpdateableChange : UpdateableChange
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     {
-        if (savedChunks is null)
-            throw new InvalidOperationException("No saved chunks to restore");
-        ChunkyImage targetImage = DrawingChangeHelper.GetTargetImageOrThrow(target, memberGuid, drawOnMask);
-        savedChunks.ApplyChunksToImage(targetImage);
-        var chunks = targetImage.FindAffectedChunks();
-        targetImage.CommitChanges();
-        hasEnqueudImage = false;
-        savedChunks.Dispose();
-        savedChunks = null;
+        var chunks = DrawingChangeHelper.ApplyStoredChunksDisposeAndSetToNull(target, memberGuid, drawOnMask, ref savedChunks);
         return DrawingChangeHelper.CreateChunkChangeInfo(memberGuid, chunks, drawOnMask);
     }
 

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

@@ -145,14 +145,7 @@ internal class PathBasedPen_UpdateableChange : UpdateableChange
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     {
-        if (storedChunks is null)
-            throw new InvalidOperationException("No saved chunks to revert to");
-        var image = DrawingChangeHelper.GetTargetImageOrThrow(target, memberGuid, drawOnMask);
-        storedChunks.ApplyChunksToImage(image);
-        var affected = image.FindAffectedChunks();
-        image.CommitChanges();
-        storedChunks.Dispose();
-        storedChunks = null;
+        var affected = DrawingChangeHelper.ApplyStoredChunksDisposeAndSetToNull(target, memberGuid, drawOnMask, ref storedChunks);
         return DrawingChangeHelper.CreateChunkChangeInfo(memberGuid, affected, drawOnMask);
     }
 

+ 1 - 7
src/PixiEditor.ChangeableDocument/Changes/Drawing/ShiftLayer_UpdateableChange.cs

@@ -60,14 +60,8 @@ internal class ShiftLayer_UpdateableChange : UpdateableChange
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     {
-        if (originalLayerChunks is null)
-            throw new InvalidOperationException("No saved chunks to restore to");
         var image = ((Layer)target.FindMemberOrThrow(layerGuid)).LayerImage;
-        originalLayerChunks.ApplyChunksToImage(image);
-        var affected = image.FindAffectedChunks();
-        image.CommitChanges();
-        originalLayerChunks.Dispose();
-        originalLayerChunks = null;
+        var affected = DrawingChangeHelper.ApplyStoredChunksDisposeAndSetToNull(image, ref originalLayerChunks);
         return new LayerImageChunks_ChangeInfo(layerGuid, affected);
     }
 

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Root/SymmetryAxisPosition_UpdateableChange.cs

@@ -65,6 +65,6 @@ internal class SymmetryAxisPosition_UpdateableChange : UpdateableChange
 
     public override bool IsMergeableWith(Change other)
     {
-        return other is SymmetryAxisPosition_UpdateableChange;
+        return other is SymmetryAxisPosition_UpdateableChange change && change.direction == direction;
     }
 }

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Root/SymmetryAxisState_Change.cs

@@ -53,6 +53,6 @@ internal class SymmetryAxisState_Change : Change
 
     public override bool IsMergeableWith(Change other)
     {
-        return other is SymmetryAxisState_Change;
+        return other is SymmetryAxisState_Change change && change.direction == direction;
     }
 }

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

@@ -60,8 +60,8 @@ internal class SelectRectangle_UpdateableChange : UpdateableChange
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     {
-        target.Selection.SelectionPath.Dispose();
-        target.Selection.SelectionPath = new SKPath(originalPath);
+        (var toDispose, target.Selection.SelectionPath) = (target.Selection.SelectionPath, new SKPath(originalPath));
+        toDispose.Dispose();
         return new Selection_ChangeInfo(new SKPath(target.Selection.SelectionPath));
     }
 

+ 3 - 3
src/PixiEditorPrototype/ViewModels/DocumentViewModel.cs

@@ -256,7 +256,7 @@ internal class DocumentViewModel : INotifyPropertyChanged
         pastedImage = surface;
         pastingImage = true;
         ShapeCorners corners = new(intBounds);
-        Helpers.ActionAccumulator.AddActions(new PasteImage_Action(pastedImage, corners, layer.GuidValue, false));
+        Helpers.ActionAccumulator.AddActions(new PasteImage_Action(pastedImage, corners, layer.GuidValue, true, false));
         TransformViewModel.ShowFreeTransform(corners);
     }
 
@@ -503,7 +503,7 @@ internal class DocumentViewModel : INotifyPropertyChanged
         {
             if (SelectedStructureMember is null || pastedImage is null)
                 return;
-            Helpers.ActionAccumulator.AddActions(new PasteImage_Action(pastedImage, newCorners, SelectedStructureMember.GuidValue, false));
+            Helpers.ActionAccumulator.AddActions(new PasteImage_Action(pastedImage, newCorners, SelectedStructureMember.GuidValue, false, false));
         }
         else if (transformingSelectionPath)
         {
@@ -539,7 +539,7 @@ internal class DocumentViewModel : INotifyPropertyChanged
         pastedImage = Surface.Load(dialog.FileName);
         pastingImage = true;
         ShapeCorners corners = new ShapeCorners(new RectD(VecD.Zero, pastedImage.Size));
-        Helpers.ActionAccumulator.AddActions(new PasteImage_Action(pastedImage, corners, SelectedStructureMember.GuidValue, false));
+        Helpers.ActionAccumulator.AddActions(new PasteImage_Action(pastedImage, corners, SelectedStructureMember.GuidValue, false, false));
         TransformViewModel.ShowFreeTransform(corners);
     }