mirror of
https://github.com/9ParsonsB/Pulsar.git
synced 2025-07-01 08:23:42 -04:00
observatory herald (#30)
* WIP: initial commit for observatory herald * Plugin error handling refactor * make error window non-modal * tidy up plugin error handling * first pass for basic herald functionality * corrections for linux env * Use FNV hash directly instead of managing through dictionary/index file * resolve audio queuing issue, switch to personal NetCoreAudio fork * merge cleanup * add enable setting, populate defaults * framework xml doc update * Adjust settings, add style selection, replace locale with demonym in dropdown list. * Test is position is on screen before saving/loading. * use a default that's actually in the list
This commit is contained in:
@ -6,15 +6,26 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Observatory.Framework
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies text to display as the name of the setting in the UI instead of the property name.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
|
||||
public class SettingDisplayName : Attribute
|
||||
{
|
||||
private string name;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies text to display as the name of the setting in the UI instead of the property name.
|
||||
/// </summary>
|
||||
/// <param name="name">Name to display</param>
|
||||
public SettingDisplayName(string name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Accessor to get/set displayed name.
|
||||
/// </summary>
|
||||
public string DisplayName
|
||||
{
|
||||
get => name;
|
||||
@ -22,18 +33,63 @@ namespace Observatory.Framework
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the property should not be displayed to the user in the UI.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
|
||||
public class SettingIgnore : Attribute
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates numeric properly should use a slider control instead of a numeric textbox with roller.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
|
||||
public class SettingNumericUseSlider : Attribute
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Specify backing value used by Dictionary<string, object> to indicate selected option.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
|
||||
public class SettingBackingValue : Attribute
|
||||
{
|
||||
private string property;
|
||||
|
||||
/// <summary>
|
||||
/// Specify backing value used by Dictionary<string, object> to indicate selected option.
|
||||
/// </summary>
|
||||
/// <param name="property">Property name for backing value.</param>
|
||||
public SettingBackingValue(string property)
|
||||
{
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Accessor to get/set backing value property name.
|
||||
/// </summary>
|
||||
public string BackingProperty
|
||||
{
|
||||
get => property;
|
||||
set => property = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specify bounds for numeric inputs.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
|
||||
public class SettingNumericBounds : Attribute
|
||||
{
|
||||
private double minimum;
|
||||
private double maximum;
|
||||
private double increment;
|
||||
|
||||
/// <summary>
|
||||
/// Specify bounds for numeric inputs.
|
||||
/// </summary>
|
||||
/// <param name="minimum">Minimum allowed value.</param>
|
||||
/// <param name="maximum">Maximum allowed value.</param>
|
||||
/// <param name="increment">Increment between allowed values in slider/roller inputs.</param>
|
||||
public SettingNumericBounds(double minimum, double maximum, double increment = 1.0)
|
||||
{
|
||||
this.minimum = minimum;
|
||||
@ -41,16 +97,27 @@ namespace Observatory.Framework
|
||||
this.increment = increment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimum allowed value.
|
||||
/// </summary>
|
||||
public double Minimum
|
||||
{
|
||||
get => minimum;
|
||||
set => minimum = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maxunyn allowed value.
|
||||
/// </summary>
|
||||
public double Maximum
|
||||
{
|
||||
get => maximum;
|
||||
set => maximum = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increment between allowed values in slider/roller inputs.
|
||||
/// </summary>
|
||||
public double Increment
|
||||
{
|
||||
get => increment;
|
||||
|
34
ObservatoryFramework/Exceptions.cs
Normal file
34
ObservatoryFramework/Exceptions.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System;
|
||||
|
||||
namespace Observatory.Framework
|
||||
{
|
||||
/// <summary>
|
||||
/// Container for exceptions within plugins which cannot be gracefully handled in context,
|
||||
/// but benefit from having a context-specific user message.
|
||||
/// </summary>
|
||||
public class PluginException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialze new PluginException with details of the originating plugin and a specific user-facing message for display.
|
||||
/// </summary>
|
||||
/// <param name="pluginName"></param>
|
||||
/// <param name="userMessage"></param>
|
||||
/// <param name="innerException"></param>
|
||||
public PluginException(string pluginName, string userMessage, Exception innerException) : base(innerException.Message, innerException)
|
||||
{
|
||||
PluginName = pluginName;
|
||||
UserMessage = userMessage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Name of plugin from which the exception was thrown.
|
||||
/// </summary>
|
||||
public string PluginName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Message to be displayed to user.
|
||||
/// </summary>
|
||||
public string UserMessage { get; }
|
||||
|
||||
}
|
||||
}
|
@ -301,7 +301,8 @@ namespace Observatory.Framework.Files.ParameterTypes
|
||||
ActiveFighter,
|
||||
JumpImminent,
|
||||
RestrictedAccess,
|
||||
NoReason
|
||||
NoReason,
|
||||
DockOffline
|
||||
}
|
||||
|
||||
public enum ScanOrganicType
|
||||
|
@ -3,13 +3,35 @@ using System.Collections.Immutable;
|
||||
|
||||
namespace Observatory.Framework.Files
|
||||
{
|
||||
/// <summary>
|
||||
/// Elite Dangerous shipyard.json file.
|
||||
/// </summary>
|
||||
public class ShipyardFile : Journal.JournalBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique ID of market.
|
||||
/// </summary>
|
||||
public long MarketID { get; init; }
|
||||
/// <summary>
|
||||
/// Name of station where shipyard is located.
|
||||
/// </summary>
|
||||
public string StationName { get; init; }
|
||||
/// <summary>
|
||||
/// Starsystem where shipyard is located.
|
||||
/// </summary>
|
||||
public string StarSystem { get; init; }
|
||||
/// <summary>
|
||||
/// Whether player has access to Horizons content.
|
||||
/// </summary>
|
||||
public bool Horizons { get; init; }
|
||||
/// <summary>
|
||||
/// <para>Whether player has access to the Cobra MkIV.</para>
|
||||
/// <para>Will never be set to true for CMDR Nuse.</para>
|
||||
/// </summary>
|
||||
public bool AllowCobraMkIV { get; init; }
|
||||
/// <summary>
|
||||
/// List of all ships and prices for them at the current shipyard.
|
||||
/// </summary>
|
||||
public ImmutableList<ShipyardPrice> PriceList { get; init; }
|
||||
}
|
||||
}
|
||||
|
@ -4,30 +4,98 @@ using Observatory.Framework.Files.ParameterTypes;
|
||||
|
||||
namespace Observatory.Framework.Files
|
||||
{
|
||||
/// <summary>
|
||||
/// Elite Dangerous status.json file.
|
||||
/// </summary>
|
||||
public class Status : Journal.JournalBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Set of flags representing current player state.
|
||||
/// </summary>
|
||||
public StatusFlags Flags { get; init; }
|
||||
/// <summary>
|
||||
/// Additional set of flags representing current player state.
|
||||
/// Added in later versions of Elite Dangerous.
|
||||
/// </summary>
|
||||
public StatusFlags2 Flags2 { get; init; }
|
||||
/// <summary>
|
||||
/// Current allocation of power distribution (pips) between SYS, ENG, and WEP, in "half pip" increments.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(PipConverter))]
|
||||
public (int Sys, int Eng, int Wep) Pips { get; init; }
|
||||
/// <summary>
|
||||
/// Currently selected fire group.
|
||||
/// </summary>
|
||||
public int Firegroup { get; init; }
|
||||
/// <summary>
|
||||
/// UI component currently focused by the player.
|
||||
/// </summary>
|
||||
public FocusStatus GuiFocus { get; init; }
|
||||
/// <summary>
|
||||
/// Fuel remaining in the current ship.
|
||||
/// </summary>
|
||||
public FuelType Fuel { get; init; }
|
||||
/// <summary>
|
||||
/// Amount of cargo currently carried.
|
||||
/// </summary>
|
||||
public float Cargo { get; init; }
|
||||
/// <summary>
|
||||
/// Legal status in the current jurisdiction.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public LegalStatus LegalState { get; init; }
|
||||
/// <summary>
|
||||
/// <para>Current altitude.</para>
|
||||
/// <para>Check if RadialAltitude is set in StatusFlags to determine if altitude is based on planetary radius (set) or raycast to ground (unset).</para>
|
||||
/// </summary>
|
||||
public int Altitude { get; init; }
|
||||
/// <summary>
|
||||
/// Latitude of current surface location.
|
||||
/// </summary>
|
||||
public double Latitude { get; init; }
|
||||
/// <summary>
|
||||
/// Longitude of current surface location.
|
||||
/// </summary>
|
||||
public double Longitude { get; init; }
|
||||
/// <summary>
|
||||
/// Current heading for surface direction.
|
||||
/// </summary>
|
||||
public int Heading { get; init; }
|
||||
/// <summary>
|
||||
/// Body name of current location.
|
||||
/// </summary>
|
||||
public string BodyName { get; init; }
|
||||
/// <summary>
|
||||
/// Radius of current planet.
|
||||
/// </summary>
|
||||
public double PlanetRadius { get; init; }
|
||||
/// <summary>
|
||||
/// Oxygen remaining on foot, range from 0.0 - 1.0.
|
||||
/// </summary>
|
||||
public float Oxygen { get; init; }
|
||||
/// <summary>
|
||||
/// Health remaining on foot, range from 0.0 - 1.0.
|
||||
/// </summary>
|
||||
public float Health { get; init; }
|
||||
/// <summary>
|
||||
/// Current environmental temperature in K while on foot.
|
||||
/// </summary>
|
||||
public float Temperature { get; init; }
|
||||
/// <summary>
|
||||
/// Name of currently selected personal weapon.
|
||||
/// </summary>
|
||||
public string SelectedWeapon { get; init; }
|
||||
/// <summary>
|
||||
/// Current strength of gravity while on foot, in g.
|
||||
/// </summary>
|
||||
public float Gravity { get; init; }
|
||||
/// <summary>
|
||||
/// Current credit balance of player.
|
||||
/// </summary>
|
||||
public long Balance { get; init; }
|
||||
/// <summary>
|
||||
/// Currently set destination.
|
||||
/// </summary>
|
||||
public Destination Destination { get; init; }
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ namespace Observatory.Framework.Interfaces
|
||||
public PluginUI PluginUI { get; }
|
||||
|
||||
/// <summary>
|
||||
/// <para>Accessors for plugin settings object. Should be initialized in a default state.</para>
|
||||
/// <para>Accessors for plugin settings object. Should be initialized with a default state during the plugin constructor.</para>
|
||||
/// <para>Saving and loading of settings is handled by Observatory Core, and any previously saved settings will be set after plugin instantiation, but before Load() is called.</para>
|
||||
/// <para>A plugin's settings class is expected to consist of properties with public getters and setters. The settings UI will be automatically generated based on each property type.<br/>
|
||||
/// The [SettingDisplayName(string name)] attribute can be used to specify a display name, otherwise the name of the property will be used.<br/>
|
||||
|
@ -4,6 +4,76 @@
|
||||
<name>ObservatoryFramework</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:Observatory.Framework.SettingDisplayName">
|
||||
<summary>
|
||||
Specifies text to display as the name of the setting in the UI instead of the property name.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Observatory.Framework.SettingDisplayName.#ctor(System.String)">
|
||||
<summary>
|
||||
Specifies text to display as the name of the setting in the UI instead of the property name.
|
||||
</summary>
|
||||
<param name="name">Name to display</param>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.SettingDisplayName.DisplayName">
|
||||
<summary>
|
||||
Accessor to get/set displayed name.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Observatory.Framework.SettingIgnore">
|
||||
<summary>
|
||||
Indicates that the property should not be displayed to the user in the UI.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Observatory.Framework.SettingNumericUseSlider">
|
||||
<summary>
|
||||
Indicates numeric properly should use a slider control instead of a numeric textbox with roller.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Observatory.Framework.SettingBackingValue">
|
||||
<summary>
|
||||
Specify backing value used by Dictionary<string, object> to indicate selected option.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Observatory.Framework.SettingBackingValue.#ctor(System.String)">
|
||||
<summary>
|
||||
Specify backing value used by Dictionary<string, object> to indicate selected option.
|
||||
</summary>
|
||||
<param name="property">Property name for backing value.</param>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.SettingBackingValue.BackingProperty">
|
||||
<summary>
|
||||
Accessor to get/set backing value property name.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Observatory.Framework.SettingNumericBounds">
|
||||
<summary>
|
||||
Specify bounds for numeric inputs.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Observatory.Framework.SettingNumericBounds.#ctor(System.Double,System.Double,System.Double)">
|
||||
<summary>
|
||||
Specify bounds for numeric inputs.
|
||||
</summary>
|
||||
<param name="minimum">Minimum allowed value.</param>
|
||||
<param name="maximum">Maximum allowed value.</param>
|
||||
<param name="increment">Increment between allowed values in slider/roller inputs.</param>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.SettingNumericBounds.Minimum">
|
||||
<summary>
|
||||
Minimum allowed value.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.SettingNumericBounds.Maximum">
|
||||
<summary>
|
||||
Maxunyn allowed value.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.SettingNumericBounds.Increment">
|
||||
<summary>
|
||||
Increment between allowed values in slider/roller inputs.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Observatory.Framework.JournalEventArgs">
|
||||
<summary>
|
||||
Provides data for Elite Dangerous journal events.
|
||||
@ -63,6 +133,30 @@
|
||||
Specify window Y position as a percentage from upper left corner (overrides Core setting). Default -1.0 (use Core setting).
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Observatory.Framework.PluginException">
|
||||
<summary>
|
||||
Container for exceptions within plugins which cannot be gracefully handled in context,
|
||||
but benefit from having a context-specific user message.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Observatory.Framework.PluginException.#ctor(System.String,System.String,System.Exception)">
|
||||
<summary>
|
||||
Initialze new PluginException with details of the originating plugin and a specific user-facing message for display.
|
||||
</summary>
|
||||
<param name="pluginName"></param>
|
||||
<param name="userMessage"></param>
|
||||
<param name="innerException"></param>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.PluginException.PluginName">
|
||||
<summary>
|
||||
Name of plugin from which the exception was thrown.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.PluginException.UserMessage">
|
||||
<summary>
|
||||
Message to be displayed to user.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Journal.SAAScanComplete.Discoverers">
|
||||
<summary>
|
||||
This property is indicated with strikethrough in Frontier's documentation and may be deprecated.
|
||||
@ -320,6 +414,154 @@
|
||||
Altitude above average radius (sea level) when set. Altitude raycast to ground when unset.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Observatory.Framework.Files.ShipyardFile">
|
||||
<summary>
|
||||
Elite Dangerous shipyard.json file.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.ShipyardFile.MarketID">
|
||||
<summary>
|
||||
Unique ID of market.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.ShipyardFile.StationName">
|
||||
<summary>
|
||||
Name of station where shipyard is located.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.ShipyardFile.StarSystem">
|
||||
<summary>
|
||||
Starsystem where shipyard is located.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.ShipyardFile.Horizons">
|
||||
<summary>
|
||||
Whether player has access to Horizons content.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.ShipyardFile.AllowCobraMkIV">
|
||||
<summary>
|
||||
<para>Whether player has access to the Cobra MkIV.</para>
|
||||
<para>Will never be set to true for CMDR Nuse.</para>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.ShipyardFile.PriceList">
|
||||
<summary>
|
||||
List of all ships and prices for them at the current shipyard.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Observatory.Framework.Files.Status">
|
||||
<summary>
|
||||
Elite Dangerous status.json file.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Flags">
|
||||
<summary>
|
||||
Set of flags representing current player state.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Flags2">
|
||||
<summary>
|
||||
Additional set of flags representing current player state.
|
||||
Added in later versions of Elite Dangerous.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Pips">
|
||||
<summary>
|
||||
Current allocation of power distribution (pips) between SYS, ENG, and WEP, in "half pip" increments.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Firegroup">
|
||||
<summary>
|
||||
Currently selected fire group.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.GuiFocus">
|
||||
<summary>
|
||||
UI component currently focused by the player.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Fuel">
|
||||
<summary>
|
||||
Fuel remaining in the current ship.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Cargo">
|
||||
<summary>
|
||||
Amount of cargo currently carried.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.LegalState">
|
||||
<summary>
|
||||
Legal status in the current jurisdiction.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Altitude">
|
||||
<summary>
|
||||
<para>Current altitude.</para>
|
||||
<para>Check if RadialAltitude is set in StatusFlags to determine if altitude is based on planetary radius (set) or raycast to ground (unset).</para>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Latitude">
|
||||
<summary>
|
||||
Latitude of current surface location.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Longitude">
|
||||
<summary>
|
||||
Longitude of current surface location.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Heading">
|
||||
<summary>
|
||||
Current heading for surface direction.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.BodyName">
|
||||
<summary>
|
||||
Body name of current location.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.PlanetRadius">
|
||||
<summary>
|
||||
Radius of current planet.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Oxygen">
|
||||
<summary>
|
||||
Oxygen remaining on foot, range from 0.0 - 1.0.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Health">
|
||||
<summary>
|
||||
Health remaining on foot, range from 0.0 - 1.0.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Temperature">
|
||||
<summary>
|
||||
Current environmental temperature in K while on foot.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.SelectedWeapon">
|
||||
<summary>
|
||||
Name of currently selected personal weapon.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Gravity">
|
||||
<summary>
|
||||
Current strength of gravity while on foot, in g.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Balance">
|
||||
<summary>
|
||||
Current credit balance of player.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Files.Status.Destination">
|
||||
<summary>
|
||||
Currently set destination.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Observatory.Framework.Interfaces.IObservatoryPlugin">
|
||||
<summary>
|
||||
<para>Base plugin interface containing methods common to both notifiers and workers.</para>
|
||||
@ -357,7 +599,7 @@
|
||||
</member>
|
||||
<member name="P:Observatory.Framework.Interfaces.IObservatoryPlugin.Settings">
|
||||
<summary>
|
||||
<para>Accessors for plugin settings object. Should be initialized in a default state.</para>
|
||||
<para>Accessors for plugin settings object. Should be initialized with a default state during the plugin constructor.</para>
|
||||
<para>Saving and loading of settings is handled by Observatory Core, and any previously saved settings will be set after plugin instantiation, but before Load() is called.</para>
|
||||
<para>A plugin's settings class is expected to consist of properties with public getters and setters. The settings UI will be automatically generated based on each property type.<br/>
|
||||
The [SettingDisplayName(string name)] attribute can be used to specify a display name, otherwise the name of the property will be used.<br/>
|
||||
|
Reference in New Issue
Block a user