diff --git a/OpenNest/Forms/MainForm.File.cs b/OpenNest/Forms/MainForm.File.cs index 3681c68d..ebde8a1e 100644 --- a/OpenNest/Forms/MainForm.File.cs +++ b/OpenNest/Forms/MainForm.File.cs @@ -22,7 +22,7 @@ namespace OpenNest.Forms editForm.PlateChanged += (sender, e) => { NavigationEnableCheck(); - UpdatePlateStatus(); + statusBar.UpdatePlate(); mnuPlateRemove.Enabled = activeForm?.PlateManager.CanRemoveCurrent ?? false; }; editForm.WindowState = windowState; diff --git a/OpenNest/Forms/MainForm.Plate.cs b/OpenNest/Forms/MainForm.Plate.cs index 03b41f06..3dcbda81 100644 --- a/OpenNest/Forms/MainForm.Plate.cs +++ b/OpenNest/Forms/MainForm.Plate.cs @@ -43,7 +43,7 @@ namespace OpenNest.Forms if (activeForm == null) return; activeForm.ResizePlateToFitParts(); - UpdatePlateStatus(); + statusBar.UpdatePlate(); } private void RotateCw_Click(object sender, EventArgs e) diff --git a/OpenNest/Forms/MainForm.Status.cs b/OpenNest/Forms/MainForm.Status.cs index e17b455a..3d5c704e 100644 --- a/OpenNest/Forms/MainForm.Status.cs +++ b/OpenNest/Forms/MainForm.Status.cs @@ -1,9 +1,5 @@ using System; -using System.Drawing; -using System.Linq; using System.Windows.Forms; -using OpenNest.Collections; -using OpenNest.Geometry; namespace OpenNest.Forms { @@ -58,159 +54,17 @@ namespace OpenNest.Forms NavigationEnableCheck(locked); } - private void UpdateLocationStatus() - { - if (activeForm == null) - { - locationStatusLabel.Text = string.Empty; - return; - } - - locationStatusLabel.Text = string.Format( - "Location: [{0}, {1}]", - activeForm.PlateView.CurrentPoint.X.ToString("n4"), - activeForm.PlateView.CurrentPoint.Y.ToString("n4") - ); - } - - private void UpdatePlateStatus() - { - if (activeForm == null) - { - plateIndexStatusLabel.Text = string.Empty; - plateSizeStatusLabel.Text = string.Empty; - plateQtyStatusLabel.Text = string.Empty; - plateUtilStatusLabel.Text = string.Empty; - return; - } - - plateIndexStatusLabel.Text = string.Format( - "Plate: {0} of {1}", - activeForm.PlateManager.CurrentIndex + 1, - activeForm.PlateManager.Count - ); - - plateSizeStatusLabel.Text = string.Format("Size: {0}", activeForm.PlateView.Plate.Size); - - plateQtyStatusLabel.Text = string.Format( - "Qty: {0}", - activeForm.PlateView.Plate.Quantity - ); - - plateUtilStatusLabel.Text = string.Format( - "Util: {0:P1}", - activeForm.PlateView.Plate.Utilization() - ); - } - - private void UpdateSelectionStatus() - { - if (activeForm == null || activeForm.PlateView.SelectedParts.Count == 0) - { - selectionStatusLabel.Text = string.Empty; - return; - } - - var selected = activeForm.PlateView.SelectedParts; - - if (selected.Count == 1) - { - var box = selected[0].BoundingBox; - selectionStatusLabel.Text = string.Format( - "Selected: [{0}, {1}] {2} x {3}", - box.X.ToString("n4"), - box.Y.ToString("n4"), - box.Width.ToString("n4"), - box.Length.ToString("n4") - ); - } - else - { - var bounds = selected.Select(p => p.BasePart).ToList().GetBoundingBox(); - selectionStatusLabel.Text = string.Format( - "Selected ({0}): [{1}, {2}] {3} x {4}", - selected.Count, - bounds.X.ToString("n4"), - bounds.Y.ToString("n4"), - bounds.Width.ToString("n4"), - bounds.Length.ToString("n4") - ); - } - } - - private void UpdateStatus() - { - UpdateLocationStatus(); - UpdatePlateStatus(); - UpdateSelectionStatus(); - } - private void EngineComboBox_SelectedIndexChanged(object sender, EventArgs e) { if (engineComboBox.SelectedItem is string name) EngineSelection.EngineName = name; } - private void UpdateLocationMode() - { - if (activeForm == null) - return; - - if (clickUpdateLocation) - { - clickUpdateLocation = true; - locationStatusLabel.ForeColor = Color.Gray; - activeForm.PlateView.MouseMove -= PlateView_MouseMove; - activeForm.PlateView.MouseClick += PlateView_MouseClick; - } - else - { - clickUpdateLocation = false; - locationStatusLabel.ForeColor = Color.Black; - activeForm.PlateView.MouseMove += PlateView_MouseMove; - activeForm.PlateView.MouseClick -= PlateView_MouseClick; - } - } - #region Statusbar Events - private void LocationStatusLabel_Click(object sender, EventArgs e) - { - clickUpdateLocation = !clickUpdateLocation; - UpdateLocationMode(); - } + private void LocationStatusLabel_Click(object sender, EventArgs e) => + statusBar.ToggleLocationMode(); #endregion Statusbar Events - - #region PlateView Events - - private void PlateView_PartAdded(object sender, ItemAddedEventArgs e) => - UpdatePlateStatus(); - - private void PlateView_PartRemoved(object sender, ItemRemovedEventArgs e) => - UpdatePlateStatus(); - - private void PlateView_MouseMove(object sender, MouseEventArgs e) - { - UpdateLocationStatus(); - } - - private void PlateView_MouseClick(object sender, MouseEventArgs e) - { - if (e.Button == MouseButtons.Left) - UpdateLocationStatus(); - } - - private void PlateView_StatusChanged(object sender, EventArgs e) - { - statusLabel1.Text = activeForm.PlateView.Status; - } - - private void PlateView_SelectionChanged(object sender, EventArgs e) - { - UpdateSelectionStatus(); - } - - #endregion PlateView Events } } diff --git a/OpenNest/Forms/MainForm.cs b/OpenNest/Forms/MainForm.cs index 2cfefe12..54ff7dfb 100644 --- a/OpenNest/Forms/MainForm.cs +++ b/OpenNest/Forms/MainForm.cs @@ -17,7 +17,7 @@ namespace OpenNest.Forms { private EditNestForm activeForm; - private bool clickUpdateLocation; + private readonly MainStatusBar statusBar; private bool nestingInProgress; private CancellationTokenSource nestingCts; private readonly NestStorageController storage; @@ -98,6 +98,8 @@ namespace OpenNest.Forms storage = new NestStorageController(this, text => statusLabel1.Text = text); storage.StateChanged += Storage_StateChanged; InitializeComponent(); + statusBar = new MainStatusBar(statusLabel1, locationStatusLabel, selectionStatusLabel, + plateIndexStatusLabel, plateSizeStatusLabel, plateQtyStatusLabel, plateUtilStatusLabel); toolStrip1.Items.Add(CreateActionButton("btnCutPlanner", "Plan Cutting", Resources.cut_planner, PlatePlanCutting_Click)); toolStrip1.Items.Add(CreateActionButton("btnManualSequence", "Manual Sequence", @@ -117,14 +119,12 @@ namespace OpenNest.Forms mnuViewZoomIn.ShortcutKeyDisplayString = "Ctrl+Plus"; mnuViewZoomOut.ShortcutKeyDisplayString = "Ctrl+Minus"; - clickUpdateLocation = true; - this.SetBevel(false); AllowDrop = true; LoadPosts(PostProcessorLoader.Load(PostProcessorLoader.DefaultDirectory)); EnableCheck(); - UpdateStatus(); + statusBar.UpdateAll(); // Jobs-side plug-in discovery: INestingEngine implementations are registered per // assembly/type with per-DLL isolation. Existing plug-ins must implement the jobs @@ -205,16 +205,9 @@ namespace OpenNest.Forms editor.CuttingInspection.RequestClose(); base.OnMdiChildActivate(e); + statusBar.Unbind(); if (activeForm != null) - { - activeForm.PlateView.MouseMove -= PlateView_MouseMove; - activeForm.PlateView.MouseClick -= PlateView_MouseClick; - activeForm.PlateView.StatusChanged -= PlateView_StatusChanged; activeForm.PlateView.OverlapStateChanged -= OverlapStateChanged; - activeForm.PlateView.SelectionChanged -= PlateView_SelectionChanged; - activeForm.PlateView.PartAdded -= PlateView_PartAdded; - activeForm.PlateView.PartRemoved -= PlateView_PartRemoved; - } // If nesting is in progress and the active form changed, cancel nesting if (nestingInProgress && nestingCts != null) @@ -226,30 +219,18 @@ namespace OpenNest.Forms UpdateOverlapMenu(); EnableCheck(); - UpdatePlateStatus(); - UpdateLocationStatus(); + statusBar.Bind(activeForm); if (activeForm == null) - { - statusLabel1.Text = ""; - selectionStatusLabel.Text = ""; return; - } - UpdateLocationMode(); - UpdateSelectionStatus(); - activeForm.PlateView.StatusChanged += PlateView_StatusChanged; activeForm.PlateView.OverlapStateChanged += OverlapStateChanged; - activeForm.PlateView.SelectionChanged += PlateView_SelectionChanged; - activeForm.PlateView.PartAdded += PlateView_PartAdded; - activeForm.PlateView.PartRemoved += PlateView_PartRemoved; var activeNest = activeForm.Nest; activeForm.PlateView.CanEditClamps = () => !ClampsInUse(activeNest); mnuViewDrawRapids.Checked = activeForm.PlateView.DrawRapid; mnuViewDrawPiercePoints.Checked = activeForm.PlateView.DrawPiercePoints; mnuViewDrawBounds.Checked = activeForm.PlateView.DrawBounds; mnuViewDrawCutDirection.Checked = activeForm.PlateView.DrawCutDirection; - statusLabel1.Text = activeForm.PlateView.Status; } protected override void OnLoad(EventArgs e) diff --git a/OpenNest/Forms/MainStatusBar.cs b/OpenNest/Forms/MainStatusBar.cs new file mode 100644 index 00000000..ad4a5433 --- /dev/null +++ b/OpenNest/Forms/MainStatusBar.cs @@ -0,0 +1,214 @@ +using System; +using System.Drawing; +using System.Linq; +using System.Windows.Forms; +using OpenNest.Collections; +using OpenNest.Geometry; + +namespace OpenNest.Forms +{ + /// + /// The main window's status labels for the active nest document: status text, cursor + /// location, selection bounds and plate index/size/quantity/utilization. The location + /// follows the mouse, or only left clicks while click mode is on (the default). + /// + internal sealed class MainStatusBar + { + private readonly ToolStripStatusLabel status; + private readonly ToolStripStatusLabel location; + private readonly ToolStripStatusLabel selection; + private readonly ToolStripStatusLabel plateIndex; + private readonly ToolStripStatusLabel plateSize; + private readonly ToolStripStatusLabel plateQty; + private readonly ToolStripStatusLabel plateUtil; + + private EditNestForm form; + private bool clickUpdatesLocation = true; + + public MainStatusBar(ToolStripStatusLabel status, ToolStripStatusLabel location, + ToolStripStatusLabel selection, ToolStripStatusLabel plateIndex, ToolStripStatusLabel plateSize, + ToolStripStatusLabel plateQty, ToolStripStatusLabel plateUtil) + { + this.status = status; + this.location = location; + this.selection = selection; + this.plateIndex = plateIndex; + this.plateSize = plateSize; + this.plateQty = plateQty; + this.plateUtil = plateUtil; + } + + /// + /// Follows 's plate view after detaching from the previous + /// document; null clears every label. + /// + public void Bind(EditNestForm editForm) + { + Unbind(); + form = editForm; + UpdatePlate(); + UpdateLocation(); + + if (form == null) + { + status.Text = ""; + selection.Text = ""; + return; + } + + ApplyLocationMode(); + UpdateSelection(); + var view = form.PlateView; + view.StatusChanged += PlateView_StatusChanged; + view.SelectionChanged += PlateView_SelectionChanged; + view.PartAdded += PlateView_PartAdded; + view.PartRemoved += PlateView_PartRemoved; + status.Text = view.Status; + } + + public void Unbind() + { + if (form == null) + return; + + var view = form.PlateView; + view.MouseMove -= PlateView_MouseMove; + view.MouseClick -= PlateView_MouseClick; + view.StatusChanged -= PlateView_StatusChanged; + view.SelectionChanged -= PlateView_SelectionChanged; + view.PartAdded -= PlateView_PartAdded; + view.PartRemoved -= PlateView_PartRemoved; + form = null; + } + + public void ToggleLocationMode() + { + clickUpdatesLocation = !clickUpdatesLocation; + ApplyLocationMode(); + } + + public void UpdateAll() + { + UpdateLocation(); + UpdatePlate(); + UpdateSelection(); + } + + public void UpdateLocation() + { + if (form == null) + { + location.Text = string.Empty; + return; + } + + location.Text = string.Format( + "Location: [{0}, {1}]", + form.PlateView.CurrentPoint.X.ToString("n4"), + form.PlateView.CurrentPoint.Y.ToString("n4") + ); + } + + public void UpdatePlate() + { + if (form == null) + { + plateIndex.Text = string.Empty; + plateSize.Text = string.Empty; + plateQty.Text = string.Empty; + plateUtil.Text = string.Empty; + return; + } + + plateIndex.Text = string.Format( + "Plate: {0} of {1}", + form.PlateManager.CurrentIndex + 1, + form.PlateManager.Count + ); + + plateSize.Text = string.Format("Size: {0}", form.PlateView.Plate.Size); + + plateQty.Text = string.Format( + "Qty: {0}", + form.PlateView.Plate.Quantity + ); + + plateUtil.Text = string.Format( + "Util: {0:P1}", + form.PlateView.Plate.Utilization() + ); + } + + public void UpdateSelection() + { + if (form == null || form.PlateView.SelectedParts.Count == 0) + { + selection.Text = string.Empty; + return; + } + + var selected = form.PlateView.SelectedParts; + + if (selected.Count == 1) + { + var box = selected[0].BoundingBox; + selection.Text = string.Format( + "Selected: [{0}, {1}] {2} x {3}", + box.X.ToString("n4"), + box.Y.ToString("n4"), + box.Width.ToString("n4"), + box.Length.ToString("n4") + ); + } + else + { + var bounds = selected.Select(p => p.BasePart).ToList().GetBoundingBox(); + selection.Text = string.Format( + "Selected ({0}): [{1}, {2}] {3} x {4}", + selected.Count, + bounds.X.ToString("n4"), + bounds.Y.ToString("n4"), + bounds.Width.ToString("n4"), + bounds.Length.ToString("n4") + ); + } + } + + private void ApplyLocationMode() + { + if (form == null) + return; + + var view = form.PlateView; + // Detach both first so repeated calls never stack handlers. + view.MouseMove -= PlateView_MouseMove; + view.MouseClick -= PlateView_MouseClick; + if (clickUpdatesLocation) + { + location.ForeColor = Color.Gray; + view.MouseClick += PlateView_MouseClick; + } + else + { + location.ForeColor = Color.Black; + view.MouseMove += PlateView_MouseMove; + } + } + + private void PlateView_PartAdded(object sender, ItemAddedEventArgs e) => UpdatePlate(); + + private void PlateView_PartRemoved(object sender, ItemRemovedEventArgs e) => UpdatePlate(); + + private void PlateView_MouseMove(object sender, MouseEventArgs e) => UpdateLocation(); + + private void PlateView_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + UpdateLocation(); + } + + private void PlateView_StatusChanged(object sender, EventArgs e) => status.Text = form.PlateView.Status; + + private void PlateView_SelectionChanged(object sender, EventArgs e) => UpdateSelection(); + } +}