From a1266f4cd47f802bb2680644b6018bbd7104e63f Mon Sep 17 00:00:00 2001 From: Avasam Date: Sun, 19 Jul 2026 21:46:21 -0400 Subject: [PATCH] Reduce new settings churn --- .../AutoSplitIntegrationComponent.cs | 2 +- ...itIntegrationComponentSettings.Designer.cs | 3 - .../AutoSplitIntegrationComponentSettings.cs | 58 ++++++++++++++++--- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/UI/Components/AutoSplitIntegrationComponent.cs b/UI/Components/AutoSplitIntegrationComponent.cs index 9963ca2..e4332c3 100644 --- a/UI/Components/AutoSplitIntegrationComponent.cs +++ b/UI/Components/AutoSplitIntegrationComponent.cs @@ -14,7 +14,7 @@ public class AutoSplitIntegrationComponent : IComponent internal AutoSplitProcess AutoSplit { get; set; } - internal bool GameTimePausing { get; set; } = false; + public bool GameTimePausing { get; set; } = false; internal AutoSplitIntegrationComponentSettings Settings { get; } diff --git a/UI/Components/AutoSplitIntegrationComponentSettings.Designer.cs b/UI/Components/AutoSplitIntegrationComponentSettings.Designer.cs index 6a5f288..ef59d13 100644 --- a/UI/Components/AutoSplitIntegrationComponentSettings.Designer.cs +++ b/UI/Components/AutoSplitIntegrationComponentSettings.Designer.cs @@ -77,7 +77,6 @@ private void InitializeComponent() this.textBoxAutoSplitPath.Name = "textBoxAutoSplitPath"; this.textBoxAutoSplitPath.Size = new System.Drawing.Size(294, 20); this.textBoxAutoSplitPath.TabIndex = 1; - this.textBoxAutoSplitPath.TextChanged += new System.EventHandler(this.TextBoxAutoSplitPath_TextChanged); // // tableLayoutPanel1 // @@ -125,7 +124,6 @@ private void InitializeComponent() this.textBoxSettingsPath.Name = "textBoxSettingsPath"; this.textBoxSettingsPath.Size = new System.Drawing.Size(294, 20); this.textBoxSettingsPath.TabIndex = 4; - this.textBoxSettingsPath.TextChanged += new System.EventHandler(this.TextBoxSettingsPath_TextChanged); // // labelSettingsPath // @@ -216,7 +214,6 @@ private void InitializeComponent() this.checkBoxGameTimePausing.TabIndex = 12; this.checkBoxGameTimePausing.Text = "Pause Game Time only (this will disallow manual unpausing)"; this.checkBoxGameTimePausing.UseVisualStyleBackColor = true; - this.checkBoxGameTimePausing.CheckedChanged += new System.EventHandler(this.CheckBoxGameTimePausing_CheckedChanged); // // AutoSplitIntegrationComponentSettings // diff --git a/UI/Components/AutoSplitIntegrationComponentSettings.cs b/UI/Components/AutoSplitIntegrationComponentSettings.cs index 26415d5..d2a6ecf 100644 --- a/UI/Components/AutoSplitIntegrationComponentSettings.cs +++ b/UI/Components/AutoSplitIntegrationComponentSettings.cs @@ -11,6 +11,7 @@ public partial class AutoSplitIntegrationComponentSettings : UserControl { private readonly AutoSplitIntegrationComponent component; private readonly LiveSplitState state; + private readonly Setting[] settingDefs; internal string LabelAutoSplitVersion_Text { @@ -61,6 +62,10 @@ internal AutoSplitIntegrationComponentSettings(AutoSplitIntegrationComponent com InitializeComponent(); + settingDefs = BuildSettingDefs(); + foreach (Setting setting in settingDefs) + setting.Bind(); + checkBoxGameTimePausing.Enabled = state.CurrentPhase == TimerPhase.NotRunning; } @@ -73,9 +78,8 @@ internal XmlNode GetSettings(XmlDocument document) XmlElement settingsElement = document.CreateElement("Settings"); SettingsHelper.CreateSetting(document, settingsElement, "Version", "1.8"); - SettingsHelper.CreateSetting(document, settingsElement, "AutoSplitPath", component.AutoSplitPath); - SettingsHelper.CreateSetting(document, settingsElement, "SettingsPath", component.SettingsPath); - SettingsHelper.CreateSetting(document, settingsElement, "GameTimePausing", component.GameTimePausing); + foreach (Setting setting in settingDefs) + setting.Save(document, settingsElement); return settingsElement; } @@ -85,9 +89,8 @@ internal void SetSettings(XmlNode settings) if (((XmlElement)settings).IsEmpty) return; - component.AutoSplitPath = textBoxAutoSplitPath.Text = SettingsHelper.ParseString(settings["AutoSplitPath"]); - component.SettingsPath = textBoxSettingsPath.Text = SettingsHelper.ParseString(settings["SettingsPath"]); - component.GameTimePausing = checkBoxGameTimePausing.Checked = SettingsHelper.ParseBool(settings["GameTimePausing"]); + foreach (Setting setting in settingDefs) + setting.Load(settings); if (component.AutoSplit != null) { @@ -140,11 +143,48 @@ private void ButtonSettingsPathBrowse_Click(object sender, EventArgs e) => Brows private void ButtonKillAutoSplit_Click(object sender, EventArgs e) => component.KillAutoSplit(); - private void CheckBoxGameTimePausing_CheckedChanged(object sender, EventArgs e) => component.GameTimePausing = checkBoxGameTimePausing.Checked; + // Registry of persisted settings. Each entry two-way binds a control to a + // component property and knows how to save/load itself. Adding a setting = + // one row here (plus the component property and the Designer control) — no + // change-handler, no GetSettings/SetSettings edits. + private Setting[] BuildSettingDefs() => + [ + TextSetting("AutoSplitPath", textBoxAutoSplitPath, nameof(component.AutoSplitPath), v => component.AutoSplitPath = v), + TextSetting("SettingsPath", textBoxSettingsPath, nameof(component.SettingsPath), v => component.SettingsPath = v), + BoolSetting("GameTimePausing", checkBoxGameTimePausing, nameof(component.GameTimePausing), v => component.GameTimePausing = v), + ]; + + private Setting TextSetting(string key, TextBox box, string boundProperty, Action set) => new( + bind: () => box.DataBindings.Add(nameof(TextBox.Text), component, boundProperty, false, DataSourceUpdateMode.OnPropertyChanged), + save: (document, parent) => SettingsHelper.CreateSetting(document, parent, key, box.Text), + load: settings => + { + string value = SettingsHelper.ParseString(settings[key]); + box.Text = value; // reflect in the UI + set(value); // and in the component: bindings aren't live until the panel is shown + }); - private void TextBoxAutoSplitPath_TextChanged(object sender, EventArgs e) => component.AutoSplitPath = textBoxAutoSplitPath.Text; + private Setting BoolSetting(string key, CheckBox box, string boundProperty, Action set) => new( + bind: () => box.DataBindings.Add(nameof(CheckBox.Checked), component, boundProperty, false, DataSourceUpdateMode.OnPropertyChanged), + save: (document, parent) => SettingsHelper.CreateSetting(document, parent, key, box.Checked), + load: settings => + { + bool value = SettingsHelper.ParseBool(settings[key]); + box.Checked = value; + set(value); + }); - private void TextBoxSettingsPath_TextChanged(object sender, EventArgs e) => component.SettingsPath = textBoxSettingsPath.Text; + /// + /// One persisted setting: a two-way binding between a control and a component + /// property, plus how it saves to and loads from the layout XML. The stable XML + /// key is passed explicitly so it stays decoupled from the code identifier. + /// + private sealed class Setting(Action bind, Action save, Action load) + { + public readonly Action Bind = bind; + public readonly Action Save = save; + public readonly Action Load = load; + } } }