diff --git a/ClientGUI/INItializableWindow.cs b/ClientGUI/INItializableWindow.cs
index 84ebfed40..65c0e731f 100644
--- a/ClientGUI/INItializableWindow.cs
+++ b/ClientGUI/INItializableWindow.cs
@@ -216,6 +216,10 @@ static string Localize(XNAControl control, string attributeName, string defaultV
if (kvp.Value == "Disable")
control.LeftClick += (s, e) => Disable();
}
+ else if (kvp.Key == "$ToggleableControl" && control is XNAClientButton button)
+ {
+ button.SetToggleableControl(kvp.Value);
+ }
else
{
control.ParseINIAttribute(ConfigIni, kvp.Key, kvp.Value);
diff --git a/ClientGUI/UIHelpers.cs b/ClientGUI/UIHelpers.cs
new file mode 100644
index 000000000..51c5685a9
--- /dev/null
+++ b/ClientGUI/UIHelpers.cs
@@ -0,0 +1,57 @@
+using System;
+using Rampastring.XNAUI.XNAControls;
+
+namespace ClientGUI;
+
+///
+/// Contains helper methods for UI / UI control-related functionality
+///
+public static class UIHelpers
+{
+ ///
+ /// Finds a child control matching a name and optionally a type.
+ ///
+ /// Type of the child control to find.
+ /// Parent control.
+ /// Name of the child control.
+ /// Whether or not to look for children recursively.
+ /// Child control matching the given name if found, otherwise type default value.
+ public static T FindMatchingChild(XNAControl parent, string controlName, bool recursive = false)
+ {
+ if (parent == null || string.IsNullOrEmpty(controlName))
+ return default;
+
+ foreach (var child in parent.Children)
+ {
+ if (controlName.Equals(child.Name, StringComparison.Ordinal) && child is T returnValue)
+ {
+ return returnValue;
+ }
+ else if (recursive)
+ {
+ var match = FindMatchingChild(child, controlName, recursive);
+
+ if (match != null && child is T)
+ return match;
+ }
+ }
+
+ return default;
+ }
+
+ ///
+ /// Finds control's parent window (instance of XNAWindow or INItializableWindow)
+ ///
+ /// Control to find the parent window for.
+ /// Control's parent window if found, otherwise null
+ public static XNAControl FindParentWindow(XNAControl control)
+ {
+ if (control == null || control.Parent == null)
+ return null;
+
+ if (control.Parent is INItializableWindow or XNAWindow)
+ return control.Parent;
+
+ return FindParentWindow(control.Parent);
+ }
+}
\ No newline at end of file
diff --git a/ClientGUI/XNAClientButton.cs b/ClientGUI/XNAClientButton.cs
index ba4b88a0b..60153eb4c 100644
--- a/ClientGUI/XNAClientButton.cs
+++ b/ClientGUI/XNAClientButton.cs
@@ -1,8 +1,6 @@
using Rampastring.XNAUI.XNAControls;
using Rampastring.XNAUI;
using Rampastring.Tools;
-using System;
-using ClientCore;
using ClientCore.Extensions;
namespace ClientGUI
@@ -11,6 +9,8 @@ public class XNAClientButton : XNAButton, IToolTipContainer
{
public ToolTip ToolTip { get; private set; }
+ public XNAControl ToggleableControl { get; set; }
+
private string _initialToolTipText;
public string ToolTipText
{
@@ -67,5 +67,35 @@ protected override void ParseControlINIAttribute(IniFile iniFile, string key, st
base.ParseControlINIAttribute(iniFile, key, value);
}
+
+ public void SetToggleableControl(string controlName)
+ {
+ if (!string.IsNullOrEmpty(controlName))
+ {
+ var parent = UIHelpers.FindParentWindow(this);
+
+ if (parent == null)
+ return;
+
+ ToggleableControl = UIHelpers.FindMatchingChild(parent, controlName, true);
+ }
+ }
+
+ public override void OnLeftClick()
+ {
+ if (!AllowClick)
+ return;
+
+ if (ToggleableControl != null)
+ {
+ if (ToggleableControl.Enabled)
+ ToggleableControl.Disable();
+ else
+ ToggleableControl.Enable();
+ }
+
+ base.OnLeftClick();
+ }
+
}
}
diff --git a/DTAConfig/Settings/SettingCheckBoxBase.cs b/DTAConfig/Settings/SettingCheckBoxBase.cs
index f5be9ba8e..3f010485f 100644
--- a/DTAConfig/Settings/SettingCheckBoxBase.cs
+++ b/DTAConfig/Settings/SettingCheckBoxBase.cs
@@ -45,7 +45,7 @@ public string ParentCheckBoxName
set
{
_parentCheckBoxName = value;
- UpdateParentCheckBox(FindParentCheckBox());
+ UpdateParentCheckBox(UIHelpers.FindMatchingChild(Parent, _parentCheckBoxName, false));
}
}
@@ -104,21 +104,6 @@ protected override void ParseControlINIAttribute(IniFile iniFile, string key, st
public abstract bool Save();
-
- private XNAClientCheckBox FindParentCheckBox()
- {
- if (string.IsNullOrEmpty(ParentCheckBoxName))
- return null;
-
- foreach (var control in Parent.Children)
- {
- if (control is XNAClientCheckBox && control.Name == ParentCheckBoxName)
- return control as XNAClientCheckBox;
- }
-
- return null;
- }
-
private void UpdateParentCheckBox(XNAClientCheckBox parentCheckBox)
{
if (ParentCheckBox != null)
diff --git a/Docs/INISystem.md b/Docs/INISystem.md
index f833e4c9b..daf48f426 100644
--- a/Docs/INISystem.md
+++ b/Docs/INISystem.md
@@ -242,6 +242,7 @@ These can ONLY be used in parent controls that inherit the `INItializableWindow`
`$Width` = ``{integer}`` the Width of the control
`$Height` = ``{integer}`` the Height of the control
`$TextAnchor`
+`$ToggleableControl` = ``{control name}`` (only on `XNAClientButton` or derived classes) Name of control whose visibility this button toggles, only works if the target control is initialized before the button and is not the parent window
### Dynamic Control Property Examples
```