Initial release: HSUI v1.0.0.0 - HUD replacement with configurable hotbars
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,682 @@
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Utility;
|
||||
using HSUI.Enums;
|
||||
using HSUI.Helpers;
|
||||
using HSUI.Interface.GeneralElements;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Reflection;
|
||||
|
||||
namespace HSUI.Config.Attributes
|
||||
{
|
||||
#region class attributes
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class ExportableAttribute : Attribute
|
||||
{
|
||||
public bool exportable;
|
||||
|
||||
public ExportableAttribute(bool exportable)
|
||||
{
|
||||
this.exportable = exportable;
|
||||
}
|
||||
}
|
||||
|
||||
public class ShareableAttribute : Attribute
|
||||
{
|
||||
public bool shareable;
|
||||
|
||||
public ShareableAttribute(bool shareable)
|
||||
{
|
||||
this.shareable = shareable;
|
||||
}
|
||||
}
|
||||
|
||||
public class ResettableAttribute : Attribute
|
||||
{
|
||||
public bool resettable;
|
||||
|
||||
public ResettableAttribute(bool resettable)
|
||||
{
|
||||
this.resettable = resettable;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class DisableableAttribute : Attribute
|
||||
{
|
||||
public bool disableable;
|
||||
|
||||
public DisableableAttribute(bool disableable)
|
||||
{
|
||||
this.disableable = disableable;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class DisableParentSettingsAttribute : Attribute
|
||||
{
|
||||
public readonly string[] DisabledFields;
|
||||
|
||||
public DisableParentSettingsAttribute(params string[] fields)
|
||||
{
|
||||
this.DisabledFields = fields;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region method attributes
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class ManualDrawAttribute : Attribute
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region field attributes
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public abstract class ConfigAttribute : Attribute
|
||||
{
|
||||
public string friendlyName;
|
||||
public bool isMonitored = false;
|
||||
public bool separator = false;
|
||||
public bool spacing = false;
|
||||
public string? help = null;
|
||||
|
||||
public ConfigAttribute(string friendlyName)
|
||||
{
|
||||
this.friendlyName = friendlyName;
|
||||
}
|
||||
|
||||
public bool Draw(FieldInfo field, PluginConfigObject config, string? ID, bool collapsingHeader = false)
|
||||
{
|
||||
bool result = DrawField(field, config, ID, collapsingHeader);
|
||||
|
||||
if (help != null && ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip(help);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public abstract bool DrawField(FieldInfo field, PluginConfigObject config, string? ID, bool collapsingHeader = false);
|
||||
|
||||
protected string IDText(string? ID) => ID != null ? " ##" + ID : "";
|
||||
|
||||
protected void TriggerChangeEvent<T>(PluginConfigObject config, string fieldName, object value, ChangeType type = ChangeType.None)
|
||||
{
|
||||
if (!isMonitored || config is not IOnChangeEventArgs eventObject)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
eventObject.OnValueChanged(new OnChangeEventArgs<T>(fieldName, (T)value, type));
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class CheckboxAttribute : ConfigAttribute
|
||||
{
|
||||
public CheckboxAttribute(string friendlyName) : base(friendlyName) { }
|
||||
|
||||
public override bool DrawField(FieldInfo field, PluginConfigObject config, string? ID, bool collapsingHeader)
|
||||
{
|
||||
var disableable = config.Disableable;
|
||||
|
||||
if (!disableable && friendlyName == "Enabled")
|
||||
{
|
||||
if (ID != null)
|
||||
{
|
||||
ImGui.Text(ID);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool? fieldVal = (bool?)field.GetValue(config);
|
||||
bool boolVal = fieldVal.HasValue ? fieldVal.Value : false;
|
||||
|
||||
if (ImGui.Checkbox(ID != null && friendlyName == "Enabled" && !collapsingHeader ? ID : friendlyName + IDText(ID), ref boolVal))
|
||||
{
|
||||
field.SetValue(config, boolVal);
|
||||
|
||||
TriggerChangeEvent<bool>(config, field.Name, boolVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
|
||||
public class RadioSelector : ConfigAttribute
|
||||
{
|
||||
private string[] _options;
|
||||
|
||||
public string? Label { get; set; }
|
||||
|
||||
public RadioSelector(params string[] options) : base(string.Join("_", options))
|
||||
{
|
||||
_options = options;
|
||||
}
|
||||
|
||||
public RadioSelector(Type enumType) : this(enumType.IsEnum ? Enum.GetNames(enumType) : Array.Empty<string>()) { }
|
||||
|
||||
public override bool DrawField(FieldInfo field, PluginConfigObject config, string? ID, bool collapsingHeader)
|
||||
{
|
||||
bool changed = false;
|
||||
object? fieldVal = field.GetValue(config);
|
||||
|
||||
int intVal = 0;
|
||||
if (fieldVal != null)
|
||||
{
|
||||
intVal = (int)fieldVal;
|
||||
}
|
||||
|
||||
string? label = Label ?? friendlyName;
|
||||
if (!string.IsNullOrEmpty(label) && label != string.Join("_", _options))
|
||||
{
|
||||
ImGui.TextUnformatted(label);
|
||||
ImGui.SameLine();
|
||||
}
|
||||
|
||||
for (int i = 0; i < _options.Length; i++)
|
||||
{
|
||||
changed |= ImGui.RadioButton(_options[i], ref intVal, i);
|
||||
if (i < _options.Length - 1)
|
||||
{
|
||||
ImGui.SameLine();
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
field.SetValue(config, intVal);
|
||||
TriggerChangeEvent<int>(config, field.Name, intVal);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class DragFloatAttribute : ConfigAttribute
|
||||
{
|
||||
public float min;
|
||||
public float max;
|
||||
public float velocity;
|
||||
|
||||
public DragFloatAttribute(string friendlyName) : base(friendlyName)
|
||||
{
|
||||
min = 1f;
|
||||
max = 1000f;
|
||||
velocity = 1f;
|
||||
}
|
||||
|
||||
public override bool DrawField(FieldInfo field, PluginConfigObject config, string? ID, bool collapsingHeader)
|
||||
{
|
||||
float? fieldVal = (float?)field.GetValue(config);
|
||||
float floatVal = fieldVal.HasValue ? fieldVal.Value : 0;
|
||||
|
||||
if (ImGui.DragFloat(friendlyName + IDText(ID), ref floatVal, velocity, min, max))
|
||||
{
|
||||
field.SetValue(config, floatVal);
|
||||
|
||||
TriggerChangeEvent<float>(config, field.Name, floatVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class DragIntAttribute : ConfigAttribute
|
||||
{
|
||||
public int min;
|
||||
public int max;
|
||||
public float velocity;
|
||||
|
||||
public DragIntAttribute(string friendlyName) : base(friendlyName)
|
||||
{
|
||||
min = 1;
|
||||
max = 1000;
|
||||
velocity = 1;
|
||||
}
|
||||
|
||||
public override bool DrawField(FieldInfo field, PluginConfigObject config, string? ID, bool collapsingHeader)
|
||||
{
|
||||
int? fieldVal = (int?)field.GetValue(config);
|
||||
int intVal = fieldVal.HasValue ? fieldVal.Value : 0;
|
||||
|
||||
if (ImGui.DragInt(friendlyName + IDText(ID), ref intVal, velocity, min, max))
|
||||
{
|
||||
field.SetValue(config, intVal);
|
||||
|
||||
TriggerChangeEvent<int>(config, field.Name, intVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class DragFloat2Attribute : ConfigAttribute
|
||||
{
|
||||
public float min;
|
||||
public float max;
|
||||
public float velocity;
|
||||
|
||||
public DragFloat2Attribute(string friendlyName) : base(friendlyName)
|
||||
{
|
||||
min = 1f;
|
||||
max = 1000f;
|
||||
velocity = 1f;
|
||||
}
|
||||
|
||||
public override bool DrawField(FieldInfo field, PluginConfigObject config, string? ID, bool collapsingHeader)
|
||||
{
|
||||
Vector2? fieldVal = (Vector2?)field.GetValue(config);
|
||||
Vector2 vectorVal = fieldVal.HasValue ? fieldVal.Value : Vector2.Zero;
|
||||
|
||||
if (ImGui.DragFloat2(friendlyName + IDText(ID), ref vectorVal, velocity, min, max))
|
||||
{
|
||||
field.SetValue(config, vectorVal);
|
||||
|
||||
TriggerChangeEvent<Vector2>(config, field.Name, vectorVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class DragInt2Attribute : ConfigAttribute
|
||||
{
|
||||
public int min;
|
||||
public int max;
|
||||
public int velocity;
|
||||
|
||||
public DragInt2Attribute(string friendlyName) : base(friendlyName)
|
||||
{
|
||||
min = 1;
|
||||
max = 1000;
|
||||
velocity = 1;
|
||||
}
|
||||
|
||||
public override bool DrawField(FieldInfo field, PluginConfigObject config, string? ID, bool collapsingHeader)
|
||||
{
|
||||
Vector2? fieldVal = (Vector2?)field.GetValue(config);
|
||||
Vector2 vectorVal = fieldVal.HasValue ? fieldVal.Value : Vector2.Zero;
|
||||
|
||||
if (ImGui.DragFloat2(friendlyName + IDText(ID), ref vectorVal, velocity, min, max))
|
||||
{
|
||||
field.SetValue(config, vectorVal);
|
||||
|
||||
TriggerChangeEvent<Vector2>(config, field.Name, vectorVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class InputTextAttribute : ConfigAttribute
|
||||
{
|
||||
public int maxLength;
|
||||
public bool formattable = true;
|
||||
|
||||
private string _searchText = "";
|
||||
|
||||
public InputTextAttribute(string friendlyName) : base(friendlyName)
|
||||
{
|
||||
this.friendlyName = friendlyName;
|
||||
maxLength = 999;
|
||||
}
|
||||
|
||||
public override bool DrawField(FieldInfo field, PluginConfigObject config, string? ID, bool collapsingHeader)
|
||||
{
|
||||
string? fieldVal = (string?)field.GetValue(config);
|
||||
string stringVal = fieldVal ?? "";
|
||||
string? finalValue = null;
|
||||
|
||||
string popupId = ID != null ? "DelvUI_TextTagsList " + ID : "DelvUI_TextTagsList ##" + friendlyName;
|
||||
|
||||
if (!formattable)
|
||||
{
|
||||
if (ImGui.InputText(friendlyName + IDText(ID), ref stringVal))
|
||||
{
|
||||
finalValue = stringVal;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float scale = ImGuiHelpers.GlobalScale;
|
||||
float width = ImGui.CalcItemWidth();
|
||||
float height = Math.Max(24 * scale, ImGui.CalcTextSize(stringVal, false, width).Y + 6 * scale);
|
||||
Vector2 size = new Vector2(width, height);
|
||||
|
||||
if (ImGui.InputTextMultiline(friendlyName + IDText(ID), ref stringVal, maxLength, size, ImGuiInputTextFlags.AllowTabInput))
|
||||
{
|
||||
finalValue = stringVal;
|
||||
}
|
||||
|
||||
// text tags
|
||||
ImGui.SameLine();
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
if (ImGui.Button(FontAwesomeIcon.Pen.ToIconString() + "##" + ID))
|
||||
{
|
||||
ImGui.OpenPopup(popupId);
|
||||
}
|
||||
ImGui.PopFont();
|
||||
|
||||
ImGuiHelper.SetTooltip("Text Tags");
|
||||
}
|
||||
|
||||
var selectedTag = ImGuiHelper.DrawTextTagsList(popupId, ref _searchText);
|
||||
if (selectedTag != null)
|
||||
{
|
||||
finalValue = stringVal + selectedTag;
|
||||
}
|
||||
|
||||
if (finalValue != null)
|
||||
{
|
||||
field.SetValue(config, finalValue);
|
||||
TriggerChangeEvent<string>(config, field.Name, finalValue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class ColorEdit4Attribute : ConfigAttribute
|
||||
{
|
||||
public ColorEdit4Attribute(string friendlyName) : base(friendlyName) { }
|
||||
|
||||
public override bool DrawField(FieldInfo field, PluginConfigObject config, string? ID, bool collapsingHeader)
|
||||
{
|
||||
PluginConfigColor? colorVal = (PluginConfigColor?)field.GetValue(config);
|
||||
Vector4 vector = (colorVal != null ? colorVal.Vector : Vector4.Zero);
|
||||
|
||||
if (ImGui.ColorEdit4(friendlyName + IDText(ID), ref vector, ImGuiColorEditFlags.AlphaPreview | ImGuiColorEditFlags.AlphaBar))
|
||||
{
|
||||
if (colorVal is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
colorVal.Vector = vector;
|
||||
field.SetValue(config, colorVal);
|
||||
|
||||
TriggerChangeEvent<PluginConfigColor>(config, field.Name, colorVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class ComboAttribute : ConfigAttribute
|
||||
{
|
||||
public string[] options;
|
||||
|
||||
public ComboAttribute(string friendlyName, params string[] options) : base(friendlyName)
|
||||
{
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public override bool DrawField(FieldInfo field, PluginConfigObject config, string? ID, bool collapsingHeader)
|
||||
{
|
||||
object? fieldVal = field.GetValue(config);
|
||||
|
||||
int intVal = 0;
|
||||
if (fieldVal != null)
|
||||
{
|
||||
intVal = (int)fieldVal;
|
||||
}
|
||||
|
||||
if (ImGui.Combo(friendlyName + IDText(ID), ref intVal, options, 4))
|
||||
{
|
||||
field.SetValue(config, intVal);
|
||||
|
||||
TriggerChangeEvent<int>(config, field.Name, intVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class DragDropHorizontalAttribute : ConfigAttribute
|
||||
{
|
||||
public string[] names;
|
||||
|
||||
public DragDropHorizontalAttribute(string friendlyName, params string[] names) : base(friendlyName)
|
||||
{
|
||||
this.names = names;
|
||||
}
|
||||
|
||||
public override bool DrawField(FieldInfo field, PluginConfigObject config, string? ID, bool collapsingHeader)
|
||||
{
|
||||
ImGui.Text(friendlyName);
|
||||
int[]? fieldVal = (int[]?)field.GetValue(config);
|
||||
int[] order = fieldVal ?? Array.Empty<int>();
|
||||
|
||||
for (int i = 0; i < order.Length; i++)
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGui.Button(names[order[i]], new Vector2(100, 25));
|
||||
|
||||
if (ImGui.IsItemActive())
|
||||
{
|
||||
float drag_dx = ImGui.GetMouseDragDelta(ImGuiMouseButton.Left).X;
|
||||
|
||||
if ((drag_dx > 80.0f && i < order.Length - 1))
|
||||
{
|
||||
var _curri = order[i];
|
||||
order[i] = order[i + 1];
|
||||
order[i + 1] = _curri;
|
||||
field.SetValue(config, order);
|
||||
ImGui.ResetMouseDragDelta();
|
||||
}
|
||||
else if ((drag_dx < -80.0f && i > 0))
|
||||
{
|
||||
var _curri = order[i];
|
||||
order[i] = order[i - 1];
|
||||
order[i - 1] = _curri;
|
||||
field.SetValue(config, order);
|
||||
ImGui.ResetMouseDragDelta();
|
||||
}
|
||||
|
||||
TriggerChangeEvent<int[]>(config, field.Name, order);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class FontAttribute : ConfigAttribute
|
||||
{
|
||||
public FontAttribute(string friendlyName = "Font and Size") : base(friendlyName) { }
|
||||
|
||||
public override bool DrawField(FieldInfo field, PluginConfigObject config, string? ID, bool collapsingHeader)
|
||||
{
|
||||
var fontsConfig = ConfigurationManager.Instance.GetConfigObject<FontsConfig>();
|
||||
if (fontsConfig == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string? stringVal = (string?)field.GetValue(config);
|
||||
|
||||
int index = stringVal == null || stringVal.Length == 0 || !fontsConfig.Fonts.ContainsKey(stringVal) ? -1 :
|
||||
fontsConfig.Fonts.IndexOfKey(stringVal);
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
if (fontsConfig.Fonts.ContainsKey(FontsConfig.DefaultBigFontKey))
|
||||
{
|
||||
index = fontsConfig.Fonts.IndexOfKey(FontsConfig.DefaultBigFontKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var options = fontsConfig.Fonts.Values.Select(fontData => fontData.Name + " " + fontData.Size.ToString()).ToArray();
|
||||
|
||||
if (ImGui.Combo(friendlyName + IDText(ID), ref index, options, 4))
|
||||
{
|
||||
stringVal = fontsConfig.Fonts.Keys[index];
|
||||
field.SetValue(config, stringVal);
|
||||
|
||||
TriggerChangeEvent<string>(config, field.Name, stringVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class BarTextureAttribute : ConfigAttribute
|
||||
{
|
||||
public BarTextureAttribute(string friendlyName = "Bar Texture") : base(friendlyName) { }
|
||||
|
||||
public override bool DrawField(FieldInfo field, PluginConfigObject config, string? ID, bool collapsingHeader)
|
||||
{
|
||||
if (BarTexturesManager.Instance == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
List<string> textures = BarTexturesManager.Instance.BarTextureNames.ToList();
|
||||
string? stringVal = (string?)field.GetValue(config);
|
||||
|
||||
int index = 0;
|
||||
if (stringVal != null && stringVal.Length > 0 && textures.Contains(stringVal))
|
||||
{
|
||||
index = textures.IndexOf(stringVal);
|
||||
}
|
||||
|
||||
string[] options = textures.ToArray();
|
||||
|
||||
if (ImGui.Combo(friendlyName + IDText(ID), ref index, options, 10))
|
||||
{
|
||||
stringVal = options[index];
|
||||
field.SetValue(config, stringVal);
|
||||
|
||||
TriggerChangeEvent<string>(config, field.Name, stringVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class AnchorAttribute : ComboAttribute
|
||||
{
|
||||
public AnchorAttribute(string friendlyName)
|
||||
: base(friendlyName, new string[] { "Center", "Left", "Right", "Top", "TopLeft", "TopRight", "Bottom", "BottomLeft", "BottomRight" })
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class BarTextureDrawModeAttribute : ComboAttribute
|
||||
{
|
||||
public BarTextureDrawModeAttribute(string friendlyName)
|
||||
: base(friendlyName, new string[] { "Stretch", "Repeat Horizontal", "Repeat Vertical", "Repeat" })
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class StrataLevelAttribute : ConfigAttribute
|
||||
{
|
||||
private string[] options = { "Lowest", "Low", "Mid-Low", "Mid", "Mid-High", "High", "Highest" };
|
||||
|
||||
public StrataLevelAttribute(string friendlyName) : base(friendlyName)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool DrawField(FieldInfo field, PluginConfigObject config, string? ID, bool collapsingHeader)
|
||||
{
|
||||
object? fieldVal = field.GetValue(config);
|
||||
|
||||
int intVal = 0;
|
||||
if (fieldVal != null)
|
||||
{
|
||||
intVal = (int)fieldVal;
|
||||
}
|
||||
|
||||
if (ImGui.Combo(friendlyName + IDText(ID), ref intVal, options, 4))
|
||||
{
|
||||
field.SetValue(config, (StrataLevel?)intVal);
|
||||
|
||||
TriggerChangeEvent<int>(config, field.Name, intVal);
|
||||
ConfigurationManager.Instance?.OnStrataLevelChanged(config);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region field ordering attributes
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class OrderAttribute : Attribute
|
||||
{
|
||||
public int pos;
|
||||
public string? collapseWith = "Enabled";
|
||||
|
||||
public OrderAttribute(int pos)
|
||||
{
|
||||
this.pos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class NestedConfigAttribute : OrderAttribute
|
||||
{
|
||||
public string friendlyName;
|
||||
public bool separator = false;
|
||||
public bool spacing = true;
|
||||
public bool nest = true;
|
||||
public bool collapsingHeader = true;
|
||||
|
||||
public NestedConfigAttribute(string friendlyName, int pos) : base(pos)
|
||||
{
|
||||
this.friendlyName = friendlyName;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user