mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-27 05:01:05 -04:00
refactor(ui): extract MainForm status bar binding
MainStatusBar owns the status, location, selection and plate labels and the click-vs-move location mode. Bind(EditNestForm)/Unbind() replace the manual PlateView subscribe/unsubscribe pairs in OnMdiChildActivate; MainForm keeps only its overlap-menu subscription. Applying the location mode now detaches both mouse handlers first, which also drops the old self-assignment of the mode flag. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9b46db4891
commit
93d118585f
5 files changed
+224
-175
No files matched your search
@@ -22,7 +22,7 @@ namespace OpenNest.Forms
|
||||
editForm.PlateChanged += (sender, e) =>
|
||||
{
|
||||
NavigationEnableCheck();
|
||||
UpdatePlateStatus();
|
||||
statusBar.UpdatePlate();
|
||||
mnuPlateRemove.Enabled = activeForm?.PlateManager.CanRemoveCurrent ?? false;
|
||||
};
|
||||
editForm.WindowState = windowState;
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace OpenNest.Forms
|
||||
if (activeForm == null)
|
||||
return;
|
||||
activeForm.ResizePlateToFitParts();
|
||||
UpdatePlateStatus();
|
||||
statusBar.UpdatePlate();
|
||||
}
|
||||
|
||||
private void RotateCw_Click(object sender, EventArgs e)
|
||||
|
||||
@@ -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<Part> e) =>
|
||||
UpdatePlateStatus();
|
||||
|
||||
private void PlateView_PartRemoved(object sender, ItemRemovedEventArgs<Part> 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
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 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).
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Follows <paramref name="editForm"/>'s plate view after detaching from the previous
|
||||
/// document; null clears every label.
|
||||
/// </summary>
|
||||
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<Part> e) => UpdatePlate();
|
||||
|
||||
private void PlateView_PartRemoved(object sender, ItemRemovedEventArgs<Part> 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();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user