Add toggleable pierce point drawing to PlateView that shows small red filled circles at each rapid move endpoint (where cutting begins). Wire through View menu, EditNestForm toggle, and MainForm handler. Also rename RectangleShape/RoundedRectangleShape Width/Height to Length/Width for consistency with CNC conventions, update MCP tools and tests accordingly. Fix SplitDrawingForm designer layout ordering and EntityView bend line selection styling. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
843 lines
25 KiB
C#
843 lines
25 KiB
C#
using OpenNest.Actions;
|
|
using OpenNest.CNC.CuttingStrategy;
|
|
using OpenNest.Collections;
|
|
using OpenNest.Controls;
|
|
using OpenNest.Engine.Sequencing;
|
|
using OpenNest.IO;
|
|
using OpenNest.Math;
|
|
using OpenNest.Properties;
|
|
using System;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
using OpenNest.Api;
|
|
using Timer = System.Timers.Timer;
|
|
|
|
namespace OpenNest.Forms
|
|
{
|
|
public partial class EditNestForm : Form
|
|
{
|
|
public event EventHandler PlateChanged;
|
|
|
|
public readonly Nest Nest;
|
|
public readonly PlateView PlateView;
|
|
|
|
private readonly Timer updateDrawingListTimer;
|
|
|
|
private Panel plateHeaderPanel;
|
|
private Label plateInfoLabel;
|
|
private Button btnFirstPlate;
|
|
private Button btnRemovePlate;
|
|
|
|
private Button btnPreviousPlate;
|
|
private Button btnNextPlate;
|
|
private Button btnLastPlate;
|
|
|
|
/// <summary>
|
|
/// Used to distinguish between single/double click on drawing within drawinglistbox.
|
|
/// If double click, this is set to false so the single click action won't be triggered.
|
|
/// </summary>
|
|
private bool addPart;
|
|
|
|
private EditNestForm()
|
|
{
|
|
PlateView = new PlateView();
|
|
PlateView.Enter += PlateView_Enter;
|
|
PlateView.PartAdded += PlateView_PartAdded;
|
|
PlateView.PartRemoved += PlateView_PartRemoved;
|
|
PlateView.Dock = DockStyle.Fill;
|
|
|
|
InitializeComponent();
|
|
CreatePlateHeader();
|
|
|
|
splitContainer.Panel2.Controls.Add(PlateView);
|
|
splitContainer.Panel2.Controls.Add(plateHeaderPanel);
|
|
|
|
var renderer = new ToolStripRenderer(ToolbarTheme.Toolbar);
|
|
toolStrip1.Renderer = renderer;
|
|
toolStrip2.Renderer = renderer;
|
|
|
|
platesListView.SelectedIndexChanged += (sender, e) =>
|
|
{
|
|
if (platesListView.SelectedIndices.Count == 0)
|
|
return;
|
|
|
|
CurrentPlateIndex = platesListView.SelectedIndices[0];
|
|
PlateView.Plate = Nest.Plates[CurrentPlateIndex];
|
|
PlateView.ZoomToFit();
|
|
FirePlateChanged(false);
|
|
};
|
|
}
|
|
|
|
private void CreatePlateHeader()
|
|
{
|
|
plateHeaderPanel = new Panel
|
|
{
|
|
Dock = DockStyle.Top,
|
|
Height = 30,
|
|
BackColor = Color.FromArgb(240, 240, 240),
|
|
Padding = new Padding(4, 0, 4, 0)
|
|
};
|
|
|
|
plateInfoLabel = new Label
|
|
{
|
|
AutoSize = true,
|
|
TextAlign = ContentAlignment.MiddleLeft,
|
|
Font = new Font("Segoe UI", 12f, FontStyle.Bold),
|
|
ForeColor = Color.FromArgb(120, 120, 120),
|
|
Dock = DockStyle.Left,
|
|
Padding = new Padding(4, 4, 4, 4)
|
|
};
|
|
|
|
var btnSize = new System.Drawing.Size(28, 28);
|
|
|
|
btnFirstPlate = CreateNavButton(Resources.move_first);
|
|
btnFirstPlate.Click += (s, e) => LoadFirstPlate();
|
|
|
|
btnPreviousPlate = CreateNavButton(Resources.move_previous);
|
|
btnPreviousPlate.Click += (s, e) => LoadPreviousPlate();
|
|
|
|
btnNextPlate = CreateNavButton(Resources.move_next);
|
|
btnNextPlate.Click += (s, e) => LoadNextPlate();
|
|
|
|
btnLastPlate = CreateNavButton(Resources.move_last);
|
|
btnLastPlate.Click += (s, e) => LoadLastPlate();
|
|
|
|
// Panel that holds the nav buttons and centers itself in the header
|
|
var navPanel = new Panel
|
|
{
|
|
Width = btnSize.Width * 4,
|
|
Height = btnSize.Height,
|
|
Anchor = AnchorStyles.None
|
|
};
|
|
|
|
btnFirstPlate.Location = new Point(0, 0);
|
|
btnPreviousPlate.Location = new Point(btnSize.Width, 0);
|
|
btnNextPlate.Location = new Point(btnSize.Width * 2, 0);
|
|
btnLastPlate.Location = new Point(btnSize.Width * 3, 0);
|
|
|
|
navPanel.Controls.AddRange(new Control[] { btnFirstPlate, btnPreviousPlate, btnNextPlate, btnLastPlate });
|
|
|
|
btnRemovePlate = CreateNavButton(Resources.remove);
|
|
btnRemovePlate.Dock = DockStyle.Right;
|
|
btnRemovePlate.Click += (s, e) => RemoveCurrentPlate();
|
|
|
|
var btnAddPlate = CreateNavButton(Resources.add);
|
|
btnAddPlate.Dock = DockStyle.Right;
|
|
btnAddPlate.Click += (s, e) => Nest.CreatePlate();
|
|
|
|
plateHeaderPanel.Controls.Add(navPanel);
|
|
plateHeaderPanel.Controls.Add(plateInfoLabel);
|
|
plateHeaderPanel.Controls.Add(btnRemovePlate);
|
|
plateHeaderPanel.Controls.Add(btnAddPlate);
|
|
|
|
// Center the nav panel on resize
|
|
CenterNavPanel(navPanel);
|
|
plateHeaderPanel.Resize += (s, e) => CenterNavPanel(navPanel);
|
|
}
|
|
|
|
private void CenterNavPanel(Panel navPanel)
|
|
{
|
|
navPanel.Left = (plateHeaderPanel.Width - navPanel.Width) / 2;
|
|
navPanel.Top = (plateHeaderPanel.Height - navPanel.Height) / 2;
|
|
}
|
|
|
|
private static Button CreateNavButton(System.Drawing.Image image)
|
|
{
|
|
return new Button
|
|
{
|
|
Image = image,
|
|
Size = new System.Drawing.Size(28, 28),
|
|
FlatStyle = FlatStyle.Flat,
|
|
FlatAppearance = { BorderSize = 0 },
|
|
Cursor = Cursors.Hand
|
|
};
|
|
}
|
|
|
|
public EditNestForm(Nest nest)
|
|
: this()
|
|
{
|
|
updateDrawingListTimer = new Timer()
|
|
{
|
|
AutoReset = false,
|
|
Enabled = true,
|
|
Interval = 50
|
|
};
|
|
updateDrawingListTimer.Elapsed += drawingListUpdateTimer_Elapsed;
|
|
|
|
Nest = nest;
|
|
Nest.Plates.ItemAdded += Plates_PlateAdded;
|
|
Nest.Plates.ItemRemoved += Plates_PlateRemoved;
|
|
|
|
if (Nest.Plates.Count == 0)
|
|
Nest.CreatePlate();
|
|
|
|
UpdatePlateList();
|
|
UpdateDrawingList();
|
|
UpdateRemovePlateButton();
|
|
|
|
LoadFirstPlate();
|
|
|
|
Text = Nest.Name;
|
|
drawingListBox1.Units = Nest.Units;
|
|
}
|
|
|
|
public string LastSavePath { get; private set; }
|
|
|
|
public DateTime LastSaveDate { get; private set; }
|
|
|
|
public int CurrentPlateIndex { get; private set; }
|
|
|
|
public int PlateCount
|
|
{
|
|
get { return Nest.Plates.Count; }
|
|
}
|
|
|
|
public void LoadFirstPlate()
|
|
{
|
|
if (Nest.Plates.Count > 0)
|
|
{
|
|
CurrentPlateIndex = 0;
|
|
PlateView.Plate = Nest.Plates[CurrentPlateIndex];
|
|
PlateView.ZoomToFit();
|
|
FirePlateChanged();
|
|
}
|
|
}
|
|
|
|
public void LoadLastPlate()
|
|
{
|
|
if (Nest.Plates.Count > 0)
|
|
{
|
|
CurrentPlateIndex = Nest.Plates.Count - 1;
|
|
PlateView.Plate = Nest.Plates[CurrentPlateIndex];
|
|
PlateView.ZoomToFit();
|
|
FirePlateChanged();
|
|
}
|
|
}
|
|
|
|
public bool LoadNextPlate()
|
|
{
|
|
if (CurrentPlateIndex + 1 >= Nest.Plates.Count)
|
|
return false;
|
|
|
|
CurrentPlateIndex++;
|
|
PlateView.Plate = Nest.Plates[CurrentPlateIndex];
|
|
PlateView.ZoomToFit();
|
|
FirePlateChanged();
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool LoadPreviousPlate()
|
|
{
|
|
if (Nest.Plates.Count == 0 || CurrentPlateIndex - 1 < 0)
|
|
return false;
|
|
|
|
CurrentPlateIndex--;
|
|
PlateView.Plate = Nest.Plates[CurrentPlateIndex];
|
|
PlateView.ZoomToFit();
|
|
FirePlateChanged();
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool IsFirstPlate()
|
|
{
|
|
return (Nest.Plates.Count == 0 || (CurrentPlateIndex - 1) < 0);
|
|
}
|
|
|
|
public bool IsLastPlate()
|
|
{
|
|
return CurrentPlateIndex + 1 >= Nest.Plates.Count;
|
|
}
|
|
|
|
public void UpdatePlateList()
|
|
{
|
|
platesListView.Items.Clear();
|
|
|
|
var items = new ListViewItem[Nest.Plates.Count];
|
|
|
|
for (int i = 0; i < items.Length; ++i)
|
|
{
|
|
var plate = Nest.Plates[i];
|
|
var item = GetListViewItem(plate, i + 1);
|
|
items[i] = item;
|
|
}
|
|
|
|
platesListView.Items.AddRange(items);
|
|
}
|
|
|
|
public void UpdateDrawingList()
|
|
{
|
|
drawingListBox1.Items.Clear();
|
|
|
|
foreach (var dwg in Nest.Drawings.OrderBy(d => d.Name).ToList())
|
|
drawingListBox1.Items.Add(dwg);
|
|
}
|
|
|
|
public void Save()
|
|
{
|
|
if (File.Exists(LastSavePath))
|
|
SaveAs(LastSavePath);
|
|
else
|
|
SaveAs();
|
|
}
|
|
|
|
public void SaveAs()
|
|
{
|
|
var dlg = new SaveFileDialog();
|
|
dlg.Filter = $"{NestFormat.FileFilter}|Template File|*.nstdot";
|
|
dlg.FileName = Nest.Name;
|
|
|
|
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
|
{
|
|
if (dlg.FilterIndex == 2)
|
|
SaveTemplate(dlg.FileName);
|
|
else
|
|
SaveAs(dlg.FileName);
|
|
}
|
|
}
|
|
|
|
public void SaveAs(string path)
|
|
{
|
|
var name = Path.GetFileNameWithoutExtension(path);
|
|
Nest.Name = name;
|
|
Text = name;
|
|
LastSaveDate = DateTime.Now;
|
|
LastSavePath = path;
|
|
|
|
var writer = new NestWriter(Nest);
|
|
writer.Write(path);
|
|
}
|
|
|
|
public void SaveTemplate(string path)
|
|
{
|
|
var nst = new Nest();
|
|
nst.Name = Path.GetFileNameWithoutExtension(path);
|
|
nst.PlateDefaults = Nest.PlateDefaults;
|
|
nst.Units = Nest.Units;
|
|
|
|
var writer = new NestWriter(nst);
|
|
writer.Write(path);
|
|
}
|
|
|
|
public void Import()
|
|
{
|
|
var dlg = new OpenFileDialog();
|
|
dlg.Multiselect = true;
|
|
dlg.Filter = "DXF Files (*.dxf) | *.dxf";
|
|
|
|
if (dlg.ShowDialog() != DialogResult.OK)
|
|
return;
|
|
|
|
var converter = new CadConverterForm();
|
|
converter.AddFiles(dlg.FileNames);
|
|
|
|
var result = converter.ShowDialog();
|
|
|
|
if (result != DialogResult.OK)
|
|
return;
|
|
|
|
var drawings = converter.GetDrawings();
|
|
drawings.ForEach(d => Nest.Drawings.Add(d));
|
|
|
|
UpdateDrawingList();
|
|
tabControl1.SelectedIndex = 1;
|
|
}
|
|
|
|
public bool Export()
|
|
{
|
|
var dlg = new SaveFileDialog();
|
|
dlg.Filter = "DXF file (*.dxf)|*.dxf|" +
|
|
"Image as displayed (*.jpg)|*.jpg|" +
|
|
"Locations and rotations (*.txt)|*.txt";
|
|
|
|
dlg.FileName = string.Format("{0}-P{1}", Nest.Name, CurrentPlateIndex + 1);
|
|
dlg.AddExtension = true;
|
|
dlg.DefaultExt = ".";
|
|
|
|
if (dlg.ShowDialog() == DialogResult.OK)
|
|
{
|
|
if (dlg.FilterIndex == 1)
|
|
{
|
|
var exporter = new DxfExporter();
|
|
var success = exporter.ExportPlate(PlateView.Plate, dlg.FileName);
|
|
return success;
|
|
}
|
|
else if (dlg.FilterIndex == 2)
|
|
{
|
|
try
|
|
{
|
|
var img = new Bitmap(PlateView.Width, PlateView.Height);
|
|
PlateView.DrawToBitmap(img, new Rectangle(0, 0, PlateView.Width, PlateView.Height));
|
|
img.Save(dlg.FileName);
|
|
}
|
|
catch { }
|
|
|
|
return true;
|
|
}
|
|
else if (dlg.FilterIndex == 3)
|
|
{
|
|
StreamWriter writer = null;
|
|
|
|
try
|
|
{
|
|
writer = new StreamWriter(dlg.FileName);
|
|
|
|
foreach (var part in PlateView.Plate.Parts)
|
|
{
|
|
var pt = part.BaseDrawing.Source.Offset.Rotate(part.Rotation);
|
|
|
|
writer.WriteLine("{0}|{1},{2}|{3}",
|
|
part.BaseDrawing.Source.Path,
|
|
System.Math.Round(part.Location.X - pt.X, 8),
|
|
System.Math.Round(part.Location.Y - pt.Y, 8),
|
|
Angle.ToDegrees(part.Rotation));
|
|
}
|
|
}
|
|
catch { }
|
|
finally
|
|
{
|
|
if (writer != null)
|
|
writer.Dispose();
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public void ExportAll()
|
|
{
|
|
LoadFirstPlate();
|
|
|
|
do
|
|
{
|
|
if (!Export()) return;
|
|
}
|
|
while (LoadNextPlate());
|
|
}
|
|
|
|
public void RotateCw()
|
|
{
|
|
PlateView.Plate.Rotate90(RotationType.CW);
|
|
PlateView.ZoomToFit();
|
|
}
|
|
|
|
public void RotateCcw()
|
|
{
|
|
PlateView.Plate.Rotate90(RotationType.CCW);
|
|
PlateView.ZoomToFit();
|
|
}
|
|
|
|
public void Rotate180()
|
|
{
|
|
PlateView.Plate.Rotate180();
|
|
PlateView.ZoomToFit();
|
|
}
|
|
|
|
public void ShowNestInfoEditor()
|
|
{
|
|
var form = new EditNestInfoForm();
|
|
form.LoadNestInfo(Nest);
|
|
|
|
if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
|
{
|
|
form.SaveNestInfo(Nest);
|
|
drawingListBox1.Units = Nest.Units;
|
|
drawingListBox1.Invalidate();
|
|
}
|
|
}
|
|
|
|
public void ResizePlateToFitParts()
|
|
{
|
|
PlateView.Plate.AutoSize(Settings.Default.AutoSizePlateFactor);
|
|
PlateView.ZoomToPlate();
|
|
PlateView.Refresh();
|
|
UpdatePlateList();
|
|
UpdatePlateHeader();
|
|
}
|
|
|
|
public void SelectAllParts()
|
|
{
|
|
PlateView.SelectAll();
|
|
PlateView.Invalidate();
|
|
}
|
|
|
|
public void ToggleRapid()
|
|
{
|
|
PlateView.DrawRapid = !PlateView.DrawRapid;
|
|
PlateView.Invalidate();
|
|
}
|
|
|
|
public void TogglePiercePoints()
|
|
{
|
|
PlateView.DrawPiercePoints = !PlateView.DrawPiercePoints;
|
|
PlateView.Invalidate();
|
|
}
|
|
|
|
public void ToggleDrawBounds()
|
|
{
|
|
PlateView.DrawBounds = !PlateView.DrawBounds;
|
|
PlateView.Invalidate();
|
|
}
|
|
|
|
public void ToggleBendLines()
|
|
{
|
|
PlateView.ShowBendLines = !PlateView.ShowBendLines;
|
|
PlateView.Invalidate();
|
|
}
|
|
|
|
public void ToggleDrawOffset()
|
|
{
|
|
PlateView.DrawOffset = !PlateView.DrawOffset;
|
|
PlateView.Invalidate();
|
|
}
|
|
|
|
public void ToggleFillParts()
|
|
{
|
|
PlateView.FillParts = !PlateView.FillParts;
|
|
PlateView.Invalidate();
|
|
}
|
|
|
|
public void SetCurrentPlateAsNestDefault()
|
|
{
|
|
Nest.PlateDefaults.SetFromExisting(PlateView.Plate);
|
|
}
|
|
|
|
public void EditPlate()
|
|
{
|
|
var form = new EditPlateForm(PlateView.Plate);
|
|
form.Units = Nest.Units;
|
|
|
|
if (form.ShowDialog() == DialogResult.OK)
|
|
{
|
|
PlateView.Invalidate();
|
|
FirePlateChanged(false);
|
|
UpdatePlateList();
|
|
}
|
|
|
|
Nest.UpdateDrawingQuantities();
|
|
drawingListBox1.Refresh();
|
|
|
|
if (PlateView.Plate.Parts.Count == 0)
|
|
Nest.PlateDefaults.SetFromExisting(PlateView.Plate);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Opens the current plate as a DXF file by the default program set in Windows.
|
|
/// </summary>
|
|
public void OpenCurrentPlate()
|
|
{
|
|
var plate = PlateView.Plate;
|
|
var name = string.Format("{0}-P{1}.dxf", Nest.Name, CurrentPlateIndex + 1);
|
|
var path = Path.Combine(Path.GetTempPath(), name);
|
|
var exporter = new DxfExporter();
|
|
exporter.ExportPlate(plate, path);
|
|
|
|
Process.Start(path);
|
|
}
|
|
|
|
public void RemoveCurrentPlate()
|
|
{
|
|
if (Nest.Plates.Count < 2)
|
|
return;
|
|
|
|
Nest.Plates.RemoveAt(CurrentPlateIndex);
|
|
}
|
|
|
|
public void AutoSequenceCurrentPlate()
|
|
{
|
|
SequencePlate(PlateView.Plate);
|
|
PlateView.Invalidate();
|
|
}
|
|
|
|
public void AutoSequenceAllPlates()
|
|
{
|
|
foreach (var plate in Nest.Plates)
|
|
SequencePlate(plate);
|
|
|
|
PlateView.Invalidate();
|
|
}
|
|
|
|
private static void SequencePlate(Plate plate)
|
|
{
|
|
var parameters = new SequenceParameters { Method = SequenceMethod.LeastCode };
|
|
var sequencer = PartSequencerFactory.Create(parameters);
|
|
var ordered = sequencer.Sequence(plate.Parts.ToList(), plate);
|
|
|
|
plate.Parts.Clear();
|
|
for (var i = ordered.Count - 1; i >= 0; i--)
|
|
plate.Parts.Add(ordered[i].Part);
|
|
}
|
|
|
|
public void CalculateCurrentPlateCutTime()
|
|
{
|
|
var cutParamsForm = new CutParametersForm();
|
|
cutParamsForm.Units = Nest.Units;
|
|
|
|
if (cutParamsForm.ShowDialog() == DialogResult.OK)
|
|
{
|
|
var cutparams = cutParamsForm.GetCutParameters();
|
|
var info = Timing.GetTimingInfo(PlateView.Plate);
|
|
var time = Timing.CalculateTime(info, cutparams);
|
|
|
|
var timingForm = new TimingForm();
|
|
timingForm.Units = Nest.Units;
|
|
timingForm.SetCutDistance(info.CutDistance);
|
|
timingForm.SetCutTime(time);
|
|
timingForm.SetIntersectionCount(info.IntersectionCount);
|
|
timingForm.SetPierceCount(info.PierceCount);
|
|
timingForm.SetRapidDistance(info.TravelDistance);
|
|
timingForm.SetCutParameters(cutparams);
|
|
|
|
timingForm.ShowDialog();
|
|
}
|
|
}
|
|
|
|
public void CalculateNestCutTime()
|
|
{
|
|
var cutParamsForm = new CutParametersForm();
|
|
cutParamsForm.Units = Nest.Units;
|
|
|
|
if (cutParamsForm.ShowDialog() == DialogResult.OK)
|
|
{
|
|
var cutparams = cutParamsForm.GetCutParameters();
|
|
var info = Timing.GetTimingInfo(Nest);
|
|
var time = Timing.CalculateTime(info, cutparams);
|
|
|
|
var timingForm = new TimingForm();
|
|
timingForm.Units = Nest.Units;
|
|
timingForm.SetCutDistance(info.CutDistance);
|
|
timingForm.SetCutTime(time);
|
|
timingForm.SetIntersectionCount(info.IntersectionCount);
|
|
timingForm.SetPierceCount(info.PierceCount);
|
|
timingForm.SetRapidDistance(info.TravelDistance);
|
|
timingForm.SetCutParameters(cutparams);
|
|
|
|
timingForm.ShowDialog();
|
|
}
|
|
}
|
|
|
|
private void FirePlateChanged(bool updateListView = true)
|
|
{
|
|
if (updateListView)
|
|
platesListView.Items[CurrentPlateIndex].Selected = true;
|
|
|
|
UpdatePlateHeader();
|
|
|
|
if (PlateChanged != null)
|
|
PlateChanged.Invoke(this, EventArgs.Empty);
|
|
}
|
|
|
|
private void UpdatePlateHeader()
|
|
{
|
|
var plate = Nest.Plates.Count > 0 ? Nest.Plates[CurrentPlateIndex] : null;
|
|
|
|
if (plate != null)
|
|
{
|
|
plateInfoLabel.Text = string.Format("Plate {0} of {1} | {2}",
|
|
CurrentPlateIndex + 1, Nest.Plates.Count, plate.Size);
|
|
}
|
|
else
|
|
{
|
|
plateInfoLabel.Text = "No plates";
|
|
}
|
|
|
|
btnFirstPlate.Enabled = !IsFirstPlate();
|
|
btnPreviousPlate.Enabled = !IsFirstPlate();
|
|
btnNextPlate.Enabled = !IsLastPlate();
|
|
btnLastPlate.Enabled = !IsLastPlate();
|
|
}
|
|
|
|
#region Overrides
|
|
|
|
protected override void OnSizeChanged(EventArgs e)
|
|
{
|
|
base.OnSizeChanged(e);
|
|
PlateView.Invalidate();
|
|
}
|
|
|
|
protected override void OnLoad(EventArgs e)
|
|
{
|
|
base.OnLoad(e);
|
|
Icon = Icon.Clone() as Icon;
|
|
PlateView.DrawBounds = Settings.Default.PlateViewDrawBounds;
|
|
PlateView.DrawRapid = Settings.Default.PlateViewDrawRapid;
|
|
splitContainer.SplitterDistance = Settings.Default.SplitterDistance;
|
|
}
|
|
|
|
protected override void OnClosing(CancelEventArgs e)
|
|
{
|
|
base.OnClosing(e);
|
|
|
|
Settings.Default.PlateViewDrawBounds = PlateView.DrawBounds;
|
|
Settings.Default.PlateViewDrawRapid = PlateView.DrawRapid;
|
|
Settings.Default.SplitterDistance = splitContainer.SplitterDistance;
|
|
Settings.Default.Save();
|
|
}
|
|
|
|
protected override void OnResize(EventArgs e)
|
|
{
|
|
base.OnResize(e);
|
|
PlateView.Invalidate();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Plates/Drawings Panel Events
|
|
|
|
private void AddPlate_Click(object sender, EventArgs e)
|
|
{
|
|
Nest.CreatePlate();
|
|
}
|
|
|
|
private void EditSelectedPlate_Click(object sender, EventArgs e)
|
|
{
|
|
if (platesListView.SelectedIndices.Count != 0)
|
|
EditPlate();
|
|
}
|
|
|
|
private void RemoveSelectedPlate_Click(object sender, EventArgs e)
|
|
{
|
|
RemoveCurrentPlate();
|
|
}
|
|
|
|
private void CalculateSelectedPlateCutTime_Click(object sender, EventArgs e)
|
|
{
|
|
CalculateCurrentPlateCutTime();
|
|
}
|
|
|
|
private void ImportDrawings_Click(object sender, EventArgs e)
|
|
{
|
|
Import();
|
|
}
|
|
|
|
private void CleanUnusedDrawings_Click(object sender, EventArgs e)
|
|
{
|
|
var result = MessageBox.Show(
|
|
"Remove unused drawings?",
|
|
"Clean Drawings",
|
|
MessageBoxButtons.YesNoCancel,
|
|
MessageBoxIcon.Question,
|
|
MessageBoxDefaultButton.Button1);
|
|
|
|
if (result == DialogResult.Yes)
|
|
{
|
|
Nest.Drawings.RemoveWhere(d => d.Quantity.Nested == 0);
|
|
UpdateDrawingList();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Plate Collection Events
|
|
|
|
private void Plates_PlateRemoved(object sender, ItemRemovedEventArgs<Plate> e)
|
|
{
|
|
if (Nest.Plates.Count <= CurrentPlateIndex)
|
|
LoadLastPlate();
|
|
else
|
|
PlateView.Plate = Nest.Plates[CurrentPlateIndex];
|
|
|
|
UpdatePlateList();
|
|
UpdateRemovePlateButton();
|
|
PlateView.ZoomToFit();
|
|
}
|
|
|
|
private void Plates_PlateAdded(object sender, ItemAddedEventArgs<Plate> e)
|
|
{
|
|
tabControl1.SelectedIndex = 0;
|
|
UpdatePlateList();
|
|
UpdateRemovePlateButton();
|
|
LoadLastPlate();
|
|
PlateView.ZoomToFit();
|
|
}
|
|
|
|
private void UpdateRemovePlateButton()
|
|
{
|
|
btnRemovePlate.Enabled = Nest.Plates.Count > 1;
|
|
}
|
|
|
|
#endregion
|
|
|
|
private static ListViewItem GetListViewItem(Plate plate, int id)
|
|
{
|
|
var item = new ListViewItem();
|
|
item.Text = id.ToString();
|
|
item.SubItems.Add(plate.Size.ToString());
|
|
item.SubItems.Add(plate.Quantity.ToString());
|
|
return item;
|
|
}
|
|
|
|
private void PlateView_PartRemoved(object sender, ItemRemovedEventArgs<Part> e)
|
|
{
|
|
updateDrawingListTimer.Stop();
|
|
updateDrawingListTimer.Start();
|
|
}
|
|
|
|
private void PlateView_PartAdded(object sender, ItemAddedEventArgs<Part> e)
|
|
{
|
|
updateDrawingListTimer.Stop();
|
|
updateDrawingListTimer.Start();
|
|
}
|
|
|
|
private void drawingListUpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
|
{
|
|
if (!drawingListBox1.IsHandleCreated)
|
|
return;
|
|
|
|
drawingListBox1.Invoke(new MethodInvoker(() =>
|
|
{
|
|
drawingListBox1.Refresh();
|
|
}));
|
|
}
|
|
|
|
private void drawingListBox1_DoubleClick(object sender, EventArgs e)
|
|
{
|
|
addPart = false;
|
|
|
|
var drawing = drawingListBox1.SelectedItem as Drawing;
|
|
|
|
if (drawing == null)
|
|
return;
|
|
|
|
var form = new EditDrawingForm();
|
|
form.LoadDrawing(drawing);
|
|
|
|
if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
|
{
|
|
form.SaveDrawing(drawing);
|
|
|
|
foreach (var part in PlateView.Parts)
|
|
part.Update();
|
|
|
|
PlateView.Invalidate();
|
|
}
|
|
}
|
|
|
|
private void drawingListBox1_Click(object sender, EventArgs e)
|
|
{
|
|
addPart = true;
|
|
}
|
|
|
|
private void PlateView_Enter(object sender, EventArgs e)
|
|
{
|
|
if (!addPart)
|
|
return;
|
|
|
|
var drawing = drawingListBox1.SelectedItem as Drawing;
|
|
|
|
if (drawing == null)
|
|
return;
|
|
|
|
PlateView.SetAction(typeof(ActionClone), drawing);
|
|
|
|
addPart = false;
|
|
}
|
|
}
|
|
}
|