|
@@ -6,40 +6,54 @@ using Terminal.Gui;
|
|
|
|
|
|
namespace UICatalog {
|
|
|
/// <summary>
|
|
|
- /// Base class for each demo/scenario. To define a new scenario simply
|
|
|
+ /// Base class for each demo/scenario. To define a new <see cref="Scenario"/> simply
|
|
|
///
|
|
|
- /// 1) declare a class derived from Scenario,
|
|
|
- /// 2) Set Name and Description as appropriate using [ScenarioMetadata] attribute
|
|
|
- /// 3) Set one or more categories with the [ScenarioCategory] attribute
|
|
|
+ /// 1) declare a class derived from <see cref="Scenario"/>,
|
|
|
+ /// 2) Set Name and Description as appropriate using [<see cref="ScenarioMetadata"/>] attribute
|
|
|
+ /// 3) Set one or more categories with the [<see cref="ScenarioCatagory"/>] attribute
|
|
|
/// 4) Implement Setup.
|
|
|
- /// 5) Optionally, implement Run.
|
|
|
+ /// 5) Optionally, implement <see cref="Init"/> and/or <see cref="Run"/>.
|
|
|
///
|
|
|
- /// The Main program uses reflection to find all scenarios and adds them to the
|
|
|
- /// ListViews. Press ENTER to run the selected scenario. Press CTRL-Q to exit it.
|
|
|
+ /// This program uses reflection to find all scenarios and adds them to the
|
|
|
+ /// ListViews. Press ENTER to run the selected <see cref="Scenario"/>. Press CTRL-Q to exit it.
|
|
|
/// </summary>
|
|
|
public class Scenario : IDisposable {
|
|
|
private bool _disposedValue;
|
|
|
|
|
|
/// <summary>
|
|
|
- /// The Top level for the Scenario. This should be set to `Application.Top` in most cases.
|
|
|
+ /// The <see cref="Toplevel"/> for the <see cref="Scenario"/>. This should be set to <see cref="Application.Top"/> in most cases.
|
|
|
/// </summary>
|
|
|
public Toplevel Top { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
- /// The Window for the Scenario. This should be set within the `Application.Top` in most cases.
|
|
|
+ /// The <see cref="Window"/> for the <see cref="Scenario"/>. This should be set within <see cref="Application.Top"/>` in most cases.
|
|
|
/// </summary>
|
|
|
public Window Win { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Helper that provides the default Window implementation with a frame and
|
|
|
- /// label showing the name of the Scenario and logic to exit back to
|
|
|
- /// the Scenario picker UI.
|
|
|
+ /// Helper that provides the default <see cref="Window"/> implementation with a frame and
|
|
|
+ /// label showing the name of the <see cref="Scenario"/> and logic to exit back to
|
|
|
+ /// the <see cref="Scenario"/> picker UI.
|
|
|
/// Override Init to provide any `Toplevel` behavior needed.
|
|
|
/// </summary>
|
|
|
/// <param name="top"></param>
|
|
|
+ /// <remarks>
|
|
|
+ /// <para>
|
|
|
+ /// Thg base implementation calls <see cref="Application.Init"/>, sets <see cref="Top"/> to the passed in <see cref="Toplevel"/>, creates a <see cref="Window"/> for <see cref="Win"/> and adds it to <see cref="Top"/>.
|
|
|
+ /// </para>
|
|
|
+ /// <para>
|
|
|
+ /// Overrides that do not call the base.<see cref="Run"/>, must call <see cref="Application.Init "/> before creating any views or calling other Terminal.Gui APIs.
|
|
|
+ /// </para>
|
|
|
+ /// </remarks>
|
|
|
public virtual void Init(Toplevel top)
|
|
|
{
|
|
|
+ Application.Init ();
|
|
|
+
|
|
|
Top = top;
|
|
|
+ if (Top == null) {
|
|
|
+ Top = Application.Top;
|
|
|
+ }
|
|
|
+
|
|
|
Win = new Window ($"CTRL-Q to Close - Scenario: {GetName ()}") {
|
|
|
X = 0,
|
|
|
Y = 0,
|
|
@@ -49,15 +63,18 @@ namespace UICatalog {
|
|
|
Top.Add (Win);
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// Defines the metadata (Name and Description) for a <see cref="Scenario"/>
|
|
|
+ /// </summary>
|
|
|
[System.AttributeUsage (System.AttributeTargets.Class)]
|
|
|
public class ScenarioMetadata : System.Attribute {
|
|
|
/// <summary>
|
|
|
- /// Scenario Name
|
|
|
+ /// <see cref="Scenario"/> Name
|
|
|
/// </summary>
|
|
|
public string Name { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Scenario Description
|
|
|
+ /// <see cref="Scenario"/> Description
|
|
|
/// </summary>
|
|
|
public string Description { get; set; }
|
|
|
|
|
@@ -68,14 +85,14 @@ namespace UICatalog {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Static helper function to get the Scenario Name given a Type
|
|
|
+ /// Static helper function to get the <see cref="Scenario"/> Name given a Type
|
|
|
/// </summary>
|
|
|
/// <param name="t"></param>
|
|
|
/// <returns></returns>
|
|
|
public static string GetName (Type t) => ((ScenarioMetadata)System.Attribute.GetCustomAttributes (t) [0]).Name;
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Static helper function to get the Scenario Description given a Type
|
|
|
+ /// Static helper function to get the <see cref="Scenario"/> Description given a Type
|
|
|
/// </summary>
|
|
|
/// <param name="t"></param>
|
|
|
/// <returns></returns>
|
|
@@ -83,17 +100,20 @@ namespace UICatalog {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Helper to get the Scenario Name
|
|
|
+ /// Helper to get the <see cref="Scenario"/> Name (defined in <see cref="ScenarioMetadata"/>)
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public string GetName () => ScenarioMetadata.GetName (this.GetType ());
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Helper to get the Scenario Description
|
|
|
+ /// Helper to get the <see cref="Scenario"/> Description (defined in <see cref="ScenarioMetadata"/>)
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public string GetDescription () => ScenarioMetadata.GetDescription (this.GetType ());
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// Defines the category names used to catagorize a <see cref="Scenario"/>
|
|
|
+ /// </summary>
|
|
|
[System.AttributeUsage (System.AttributeTargets.Class, AllowMultiple = true)]
|
|
|
public class ScenarioCategory : System.Attribute {
|
|
|
/// <summary>
|
|
@@ -104,17 +124,17 @@ namespace UICatalog {
|
|
|
public ScenarioCategory (string Name) => this.Name = Name;
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Static helper function to get the Scenario Name given a Type
|
|
|
+ /// Static helper function to get the <see cref="Scenario"/> Name given a Type
|
|
|
/// </summary>
|
|
|
/// <param name="t"></param>
|
|
|
- /// <returns></returns>
|
|
|
+ /// <returns>Name of the catagory</returns>
|
|
|
public static string GetName (Type t) => ((ScenarioCategory)System.Attribute.GetCustomAttributes (t) [0]).Name;
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Static helper function to get the Scenario Categories given a Type
|
|
|
+ /// Static helper function to get the <see cref="Scenario"/> Categories given a Type
|
|
|
/// </summary>
|
|
|
/// <param name="t"></param>
|
|
|
- /// <returns></returns>
|
|
|
+ /// <returns>list of catagory names</returns>
|
|
|
public static List<string> GetCategories (Type t) => System.Attribute.GetCustomAttributes (t)
|
|
|
.ToList ()
|
|
|
.Where (a => a is ScenarioCategory)
|
|
@@ -123,30 +143,40 @@ namespace UICatalog {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Helper function to get the Categories of a Scenario
|
|
|
+ /// Helper function to get the list of categories a <see cref="Scenario"/> belongs to (defined in <see cref="ScenarioCategory"/>)
|
|
|
/// </summary>
|
|
|
- /// <returns></returns>
|
|
|
+ /// <returns>list of catagory names</returns>
|
|
|
public List<string> GetCategories () => ScenarioCategory.GetCategories (this.GetType ());
|
|
|
|
|
|
+ /// <inheritdoc cref="ToString"/>
|
|
|
public override string ToString () => $"{GetName (),-30}{GetDescription ()}";
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Override this to implement the Scenario setup logic (create controls, etc...).
|
|
|
+ /// Override this to implement the <see cref="Scenario"/> setup logic (create controls, etc...).
|
|
|
/// </summary>
|
|
|
+ /// <remarks>This is typically the best place to put scenario logic code.</remarks>
|
|
|
public virtual void Setup ()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Runs the scenario. Override to start the scenario using a Top level different than `Top`.
|
|
|
+ /// Runs the <see cref="Scenario"/>. Override to start the <see cref="Scenario"/> using a <see cref="Toplevel"/> different than `Top`.
|
|
|
+ ///
|
|
|
/// </summary>
|
|
|
+ /// <remarks>
|
|
|
+ /// Overrides that do not call the base.<see cref="Run"/>, must call <see cref="Application.Shutdown"/> before returning.
|
|
|
+ /// </remarks>
|
|
|
public virtual void Run ()
|
|
|
{
|
|
|
Application.Run (Top);
|
|
|
+
|
|
|
+ // Every call to Application.Init must be bound by a call to Shutdown
|
|
|
+ // or Init doesn't do anything
|
|
|
+ Application.Shutdown ();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Stops the scenario. Override to implement shutdown behavior for the Scenario.
|
|
|
+ /// Stops the scenario. Override to change shutdown behavior for the <see cref="Scenario"/>.
|
|
|
/// </summary>
|
|
|
public virtual void RequestStop ()
|
|
|
{
|
|
@@ -154,13 +184,13 @@ namespace UICatalog {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Returns a list of all Categories set by all of the scenarios defined in the project.
|
|
|
+ /// Returns a list of all Categories set by all of the <see cref="Scenario"/>s defined in the project.
|
|
|
/// </summary>
|
|
|
internal static List<string> GetAllCategories ()
|
|
|
{
|
|
|
List<string> categories = new List<string> () { "All" };
|
|
|
foreach (Type type in typeof (Scenario).Assembly.GetTypes ()
|
|
|
- .Where (myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf (typeof (Scenario)))) {
|
|
|
+ .Where (myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf (typeof (Scenario)))) {
|
|
|
List<System.Attribute> attrs = System.Attribute.GetCustomAttributes (type).ToList ();
|
|
|
categories = categories.Union (attrs.Where (a => a is ScenarioCategory).Select (a => ((ScenarioCategory)a).Name)).ToList ();
|
|
|
}
|
|
@@ -168,14 +198,14 @@ namespace UICatalog {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Returns an instance of each Scenario defined in the project.
|
|
|
+ /// Returns an instance of each <see cref="Scenario"/> defined in the project.
|
|
|
/// https://stackoverflow.com/questions/5411694/get-all-inherited-classes-of-an-abstract-class
|
|
|
/// </summary>
|
|
|
internal static List<Type> GetDerivedClassesCollection ()
|
|
|
{
|
|
|
List<Type> objects = new List<Type> ();
|
|
|
foreach (Type type in typeof (Scenario).Assembly.GetTypes ()
|
|
|
- .Where (myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf (typeof (Scenario)))) {
|
|
|
+ .Where (myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf (typeof (Scenario)))) {
|
|
|
objects.Add (type);
|
|
|
}
|
|
|
return objects;
|