mirror of
https://github.com/9ParsonsB/Pulsar.git
synced 2025-07-01 08:23:42 -04:00
[Core] Settings improvements: Grouping w/labels, support for doubles (#137)
* [Core] Settings improvements: Grouping w/labels, support for doubles Layout improvements: * Plugins can set `[SettingSuggestedColumnWidth(123)]` on a settings class to adjust the settings view column width to make it wider or narrower to fit things nicely. * Plugins can set `[SettingNewGroup("label")]` on any setting property to force a "new paragraph", or group, of settings. If "label" is also provided, a grouping header with that text will also be created. * A double precision up/down numeric control has been added. In support of this, there is now a precision value on the existing `[SettingNumericBounds]` attribute to specify the number of digits of precision the control displays/allows. Plugins: * The above have been applied/demonstrated on the Botanist and Explorer plugin settings.
This commit is contained in:
@ -26,6 +26,12 @@ namespace Observatory.UI
|
||||
_plugin = plugin;
|
||||
|
||||
// Filtered to only settings without SettingIgnore attribute
|
||||
var attrib = _plugin.Settings.GetType().GetCustomAttribute<SettingSuggestedColumnWidth>();
|
||||
if (attrib != null && attrib.Width > 0)
|
||||
{
|
||||
int minScreenWidth = Screen.AllScreens.Min(s => s.Bounds.Width);
|
||||
_colWidth = Math.Min(attrib.Width, minScreenWidth / 2);
|
||||
}
|
||||
var settings = PluginManagement.PluginManager.GetSettingDisplayNames(plugin.Settings).Where(s => !Attribute.IsDefined(s.Key, typeof(SettingIgnore)));
|
||||
CreateControls(settings);
|
||||
|
||||
@ -51,12 +57,30 @@ namespace Observatory.UI
|
||||
|
||||
foreach (var setting in settings)
|
||||
{
|
||||
// Reset the column tracking for checkboxes if this isn't a checkbox
|
||||
// Reset the column tracking for checkboxes if this isn't a checkbox or explicitly requested
|
||||
// to start a new grouping of settings.
|
||||
int addedHeight = 35;
|
||||
if (setting.Key.PropertyType.Name != "Boolean")
|
||||
var newGroup = Attribute.GetCustomAttribute(setting.Key, typeof(SettingNewGroup)) as SettingNewGroup;
|
||||
|
||||
if (setting.Key.PropertyType.Name != "Boolean" || newGroup != null)
|
||||
{
|
||||
if (recentHalfCol) _colHeight.Add(addedHeight);
|
||||
recentHalfCol = false;
|
||||
|
||||
if (newGroup != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(newGroup.Label))
|
||||
{
|
||||
var label = CreateGroupLabel(newGroup.Label);
|
||||
label.Location = GetSettingPosition();
|
||||
|
||||
Controls.Add(label);
|
||||
trackBottomEdge(label);
|
||||
_colHeight.Add(label.Height);
|
||||
}
|
||||
else
|
||||
_colHeight.Add(10);
|
||||
}
|
||||
}
|
||||
|
||||
switch (setting.Key.GetValue(_plugin.Settings))
|
||||
@ -98,7 +122,7 @@ namespace Observatory.UI
|
||||
break;
|
||||
case int:
|
||||
// We have two options for integer values:
|
||||
// 1) A slider (explicit by way of the SettingIntegerUseSlider attribute and bounded to 0..100 by default)
|
||||
// 1) A slider (explicit by way of the SettingNumericUseSlider attribute and bounded to 0..100 by default)
|
||||
// 2) A numeric up/down (default otherwise, and is unbounded by default).
|
||||
// Bounds for both can be set via the SettingNumericBounds attribute, only the up/down uses Increment.
|
||||
var intLabel = CreateSettingLabel(setting.Value);
|
||||
@ -109,7 +133,7 @@ namespace Observatory.UI
|
||||
}
|
||||
else
|
||||
{
|
||||
intControl = CreateSettingNumericUpDown(setting.Key);
|
||||
intControl = CreateSettingNumericUpDownForInt(setting.Key);
|
||||
}
|
||||
intLabel.Location = GetSettingPosition();
|
||||
intControl.Location = GetSettingPosition(true);
|
||||
@ -122,6 +146,23 @@ namespace Observatory.UI
|
||||
Controls.Add(intControl);
|
||||
trackBottomEdge(intControl);
|
||||
break;
|
||||
case double:
|
||||
// We have one options for double values:
|
||||
// 1) A numeric up/down (default otherwise, and is unbounded by default).
|
||||
// Bounds can be set via the SettingNumericBounds attribute.
|
||||
var doubleLabel = CreateSettingLabel(setting.Value);
|
||||
Control doubleControl = CreateSettingNumericUpDownForDouble(setting.Key);
|
||||
doubleLabel.Location = GetSettingPosition();
|
||||
doubleControl.Location = GetSettingPosition(true);
|
||||
|
||||
addedHeight = doubleControl.Height + 2;
|
||||
doubleLabel.Height = doubleControl.Height;
|
||||
doubleLabel.TextAlign = ContentAlignment.MiddleRight;
|
||||
|
||||
Controls.Add(doubleLabel);
|
||||
Controls.Add(doubleControl);
|
||||
trackBottomEdge(doubleControl);
|
||||
break;
|
||||
case Action action:
|
||||
var button = CreateSettingButton(setting.Value, action);
|
||||
|
||||
@ -152,8 +193,7 @@ namespace Observatory.UI
|
||||
|
||||
private Point GetSettingPosition(bool secondCol = false)
|
||||
{
|
||||
//return new Point(10 + (secondCol ? 200 : 0), -26 + _colHeight.Sum());
|
||||
return new Point(10 + (secondCol ? _colWidth : 0), 15 + _colHeight.Sum());
|
||||
return new Point(20 + (secondCol ? _colWidth + 20 : 0), 15 + _colHeight.Sum());
|
||||
}
|
||||
|
||||
|
||||
@ -170,6 +210,20 @@ namespace Observatory.UI
|
||||
return label;
|
||||
}
|
||||
|
||||
private Label CreateGroupLabel(string groupLabel)
|
||||
{
|
||||
Label label = new()
|
||||
{
|
||||
Text = groupLabel,
|
||||
TextAlign = System.Drawing.ContentAlignment.MiddleLeft,
|
||||
Width = _colWidth * 2,
|
||||
ForeColor = Color.LightGray,
|
||||
};
|
||||
label.Font = new Font(label.Font.FontFamily, label.Font.Size + 1, FontStyle.Bold);
|
||||
label.Height += 10; // Add spacing.
|
||||
return label;
|
||||
}
|
||||
|
||||
private ComboBox CreateSettingDropdown(PropertyInfo setting, Dictionary<string, object> dropdownItems)
|
||||
{
|
||||
var backingValueName = (SettingBackingValue?)Attribute.GetCustomAttribute(setting, typeof(SettingBackingValue));
|
||||
@ -225,7 +279,7 @@ namespace Observatory.UI
|
||||
|
||||
private TrackBar CreateSettingTrackbar(PropertyInfo setting)
|
||||
{
|
||||
SettingNumericBounds? bounds = (SettingNumericBounds?)System.Attribute.GetCustomAttribute(setting, typeof(SettingNumericBounds));
|
||||
SettingNumericBounds? bounds = (SettingNumericBounds?)Attribute.GetCustomAttribute(setting, typeof(SettingNumericBounds));
|
||||
|
||||
var minBound = Convert.ToInt32(bounds?.Minimum ?? 0);
|
||||
var maxBound = Convert.ToInt32(bounds?.Maximum ?? 100);
|
||||
@ -246,16 +300,16 @@ namespace Observatory.UI
|
||||
|
||||
trackBar.ValueChanged += (sender, e) =>
|
||||
{
|
||||
setting.SetValue(_plugin.Settings, Convert.ToInt32(trackBar.Value));
|
||||
setting.SetValue(_plugin.Settings, trackBar.Value);
|
||||
SaveSettings();
|
||||
};
|
||||
|
||||
return trackBar;
|
||||
}
|
||||
|
||||
private NumericUpDown CreateSettingNumericUpDown(PropertyInfo setting)
|
||||
private NumericUpDown CreateSettingNumericUpDownForInt(PropertyInfo setting)
|
||||
{
|
||||
SettingNumericBounds? bounds = (SettingNumericBounds?)System.Attribute.GetCustomAttribute(setting, typeof(SettingNumericBounds));
|
||||
SettingNumericBounds? bounds = (SettingNumericBounds?)Attribute.GetCustomAttribute(setting, typeof(SettingNumericBounds));
|
||||
NumericUpDown numericUpDown = new()
|
||||
{
|
||||
Width = _colWidth,
|
||||
@ -265,7 +319,6 @@ namespace Observatory.UI
|
||||
};
|
||||
|
||||
numericUpDown.Value = (int?)setting.GetValue(_plugin.Settings) ?? 0;
|
||||
|
||||
numericUpDown.ValueChanged += (sender, e) =>
|
||||
{
|
||||
setting.SetValue(_plugin.Settings, Convert.ToInt32(numericUpDown.Value));
|
||||
@ -275,6 +328,28 @@ namespace Observatory.UI
|
||||
return numericUpDown;
|
||||
}
|
||||
|
||||
private NumericUpDown CreateSettingNumericUpDownForDouble(PropertyInfo setting)
|
||||
{
|
||||
SettingNumericBounds? bounds = (SettingNumericBounds?)Attribute.GetCustomAttribute(setting, typeof(SettingNumericBounds));
|
||||
NumericUpDown numericUpDown = new()
|
||||
{
|
||||
Width = _colWidth,
|
||||
Minimum = Convert.ToDecimal(bounds?.Minimum ?? Double.MinValue),
|
||||
Maximum = Convert.ToDecimal(bounds?.Maximum ?? Double.MaxValue),
|
||||
Increment = Convert.ToDecimal(bounds?.Increment ?? 1.0),
|
||||
DecimalPlaces = bounds?.Precision ?? 1,
|
||||
};
|
||||
|
||||
numericUpDown.Value = Convert.ToDecimal(setting.GetValue(_plugin.Settings) ?? 0);
|
||||
numericUpDown.ValueChanged += (sender, e) =>
|
||||
{
|
||||
setting.SetValue(_plugin.Settings, Convert.ToDouble(numericUpDown.Value));
|
||||
SaveSettings();
|
||||
};
|
||||
|
||||
return numericUpDown;
|
||||
}
|
||||
|
||||
private CheckBox CreateBoolSetting(KeyValuePair<PropertyInfo, string> setting)
|
||||
{
|
||||
CheckBox checkBox = new()
|
||||
|
Reference in New Issue
Block a user