Browse Source

Added bitmap supporter

flabbet 5 years ago
parent
commit
e74e8c3599

+ 1 - 1
PixiEditor/Models/Controllers/BitmapManager.cs

@@ -131,7 +131,7 @@ namespace PixiEditor.Models.Controllers
 
         private void Controller_MousePositionChanged(object sender, MouseMovementEventArgs e)
         {
-            if (Mouse.LeftButton == MouseButtonState.Pressed && ActiveDocument != null)
+            if (Mouse.LeftButton == MouseButtonState.Pressed && MouseController.ClickedOnCanvas && ActiveDocument != null)
             {
                 if (IsOperationTool(SelectedTool))
                     BitmapOperations.ExecuteTool(e.NewPosition,

+ 6 - 2
PixiEditor/Models/Controllers/MouseMovementController.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using Accessibility;
 using PixiEditor.Models.Position;
 
 namespace PixiEditor.Models.Controllers
@@ -8,16 +9,18 @@ namespace PixiEditor.Models.Controllers
     {
         public List<Coordinates> LastMouseMoveCoordinates { get; } = new List<Coordinates>();
         public bool IsRecordingChanges { get; private set; }
+        public bool ClickedOnCanvas { get; set; }
         public event EventHandler StartedRecordingChanges;
         public event EventHandler<MouseMovementEventArgs> MousePositionChanged;
         public event EventHandler StoppedRecordingChanges;
 
-        public void StartRecordingMouseMovementChanges()
+        public void StartRecordingMouseMovementChanges(bool clickedOnCanvas)
         {
             if (IsRecordingChanges == false)
             {
                 LastMouseMoveCoordinates.Clear();
                 IsRecordingChanges = true;
+                ClickedOnCanvas = clickedOnCanvas;
                 StartedRecordingChanges?.Invoke(this, EventArgs.Empty);
             }
         }
@@ -33,7 +36,7 @@ namespace PixiEditor.Models.Controllers
         }
 
         /// <summary>
-        ///     Plain mose move, does not affect mouse drag recordings
+        ///     Plain mouse move, does not affect mouse drag recordings
         /// </summary>
         /// <param name="mouseCoordinates"></param>
         public void MouseMoved(Coordinates mouseCoordinates)
@@ -46,6 +49,7 @@ namespace PixiEditor.Models.Controllers
             if (IsRecordingChanges)
             {
                 IsRecordingChanges = false;
+                ClickedOnCanvas = false;
                 StoppedRecordingChanges?.Invoke(this, EventArgs.Empty);
             }
         }

+ 11 - 0
PixiEditor/Models/Enums/CapType.cs

@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace PixiEditor.Models.Enums
+{
+    public enum CapType
+    {
+        Square, Round
+    }
+}

+ 32 - 1
PixiEditor/Models/Tools/Tools/CircleTool.cs

@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
 using System.Linq;
 using System.Windows.Media;
 using PixiEditor.Helpers.Extensions;
@@ -34,6 +35,36 @@ namespace PixiEditor.Models.Tools.Tools
             return new[] {new LayerChange(pixels, layer)};
         }
 
+        /// <summary>
+        ///     Calculates ellipse points for specified coordinates and thickness.
+        /// </summary>
+        /// <param name="startCoordinates">Top left coordinate of ellipse</param>
+        /// <param name="endCoordinates">Bottom right coordinate of ellipse</param>
+        /// <param name="thickness">Thickness of ellipse</param>
+        /// <param name="filled">Should ellipse be filled</param>
+        /// <returns>Coordinates for ellipse</returns>
+        public Coordinates[] CreateEllipse(Coordinates startCoordinates, Coordinates endCoordinates, int thickness,
+            bool filled)
+        {
+            List<Coordinates> output = new List<Coordinates>();
+            Coordinates[] outline = CreateEllipse(startCoordinates, endCoordinates, thickness);
+            output.AddRange(outline);
+            if (filled)
+            {
+                output.AddRange(CalculateFillForEllipse(outline));
+                return output.Distinct().ToArray();
+            }
+
+            return output.ToArray();
+        }
+        /// <summary>
+        ///     Calculates ellipse points for specified coordinates and thickness.
+        /// </summary>
+        /// <param name="startCoordinates">Top left coordinate of ellipse</param>
+        /// <param name="endCoordinates">Bottom right coordinate of ellipse</param>
+        /// <param name="thickness">Thickness of ellipse</param>
+        /// <returns>Coordinates for ellipse</returns>
+        
         public Coordinates[] CreateEllipse(Coordinates startCoordinates, Coordinates endCoordinates, int thickness)
         {
             Coordinates centerCoordinates = CoordinatesCalculator.GetCenterPoint(startCoordinates, endCoordinates);

+ 2 - 1
PixiEditor/Models/Tools/Tools/EarserTool.cs

@@ -23,8 +23,9 @@ namespace PixiEditor.Models.Tools.Tools
 
         public LayerChange[] Earse(Layer layer, Coordinates[] coordinates, int toolSize)
         {
+            Coordinates startingCords = coordinates.Length > 1 ? coordinates[1] : coordinates[0];
             PenTool pen = new PenTool();
-            var pixels = pen.Draw(coordinates[0], System.Windows.Media.Colors.Transparent, toolSize);
+            var pixels = pen.Draw(startingCords, coordinates[0], System.Windows.Media.Colors.Transparent, toolSize);
             return new[] {new LayerChange(pixels, layer)};
         }
     }

+ 55 - 24
PixiEditor/Models/Tools/Tools/LineTool.cs

@@ -1,6 +1,9 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
+using System.Linq;
 using System.Windows.Media;
 using PixiEditor.Models.DataHolders;
+using PixiEditor.Models.Enums;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Tools.ToolSettings;
@@ -21,20 +24,65 @@ namespace PixiEditor.Models.Tools.Tools
         {
             var pixels =
                 BitmapPixelChanges.FromSingleColoredArray(
-                    CreateLine(coordinates, (int) Toolbar.GetSetting("ToolSize").Value), color);
-            return new[] {new LayerChange(pixels, layer)};
+                    CreateLine(coordinates, 
+                        (int) Toolbar.GetSetting("ToolSize").Value, CapType.Round, CapType.Round), color);
+            return Only(pixels, layer);
         }
 
