Skip to content

Commit 2093bd0

Browse files
committed
feat: add eraser tool
1 parent 2473faf commit 2093bd0

9 files changed

Lines changed: 64 additions & 59 deletions

File tree

CHANGELOG.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,22 @@ All notable changes to GhostDraw will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## v1.0.6
9+
10+
### Added
11+
- **Eraser Tool** - Remove drawing objects underneath the cursor
12+
- Press `E` to activate Eraser tool
13+
- Click and drag to erase drawings interactively
14+
- Eraser size adjusts with mouse wheel (same as brush thickness)
15+
- Intelligent intersection detection for precise erasing
16+
- Works with both polylines (pen strokes) and lines (straight line tool)
17+
- Custom eraser cursor with visual feedback
18+
- **Improved Code Quality**
19+
- Enhanced tool interface consistency
20+
21+
### Fixed
22+
- LineTool's `OnDeactivated` method now properly resets state without calling non-existent method
23+
824
## v1.0.5
925

1026
### Added
@@ -115,4 +131,3 @@ When adding new features or fixes:
115131

116132
### Fixed
117133
- Issue description and what was fixed
118-
```

Installer/GhostDraw.Installer.wixproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project Sdk="WixToolset.Sdk/4.0.5">
22
<PropertyGroup>
3-
<Version Condition="'$(Version)' == ''">1.0.5</Version>
3+
<Version Condition="'$(Version)' == ''">1.0.6</Version>
44
<OutputName>GhostDrawSetup-$(Version)</OutputName>
55
<OutputType>Package</OutputType>
66
<Platform>x64</Platform>

Src/GhostDraw/GhostDraw.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<UseWPF>true</UseWPF>
99
<UseWindowsForms>true</UseWindowsForms>
1010
<ApplicationIcon>Assets\favicon.ico</ApplicationIcon>
11-
<Version>1.0.5</Version>
11+
<Version>1.0.6</Version>
1212
</PropertyGroup>
1313

1414
<ItemGroup>

Src/GhostDraw/Tools/EraserTool.cs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,25 @@
11
using System.Windows;
22
using System.Windows.Controls;
33
using System.Windows.Input;
4-
using System.Windows.Media;
54
using System.Windows.Shapes;
65
using Microsoft.Extensions.Logging;
6+
using Point = System.Windows.Point;
77

88
namespace GhostDraw.Tools;
99

1010
/// <summary>
1111
/// Eraser tool - removes drawing objects underneath the cursor
1212
/// </summary>
13-
public class EraserTool : IDrawingTool
13+
public class EraserTool(ILogger<EraserTool> logger) : IDrawingTool
1414
{
15-
private readonly ILogger<EraserTool> _logger;
15+
private readonly ILogger<EraserTool> _logger = logger;
1616
private bool _isErasing = false;
1717
private double _currentThickness = 3.0;
1818
private readonly HashSet<UIElement> _erasedElements = new();
19-
19+
2020
// Tolerance for parallel line detection in intersection algorithm
2121
private const double PARALLEL_LINE_TOLERANCE = 0.001;
2222

23-
public EraserTool(ILogger<EraserTool> logger)
24-
{
25-
_logger = logger;
26-
}
27-
2823
public void OnMouseDown(Point position, Canvas canvas)
2924
{
3025
_isErasing = true;

Src/GhostDraw/Tools/IDrawingTool.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
using System.Windows;
21
using System.Windows.Controls;
32
using System.Windows.Input;
3+
using Point = System.Windows.Point;
44

55
namespace GhostDraw.Tools;
66

Src/GhostDraw/Tools/LineTool.cs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,28 @@
1-
using System.Windows;
21
using System.Windows.Controls;
32
using System.Windows.Input;
43
using System.Windows.Media;
54
using System.Windows.Shapes;
65
using Microsoft.Extensions.Logging;
6+
using Point = System.Windows.Point;
7+
using Brush = System.Windows.Media.Brush;
8+
using Brushes = System.Windows.Media.Brushes;
9+
using Color = System.Windows.Media.Color;
10+
using ColorConverter = System.Windows.Media.ColorConverter;
711

812
namespace GhostDraw.Tools;
913

1014
/// <summary>
1115
/// Straight line drawing tool - click two points to draw a line
1216
/// </summary>
13-
public class LineTool : IDrawingTool
17+
public class LineTool(ILogger<LineTool> logger) : IDrawingTool
1418
{
15-
private readonly ILogger<LineTool> _logger;
19+
private readonly ILogger<LineTool> _logger = logger;
1620
private Line? _currentLine;
1721
private Point? _lineStartPoint;
1822
private bool _isCreatingLine = false;
1923
private string _currentColor = "#FF0000";
2024
private double _currentThickness = 3.0;
2125

22-
public LineTool(ILogger<LineTool> logger)
23-
{
24-
_logger = logger;
25-
}
26-
2726
public void OnMouseDown(Point position, Canvas canvas)
2827
{
2928
if (!_isCreatingLine)
@@ -61,42 +60,47 @@ public void OnActivated()
6160
public void OnDeactivated()
6261
{
6362
_logger.LogDebug("Line tool deactivated");
64-
CancelCurrentLine();
63+
if (_currentLine != null)
64+
{
65+
_currentLine = null;
66+
_lineStartPoint = null;
67+
_isCreatingLine = false;
68+
}
6569
}
6670

6771
public void OnColorChanged(string colorHex)
6872
{
6973
_currentColor = colorHex;
70-
74+
7175
// Update in-progress line color if one exists
7276
if (_currentLine != null)
7377
{
7478
_currentLine.Stroke = CreateBrushFromHex(colorHex);
7579
}
76-
80+
7781
_logger.LogDebug("Line color changed to {Color}", colorHex);
7882
}
7983

8084
public void OnThicknessChanged(double thickness)
8185
{
8286
_currentThickness = thickness;
83-
87+
8488
// Update in-progress line thickness if one exists
8589
if (_currentLine != null)
8690
{
8791
_currentLine.StrokeThickness = thickness;
8892
}
89-
93+
9094
_logger.LogDebug("Line thickness changed to {Thickness}", thickness);
9195
}
9296

9397
private void StartNewLine(Point startPoint, Canvas canvas)
9498
{
9599
_lineStartPoint = startPoint;
96100
_isCreatingLine = true;
97-
101+
98102
var brush = CreateBrushFromHex(_currentColor);
99-
103+
100104
_currentLine = new Line
101105
{
102106
X1 = startPoint.X,
@@ -108,7 +112,7 @@ private void StartNewLine(Point startPoint, Canvas canvas)
108112
StrokeStartLineCap = PenLineCap.Round,
109113
StrokeEndLineCap = PenLineCap.Round
110114
};
111-
115+
112116
canvas.Children.Add(_currentLine);
113117
_logger.LogInformation("Line started at ({X:F0}, {Y:F0})", startPoint.X, startPoint.Y);
114118
}
@@ -119,17 +123,15 @@ private void FinishLine(Point endPoint)
119123
{
120124
_currentLine.X2 = endPoint.X;
121125
_currentLine.Y2 = endPoint.Y;
122-
126+
123127
_logger.LogInformation("Line finished at ({X:F0}, {Y:F0})", endPoint.X, endPoint.Y);
124128
}
125-
129+
126130
_currentLine = null;
127131
_lineStartPoint = null;
128132
_isCreatingLine = false;
129133
}
130134

131-
132-
133135
private Brush CreateBrushFromHex(string colorHex)
134136
{
135137
try

Src/GhostDraw/Tools/PenTool.cs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
1-
using System.Windows;
21
using System.Windows.Controls;
32
using System.Windows.Input;
43
using System.Windows.Media;
54
using System.Windows.Shapes;
65
using Microsoft.Extensions.Logging;
6+
using Point = System.Windows.Point;
7+
using Brush = System.Windows.Media.Brush;
8+
using Brushes = System.Windows.Media.Brushes;
9+
using Color = System.Windows.Media.Color;
10+
using ColorConverter = System.Windows.Media.ColorConverter;
711

812
namespace GhostDraw.Tools;
913

1014
/// <summary>
1115
/// Freehand drawing tool
1216
/// </summary>
13-
public class PenTool : IDrawingTool
17+
public class PenTool(ILogger<PenTool> logger) : IDrawingTool
1418
{
15-
private readonly ILogger<PenTool> _logger;
19+
private readonly ILogger<PenTool> _logger = logger;
1620
private Polyline? _currentStroke;
1721
private string _currentColor = "#FF0000";
1822
private double _currentThickness = 3.0;
1923

20-
public PenTool(ILogger<PenTool> logger)
21-
{
22-
_logger = logger;
23-
}
24-
2524
public void OnMouseDown(Point position, Canvas canvas)
2625
{
2726
_logger.LogInformation("Starting new stroke at ({X:F0}, {Y:F0})", position.X, position.Y);

Src/GhostDraw/ViewModels/SettingsViewModel.cs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,23 @@ namespace GhostDraw.ViewModels;
88
/// This enables proper MVVM pattern with dependency injection while keeping
99
/// UserControls visible in the XAML designer.
1010
/// </summary>
11-
public class SettingsViewModel
11+
public class SettingsViewModel(
12+
AppSettingsService appSettings,
13+
LoggingSettingsService loggingSettings,
14+
ILoggerFactory loggerFactory)
1215
{
1316
/// <summary>
1417
/// Service for managing application settings (brush, hotkey, mode, etc.)
1518
/// </summary>
16-
public AppSettingsService AppSettings { get; }
17-
19+
public AppSettingsService AppSettings { get; } = appSettings;
20+
1821
/// <summary>
1922
/// Service for managing logging configuration
2023
/// </summary>
21-
public LoggingSettingsService LoggingSettings { get; }
22-
24+
public LoggingSettingsService LoggingSettings { get; } = loggingSettings;
25+
2326
/// <summary>
2427
/// Factory for creating loggers for child controls
2528
/// </summary>
26-
public ILoggerFactory LoggerFactory { get; }
27-
28-
public SettingsViewModel(
29-
AppSettingsService appSettings,
30-
LoggingSettingsService loggingSettings,
31-
ILoggerFactory loggerFactory)
32-
{
33-
AppSettings = appSettings;
34-
LoggingSettings = loggingSettings;
35-
LoggerFactory = loggerFactory;
36-
}
29+
public ILoggerFactory LoggerFactory { get; } = loggerFactory;
3730
}

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ghost-draw",
3-
"version": "1.0.5",
3+
"version": "1.0.6",
44
"description": "Draw directly on your screen with a transparent overlay",
55
"repository": {
66
"type": "git",
@@ -24,7 +24,8 @@
2424
"format": "dotnet format GhostDraw.sln",
2525
"format:check": "dotnet format GhostDraw.sln --verify-no-changes",
2626
"version:check": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File Scripts/Update-Version.ps1 -CreateTag -PushTag -UpdateProjFiles -Bump patch -DryRun",
27-
"version:tag": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File Scripts/Update-Version.ps1 -CreateTag -PushTag -Bump patch -DryRun"
27+
"version:tag": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File Scripts/Update-Version.ps1 -CreateTag -PushTag -Bump patch -DryRun",
28+
"version:bump": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File Scripts/Update-Version.ps1 -CreateTag -PushTag -UpdateProjFiles -Bump patch"
2829
},
2930
"engines": {
3031
"node": ">=18.0.0",

0 commit comments

Comments
 (0)