feat: add fill strategy enable/disable settings in options

OptionsForm now shows checkboxes for each fill strategy, persisted via
the new DisabledStrategies user setting. FillStrategyRegistry exposes
AllStrategies and DisabledNames for the UI. MainForm applies disabled
strategies on startup via OptionsForm.ApplyDisabledStrategies().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-27 14:14:10 -04:00
parent fd93cc9db2
commit 5568789902
6 changed files with 109 additions and 6 deletions

View File

@@ -22,6 +22,17 @@ namespace OpenNest.Engine.Strategies
public static IReadOnlyList<IFillStrategy> Strategies =>
sorted ??= FilterStrategies();
/// <summary>
/// Returns all registered strategies regardless of enabled/disabled state.
/// </summary>
public static IReadOnlyList<IFillStrategy> AllStrategies =>
strategies.OrderBy(s => s.Order).ToList();
/// <summary>
/// Returns the names of all permanently disabled strategies.
/// </summary>
public static IReadOnlyCollection<string> DisabledNames => disabled;
private static List<IFillStrategy> FilterStrategies()
{
var source = enabledFilter != null

View File

@@ -58,6 +58,8 @@ namespace OpenNest.Forms
var enginesDir = Path.Combine(Application.StartupPath, "Engines");
NestEngineRegistry.LoadPlugins(enginesDir);
OptionsForm.ApplyDisabledStrategies();
foreach (var engine in NestEngineRegistry.AvailableEngines)
engineComboBox.Items.Add(engine.Name);

View File

@@ -42,6 +42,7 @@
this.saveButton = new System.Windows.Forms.Button();
this.cancelButton = new System.Windows.Forms.Button();
this.bottomPanel1 = new OpenNest.Controls.BottomPanel();
this.strategyGroupBox = new System.Windows.Forms.GroupBox();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
this.tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).BeginInit();
@@ -210,13 +211,23 @@
this.bottomPanel1.Name = "bottomPanel1";
this.bottomPanel1.Size = new System.Drawing.Size(708, 50);
this.bottomPanel1.TabIndex = 1;
//
//
// strategyGroupBox
//
this.strategyGroupBox.Location = new System.Drawing.Point(12, 178);
this.strategyGroupBox.Name = "strategyGroupBox";
this.strategyGroupBox.Size = new System.Drawing.Size(684, 180);
this.strategyGroupBox.TabIndex = 2;
this.strategyGroupBox.TabStop = false;
this.strategyGroupBox.Text = "Fill Strategies";
//
// OptionsForm
//
//
this.AcceptButton = this.saveButton;
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.CancelButton = this.cancelButton;
this.ClientSize = new System.Drawing.Size(708, 418);
this.Controls.Add(this.strategyGroupBox);
this.Controls.Add(this.tableLayoutPanel1);
this.Controls.Add(this.bottomPanel1);
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
@@ -252,5 +263,6 @@
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.GroupBox strategyGroupBox;
}
}

View File

@@ -1,27 +1,58 @@
using OpenNest.Properties;
using OpenNest.Engine.Strategies;
using OpenNest.Properties;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace OpenNest.Forms
{
public partial class OptionsForm : Form
{
private readonly List<CheckBox> _strategyCheckBoxes = new();
public OptionsForm()
{
InitializeComponent();
BuildStrategyCheckBoxes();
}
protected override void OnLoad(System.EventArgs e)
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
LoadSettings();
}
private void BuildStrategyCheckBoxes()
{
var strategies = FillStrategyRegistry.AllStrategies;
var y = 20;
foreach (var strategy in strategies)
{
var cb = new CheckBox
{
Text = strategy.Name,
Tag = strategy.Name,
AutoSize = true,
Location = new System.Drawing.Point(10, y),
};
strategyGroupBox.Controls.Add(cb);
_strategyCheckBoxes.Add(cb);
y += 24;
}
}
private void LoadSettings()
{
textBox1.Text = Settings.Default.NestTemplatePath;
checkBox1.Checked = Settings.Default.CreateNewNestOnOpen;
numericUpDown1.Value = (decimal)Settings.Default.AutoSizePlateFactor;
numericUpDown2.Value = (decimal)Settings.Default.ImportSplinePrecision;
var disabledNames = ParseDisabledStrategies(Settings.Default.DisabledStrategies);
foreach (var cb in _strategyCheckBoxes)
cb.Checked = !disabledNames.Contains((string)cb.Tag);
}
private void SaveSettings()
@@ -30,15 +61,47 @@ namespace OpenNest.Forms
Settings.Default.CreateNewNestOnOpen = checkBox1.Checked;
Settings.Default.AutoSizePlateFactor = (double)numericUpDown1.Value;
Settings.Default.ImportSplinePrecision = (int)numericUpDown2.Value;
var disabledNames = _strategyCheckBoxes
.Where(cb => !cb.Checked)
.Select(cb => (string)cb.Tag);
Settings.Default.DisabledStrategies = string.Join(",", disabledNames);
Settings.Default.Save();
ApplyDisabledStrategies();
}
private void SaveSettings_Click(object sender, System.EventArgs e)
/// <summary>
/// Applies the DisabledStrategies setting to the FillStrategyRegistry.
/// Called on save and at startup from MainForm.
/// </summary>
public static void ApplyDisabledStrategies()
{
// Re-enable all, then disable the persisted set.
var all = FillStrategyRegistry.AllStrategies.Select(s => s.Name).ToArray();
FillStrategyRegistry.Enable(all);
var disabled = ParseDisabledStrategies(Settings.Default.DisabledStrategies);
if (disabled.Count > 0)
FillStrategyRegistry.Disable(disabled.ToArray());
}
private static HashSet<string> ParseDisabledStrategies(string value)
{
if (string.IsNullOrWhiteSpace(value))
return new HashSet<string>(StringComparer.OrdinalIgnoreCase);
return new HashSet<string>(
value.Split(',').Select(s => s.Trim()).Where(s => s.Length > 0),
StringComparer.OrdinalIgnoreCase);
}
private void SaveSettings_Click(object sender, EventArgs e)
{
SaveSettings();
}
private void BrowseNestTemplatePath_Click(object sender, System.EventArgs e)
private void BrowseNestTemplatePath_Click(object sender, EventArgs e)
{
var dlg = new OpenFileDialog();
dlg.Filter = "Template File|*.nstdot";

View File

@@ -214,5 +214,17 @@ namespace OpenNest.Properties {
this["LastPierceTime"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string DisabledStrategies {
get {
return ((string)(this["DisabledStrategies"]));
}
set {
this["DisabledStrategies"] = value;
}
}
}
}

View File

@@ -50,5 +50,8 @@
<Setting Name="LastPierceTime" Type="System.Decimal" Scope="User">
<Value Profile="(Default)">0</Value>
</Setting>
<Setting Name="DisabledStrategies" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings>
</SettingsFile>