-        public Coordinates[] CreateLine(Coordinates[] coordinates, int thickness)
+        public Coordinates[] CreateLine(Coordinates[] coordinates, int thickness, CapType startCap, CapType endCap)
         {
             Coordinates startingCoordinates = coordinates[^1];
             Coordinates latestCoordinates = coordinates[0];
             if (thickness == 1)
                 return BresenhamLine(startingCoordinates.X, startingCoordinates.Y, latestCoordinates.X,
                     latestCoordinates.Y);
-            return GetThickShape(
-                BresenhamLine(startingCoordinates.X, startingCoordinates.Y, latestCoordinates.X, latestCoordinates.Y),
-                thickness);
+            return GetLinePoints(startingCoordinates, latestCoordinates, thickness, startCap, endCap);
+        }
+
+        private Coordinates[] GetLinePoints(Coordinates start, Coordinates end, int thickness, CapType startCap, CapType endCap)
+        {
+            var startingCap = GetCapCoordinates(startCap, start, thickness);
+            if (start == end) return startingCap;
+
+            var line = BresenhamLine(start.X, start.Y, end.X, end.Y);
+
+            List<Coordinates> output = new List<Coordinates>(startingCap);
+
+            output.AddRange(GetCapCoordinates(endCap, end, thickness));
+            if (line.Length > 2)
+            {
+                output.AddRange(GetThickShape(line.Except(new []{start,end}).ToArray(), thickness));
+            }
+
+            return output.Distinct().ToArray();
+
+        }
+
+        private Coordinates[] GetCapCoordinates(CapType cap, Coordinates position, int thickness)
+        {
+            switch (cap)
+            {
+                case CapType.Round:
+                {
+                    return GetRoundCap(position, thickness); // Round cap is not working very well, circle tool must be improved
+                }
+                default: 
+                    return GetThickShape(new[] { position }, thickness);
+            }
+        }
+
+        /// <summary>
+        ///     Gets points for rounded cap on specified position and thickness
+        /// </summary>
+        /// <param name="position">Starting position of cap</param>
+        /// <param name="thickness">Thickness of cap</param>
+        /// <returns></returns>
+        private Coordinates[] GetRoundCap(Coordinates position, int thickness)
+        {
+            CircleTool circle = new CircleTool();
+            var rectangleCords = CoordinatesCalculator.RectangleToCoordinates(
+                CoordinatesCalculator.CalculateThicknessCenter(position, thickness));
+            return circle.CreateEllipse(rectangleCords[0], rectangleCords[^1], 1, true);
         }
 
         private Coordinates[] BresenhamLine(int x1, int y1, int x2, int y2)
