Equbuxu 3 years ago
parent
commit
228017c5a6
52 changed files with 399 additions and 457 deletions
  1. 2 2
      src/ChunkyImageLib/Chunk.cs
  2. 31 61
      src/ChunkyImageLib/ChunkyImage.cs
  3. 2 2
      src/ChunkyImageLib/CommittedChunkStorage.cs
  4. 11 11
      src/ChunkyImageLib/DataHolders/ShapeCorners.cs
  5. 3 3
      src/ChunkyImageLib/DataHolders/ShapeData.cs
  6. 54 54
      src/ChunkyImageLib/DataHolders/Vector2d.cs
  7. 34 34
      src/ChunkyImageLib/DataHolders/Vector2i.cs
  8. 5 5
      src/ChunkyImageLib/IReadOnlyChunkyImage.cs
  9. 9 9
      src/ChunkyImageLib/Operations/ClearRegionOperation.cs
  10. 2 2
      src/ChunkyImageLib/Operations/IDrawOperation.cs
  11. 7 7
      src/ChunkyImageLib/Operations/ImageOperation.cs
  12. 46 46
      src/ChunkyImageLib/Operations/OperationHelper.cs
  13. 3 3
      src/ChunkyImageLib/Operations/RectangleOperation.cs
  14. 2 2
      src/ChunkyImageLib/Operations/ResizeOperation.cs
  15. 3 3
      src/ChunkyImageLib/Surface.cs
  16. 2 2
      src/ChunkyImageLibTest/ClearRegionOperationTests.cs
  17. 2 2
      src/ChunkyImageLibTest/OperationHelperTests.cs
  18. 7 7
      src/ChunkyImageLibTest/RectangleOperationTests.cs
  19. 4 4
      src/ChunkyImageLibVis/MainWindow.xaml.cs
  20. 3 3
      src/PixiEditor.ChangeableDocument/Actions/Drawing/Selection/SelectRectangle_Action.cs
  21. 2 2
      src/PixiEditor.ChangeableDocument/Actions/Root/ResizeCanvas_Action.cs
  22. 1 1
      src/PixiEditor.ChangeableDocument/ChangeInfos/Drawing/LayerImageChunks_ChangeInfo.cs
  23. 1 1
      src/PixiEditor.ChangeableDocument/ChangeInfos/Drawing/MaskChunks_ChangeInfo.cs
  24. 1 1
      src/PixiEditor.ChangeableDocument/ChangeInfos/Drawing/Selection_ChangeInfo.cs
  25. 2 2
      src/PixiEditor.ChangeableDocument/Changeables/Document.cs
  26. 1 1
      src/PixiEditor.ChangeableDocument/Changeables/Interfaces/IReadOnlyDocument.cs
  27. 1 1
      src/PixiEditor.ChangeableDocument/Changeables/Layer.cs
  28. 2 2
      src/PixiEditor.ChangeableDocument/Changes/Drawing/ClearSelection_Change.cs
  29. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Drawing/CombineStructureMembersOnto_Change.cs
  30. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Drawing/DrawRectangle_UpdateableChange.cs
  31. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Drawing/DrawingChangeHelper.cs
  32. 1 1
      src/PixiEditor.ChangeableDocument/Changes/Drawing/PasteImage_UpdateableChange.cs
  33. 4 4
      src/PixiEditor.ChangeableDocument/Changes/Drawing/SelectRectangle_UpdateableChange.cs
  34. 3 3
      src/PixiEditor.ChangeableDocument/Changes/Root/ResizeCanvas_Change.cs
  35. 3 3
      src/PixiEditor.ChangeableDocument/Rendering/ChunkRenderer.cs
  36. 5 5
      src/PixiEditor.Zoombox/MoveDragOperation.cs
  37. 2 2
      src/PixiEditor.Zoombox/RotateDragOperation.cs
  38. 4 4
      src/PixiEditor.Zoombox/ViewportRoutedEventArgs.cs
  39. 3 3
      src/PixiEditor.Zoombox/ZoomDragOperation.cs
  40. 30 30
      src/PixiEditor.Zoombox/Zoombox.xaml.cs
  41. 8 8
      src/PixiEditorPrototype/CustomControls/SymmetryOverlay/SymmetryOverlay.cs
  42. 20 20
      src/PixiEditorPrototype/CustomControls/TransformOverlay/TransformHelper.cs
  43. 17 17
      src/PixiEditorPrototype/CustomControls/TransformOverlay/TransformOverlay.cs
  44. 1 1
      src/PixiEditorPrototype/CustomControls/TransformOverlay/TransformState.cs
  45. 15 15
      src/PixiEditorPrototype/CustomControls/TransformOverlay/TransformUpdateHelper.cs
  46. 0 37
      src/PixiEditorPrototype/Models/DocumentStateHandler.cs
  47. 2 2
      src/PixiEditorPrototype/Models/DocumentUpdater.cs
  48. 1 1
      src/PixiEditorPrototype/Models/Rendering/RenderInfos/DirtyRect_RenderInfo.cs
  49. 8 8
      src/PixiEditorPrototype/Models/Rendering/WriteableBitmapUpdater.cs
  50. 1 1
      src/PixiEditorPrototype/Models/ViewportLocation.cs
  51. 7 7
      src/PixiEditorPrototype/UserControls/Viewport/Viewport.xaml.cs
  52. 18 9
      src/PixiEditorPrototype/ViewModels/DocumentViewModel.cs

+ 2 - 2
src/ChunkyImageLib/Chunk.cs

@@ -15,7 +15,7 @@ public class Chunk : IDisposable
 
     private bool returned = false;
     public Surface Surface { get; }
-    public Vector2i PixelSize { get; }
+    public VecI PixelSize { get; }
     public ChunkResolution Resolution { get; }
     private Chunk(ChunkResolution resolution)
     {
@@ -34,7 +34,7 @@ public class Chunk : IDisposable
         return chunk;
     }
 
-    public void DrawOnSurface(SKSurface surface, Vector2i pos, SKPaint? paint = null)
+    public void DrawOnSurface(SKSurface surface, VecI pos, SKPaint? paint = null)
     {
         surface.Canvas.DrawSurface(Surface.SkiaSurface, pos.X, pos.Y, paint);
     }

+ 31 - 61
src/ChunkyImageLib/ChunkyImage.cs

@@ -57,21 +57,21 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
     private static SKPaint AddingPaint { get; } = new SKPaint() { BlendMode = SKBlendMode.Plus };
     private SKPaint blendModePaint = new SKPaint() { BlendMode = SKBlendMode.Src };
 
-    public Vector2i CommittedSize { get; private set; }
-    public Vector2i LatestSize { get; private set; }
+    public VecI CommittedSize { get; private set; }
+    public VecI LatestSize { get; private set; }
 
-    private List<(IOperation operation, HashSet<Vector2i> affectedChunks)> queuedOperations = new();
+    private List<(IOperation operation, HashSet<VecI> affectedChunks)> queuedOperations = new();
     private List<ChunkyImage> activeClips = new();
     private SKBlendMode blendMode = SKBlendMode.Src;
     private bool lockTransparency = false;
     private int? horizontalSymmetryAxis = null;
     private int? verticalSymmetryAxis = null;
 
-    private Dictionary<ChunkResolution, Dictionary<Vector2i, Chunk>> committedChunks;
-    private Dictionary<ChunkResolution, Dictionary<Vector2i, Chunk>> latestChunks;
-    private Dictionary<ChunkResolution, Dictionary<Vector2i, LatestChunkData>> latestChunksData = new();
+    private Dictionary<ChunkResolution, Dictionary<VecI, Chunk>> committedChunks;
+    private Dictionary<ChunkResolution, Dictionary<VecI, Chunk>> latestChunks;
+    private Dictionary<ChunkResolution, Dictionary<VecI, LatestChunkData>> latestChunksData = new();
 
