2
0
Эх сурвалжийг харах

Merge branch 'uicatalog_tweaks' into docs

Charlie Kindel 5 жил өмнө
parent
commit
b2fc685622

+ 20 - 20
UICatalog/Program.cs

@@ -12,7 +12,7 @@ namespace UICatalog {
 	/// Main program for the Terminal.gui UI Catalog app. This app provides a chooser that allows
 	/// for a calalog of UI demos, examples, and tests.
 	/// </summary>
-	class Program {
+	internal class Program {
 		private static Toplevel _top;
 		private static MenuBar _menu;
 		private static int _nameColumnWidth;
@@ -24,34 +24,33 @@ namespace UICatalog {
 		private static ListView _scenarioListView;
 		private static StatusBar _statusBar;
 
-		private static Scenario _runningScenario = null;
+		private static Scenario _selectedScenario = null;
 
 		static void Main (string [] args)
 		{
 			if (Debugger.IsAttached)
 				CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.GetCultureInfo ("en-US");
 
-			_scenarios = Scenario.GetDerivedClassesCollection ().ToList ();
+			_scenarios = Scenario.GetDerivedClassesCollection ().OrderBy (t => Scenario.ScenarioMetadata.GetName (t)).ToList();
 
 			if (args.Length > 0) {
 				var item = _scenarios.FindIndex (t => Scenario.ScenarioMetadata.GetName (t).Equals (args [0], StringComparison.OrdinalIgnoreCase));
-				_runningScenario = (Scenario)Activator.CreateInstance (_scenarios [item]);
-				Application.Init ();
-				_runningScenario.Init (Application.Top);
-				_runningScenario.Setup ();
-				_runningScenario.Run ();
-				_runningScenario = null;
+				_selectedScenario = (Scenario)Activator.CreateInstance (_scenarios [item]);
+				_selectedScenario.Init (Application.Top);
+				_selectedScenario.Setup ();
+				_selectedScenario.Run ();
+				_selectedScenario = null;
 				return;
 			}
 
 			Scenario scenario = GetScenarioToRun ();
 			while (scenario != null) {
-				Application.Init ();
 				scenario.Init (Application.Top);
 				scenario.Setup ();
 				scenario.Run ();
 				scenario = GetScenarioToRun ();
 			}
+
 		}
 
 		/// <summary>
@@ -75,7 +74,7 @@ namespace UICatalog {
 			};
 
 
-			_categories = Scenario.GetAllCategories ();
+			_categories = Scenario.GetAllCategories ().OrderBy(c => c).ToList();
 			_categoryListView = new ListView (_categories) {
 				X = 1,
 				Y = 0,
@@ -125,12 +124,12 @@ namespace UICatalog {
 			_statusBar = new StatusBar (new StatusItem [] {
 				//new StatusItem(Key.F1, "~F1~ Help", () => Help()),
 				new StatusItem(Key.ControlQ, "~CTRL-Q~ Quit", () => {
-					if (_runningScenario is null){
+					if (_selectedScenario is null){
 						// This causes GetScenarioToRun to return null
-						_runningScenario = null;
+						_selectedScenario = null;
 						Application.RequestStop();
 					} else {
-						_runningScenario.RequestStop();
+						_selectedScenario.RequestStop();
 					}
 				}),
 			});
@@ -163,15 +162,16 @@ namespace UICatalog {
 				Application.Iteration += Application_Iteration;
 #else
 			_top.Ready += (o, a) => {
-				if (_runningScenario != null) {
+				if (_selectedScenario != null) {
 					_top.SetFocus (_rightPane);
-					_runningScenario = null;
+					_selectedScenario = null;
 				}
 			};
 #endif
 			
 			Application.Run (_top);
-			return _runningScenario;
+			Application.Shutdown ();
+			return _selectedScenario;
 		}
 
 #if false
@@ -183,9 +183,9 @@ namespace UICatalog {
 #endif
 		private static void _scenarioListView_OpenSelectedItem (object sender, EventArgs e)
 		{
-			if (_runningScenario is null) {
+			if (_selectedScenario is null) {
 				var source = _scenarioListView.Source as ScenarioListDataSource;
-				_runningScenario = (Scenario)Activator.CreateInstance (source.Scenarios [_scenarioListView.SelectedItem]);
+				_selectedScenario = (Scenario)Activator.CreateInstance (source.Scenarios [_scenarioListView.SelectedItem]);
 				Application.RequestStop ();
 			}
 		}
@@ -246,7 +246,7 @@ namespace UICatalog {
 		/// <param name="ke"></param>
 		private static void KeyUpHandler (object sender, View.KeyEventEventArgs a)
 		{
-			if (_runningScenario != null) {
+			if (_selectedScenario != null) {
 				//switch (ke.Key) {
 				//case Key.Esc:
 				//	//_runningScenario.RequestStop ();

+ 61 - 31
UICatalog/Scenario.cs

@@ -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;

+ 2 - 2
UICatalog/Scenarios/Editor.cs

@@ -14,7 +14,7 @@ namespace UICatalog {
 
 		public override void Init (Toplevel top)
 		{
-			Top = top;
+			base.Init (top);
 		}
 
 		public override void Setup ()
@@ -144,7 +144,7 @@ namespace UICatalog {
 
 		public override void Run ()
 		{
-			Application.Run (Top);
+			base.Run ();
 		}
 	}
 }

+ 0 - 11
UICatalog/Scenarios/HexEditor.cs

@@ -12,12 +12,6 @@ namespace UICatalog {
 		private HexView _hexView;
 		private bool _saved = true;
 
-
-		public override void Init (Toplevel top)
-		{
-			Top = top;
-		}
-
 		public override void Setup ()
 		{
 			var menu = new MenuBar (new MenuBarItem [] {
@@ -145,10 +139,5 @@ namespace UICatalog {
 			sw.Write (sb.ToString ());
 			sw.Close ();
 		}
-
-		public override void Run ()
-		{
-			Application.Run (Top);
-		}
 	}
 }

+ 1 - 0
UICatalog/Scenarios/Keys.cs

@@ -50,6 +50,7 @@ namespace UICatalog {
 
 		public override void Init (Toplevel top)
 		{
+			Application.Init ();
 			Top = top;
 
 			Win = new TestWindow ($"CTRL-Q to Close - Scenario: {GetName ()}") {

+ 1 - 1
UICatalog/Scenarios/ListsAndCombos.cs

@@ -6,7 +6,7 @@ using Terminal.Gui;
 using NStack;
 
 namespace UICatalog.Scenarios {
-	[ScenarioMetadata (Name: "Lists", Description: "Demonstrates list selections")]
+	[ScenarioMetadata (Name: "ListView & ComboBox", Description: "Demonstrates a ListView populating a ComboBox that acts as a filter.")]
 	[ScenarioCategory ("Controls")]
 	class ListsAndCombos : Scenario {
 

+ 0 - 5
UICatalog/Scenarios/MessageBoxes.cs

@@ -33,10 +33,5 @@ namespace UICatalog {
 			Top.Add (Win);
 
 		}
-
-		public override void Run ()
-		{
-			Application.Run (Top);
-		}
 	}
 }

+ 15 - 10
UICatalog/Scenarios/Progress.cs

@@ -6,8 +6,9 @@ namespace UICatalog {
 	// 
 	// This would be a great scenario to show of threading (Issue #471)
 	//
-	[ScenarioMetadata (Name: "Progress", Description: "Shows off ProgressBar.")]
+	[ScenarioMetadata (Name: "Progress", Description: "Shows off ProgressBar and Threading")]
 	[ScenarioCategory ("Controls")]
+	[ScenarioCategory ("Threading")]
 	class Progress : Scenario {
 
 		private ProgressBar _activityProgressBar;
@@ -19,23 +20,28 @@ namespace UICatalog {
 		{
 			var pulseButton = new Button ("Pulse") {
 				X = Pos.Center (),
-				Y = Pos.Center () - 5,
+				Y = Pos.Center () - 3,
 				Clicked = () => Pulse ()
 			};
 
-			Win.Add (new Button ("Start Timer") {
-				X = Pos.Left(pulseButton) - 20,
+			var startButton = new Button ("Start Timer") {
 				Y = Pos.Y(pulseButton),
 				Clicked = () => Start ()
-			});
+			};
 
-			Win.Add (new Button ("Stop Timer") {
-				X = Pos.Right (pulseButton) + 20, // BUGBUG: Right is somehow adding additional width
+			var stopbutton = new Button ("Stop Timer") {
 				Y = Pos.Y (pulseButton),
 				Clicked = () => Stop()
-			});
+			};
+
+			// Center three buttons with 5 spaces between them
+			// TODO: Use Pos.Width instead of (Right-Left) when implemented (#502)
+			startButton.X = Pos.Left (pulseButton) - (Pos.Right (startButton) - Pos.Left (startButton)) - 5;
+			stopbutton.X = Pos.Right (pulseButton) + 5;
 
+			Win.Add (startButton);
 			Win.Add (pulseButton);
+			Win.Add (stopbutton);
 
 			_activityProgressBar = new ProgressBar () {
 				X = Pos.Center (),
@@ -84,9 +90,8 @@ namespace UICatalog {
 			_pulseProgressBar.Fraction = 0F;
 
 			_timer = new Timer ((o) => {
-				// BUGBUG: #409 - Invoke does not cause Wakeup as it should
 				Application.MainLoop.Invoke (() => Pulse ());
-			}, null, 0, 250);
+			}, null, 0, 20);
 		}
 
 		private void Stop ()

+ 33 - 0
UICatalog/Scenarios/SystemConsole.cs

@@ -0,0 +1,33 @@
+using Terminal.Gui;
+
+namespace UICatalog {
+	[ScenarioMetadata (Name: "System Console", Description: "Not working - #518 - Enables System Console and exercises things")]
+	[ScenarioCategory ("Bug Repro")]
+	[ScenarioCategory ("Console")]
+	class UseSystemConsole : Scenario {
+		public override void Init (Toplevel top)
+		{
+			Application.UseSystemConsole = true;
+			base.Init (top);
+		}
+
+		public override void RequestStop ()
+		{
+			base.RequestStop ();
+		}
+
+		public override void Run ()
+		{
+			base.Run ();
+		}
+
+		public override void Setup ()
+		{
+		       Win.Add (new Button ("Press me!") {
+			       X = Pos.Center (),
+			       Y = Pos.Center (),
+			       Clicked = () => MessageBox.Query (20, 7, "Hi", "Neat?", "Yes", "No")
+		       });
+		}
+	}
+}

+ 1 - 1
UICatalog/Scenarios/TopLevelNoWindowBug.cs

@@ -34,7 +34,7 @@ namespace UICatalog {
 			};
 			ntop.Add (win);
 
-			Application.Run (ntop);
+			base.Run ();
 		}
 	}
 }

+ 142 - 0
UICatalog/Scenarios/WindowExperiment.cs

@@ -0,0 +1,142 @@
+using System.Collections.Generic;
+using System.Linq;
+using Terminal.Gui;
+
+namespace UICatalog {
+	[ScenarioMetadata (Name: "Windows & FrameViews", Description: "Shows Windows, sub-Windows, FrameViews, and how TAB doesn't work right (#434, #522)")]
+	[ScenarioCategory ("Views")]
+	class WindowExperiment : Scenario {
+		public override void Init (Toplevel top)
+		{
+			Application.Init ();
+
+			Top = top;
+			if (Top == null) {
+				Top = Application.Top;
+			}
+		}
+
+		public override void RequestStop ()
+		{
+			base.RequestStop ();
+		}
+
+		public override void Run ()
+		{
+			base.Run ();
+		}
+
+		public override void Setup ()
+		{
+			int margin = 3;
+			int padding = 1;
+			int height = 10;
+			var listWin = new List<View> ();
+			Win = new Window ($"{listWin.Count} - Scenario: {GetName ()}", padding) {
+				X = margin,
+				Y = margin,
+				Width = Dim.Fill (margin),
+				Height = height,
+			};
+			Win.ColorScheme = Colors.Dialog;
+			Win.Add (new Button ("Press me!") {
+				X = Pos.Center (),
+				Y = 0,
+				ColorScheme = Colors.Error,
+				Clicked = () => MessageBox.ErrorQuery (30, 10, Win.Title.ToString (), "Neat?", "Yes", "No")
+			});
+			Top.Add (Win);
+			listWin.Add (Win);
+
+			for (var i = 0; i < 2; i++) {
+				Window win = null;
+				win = new Window ($"{listWin.Count} - Scenario: {GetName ()}", padding) {
+					X = margin,
+					Y = Pos.Bottom(listWin.Last()) + (margin/2),
+					Width = Dim.Fill (margin),
+					Height = height,
+				};
+				win.ColorScheme = Colors.Dialog;
+				win.Add (new Button ("Press me!") {
+					X = Pos.Center (),
+					Y = 0,
+					ColorScheme = Colors.Error,
+					Clicked = () => MessageBox.ErrorQuery (30, 10, win.Title.ToString (), "Neat?", "Yes", "No")
+				});
+				var subWin = new Window("Sub Window") {
+					X = Pos.Percent (0),
+					Y = Pos.AnchorEnd() - 5,
+					Width = Dim.Percent (50),
+					Height = 5,
+					ColorScheme = Colors.Base,
+				};
+				subWin.Add (new TextField (win.Title.ToString ()));
+				win.Add (subWin);
+				var frameView = new FrameView ("This is a Sub-FrameView") {
+					X = Pos.Percent(50),
+					Y = Pos.AnchorEnd () - 5,
+					Width = Dim.Percent (100),
+					Height = 5,
+					ColorScheme = Colors.Base,
+				};
+				frameView.Add (new TextField ("Edit Me"));
+				win.Add (frameView);
+
+				Top.Add (win);
+				listWin.Add (win);
+			}
+
+
+			FrameView frame = null;
+			frame = new FrameView ($"This is a FrameView") {
+				X = margin,
+				Y = Pos.Bottom (listWin.Last ()) + (margin / 2),
+				Width = Dim.Fill (margin),
+				Height = height,
+			};
+			frame.ColorScheme = Colors.Dialog;
+			frame.Add (new Button ("Press me!") {
+				X = Pos.Center (),
+				Y = 0,
+				ColorScheme = Colors.Error,
+				Clicked = () => MessageBox.ErrorQuery (30, 10, frame.Title.ToString (), "Neat?", "Yes", "No")
+			});
+			var subWinFV = new Window ("this is a Sub-Window") {
+				X = Pos.Percent (0),
+				Y = Pos.AnchorEnd () - (height - 4),
+				Width = Dim.Percent (50),
+				Height = Dim.Fill () - 1,
+				ColorScheme = Colors.Base,
+			};
+			subWinFV.Add (new TextField (frame.Title.ToString ()));
+			frame.Add (subWinFV);
+			var frameViewFV = new FrameView ("this is a Sub-FrameView") {
+				X = Pos.Percent (50),
+				Y = Pos.AnchorEnd () - (height - 4),
+				Width = Dim.Percent (100),
+				Height = Dim.Fill() - 1, 
+				ColorScheme = Colors.Base,
+			};
+			frameViewFV.Add (new TextField ("Edit Me"));
+
+			frameViewFV.Add (new CheckBox (0, 1, "Check me"));
+			// BUGBUG: This checkbox is not shown even though frameViewFV has 3 rows in 
+			// it's client area. #522
+			frameViewFV.Add (new CheckBox (0, 2, "Or, Check me"));
+
+			frame.Add (new CheckBox ("No, Check me!") { 
+				X = 0,
+				Y = Pos.AnchorEnd() - 1, // BUGBUG: #522 If I don't do the -1 it doesn't draw, but it should!
+			});
+			frame.Add (new CheckBox ("Really, Check me!") {
+				X = Pos.Percent(50),
+				Y = Pos.AnchorEnd () - 1, // BUGBUG: #522 If I don't do the -1 it doesn't draw, but it should!
+			});
+
+			frame.Add (frameViewFV);
+
+			Top.Add (frame);
+			listWin.Add (frame);
+		}
+	}
+}