@@ -118,22 +166,5 @@ namespace PixiEditor.Models.Tools.Tools
 
             return coordinates.ToArray();
         }
-
-        private int[,] GetMaskForThickness(int thickness)
-        {
-            if (thickness == 2)
-                return new[,]
-                {
-                    {0, 0, 0},
-                    {0, 1, 1},
-                    {0, 1, 1}
-                };
-            int[,] mask = new int[thickness, thickness];
-
-            for (int i = 0; i < thickness; i++)
-            for (int j = 0; j < thickness; j++)
-                mask[i, j] = 1;
-            return mask;
-        }
     }
 }

+ 7 - 9
PixiEditor/Models/Tools/Tools/PenTool.cs

@@ -1,6 +1,7 @@
 using System.Windows.Input;
 using System.Windows.Media;
 using PixiEditor.Models.DataHolders;
+using PixiEditor.Models.Enums;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Tools.ToolSettings;
@@ -22,20 +23,17 @@ namespace PixiEditor.Models.Tools.Tools
 
         public override LayerChange[] Use(Layer layer, Coordinates[] coordinates, Color color)
         {
-            var pixels = Draw(coordinates[0], color, (int) Toolbar.Settings[_toolSizeIndex].Value);
+            Coordinates startingCords = coordinates.Length > 1 ? coordinates[1] : coordinates[0];
+            var pixels = Draw(startingCords, coordinates[0], color, (int) Toolbar.Settings[_toolSizeIndex].Value);
             return new[] {new LayerChange(pixels, layer)};
         }
 
-        public BitmapPixelChanges Draw(Coordinates startingCoords, Color color, int toolSize)
+        public BitmapPixelChanges Draw(Coordinates startingCoords, Coordinates latestCords, Color color, int toolSize)
         {
-            int x1, y1, x2, y2;
-            DoubleCords centeredCoords = CoordinatesCalculator.CalculateThicknessCenter(startingCoords, toolSize);
-            x1 = centeredCoords.Coords1.X;
-            y1 = centeredCoords.Coords1.Y;
-            x2 = centeredCoords.Coords2.X;
-            y2 = centeredCoords.Coords2.Y;
+            LineTool line = new LineTool();
             return BitmapPixelChanges.FromSingleColoredArray(
-                CoordinatesCalculator.RectangleToCoordinates(x1, y1, x2, y2), color);
+                line.CreateLine(new[] { startingCoords, latestCords }, toolSize, 
+                    CapType.Square, CapType.Square), color);
         }
     }
 }

+ 2 - 11
PixiEditor/ViewModels/ViewModelMain.cs

@@ -277,8 +277,6 @@ namespace PixiEditor.ViewModels
             }
         }
 
-        private bool _mouseMoveStartedOnCanvas = false;
-
         public ClipboardController ClipboardController { get; set; }
 
         private void CenterContent(object property)
@@ -594,11 +592,7 @@ namespace PixiEditor.ViewModels
         /// <param name="parameter"></param>
         private void MouseUp(object parameter)
         {
-            if (_mouseMoveStartedOnCanvas)
-            {
-                BitmapManager.MouseController.StopRecordingMouseMovementChanges();
-                _mouseMoveStartedOnCanvas = false;
-            }
+            BitmapManager.MouseController.StopRecordingMouseMovementChanges();
         }
 
         private void MouseDown(object parameter)
@@ -606,10 +600,9 @@ namespace PixiEditor.ViewModels
             if (BitmapManager.ActiveDocument.Layers.Count == 0) return;
             if (Mouse.LeftButton == MouseButtonState.Pressed)
             {
-                _mouseMoveStartedOnCanvas = true;
                 if (!BitmapManager.MouseController.IsRecordingChanges)
                 {
-                    BitmapManager.MouseController.StartRecordingMouseMovementChanges();
+                    BitmapManager.MouseController.StartRecordingMouseMovementChanges(true);
                     BitmapManager.MouseController.RecordMouseMovementChange(MousePositionConverter.CurrentCoordinates);
                 }
             }
@@ -624,8 +617,6 @@ namespace PixiEditor.ViewModels
             Coordinates cords = new Coordinates((int) MouseXOnCanvas, (int) MouseYOnCanvas);
             MousePositionConverter.CurrentCoordinates = cords;
 
-            if (_mouseMoveStartedOnCanvas == false) return;
-
 
             if (BitmapManager.MouseController.IsRecordingChanges && Mouse.LeftButton == MouseButtonState.Pressed)
                 BitmapManager.MouseController.RecordMouseMovementChange(cords);