feat: add bend line pick mode with hit-testing to EntityView
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using OpenNest.Bending;
|
||||
using OpenNest.Geometry;
|
||||
using OpenNest.Math;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
@@ -17,6 +18,20 @@ namespace OpenNest.Controls
|
||||
private readonly Pen gridPen = new Pen(Color.FromArgb(70, 70, 70));
|
||||
private readonly Dictionary<int, Pen> penCache = new Dictionary<int, Pen>();
|
||||
|
||||
public event EventHandler<Line> LinePicked;
|
||||
public event EventHandler PickCancelled;
|
||||
|
||||
private bool isPickingBendLine;
|
||||
public bool IsPickingBendLine
|
||||
{
|
||||
get => isPickingBendLine;
|
||||
set
|
||||
{
|
||||
isPickingBendLine = value;
|
||||
Cursor = value ? Cursors.Hand : Cursors.Cross;
|
||||
}
|
||||
}
|
||||
|
||||
public EntityView()
|
||||
{
|
||||
Entities = new List<Entity>();
|
||||
@@ -34,6 +49,13 @@ namespace OpenNest.Controls
|
||||
{
|
||||
base.OnMouseClick(e);
|
||||
if (!Focused) Focus();
|
||||
|
||||
if (IsPickingBendLine && e.Button == MouseButtons.Left)
|
||||
{
|
||||
var line = HitTestLine(e.Location);
|
||||
if (line != null)
|
||||
LinePicked?.Invoke(this, line);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
@@ -123,6 +145,12 @@ namespace OpenNest.Controls
|
||||
|
||||
if (e.KeyCode == Keys.F)
|
||||
ZoomToFit();
|
||||
|
||||
if (IsPickingBendLine && e.KeyCode == Keys.Escape)
|
||||
{
|
||||
IsPickingBendLine = false;
|
||||
PickCancelled?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private Pen GetEntityPen(Color color)
|
||||
@@ -180,6 +208,32 @@ namespace OpenNest.Controls
|
||||
}
|
||||
}
|
||||
|
||||
private Line HitTestLine(Point controlPoint)
|
||||
{
|
||||
var worldPoint = PointControlToWorld(controlPoint);
|
||||
var tolerance = LengthGuiToWorld(6);
|
||||
Line bestLine = null;
|
||||
var bestDistance = double.MaxValue;
|
||||
|
||||
foreach (var entity in Entities)
|
||||
{
|
||||
if (entity.Type != EntityType.Line || !entity.IsVisible)
|
||||
continue;
|
||||
|
||||
var line = (Line)entity;
|
||||
var closest = line.ClosestPointTo(worldPoint);
|
||||
var distance = worldPoint.DistanceTo(closest);
|
||||
|
||||
if (distance < tolerance && distance < bestDistance)
|
||||
{
|
||||
bestLine = line;
|
||||
bestDistance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
return bestLine;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
|
||||
Reference in New Issue
Block a user