Charlie Kindel 5 年之前
父节点
当前提交
90b19a5e04

+ 9 - 1
Terminal.Gui/Core/Toplevel.cs

@@ -179,6 +179,10 @@ namespace Terminal.Gui {
 
 		IEnumerable<View> GetToplevelSubviews (bool isForward)
 		{
+			if (SuperView == null) {
+				return null;
+			}
+
 			HashSet<View> views = new HashSet<View> ();
 
 			foreach (var v in SuperView.Subviews) {
@@ -190,6 +194,10 @@ namespace Terminal.Gui {
 
 		void FocusNearestView (IEnumerable<View> views)
 		{
+			if (views == null) {
+				return;
+			}
+
 			bool found = false;
 
 			foreach (var v in views) {
@@ -205,7 +213,7 @@ namespace Terminal.Gui {
 			}
 		}
 
-		///<inheritdoc cref="Add"/>
+		///<inheritdoc/>
 		public override void Add (View view)
 		{
 			if (this == Application.Top) {

+ 8 - 3
Terminal.Gui/Core/Window.cs

@@ -69,7 +69,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Initializes a new instance of the <see cref="Window"/> class with an optional title.
+		/// Initializes a new instance of the <see cref="Window"/> class with an optional title using <see cref="LayoutStyle.Computed"/> positioning.
 		/// </summary>
 		/// <param name="title">Title.</param>
 		/// <remarks>
@@ -80,9 +80,14 @@ namespace Terminal.Gui {
 		{
 		}
 
+		/// <summary>
+		/// Initializes a new instance of the <see cref="Window"/> class using <see cref="LayoutStyle.Computed"/> positioning.
+		/// </summary>
+		public Window () : this (title: null) { }
+
 		int padding;
 		/// <summary>
-		/// Initializes a new instance of the <see cref="Window"/> with the specified frame for its location, with the specified border,
+		/// Initializes a new instance of the <see cref="Window"/> using <see cref="LayoutStyle.Absolute"/> positioning with the specified frame for its location, with the specified frame padding,
 		/// and an optional title.
 		/// </summary>
 		/// <param name="frame">Superview-relatie rectangle specifying the location and size</param>
@@ -103,7 +108,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Initializes a new instance of the <see cref="Window"/> with the specified frame for its location, with the specified border,
+		/// Initializes a new instance of the <see cref="Window"/> using <see cref="LayoutStyle.Absolute"/> positioning with the specified frame for its location, with the specified frame padding,
 		/// and an optional title.
 		/// </summary>
 		/// <param name="padding">Number of characters to use for padding of the drawn frame.</param>

+ 9 - 0
Terminal.Gui/Views/Button.cs

@@ -54,6 +54,15 @@ namespace Terminal.Gui {
 		/// </remarks>
 		public Action Clicked;
 
+		/// <summary>
+		///   Initializes a new instance of <see cref="Button"/> using <see cref="LayoutStyle.Computed"/> layout.
+		/// </summary>
+		/// <remarks>
+		///   The width of the <see cref="Button"/> is computed based on the
+		///   text length. The height will always be 1.
+		/// </remarks>
+		public Button () : this (string.Empty) { }
+
 		/// <summary>
 		///   Initializes a new instance of <see cref="Button"/> using <see cref="LayoutStyle.Computed"/> layout.
 		/// </summary>

+ 10 - 4
Terminal.Gui/Views/Checkbox.cs

@@ -30,12 +30,18 @@ namespace Terminal.Gui {
 		/// <summary>
 		/// Called when the <see cref="Checked"/> property changes. Invokes the <see cref="Toggled"/> event.
 		/// </summary>
-		public virtual void OnToggled (bool previousChecked) {
+		public virtual void OnToggled (bool previousChecked)
+		{
 			Toggled?.Invoke (this, previousChecked);
 		}
 
 		/// <summary>
-		/// Initializes a new instance of <see cref="CheckBox"/> based on the given text, uses Computed layout and sets the height and width.
+		/// Initializes a new instance of <see cref="CheckBox"/> based on the given text, using <see cref="LayoutStyle.Computed"/> layout.
+		/// </summary>
+		public CheckBox () : this (string.Empty) { }
+
+		/// <summary>
+		/// Initializes a new instance of <see cref="CheckBox"/> based on the given text, using <see cref="LayoutStyle.Computed"/> layout.
 		/// </summary>
 		/// <param name="s">S.</param>
 		/// <param name="is_checked">If set to <c>true</c> is checked.</param>
@@ -49,7 +55,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Initializes a new instance of <see cref="CheckBox"/> based on the given text at the given position and a state.
+		/// Initializes a new instance of <see cref="CheckBox"/> using <see cref="LayoutStyle.Absolute"/> layout.
 		/// </summary>
 		/// <remarks>
 		///   The size of <see cref="CheckBox"/> is computed based on the
@@ -60,7 +66,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Initializes a new instance of <see cref="CheckBox"/> based on the given text at the given position and a state.
+		/// Initializes a new instance of <see cref="CheckBox"/> using <see cref="LayoutStyle.Absolute"/> layout.
 		/// </summary>
 		/// <remarks>
 		///   The size of <see cref="CheckBox"/> is computed based on the

+ 13 - 8
Terminal.Gui/Views/DateField.cs

@@ -29,20 +29,25 @@ namespace Terminal.Gui {
 		string Format { get { return isShort ? shortFormat : longFormat; } }
 
 		/// <summary>
-		///    Initializes a new instance of <see cref="DateField"/> at an absolute position and fixed size.
+		///    Initializes a new instance of <see cref="DateField"/> using <see cref="LayoutStyle.Absolute"/> layout.
 		/// </summary>
 		/// <param name="x">The x coordinate.</param>
 		/// <param name="y">The y coordinate.</param>
 		/// <param name="date">Initial date contents.</param>
 		/// <param name="isShort">If true, shows only two digits for the year.</param>
-		public DateField (int x, int y, DateTime date, bool isShort = false) : base(x, y, isShort ? 10 : 12, "")
+		public DateField (int x, int y, DateTime date, bool isShort = false) : base (x, y, isShort ? 10 : 12, "")
 		{
 			this.isShort = isShort;
 			Initialize (date);
 		}
 
 		/// <summary>
-		///  Initializes a new instance of <see cref="DateField"/> 
+		///  Initializes a new instance of <see cref="DateField"/> using <see cref="LayoutStyle.Computed"/> layout.
+		/// </summary>
+		public DateField () : this (DateTime.MinValue) { }
+
+		/// <summary>
+		///  Initializes a new instance of <see cref="DateField"/> using <see cref="LayoutStyle.Computed"/> layout.
 		/// </summary>
 		/// <param name="date"></param>
 		public DateField (DateTime date) : base ("")
@@ -65,7 +70,7 @@ namespace Terminal.Gui {
 
 		void DateField_Changed (object sender, ustring e)
 		{
-			if (!DateTime.TryParseExact (GetDate (Text).ToString(), GetInvarianteFormat (), CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime result))
+			if (!DateTime.TryParseExact (GetDate (Text).ToString (), GetInvarianteFormat (), CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime result))
 				Text = e;
 		}
 
@@ -259,8 +264,8 @@ namespace Terminal.Gui {
 				CursorPosition++;
 		}
 
-		///<inheritdoc/>
-		public override bool ProcessKey(KeyEvent kb)
+		/// <inheritdoc/>
+		public override bool ProcessKey (KeyEvent kb)
 		{
 			switch (kb.Key) {
 			case Key.DeleteChar:
@@ -306,8 +311,8 @@ namespace Terminal.Gui {
 			return true;
 		}
 
-		///<inheritdoc/>
-		public override bool MouseEvent(MouseEvent ev)
+		/// <inheritdoc/>
+		public override bool MouseEvent (MouseEvent ev)
 		{
 			if (!ev.Flags.HasFlag (MouseFlags.Button1Clicked))
 				return false;

+ 16 - 14
Terminal.Gui/Views/FrameView.cs

@@ -4,10 +4,10 @@
 // Authors:
 //   Miguel de Icaza ([email protected])
 //
-	using System;
-	using System.Collections;
-	using System.Collections.Generic;
-	using NStack;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using NStack;
 
 namespace Terminal.Gui {
 	/// <summary>
@@ -36,27 +36,25 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Initializes a new instance of the <see cref="Gui.FrameView"/> class with
-		/// an absolute position and a title.
+		/// Initializes a new instance of the <see cref="Gui.FrameView"/> class using <see cref="LayoutStyle.Absolute"/> layout.
 		/// </summary>
 		/// <param name="frame">Frame.</param>
 		/// <param name="title">Title.</param>
 		public FrameView (Rect frame, ustring title) : base (frame)
 		{
-			var cFrame = new Rect (1, 1 , frame.Width - 2, frame.Height - 2);
+			var cFrame = new Rect (1, 1, frame.Width - 2, frame.Height - 2);
 			this.title = title;
 			contentView = new ContentView (cFrame);
 			Initialize ();
 		}
 
 		/// <summary>
-		/// Initializes a new instance of the <see cref="Gui.FrameView"/> class with
-		/// an absolute position, a title and <see cref="View"/>s.
+		/// Initializes a new instance of the <see cref="Gui.FrameView"/> class using <see cref="LayoutStyle.Computed"/> layout.
 		/// </summary>
 		/// <param name="frame">Frame.</param>
 		/// <param name="title">Title.</param>
 		/// /// <param name="views">Views.</param>
-		public FrameView (Rect frame, ustring title, View[] views) : this (frame, title)
+		public FrameView (Rect frame, ustring title, View [] views) : this (frame, title)
 		{
 			foreach (var view in views) {
 				contentView.Add (view);
@@ -65,8 +63,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Initializes a new instance of the <see cref="Gui.FrameView"/> class with
-		/// a title and the result is suitable to have its X, Y, Width and Height properties computed.
+		/// Initializes a new instance of the <see cref="Gui.FrameView"/> class using <see cref="LayoutStyle.Computed"/> layout.
 		/// </summary>
 		/// <param name="title">Title.</param>
 		public FrameView (ustring title)
@@ -81,6 +78,11 @@ namespace Terminal.Gui {
 			Initialize ();
 		}
 
+		/// <summary>
+		/// Initializes a new instance of the <see cref="Gui.FrameView"/> class using <see cref="LayoutStyle.Computed"/> layout.
+		/// </summary>
+		public FrameView () : this (title: string.Empty) { }
+
 		void Initialize ()
 		{
 			base.Add (contentView);
@@ -126,9 +128,9 @@ namespace Terminal.Gui {
 		/// </summary>
 		/// <remarks>
 		/// </remarks>
-		public override void RemoveAll()
+		public override void RemoveAll ()
 		{
-			contentView.RemoveAll();
+			contentView.RemoveAll ();
 		}
 
 		///<inheritdoc/>

+ 12 - 7
Terminal.Gui/Views/HexView.cs

@@ -41,10 +41,10 @@ namespace Terminal.Gui {
 		bool firstNibble, leftSide;
 
 		/// <summary>
-		/// Initialzies a <see cref="HexView"/>
+		/// Initialzies a <see cref="HexView"/> class using <see cref="LayoutStyle.Computed"/> layout.
 		/// </summary>
 		/// <param name="source">The <see cref="Stream"/> to view and edit as hex, this <see cref="Stream"/> must support seeking, or an exception will be thrown.</param>
-		public HexView (Stream source) : base()
+		public HexView (Stream source) : base ()
 		{
 			Source = source;
 			this.source = source;
@@ -53,6 +53,11 @@ namespace Terminal.Gui {
 			firstNibble = true;
 		}
 
+		/// <summary>
+		/// Initialzies a <see cref="HexView"/> class using <see cref="LayoutStyle.Computed"/> layout.
+		/// </summary>
+		public HexView () : this (source: new MemoryStream ()) { }
+
 		/// <summary>
 		/// Sets or gets the <see cref="Stream"/> the <see cref="HexView"/> is operating on; the stream must support seeking (<see cref="Stream.CanSeek"/> == true).
 		/// </summary>
@@ -151,7 +156,7 @@ namespace Terminal.Gui {
 				var lineRect = new Rect (0, line, frame.Width, 1);
 				if (!bounds.Contains (lineRect))
 					continue;
-				
+
 				Move (0, line);
 				Driver.SetAttribute (ColorScheme.HotNormal);
 				Driver.AddStr (string.Format ("{0:x8} ", displayStart + line * nblocks * 4));
@@ -197,7 +202,7 @@ namespace Terminal.Gui {
 						SetAttribute (leftSide ? trackingColor : activeColor);
 					else
 						SetAttribute (ColorScheme.Normal);
-					
+
 					Driver.AddRune (c);
 				}
 			}
@@ -229,7 +234,7 @@ namespace Terminal.Gui {
 
 		void RedisplayLine (long pos)
 		{
-			var delta = (int) (pos - DisplayStart);
+			var delta = (int)(pos - DisplayStart);
 			var line = delta / bytesPerLine;
 
 			SetNeedsDisplay (new Rect (0, line, Frame.Width, 1));
@@ -277,7 +282,7 @@ namespace Terminal.Gui {
 				SetDisplayStart (DisplayStart + bytes);
 				SetNeedsDisplay ();
 			} else
-				RedisplayLine (position);			
+				RedisplayLine (position);
 		}
 
 		/// <inheritdoc/>
@@ -376,7 +381,7 @@ namespace Terminal.Gui {
 		/// Each Key indicates an offset where an edit was made and the Value is the changed byte.
 		/// </summary>
 		/// <value>The edits.</value>
-		public IReadOnlyDictionary<long,byte> Edits => edits;
+		public IReadOnlyDictionary<long, byte> Edits => edits;
 
 		/// <summary>
 		/// This method applies andy edits made to the <see cref="Stream"/> and resets the 

+ 54 - 9
Terminal.Gui/Views/Label.cs

@@ -64,29 +64,59 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		///   Initializes a new instance of <see cref="Label"/> at the given
-		///   coordinate with the given string, computes the bounding box
-		///   based on the size of the string, assumes that the string contains
-		///   newlines for multiple lines, no special breaking rules are used.
+		///   Initializes a new instance of <see cref="Label"/> using <see cref="LayoutStyle.Absolute"/> layout.
 		/// </summary>
+		/// <remarks>
+		/// <para>
+		///   The <see cref="Label"/> will be created at the given
+		///   coordinates with the given string. The size (<see cref="View.Frame"/> will be 
+		///   adjusted to fit the contents of <see cref="Text"/>, including newlines ('\n') for multiple lines. 
+		/// </para>
+		/// <para>
+		///   No line wraping is provided.
+		/// </para>
+		/// </remarks>
+		/// <param name="x">column to locate the Label.</param>
+		/// <param name="y">row to locate the Label.</param>
+		/// <param name="text">text to initialize the <see cref="Text"/> property with.</param>
 		public Label (int x, int y, ustring text) : this (CalcRect (x, y, text), text)
 		{
 		}
 
 		/// <summary>
-		///   Initializes a new instance of <see cref="Label"/> at the given
-		///   coordinate with the given string and uses the specified
-		///   frame for the string.
+		///   Initializes a new instance of <see cref="Label"/> using <see cref="LayoutStyle.Absolute"/> layout.
 		/// </summary>
+		/// <remarks>
+		/// <para>
+		///   The <see cref="Label"/> will be created at the given
+		///   coordinates with the given string. The initial size (<see cref="View.Frame"/> will be 
+		///   adjusted to fit the contents of <see cref="Text"/>, including newlines ('\n') for multiple lines. 
+		/// </para>
+		/// <para>
+		///   No line wraping is provided.
+		/// </para>
+		/// </remarks>
+		/// <param name="rect">Location.</param>
+		/// <param name="text">text to initialize the <see cref="Text"/> property with.</param>
 		public Label (Rect rect, ustring text) : base (rect)
 		{
 			this.text = text;
 		}
 
 		/// <summary>
-		/// Initializes a new instance of <see cref="Label"/> and configures the default Width and Height based on the text, the result is suitable for Computed layout.
+		///   Initializes a new instance of <see cref="Label"/> using <see cref="LayoutStyle.Computed"/> layout.
 		/// </summary>
-		/// <param name="text">Text.</param>
+		/// <remarks>
+		/// <para>
+		///   The <see cref="Label"/> will be created using <see cref="LayoutStyle.Computed"/>
+		///   coordinates with the given string. The initial size (<see cref="View.Frame"/> will be 
+		///   adjusted to fit the contents of <see cref="Text"/>, including newlines ('\n') for multiple lines. 
+		/// </para>
+		/// <para>
+		///   No line wraping is provided.
+		/// </para>
+		/// </remarks>
+		/// <param name="text">text to initialize the <see cref="Text"/> property with.</param>
 		public Label (ustring text) : base ()
 		{
 			this.text = text;
@@ -95,6 +125,21 @@ namespace Terminal.Gui {
 			Height = r.Height;
 		}
 
+		/// <summary>
+		///   Initializes a new instance of <see cref="Label"/> using <see cref="LayoutStyle.Computed"/> layout.
+		/// </summary>
+		/// <remarks>
+		/// <para>
+		///   The <see cref="Label"/> will be created using <see cref="LayoutStyle.Computed"/>
+		///   coordinates. The initial size (<see cref="View.Frame"/> will be 
+		///   adjusted to fit the contents of <see cref="Text"/>, including newlines ('\n') for multiple lines. 
+		/// </para>
+		/// <para>
+		///   No line wraping is provided.
+		/// </para>
+		/// </remarks>
+		public Label () : this (text: string.Empty) { }
+
 		static char [] whitespace = new char [] { ' ', '\t' };
 
 		static ustring ClipAndJustify (ustring str, int width, TextAlignment talign)

+ 11 - 3
Terminal.Gui/Views/Menu.cs

@@ -173,9 +173,12 @@ namespace Terminal.Gui {
 		/// Initializes a new <see cref="MenuBarItem"/>.
 		/// </summary>
 		/// <param name="children">The items in the current menu.</param>
-		public MenuBarItem (MenuItem [] children) : this (new string (' ', GetMaxTitleLength (children)), children)
-		{
-		}
+		public MenuBarItem (MenuItem [] children) : this (new string (' ', GetMaxTitleLength (children)), children) { }
+
+		/// <summary>
+		/// Initializes a new <see cref="MenuBarItem"/>.
+		/// </summary>
+		public MenuBarItem () : this (children: new MenuItem [] { }) { }
 
 		static int GetMaxTitleLength (MenuItem [] children)
 		{
@@ -550,6 +553,11 @@ namespace Terminal.Gui {
 		/// </summary>
 		public bool UseKeysUpDownAsKeysLeftRight { get; set; } = true;
 
+		/// <summary>
+		/// Initializes a new instance of the <see cref="MenuBar"/>.
+		/// </summary>
+		public MenuBar () : this (new MenuBarItem [] { }) { }
+
 		/// <summary>
 		/// Initializes a new instance of the <see cref="MenuBar"/> class with the specified set of toplevel menu items.
 		/// </summary>

+ 9 - 10
Terminal.Gui/Views/RadioGroup.cs

@@ -7,9 +7,7 @@ namespace Terminal.Gui {
 		int selected, cursor;
 
 		/// <summary>
-		/// Initializes a new instance of the <see cref="RadioGroup"/> class
-		/// setting up the initial set of radio labels and the item that should be selected and uses
-		/// an absolute layout for the result.
+		/// Initializes a new instance of the <see cref="RadioGroup"/> class using <see cref="LayoutStyle.Computed"/> layout.
 		/// </summary>
 		/// <param name="rect">Boundaries for the radio group.</param>
 		/// <param name="radioLabels">The radio labels; an array of strings that can contain hotkeys using an underscore before the letter.</param>
@@ -35,8 +33,12 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Initializes a new instance of the <see cref="RadioGroup"/> class
-		/// setting up the initial set of radio labels and the item that should be selected.
+		/// Initializes a new instance of the <see cref="RadioGroup"/> class using <see cref="LayoutStyle.Computed"/> layout.
+		/// </summary>
+		public RadioGroup () : this (radioLabels: new string [] { }) { }
+
+		/// <summary>
+		/// Initializes a new instance of the <see cref="RadioGroup"/> class using <see cref="LayoutStyle.Computed"/> layout.
 		/// </summary>
 		/// <param name="radioLabels">The radio labels; an array of strings that can contain hotkeys using an underscore before the letter.</param>
 		/// <param name="selected">The index of the item to be selected, the value is clamped to the number of items.</param>
@@ -66,17 +68,14 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Initializes a new instance of the <see cref="RadioGroup"/> class
-		/// setting up the initial set of radio labels and the item that should be selected.
+		/// Initializes a new instance of the <see cref="RadioGroup"/> class using <see cref="LayoutStyle.Absolute"/> layout.
 		/// The <see cref="View"/> frame is computed from the provided radio labels.
 		/// </summary>
 		/// <param name="x">The x coordinate.</param>
 		/// <param name="y">The y coordinate.</param>
 		/// <param name="radioLabels">The radio labels; an array of strings that can contain hotkeys using an underscore before the letter.</param>
 		/// <param name="selected">The item to be selected, the value is clamped to the number of items.</param>		
-		public RadioGroup (int x, int y, string [] radioLabels, int selected = 0) : this (MakeRect (x, y, radioLabels), radioLabels, selected)
-		{
-		}
+		public RadioGroup (int x, int y, string [] radioLabels, int selected = 0) : this (MakeRect (x, y, radioLabels), radioLabels, selected) { }
 
 		string [] radioLabels;
 

+ 1 - 1
Terminal.Gui/Views/ScrollView.cs

@@ -125,7 +125,7 @@ namespace Terminal.Gui {
 		///<inheritdoc/>
 		public override void Redraw (Rect region)
 		{
-			if (ColorScheme == null)
+			if (ColorScheme == null || Size == 0)
 				return;
 
 			Driver.SetAttribute (ColorScheme.Normal);

+ 11 - 6
Terminal.Gui/Views/StatusBar.cs

@@ -47,7 +47,7 @@ namespace Terminal.Gui {
 		/// A <see cref="StatusItem.Title"/> set to `~F1~ Help` will render as *F1* using <see cref="ColorScheme.HotNormal"/> and
 		/// *Help* as <see cref="ColorScheme.HotNormal"/>.
 		/// </remarks>
-		public ustring Title { get; set;}
+		public ustring Title { get; set; }
 
 		/// <summary>
 		/// Gets or sets the action to be invoked when the statusbar item is triggered
@@ -103,6 +103,11 @@ namespace Terminal.Gui {
 		/// </summary>
 		public StatusItem [] Items { get; set; }
 
+		/// <summary>
+		/// Initializes a new instance of the <see cref="StatusBar"/> class.
+		/// </summary>
+		public StatusBar () : this (items: new StatusItem [] { }) { }
+
 		/// <summary>
 		/// Initializes a new instance of the <see cref="StatusBar"/> class with the specified set of <see cref="StatusItem"/>s.
 		/// The <see cref="StatusBar"/> will be drawn on the lowest line of the terminal or <see cref="StatusBar.Parent"/> (if not null).
@@ -131,11 +136,11 @@ namespace Terminal.Gui {
 					break;
 				case StatusBarStyle.SnapToBottom:
 #endif
-					if (Parent == null) {
-						Y = Driver.Rows - 1; 
-					} else {
-						Y = Pos.Bottom (Parent);
-					}
+				if (Parent == null) {
+					Y = Driver.Rows - 1;
+				} else {
+					Y = Pos.Bottom (Parent);
+				}
 #if SNAP_TO_TOP
 					break;
 				}

+ 8 - 3
Terminal.Gui/Views/TextField.cs

@@ -44,7 +44,7 @@ namespace Terminal.Gui {
 		public event EventHandler<ustring> Changed;
 
 		/// <summary>
-		///    Public constructor that creates a text field, with layout controlled with X, Y, Width and Height.
+		/// Initializes a new instance of the <see cref="TextField"/> class using <see cref="LayoutStyle.Computed"/> positioning.
 		/// </summary>
 		/// <param name="text">Initial text contents.</param>
 		public TextField (string text) : this (ustring.Make (text))
@@ -53,7 +53,12 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		///    Public constructor that creates a text field, with layout controlled with X, Y, Width and Height.
+		/// Initializes a new instance of the <see cref="TextField"/> class using <see cref="LayoutStyle.Computed"/> positioning.
+		/// </summary>
+		public TextField () : this (string.Empty) { }
+
+		/// <summary>
+		/// Initializes a new instance of the <see cref="TextField"/> class using <see cref="LayoutStyle.Computed"/> positioning.
 		/// </summary>
 		/// <param name="text">Initial text contents.</param>
 		public TextField (ustring text)
@@ -62,7 +67,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		///    Public constructor that creates a text field at an absolute position and size.
+		/// Initializes a new instance of the <see cref="TextField"/> class using <see cref="LayoutStyle.Absolute"/> positioning.
 		/// </summary>
 		/// <param name="x">The x coordinate.</param>
 		/// <param name="y">The y coordinate.</param>

+ 12 - 7
Terminal.Gui/Views/TimeField.cs

@@ -30,12 +30,12 @@ namespace Terminal.Gui {
 
 
 		/// <summary>
-		///    Initializes a new instance of <see cref="TimeField"/> at an absolute position and fixed size.
+		///    Initializes a new instance of <see cref="TimeField"/> using <see cref="LayoutStyle.Absolute"/> positioning.
 		/// </summary>
 		/// <param name="x">The x coordinate.</param>
 		/// <param name="y">The y coordinate.</param>
-		/// <param name="time">Initial time contents.</param>
-		/// <param name="isShort">If true, the seconds are hidden.</param>
+		/// <param name="time">Initial time.</param>
+		/// <param name="isShort">If true, the seconds are hidden. Sets the <see cref="IsShortFormat"/> property.</param>
 		public TimeField (int x, int y, DateTime time, bool isShort = false) : base (x, y, isShort ? 7 : 10, "")
 		{
 			this.isShort = isShort;
@@ -43,16 +43,21 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Initializes a new instance of <see cref="TimeField"/> 
+		///    Initializes a new instance of <see cref="TimeField"/> using <see cref="LayoutStyle.Computed"/> positioning.
 		/// </summary>
-		/// <param name="time"></param>
-		public TimeField (DateTime time) : base ("")
+		/// <param name="time">Initial time</param>
+		public TimeField (DateTime time) : base (string.Empty)
 		{
 			this.isShort = true;
 			Width = FieldLen + 2;
 			Initialize (time);
 		}
 
+		/// <summary>
+		///    Initializes a new instance of <see cref="TimeField"/> using <see cref="LayoutStyle.Computed"/> positioning.
+		/// </summary>
+		public TimeField () : this (time: DateTime.MinValue) { }
+
 		void Initialize (DateTime time)
 		{
 			CultureInfo cultureInfo = CultureInfo.CurrentCulture;
@@ -86,7 +91,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Get or set the data format for the widget.
+		/// Get or sets whether <see cref="TimeField"/> uses the short or long time format.
 		/// </summary>
 		public bool IsShortFormat {
 			get => isShort;

+ 17 - 7
Terminal.Gui/Windows/Dialog.cs

@@ -24,7 +24,7 @@ namespace Terminal.Gui {
 		const int padding = 0;
 
 		/// <summary>
-		/// Initializes a new instance of the <see cref="Dialog"/> class using <see cref="LayoutStyle.Absolute"/> positioning 
+		/// Initializes a new instance of the <see cref="Dialog"/> class using <see cref="LayoutStyle.Computed"/> positioning 
 		/// and an optional set of <see cref="Button"/>s to display
 		/// </summary>
 		/// <param name="title">Title for the dialog.</param>
@@ -61,10 +61,22 @@ namespace Terminal.Gui {
 					Add (b);
 				}
 			}
-
-			//LayoutComplete += (sender, a) => AdjustButtonLayout ();
 		}
 
+		/// <summary>
+		/// Initializes a new instance of the <see cref="Dialog"/> class using <see cref="LayoutStyle.Computed"/>.
+		/// </summary>
+		/// <remarks>
+		/// <para>
+		/// Te Dialog will be vertically and horizontally centered in the container and the size will be 85% of the container. 
+		/// After initialzation use <c>X</c>, <c>Y</c>, <c>Width</c>, and <c>Height</c> to override this with a location or size.
+		/// </para>
+		/// <para>
+		/// Use <see cref="AddButton(Button)"/> to add buttons to the dialog.
+		/// </para>
+		/// </remarks>
+		public Dialog () : this (title: string.Empty, width: 0, height: 0, buttons: null) { }
+
 		/// <summary>
 		/// Initializes a new instance of the <see cref="Dialog"/> class using <see cref="LayoutStyle.Computed"/> positioning 
 		/// and with an optional set of <see cref="Button"/>s to display
@@ -72,12 +84,10 @@ namespace Terminal.Gui {
 		/// <param name="title">Title for the dialog.</param>
 		/// <param name="buttons">Optional buttons to lay out at the bottom of the dialog.</param>
 		/// <remarks>
-		/// if <c>width</c> and <c>height</c> are both 0, the Dialog will be vertically and horizontally centered in the
-		/// container and the size will be 85% of the container. 
+		/// Te Dialog will be vertically and horizontally centered in the container and the size will be 85% of the container. 
 		/// After initialzation use <c>X</c>, <c>Y</c>, <c>Width</c>, and <c>Height</c> to override this with a location or size.
 		/// </remarks>
-		public Dialog (ustring title, params Button [] buttons) : this (title: title, width: 0, height: 0, buttons: buttons) { 
-		}
+		public Dialog (ustring title, params Button [] buttons) : this (title: title, width: 0, height: 0, buttons: buttons) { }
 
 		/// <summary>
 		/// Adds a <see cref="Button"/> to the <see cref="Dialog"/>, its layout will be controled by the <see cref="Dialog"/>

+ 28 - 15
Terminal.Gui/Windows/FileDialog.cs

@@ -19,7 +19,7 @@ namespace Terminal.Gui {
 	internal class DirListView : View {
 		int top, selected;
 		DirectoryInfo dirInfo;
-		List<(string,bool,bool)> infos;
+		List<(string, bool, bool)> infos;
 		internal bool canChooseFiles = true;
 		internal bool canChooseDirectories = false;
 		internal bool allowsMultipleSelection = false;
@@ -27,7 +27,7 @@ namespace Terminal.Gui {
 
 		public DirListView (FileDialog host)
 		{
-			infos = new List<(string,bool,bool)> ();
+			infos = new List<(string, bool, bool)> ();
 			CanFocus = true;
 			this.host = host;
 		}
@@ -35,7 +35,7 @@ namespace Terminal.Gui {
 		bool IsAllowed (FileSystemInfo fsi)
 		{
 			if (fsi.Attributes.HasFlag (FileAttributes.Directory))
-			    return true;
+				return true;
 			if (allowedFileTypes == null)
 				return true;
 			foreach (var ft in allowedFileTypes)
@@ -48,9 +48,9 @@ namespace Terminal.Gui {
 		{
 			dirInfo = new DirectoryInfo (directory.ToString ());
 			infos = (from x in dirInfo.GetFileSystemInfos ()
-			         where IsAllowed (x)
-			         orderby (!x.Attributes.HasFlag (FileAttributes.Directory)) + x.Name
-			         select (x.Name, x.Attributes.HasFlag (FileAttributes.Directory), false)).ToList ();
+				 where IsAllowed (x)
+				 orderby (!x.Attributes.HasFlag (FileAttributes.Directory)) + x.Name
+				 select (x.Name, x.Attributes.HasFlag (FileAttributes.Directory), false)).ToList ();
 			infos.Insert (0, ("..", true, false));
 			top = 0;
 			selected = 0;
@@ -407,7 +407,7 @@ namespace Terminal.Gui {
 							return new List<string> () { MakePath (infos [selected].Item1) };
 						return Array.Empty<string> ();
 					} else {
-						if (canChooseFiles) 
+						if (canChooseFiles)
 							return new List<string> () { MakePath (infos [selected].Item1) };
 						return Array.Empty<string> ();
 					}
@@ -425,6 +425,11 @@ namespace Terminal.Gui {
 		TextField dirEntry, nameEntry;
 		internal DirListView dirListView;
 
+		/// <summary>
+		/// Initializes a new <see cref="FileDialog"/>.
+		/// </summary>
+		public FileDialog () : this (title: string.Empty, prompt: string.Empty, nameFieldLabel: string.Empty, message: string.Empty) { }
+
 		/// <summary>
 		/// Initializes a new instance of <see cref="FileDialog"/>
 		/// </summary>
@@ -582,9 +587,9 @@ namespace Terminal.Gui {
 		/// </summary>
 		/// <value>The absolute file path for the file path entered.</value>
 		public ustring FilePath {
-			get => dirListView.MakePath(nameEntry.Text.ToString());
+			get => dirListView.MakePath (nameEntry.Text.ToString ());
 			set {
-				nameEntry.Text = Path.GetFileName(value.ToString());
+				nameEntry.Text = Path.GetFileName (value.ToString ());
 			}
 		}
 
@@ -608,13 +613,16 @@ namespace Terminal.Gui {
 	/// </remarks>
 	public class SaveDialog : FileDialog {
 		/// <summary>
-		/// Initializes a new <see cref="SaveDialog"/>
+		/// Initializes a new <see cref="SaveDialog"/>.
+		/// </summary>
+		public SaveDialog () : this (title: string.Empty, message: string.Empty) { }
+
+		/// <summary>
+		/// Initializes a new <see cref="SaveDialog"/>.
 		/// </summary>
 		/// <param name="title">The title.</param>
 		/// <param name="message">The message.</param>
-		public SaveDialog (ustring title, ustring message) : base (title, prompt: "Save", nameFieldLabel: "Save as:", message: message)
-		{
-		}
+		public SaveDialog (ustring title, ustring message) : base (title, prompt: "Save", nameFieldLabel: "Save as:", message: message) { }
 
 		/// <summary>
 		/// Gets the name of the file the user selected for saving, or null
@@ -625,7 +633,7 @@ namespace Terminal.Gui {
 			get {
 				if (canceled)
 					return null;
-				return Path.GetFileName(FilePath.ToString());
+				return Path.GetFileName (FilePath.ToString ());
 			}
 		}
 	}
@@ -650,7 +658,12 @@ namespace Terminal.Gui {
 	/// </remarks>
 	public class OpenDialog : FileDialog {
 		/// <summary>
-		/// Initializes a new <see cref="OpenDialog"/>
+		/// Initializes a new <see cref="OpenDialog"/>.
+		/// </summary>
+		public OpenDialog () : this (title: string.Empty, message: string.Empty) { }
+
+		/// <summary>
+		/// Initializes a new <see cref="OpenDialog"/>.
 		/// </summary>
 		/// <param name="title"></param>
 		/// <param name="message"></param>

+ 122 - 6
UICatalog/Scenarios/ComputedLayout.cs

@@ -1,6 +1,8 @@
-using System;
+using NStack;
+using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Reflection;
 using System.Text;
 using Terminal.Gui;
 
@@ -17,13 +19,27 @@ namespace UICatalog {
 
 		public override void Setup ()
 		{
+			var menu = new MenuBar (new MenuBarItem [] {
+				new MenuBarItem ("_Settings", new MenuItem [] {
+					null,
+					new MenuItem ("_Quit", "", () => Quit()),
+				}),
+				new MenuBarItem ("_All Controls", "Tests all controls", () => DemoAllViewClasses() ),
+			});
+			Top.Add (menu);
+
+			var statusBar = new StatusBar (new StatusItem [] {
+				new StatusItem(Key.ControlQ, "~^Q~ Quit", () => Quit()),
+			});
+			Top.Add (statusBar);
+
 			//Top.LayoutStyle = LayoutStyle.Computed;
 			// Demonstrate using Dim to create a horizontal ruler that always measures the parent window's width
 			// BUGBUG: Dim.Fill returns too big a value sometimes.
 			const string rule = "|123456789";
 			var horizontalRuler = new Label ("") {
 				X = 0,
-				Y = 0,		
+				Y = 0,
 				Width = Dim.Fill (1),  // BUGBUG: I don't think this should be needed; DimFill() should respect container's frame. X does.
 				ColorScheme = Colors.Error
 			};
@@ -44,7 +60,7 @@ namespace UICatalog {
 
 			Win.LayoutComplete += (sender, a) => {
 				horizontalRuler.Text = rule.Repeat ((int)Math.Ceiling ((double)(horizontalRuler.Bounds.Width) / (double)rule.Length)) [0..(horizontalRuler.Bounds.Width)];
-				verticalRuler.Text = vrule.Repeat ((int)Math.Ceiling ((double)(verticalRuler.Bounds.Height*2) / (double)rule.Length)) [0..(verticalRuler.Bounds.Height*2)];
+				verticalRuler.Text = vrule.Repeat ((int)Math.Ceiling ((double)(verticalRuler.Bounds.Height * 2) / (double)rule.Length)) [0..(verticalRuler.Bounds.Height * 2)];
 			};
 
 			Win.Add (verticalRuler);
@@ -59,7 +75,7 @@ namespace UICatalog {
 			// Demonstrate using Dim to create a window that fills the parent with a margin
 			int margin = 10;
 			var subWin = new Window ($"Centered Sub Window with {margin} character margin") {
-				X = Pos.Center(),
+				X = Pos.Center (),
 				Y = 2,
 				Width = Dim.Fill (margin),
 				Height = 7
@@ -79,7 +95,7 @@ namespace UICatalog {
 			// #522 repro?
 			var frameView = new FrameView ($"Centered FrameView with {margin} character margin") {
 				X = Pos.Center (),
-				Y = Pos.Bottom(subWin),
+				Y = Pos.Bottom (subWin),
 				Width = Dim.Fill (margin),
 				Height = 7
 			};
@@ -176,7 +192,7 @@ namespace UICatalog {
 
 			// Center three buttons with 5 spaces between them
 			// TODO: Use Pos.Width instead of (Right-Left) when implemented (#502)
-			leftButton.X = Pos.Left (centerButton) - (Pos.Right(leftButton) - Pos.Left (leftButton)) - 5;
+			leftButton.X = Pos.Left (centerButton) - (Pos.Right (leftButton) - Pos.Left (leftButton)) - 5;
 			rightButton.X = Pos.Right (centerButton) + 5;
 
 			Win.Add (leftButton);
@@ -184,10 +200,110 @@ namespace UICatalog {
 			Win.Add (rightButton);
 		}
 
+		/// <summary>
+		/// Displays a Dialog that uses a wizard (next/prev) idom to step through each class derived from View
+		/// testing various Computed layout scenarios
+		/// </summary>
+		private void DemoAllViewClasses ()
+		{
+			List<Type> GetAllViewClassesCollection ()
+			{
+				List<Type> objects = new List<Type> ();
+				foreach (Type type in typeof (View).Assembly.GetTypes ()
+				 .Where (myType => myType.IsClass && !myType.IsAbstract && myType.IsPublic && myType.IsSubclassOf (typeof (View)))) {
+					objects.Add (type);
+				}
+				return objects;
+			}
+
+			var viewClasses = GetAllViewClassesCollection ().OrderByDescending (c => c.Name).ToList ();
+			var curClass = 0;
+
+			var closeBtn = new Button ("_Close") {
+				Clicked = () => {
+					Application.RequestStop ();
+				},
+			};
+			var nextBtn = new Button ("_Next");
+			var prevBtn = new Button ("_Previous");
+			var dialog = new Dialog ("Demoing all View classs", new [] { prevBtn, nextBtn, closeBtn });
+
+			var label = new Label ("Class:") {
+				X = 0,
+				Y = 0,
+			};
+			dialog.Add (label);
+			var currentClassLabel = new Label ("") {
+				X = Pos.Right (label) + 1,
+				Y = Pos.Y (label),
+			};
+			dialog.Add (currentClassLabel);
+
+			View curView = null;
+			void SetCurrentClass ()
+			{
+				currentClassLabel.Text = $"{viewClasses [curClass].Name}";
+
+				// Remove existing class, if any
+				if (curView != null) {
+					dialog.Remove (curView);
+					curView = null;
+				}
+
+				// Instantiate view
+				curView = (View)Activator.CreateInstance (viewClasses [curClass]);
+
+				curView.X = Pos.Center ();
+				curView.Y = Pos.Center ();
+				curView.Width = Dim.Fill (5);
+				curView.Height = Dim.Fill (5);
+
+				// If the view supports a Text property, set it so we have something to look at
+				if (viewClasses [curClass].GetProperty("Text") != null) {
+					curView.GetType ().GetProperty ("Text")?.GetSetMethod ()?.Invoke (curView, new [] { ustring.Make("09/10/1966") });
+				}
+
+				// If the view supports a Title property, set it so we have something to look at
+				if (viewClasses [curClass].GetProperty ("Title") != null) {
+					curView.GetType ().GetProperty ("Title")?.GetSetMethod ()?.Invoke (curView, new [] { ustring.Make ("Test Title") });
+				}
+
+
+				dialog.Add (curView);
+				dialog.LayoutSubviews ();
+			}
+
+			nextBtn.Clicked = () => {
+				curClass++;
+				if (curClass >= viewClasses.Count) {
+					curClass = 0;
+				}
+				SetCurrentClass ();
+			};
+
+			prevBtn.Clicked = () => {
+				if (curClass == 0) {
+					curClass = viewClasses.Count - 1;
+				} else {
+					curClass--;
+				}
+				SetCurrentClass ();
+			};
+
+			SetCurrentClass ();
+
+			Application.Run (dialog);
+		}
+
 		public override void Run ()
 		{
 			base.Run ();
 		}
+
+		private void Quit ()
+		{
+			Application.RequestStop ();
+		}
 	}
 
 	internal static class StringExtensions {