Skip to content

Rectangle #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Pixed/Selection/LassoSelection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ private void VisitPixel(Point point, Frame frame)
return true;
});

foreach(var pixel in visited)
foreach (var pixel in visited)
{
SetPixel(new Point(pixel.X, pixel.Y), frameBorderReached ? OUTSIDE : INSIDE);
}
Expand Down
78 changes: 78 additions & 0 deletions Pixed/Tools/ShapeTool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using Pixed.Input;
using Pixed.Models;
using Pixed.Services.History;
using Pixed.Utils;
using System;
using System.Drawing;

namespace Pixed.Tools
{
internal abstract class ShapeTool : BaseTool
{
protected int _startX = -1;
protected int _startY = -1;

public override void ApplyTool(int x, int y, Frame frame, ref Bitmap overlay)
{
_startX = x;
_startY = y;

overlay.SetPixel(x, y, GetToolColor());
}

public override void MoveTool(int x, int y, Frame frame, ref Bitmap overlay)
{
overlay.Clear();
bool isShift = Keyboard.Modifiers.HasFlag(Avalonia.Input.KeyModifiers.Shift);
var color = GetToolColor();

if (color == UniColor.Transparent)
{
color = new UniColor(50, 160, 215, 240);
}

Draw(x, y, color, isShift, ref overlay);
}

public override void ReleaseTool(int x, int y, Frame frame, ref Bitmap overlay)
{
bool isShift = Keyboard.Modifiers.HasFlag(Avalonia.Input.KeyModifiers.Shift);
var color = GetToolColor();

var historyEntry = Draw(x, y, color, isShift, frame);
Global.CurrentModel.AddHistory(historyEntry);

overlay.Clear();
Subjects.RefreshCanvas.OnNext(null);
}

protected void Draw(int x, int y, int color, bool isShift, ref Bitmap overlay)
{
Bitmap bitmap = overlay;
Draw(x, y, color, isShift, (x, y, color) =>
{
bitmap.SetPixel(x, y, (UniColor)color);
});

overlay = bitmap;
}

protected HistoryEntry Draw(int x, int y, int color, bool isShift, Frame frame)
{
DynamicHistoryEntry entry = new()
{
FrameId = frame.Id,
LayerId = frame.Layers[frame.SelectedLayer].Id
};
Draw(x, y, color, isShift, (x1, y1, _) =>
{
int oldColor = frame.GetPixel(x1, y1);
entry.Add(x1, y1, oldColor, color);
frame.SetPixel(x1, y1, color);
});

return entry.ToEntry();
}
protected abstract void Draw(int x, int y, int color, bool isShift, Action<int, int, int> setPixelAction);
}
}
34 changes: 34 additions & 0 deletions Pixed/Tools/ToolRectangle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Pixed.Utils;
using System;

namespace Pixed.Tools
{
internal class ToolRectangle : ShapeTool
{
protected override void Draw(int x, int y, int color, bool isShift, Action<int, int, int> setPixelAction)
{
var rectangle = MathUtils.GetOrderedRectangle(_startX, _startY, x, y);

if (isShift)
{
int width = Math.Abs(rectangle[2] - rectangle[0]);
int height = Math.Abs(rectangle[3] - rectangle[1]);
int size = Math.Min(width, height);

rectangle[2] = rectangle[0] + size;
rectangle[3] = rectangle[1] + size;
}

for (int rx = rectangle[0]; rx <= rectangle[2]; rx++)
{
for (int ry = rectangle[1]; ry <= rectangle[3]; ry++)
{
if (rx == rectangle[0] || rx == rectangle[2] || ry == rectangle[1] || ry == rectangle[3])
{
setPixelAction.Invoke(rx, ry, color);
}
}
}
}
}
}
9 changes: 3 additions & 6 deletions Pixed/Tools/ToolSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public ToolSelector(Action<string> selectToolAction)
_tools.Add("tool_mirror_pen", new ToolVerticalPen());
_tools.Add("tool_colorswap", new ToolColorSwap());
_tools.Add("tool_stroke", new ToolStroke());
_tools.Add("tool_rectangle", new ToolRectangle());
}

