mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-02 06:41:35 -05:00
Disable toolbar buttons that cannot be used
Plate commands need an open nest and no running job; Trim/Extend Cut-Off needs a cut-off on the plate and Sequence by Path needs two parts. The Plate menu's Trim/Extend item follows the same rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a89adc7911
commit
d57678ecee
4 files changed
+114
-7
No files matched your search
@@ -1,4 +1,5 @@
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using OpenNest.Controls;
|
||||
using OpenNest.Forms;
|
||||
using OpenNest.Geometry;
|
||||
@@ -77,6 +78,65 @@ public class MainFormCharacterizationTests
|
||||
Assert.Equal(new Guards(false, true, false, false), Read(host, editor, views));
|
||||
}, TimeSpan.FromMinutes(1), "The STA test did not complete.");
|
||||
|
||||
[Fact]
|
||||
public void ToolbarFollowsTheActiveDocumentAndItsPlate() => UndoTestEnv.Run(env =>
|
||||
{
|
||||
var host = env.Host;
|
||||
bool Enabled(string button) => Field<ToolStripItem>(typeof(MainForm), host, button).Enabled;
|
||||
void AddCutOff()
|
||||
{
|
||||
using var change = env.View.BeginChange("Add Cut-Off");
|
||||
change.MarkChanged();
|
||||
env.View.Plate.CutOffs.Add(new CutOff(new Vector(50, 0), CutOffAxis.Vertical));
|
||||
env.View.Plate.RegenerateCutOffs(env.View.CutOffSettings);
|
||||
change.Complete();
|
||||
}
|
||||
|
||||
// The first plate holds two parts and no cut-offs.
|
||||
env.Editor.PlateManager.LoadAt(0);
|
||||
Assert.True(Enabled("btnCutOff"));
|
||||
Assert.True(Enabled("btnSequenceByPath"));
|
||||
Assert.False(Enabled("btnTrimExtendCutOff"));
|
||||
Assert.False(UndoTestEnv.MenuItem(host, "mnuPlateTrimExtendCutOff").Enabled);
|
||||
|
||||
AddCutOff();
|
||||
Assert.True(Enabled("btnTrimExtendCutOff"));
|
||||
Assert.True(UndoTestEnv.MenuItem(host, "mnuPlateTrimExtendCutOff").Enabled);
|
||||
|
||||
Assert.True(host.TryUndo(env.Editor));
|
||||
Assert.False(Enabled("btnTrimExtendCutOff"));
|
||||
Assert.True(host.TryRedo(env.Editor));
|
||||
Assert.True(Enabled("btnTrimExtendCutOff"));
|
||||
|
||||
// Another plate has its own cut-offs; the third one is empty.
|
||||
env.Editor.PlateManager.LoadAt(2);
|
||||
Assert.False(Enabled("btnTrimExtendCutOff"));
|
||||
Assert.False(Enabled("btnSequenceByPath"));
|
||||
env.View.Plate.Parts.Add(new Part(env.Nest.Drawings.First(), new Vector(5, 5)));
|
||||
env.View.Plate.Parts.Add(new Part(env.Nest.Drawings.First(), new Vector(25, 5)));
|
||||
Assert.True(Enabled("btnSequenceByPath"));
|
||||
|
||||
// A running job locks the plate commands, as it does the Nest and Plate menus.
|
||||
Invoke(host, "SetNestingLockout", true);
|
||||
Assert.False(Enabled("btnAutoNest"));
|
||||
Assert.False(Enabled("btnCutOff"));
|
||||
Assert.False(Enabled("postButton"));
|
||||
Invoke(host, "SetNestingLockout", false);
|
||||
Assert.True(Enabled("btnAutoNest"));
|
||||
|
||||
env.Editor.Close();
|
||||
foreach (var button in ToolbarPlateCommands)
|
||||
Assert.False(Enabled(button), button);
|
||||
Assert.True(Enabled("btnNew"));
|
||||
Assert.True(Enabled("btnOpen"));
|
||||
});
|
||||
|
||||
private static readonly string[] ToolbarPlateCommands =
|
||||
{
|
||||
"btnSave", "btnSaveAs", "btnAutoNest", "btnShowRemnants", "btnCutOff", "btnTrimExtendCutOff",
|
||||
"btnCutPlanner", "btnSimulateCutting", "btnSequenceByPath", "postButton",
|
||||
};
|
||||
|
||||
private sealed record Guards(bool ExpandSpacing, bool CuttingPlan, bool Clamps, bool NestJob);
|
||||
|
||||
private static Guards Read(MainForm host, EditNestForm editor, PlateView[] views) => new(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using OpenNest.Collections;
|
||||
|
||||
namespace OpenNest.Forms
|
||||
{
|
||||
@@ -8,6 +9,7 @@ namespace OpenNest.Forms
|
||||
private void EnableCheck()
|
||||
{
|
||||
NavigationEnableCheck();
|
||||
ToolbarEnableCheck();
|
||||
|
||||
var hasValue = activeForm != null;
|
||||
|
||||
@@ -45,6 +47,31 @@ namespace OpenNest.Forms
|
||||
mnuNestLastPlate.Enabled = hasPlates && !plates.IsLast;
|
||||
}
|
||||
|
||||
// The plate commands need a plate to act on and, like the Nest and Plate menus, no
|
||||
// running job. Trim/Extend works on existing cut-offs; Sequence by Path needs two parts.
|
||||
private void ToolbarEnableCheck()
|
||||
{
|
||||
var plate = nestingInProgress ? null : activeForm?.PlateView?.Plate;
|
||||
var hasPlate = plate != null;
|
||||
var hasCutOffs = plate?.CutOffs.Count > 0;
|
||||
|
||||
btnAutoNest.Enabled = hasPlate;
|
||||
btnShowRemnants.Enabled = hasPlate;
|
||||
btnCutOff.Enabled = hasPlate;
|
||||
btnTrimExtendCutOff.Enabled = hasCutOffs;
|
||||
mnuPlateTrimExtendCutOff.Enabled = hasCutOffs;
|
||||
btnCutPlanner.Enabled = hasPlate;
|
||||
btnSimulateCutting.Enabled = hasPlate;
|
||||
btnSequenceByPath.Enabled = plate?.Parts.Count >= 2;
|
||||
postButton.Enabled = hasPlate;
|
||||
}
|
||||
|
||||
private void EditForm_PlateChanged(object sender, EventArgs e) => ToolbarEnableCheck();
|
||||
|
||||
private void PlateView_PartAdded(object sender, ItemAddedEventArgs<Part> e) => ToolbarEnableCheck();
|
||||
|
||||
private void PlateView_PartRemoved(object sender, ItemRemovedEventArgs<Part> e) => ToolbarEnableCheck();
|
||||
|
||||
private void SetNestingLockout(bool locked)
|
||||
{
|
||||
nestingInProgress = locked;
|
||||
@@ -53,6 +80,7 @@ namespace OpenNest.Forms
|
||||
mnuNest.Enabled = !locked;
|
||||
mnuPlate.Enabled = !locked;
|
||||
NavigationEnableCheck(locked);
|
||||
ToolbarEnableCheck();
|
||||
}
|
||||
|
||||
private void EngineComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||
|
||||
@@ -105,7 +105,12 @@ namespace OpenNest.Forms
|
||||
UpdateUndoMenu();
|
||||
}
|
||||
|
||||
private void History_Changed(object sender, EventArgs e) => UpdateUndoMenu();
|
||||
// Every recorded edit lands here, including those that add or remove a cut-off.
|
||||
private void History_Changed(object sender, EventArgs e)
|
||||
{
|
||||
UpdateUndoMenu();
|
||||
ToolbarEnableCheck();
|
||||
}
|
||||
|
||||
internal void UpdateUndoMenu()
|
||||
{
|
||||
|
||||
@@ -25,6 +25,9 @@ namespace OpenNest.Forms
|
||||
private readonly NestStorageController storage;
|
||||
private readonly ToolStripMenuItem storageModeMenu = new("Storage Mode...");
|
||||
private readonly ToolStripMenuItem exportNestMenu = new("Export .nest...");
|
||||
private readonly ToolStripButton btnCutPlanner;
|
||||
private readonly ToolStripButton btnSimulateCutting;
|
||||
private readonly ToolStripButton btnSequenceByPath;
|
||||
private readonly ToolStripDropDownButton postButton = new()
|
||||
{
|
||||
Name = "btnPost",
|
||||
@@ -124,12 +127,15 @@ namespace OpenNest.Forms
|
||||
statusStripToolTips = new StatusStripToolTips(statusStrip1); // The hold list lives in the ledger label's tooltip.
|
||||
statusBar = new MainStatusBar(statusLabel1, locationStatusLabel, selectionStatusLabel,
|
||||
machineStatusLabel, materialStatusLabel, plateUtilStatusLabel, ledgerStatusLabel);
|
||||
toolStrip1.Items.Add(CreateActionButton("btnCutPlanner", "Plan Cutting",
|
||||
Resources.cut_planner, ToolbarPlanCutting_Click));
|
||||
toolStrip1.Items.Add(CreateActionButton("btnSimulateCutting", "Simulate Cutting",
|
||||
Resources.cut_simulate, SimulateCutting_Click));
|
||||
toolStrip1.Items.Add(CreateActionButton("btnSequenceByPath", "Sequence by Path",
|
||||
Resources.manual_sequence, SequenceByPath_Click));
|
||||
btnCutPlanner = CreateActionButton("btnCutPlanner", "Plan Cutting",
|
||||
Resources.cut_planner, ToolbarPlanCutting_Click);
|
||||
btnSimulateCutting = CreateActionButton("btnSimulateCutting", "Simulate Cutting",
|
||||
Resources.cut_simulate, SimulateCutting_Click);
|
||||
btnSequenceByPath = CreateActionButton("btnSequenceByPath", "Sequence by Path",
|
||||
Resources.manual_sequence, SequenceByPath_Click);
|
||||
toolStrip1.Items.Add(btnCutPlanner);
|
||||
toolStrip1.Items.Add(btnSimulateCutting);
|
||||
toolStrip1.Items.Add(btnSequenceByPath);
|
||||
toolStrip1.Items.Add(postButton);
|
||||
storageModeMenu.Click += StorageMode_Click;
|
||||
exportNestMenu.Click += ExportNest_Click;
|
||||
@@ -262,7 +268,12 @@ namespace OpenNest.Forms
|
||||
|
||||
statusBar.Unbind();
|
||||
if (activeForm != null)
|
||||
{
|
||||
activeForm.PlateChanged -= EditForm_PlateChanged;
|
||||
activeForm.PlateView.OverlapStateChanged -= OverlapStateChanged;
|
||||
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)
|
||||
@@ -280,7 +291,10 @@ namespace OpenNest.Forms
|
||||
if (activeForm == null)
|
||||
return;
|
||||
|
||||
activeForm.PlateChanged += EditForm_PlateChanged;
|
||||
activeForm.PlateView.OverlapStateChanged += OverlapStateChanged;
|
||||
activeForm.PlateView.PartAdded += PlateView_PartAdded;
|
||||
activeForm.PlateView.PartRemoved += PlateView_PartRemoved;
|
||||
var activeNest = activeForm.Nest;
|
||||
activeForm.PlateView.CanEditClamps = () => !ClampsInUse(activeNest);
|
||||
mnuViewDrawRapids.Checked = activeForm.PlateView.DrawRapid;
|
||||
|
||||
Reference in new issue
Block a user