Restructure project layout to flatten directory structure
Move all projects from Source/ to repository root for simpler navigation. - Remove External/ dependency DLLs (will use NuGet packages) - Remove Installer/ NSIS script - Replace PartCollection/PlateCollection with ObservableList - Add packages.config for NuGet dependencies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
using OpenNest.Controls;
|
||||
|
||||
namespace OpenNest.Actions
|
||||
{
|
||||
public abstract class Action
|
||||
{
|
||||
protected PlateView plateView;
|
||||
|
||||
protected Action(PlateView plateView)
|
||||
{
|
||||
this.plateView = plateView;
|
||||
}
|
||||
|
||||
public abstract void DisconnectEvents();
|
||||
|
||||
public abstract void CancelAction();
|
||||
|
||||
public abstract bool IsBusy();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using OpenNest.Controls;
|
||||
|
||||
namespace OpenNest.Actions
|
||||
{
|
||||
[DisplayName("Add Parts")]
|
||||
public class ActionAddPart : Action
|
||||
{
|
||||
private LayoutPart part;
|
||||
private double lastScale;
|
||||
|
||||
public ActionAddPart(PlateView plateView)
|
||||
: this(plateView, null)
|
||||
{
|
||||
}
|
||||
|
||||
public ActionAddPart(PlateView plateView, Drawing drawing)
|
||||
: base(plateView)
|
||||
{
|
||||
plateView.KeyDown += plateView_KeyDown;
|
||||
plateView.MouseMove += plateView_MouseMove;
|
||||
plateView.MouseDown += plateView_MouseDown;
|
||||
plateView.Paint += plateView_Paint;
|
||||
|
||||
part = LayoutPart.Create(new Part(drawing), plateView);
|
||||
part.IsSelected = true;
|
||||
|
||||
lastScale = double.NaN;
|
||||
|
||||
plateView.SelectedParts.Clear();
|
||||
plateView.SelectedParts.Add(part);
|
||||
}
|
||||
|
||||
private void plateView_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
switch (e.Button)
|
||||
{
|
||||
case MouseButtons.Left:
|
||||
Apply();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void plateView_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
switch (e.KeyCode)
|
||||
{
|
||||
case Keys.F1:
|
||||
case Keys.Enter:
|
||||
Apply();
|
||||
break;
|
||||
|
||||
case Keys.F:
|
||||
if ((Control.ModifierKeys & Keys.Control) == Keys.Control)
|
||||
Fill();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void plateView_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
if (plateView.ViewScale != lastScale)
|
||||
{
|
||||
part.Update(plateView);
|
||||
part.Draw(e.Graphics);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (part.IsDirty)
|
||||
part.Update(plateView);
|
||||
|
||||
part.Draw(e.Graphics);
|
||||
}
|
||||
|
||||
lastScale = plateView.ViewScale;
|
||||
}
|
||||
|
||||
private void plateView_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
var offset = plateView.CurrentPoint - part.BoundingBox.Location;
|
||||
part.Offset(offset);
|
||||
plateView.Invalidate();
|
||||
}
|
||||
|
||||
public override void DisconnectEvents()
|
||||
{
|
||||
plateView.KeyDown -= plateView_KeyDown;
|
||||
plateView.MouseMove -= plateView_MouseMove;
|
||||
plateView.MouseDown -= plateView_MouseDown;
|
||||
plateView.Paint -= plateView_Paint;
|
||||
|
||||
plateView.SelectedParts.Clear();
|
||||
plateView.Invalidate();
|
||||
}
|
||||
|
||||
public override void CancelAction()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool IsBusy()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private void Fill()
|
||||
{
|
||||
var boxes = new List<Box>();
|
||||
|
||||
foreach (var part in plateView.Plate.Parts)
|
||||
boxes.Add(part.BoundingBox.Offset(plateView.Plate.PartSpacing));
|
||||
|
||||
var bounds = plateView.Plate.WorkArea();
|
||||
|
||||
var vbox = Helper.GetLargestBoxVertically(plateView.CurrentPoint, bounds, boxes);
|
||||
var hbox = Helper.GetLargestBoxHorizontally(plateView.CurrentPoint, bounds, boxes);
|
||||
|
||||
var box = vbox.Area() > hbox.Area() ? vbox : hbox;
|
||||
|
||||
var engine = new NestEngine(plateView.Plate);
|
||||
engine.FillArea(box, new NestItem { Drawing = this.part.BasePart.BaseDrawing });
|
||||
}
|
||||
|
||||
private void Apply()
|
||||
{
|
||||
if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
|
||||
{
|
||||
switch (plateView.Plate.Quadrant)
|
||||
{
|
||||
case 1:
|
||||
plateView.PushSelected(PushDirection.Left);
|
||||
plateView.PushSelected(PushDirection.Down);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
plateView.PushSelected(PushDirection.Right);
|
||||
plateView.PushSelected(PushDirection.Down);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
plateView.PushSelected(PushDirection.Right);
|
||||
plateView.PushSelected(PushDirection.Up);
|
||||
break;
|
||||
case 4:
|
||||
plateView.PushSelected(PushDirection.Left);
|
||||
plateView.PushSelected(PushDirection.Up);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
plateView.Plate.Parts.Add(part.BasePart.Clone() as Part);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using OpenNest.Controls;
|
||||
|
||||
namespace OpenNest.Actions
|
||||
{
|
||||
[DisplayName("Clone Parts")]
|
||||
public class ActionClone : Action
|
||||
{
|
||||
private readonly List<LayoutPart> parts;
|
||||
|
||||
private double lastScale;
|
||||
|
||||
public ActionClone(PlateView plateView, List<Part> partsToClone)
|
||||
: base(plateView)
|
||||
{
|
||||
plateView.KeyDown += plateView_KeyDown;
|
||||
plateView.MouseMove += plateView_MouseMove;
|
||||
plateView.MouseDown += plateView_MouseDown;
|
||||
plateView.Paint += plateView_Paint;
|
||||
|
||||
parts = new List<LayoutPart>();
|
||||
lastScale = double.NaN;
|
||||
|
||||
for (int i = 0; i < partsToClone.Count; i++)
|
||||
{
|
||||
var part = LayoutPart.Create(partsToClone[i].Clone() as Part, plateView);
|
||||
part.IsSelected = true;
|
||||
parts.Add(part);
|
||||
}
|
||||
|
||||
plateView.SelectedParts.Clear();
|
||||
plateView.SelectedParts.AddRange(parts);
|
||||
}
|
||||
|
||||
private void plateView_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
switch (e.Button)
|
||||
{
|
||||
case MouseButtons.Left:
|
||||
Apply();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void plateView_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
switch (e.KeyCode)
|
||||
{
|
||||
case Keys.F1:
|
||||
case Keys.Enter:
|
||||
Apply();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void plateView_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
if (plateView.ViewScale != lastScale)
|
||||
{
|
||||
parts.ForEach(p =>
|
||||
{
|
||||
p.Update(plateView);
|
||||
p.Draw(e.Graphics);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
parts.ForEach(p =>
|
||||
{
|
||||
if (p.IsDirty)
|
||||
p.Update(plateView);
|
||||
|
||||
p.Draw(e.Graphics);
|
||||
});
|
||||
}
|
||||
|
||||
lastScale = plateView.ViewScale;
|
||||
}
|
||||
|
||||
private void plateView_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
var offset = plateView.CurrentPoint - parts.GetBoundingBox().Location;
|
||||
parts.ForEach(p => p.Offset(offset));
|
||||
plateView.Invalidate();
|
||||
}
|
||||
|
||||
public override void DisconnectEvents()
|
||||
{
|
||||
plateView.KeyDown -= plateView_KeyDown;
|
||||
plateView.MouseMove -= plateView_MouseMove;
|
||||
plateView.MouseDown -= plateView_MouseDown;
|
||||
plateView.Paint -= plateView_Paint;
|
||||
|
||||
plateView.SelectedParts.Clear();
|
||||
plateView.Invalidate();
|
||||
}
|
||||
|
||||
public override void CancelAction()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool IsBusy()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Apply()
|
||||
{
|
||||
if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
|
||||
{
|
||||
plateView.PushSelected(PushDirection.Left);
|
||||
plateView.PushSelected(PushDirection.Down);
|
||||
}
|
||||
|
||||
parts.ForEach(p => plateView.Plate.Parts.Add(p.BasePart.Clone() as Part));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using OpenNest.Controls;
|
||||
|
||||
namespace OpenNest.Actions
|
||||
{
|
||||
[DisplayName("Fill Area")]
|
||||
public class ActionFillArea : ActionSelectArea
|
||||
{
|
||||
private Drawing drawing;
|
||||
|
||||
public ActionFillArea(PlateView plateView, Drawing drawing)
|
||||
: base(plateView)
|
||||
{
|
||||
plateView.PreviewKeyDown += plateView_PreviewKeyDown;
|
||||
this.drawing = drawing;
|
||||
}
|
||||
|
||||
private void plateView_PreviewKeyDown(object sender, System.Windows.Forms.PreviewKeyDownEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Enter)
|
||||
FillArea();
|
||||
}
|
||||
|
||||
private void FillArea()
|
||||
{
|
||||
var engine = new NestEngine(plateView.Plate);
|
||||
engine.FillArea(SelectedArea, new NestItem
|
||||
{
|
||||
Drawing = drawing
|
||||
});
|
||||
|
||||
plateView.Invalidate();
|
||||
Update();
|
||||
}
|
||||
|
||||
public override void DisconnectEvents()
|
||||
{
|
||||
plateView.PreviewKeyDown -= plateView_PreviewKeyDown;
|
||||
base.DisconnectEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using OpenNest.Controls;
|
||||
|
||||
namespace OpenNest.Actions
|
||||
{
|
||||
[DisplayName("Select")]
|
||||
public class ActionSelect : Action
|
||||
{
|
||||
private readonly Pen borderPenContain;
|
||||
private readonly Pen borderPenIntersect;
|
||||
private readonly Brush fillBrushContain;
|
||||
private readonly Brush fillBrushIntersect;
|
||||
|
||||
private Pen borderPen;
|
||||
private Brush fillBrush;
|
||||
|
||||
public Vector Point1;
|
||||
public Vector Point2;
|
||||
|
||||
private Status status;
|
||||
|
||||
public ActionSelect(PlateView plateView)
|
||||
: base(plateView)
|
||||
{
|
||||
borderPenIntersect = new Pen(Color.FromArgb(50, 255, 50));
|
||||
fillBrushIntersect = new SolidBrush(Color.FromArgb(50, 50, 255, 50));
|
||||
|
||||
borderPenContain = new Pen(Color.FromArgb(99, 162, 228));
|
||||
fillBrushContain = new SolidBrush(Color.FromArgb(90, 150, 200, 255));
|
||||
|
||||
UpdateBrushAndPen();
|
||||
|
||||
status = Status.SetFirstPoint;
|
||||
|
||||
plateView.MouseDown += plateView_MouseDown;
|
||||
plateView.MouseUp += plateView_MouseUp;
|
||||
plateView.MouseMove += plateView_MouseMove;
|
||||
plateView.Paint += plateView_Paint;
|
||||
}
|
||||
|
||||
public override void DisconnectEvents()
|
||||
{
|
||||
plateView.MouseDown -= plateView_MouseDown;
|
||||
plateView.MouseUp -= plateView_MouseUp;
|
||||
plateView.MouseMove -= plateView_MouseMove;
|
||||
plateView.Paint -= plateView_Paint;
|
||||
}
|
||||
|
||||
public override void CancelAction()
|
||||
{
|
||||
status = Status.SetFirstPoint;
|
||||
|
||||
plateView.DeselectAll();
|
||||
plateView.Invalidate();
|
||||
}
|
||||
|
||||
public override bool IsBusy()
|
||||
{
|
||||
return status != Status.SetFirstPoint || plateView.SelectedParts.Count > 0;
|
||||
}
|
||||
|
||||
private void plateView_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button != MouseButtons.Left)
|
||||
return;
|
||||
|
||||
if (status == Status.SetSecondPoint)
|
||||
{
|
||||
Point2 = plateView.PointControlToWorld(e.Location);
|
||||
UpdateBrushAndPen();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (plateView.SelectedParts.Count == 0)
|
||||
return;
|
||||
|
||||
var offset = plateView.CurrentPoint - plateView.LastPoint;
|
||||
|
||||
foreach (var part in plateView.SelectedParts)
|
||||
part.Offset(offset.X, offset.Y);
|
||||
}
|
||||
|
||||
plateView.Invalidate();
|
||||
}
|
||||
|
||||
private void plateView_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (!plateView.AllowSelect)
|
||||
return;
|
||||
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
if (plateView.SelectedParts.Count > 0)
|
||||
{
|
||||
var part = plateView.GetPartAtControlPoint(e.Location);
|
||||
|
||||
if (part == null)
|
||||
CancelAction();
|
||||
}
|
||||
|
||||
if (SelectPartAtCurrentPoint())
|
||||
return;
|
||||
|
||||
if (status == Status.SetFirstPoint)
|
||||
{
|
||||
Point1 = plateView.PointControlToWorld(e.Location);
|
||||
Point2 = Point1;
|
||||
status = Status.SetSecondPoint;
|
||||
}
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
CancelAction();
|
||||
}
|
||||
}
|
||||
|
||||
private void plateView_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (!plateView.AllowSelect)
|
||||
return;
|
||||
|
||||
if (e.Button != MouseButtons.Left)
|
||||
return;
|
||||
|
||||
if (status == Status.SetSecondPoint)
|
||||
{
|
||||
Point2 = plateView.PointControlToWorld(e.Location);
|
||||
SelectPartsInWindow();
|
||||
|
||||
plateView.Invalidate();
|
||||
status = Status.SetFirstPoint;
|
||||
}
|
||||
}
|
||||
|
||||
private void plateView_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
if (status != Status.SetSecondPoint)
|
||||
return;
|
||||
|
||||
var rect = GetRectangle();
|
||||
|
||||
e.Graphics.FillRectangle(fillBrush, rect);
|
||||
|
||||
e.Graphics.DrawRectangle(borderPen,
|
||||
rect.X,
|
||||
rect.Y,
|
||||
rect.Width,
|
||||
rect.Height);
|
||||
}
|
||||
|
||||
private bool SelectPartAtCurrentPoint()
|
||||
{
|
||||
var part = plateView.GetPartAtPoint(plateView.CurrentPoint);
|
||||
|
||||
if (part == null)
|
||||
{
|
||||
plateView.DeselectAll();
|
||||
status = Status.SetFirstPoint;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Control.ModifierKeys != Keys.Control && plateView.SelectedParts.Contains(part) == false)
|
||||
plateView.DeselectAll();
|
||||
|
||||
if (plateView.SelectedParts.Contains(part) == false)
|
||||
{
|
||||
plateView.SelectedParts.Add(part);
|
||||
part.IsSelected = true;
|
||||
}
|
||||
|
||||
plateView.Invalidate();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SelectPartsInWindow()
|
||||
{
|
||||
var parts = plateView.GetPartsFromWindow(GetRectangle(), SelectionType);
|
||||
|
||||
foreach (var part in parts)
|
||||
{
|
||||
if (plateView.SelectedParts.Contains(part))
|
||||
continue;
|
||||
|
||||
plateView.SelectedParts.Add(part);
|
||||
part.IsSelected = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateBrushAndPen()
|
||||
{
|
||||
if (SelectionType == SelectionType.Intersect)
|
||||
{
|
||||
borderPen = borderPenIntersect;
|
||||
fillBrush = fillBrushIntersect;
|
||||
}
|
||||
else
|
||||
{
|
||||
borderPen = borderPenContain;
|
||||
fillBrush = fillBrushContain;
|
||||
}
|
||||
}
|
||||
|
||||
private RectangleF GetRectangle()
|
||||
{
|
||||
var rect = new RectangleF();
|
||||
var pt1 = plateView.PointWorldToGraph(Point1);
|
||||
var pt2 = plateView.PointWorldToGraph(Point2);
|
||||
|
||||
if (pt1.X < pt2.X)
|
||||
{
|
||||
rect.X = pt1.X;
|
||||
rect.Width = pt2.X - pt1.X;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.X = pt2.X;
|
||||
rect.Width = pt1.X - pt2.X;
|
||||
}
|
||||
|
||||
if (pt1.Y < pt2.Y)
|
||||
{
|
||||
rect.Y = pt1.Y;
|
||||
rect.Height = pt2.Y - pt1.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.Y = pt2.Y;
|
||||
rect.Height = pt1.Y - pt2.Y;
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
public SelectionType SelectionType
|
||||
{
|
||||
get
|
||||
{
|
||||
return Point1.X < Point2.X
|
||||
? SelectionType.Contains
|
||||
: SelectionType.Intersect;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Status
|
||||
{
|
||||
SetFirstPoint,
|
||||
SetSecondPoint
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using OpenNest.Controls;
|
||||
|
||||
namespace OpenNest.Actions
|
||||
{
|
||||
[DisplayName("Select Area")]
|
||||
public class ActionSelectArea : Action
|
||||
{
|
||||
public Box SelectedArea { get; private set; }
|
||||
private Box Bounds { get; set; }
|
||||
private List<Box> boxes { get; set; }
|
||||
|
||||
private bool dynamicSelect;
|
||||
private bool altSelect;
|
||||
|
||||
private readonly Pen pen;
|
||||
private readonly Brush brush;
|
||||
|
||||
private readonly Font font;
|
||||
private readonly StringFormat stringFormat;
|
||||
|
||||
public ActionSelectArea(PlateView plateView)
|
||||
: base(plateView)
|
||||
{
|
||||
boxes = new List<Box>();
|
||||
pen = new Pen(Color.FromArgb(50, 255, 50));
|
||||
brush = new SolidBrush(Color.FromArgb(50, 50, 255, 50));
|
||||
font = new Font(SystemFonts.DefaultFont.FontFamily, 14);
|
||||
|
||||
stringFormat = new StringFormat
|
||||
{
|
||||
Alignment = StringAlignment.Center,
|
||||
LineAlignment = StringAlignment.Center
|
||||
};
|
||||
|
||||
SelectedArea = Box.Empty;
|
||||
dynamicSelect = true;
|
||||
|
||||
Update();
|
||||
|
||||
if (dynamicSelect)
|
||||
plateView.MouseMove += plateView_MouseMove;
|
||||
else
|
||||
plateView.MouseClick += plateView_MouseClick;
|
||||
|
||||
plateView.KeyUp += plateView_KeyUp;
|
||||
plateView.Paint += plateView_Paint;
|
||||
}
|
||||
|
||||
private void plateView_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
switch (e.KeyCode)
|
||||
{
|
||||
case Keys.Space:
|
||||
altSelect = !altSelect;
|
||||
UpdateSelectedArea();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public bool DynamicSelect
|
||||
{
|
||||
get { return dynamicSelect; }
|
||||
set
|
||||
{
|
||||
if (value == dynamicSelect)
|
||||
return;
|
||||
|
||||
dynamicSelect = value;
|
||||
|
||||
if (dynamicSelect)
|
||||
{
|
||||
plateView.MouseMove += plateView_MouseMove;
|
||||
plateView.MouseClick -= plateView_MouseClick;
|
||||
}
|
||||
else
|
||||
{
|
||||
plateView.MouseMove -= plateView_MouseMove;
|
||||
plateView.MouseClick += plateView_MouseClick;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void plateView_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
|
||||
{
|
||||
if (SelectedArea == Box.Empty)
|
||||
return;
|
||||
|
||||
var location = plateView.PointWorldToGraph(SelectedArea.Location);
|
||||
var size = new SizeF(
|
||||
plateView.LengthWorldToGui(SelectedArea.Width),
|
||||
plateView.LengthWorldToGui(SelectedArea.Height));
|
||||
|
||||
var rect = new System.Drawing.RectangleF(location.X, location.Y - size.Height, size.Width, size.Height);
|
||||
|
||||
e.Graphics.DrawRectangle(pen,
|
||||
rect.X,
|
||||
rect.Y,
|
||||
rect.Width,
|
||||
rect.Height);
|
||||
|
||||
e.Graphics.FillRectangle(brush, rect);
|
||||
|
||||
e.Graphics.DrawString(
|
||||
SelectedArea.Size.ToString(2),
|
||||
font,
|
||||
Brushes.Green,
|
||||
rect,
|
||||
stringFormat);
|
||||
}
|
||||
|
||||
private void plateView_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
|
||||
{
|
||||
UpdateSelectedArea();
|
||||
}
|
||||
|
||||
private void plateView_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
|
||||
{
|
||||
if (e.Button != System.Windows.Forms.MouseButtons.Left)
|
||||
return;
|
||||
|
||||
UpdateSelectedArea();
|
||||
plateView.Invalidate();
|
||||
}
|
||||
|
||||
public override void DisconnectEvents()
|
||||
{
|
||||
plateView.KeyUp -= plateView_KeyUp;
|
||||
plateView.MouseMove -= plateView_MouseMove;
|
||||
plateView.MouseClick -= plateView_MouseClick;
|
||||
plateView.Paint -= plateView_Paint;
|
||||
}
|
||||
|
||||
public override void CancelAction()
|
||||
{
|
||||
plateView.Invalidate();
|
||||
}
|
||||
|
||||
public override bool IsBusy()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private void UpdateSelectedArea()
|
||||
{
|
||||
SelectedArea = altSelect
|
||||
? Helper.GetLargestBoxHorizontally(plateView.CurrentPoint, Bounds, boxes)
|
||||
: Helper.GetLargestBoxVertically(plateView.CurrentPoint, Bounds, boxes);
|
||||
|
||||
plateView.Invalidate();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
foreach (var part in plateView.Plate.Parts)
|
||||
boxes.Add(part.BoundingBox.Offset(plateView.Plate.PartSpacing));
|
||||
|
||||
Bounds = plateView.Plate.WorkArea();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using OpenNest.Controls;
|
||||
using OpenNest.Forms;
|
||||
using OpenNest.Geometry;
|
||||
|
||||
namespace OpenNest.Actions
|
||||
{
|
||||
[DisplayName("Set Sequence")]
|
||||
public class ActionSetSequence : Action
|
||||
{
|
||||
private readonly SequenceForm SequenceForm;
|
||||
private readonly List<Pair> ShapePartPairs;
|
||||
private readonly Pen pen;
|
||||
|
||||
private Shape ClosestShape;
|
||||
private Part ClosestPart;
|
||||
private int sequenceNumber = 1;
|
||||
|
||||
public int SequenceNumber
|
||||
{
|
||||
get { return sequenceNumber; }
|
||||
set
|
||||
{
|
||||
if (value <= SequenceForm.numericUpDown1.Maximum && value >= SequenceForm.numericUpDown1.Minimum)
|
||||
{
|
||||
sequenceNumber = value;
|
||||
SequenceForm.numericUpDown1.Value = sequenceNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ActionSetSequence(PlateView plateView)
|
||||
: base(plateView)
|
||||
{
|
||||
SequenceForm = new Forms.SequenceForm();
|
||||
SequenceForm.numericUpDown1.DataBindings.Add("Value", this, "SequenceNumber", false, DataSourceUpdateMode.OnPropertyChanged);
|
||||
SequenceForm.numericUpDown1.Maximum = plateView.Plate.Parts.Count;
|
||||
SequenceForm.Owner = Application.OpenForms[0];
|
||||
SequenceForm.Show();
|
||||
plateView.Invalidate();
|
||||
|
||||
pen = new Pen(Color.Blue, 2.0f);
|
||||
|
||||
ShapePartPairs = new List<Pair>();
|
||||
|
||||
foreach (var part in plateView.Plate.Parts)
|
||||
{
|
||||
var entities = ConvertProgram.ToGeometry(part.Program).Where(e => e.Layer == SpecialLayers.Cut).ToList();
|
||||
entities.ForEach(entity => entity.Offset(part.Location));
|
||||
var shapes = Helper.GetShapes(entities);
|
||||
var shape = new Shape();
|
||||
shape.Entities.AddRange(shapes);
|
||||
ShapePartPairs.Add(new Pair() { Part = part, Shape = shape });
|
||||
}
|
||||
|
||||
plateView.MouseMove += plateView_MouseMove;
|
||||
plateView.MouseClick += plateView_MouseClick;
|
||||
plateView.Paint += plateView_Paint;
|
||||
|
||||
SequenceNumber = 1;
|
||||
}
|
||||
|
||||
private void plateView_MouseClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Right)
|
||||
CancelAction();
|
||||
|
||||
if (e.Button != MouseButtons.Left)
|
||||
return;
|
||||
|
||||
if (SequenceNumber > plateView.Plate.Parts.Count)
|
||||
SequenceNumber = plateView.Plate.Parts.Count;
|
||||
|
||||
if (ClosestPart == null)
|
||||
return;
|
||||
|
||||
plateView.Plate.Parts.Remove(ClosestPart);
|
||||
plateView.Plate.Parts.Insert(SequenceNumber - 1, ClosestPart);
|
||||
|
||||
SequenceNumber++;
|
||||
|
||||
plateView.Invalidate();
|
||||
}
|
||||
|
||||
private void plateView_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
var pair = GetClosestShape();
|
||||
ClosestShape = pair.HasValue ? pair.Value.Shape : null;
|
||||
ClosestPart = pair.HasValue ? pair.Value.Part : null;
|
||||
plateView.Invalidate();
|
||||
}
|
||||
|
||||
private void plateView_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
if (ClosestShape == null) return;
|
||||
|
||||
var path = ClosestShape.GetGraphicsPath();
|
||||
path.Transform(plateView.Matrix);
|
||||
e.Graphics.DrawPath(pen, path);
|
||||
path.Dispose();
|
||||
}
|
||||
|
||||
private Pair? GetClosestShape()
|
||||
{
|
||||
Pair? closestShape = null;
|
||||
double distance = double.MaxValue;
|
||||
|
||||
for (int i = 0; i < ShapePartPairs.Count; i++)
|
||||
{
|
||||
var shape = ShapePartPairs[i];
|
||||
var closestPt = shape.Shape.ClosestPointTo(plateView.CurrentPoint);
|
||||
var distance2 = closestPt.DistanceTo(plateView.CurrentPoint);
|
||||
|
||||
if (distance2 < distance)
|
||||
{
|
||||
closestShape = shape;
|
||||
distance = distance2;
|
||||
}
|
||||
}
|
||||
|
||||
return closestShape;
|
||||
}
|
||||
|
||||
public override void DisconnectEvents()
|
||||
{
|
||||
plateView.Paint -= plateView_Paint;
|
||||
plateView.MouseMove -= plateView_MouseMove;
|
||||
plateView.MouseClick -= plateView_MouseClick;
|
||||
plateView.Invalidate();
|
||||
|
||||
SequenceForm.Close();
|
||||
}
|
||||
|
||||
public override void CancelAction()
|
||||
{
|
||||
SequenceNumber = 1;
|
||||
SequenceForm.numericUpDown1.Value = SequenceNumber + 1;
|
||||
}
|
||||
|
||||
public override bool IsBusy()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private struct Pair
|
||||
{
|
||||
public Part Part;
|
||||
public Shape Shape;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using OpenNest.Controls;
|
||||
|
||||
namespace OpenNest.Actions
|
||||
{
|
||||
[DisplayName("Zoom Window")]
|
||||
public class ActionZoomWindow : Action
|
||||
{
|
||||
public Vector Point1;
|
||||
public Vector Point2;
|
||||
|
||||
private readonly Pen borderPen;
|
||||
private readonly Brush fillBrush;
|
||||
|
||||
private Status status;
|
||||
|
||||
public ActionZoomWindow(PlateView plateView)
|
||||
: base(plateView)
|
||||
{
|
||||
borderPen = new Pen(Color.FromArgb(99, 162, 228));
|
||||
fillBrush = new SolidBrush(Color.FromArgb(90, 150, 200, 255));
|
||||
|
||||
status = Status.SetFirstPoint;
|
||||
|
||||
plateView.Cursor = Cursors.Arrow;
|
||||
plateView.MouseDown += plateView_MouseDown;
|
||||
plateView.MouseUp += plateView_MouseUp;
|
||||
plateView.MouseMove += plateView_MouseMove;
|
||||
plateView.Paint += plateView_Paint;
|
||||
}
|
||||
|
||||
public override void DisconnectEvents()
|
||||
{
|
||||
plateView.Cursor = Cursors.Cross;
|
||||
plateView.MouseDown -= plateView_MouseDown;
|
||||
plateView.MouseUp -= plateView_MouseUp;
|
||||
plateView.MouseMove -= plateView_MouseMove;
|
||||
plateView.Paint -= plateView_Paint;
|
||||
}
|
||||
|
||||
public override void CancelAction()
|
||||
{
|
||||
Point1 = Vector.Invalid;
|
||||
Point2 = Vector.Invalid;
|
||||
|
||||
plateView.Invalidate();
|
||||
status = Status.SetFirstPoint;
|
||||
}
|
||||
|
||||
public override bool IsBusy()
|
||||
{
|
||||
return status != Status.SetFirstPoint;
|
||||
}
|
||||
|
||||
private void plateView_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (status == Status.SetSecondPoint || e.Button == MouseButtons.Left)
|
||||
{
|
||||
Point2 = plateView.PointControlToWorld(e.Location);
|
||||
plateView.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void plateView_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
CancelAction();
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.Button != MouseButtons.Left)
|
||||
return;
|
||||
|
||||
if (e.Button == MouseButtons.Left && status == Status.SetFirstPoint)
|
||||
{
|
||||
Point1 = plateView.PointControlToWorld(e.Location);
|
||||
Point2 = Point1;
|
||||
plateView.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void plateView_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button != MouseButtons.Left)
|
||||
return;
|
||||
|
||||
Point2 = plateView.PointControlToWorld(e.Location);
|
||||
|
||||
if (status == Status.SetFirstPoint)
|
||||
{
|
||||
var distance1 = Point1.DistanceTo(Point2);
|
||||
var distance2 = plateView.LengthWorldToGui(distance1);
|
||||
|
||||
if (distance2 > 40)
|
||||
{
|
||||
ZoomWindow();
|
||||
CancelAction();
|
||||
}
|
||||
else
|
||||
{
|
||||
status = Status.SetSecondPoint;
|
||||
}
|
||||
}
|
||||
else if (status == Status.SetSecondPoint)
|
||||
{
|
||||
ZoomWindow();
|
||||
CancelAction();
|
||||
}
|
||||
}
|
||||
|
||||
private void plateView_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
if (!Point1.IsValid() || !Point2.IsValid())
|
||||
return;
|
||||
|
||||
var rect = GetRectangle();
|
||||
|
||||
e.Graphics.FillRectangle(fillBrush, rect);
|
||||
|
||||
e.Graphics.DrawRectangle(borderPen,
|
||||
rect.X,
|
||||
rect.Y,
|
||||
rect.Width,
|
||||
rect.Height);
|
||||
|
||||
var centerX = rect.X + rect.Width * 0.5f;
|
||||
var centerY = rect.Y + rect.Height * 0.5f;
|
||||
|
||||
const float halfWidth = 10;
|
||||
|
||||
e.Graphics.DrawLine(borderPen, centerX, centerY - halfWidth, centerX, centerY + halfWidth);
|
||||
e.Graphics.DrawLine(borderPen, centerX - halfWidth, centerY, centerX + halfWidth, centerY);
|
||||
}
|
||||
|
||||
private void ZoomWindow()
|
||||
{
|
||||
double x, y, w, h;
|
||||
|
||||
if (Point1.X < Point2.X)
|
||||
{
|
||||
x = Point1.X;
|
||||
w = Point2.X - Point1.X;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = Point2.X;
|
||||
w = Point1.X - Point2.X;
|
||||
}
|
||||
|
||||
if (Point1.Y < Point2.Y)
|
||||
{
|
||||
y = Point1.Y;
|
||||
h = Point2.Y - Point1.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
y = Point2.Y;
|
||||
h = Point1.Y - Point2.Y;
|
||||
}
|
||||
|
||||
plateView.ZoomToArea(x, y, w, h);
|
||||
plateView.Refresh();
|
||||
}
|
||||
|
||||
private RectangleF GetRectangle()
|
||||
{
|
||||
var rect = new RectangleF();
|
||||
var pt1 = plateView.PointWorldToGraph(Point1);
|
||||
var pt2 = plateView.PointWorldToGraph(Point2);
|
||||
|
||||
if (pt1.X < pt2.X)
|
||||
{
|
||||
rect.X = pt1.X;
|
||||
rect.Width = pt2.X - pt1.X;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.X = pt2.X;
|
||||
rect.Width = pt1.X - pt2.X;
|
||||
}
|
||||
|
||||
if (pt1.Y < pt2.Y)
|
||||
{
|
||||
rect.Y = pt1.Y;
|
||||
rect.Height = pt2.Y - pt1.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.Y = pt2.Y;
|
||||
rect.Height = pt1.Y - pt2.Y;
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
public enum Status
|
||||
{
|
||||
SetFirstPoint,
|
||||
SetSecondPoint
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user