-    public ChunkyImage(Vector2i size)
+    public ChunkyImage(VecI size)
     {
         CommittedSize = size;
         LatestSize = size;
@@ -119,7 +119,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
     /// <returns>
     /// True if the chunk existed and was drawn, otherwise false
     /// </returns>
-    public bool DrawMostUpToDateChunkOn(Vector2i chunkPos, ChunkResolution resolution, SKSurface surface, Vector2i pos, SKPaint? paint = null)
+    public bool DrawMostUpToDateChunkOn(VecI chunkPos, ChunkResolution resolution, SKSurface surface, VecI pos, SKPaint? paint = null)
     {
         lock (lockObject)
         {
@@ -156,7 +156,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
         }
     }
 
-    public bool LatestOrCommittedChunkExists(Vector2i chunkPos)
+    public bool LatestOrCommittedChunkExists(VecI chunkPos)
     {
         lock (lockObject)
         {
@@ -167,7 +167,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
         }
     }
 
-    internal bool DrawCommittedChunkOn(Vector2i chunkPos, ChunkResolution resolution, SKSurface surface, Vector2i pos, SKPaint? paint = null)
+    internal bool DrawCommittedChunkOn(VecI chunkPos, ChunkResolution resolution, SKSurface surface, VecI pos, SKPaint? paint = null)
     {
         lock (lockObject)
         {
@@ -179,7 +179,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
         }
     }
 
-    internal bool CommittedChunkExists(Vector2i chunkPos)
+    internal bool CommittedChunkExists(VecI chunkPos)
     {
         lock (lockObject)
         {
@@ -190,7 +190,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
     /// <summary>
     /// Returns the latest version of the chunk if it exists or should exist based on queued operation. The returned chunk is fully up to date.
     /// </summary>
-    private Chunk? GetLatestChunk(Vector2i pos, ChunkResolution resolution)
+    private Chunk? GetLatestChunk(VecI pos, ChunkResolution resolution)
     {
         if (queuedOperations.Count == 0)
             return null;
@@ -203,7 +203,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
     /// <summary>
     /// Tries it's best to return a committed chunk, either if it exists or if it can be created from it's high res version. Returns null if it can't.
     /// </summary>
-    private Chunk? GetCommittedChunk(Vector2i pos, ChunkResolution resolution)
+    private Chunk? GetCommittedChunk(VecI pos, ChunkResolution resolution)
     {
         var maybeSameRes = MaybeGetCommittedChunk(pos, resolution);
         if (maybeSameRes is not null)
@@ -216,9 +216,9 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
         return null;
     }
 
-    private Chunk? MaybeGetLatestChunk(Vector2i pos, ChunkResolution resolution)
+    private Chunk? MaybeGetLatestChunk(VecI pos, ChunkResolution resolution)
         => latestChunks[resolution].TryGetValue(pos, out Chunk? value) ? value : null;
-    private Chunk? MaybeGetCommittedChunk(Vector2i pos, ChunkResolution resolution)
+    private Chunk? MaybeGetCommittedChunk(VecI pos, ChunkResolution resolution)
         => committedChunks[resolution].TryGetValue(pos, out Chunk? value) ? value : null;
 
     public void AddRasterClip(ChunkyImage clippingMask)
@@ -296,7 +296,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
         }
     }
 
-    public void EnqueueDrawImage(Vector2i pos, Surface image)
+    public void EnqueueDrawImage(VecI pos, Surface image)
     {
         lock (lockObject)
         {
@@ -305,7 +305,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
         }
     }
 
-    public void EnqueueClearRegion(Vector2i pos, Vector2i size)
+    public void EnqueueClearRegion(VecI pos, VecI size)
     {
         lock (lockObject)
         {
@@ -323,7 +323,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
         }
     }
 
-    public void EnqueueResize(Vector2i newSize)
+    public void EnqueueResize(VecI newSize)
     {
         lock (lockObject)
         {
@@ -355,7 +355,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
         }
     }
 
-    private void EnqueueOperation(IOperation operation, HashSet<Vector2i> chunks)
+    private void EnqueueOperation(IOperation operation, HashSet<VecI> chunks)
     {
         queuedOperations.Add((operation, chunks));
     }
@@ -529,7 +529,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
     /// <returns>
     /// All chunks that have something in them, including latest (uncommitted) ones
     /// </returns>
-    public HashSet<Vector2i> FindAllChunks()
+    public HashSet<VecI> FindAllChunks()
     {
         lock (lockObject)
         {
@@ -542,7 +542,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
         }
     }
 
-    public HashSet<Vector2i> FindCommittedChunks()
+    public HashSet<VecI> FindCommittedChunks()
     {
         lock (lockObject)
         {
@@ -553,11 +553,11 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
     /// <returns>
     /// Chunks affected by operations that haven't been committed yet
     /// </returns>
-    public HashSet<Vector2i> FindAffectedChunks()
+    public HashSet<VecI> FindAffectedChunks()
     {
         lock (lockObject)
         {
-            var chunks = new HashSet<Vector2i>();
+            var chunks = new HashSet<VecI>();
             foreach (var (_, opChunks) in queuedOperations)
             {
                 chunks.UnionWith(opChunks);
@@ -569,7 +569,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
     /// <summary>
     /// Applies all operations queued for a specific (latest) chunk. If the latest chunk doesn't exist yet, creates it. If none of the existing operations affect the chunk does nothing.
     /// </summary>
-    private void MaybeCreateAndProcessQueueForChunk(Vector2i chunkPos, ChunkResolution resolution)
+    private void MaybeCreateAndProcessQueueForChunk(VecI chunkPos, ChunkResolution resolution)
     {
         if (!latestChunksData[resolution].TryGetValue(chunkPos, out LatestChunkData chunkData))
             chunkData = new() { QueueProgress = 0, IsDeleted = !committedChunks[ChunkResolution.Full].ContainsKey(chunkPos) };
@@ -617,7 +617,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
     /// <summary>
     /// (All) -> All is visible, (None) -> None is visible, (Chunk) -> Combined clip
     /// </summary>
-    private OneOf<All, None, Chunk> CombineClipsForChunk(Vector2i chunkPos, ChunkResolution resolution)
+    private OneOf<All, None, Chunk> CombineClipsForChunk(VecI chunkPos, ChunkResolution resolution)
     {
         if (lockTransparency && MaybeGetCommittedChunk(chunkPos, ChunkResolution.Full) is null)
         {
@@ -684,36 +684,6 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
         }
     }
 
-    private void DrawOperationWithSymmetry(IDrawOperation operation, Chunk chunk, Vector2i chunkPos)
-    {
-        operation.DrawOnChunk(chunk, chunkPos);
-        if (horizontalSymmetryAxis is not null)
-        {
-            chunk.Surface.SkiaSurface.Canvas.Save();
-            float y = (float)horizontalSymmetryAxis * (float)chunk.Resolution.Multiplier() - (chunkPos.Y * chunk.Resolution.PixelSize());
-            chunk.Surface.SkiaSurface.Canvas.Scale(1, -1, 0, y);
-            operation.DrawOnChunk(chunk, chunkPos);
-            chunk.Surface.SkiaSurface.Canvas.Restore();
-        }
-        if (verticalSymmetryAxis is not null)
-        {
-            chunk.Surface.SkiaSurface.Canvas.Save();
-            float x = (float)verticalSymmetryAxis * (float)chunk.Resolution.Multiplier() - (chunkPos.X * chunk.Resolution.PixelSize());
-            chunk.Surface.SkiaSurface.Canvas.Scale(-1, 1, x, 0);
-            operation.DrawOnChunk(chunk, chunkPos);
-            chunk.Surface.SkiaSurface.Canvas.Restore();
-        }
-        if (horizontalSymmetryAxis is not null && verticalSymmetryAxis is not null)
-        {
-            float x = (float)verticalSymmetryAxis * (float)chunk.Resolution.Multiplier() - (chunkPos.X * chunk.Resolution.PixelSize());
-            float y = (float)horizontalSymmetryAxis * (float)chunk.Resolution.Multiplier() - (chunkPos.Y * chunk.Resolution.PixelSize());
-            chunk.Surface.SkiaSurface.Canvas.Save();
-            chunk.Surface.SkiaSurface.Canvas.Scale(-1, -1, x, y);
-            operation.DrawOnChunk(chunk, chunkPos);
-            chunk.Surface.SkiaSurface.Canvas.Restore();
-        }
-    }
-
     /// <returns>
     /// True if the chunk was fully cleared (and should be deleted).
     /// </returns>
@@ -721,7 +691,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
         IOperation operation,
         OneOf<All, None, Chunk> combinedClips,
         Chunk targetChunk,
-        Vector2i chunkPos,
+        VecI chunkPos,
         ChunkResolution resolution,
         LatestChunkData chunkData)
     {
@@ -778,14 +748,14 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
         }
     }
 
-    private HashSet<Vector2i> FindAllChunksOutsideBounds(Vector2i size)
+    private HashSet<VecI> FindAllChunksOutsideBounds(VecI size)
     {
         var chunks = FindAllChunks();
         chunks.RemoveWhere(pos => !IsOutsideBounds(pos, size));
         return chunks;
     }
 
-    private static bool IsOutsideBounds(Vector2i chunkPos, Vector2i imageSize)
+    private static bool IsOutsideBounds(VecI chunkPos, VecI imageSize)
     {
         return chunkPos.X < 0 || chunkPos.Y < 0 || chunkPos.X * ChunkSize >= imageSize.X || chunkPos.Y * ChunkSize >= imageSize.Y;
     }
@@ -794,7 +764,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
     {
         if (queuedOperations.Count != 0)
             throw new InvalidOperationException("This method cannot be used while any operations are queued");
-        HashSet<Vector2i> toRemove = new();
+        HashSet<VecI> toRemove = new();
         foreach (var (pos, chunk) in committedChunks[ChunkResolution.Full])
         {
             if (chunk.Surface.IsFullyTransparent())
@@ -815,7 +785,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
     /// <summary>
     /// Gets existing committed chunk or creates a new one. Doesn't apply any operations to the chunk, returns it as it is.
     /// </summary>
-    private Chunk GetOrCreateCommittedChunk(Vector2i chunkPos, ChunkResolution resolution)
+    private Chunk GetOrCreateCommittedChunk(VecI chunkPos, ChunkResolution resolution)
     {
         // commited chunk of the same resolution exists
         Chunk? targetChunk = MaybeGetCommittedChunk(chunkPos, resolution);
@@ -856,7 +826,7 @@ public class ChunkyImage : IReadOnlyChunkyImage, IDisposable
     /// <summary>
     /// Gets existing latest chunk or creates a new one, based on a committed one if it exists. Doesn't do any operations to the chunk.
     /// </summary>
-    private Chunk GetOrCreateLatestChunk(Vector2i chunkPos, ChunkResolution resolution)
+    private Chunk GetOrCreateLatestChunk(VecI chunkPos, ChunkResolution resolution)
     {
         // latest chunk exists
         Chunk? targetChunk;

+ 2 - 2
src/ChunkyImageLib/CommittedChunkStorage.cs

@@ -6,10 +6,10 @@ namespace ChunkyImageLib;
 public class CommittedChunkStorage : IDisposable
 {
     private bool disposed = false;
-    private List<(Vector2i, Chunk?)> savedChunks = new();
+    private List<(VecI, Chunk?)> savedChunks = new();
     private static SKPaint ReplacingPaint { get; } = new SKPaint() { BlendMode = SKBlendMode.Src };
 
-    public CommittedChunkStorage(ChunkyImage image, HashSet<Vector2i> committedChunksToSave)
+    public CommittedChunkStorage(ChunkyImage image, HashSet<VecI> committedChunksToSave)
     {
         foreach (var chunkPos in committedChunksToSave)
         {

+ 11 - 11
src/ChunkyImageLib/DataHolders/ShapeCorners.cs

@@ -1,24 +1,24 @@
 namespace ChunkyImageLib.DataHolders;
 public struct ShapeCorners
 {
-    public ShapeCorners(Vector2d center, Vector2d size, double angle)
+    public ShapeCorners(VecD center, VecD size, double angle)
     {
         TopLeft = center - size / 2;
-        TopRight = center + new Vector2d(size.X / 2, -size.Y / 2);
+        TopRight = center + new VecD(size.X / 2, -size.Y / 2);
         BottomRight = center + size / 2;
-        BottomLeft = center + new Vector2d(-size.X / 2, size.Y / 2);
+        BottomLeft = center + new VecD(-size.X / 2, size.Y / 2);
     }
-    public ShapeCorners(Vector2d topLeft, Vector2d size)
+    public ShapeCorners(VecD topLeft, VecD size)
     {
         TopLeft = topLeft;
         TopRight = new(topLeft.X + size.X, topLeft.Y);
         BottomRight = topLeft + size;
         BottomLeft = new(topLeft.X, topLeft.Y + size.Y);
     }
-    public Vector2d TopLeft { get; set; }
-    public Vector2d TopRight { get; set; }
-    public Vector2d BottomLeft { get; set; }
-    public Vector2d BottomRight { get; set; }
+    public VecD TopLeft { get; set; }
+    public VecD TopRight { get; set; }
+    public VecD BottomLeft { get; set; }
+    public VecD BottomRight { get; set; }
     public bool IsLegal
     {
         get
@@ -33,8 +33,8 @@ public struct ShapeCorners
     }
     public bool HasNaNOrInfinity => TopLeft.IsNaNOrInfinity() || TopRight.IsNaNOrInfinity() || BottomLeft.IsNaNOrInfinity() || BottomRight.IsNaNOrInfinity();
     public bool IsRect => Math.Abs((TopLeft - BottomRight).Length - (TopRight - BottomLeft).Length) < 0.001;
-    public Vector2d RectSize => new((TopLeft - TopRight).Length, (TopLeft - BottomLeft).Length);
-    public Vector2d RectCenter => (TopLeft - BottomRight) / 2 + BottomRight;
+    public VecD RectSize => new((TopLeft - TopRight).Length, (TopLeft - BottomLeft).Length);
+    public VecD RectCenter => (TopLeft - BottomRight) / 2 + BottomRight;
     public double RectRotation =>
         (TopLeft - TopRight).Cross(TopLeft - BottomLeft) > 0 ?
         RectSize.CCWAngleTo(BottomRight - TopLeft) :
@@ -51,7 +51,7 @@ public struct ShapeCorners
                 (BottomRight - BottomRight.Round()).TaxicabLength < epsilon;
         }
     }
-    public bool IsPointInside(Vector2d point)
+    public bool IsPointInside(VecD point)
     {
         var top = TopLeft - TopRight;
         var right = TopRight - BottomRight;

+ 3 - 3
src/ChunkyImageLib/DataHolders/ShapeData.cs

@@ -4,7 +4,7 @@ namespace ChunkyImageLib.DataHolders;
 
 public record struct ShapeData
 {
-    public ShapeData(Vector2d center, Vector2d size, double rotation, int strokeWidth, SKColor strokeColor, SKColor fillColor, SKBlendMode blendMode = SKBlendMode.SrcOver)
+    public ShapeData(VecD center, VecD size, double rotation, int strokeWidth, SKColor strokeColor, SKColor fillColor, SKBlendMode blendMode = SKBlendMode.SrcOver)
     {
         StrokeColor = strokeColor;
         FillColor = fillColor;
@@ -17,9 +17,9 @@ public record struct ShapeData
     public SKColor StrokeColor { get; }
     public SKColor FillColor { get; }
     public SKBlendMode BlendMode { get; }
-    public Vector2d Center { get; }
+    public VecD Center { get; }
     /// <summary>Can be negative to show flipping </summary>
-    public Vector2d Size { get; }
+    public VecD Size { get; }
     public double Angle { get; }
     public int StrokeWidth { get; }
 

+ 54 - 54
src/ChunkyImageLib/DataHolders/Vector2d.cs

@@ -2,7 +2,7 @@
 
 namespace ChunkyImageLib.DataHolders;
 
-public struct Vector2d
+public struct VecD
 {
     public double X { set; get; }
     public double Y { set; get; }
@@ -10,44 +10,44 @@ public struct Vector2d
     public double TaxicabLength => Math.Abs(X) + Math.Abs(Y);
     public double Length => Math.Sqrt(LengthSquared);
     public double LengthSquared => X * X + Y * Y;
-    public double Angle => Y < 0 ? -AngleTo(new Vector2d(1, 0)) : AngleTo(new Vector2d(1, 0));
+    public double Angle => Y < 0 ? -AngleTo(new VecD(1, 0)) : AngleTo(new VecD(1, 0));
     public double LongestAxis => (Math.Abs(X) < Math.Abs(Y)) ? Y : X;
     public double ShortestAxis => (Math.Abs(X) < Math.Abs(Y)) ? X : Y;
 
-    public Vector2d(double x, double y)
+    public VecD(double x, double y)
     {
         X = x;
         Y = y;
     }
-    public static Vector2d FromAngleAndLength(double angle, double length)
+    public static VecD FromAngleAndLength(double angle, double length)
     {
-        return new Vector2d(Math.Cos(angle) * length, Math.Sin(angle) * length);
+        return new VecD(Math.Cos(angle) * length, Math.Sin(angle) * length);
     }
-    public Vector2d Round()
+    public VecD Round()
     {
         return new(Math.Round(X), Math.Round(Y));
     }
-    public Vector2d Rotate(double angle)
+    public VecD Rotate(double angle)
     {
-        Vector2d result = new Vector2d();
+        VecD result = new VecD();
         result.X = X * Math.Cos(angle) - Y * Math.Sin(angle);
         result.Y = X * Math.Sin(angle) + Y * Math.Cos(angle);
         return result;
     }
-    public Vector2d Rotate(double angle, Vector2d around)
+    public VecD Rotate(double angle, VecD around)
     {
         return (this - around).Rotate(angle) + around;
     }
-    public double DistanceToLineSegment(Vector2d pos1, Vector2d pos2)
+    public double DistanceToLineSegment(VecD pos1, VecD pos2)
     {
-        Vector2d segment = pos2 - pos1;
+        VecD segment = pos2 - pos1;
         if ((this - pos1).AngleTo(segment) > Math.PI / 2)
             return (this - pos1).Length;
         if ((this - pos2).AngleTo(-segment) > Math.PI / 2)
             return (this - pos2).Length;
         return DistanceToLine(pos1, pos2);
     }
-    public double DistanceToLine(Vector2d pos1, Vector2d pos2)
+    public double DistanceToLine(VecD pos1, VecD pos2)
     {
         double a = (pos1 - pos2).Length;
         double b = (this - pos1).Length;
@@ -58,32 +58,32 @@ public struct Vector2d
 
         return triangleArea / a * 2;
     }
-    public Vector2d ProjectOntoLine(Vector2d pos1, Vector2d pos2)
+    public VecD ProjectOntoLine(VecD pos1, VecD pos2)
     {
-        Vector2d line = (pos2 - pos1).Normalize();
-        Vector2d point = this - pos1;
+        VecD line = (pos2 - pos1).Normalize();
+        VecD point = this - pos1;
         return (line * point) * line + pos1;
     }
     /// <summary>
     /// Reflects the vector across a vertical line with the specified position
     /// </summary>
-    public Vector2d ReflectX(double lineX)
+    public VecD ReflectX(double lineX)
     {
         return new(2 * lineX - X, Y);
     }
     /// <summary>
     /// Reflects the vector along a horizontal line with the specified position
     /// </summary>
-    public Vector2d ReflectY(double lineY)
+    public VecD ReflectY(double lineY)
     {
         return new(X, 2 * lineY - Y);
     }
-    public Vector2d ReflectAcrossLine(Vector2d pos1, Vector2d pos2)
+    public VecD ReflectAcrossLine(VecD pos1, VecD pos2)
     {
         var onLine = ProjectOntoLine(pos1, pos2);
         return onLine - (this - onLine);
     }
-    public double AngleTo(Vector2d other)
+    public double AngleTo(VecD other)
     {
         return Math.Acos((this * other) / Length / other.Length);
     }
@@ -91,96 +91,96 @@ public struct Vector2d
     /// <summary>
     /// Returns the angle between two vectors when travelling counterclockwise (assuming Y pointing up) from this vector to passed vector
     /// </summary>
-    public double CCWAngleTo(Vector2d other)
+    public double CCWAngleTo(VecD other)
     {
         var rot = other.Rotate(-Angle);
         return rot.Angle;
     }
-    public Vector2d Lerp(Vector2d other, double factor)
+    public VecD Lerp(VecD other, double factor)
     {
         return (other - this) * factor + this;
     }
-    public Vector2d Normalize()
+    public VecD Normalize()
     {
-        return new Vector2d(X / Length, Y / Length);
+        return new VecD(X / Length, Y / Length);
     }
-    public Vector2d Abs()
+    public VecD Abs()
     {
-        return new Vector2d(Math.Abs(X), Math.Abs(Y));
+        return new VecD(Math.Abs(X), Math.Abs(Y));
     }
-    public Vector2d Signs()
+    public VecD Signs()
     {
-        return new Vector2d(X >= 0 ? 1 : -1, Y >= 0 ? 1 : -1);
+        return new VecD(X >= 0 ? 1 : -1, Y >= 0 ? 1 : -1);
     }
     /// <summary>
     /// Returns the signed magnitude (Z coordinate) of the vector resulting from the cross product
     /// </summary>
-    public double Cross(Vector2d other)
+    public double Cross(VecD other)
     {
         return (X * other.Y) - (Y * other.X);
     }
-    public Vector2d Multiply(Vector2d other)
+    public VecD Multiply(VecD other)
     {
-        return new Vector2d(X * other.X, Y * other.Y);
+        return new VecD(X * other.X, Y * other.Y);
     }
-    public Vector2d Divide(Vector2d other)
+    public VecD Divide(VecD other)
     {
-        return new Vector2d(X / other.X, Y / other.Y);
+        return new VecD(X / other.X, Y / other.Y);
     }
-    public static Vector2d operator +(Vector2d a, Vector2d b)
+    public static VecD operator +(VecD a, VecD b)
     {
-        return new Vector2d(a.X + b.X, a.Y + b.Y);
+        return new VecD(a.X + b.X, a.Y + b.Y);
     }
-    public static Vector2d operator -(Vector2d a, Vector2d b)
+    public static VecD operator -(VecD a, VecD b)
     {
-        return new Vector2d(a.X - b.X, a.Y - b.Y);
+        return new VecD(a.X - b.X, a.Y - b.Y);
     }
-    public static Vector2d operator -(Vector2d a)
+    public static VecD operator -(VecD a)
     {
-        return new Vector2d(-a.X, -a.Y);
+        return new VecD(-a.X, -a.Y);
     }
-    public static Vector2d operator *(double b, Vector2d a)
+    public static VecD operator *(double b, VecD a)
     {
-        return new Vector2d(a.X * b, a.Y * b);
+        return new VecD(a.X * b, a.Y * b);
     }
-    public static double operator *(Vector2d a, Vector2d b)
+    public static double operator *(VecD a, VecD b)
     {
         return a.X * b.X + a.Y * b.Y;
     }
-    public static Vector2d operator *(Vector2d a, double b)
+    public static VecD operator *(VecD a, double b)
     {
-        return new Vector2d(a.X * b, a.Y * b);
+        return new VecD(a.X * b, a.Y * b);
     }
-    public static Vector2d operator /(Vector2d a, double b)
+    public static VecD operator /(VecD a, double b)
     {
-        return new Vector2d(a.X / b, a.Y / b);
+        return new VecD(a.X / b, a.Y / b);
     }
-    public static bool operator ==(Vector2d a, Vector2d b)
+    public static bool operator ==(VecD a, VecD b)
     {
         return a.X == b.X && a.Y == b.Y;
     }
-    public static bool operator !=(Vector2d a, Vector2d b)
+    public static bool operator !=(VecD a, VecD b)
     {
         return !(a.X == b.X && a.Y == b.Y);
     }
 
-    public static explicit operator Vector2i(Vector2d vec)
+    public static explicit operator VecI(VecD vec)
     {
-        return new Vector2i((int)vec.X, (int)vec.Y);
+        return new VecI((int)vec.X, (int)vec.Y);
     }
-    public static explicit operator SKPointI(Vector2d vec)
+    public static explicit operator SKPointI(VecD vec)
     {
         return new SKPointI((int)vec.X, (int)vec.Y);
     }
-    public static explicit operator SKPoint(Vector2d vec)
+    public static explicit operator SKPoint(VecD vec)
     {
         return new SKPoint((float)vec.X, (float)vec.Y);
     }
-    public static explicit operator SKSizeI(Vector2d vec)
+    public static explicit operator SKSizeI(VecD vec)
     {
         return new SKSizeI((int)vec.X, (int)vec.Y);
     }
-    public static explicit operator SKSize(Vector2d vec)
+    public static explicit operator SKSize(VecD vec)
     {
         return new SKSize((float)vec.X, (float)vec.Y);
     }
@@ -197,7 +197,7 @@ public struct Vector2d
 
     public override bool Equals(object? obj)
     {
-        var item = obj as Vector2d?;
+        var item = obj as VecD?;
         if (item is null)
             return false;
         return this == item;

+ 34 - 34
src/ChunkyImageLib/DataHolders/Vector2i.cs

@@ -2,7 +2,7 @@
 
 namespace ChunkyImageLib.DataHolders;
 
-public struct Vector2i
+public struct VecI
 {
     public int X { set; get; }
     public int Y { set; get; }
@@ -13,96 +13,96 @@ public struct Vector2i
     public int LongestAxis => (Math.Abs(X) < Math.Abs(Y)) ? Y : X;
     public int ShortestAxis => (Math.Abs(X) < Math.Abs(Y)) ? X : Y;
 
-    public Vector2i(int x, int y)
+    public VecI(int x, int y)
     {
         X = x;
         Y = y;
     }
 
-    public Vector2i Signs()
+    public VecI Signs()
     {
-        return new Vector2i(X >= 0 ? 1 : -1, Y >= 0 ? 1 : -1);
+        return new VecI(X >= 0 ? 1 : -1, Y >= 0 ? 1 : -1);
     }
-    public Vector2i Multiply(Vector2i other)
+    public VecI Multiply(VecI other)
     {
-        return new Vector2i(X * other.X, Y * other.Y);
+        return new VecI(X * other.X, Y * other.Y);
     }
     /// <summary>
     /// Reflects the vector across a vertical line with the specified position
     /// </summary>
-    public Vector2i ReflectX(int lineX)
+    public VecI ReflectX(int lineX)
     {
         return new(2 * lineX - X, Y);
     }
     /// <summary>
     /// Reflects the vector along a horizontal line with the specified position
     /// </summary>
-    public Vector2i ReflectY(int lineY)
+    public VecI ReflectY(int lineY)
     {
         return new(X, 2 * lineY - Y);
     }
-    public static Vector2i operator +(Vector2i a, Vector2i b)
+    public static VecI operator +(VecI a, VecI b)
     {
-        return new Vector2i(a.X + b.X, a.Y + b.Y);
+        return new VecI(a.X + b.X, a.Y + b.Y);
     }
-    public static Vector2i operator -(Vector2i a, Vector2i b)
+    public static VecI operator -(VecI a, VecI b)
     {
-        return new Vector2i(a.X - b.X, a.Y - b.Y);
+        return new VecI(a.X - b.X, a.Y - b.Y);
     }
-    public static Vector2i operator -(Vector2i a)
+    public static VecI operator -(VecI a)
     {
-        return new Vector2i(-a.X, -a.Y);
+        return new VecI(-a.X, -a.Y);
     }
-    public static Vector2i operator *(int b, Vector2i a)
+    public static VecI operator *(int b, VecI a)
     {
-        return new Vector2i(a.X * b, a.Y * b);
+        return new VecI(a.X * b, a.Y * b);
     }
-    public static int operator *(Vector2i a, Vector2i b)
+    public static int operator *(VecI a, VecI b)
     {
         return a.X * b.X + a.Y * b.Y;
     }
-    public static Vector2i operator *(Vector2i a, int b)
+    public static VecI operator *(VecI a, int b)
     {
-        return new Vector2i(a.X * b, a.Y * b);
+        return new VecI(a.X * b, a.Y * b);
     }
-    public static Vector2d operator *(Vector2i a, double b)
+    public static VecD operator *(VecI a, double b)
     {
-        return new Vector2d(a.X * b, a.Y * b);
+        return new VecD(a.X * b, a.Y * b);
     }
-    public static Vector2i operator /(Vector2i a, int b)
+    public static VecI operator /(VecI a, int b)
     {
-        return new Vector2i(a.X / b, a.Y / b);
+        return new VecI(a.X / b, a.Y / b);
     }
-    public static Vector2d operator /(Vector2i a, double b)
+    public static VecD operator /(VecI a, double b)
     {
-        return new Vector2d(a.X / b, a.Y / b);
+        return new VecD(a.X / b, a.Y / b);
     }
-    public static bool operator ==(Vector2i a, Vector2i b)
+    public static bool operator ==(VecI a, VecI b)
     {
         return a.X == b.X && a.Y == b.Y;
     }
-    public static bool operator !=(Vector2i a, Vector2i b)
+    public static bool operator !=(VecI a, VecI b)
     {
         return !(a.X == b.X && a.Y == b.Y);
     }
 
-    public static implicit operator Vector2d(Vector2i vec)
+    public static implicit operator VecD(VecI vec)
     {
-        return new Vector2d(vec.X, vec.Y);
+        return new VecD(vec.X, vec.Y);
     }
-    public static implicit operator SKPointI(Vector2i vec)
+    public static implicit operator SKPointI(VecI vec)
     {
         return new SKPointI(vec.X, vec.Y);
     }
-    public static implicit operator SKPoint(Vector2i vec)
+    public static implicit operator SKPoint(VecI vec)
     {
         return new SKPoint(vec.X, vec.Y);
     }
-    public static implicit operator SKSizeI(Vector2i vec)
+    public static implicit operator SKSizeI(VecI vec)
     {
         return new SKSizeI(vec.X, vec.Y);
     }
-    public static implicit operator SKSize(Vector2i vec)
+    public static implicit operator SKSize(VecI vec)
     {
         return new SKSize(vec.X, vec.Y);
     }
@@ -114,7 +114,7 @@ public struct Vector2i
 
     public override bool Equals(object? obj)
     {
-        var item = obj as Vector2i?;
+        var item = obj as VecI?;
         if (item is null)
             return false;
         return this == item;

+ 5 - 5
src/ChunkyImageLib/IReadOnlyChunkyImage.cs

@@ -5,9 +5,9 @@ namespace ChunkyImageLib;
 
 public interface IReadOnlyChunkyImage
 {
-    bool DrawMostUpToDateChunkOn(Vector2i chunkPos, ChunkResolution resolution, SKSurface surface, Vector2i pos, SKPaint? paint = null);
-    bool LatestOrCommittedChunkExists(Vector2i chunkPos);
-    HashSet<Vector2i> FindAffectedChunks();
-    HashSet<Vector2i> FindCommittedChunks();
-    HashSet<Vector2i> FindAllChunks();
+    bool DrawMostUpToDateChunkOn(VecI chunkPos, ChunkResolution resolution, SKSurface surface, VecI pos, SKPaint? paint = null);
+    bool LatestOrCommittedChunkExists(VecI chunkPos);
+    HashSet<VecI> FindAffectedChunks();
+    HashSet<VecI> FindCommittedChunks();
+    HashSet<VecI> FindAllChunks();
 }

+ 9 - 9
src/ChunkyImageLib/Operations/ClearRegionOperation.cs

@@ -5,21 +5,21 @@ namespace ChunkyImageLib.Operations;
 
 internal class ClearRegionOperation : IDrawOperation
 {
-    Vector2i pos;
-    Vector2i size;
+    VecI pos;
+    VecI size;
 
     public bool IgnoreEmptyChunks => true;
 
-    public ClearRegionOperation(Vector2i pos, Vector2i size)
+    public ClearRegionOperation(VecI pos, VecI size)
     {
         this.pos = pos;
         this.size = size;
     }
 
-    public void DrawOnChunk(Chunk chunk, Vector2i chunkPos)
+    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
     {
-        Vector2i convPos = OperationHelper.ConvertForResolution(pos, chunk.Resolution);
-        Vector2i convSize = OperationHelper.ConvertForResolution(size, chunk.Resolution);
+        VecI convPos = OperationHelper.ConvertForResolution(pos, chunk.Resolution);
+        VecI convSize = OperationHelper.ConvertForResolution(size, chunk.Resolution);
 
         chunk.Surface.SkiaSurface.Canvas.Save();
         chunk.Surface.SkiaSurface.Canvas.ClipRect(SKRect.Create(convPos - chunkPos.Multiply(chunk.PixelSize), convSize));
@@ -27,7 +27,7 @@ internal class ClearRegionOperation : IDrawOperation
         chunk.Surface.SkiaSurface.Canvas.Restore();
     }
 
-    public HashSet<Vector2i> FindAffectedChunks()
+    public HashSet<VecI> FindAffectedChunks()
     {
         return OperationHelper.FindChunksFullyInsideRectangle(pos, size, ChunkPool.FullChunkSize);
     }
@@ -38,9 +38,9 @@ internal class ClearRegionOperation : IDrawOperation
         if (verAxisX is not null && horAxisY is not null)
             return new ClearRegionOperation((pos + size).ReflectX((int)verAxisX).ReflectY((int)horAxisY), size);
         if (verAxisX is not null)
-            return new ClearRegionOperation(new Vector2i(pos.X + size.X, pos.Y).ReflectX((int)verAxisX), size);
+            return new ClearRegionOperation(new VecI(pos.X + size.X, pos.Y).ReflectX((int)verAxisX), size);
         if (horAxisY is not null)
-            return new ClearRegionOperation(new Vector2i(pos.X, pos.Y + size.Y).ReflectY((int)horAxisY), size);
+            return new ClearRegionOperation(new VecI(pos.X, pos.Y + size.Y).ReflectY((int)horAxisY), size);
         return new ClearRegionOperation(pos, size);
     }
 }

+ 2 - 2
src/ChunkyImageLib/Operations/IDrawOperation.cs

@@ -5,7 +5,7 @@ namespace ChunkyImageLib.Operations;
 internal interface IDrawOperation : IOperation
 {
     bool IgnoreEmptyChunks { get; }
-    void DrawOnChunk(Chunk chunk, Vector2i chunkPos);
-    HashSet<Vector2i> FindAffectedChunks();
+    void DrawOnChunk(Chunk chunk, VecI chunkPos);
+    HashSet<VecI> FindAffectedChunks();
     IDrawOperation AsMirrored(int? verAxisX, int? horAxisY);
 }

+ 7 - 7
src/ChunkyImageLib/Operations/ImageOperation.cs

@@ -13,14 +13,14 @@ internal class ImageOperation : IDrawOperation
 
     public bool IgnoreEmptyChunks => false;
 
-    public ImageOperation(Vector2i pos, Surface image, bool copyImage = true)
+    public ImageOperation(VecI pos, Surface image, bool copyImage = true)
     {
         corners = new()
         {
             TopLeft = pos,
             TopRight = new(pos.X + image.Size.X, pos.Y),
             BottomRight = pos + image.Size,
-            BottomLeft = new Vector2d(pos.X, pos.Y + image.Size.Y)
+            BottomLeft = new VecD(pos.X, pos.Y + image.Size.Y)
         };
         transformMatrix = SKMatrix.CreateIdentity();
         transformMatrix.TransX = pos.X;
@@ -47,10 +47,10 @@ internal class ImageOperation : IDrawOperation
         imageWasCopied = copyImage;
     }
 
-    public void DrawOnChunk(Chunk chunk, Vector2i chunkPos)
+    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
     {
         float scaleMult = (float)chunk.Resolution.Multiplier();
-        Vector2d trans = -chunkPos * ChunkPool.FullChunkSize;
+        VecD trans = -chunkPos * ChunkPool.FullChunkSize;
 
         var scaleTrans = SKMatrix.CreateScaleTranslation(scaleMult, scaleMult, (float)trans.X * scaleMult, (float)trans.Y * scaleMult);
         var finalMatrix = SKMatrix.Concat(scaleTrans, transformMatrix);
@@ -61,7 +61,7 @@ internal class ImageOperation : IDrawOperation
         chunk.Surface.SkiaSurface.Canvas.Restore();
     }
 
-    public HashSet<Vector2i> FindAffectedChunks()
+    public HashSet<VecI> FindAffectedChunks()
     {
         return OperationHelper.FindChunksTouchingQuadrilateral(corners, ChunkPool.FullChunkSize);
     }
@@ -77,10 +77,10 @@ internal class ImageOperation : IDrawOperation
         if (verAxisX is not null && horAxisY is not null)
             return new ImageOperation
                 (corners.AsMirroredAcrossVerAxis((int)verAxisX).AsMirroredAcrossHorAxis((int)horAxisY), toPaint, imageWasCopied);
-        else if (verAxisX is not null)
+        if (verAxisX is not null)
             return new ImageOperation
                 (corners.AsMirroredAcrossVerAxis((int)verAxisX), toPaint, imageWasCopied);
-        else if (horAxisY is not null)
+        if (horAxisY is not null)
             return new ImageOperation
                 (corners.AsMirroredAcrossHorAxis((int)horAxisY), toPaint, imageWasCopied);
         return new ImageOperation(corners, toPaint, imageWasCopied);

+ 46 - 46
src/ChunkyImageLib/Operations/OperationHelper.cs

@@ -5,13 +5,13 @@ namespace ChunkyImageLib.Operations;
 
 public static class OperationHelper
 {
-    public static Vector2i ConvertForResolution(Vector2i pixelPos, ChunkResolution resolution)
+    public static VecI ConvertForResolution(VecI pixelPos, ChunkResolution resolution)
     {
         var mult = resolution.Multiplier();
         return new((int)Math.Round(pixelPos.X * mult), (int)Math.Round(pixelPos.Y * mult));
     }
 
-    public static Vector2d ConvertForResolution(Vector2d pixelPos, ChunkResolution resolution)
+    public static VecD ConvertForResolution(VecD pixelPos, ChunkResolution resolution)
     {
         var mult = resolution.Multiplier();
         return new(pixelPos.X * mult, pixelPos.Y * mult);
@@ -28,16 +28,16 @@ public static class OperationHelper
         };
     }
 
-    public static Vector2i GetChunkPos(Vector2i pixelPos, int chunkSize)
+    public static VecI GetChunkPos(VecI pixelPos, int chunkSize)
     {
-        return new Vector2i()
+        return new VecI()
         {
             X = (int)MathF.Floor(pixelPos.X / (float)chunkSize),
             Y = (int)MathF.Floor(pixelPos.Y / (float)chunkSize)
         };
     }
 
-    public static SKMatrix CreateMatrixFromPoints(ShapeCorners corners, Vector2d size)
+    public static SKMatrix CreateMatrixFromPoints(ShapeCorners corners, VecD size)
         => CreateMatrixFromPoints((SKPoint)corners.TopLeft, (SKPoint)corners.TopRight, (SKPoint)corners.BottomRight, (SKPoint)corners.BottomLeft, (float)size.X, (float)size.Y);
     public static SKMatrix CreateMatrixFromPoints(SKPoint topLeft, SKPoint topRight, SKPoint botRight, SKPoint botLeft, float width, float height)
     {
@@ -60,13 +60,13 @@ public static class OperationHelper
         return new SKMatrix(scaleX, skewX, transX, skewY, scaleY, transY, persp0, persp1, persp2);
     }
 
-    public static HashSet<Vector2i> FindChunksTouchingQuadrilateral(ShapeCorners corners, int chunkSize)
+    public static HashSet<VecI> FindChunksTouchingQuadrilateral(ShapeCorners corners, int chunkSize)
     {
         if (corners.HasNaNOrInfinity ||
             (corners.BottomLeft - corners.TopRight).Length > chunkSize * 40 * 20 ||
             (corners.TopLeft - corners.BottomRight).Length > chunkSize * 40 * 20)
-            return new HashSet<Vector2i>();
-        List<Vector2i>[] lines = new List<Vector2i>[] {
+            return new HashSet<VecI>();
+        List<VecI>[] lines = new List<VecI>[] {
             FindChunksAlongLine(corners.TopRight, corners.TopLeft, chunkSize),
             FindChunksAlongLine(corners.BottomRight, corners.TopRight, chunkSize),
             FindChunksAlongLine(corners.BottomLeft, corners.BottomRight, chunkSize),
@@ -75,13 +75,13 @@ public static class OperationHelper
         return FillLines(lines);
     }
 
-    public static HashSet<Vector2i> FindChunksFullyInsideQuadrilateral(ShapeCorners corners, int chunkSize)
+    public static HashSet<VecI> FindChunksFullyInsideQuadrilateral(ShapeCorners corners, int chunkSize)
     {
         if (corners.HasNaNOrInfinity ||
             (corners.BottomLeft - corners.TopRight).Length > chunkSize * 40 * 20 ||
             (corners.TopLeft - corners.BottomRight).Length > chunkSize * 40 * 20)
-            return new HashSet<Vector2i>();
-        List<Vector2i>[] lines = new List<Vector2i>[] {
+            return new HashSet<VecI>();
+        List<VecI>[] lines = new List<VecI>[] {
             FindChunksAlongLine(corners.TopLeft, corners.TopRight, chunkSize),
             FindChunksAlongLine(corners.TopRight, corners.BottomRight, chunkSize),
             FindChunksAlongLine(corners.BottomRight, corners.BottomLeft, chunkSize),
@@ -102,32 +102,32 @@ public static class OperationHelper
     /// <summary>
     /// Finds chunks that at least partially lie inside of a rectangle
     /// </summary>
-    public static HashSet<Vector2i> FindChunksTouchingRectangle(Vector2d center, Vector2d size, double angle, int chunkSize)
+    public static HashSet<VecI> FindChunksTouchingRectangle(VecD center, VecD size, double angle, int chunkSize)
     {
         if (size.X == 0 || size.Y == 0 || center.IsNaNOrInfinity() || size.IsNaNOrInfinity() || double.IsNaN(angle) || double.IsInfinity(angle))
-            return new HashSet<Vector2i>();
+            return new HashSet<VecI>();
         if (size.X > chunkSize * 40 * 20 || size.Y > chunkSize * 40 * 20)
-            return new HashSet<Vector2i>();
+            return new HashSet<VecI>();
         // draw a line on the outside of each side
         var corners = FindRectangleCorners(center, size, angle);
-        List<Vector2i>[] lines = new List<Vector2i>[] {
+        List<VecI>[] lines = new List<VecI>[] {
             FindChunksAlongLine(corners.Item2, corners.Item1, chunkSize),
             FindChunksAlongLine(corners.Item3, corners.Item2, chunkSize),
             FindChunksAlongLine(corners.Item4, corners.Item3, chunkSize),
             FindChunksAlongLine(corners.Item1, corners.Item4, chunkSize)
         };
         if (lines[0].Count == 0 || lines[1].Count == 0 || lines[2].Count == 0 || lines[3].Count == 0)
-            return new HashSet<Vector2i>();
+            return new HashSet<VecI>();
         return FillLines(lines);
     }
 
-    public static HashSet<Vector2i> FillLines(List<Vector2i>[] lines)
+    public static HashSet<VecI> FillLines(List<VecI>[] lines)
     {
         if (lines.Length == 0)
-            return new HashSet<Vector2i>();
+            return new HashSet<VecI>();
 
         //find min and max X for each Y in lines
-        var ySel = (Vector2i vec) => vec.Y;
+        var ySel = (VecI vec) => vec.Y;
         int minY = int.MaxValue;
         int maxY = int.MinValue;
         foreach (var line in lines)
@@ -151,7 +151,7 @@ public static class OperationHelper
         }
 
         //draw a line from min X to max X for each Y
-        HashSet<Vector2i> output = new();
+        HashSet<VecI> output = new();
         for (int i = 0; i < minXValues.Length; i++)
         {
             int minX = minXValues[i];
@@ -163,32 +163,32 @@ public static class OperationHelper
         return output;
     }
 
-    public static HashSet<Vector2i> FindChunksFullyInsideRectangle(Vector2i pos, Vector2i size, int chunkSize)
+    public static HashSet<VecI> FindChunksFullyInsideRectangle(VecI pos, VecI size, int chunkSize)
     {
         if (size.X > chunkSize * 40 * 20 || size.Y > chunkSize * 40 * 20)
-            return new HashSet<Vector2i>();
-        Vector2i startChunk = GetChunkPos(pos, ChunkPool.FullChunkSize);
-        Vector2i endChunk = GetChunkPosBiased(pos + size, false, false, chunkSize);
-        HashSet<Vector2i> output = new();
+            return new HashSet<VecI>();
+        VecI startChunk = GetChunkPos(pos, ChunkPool.FullChunkSize);
+        VecI endChunk = GetChunkPosBiased(pos + size, false, false, chunkSize);
+        HashSet<VecI> output = new();
         for (int x = startChunk.X; x <= endChunk.X; x++)
         {
             for (int y = startChunk.Y; y <= endChunk.Y; y++)
             {
-                output.Add(new Vector2i(x, y));
+                output.Add(new VecI(x, y));
             }
         }
         return output;
     }
 
-    public static HashSet<Vector2i> FindChunksFullyInsideRectangle(Vector2d center, Vector2d size, double angle, int chunkSize)
+    public static HashSet<VecI> FindChunksFullyInsideRectangle(VecD center, VecD size, double angle, int chunkSize)
     {
         if (size.X < chunkSize || size.Y < chunkSize || center.IsNaNOrInfinity() || size.IsNaNOrInfinity() || double.IsNaN(angle) || double.IsInfinity(angle))
-            return new HashSet<Vector2i>();
+            return new HashSet<VecI>();
         if (size.X > chunkSize * 40 * 20 || size.Y > chunkSize * 40 * 20)
-            return new HashSet<Vector2i>();
+            return new HashSet<VecI>();
         // draw a line on the inside of each side
         var corners = FindRectangleCorners(center, size, angle);
-        List<Vector2i>[] lines = new List<Vector2i>[] {
+        List<VecI>[] lines = new List<VecI>[] {
             FindChunksAlongLine(corners.Item1, corners.Item2, chunkSize),
             FindChunksAlongLine(corners.Item2, corners.Item3, chunkSize),
             FindChunksAlongLine(corners.Item3, corners.Item4, chunkSize),
@@ -206,7 +206,7 @@ public static class OperationHelper
         return output;
     }
 
-    private static void UpdateMinXValues(List<Vector2i> line, int[] minXValues, int minY)
+    private static void UpdateMinXValues(List<VecI> line, int[] minXValues, int minY)
     {
         for (int i = 0; i < line.Count; i++)
         {
@@ -215,7 +215,7 @@ public static class OperationHelper
         }
     }
 
-    private static void UpdateMaxXValues(List<Vector2i> line, int[] maxXValues, int minY)
+    private static void UpdateMaxXValues(List<VecI> line, int[] maxXValues, int minY)
     {
         for (int i = 0; i < line.Count; i++)
         {
@@ -230,10 +230,10 @@ public static class OperationHelper
     /// This ensures that when you draw a filled shape all updated chunks will be covered (the filled part should go to the right of the line)
     /// No parts of the line will stick out to the left and be left uncovered
     /// </summary>
-    public static List<Vector2i> FindChunksAlongLine(Vector2d p1, Vector2d p2, int chunkSize)
+    public static List<VecI> FindChunksAlongLine(VecD p1, VecD p2, int chunkSize)
     {
         if (p1 == p2 || p1.IsNaNOrInfinity() || p2.IsNaNOrInfinity())
-            return new List<Vector2i>();
+            return new List<VecI>();
 
         //rotate the line into the first quadrant of the coordinate plane
         int quadrant;
@@ -260,14 +260,14 @@ public static class OperationHelper
             (p2.X, p2.Y) = (-p2.Y, p2.X);
         }
 
-        List<Vector2i> output = new();
+        List<VecI> output = new();
         //vertical line
         if (p1.X == p2.X)
         {
             //if exactly on a chunk boundary, pick the chunk on the top-left
-            Vector2i start = GetChunkPosBiased(p1, false, true, chunkSize);
+            VecI start = GetChunkPosBiased(p1, false, true, chunkSize);
             //if exactly on chunk boundary, pick the chunk on the bottom-left
-            Vector2i end = GetChunkPosBiased(p2, false, false, chunkSize);
+            VecI end = GetChunkPosBiased(p2, false, false, chunkSize);
             for (int y = start.Y; y <= end.Y; y++)
                 output.Add(new(start.X, y));
         }
@@ -275,9 +275,9 @@ public static class OperationHelper
         else if (p1.Y == p2.Y)
         {
             //if exactly on a chunk boundary, pick the chunk on the top-right
-            Vector2i start = GetChunkPosBiased(p1, true, true, chunkSize);
+            VecI start = GetChunkPosBiased(p1, true, true, chunkSize);
             //if exactly on chunk boundary, pick the chunk on the top-left
-            Vector2i end = GetChunkPosBiased(p2, false, true, chunkSize);
+            VecI end = GetChunkPosBiased(p2, false, true, chunkSize);
             for (int x = start.X; x <= end.X; x++)
                 output.Add(new(x, start.Y));
         }
@@ -287,11 +287,11 @@ public static class OperationHelper
             //y = mx + b
             double m = (p2.Y - p1.Y) / (p2.X - p1.X);
             double b = p1.Y - (p1.X * m);
-            Vector2i cur = GetChunkPosBiased(p1, true, true, chunkSize);
+            VecI cur = GetChunkPosBiased(p1, true, true, chunkSize);
             output.Add(cur);
             if (LineEq(m, cur.X * chunkSize + chunkSize, b) > cur.Y * chunkSize + chunkSize)
                 cur.X--;
-            Vector2i end = GetChunkPosBiased(p2, false, false, chunkSize);
+            VecI end = GetChunkPosBiased(p2, false, false, chunkSize);
             if (m < 1)
             {
                 while (true)
@@ -357,10 +357,10 @@ public static class OperationHelper
         return m * x + b;
     }
 
-    public static Vector2i GetChunkPosBiased(Vector2d pos, bool positiveX, bool positiveY, int chunkSize)
+    public static VecI GetChunkPosBiased(VecD pos, bool positiveX, bool positiveY, int chunkSize)
     {
         pos /= chunkSize;
-        return new Vector2i()
+        return new VecI()
         {
             X = positiveX ? (int)Math.Floor(pos.X) : (int)Math.Ceiling(pos.X) - 1,
             Y = positiveY ? (int)Math.Floor(pos.Y) : (int)Math.Ceiling(pos.Y) - 1,
@@ -370,10 +370,10 @@ public static class OperationHelper
     /// <summary>
     /// Returns corners in ccw direction (assuming y points up)
     /// </summary>
-    private static (Vector2d, Vector2d, Vector2d, Vector2d) FindRectangleCorners(Vector2d center, Vector2d size, double angle)
+    private static (VecD, VecD, VecD, VecD) FindRectangleCorners(VecD center, VecD size, double angle)
     {
-        Vector2d right = Vector2d.FromAngleAndLength(angle, size.X / 2);
-        Vector2d up = Vector2d.FromAngleAndLength(angle + Math.PI / 2, size.Y / 2);
+        VecD right = VecD.FromAngleAndLength(angle, size.X / 2);
+        VecD up = VecD.FromAngleAndLength(angle + Math.PI / 2, size.Y / 2);
         return (
             center + right + up,
             center - right + up,

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

@@ -14,7 +14,7 @@ internal class RectangleOperation : IDrawOperation
 
     public bool IgnoreEmptyChunks => false;
 
-    public void DrawOnChunk(Chunk chunk, Vector2i chunkPos)
+    public void DrawOnChunk(Chunk chunk, VecI chunkPos)
     {
         var skiaSurf = chunk.Surface.SkiaSurface;
         // use a clipping rectangle with 2x stroke width to make sure stroke doesn't stick outside rect bounds
@@ -54,7 +54,7 @@ internal class RectangleOperation : IDrawOperation
         skiaSurf.Canvas.Restore();
     }
 
-    public HashSet<Vector2i> FindAffectedChunks()
+    public HashSet<VecI> FindAffectedChunks()
     {
         if (Math.Abs(Data.Size.X) < 1 || Math.Abs(Data.Size.Y) < 1 || Data.StrokeColor.Alpha == 0 && Data.FillColor.Alpha == 0)
             return new();
@@ -65,7 +65,7 @@ internal class RectangleOperation : IDrawOperation
         chunks.ExceptWith(
             OperationHelper.FindChunksFullyInsideRectangle(
                 Data.Center,
-                Data.Size.Abs() - new Vector2d(Data.StrokeWidth * 2, Data.StrokeWidth * 2),
+                Data.Size.Abs() - new VecD(Data.StrokeWidth * 2, Data.StrokeWidth * 2),
                 Data.Angle,
                 ChunkPool.FullChunkSize));
         return chunks;

+ 2 - 2
src/ChunkyImageLib/Operations/ResizeOperation.cs

@@ -4,8 +4,8 @@ namespace ChunkyImageLib.Operations;
 
 internal record class ResizeOperation : IOperation
 {
-    public Vector2i Size { get; }
-    public ResizeOperation(Vector2i size)
+    public VecI Size { get; }
+    public ResizeOperation(VecI size)
     {
         Size = size;
     }

+ 3 - 3
src/ChunkyImageLib/Surface.cs

@@ -11,9 +11,9 @@ public class Surface : IDisposable
     private int bytesPerPixel;
     public IntPtr PixelBuffer { get; }
     public SKSurface SkiaSurface { get; }
-    public Vector2i Size { get; }
+    public VecI Size { get; }
 
-    public Surface(Vector2i size)
+    public Surface(VecI size)
     {
         if (size.X < 1 || size.Y < 1)
             throw new ArgumentException("Width and height must be >1");
@@ -39,7 +39,7 @@ public class Surface : IDisposable
         using var bitmap = SKBitmap.Decode(path);
         if (bitmap is null)
             throw new ArgumentException($"The image with path {path} couldn't be loaded");
-        var surface = new Surface(new Vector2i(bitmap.Width, bitmap.Height));
+        var surface = new Surface(new VecI(bitmap.Width, bitmap.Height));
         surface.SkiaSurface.Canvas.DrawBitmap(bitmap, 0, 0);
         return surface;
     }

+ 2 - 2
src/ChunkyImageLibTest/ClearRegionOperationTests.cs

@@ -13,7 +13,7 @@ public class ClearRegionOperationTests
     public void FindAffectedChunks_SingleChunk_ReturnsSingleChunk()
     {
         ClearRegionOperation operation = new(new(chunkSize, chunkSize), new(chunkSize, chunkSize));
-        var expected = new HashSet<Vector2i>() { new(1, 1) };
+        var expected = new HashSet<VecI>() { new(1, 1) };
         var actual = operation.FindAffectedChunks();
         Assert.Equal(expected, actual);
     }
@@ -26,7 +26,7 @@ public class ClearRegionOperationTests
         int from = -chunkSize - chunkSize / 2;
         int to = chunkSize + chunkSize / 2;
         ClearRegionOperation operation = new(new(from, from), new(to - from, to - from));
-        var expected = new HashSet<Vector2i>() 
+        var expected = new HashSet<VecI>() 
         { 
             new(-2, -2), new(-1, -2), new(0, -2), new(1, -2),
             new(-2, -1), new(-1, -1), new(0, -1), new(1, -1),

+ 2 - 2
src/ChunkyImageLibTest/OperationHelperTests.cs

@@ -14,7 +14,7 @@ public class OperationHelperTests
     [InlineData(-33, -33, -2, -2)]
     public void GetChunkPos_32ChunkSize_ReturnsCorrectValues(int x, int y, int expX, int expY)
     {
-        Vector2i act = OperationHelper.GetChunkPos(new(x, y), 32);
+        VecI act = OperationHelper.GetChunkPos(new(x, y), 32);
         Assert.Equal(expX, act.X);
         Assert.Equal(expY, act.Y);
     }
@@ -30,7 +30,7 @@ public class OperationHelperTests
     [InlineData(48.5, 48.5, false, false, 1, 1)]
     public void GetChunkPosBiased_32ChunkSize_ReturnsCorrectValues(double x, double y, bool positiveX, bool positiveY, int expX, int expY)
     {
-        Vector2i act = OperationHelper.GetChunkPosBiased(new(x, y), positiveX, positiveY, 32);
+        VecI act = OperationHelper.GetChunkPosBiased(new(x, y), positiveX, positiveY, 32);
         Assert.Equal(expX, act.X);
         Assert.Equal(expY, act.Y);
     }

+ 7 - 7
src/ChunkyImageLibTest/RectangleOperationTests.cs

@@ -18,7 +18,7 @@ public class RectangleOperationTests
         var (x, y, w, h) = (0, 0, chunkSize, chunkSize);
         RectangleOperation operation = new(new(new(x, y), new(w, h), 1, SKColors.Black, SKColors.Transparent));
 
-        HashSet<Vector2i> expected = new() { new(0, 0) };
+        HashSet<VecI> expected = new() { new(0, 0) };
         var actual = operation.FindAffectedChunks();
 
         Assert.Equal(expected, actual);
@@ -30,7 +30,7 @@ public class RectangleOperationTests
         var (x, y, w, h) = (-chunkSize, -chunkSize, chunkSize * 2, chunkSize * 2);
         RectangleOperation operation = new(new(new(x, y), new(w, h), 1, SKColors.Black, SKColors.Transparent));
 
-        HashSet<Vector2i> expected = new() { new(-1, -1), new(0, -1), new(-1, 0), new(0, 0) };
+        HashSet<VecI> expected = new() { new(-1, -1), new(0, -1), new(-1, 0), new(0, 0) };
         var actual = operation.FindAffectedChunks();
 
         Assert.Equal(expected, actual);
@@ -42,7 +42,7 @@ public class RectangleOperationTests
         var (x, y, w, h) = (chunkSize + chunkSize / 2, chunkSize + chunkSize / 2, chunkSize * 2, chunkSize * 2);
         RectangleOperation operation = new(new(new(x, y), new(w, h), 1, SKColors.Black, SKColors.Transparent));
 
-        HashSet<Vector2i> expected = new()
+        HashSet<VecI> expected = new()
         {
             new(1, 1), new(2, 1), new(3, 1),
             new(1, 2),            new(3, 2),
@@ -59,7 +59,7 @@ public class RectangleOperationTests
         var (x, y, w, h) = (-chunkSize * 3 - chunkSize / 2, -chunkSize * 3 - chunkSize / 2, chunkSize * 2, chunkSize * 2);
         RectangleOperation operation = new(new(new(x, y), new(w, h), 1, SKColors.Black, SKColors.Transparent));
 
-        HashSet<Vector2i> expected = new()
+        HashSet<VecI> expected = new()
         {
             new(-4, -4), new(-3, -4), new(-2, -4),
             new(-4, -3),              new(-2, -3),
@@ -76,7 +76,7 @@ public class RectangleOperationTests
         var (x, y, w, h) = (chunkSize + chunkSize / 2, chunkSize + chunkSize / 2, chunkSize * 2, chunkSize * 2);
         RectangleOperation operation = new(new(new(x, y), new(w, h), 1, SKColors.Black, SKColors.White));
 
-        HashSet<Vector2i> expected = new()
+        HashSet<VecI> expected = new()
         {
             new(1, 1), new(2, 1), new(3, 1), 
             new(1, 2), new(2, 2), new(3, 2),
@@ -93,7 +93,7 @@ public class RectangleOperationTests
         var (x, y, w, h) = (chunkSize / 2, chunkSize / 2, chunkSize * 4, chunkSize * 4);
         RectangleOperation operation = new(new(new(x, y), new(w, h), chunkSize, SKColors.Black, SKColors.Transparent));
 
-        HashSet<Vector2i> expected = new()
+        HashSet<VecI> expected = new()
         {
             new(0, 0), new(1, 0), new(2, 0), new(3, 0), new(4, 0),
             new(0, 1), new(1, 1), new(2, 1), new(3, 1), new(4, 1),
@@ -112,7 +112,7 @@ public class RectangleOperationTests
         var (x, y, w, h) = (chunkSize / 2, chunkSize / 2, 1, 1);
         RectangleOperation operation = new(new(new(x, y), new(w, h), 256, SKColors.Black, SKColors.White));
 
-        HashSet<Vector2i> expected = new() { new(0, 0) };
+        HashSet<VecI> expected = new() { new(0, 0) };
         var actual = operation.FindAffectedChunks();
 
         Assert.Equal(expected, actual);

+ 4 - 4
src/ChunkyImageLibVis/MainWindow.xaml.cs

@@ -126,8 +126,8 @@ public partial class MainWindow : Window, INotifyPropertyChanged
             canvas.Children.Remove(rect);
         }
         rectangles.Clear();
-        var chunks = OperationHelper.FindChunksTouchingRectangle(new Vector2d(X1 + HalfRectWidth, Y1 + HalfRectHeight), new(X2 - X1, Y2 - Y1), Angle * Math.PI / 180, 32);
-        var innerChunks = OperationHelper.FindChunksFullyInsideRectangle(new Vector2d(X1 + HalfRectWidth, Y1 + HalfRectHeight), new(X2 - X1, Y2 - Y1), Angle * Math.PI / 180, 32);
+        var chunks = OperationHelper.FindChunksTouchingRectangle(new VecD(X1 + HalfRectWidth, Y1 + HalfRectHeight), new(X2 - X1, Y2 - Y1), Angle * Math.PI / 180, 32);
+        var innerChunks = OperationHelper.FindChunksFullyInsideRectangle(new VecD(X1 + HalfRectWidth, Y1 + HalfRectHeight), new(X2 - X1, Y2 - Y1), Angle * Math.PI / 180, 32);
         chunks.ExceptWith(innerChunks);
         foreach (var chunk in chunks)
         {
@@ -188,8 +188,8 @@ public partial class MainWindow : Window, INotifyPropertyChanged
         }
         else if (rotating)
         {
-            Vector2d center = new Vector2d(X1 + HalfRectWidth, Y1 + HalfRectHeight);
-            Angle = new Vector2d(pos.X - center.X, pos.Y - center.Y).CCWAngleTo(new Vector2d(X2 - center.X, Y2 - center.Y)) * -180 / Math.PI;
+            VecD center = new VecD(X1 + HalfRectWidth, Y1 + HalfRectHeight);
+            Angle = new VecD(pos.X - center.X, pos.Y - center.Y).CCWAngleTo(new VecD(X2 - center.X, Y2 - center.Y)) * -180 / Math.PI;
         }
         UpdateChunks();
     }

+ 3 - 3
src/PixiEditor.ChangeableDocument/Actions/Drawing/Selection/SelectRectangle_Action.cs

@@ -6,9 +6,9 @@ namespace PixiEditor.ChangeableDocument.Actions.Drawing.Selection;
 
 public record class SelectRectangle_Action : IStartOrUpdateChangeAction
 {
-    public Vector2i Pos { get; }
-    public Vector2i Size { get; }
-    public SelectRectangle_Action(Vector2i pos, Vector2i size)
+    public VecI Pos { get; }
+    public VecI Size { get; }
+    public SelectRectangle_Action(VecI pos, VecI size)
     {
         Pos = pos;
         Size = size;

+ 2 - 2
src/PixiEditor.ChangeableDocument/Actions/Root/ResizeCanvas_Action.cs

@@ -6,8 +6,8 @@ namespace PixiEditor.ChangeableDocument.Actions.Root;
 
 public record class ResizeCanvas_Action : IMakeChangeAction
 {
-    public Vector2i Size { get; }
-    public ResizeCanvas_Action(Vector2i size)
+    public VecI Size { get; }
+    public ResizeCanvas_Action(VecI size)
     {
         Size = size;
     }

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

@@ -5,5 +5,5 @@ namespace PixiEditor.ChangeableDocument.ChangeInfos.Drawing;
 public record class LayerImageChunks_ChangeInfo : IChangeInfo
 {
     public Guid LayerGuid { get; init; }
-    public HashSet<Vector2i>? Chunks { get; init; }
+    public HashSet<VecI>? Chunks { get; init; }
 }

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

@@ -5,5 +5,5 @@ namespace PixiEditor.ChangeableDocument.ChangeInfos.Drawing;
 public record class MaskChunks_ChangeInfo : IChangeInfo
 {
     public Guid MemberGuid { get; init; }
-    public HashSet<Vector2i>? Chunks { get; init; }
+    public HashSet<VecI>? Chunks { get; init; }
 }

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

@@ -4,5 +4,5 @@ namespace PixiEditor.ChangeableDocument.ChangeInfos.Drawing;
 
 public record class Selection_ChangeInfo : IChangeInfo
 {
-    public HashSet<Vector2i>? Chunks { get; init; }
+    public HashSet<VecI>? Chunks { get; init; }
 }

+ 2 - 2
src/PixiEditor.ChangeableDocument/Changeables/Document.cs

@@ -12,10 +12,10 @@ internal class Document : IChangeable, IReadOnlyDocument, IDisposable
     IReadOnlyStructureMember IReadOnlyDocument.FindMemberOrThrow(Guid guid) => FindMemberOrThrow(guid);
     (IReadOnlyStructureMember, IReadOnlyFolder) IReadOnlyDocument.FindChildAndParentOrThrow(Guid guid) => FindChildAndParentOrThrow(guid);
 
-    public static Vector2i DefaultSize { get; } = new Vector2i(64, 64);
+    public static VecI DefaultSize { get; } = new VecI(64, 64);
     internal Folder StructureRoot { get; } = new() { GuidValue = Guid.Empty };
     internal Selection Selection { get; } = new();
-    public Vector2i Size { get; set; } = DefaultSize;
+    public VecI Size { get; set; } = DefaultSize;
     public bool HorizontalSymmetryAxisEnabled { get; set; }
     public bool VerticalSymmetryAxisEnabled { get; set; }
     public int HorizontalSymmetryAxisY { get; set; }

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

@@ -6,7 +6,7 @@ public interface IReadOnlyDocument
 {
     IReadOnlyFolder ReadOnlyStructureRoot { get; }
     IReadOnlySelection ReadOnlySelection { get; }
-    Vector2i Size { get; }
+    VecI Size { get; }
     bool HorizontalSymmetryAxisEnabled { get; }
     bool VerticalSymmetryAxisEnabled { get; }
     int HorizontalSymmetryAxisY { get; }

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

@@ -10,7 +10,7 @@ internal class Layer : StructureMember, IReadOnlyLayer
     public ChunkyImage LayerImage { get; set; }
     IReadOnlyChunkyImage IReadOnlyLayer.ReadOnlyLayerImage => LayerImage;
 
-    public Layer(Vector2i size)
+    public Layer(VecI size)
     {
         LayerImage = new(size);
     }

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

@@ -31,7 +31,7 @@ internal class ClearSelection_Change : Change
 
         target.Selection.SelectionImage.CancelChanges();
         target.Selection.SelectionImage.EnqueueClear();
-        HashSet<Vector2i> affChunks = target.Selection.SelectionImage.FindAffectedChunks();
+        HashSet<VecI> affChunks = target.Selection.SelectionImage.FindAffectedChunks();
         target.Selection.SelectionImage.CommitChanges();
 
         target.Selection.SelectionPath.Dispose();
@@ -49,7 +49,7 @@ internal class ClearSelection_Change : Change
 
         target.Selection.SelectionImage.CancelChanges();
         savedSelection!.ApplyChunksToImage(target.Selection.SelectionImage);
-        HashSet<Vector2i> affChunks = target.Selection.SelectionImage.FindAffectedChunks();
+        HashSet<VecI> affChunks = target.Selection.SelectionImage.FindAffectedChunks();
         target.Selection.SelectionImage.CommitChanges();
 
         target.Selection.SelectionPath.Dispose();

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

@@ -49,7 +49,7 @@ internal class CombineStructureMembersOnto_Change : Change
     {
         Layer toDrawOn = (Layer)target.FindMemberOrThrow(targetLayer);
 
-        var chunksToCombine = new HashSet<Vector2i>();
+        var chunksToCombine = new HashSet<VecI>();
         foreach (var guid in layersToCombine)
         {
             var layer = (Layer)target.FindMemberOrThrow(guid);

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

@@ -23,7 +23,7 @@ internal class DrawRectangle_UpdateableChange : UpdateableChange
         rect = updatedRectangle;
     }
 
-    private HashSet<Vector2i> UpdateRectangle(Document target, ChunkyImage targetImage)
+    private HashSet<VecI> UpdateRectangle(Document target, ChunkyImage targetImage)
     {
         var oldAffectedChunks = targetImage.FindAffectedChunks();
         targetImage.CancelChanges();

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

@@ -23,7 +23,7 @@ internal static class DrawingChangeHelper
         return ((Layer)member).LayerImage;
     }
 
-    public static IChangeInfo CreateChunkChangeInfo(Guid memberGuid, HashSet<Vector2i> affectedChunks, bool drawOnMask)
+    public static IChangeInfo CreateChunkChangeInfo(Guid memberGuid, HashSet<VecI> affectedChunks, bool drawOnMask)
     {
         return drawOnMask switch
         {

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

@@ -27,7 +27,7 @@ internal class PasteImage_UpdateableChange : UpdateableChange
         corners = newCorners;
     }
 
-    private HashSet<Vector2i> DrawImage(ChunkyImage targetImage)
+    private HashSet<VecI> DrawImage(ChunkyImage targetImage)
     {
         var prevChunks = targetImage.FindAffectedChunks();
 

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

@@ -10,11 +10,11 @@ namespace PixiEditor.ChangeableDocument.Changes.Drawing;
 internal class SelectRectangle_UpdateableChange : UpdateableChange
 {
     private bool originalIsEmpty;
-    private Vector2i pos;
-    private Vector2i size;
+    private VecI pos;
+    private VecI size;
     private CommittedChunkStorage? originalSelectionState;
     private SKPath? originalPath;
-    public SelectRectangle_UpdateableChange(Vector2i pos, Vector2i size)
+    public SelectRectangle_UpdateableChange(VecI pos, VecI size)
     {
         Update(pos, size);
     }
@@ -24,7 +24,7 @@ internal class SelectRectangle_UpdateableChange : UpdateableChange
         originalPath = new SKPath(target.Selection.SelectionPath);
     }
 
-    public void Update(Vector2i pos, Vector2i size)
+    public void Update(VecI pos, VecI size)
     {
         this.pos = pos;
         this.size = size;

+ 3 - 3
src/PixiEditor.ChangeableDocument/Changes/Root/ResizeCanvas_Change.cs

@@ -8,14 +8,14 @@ namespace PixiEditor.ChangeableDocument.Changes.Root;
 
 internal class ResizeCanvas_Change : Change
 {
-    private Vector2i originalSize;
+    private VecI originalSize;
     private int originalHorAxisY;
     private int originalVerAxisX;
     private Dictionary<Guid, CommittedChunkStorage> deletedChunks = new();
     private Dictionary<Guid, CommittedChunkStorage> deletedMaskChunks = new();
     private CommittedChunkStorage? selectionChunkStorage;
-    private Vector2i newSize;
-    public ResizeCanvas_Change(Vector2i size)
+    private VecI newSize;
+    public ResizeCanvas_Change(VecI size)
     {
         newSize = size;
     }

+ 3 - 3
src/PixiEditor.ChangeableDocument/Rendering/ChunkRenderer.cs

@@ -11,12 +11,12 @@ public static class ChunkRenderer
     private static SKPaint PaintToDrawChunksWith = new SKPaint() { BlendMode = SKBlendMode.SrcOver };
     private static SKPaint ReplacingPaint = new SKPaint() { BlendMode = SKBlendMode.Src };
     private static SKPaint ClippingPaint = new SKPaint() { BlendMode = SKBlendMode.DstIn };
-    public static Chunk RenderWholeStructure(Vector2i pos, ChunkResolution resolution, IReadOnlyFolder root)
+    public static Chunk RenderWholeStructure(VecI pos, ChunkResolution resolution, IReadOnlyFolder root)
     {
         return RenderChunkRecursively(pos, resolution, 0, root, null);
     }
 
-    public static Chunk RenderSpecificLayers(Vector2i pos, ChunkResolution resolution, IReadOnlyFolder root, HashSet<Guid> layers)
+    public static Chunk RenderSpecificLayers(VecI pos, ChunkResolution resolution, IReadOnlyFolder root, HashSet<Guid> layers)
     {
         return RenderChunkRecursively(pos, resolution, 0, root, layers);
     }
@@ -46,7 +46,7 @@ public static class ChunkRenderer
         };
     }
 
-    private static Chunk RenderChunkRecursively(Vector2i chunkPos, ChunkResolution resolution, int depth, IReadOnlyFolder folder, HashSet<Guid>? visibleLayers)
+    private static Chunk RenderChunkRecursively(VecI chunkPos, ChunkResolution resolution, int depth, IReadOnlyFolder folder, HashSet<Guid>? visibleLayers)
     {
         Chunk targetChunk = Chunk.Create(resolution);
         targetChunk.Surface.SkiaSurface.Canvas.Clear();

+ 5 - 5
src/PixiEditor.Zoombox/MoveDragOperation.cs

@@ -1,12 +1,12 @@
-using ChunkyImageLib.DataHolders;
-using System.Windows.Input;
+using System.Windows.Input;
+using ChunkyImageLib.DataHolders;
 
 namespace PixiEditor.Zoombox;
 
 internal class MoveDragOperation : IDragOperation
 {
     private Zoombox parent;
-    private Vector2d prevMousePos;
+    private VecD prevMousePos;
 
     public MoveDragOperation(Zoombox zoomBox)
     {
@@ -14,13 +14,13 @@ internal class MoveDragOperation : IDragOperation
     }
     public void Start(MouseButtonEventArgs e)
     {
-        prevMousePos = Zoombox.ToVector2d(e.GetPosition(parent.mainCanvas));
+        prevMousePos = Zoombox.ToVecD(e.GetPosition(parent.mainCanvas));
         parent.mainCanvas.CaptureMouse();
     }
 
     public void Update(MouseEventArgs e)
     {
-        var curMousePos = Zoombox.ToVector2d(e.GetPosition(parent.mainCanvas));
+        var curMousePos = Zoombox.ToVecD(e.GetPosition(parent.mainCanvas));
         parent.Center += parent.ToZoomboxSpace(prevMousePos) - parent.ToZoomboxSpace(curMousePos);
         prevMousePos = curMousePos;
     }

+ 2 - 2
src/PixiEditor.Zoombox/RotateDragOperation.cs

@@ -22,9 +22,9 @@ internal class RotateDragOperation : IDragOperation
         parent.mainCanvas.CaptureMouse();
     }
 
-    private double GetAngle(Vector2d point)
+    private double GetAngle(VecD point)
     {
-        Vector2d center = new(parent.mainCanvas.ActualWidth / 2, parent.mainCanvas.ActualHeight / 2);
+        VecD center = new(parent.mainCanvas.ActualWidth / 2, parent.mainCanvas.ActualHeight / 2);
         double angle = (point - center).Angle;
         if (double.IsNaN(angle) || double.IsInfinity(angle))
             return 0;

+ 4 - 4
src/PixiEditor.Zoombox/ViewportRoutedEventArgs.cs

@@ -5,7 +5,7 @@ namespace PixiEditor.Zoombox;
 
 public class ViewportRoutedEventArgs : RoutedEventArgs
 {
-    public ViewportRoutedEventArgs(RoutedEvent e, Vector2d center, Vector2d size, Vector2d realSize, double angle) : base(e)
+    public ViewportRoutedEventArgs(RoutedEvent e, VecD center, VecD size, VecD realSize, double angle) : base(e)
     {
         Center = center;
         Size = size;
@@ -13,8 +13,8 @@ public class ViewportRoutedEventArgs : RoutedEventArgs
         Angle = angle;
     }
 
-    public Vector2d Center { get; }
-    public Vector2d Size { get; }
-    public Vector2d RealSize { get; }
+    public VecD Center { get; }
+    public VecD Size { get; }
+    public VecD RealSize { get; }
     public double Angle { get; }
 }

+ 3 - 3
src/PixiEditor.Zoombox/ZoomDragOperation.cs

@@ -10,8 +10,8 @@ internal class ZoomDragOperation : IDragOperation
 
     private double initScale;
 
-    private Vector2d scaleOrigin;
-    private Vector2d screenScaleOrigin;
+    private VecD scaleOrigin;
+    private VecD screenScaleOrigin;
 
     public ZoomDragOperation(Zoombox zoomBox)
     {
@@ -19,7 +19,7 @@ internal class ZoomDragOperation : IDragOperation
     }
     public void Start(MouseButtonEventArgs e)
     {
-        screenScaleOrigin = parent.ToZoomboxSpace(Zoombox.ToVector2d(e.GetPosition(parent.mainCanvas)));
+        screenScaleOrigin = parent.ToZoomboxSpace(Zoombox.ToVecD(e.GetPosition(parent.mainCanvas)));
         scaleOrigin = parent.ToZoomboxSpace(screenScaleOrigin);
         initScale = parent.Scale;
         parent.mainCanvas.CaptureMouse();

+ 30 - 30
src/PixiEditor.Zoombox/Zoombox.xaml.cs

@@ -31,13 +31,13 @@ public partial class Zoombox : ContentControl, INotifyPropertyChanged
         DependencyProperty.Register(nameof(Scale), typeof(double), typeof(Zoombox), new(1.0, OnPropertyChange));
 
     public static readonly DependencyProperty CenterProperty =
-        DependencyProperty.Register(nameof(Center), typeof(Vector2d), typeof(Zoombox), new(new Vector2d(0, 0), OnPropertyChange));
+        DependencyProperty.Register(nameof(Center), typeof(VecD), typeof(Zoombox), new(new VecD(0, 0), OnPropertyChange));
 
     public static readonly DependencyProperty DimensionsProperty =
-        DependencyProperty.Register(nameof(Dimensions), typeof(Vector2d), typeof(Zoombox));
+        DependencyProperty.Register(nameof(Dimensions), typeof(VecD), typeof(Zoombox));
 
     public static readonly DependencyProperty RealDimensionsProperty =
-        DependencyProperty.Register(nameof(RealDimensions), typeof(Vector2d), typeof(Zoombox));
+        DependencyProperty.Register(nameof(RealDimensions), typeof(VecD), typeof(Zoombox));
 
     public static readonly DependencyProperty AngleProperty =
         DependencyProperty.Register(nameof(Angle), typeof(double), typeof(Zoombox), new(0.0, OnPropertyChange));
@@ -98,21 +98,21 @@ public partial class Zoombox : ContentControl, INotifyPropertyChanged
         set => SetValue(AngleProperty, value);
     }
 
-    public Vector2d Center
+    public VecD Center
     {
-        get => (Vector2d)GetValue(CenterProperty);
+        get => (VecD)GetValue(CenterProperty);
         set => SetValue(CenterProperty, value);
     }
 
-    public Vector2d Dimensions
+    public VecD Dimensions
     {
-        get => (Vector2d)GetValue(DimensionsProperty);
+        get => (VecD)GetValue(DimensionsProperty);
         set => SetValue(DimensionsProperty, value);
     }
 
-    public Vector2d RealDimensions
+    public VecD RealDimensions
     {
-        get => (Vector2d)GetValue(RealDimensionsProperty);
+        get => (VecD)GetValue(RealDimensionsProperty);
         set => SetValue(RealDimensionsProperty, value);
     }
 
@@ -145,21 +145,21 @@ public partial class Zoombox : ContentControl, INotifyPropertyChanged
 
     private double[] roundZoomValues = new double[] { .01, .02, .03, .04, .05, .06, .07, .08, .1, .13, .17, .2, .25, .33, .5, .67, 1, 1.5, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64 };
 
-    internal Vector2d ToScreenSpace(Vector2d p)
+    internal VecD ToScreenSpace(VecD p)
     {
-        Vector2d delta = p - Center;
+        VecD delta = p - Center;
         delta = delta.Rotate(Angle) * Scale;
         if (FlipX)
             delta.X = -delta.X;
         if (FlipY)
             delta.Y = -delta.Y;
-        delta += new Vector2d(mainCanvas.ActualWidth / 2, mainCanvas.ActualHeight / 2);
+        delta += new VecD(mainCanvas.ActualWidth / 2, mainCanvas.ActualHeight / 2);
         return delta;
     }
 
-    internal Vector2d ToZoomboxSpace(Vector2d mousePos)
+    internal VecD ToZoomboxSpace(VecD mousePos)
     {
-        Vector2d delta = mousePos - new Vector2d(mainCanvas.ActualWidth / 2, mainCanvas.ActualHeight / 2);
+        VecD delta = mousePos - new VecD(mainCanvas.ActualWidth / 2, mainCanvas.ActualHeight / 2);
         if (FlipX)
             delta.X = -delta.X;
         if (FlipY)
@@ -190,7 +190,7 @@ public partial class Zoombox : ContentControl, INotifyPropertyChanged
 
     private void RaiseViewportEvent()
     {
-        var realDim = new Vector2d(mainCanvas.ActualWidth, mainCanvas.ActualHeight);
+        var realDim = new VecD(mainCanvas.ActualWidth, mainCanvas.ActualHeight);
         RealDimensions = realDim;
         RaiseEvent(new ViewportRoutedEventArgs(
             ViewportMovedEvent,
@@ -202,7 +202,7 @@ public partial class Zoombox : ContentControl, INotifyPropertyChanged
 
     public void CenterContent() => CenterContent(new(mainGrid.ActualWidth, mainGrid.ActualHeight));
 
-    public void CenterContent(Vector2d newSize)
+    public void CenterContent(VecD newSize)
     {
 
         const double marginFactor = 1.1;
@@ -219,10 +219,10 @@ public partial class Zoombox : ContentControl, INotifyPropertyChanged
 
     public void ZoomIntoCenter(double delta)
     {
-        ZoomInto(new Vector2d(mainCanvas.ActualWidth / 2, mainCanvas.ActualHeight / 2), delta);
+        ZoomInto(new VecD(mainCanvas.ActualWidth / 2, mainCanvas.ActualHeight / 2), delta);
     }
 
-    public void ZoomInto(Vector2d mousePos, double delta)
+    public void ZoomInto(VecD mousePos, double delta)
     {
         if (delta == 0)
             return;
@@ -299,7 +299,7 @@ public partial class Zoombox : ContentControl, INotifyPropertyChanged
         else
         {
             if (ZoomMode == ZoomboxMode.Zoom && e.ChangedButton == MouseButton.Left)
-                ZoomInto(ToVector2d(e.GetPosition(mainCanvas)), ZoomOutOnClick ? -1 : 1);
+                ZoomInto(ToVecD(e.GetPosition(mainCanvas)), ZoomOutOnClick ? -1 : 1);
         }
         activeMouseDownEventArgs = null;
     }
@@ -320,7 +320,7 @@ public partial class Zoombox : ContentControl, INotifyPropertyChanged
     {
         for (int i = 0; i < Math.Abs(e.Delta / 100); i++)
         {
-            ZoomInto(ToVector2d(e.GetPosition(mainCanvas)), e.Delta / 100);
+            ZoomInto(ToVecD(e.GetPosition(mainCanvas)), e.Delta / 100);
         }
     }
 
@@ -329,35 +329,35 @@ public partial class Zoombox : ContentControl, INotifyPropertyChanged
         if (!UseTouchGestures)
             return;
         e.Handled = true;
-        Vector2d screenTranslation = new(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);
-        Vector2d screenOrigin = new(e.ManipulationOrigin.X, e.ManipulationOrigin.Y);
+        VecD screenTranslation = new(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);
+        VecD screenOrigin = new(e.ManipulationOrigin.X, e.ManipulationOrigin.Y);
         Manipulate(e.DeltaManipulation.Scale.X, screenTranslation, screenOrigin, e.DeltaManipulation.Rotation / 180 * Math.PI);
     }
 
-    private void Manipulate(double deltaScale, Vector2d screenTranslation, Vector2d screenOrigin, double rotation)
+    private void Manipulate(double deltaScale, VecD screenTranslation, VecD screenOrigin, double rotation)
     {
         double newScale = Math.Clamp(Scale * deltaScale, MinScale, MaxScale);
         double newAngle = Angle + rotation;
 
-        Vector2d originalPos = ToZoomboxSpace(screenOrigin);
+        VecD originalPos = ToZoomboxSpace(screenOrigin);
         Angle = newAngle;
         Scale = newScale;
-        Vector2d newPos = ToZoomboxSpace(screenOrigin);
-        Vector2d centerTranslation = originalPos - newPos;
+        VecD newPos = ToZoomboxSpace(screenOrigin);
+        VecD centerTranslation = originalPos - newPos;
         Center += centerTranslation;
 
-        Vector2d translatedZoomboxPos = ToZoomboxSpace(screenOrigin + screenTranslation);
+        VecD translatedZoomboxPos = ToZoomboxSpace(screenOrigin + screenTranslation);
         Center -= translatedZoomboxPos - originalPos;
     }
 
-    internal static Vector2d ToVector2d(Point point) => new Vector2d(point.X, point.Y);
+    internal static VecD ToVecD(Point point) => new VecD(point.X, point.Y);
 
     private static void OnPropertyChange(DependencyObject obj, DependencyPropertyChangedEventArgs args)
     {
         var zoombox = (Zoombox)obj;
 
-        Vector2d topLeft = zoombox.ToZoomboxSpace(new(0, 0)).Rotate(zoombox.Angle);
-        Vector2d bottomRight = zoombox.ToZoomboxSpace(new(zoombox.mainCanvas.ActualWidth, zoombox.mainCanvas.ActualHeight)).Rotate(zoombox.Angle);
+        VecD topLeft = zoombox.ToZoomboxSpace(new(0, 0)).Rotate(zoombox.Angle);
+        VecD bottomRight = zoombox.ToZoomboxSpace(new(zoombox.mainCanvas.ActualWidth, zoombox.mainCanvas.ActualHeight)).Rotate(zoombox.Angle);
 
         zoombox.Dimensions = (bottomRight - topLeft).Abs();
         zoombox.PropertyChanged?.Invoke(zoombox, new(nameof(zoombox.ScaleTransformXY)));

+ 8 - 8
src/PixiEditorPrototype/CustomControls/SymmetryOverlay/SymmetryOverlay.cs

@@ -132,13 +132,13 @@ internal class SymmetryOverlay : Control
         return new PointHitTestResult(this, hitTestParameters.HitPoint);
     }
 
-    private SymmetryAxisDirection? IsTouchingHandle(Vector2d position)
+    private SymmetryAxisDirection? IsTouchingHandle(VecD position)
     {
         double radius = HandleSize / ZoomboxScale / 2;
-        Vector2d left = new(-radius, horizontalAxisY);
-        Vector2d right = new(ActualWidth + radius, horizontalAxisY);
-        Vector2d up = new(verticalAxisX, -radius);
-        Vector2d down = new(verticalAxisX, ActualHeight + radius);
+        VecD left = new(-radius, horizontalAxisY);
+        VecD right = new(ActualWidth + radius, horizontalAxisY);
+        VecD up = new(verticalAxisX, -radius);
+        VecD down = new(verticalAxisX, ActualHeight + radius);
 
         if (HorizontalAxisVisible && (Math.Abs((left - position).LongestAxis) < radius || Math.Abs((right - position).LongestAxis) < radius))
             return SymmetryAxisDirection.Horizontal;
@@ -147,7 +147,7 @@ internal class SymmetryOverlay : Control
         return null;
     }
 
-    private Vector2d ToVector2d(Point pos) => new Vector2d(pos.X, pos.Y);
+    private VecD ToVecD(Point pos) => new VecD(pos.X, pos.Y);
 
     public SymmetryAxisDirection? capturedDirection;
 
@@ -155,7 +155,7 @@ internal class SymmetryOverlay : Control
     {
         base.OnMouseDown(e);
 
-        var pos = ToVector2d(e.GetPosition(this));
+        var pos = ToVecD(e.GetPosition(this));
         var dir = IsTouchingHandle(pos);
         if (dir is null)
             return;
@@ -196,7 +196,7 @@ internal class SymmetryOverlay : Control
 
         if (capturedDirection is null)
             return;
-        var pos = ToVector2d(e.GetPosition(this));
+        var pos = ToVecD(e.GetPosition(this));
         if (capturedDirection == SymmetryAxisDirection.Horizontal)
         {
             horizontalAxisY = (int)Math.Round(Math.Clamp(pos.Y, 0, ActualHeight));

+ 20 - 20
src/PixiEditorPrototype/CustomControls/TransformOverlay/TransformHelper.cs

@@ -8,20 +8,20 @@ internal static class TransformHelper
     public const double AnchorSize = 10;
     public const double MoveHandleSize = 16;
 
-    public static Rect ToAnchorRect(Vector2d pos, double zoomboxScale)
+    public static Rect ToAnchorRect(VecD pos, double zoomboxScale)
     {
         double scaled = AnchorSize / zoomboxScale;
         return new Rect(pos.X - scaled / 2, pos.Y - scaled / 2, scaled, scaled);
     }
 
-    public static Rect ToHandleRect(Vector2d pos, double zoomboxScale)
+    public static Rect ToHandleRect(VecD pos, double zoomboxScale)
     {
         double scaled = MoveHandleSize / zoomboxScale;
         return new Rect(pos.X - scaled / 2, pos.Y - scaled / 2, scaled, scaled);
     }
 
-    public static Vector2d ToVector2d(Point pos) => new Vector2d(pos.X, pos.Y);
-    public static Point ToPoint(Vector2d vec) => new Point(vec.X, vec.Y);
+    public static VecD ToVecD(Point pos) => new VecD(pos.X, pos.Y);
+    public static Point ToPoint(VecD vec) => new Point(vec.X, vec.Y);
 
     public static ShapeCorners SnapToPixels(ShapeCorners corners)
     {
@@ -58,7 +58,7 @@ internal static class TransformHelper
         return minDelta + desiredAngle;
     }
 
-    public static Vector2d OriginFromCorners(ShapeCorners corners)
+    public static VecD OriginFromCorners(ShapeCorners corners)
     {
         var maybeOrigin = TwoLineIntersection(
             GetAnchorPosition(corners, Anchor.Top),
@@ -69,12 +69,12 @@ internal static class TransformHelper
         return maybeOrigin ?? corners.TopLeft.Lerp(corners.BottomRight, 0.5);
     }
 
-    public static Vector2d? TwoLineIntersection(Vector2d line1Start, Vector2d line1End, Vector2d line2Start, Vector2d line2End)
+    public static VecD? TwoLineIntersection(VecD line1Start, VecD line1End, VecD line2Start, VecD line2End)
     {
         const double epsilon = 0.0001;
 
-        Vector2d line1delta = line1End - line1Start;
-        Vector2d line2delta = line2End - line2Start;
+        VecD line1delta = line1End - line1Start;
+        VecD line2delta = line2End - line2Start;
 
         // both lines are vertical, no intersections
         if (Math.Abs(line1delta.X) < epsilon && Math.Abs(line2delta.X) < epsilon)
@@ -166,7 +166,7 @@ internal static class TransformHelper
         };
     }
 
-    public static ShapeCorners UpdateCorner(ShapeCorners original, Anchor corner, Vector2d newPos)
+    public static ShapeCorners UpdateCorner(ShapeCorners original, Anchor corner, VecD newPos)
     {
         if (corner == Anchor.TopLeft)
             original.TopLeft = newPos;
@@ -181,7 +181,7 @@ internal static class TransformHelper
         return original;
     }
 
-    public static Vector2d GetAnchorPosition(ShapeCorners corners, Anchor anchor)
+    public static VecD GetAnchorPosition(ShapeCorners corners, Anchor anchor)
     {
         return anchor switch
         {
@@ -197,12 +197,12 @@ internal static class TransformHelper
         };
     }
 
-    public static Anchor? GetAnchorInPosition(Vector2d pos, ShapeCorners corners, Vector2d origin, double zoomboxScale)
+    public static Anchor? GetAnchorInPosition(VecD pos, ShapeCorners corners, VecD origin, double zoomboxScale)
     {
-        Vector2d topLeft = corners.TopLeft;
-        Vector2d topRight = corners.TopRight;
-        Vector2d bottomLeft = corners.BottomLeft;
-        Vector2d bottomRight = corners.BottomRight;
+        VecD topLeft = corners.TopLeft;
+        VecD topRight = corners.TopRight;
+        VecD bottomLeft = corners.BottomLeft;
+        VecD bottomRight = corners.BottomRight;
 
         // corners
         if (IsWithinAnchor(topLeft, pos, zoomboxScale))
@@ -230,25 +230,25 @@ internal static class TransformHelper
         return null;
     }
 
-    public static bool IsWithinAnchor(Vector2d anchorPos, Vector2d mousePos, double zoomboxScale)
+    public static bool IsWithinAnchor(VecD anchorPos, VecD mousePos, double zoomboxScale)
     {
         var delta = (anchorPos - mousePos).Abs();
         double scaled = AnchorSize / zoomboxScale / 2;
         return delta.X < scaled && delta.Y < scaled;
     }
 
-    public static bool IsWithinTransformHandle(Vector2d handlePos, Vector2d mousePos, double zoomboxScale)
+    public static bool IsWithinTransformHandle(VecD handlePos, VecD mousePos, double zoomboxScale)
     {
         var delta = (handlePos - mousePos).Abs();
         double scaled = MoveHandleSize / zoomboxScale / 2;
         return delta.X < scaled && delta.Y < scaled;
     }
 
-    public static Vector2d GetDragHandlePos(ShapeCorners corners, double zoomboxScale)
+    public static VecD GetDragHandlePos(ShapeCorners corners, double zoomboxScale)
     {
-        Vector2d max = new(
+        VecD max = new(
             Math.Max(Math.Max(corners.TopLeft.X, corners.TopRight.X), Math.Max(corners.BottomLeft.X, corners.BottomRight.X)),
             Math.Max(Math.Max(corners.TopLeft.Y, corners.TopRight.Y), Math.Max(corners.BottomLeft.Y, corners.BottomRight.Y)));
-        return max + new Vector2d(MoveHandleSize / zoomboxScale, MoveHandleSize / zoomboxScale);
+        return max + new VecD(MoveHandleSize / zoomboxScale, MoveHandleSize / zoomboxScale);
     }
 }

+ 17 - 17
src/PixiEditorPrototype/CustomControls/TransformOverlay/TransformOverlay.cs

@@ -78,20 +78,20 @@ internal class TransformOverlay : Control
     }
 
     private bool isMoving = false;
-    private Vector2d mousePosOnStartMove = new();
-    private Vector2d originOnStartMove = new();
+    private VecD mousePosOnStartMove = new();
+    private VecD originOnStartMove = new();
     private ShapeCorners cornersOnStartMove = new();
 
     private bool isRotating = false;
-    private Vector2d mousePosOnStartRotate = new();
+    private VecD mousePosOnStartRotate = new();
     private ShapeCorners cornersOnStartRotate = new();
     private double propAngle1OnStartRotate = 0;
     private double propAngle2OnStartRotate = 0;
 
     private Anchor? capturedAnchor;
     private ShapeCorners cornersOnStartAnchorDrag;
-    private Vector2d mousePosOnStartAnchorDrag;
-    private Vector2d originOnStartAnchorDrag;
+    private VecD mousePosOnStartAnchorDrag;
+    private VecD originOnStartAnchorDrag;
 
     private Pen blackPen = new Pen(Brushes.Black, 1);
     private Pen blackDashedPen = new Pen(Brushes.Black, 1) { DashStyle = new DashStyle(new double[] { 2, 4 }, 0) };
@@ -112,7 +112,7 @@ internal class TransformOverlay : Control
     }
 
     private void DrawOverlay
-        (DrawingContext context, Vector2d size, ShapeCorners corners, Vector2d origin, double zoomboxScale)
+        (DrawingContext context, VecD size, ShapeCorners corners, VecD origin, double zoomboxScale)
     {
         // draw transparent background to enable mouse input everywhere
         context.DrawRectangle(Brushes.Transparent, null, new Rect(new Point(0, 0), new Size(size.X, size.Y)));
@@ -123,10 +123,10 @@ internal class TransformOverlay : Control
         blackFreqDashedPen.Thickness = 1 / zoomboxScale;
         whiteFreqDashedPen.Thickness = 1 / zoomboxScale;
 
-        Vector2d topLeft = corners.TopLeft;
-        Vector2d topRight = corners.TopRight;
-        Vector2d bottomLeft = corners.BottomLeft;
-        Vector2d bottomRight = corners.BottomRight;
+        VecD topLeft = corners.TopLeft;
+        VecD topRight = corners.TopRight;
+        VecD bottomLeft = corners.BottomLeft;
+        VecD bottomRight = corners.BottomRight;
 
         // lines
         context.DrawLine(blackDashedPen, TransformHelper.ToPoint(topLeft), TransformHelper.ToPoint(topRight));
@@ -156,7 +156,7 @@ internal class TransformOverlay : Control
         context.DrawEllipse(Brushes.Transparent, whiteFreqDashedPen, TransformHelper.ToPoint(origin), radius, radius);
 
         // move handle
-        Vector2d handlePos = TransformHelper.GetDragHandlePos(corners, zoomboxScale);
+        VecD handlePos = TransformHelper.GetDragHandlePos(corners, zoomboxScale);
         const double CrossSize = TransformHelper.MoveHandleSize - 1;
         context.DrawRectangle(Brushes.White, blackPen, TransformHelper.ToHandleRect(handlePos, zoomboxScale));
         handleGeometry.Transform = new MatrixTransform(
@@ -172,7 +172,7 @@ internal class TransformOverlay : Control
         base.OnMouseDown(e);
 
         e.Handled = true;
-        var pos = TransformHelper.ToVector2d(e.GetPosition(this));
+        var pos = TransformHelper.ToVecD(e.GetPosition(this));
         var anchor = TransformHelper.GetAnchorInPosition(pos, Corners, InternalState.Origin, ZoomboxScale);
         if (anchor is not null)
         {
@@ -184,14 +184,14 @@ internal class TransformOverlay : Control
         else if (Corners.IsPointInside(pos) || TransformHelper.IsWithinTransformHandle(TransformHelper.GetDragHandlePos(Corners, ZoomboxScale), pos, ZoomboxScale))
         {
             isMoving = true;
-            mousePosOnStartMove = TransformHelper.ToVector2d(e.GetPosition(this));
+            mousePosOnStartMove = TransformHelper.ToVecD(e.GetPosition(this));
             originOnStartMove = InternalState.Origin;
             cornersOnStartMove = Corners;
         }
         else
         {
             isRotating = true;
-            mousePosOnStartRotate = TransformHelper.ToVector2d(e.GetPosition(this));
+            mousePosOnStartRotate = TransformHelper.ToVecD(e.GetPosition(this));
             cornersOnStartRotate = Corners;
             propAngle1OnStartRotate = InternalState.ProportionalAngle1;
             propAngle2OnStartRotate = InternalState.ProportionalAngle2;
@@ -208,7 +208,7 @@ internal class TransformOverlay : Control
         }
         else if (isMoving)
         {
-            var pos = TransformHelper.ToVector2d(e.GetPosition(this));
+            var pos = TransformHelper.ToVecD(e.GetPosition(this));
             var delta = pos - mousePosOnStartMove;
 
             if (Corners.IsSnappedToPixels)
@@ -226,7 +226,7 @@ internal class TransformOverlay : Control
         }
         else if (isRotating)
         {
-            var pos = TransformHelper.ToVector2d(e.GetPosition(this));
+            var pos = TransformHelper.ToVecD(e.GetPosition(this));
             var angle = (mousePosOnStartRotate - InternalState.Origin).CCWAngleTo(pos - InternalState.Origin);
             if (SnapToAngles)
                 angle = TransformHelper.FindSnappingAngle(cornersOnStartRotate, angle);
@@ -248,7 +248,7 @@ internal class TransformOverlay : Control
             TransformHelper.IsSide((Anchor)capturedAnchor) && SideFreedom == TransformSideFreedom.Locked)
             return;
 
-        var pos = TransformHelper.ToVector2d(e.GetPosition(this));
+        var pos = TransformHelper.ToVecD(e.GetPosition(this));
 
         if (TransformHelper.IsCorner((Anchor)capturedAnchor))
         {

+ 1 - 1
src/PixiEditorPrototype/CustomControls/TransformOverlay/TransformState.cs

@@ -4,7 +4,7 @@ namespace PixiEditorPrototype.CustomControls.TransformOverlay;
 internal struct TransformState
 {
     public bool OriginWasManuallyDragged { get; set; }
-    public Vector2d Origin { get; set; }
+    public VecD Origin { get; set; }
     public double ProportionalAngle1 { get; set; }
     public double ProportionalAngle2 { get; set; }
 }

+ 15 - 15
src/PixiEditorPrototype/CustomControls/TransformOverlay/TransformUpdateHelper.cs

@@ -5,7 +5,7 @@ namespace PixiEditorPrototype.CustomControls.TransformOverlay;
 internal static class TransformUpdateHelper
 {
     public static ShapeCorners? UpdateShapeFromCorner
-        (Anchor targetCorner, TransformCornerFreedom freedom, double propAngle1, double propAngle2, ShapeCorners corners, Vector2d desiredPos)
+        (Anchor targetCorner, TransformCornerFreedom freedom, double propAngle1, double propAngle2, ShapeCorners corners, VecD desiredPos)
     {
         if (!TransformHelper.IsCorner(targetCorner))
             throw new ArgumentException($"{targetCorner} is not a corner");
@@ -22,7 +22,7 @@ internal static class TransformUpdateHelper
             if (freedom == TransformCornerFreedom.ScaleProportionally)
             {
                 double correctAngle = targetCorner is Anchor.TopLeft or Anchor.BottomRight ? propAngle1 : propAngle2;
-                desiredPos = desiredPos.ProjectOntoLine(oppositePos, oppositePos + Vector2d.FromAngleAndLength(correctAngle, 1));
+                desiredPos = desiredPos.ProjectOntoLine(oppositePos, oppositePos + VecD.FromAngleAndLength(correctAngle, 1));
             }
 
             var (leftNeighbor, rightNeighbor) = TransformHelper.GetNeighboringCorners(targetCorner);
@@ -34,7 +34,7 @@ internal static class TransformUpdateHelper
             var leftNeighTrans = (leftNeighborPos - oppositePos).Rotate(-angle);
             var rightNeighTrans = (rightNeighborPos - oppositePos).Rotate(-angle);
 
-            Vector2d delta = (desiredPos - targetPos).Rotate(-angle);
+            VecD delta = (desiredPos - targetPos).Rotate(-angle);
 
             corners = TransformHelper.UpdateCorner(corners, targetCorner,
                 (targetTrans + delta).Rotate(angle) + oppositePos);
@@ -56,7 +56,7 @@ internal static class TransformUpdateHelper
     }
 
     public static ShapeCorners? UpdateShapeFromSide
-        (Anchor targetSide, TransformSideFreedom freedom, double propAngle1, double propAngle2, ShapeCorners corners, Vector2d desiredPos)
+        (Anchor targetSide, TransformSideFreedom freedom, double propAngle1, double propAngle2, ShapeCorners corners, VecD desiredPos)
     {
         if (!TransformHelper.IsSide(targetSide))
             throw new ArgumentException($"{targetSide} is not a side");
@@ -72,8 +72,8 @@ internal static class TransformUpdateHelper
 
             desiredPos = desiredPos.ProjectOntoLine(targetPos, oppositePos);
 
-            Vector2d thing = targetPos - oppositePos;
-            thing = Vector2d.FromAngleAndLength(thing.Angle, 1 / thing.Length);
+            VecD thing = targetPos - oppositePos;
+            thing = VecD.FromAngleAndLength(thing.Angle, 1 / thing.Length);
             double scalingFactor = (desiredPos - oppositePos) * thing;
             if (!double.IsNormal(scalingFactor))
                 return corners;
@@ -94,18 +94,18 @@ internal static class TransformUpdateHelper
 
                 var (leftAngle, rightAngle) = leftCorn is Anchor.TopLeft or Anchor.BottomRight ? (propAngle1, propAngle2) : (propAngle2, propAngle1);
 
-                var updLeftCorn = TransformHelper.TwoLineIntersection(leftCornPos + delta, rightCornPos + delta, center, center + Vector2d.FromAngleAndLength(leftAngle, 1));
-                var updRightCorn = TransformHelper.TwoLineIntersection(leftCornPos + delta, rightCornPos + delta, center, center + Vector2d.FromAngleAndLength(rightAngle, 1));
-                var updLeftOppCorn = TransformHelper.TwoLineIntersection(leftOppCornPos, rightOppCornPos, center, center + Vector2d.FromAngleAndLength(rightAngle, 1));
-                var updRightOppCorn = TransformHelper.TwoLineIntersection(leftOppCornPos, rightOppCornPos, center, center + Vector2d.FromAngleAndLength(leftAngle, 1));
+                var updLeftCorn = TransformHelper.TwoLineIntersection(leftCornPos + delta, rightCornPos + delta, center, center + VecD.FromAngleAndLength(leftAngle, 1));
+                var updRightCorn = TransformHelper.TwoLineIntersection(leftCornPos + delta, rightCornPos + delta, center, center + VecD.FromAngleAndLength(rightAngle, 1));
+                var updLeftOppCorn = TransformHelper.TwoLineIntersection(leftOppCornPos, rightOppCornPos, center, center + VecD.FromAngleAndLength(rightAngle, 1));
+                var updRightOppCorn = TransformHelper.TwoLineIntersection(leftOppCornPos, rightOppCornPos, center, center + VecD.FromAngleAndLength(leftAngle, 1));
 
                 if (updLeftCorn is null || updRightCorn is null || updLeftOppCorn is null || updRightOppCorn is null)
                     goto fallback;
 
-                corners = TransformHelper.UpdateCorner(corners, leftCorn, (Vector2d)updLeftCorn);
-                corners = TransformHelper.UpdateCorner(corners, rightCorn, (Vector2d)updRightCorn);
-                corners = TransformHelper.UpdateCorner(corners, leftOppCorn, (Vector2d)updLeftOppCorn);
-                corners = TransformHelper.UpdateCorner(corners, rightOppCorn, (Vector2d)updRightOppCorn);
+                corners = TransformHelper.UpdateCorner(corners, leftCorn, (VecD)updLeftCorn);
+                corners = TransformHelper.UpdateCorner(corners, rightCorn, (VecD)updRightCorn);
+                corners = TransformHelper.UpdateCorner(corners, leftOppCorn, (VecD)updLeftOppCorn);
+                corners = TransformHelper.UpdateCorner(corners, rightOppCorn, (VecD)updRightOppCorn);
 
                 return corners;
             }
@@ -150,7 +150,7 @@ fallback:
         throw new ArgumentException($"Freedom degree {freedom} is not supported");
     }
 
-    public static ShapeCorners UpdateShapeFromRotation(ShapeCorners corners, Vector2d origin, double angle)
+    public static ShapeCorners UpdateShapeFromRotation(ShapeCorners corners, VecD origin, double angle)
     {
         corners.TopLeft = corners.TopLeft.Rotate(angle, origin);
         corners.TopRight = corners.TopRight.Rotate(angle, origin);

+ 0 - 37
src/PixiEditorPrototype/Models/DocumentStateHandler.cs

@@ -1,37 +0,0 @@
-using System;
-using ChunkyImageLib.DataHolders;
-using PixiEditorPrototype.ViewModels;
-
-namespace PixiEditorPrototype.Models;
-internal class DocumentStateHandler
-{
-    private DocumentViewModel owner;
-
-    private Tool activeTool = Tool.Rectangle;
-    private bool updateableChangeActive = false;
-    private bool transformActive = false;
-
-    public DocumentStateHandler(DocumentViewModel owner)
-    {
-        this.owner = owner;
-    }
-
-    public void OnMouseDown(Vector2i position)
-    {
-
-    }
-
-    public void ChangeTool(Tool newTool)
-    {
-        if (updateableChangeActive)
-            EndUpdateableChange();
-        activeTool = newTool;
-    }
-
-    private void EndUpdateableChange()
-    {
-        if (!updateableChangeActive)
-            throw new InvalidOperationException("No updateable change active");
-        updateableChangeActive = false;
-    }
-}

+ 2 - 2
src/PixiEditorPrototype/Models/DocumentUpdater.cs

@@ -136,7 +136,7 @@ internal class DocumentUpdater
         foreach (var (res, surf) in doc.Surfaces)
         {
             surf.Dispose();
-            newBitmaps[res] = CreateBitmap((Vector2i)(size * res.Multiplier()));
+            newBitmaps[res] = CreateBitmap((VecI)(size * res.Multiplier()));
             doc.Surfaces[res] = CreateSKSurface(newBitmaps[res]);
         }
 
@@ -148,7 +148,7 @@ internal class DocumentUpdater
         doc.RaisePropertyChanged(nameof(doc.VerticalSymmetryAxisX));
     }
 
-    private WriteableBitmap CreateBitmap(Vector2i size)
+    private WriteableBitmap CreateBitmap(VecI size)
     {
         return new WriteableBitmap(Math.Max(size.X, 1), Math.Max(size.Y, 1), 96, 96, PixelFormats.Pbgra32, null);
     }

+ 1 - 1
src/PixiEditorPrototype/Models/Rendering/RenderInfos/DirtyRect_RenderInfo.cs

@@ -2,4 +2,4 @@
 
 namespace PixiEditorPrototype.Models.Rendering.RenderInfos;
 
-public record class DirtyRect_RenderInfo(Vector2i Pos, Vector2i Size, ChunkResolution Resolution) : IRenderInfo;
+public record class DirtyRect_RenderInfo(VecI Pos, VecI Size, ChunkResolution Resolution) : IRenderInfo;

+ 8 - 8
src/PixiEditorPrototype/Models/Rendering/WriteableBitmapUpdater.cs

@@ -27,7 +27,7 @@ internal class WriteableBitmapUpdater
     private static readonly SKPaint SelectionPaint = new SKPaint() { BlendMode = SKBlendMode.SrcOver, Color = new(0xa0FFFFFF) };
     private static readonly SKPaint ClearPaint = new SKPaint() { BlendMode = SKBlendMode.Src, Color = SKColors.Transparent };
 
-    private readonly Dictionary<ChunkResolution, HashSet<Vector2i>> postponedChunks = new()
+    private readonly Dictionary<ChunkResolution, HashSet<VecI>> postponedChunks = new()
     {
         [ChunkResolution.Full] = new(),
         [ChunkResolution.Half] = new(),
@@ -51,9 +51,9 @@ internal class WriteableBitmapUpdater
         return Render(changes);
     }
 
-    private Dictionary<ChunkResolution, HashSet<Vector2i>> FindChunksToRerender(IReadOnlyList<IChangeInfo?> changes)
+    private Dictionary<ChunkResolution, HashSet<VecI>> FindChunksToRerender(IReadOnlyList<IChangeInfo?> changes)
     {
-        HashSet<Vector2i> affectedChunks = new();
+        HashSet<VecI> affectedChunks = new();
         foreach (var change in changes)
         {
             switch (change)
@@ -112,7 +112,7 @@ internal class WriteableBitmapUpdater
             postponed.UnionWith(affectedChunks);
         }
 
-        var chunksOnScreen = new Dictionary<ChunkResolution, HashSet<Vector2i>>()
+        var chunksOnScreen = new Dictionary<ChunkResolution, HashSet<VecI>>()
         {
             [ChunkResolution.Full] = new(),
             [ChunkResolution.Half] = new(),
@@ -139,9 +139,9 @@ internal class WriteableBitmapUpdater
         return chunksOnScreen;
     }
 
-    private void AddAllChunks(HashSet<Vector2i> chunks)
+    private void AddAllChunks(HashSet<VecI> chunks)
     {
-        Vector2i size = new(
+        VecI size = new(
             (int)Math.Ceiling(helpers.Tracker.Document.Size.X / (float)ChunkyImage.ChunkSize),
             (int)Math.Ceiling(helpers.Tracker.Document.Size.Y / (float)ChunkyImage.ChunkSize));
         for (int i = 0; i < size.X; i++)
@@ -155,7 +155,7 @@ internal class WriteableBitmapUpdater
 
     private List<IRenderInfo> Render(IReadOnlyList<IChangeInfo?> changes)
     {
-        Dictionary<ChunkResolution, HashSet<Vector2i>> chunksToRerender = FindChunksToRerender(changes);
+        Dictionary<ChunkResolution, HashSet<VecI>> chunksToRerender = FindChunksToRerender(changes);
 
         List<IRenderInfo> infos = new();
 
@@ -177,7 +177,7 @@ internal class WriteableBitmapUpdater
         return infos;
     }
 
-    private void RenderChunk(Vector2i chunkPos, SKSurface screenSurface, ChunkResolution resolution)
+    private void RenderChunk(VecI chunkPos, SKSurface screenSurface, ChunkResolution resolution)
     {
         using Chunk renderedChunk = ChunkRenderer.RenderWholeStructure(chunkPos, resolution, helpers.Tracker.Document.ReadOnlyStructureRoot);
 

+ 1 - 1
src/PixiEditorPrototype/Models/ViewportLocation.cs

@@ -3,4 +3,4 @@ using ChunkyImageLib.DataHolders;
 
 namespace PixiEditorPrototype.Models;
 internal readonly record struct ViewportLocation
-    (double Angle, Vector2d Center, Vector2d RealDimensions, Vector2d Dimensions, ChunkResolution Resolution, Guid GuidValue, Action InvalidateVisual);
+    (double Angle, VecD Center, VecD RealDimensions, VecD Dimensions, ChunkResolution Resolution, Guid GuidValue, Action InvalidateVisual);

+ 7 - 7
src/PixiEditorPrototype/UserControls/Viewport/Viewport.xaml.cs

@@ -102,8 +102,8 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
         }
     }
 
-    private Vector2d center = new(32, 32);
-    public Vector2d Center
+    private VecD center = new(32, 32);
+    public VecD Center
     {
         get => center;
         set
@@ -114,8 +114,8 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
         }
     }
 
-    private Vector2d realDimensions = new(double.MaxValue, double.MaxValue);
-    public Vector2d RealDimensions
+    private VecD realDimensions = new(double.MaxValue, double.MaxValue);
+    public VecD RealDimensions
     {
         get => realDimensions;
         set
@@ -132,8 +132,8 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
         }
     }
 
-    private Vector2d dimensions = new(64, 64);
-    public Vector2d Dimensions
+    private VecD dimensions = new(64, 64);
+    public VecD Dimensions
     {
         get => dimensions;
         set
@@ -207,7 +207,7 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
 
     private ChunkResolution CalculateResolution()
     {
-        Vector2d densityVec = Dimensions.Divide(RealDimensions);
+        VecD densityVec = Dimensions.Divide(RealDimensions);
         double density = Math.Min(densityVec.X, densityVec.Y);
         if (density > 8.01)
             return ChunkResolution.Eighth;

+ 18 - 9
src/PixiEditorPrototype/ViewModels/DocumentViewModel.cs

@@ -91,7 +91,6 @@ internal class DocumentViewModel : INotifyPropertyChanged
 
     public Dictionary<ChunkResolution, SKSurface> Surfaces { get; set; } = new();
 
-    public DocumentStateHandler StateHandler { get; }
 
     public int ResizeWidth { get; set; }
     public int ResizeHeight { get; set; }
@@ -107,7 +106,6 @@ internal class DocumentViewModel : INotifyPropertyChanged
         TransformViewModel = new();
         TransformViewModel.TransformMoved += OnTransformUpdate;
 
-        StateHandler = new(this);
         Helpers = new DocumentHelpers(this);
         StructureRoot = new FolderViewModel(this, Helpers, Helpers.Tracker.Document.ReadOnlyStructureRoot);
 
@@ -214,7 +212,7 @@ internal class DocumentViewModel : INotifyPropertyChanged
     }
 
     bool startedSelection = false;
-    public void StartUpdateSelection(Vector2i pos, Vector2i size)
+    public void StartUpdateSelection(VecI pos, VecI size)
     {
         //if (!startedSelection)
         //   Helpers.ActionAccumulator.AddActions(new ClearSelection_Action());
@@ -280,34 +278,43 @@ internal class DocumentViewModel : INotifyPropertyChanged
 
     private void ClearSelection(object? param)
     {
+        if (updateableChangeActive)
+            return;
         Helpers.ActionAccumulator.AddFinishedActions(new ClearSelection_Action());
     }
 
     private void DeleteStructureMember(object? param)
     {
-        if (SelectedStructureMember is not null)
-            Helpers.ActionAccumulator.AddFinishedActions(new DeleteStructureMember_Action(SelectedStructureMember.GuidValue));
+        if (updateableChangeActive || SelectedStructureMember is null)
+            return;
+        Helpers.ActionAccumulator.AddFinishedActions(new DeleteStructureMember_Action(SelectedStructureMember.GuidValue));
     }
 
     private void Undo(object? param)
     {
+        if (updateableChangeActive)
+            return;
         Helpers.ActionAccumulator.AddActions(new Undo_Action());
     }
 
     private void Redo(object? param)
     {
+        if (updateableChangeActive)
+            return;
         Helpers.ActionAccumulator.AddActions(new Redo_Action());
     }
 
     private void ToggleLockTransparency(object? param)
     {
-        if (SelectedStructureMember is not LayerViewModel layer)
+        if (updateableChangeActive || SelectedStructureMember is not LayerViewModel layer)
             return;
         layer.LockTransparency = !layer.LockTransparency;
     }
 
     private void ResizeCanvas(object? param)
     {
+        if (updateableChangeActive)
+            return;
         Helpers.ActionAccumulator.AddFinishedActions(new ResizeCanvas_Action(new(ResizeWidth, ResizeHeight)));
     }
 
@@ -318,21 +325,21 @@ internal class DocumentViewModel : INotifyPropertyChanged
 
     private void CreateMask(object? param)
     {
-        if (SelectedStructureMember is null || SelectedStructureMember.HasMask)
+        if (updateableChangeActive || SelectedStructureMember is null || SelectedStructureMember.HasMask)
             return;
         Helpers.ActionAccumulator.AddFinishedActions(new CreateStructureMemberMask_Action(SelectedStructureMember.GuidValue));
     }
 
     private void DeleteMask(object? param)
     {
-        if (SelectedStructureMember is null || !SelectedStructureMember.HasMask)
+        if (updateableChangeActive || SelectedStructureMember is null || !SelectedStructureMember.HasMask)
             return;
         Helpers.ActionAccumulator.AddFinishedActions(new DeleteStructureMemberMask_Action(SelectedStructureMember.GuidValue));
     }
 
     private void Combine(object? param)
     {
-        if (SelectedStructureMember is null)
+        if (updateableChangeActive || SelectedStructureMember is null)
             return;
         List<Guid> selected = new();
         AddSelectedMembers(StructureRoot, selected);
@@ -355,6 +362,8 @@ internal class DocumentViewModel : INotifyPropertyChanged
 
     private void ClearHistory(object? param)
     {
+        if (updateableChangeActive)
+            return;
         Helpers.ActionAccumulator.AddActions(new DeleteRecordedChanges_Action());
     }