123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- using NStack;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using Terminal.Gui;
- namespace UICatalog {
- /// <summary>
- /// Base class for each demo/scenario. To define a new sceanrio 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
- /// 4) Implement Setup.
- /// 5) Optionally, implement Run.
- ///
- /// The Main program uses reflection to find all sceanarios and adds them to the
- /// ListViews. Press ENTER to run the selected sceanrio. Press CTRL-Q to exit it.
- /// </summary>
- public class Scenario {
- /// <summary>
- /// The Top level for the Scenario. This should be set to `Application.Top` in most cases.
- /// </summary>
- public Toplevel Top { get; set; }
- /// <summary>
- /// </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.
- /// Override Init to provide any `Toplevel` behavior needed.
- /// </summary>
- /// <param name="top"></param>
- public virtual void Init(Toplevel top)
- {
- Top = top;
- Win = new Window ($"CTRL-Q to Close - Scenario: {GetName ()}") {
- X = 0,
- Y = 0,
- Width = Dim.Fill (),
- Height = Dim.Fill ()
- };
- Top.Add (Win);
- }
- [System.AttributeUsage (System.AttributeTargets.Class)]
- public class ScenarioMetadata : System.Attribute {
- /// <summary>
- /// Scenario Name
- /// </summary>
- public string Name { get; set; }
- /// <summary>
- /// Scenario Description
- /// </summary>
- public string Description { get; set; }
- public ScenarioMetadata (string Name, string Description)
- {
- this.Name = Name;
- this.Description = Description;
- }
- /// <summary>
- /// Static helper function to get the 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
- /// </summary>
- /// <param name="t"></param>
- /// <returns></returns>
- public static string GetDescription (Type t) => ((ScenarioMetadata)System.Attribute.GetCustomAttributes (t) [0]).Description;
- }
- /// <summary>
- /// Helper to get the Scenario Name
- /// </summary>
- /// <returns></returns>
- public string GetName () => ScenarioMetadata.GetName (this.GetType ());
- /// <summary>
- /// Helper to get the Scenario Descripiton
- /// </summary>
- /// <returns></returns>
- public string GetDescription () => ScenarioMetadata.GetDescription (this.GetType ());
- [System.AttributeUsage (System.AttributeTargets.Class, AllowMultiple = true)]
- public class ScenarioCategory : System.Attribute {
- /// <summary>
- /// Category Name
- /// </summary>
- public string Name { get; set; }
- public ScenarioCategory (string Name) => this.Name = Name;
- /// <summary>
- /// Static helper function to get the Scenario Name given a Type
- /// </summary>
- /// <param name="t"></param>
- /// <returns></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
- /// </summary>
- /// <param name="t"></param>
- /// <returns></returns>
- public static List<string> GetCategories (Type t) => System.Attribute.GetCustomAttributes (t)
- .ToList ()
- .Where (a => a is ScenarioCategory)
- .Select (a => ((ScenarioCategory)a).Name)
- .ToList ();
- }
- /// <summary>
- /// Helper function to get the Categories of a Scenario
- /// </summary>
- /// <returns></returns>
- public List<string> GetCategories () => ScenarioCategory.GetCategories (this.GetType ());
- public override string ToString () => $"{GetName (),-30}{GetDescription ()}";
- /// <summary>
- /// Override this to implement the Scenario setup logic (create controls, etc...).
- /// </summary>
- public virtual void Setup ()
- {
- }
- /// <summary>
- /// Runs the scenario. Override to start the scearnio using a Top level different than `Top`.
- /// </summary>
- public virtual void Run ()
- {
- Application.Run (Top);
- }
- /// <summary>
- /// Stops the scenario. Override to implement shutdown behavior for the Scenario.
- /// </summary>
- public virtual void RequestStop ()
- {
- Application.RequestStop ();
- }
- /// <summary>
- /// Returns a list of all Categories set by all of the scenarios 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)))) {
- List<System.Attribute> attrs = System.Attribute.GetCustomAttributes (type).ToList ();
- categories = categories.Union (attrs.Where (a => a is ScenarioCategory).Select (a => ((ScenarioCategory)a).Name)).ToList ();
- }
- return categories;
- }
- /// <summary>
- /// Returns an instance of each 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)))) {
- objects.Add (type);
- }
- return objects;
- }
- }
- }
|