public void SelectTool(string name)
Expand All @@ -33,11 +34,7 @@ public void SelectTool(string name)
}
public BaseTool? GetTool(string name)
{
if (_tools.ContainsKey(name))
{
return _tools[name];
}

return null;
_tools.TryGetValue(name, out BaseTool? value);
return value;
}
}
74 changes: 4 additions & 70 deletions Pixed/Tools/ToolStroke.cs
Original file line number Diff line number Diff line change
@@ -1,83 +1,17 @@
using Pixed.Input;
using Pixed.Models;
using Pixed.Services.History;
using Pixed.Utils;
using Pixed.Utils;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Pixed.Tools
{
internal class ToolStroke : BaseTool
internal class ToolStroke : ShapeTool
{
private int _startX = -1;
private int _startY = -1;

public override void ApplyTool(int x, int y, Frame frame, ref Bitmap overlay)
{
_startX = x;
_startY = y;

overlay.SetPixel(x, y, GetToolColor());
}

public override void MoveTool(int x, int y, Frame frame, ref Bitmap overlay)
{
overlay.Clear();
bool isStraight = Keyboard.Modifiers.HasFlag(Avalonia.Input.KeyModifiers.Shift);
var color = GetToolColor();

if(color == UniColor.Transparent)
{
color = new UniColor(50, 160, 215, 240);
}

DrawLine(x, y, color, isStraight, overlay);
}

public override void ReleaseTool(int x, int y, Frame frame, ref Bitmap overlay)
{
bool isStraight = Keyboard.Modifiers.HasFlag(Avalonia.Input.KeyModifiers.Shift);
var color = GetToolColor();

var historyEntry = DrawLine(x, y, color, isStraight, frame);
Global.CurrentModel.AddHistory(historyEntry);

overlay.Clear();
Subjects.RefreshCanvas.OnNext(null);
}

private void DrawLine(int x, int y, int color, bool isStraight, Bitmap overlay)
{
DrawLine(x, y, color, isStraight, (x, y, color) =>
{
overlay.SetPixel(x, y, (UniColor)color);
});
}

private HistoryEntry DrawLine(int x, int y, int color, bool isStraight, Frame frame)
{
DynamicHistoryEntry entry = new DynamicHistoryEntry();
entry.FrameId = frame.Id;
entry.LayerId = frame.Layers[frame.SelectedLayer].Id;
DrawLine(x, y, color, isStraight, (x1, y1, _) =>
{
int oldColor = frame.GetPixel(x1, y1);
entry.Add(x1, y1, oldColor, color);
frame.SetPixel(x1, y1, color);
});

return entry.ToEntry();
}

private void DrawLine(int x, int y, int color, bool isStraight, Action<int, int, int> setPixelAction)
protected override void Draw(int x, int y, int color, bool isShift, Action<int, int, int> setPixelAction)
{
List<Point> linePixels;

if (isStraight)
if (isShift)
{
linePixels = MathUtils.GetUniformLinePixels(_startX, _startY, x, y);
}
Expand Down
17 changes: 10 additions & 7 deletions Pixed/Utils/MathUtils.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using Avalonia.Media.TextFormatting.Unicode;
using System;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Numerics;

namespace Pixed.Utils;

Expand Down Expand Up @@ -55,7 +53,7 @@ public static List<Point> GetUniformLinePixels(int x0, int y0, int x1, int y1)

var ratio = (double)Math.Max(dx, dy) / (double)Math.Min(dx, dy);
var step = Math.Round(ratio);
if(step > Math.Min(dx, dy))
if (step > Math.Min(dx, dy))
{
step = double.MaxValue;
}
Expand All @@ -66,7 +64,7 @@ public static List<Point> GetUniformLinePixels(int x0, int y0, int x1, int y1)
var y = y0;
int i = 0;

while(true)
while (true)
{
i++;
pixels.Add(new Point(x, y));
Expand All @@ -77,12 +75,12 @@ public static List<Point> GetUniformLinePixels(int x0, int y0, int x1, int y1)

bool isAtStep = (int)(i % step) == 0;

if(dx >= dy || isAtStep)
if (dx >= dy || isAtStep)
{
x += sx;
}

if(dy >= dx || isAtStep)
if (dy >= dx || isAtStep)
{
y += sy;
}
Expand All @@ -97,4 +95,9 @@ public static double Distance(int x0, int y0, int x1, int y1)
var dy = Math.Abs((double)y1 - (double)y0);
return Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2));
}

public static int[] GetOrderedRectangle(int x0, int y0, int x1, int y1)
{
return [Math.Min(x0, x1), Math.Min(y0, y1), Math.Max(x0, x1), Math.Max(y0, y1)];
}
}
2 changes: 1 addition & 1 deletion Pixed/Utils/PaintUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public static DynamicHistoryEntry PaintSimiliarConnected(Layer layer, int x, int
return false;
});

foreach(var pixel in pixels)
foreach (var pixel in pixels)
{
layer.SetPixel(pixel.X, pixel.Y, replacementColor);
entry.Add(pixel.X, pixel.Y, pixel.Color, replacementColor);
Expand Down