Przeglądaj źródła

improved API docs, removed duplicate code, refactored to make more readable

Tig Kindel 2 lat temu
rodzic
commit
ab2bda109b

+ 4 - 7
Terminal.Gui/Core/Application.cs

@@ -951,13 +951,10 @@ namespace Terminal.Gui {
 
 			var rs = new RunState (toplevel);
 
-			if (toplevel is ISupportInitializeNotification initializableNotification &&
-			    !initializableNotification.IsInitialized) {
-				initializableNotification.BeginInit ();
-				initializableNotification.EndInit ();
-			} else if (toplevel is ISupportInitialize initializable) {
-				initializable.BeginInit ();
-				initializable.EndInit ();
+			// View implements ISupportInitializeNotification which is derived from ISupportInitialize
+			if (!toplevel.IsInitialized) {
+				toplevel.BeginInit ();
+				toplevel.EndInit ();
 			}
 
 			lock (toplevels) {

+ 0 - 13
Terminal.Gui/Core/Toplevel.cs

@@ -20,19 +20,6 @@ namespace Terminal.Gui {
 	///     and run (e.g. <see cref="Dialog"/>s. To run a Toplevel, create the <see cref="Toplevel"/> and 
 	///     call <see cref="Application.Run(Toplevel, Func{Exception, bool})"/>.
 	///   </para>
-	///   <para>
-	///     Toplevels can also opt-in to more sophisticated initialization
-	///     by implementing <see cref="ISupportInitialize"/>. When they do
-	///     so, the <see cref="ISupportInitialize.BeginInit"/> and
-	///     <see cref="ISupportInitialize.EndInit"/> methods will be called
-	///     before running the view.
-	///     If first-run-only initialization is preferred, the <see cref="ISupportInitializeNotification"/>
-	///     can be implemented too, in which case the <see cref="ISupportInitialize"/>
-	///     methods will only be called if <see cref="ISupportInitializeNotification.IsInitialized"/>
-	///     is <see langword="false"/>. This allows proper <see cref="View"/> inheritance hierarchies
-	///     to override base class layout code optimally by doing so only on first run,
-	///     instead of on every run.
-	///   </para>
 	/// </remarks>
 	public class Toplevel : View {
 		/// <summary>

+ 154 - 100
Terminal.Gui/Core/View.cs

@@ -100,6 +100,20 @@ namespace Terminal.Gui {
 	///    for views that use the <see cref="LayoutStyle.Absolute"/>, and will recompute the
 	///    frames for the vies that use <see cref="LayoutStyle.Computed"/>.
 	/// </para>
+	/// <para>
+	///     Views can also opt-in to more sophisticated initialization
+	///     by implementing overrides to <see cref="ISupportInitialize.BeginInit"/> and
+	///     <see cref="ISupportInitialize.EndInit"/> which will be called
+	///     when the view is added to a <see cref="SuperView"/>. 
+	/// </para>
+	/// <para>
+	///     If first-run-only initialization is preferred, overrides to <see cref="ISupportInitializeNotification"/>
+	///     can be implemented, in which case the <see cref="ISupportInitialize"/>
+	///     methods will only be called if <see cref="ISupportInitializeNotification.IsInitialized"/>
+	///     is <see langword="false"/>. This allows proper <see cref="View"/> inheritance hierarchies
+	///     to override base class layout code optimally by doing so only on first run,
+	///     instead of on every run.
+	///   </para>
 	/// </remarks>
 	public class View : Responder, ISupportInitializeNotification {
 
@@ -448,7 +462,7 @@ namespace Terminal.Gui {
 			get => frame;
 			set {
 				frame = new Rect (value.X, value.Y, Math.Max (value.Width, 0), Math.Max (value.Height, 0));
-				TextFormatter.Size = GetBoundsTextFormatterSize ();
+				TextFormatter.Size = GetSizeNeededForTextAndHotKey ();
 				SetNeedsLayout ();
 				SetNeedsDisplay ();
 			}
@@ -618,11 +632,16 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Verifies if the minimum width or height can be sets in the view.
+		/// Gets the minimum dimensions required to fit the View's <see cref="Text"/>, factoring in <see cref="TextDirection"/>.
 		/// </summary>
-		/// <param name="size">The size.</param>
-		/// <returns><see langword="true"/> if the size can be set, <see langword="false"/> otherwise.</returns>
-		public bool GetMinWidthHeight (out Size size)
+		/// <param name="size">The minimum dimensions required.</param>
+		/// <returns><see langword="true"/> if the dimensions fit within the View's <see cref="Bounds"/>, <see langword="false"/> otherwise.</returns>
+		/// <remarks>
+		/// Always returns <see langword="false"/> if <see cref="AutoSize"/> is <see langword="true"/> or
+		/// if <see cref="Height"/> (Horizontal) or <see cref="Width"/> (Vertical) are not not set or zero.
+		/// Does not take into account word wrapping.
+		/// </remarks>
+		public bool GetMinimumBounds (out Size size)
 		{
 			size = Size.Empty;
 
@@ -630,14 +649,22 @@ namespace Terminal.Gui {
 				switch (TextFormatter.IsVerticalDirection (TextDirection)) {
 				case true:
 					var colWidth = TextFormatter.GetSumMaxCharWidth (new List<ustring> { TextFormatter.Text }, 0, 1);
-					if (frame.Width < colWidth && (Width == null || (Bounds.Width >= 0 && Width is Dim.DimAbsolute
-						&& Width.Anchor (0) >= 0 && Width.Anchor (0) < colWidth))) {
+					// TODO: v2 - This uses frame.Width; it should only use Bounds
+					if (frame.Width < colWidth &&
+						(Width == null ||
+							(Bounds.Width >= 0 &&
+								Width is Dim.DimAbsolute &&
+								Width.Anchor (0) >= 0 &&
+								Width.Anchor (0) < colWidth))) {
 						size = new Size (colWidth, Bounds.Height);
 						return true;
 					}
 					break;
 				default:
-					if (frame.Height < 1 && (Height == null || (Height is Dim.DimAbsolute && Height.Anchor (0) == 0))) {
+					if (frame.Height < 1 &&
+						(Height == null ||
+							(Height is Dim.DimAbsolute &&
+								Height.Anchor (0) == 0))) {
 						size = new Size (Bounds.Width, 1);
 						return true;
 					}
@@ -648,14 +675,14 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Sets the minimum width or height if the view can be resized.
+		/// Sets the size of the View to the minimum width or height required to fit <see cref="Text"/> (see <see cref="GetMinimumBounds(out Size)"/>.
 		/// </summary>
-		/// <returns><see langword="true"/> if the size can be set, <see langword="false"/> otherwise.</returns>
+		/// <returns><see langword="true"/> if the size was changed, <see langword="false"/> if <see cref="Text"/>
+		/// will not fit.</returns>
 		public bool SetMinWidthHeight ()
 		{
-			if (GetMinWidthHeight (out Size size)) {
+			if (GetMinimumBounds (out Size size)) {
 				Bounds = new Rect (Bounds.Location, size);
-				TextFormatter.Size = GetBoundsTextFormatterSize ();
 				return true;
 			}
 			return false;
@@ -683,7 +710,7 @@ namespace Terminal.Gui {
 		/// </remarks>
 		public View (Rect frame)
 		{
-			Initialize (ustring.Empty, frame, LayoutStyle.Absolute, TextDirection.LeftRight_TopBottom);
+			SetInitialProperties (ustring.Empty, frame, LayoutStyle.Absolute, TextDirection.LeftRight_TopBottom);
 		}
 
 		/// <summary>
@@ -742,7 +769,7 @@ namespace Terminal.Gui {
 		/// <param name="border">The <see cref="Border"/>.</param>
 		public View (Rect rect, ustring text, Border border = null)
 		{
-			Initialize (text, rect, LayoutStyle.Absolute, TextDirection.LeftRight_TopBottom, border);
+			SetInitialProperties (text, rect, LayoutStyle.Absolute, TextDirection.LeftRight_TopBottom, border);
 		}
 
 		/// <summary>
@@ -763,19 +790,25 @@ namespace Terminal.Gui {
 		/// <param name="border">The <see cref="Border"/>.</param>
 		public View (ustring text, TextDirection direction = TextDirection.LeftRight_TopBottom, Border border = null)
 		{
-			Initialize (text, Rect.Empty, LayoutStyle.Computed, direction, border);
+			SetInitialProperties (text, Rect.Empty, LayoutStyle.Computed, direction, border);
 		}
 
-		void Initialize (ustring text, Rect rect, LayoutStyle layoutStyle = LayoutStyle.Computed,
+		// TODO: v2 - Remove constructors with parameters
+		/// <summary>
+		/// Private helper to set the initial properties of the View that were provided via constructors.
+		/// </summary>
+		/// <param name="text"></param>
+		/// <param name="rect"></param>
+		/// <param name="layoutStyle"></param>
+		/// <param name="direction"></param>
+		/// <param name="border"></param>
+		void SetInitialProperties (ustring text, Rect rect, LayoutStyle layoutStyle = LayoutStyle.Computed,
 		    TextDirection direction = TextDirection.LeftRight_TopBottom, Border border = null)
 		{
+
 			TextFormatter = new TextFormatter ();
 			TextFormatter.HotKeyChanged += TextFormatter_HotKeyChanged;
 			TextDirection = direction;
-			Border = border;
-			if (Border != null) {
-				Border.Child = this;
-			}
 			shortcutHelper = new ShortcutHelper ();
 			CanFocus = false;
 			TabIndex = -1;
@@ -783,11 +816,17 @@ namespace Terminal.Gui {
 			LayoutStyle = layoutStyle;
 			// BUGBUG: CalcRect doesn't account for line wrapping
 
+			// TODO: Remove this once v2's new Frames is ready
+			Border = border;
+			if (Border != null) {
+				Border.Child = this;
+			}
+
 			var r = rect.IsEmpty ? TextFormatter.CalcRect (0, 0, text, direction) : rect;
 			Frame = r;
 
 			Text = text;
-			UpdateTextFormatterText ();
+
 			ProcessResizeView ();
 		}
 
@@ -801,6 +840,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
+		/// Called whenever the view needs to be resized. 
 		/// Can be overridden if the view resize behavior is
 		///  different than the default.
 		/// </summary>
@@ -820,7 +860,8 @@ namespace Terminal.Gui {
 				frame = new Rect (new Point (actX, actY), new Size (w, h));
 				SetMinWidthHeight ();
 			}
-			TextFormatter.Size = GetBoundsTextFormatterSize ();
+			// BUGBUG: I think these calls are redundant or should be moved into just the AutoSize case
+			TextFormatter.Size = GetSizeNeededForTextAndHotKey ();
 			SetNeedsLayout ();
 			SetNeedsDisplay ();
 		}
@@ -943,7 +984,7 @@ namespace Terminal.Gui {
 			SetNeedsLayout ();
 			SetNeedsDisplay ();
 			OnAdded (view);
-			if (IsInitialized) {
+			if (IsInitialized && !view.IsInitialized) {
 				view.BeginInit ();
 				view.EndInit ();
 			}
@@ -2271,8 +2312,9 @@ namespace Terminal.Gui {
 			var r = new Rect (newX, newY, newW, newH);
 			if (Frame != r) {
 				Frame = r;
+				// BUGBUG: Why is this AFTER setting Frame? Seems duplicative.
 				if (!SetMinWidthHeight ()) {
-					TextFormatter.Size = GetBoundsTextFormatterSize ();
+					TextFormatter.Size = GetSizeNeededForTextAndHotKey ();
 				}
 			}
 		}
@@ -2443,7 +2485,7 @@ namespace Terminal.Gui {
 			var oldBounds = Bounds;
 			OnLayoutStarted (new LayoutEventArgs () { OldBounds = oldBounds });
 
-			TextFormatter.Size = GetBoundsTextFormatterSize ();
+			TextFormatter.Size = GetSizeNeededForTextAndHotKey ();
 
 			// Sort out the dependencies of the X, Y, Width, Height properties
 			var nodes = new HashSet<View> ();
@@ -2509,12 +2551,17 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Gets or sets a flag that determines whether the View will be automatically resized to fit the <see cref="Text"/>.
-		/// The default is <see langword="false"/>. Set to <see langword="true"/> to turn on AutoSize. If <see cref="AutoSize"/> is <see langword="true"/> the <see cref="Width"/>
-		/// and <see cref="Height"/> will always be used if the text size is lower. If the text size is higher the bounds will
-		/// be resized to fit it.
+		/// Gets or sets a flag that determines whether the View will be automatically resized to fit the <see cref="Text"/> 
+		/// within <see cref="Bounds"/>
+		/// <para>
+		/// The default is <see langword="false"/>. Set to <see langword="true"/> to turn on AutoSize. If <see langword="true"/> then
+		/// <see cref="Width"/> and <see cref="Height"/> will be used if <see cref="Text"/> can fit; 
+		/// if <see cref="Text"/> won't fit the view will be resized as needed.
+		/// </para>
+		/// <para>
 		/// In addition, if <see cref="ForceValidatePosDim"/> is <see langword="true"/> the new values of <see cref="Width"/> and
 		/// <see cref="Height"/> must be of the same types of the existing one to avoid breaking the <see cref="Dim"/> settings.
+		/// </para>
 		/// </summary>
 		public virtual bool AutoSize {
 			get => autoSize;
@@ -2596,16 +2643,24 @@ namespace Terminal.Gui {
 					} else {
 						SetMinWidthHeight ();
 					}
-					TextFormatter.Size = GetBoundsTextFormatterSize ();
+					TextFormatter.Size = GetSizeNeededForTextAndHotKey ();
 					SetNeedsDisplay ();
 				}
 			}
 		}
 
 		/// <summary>
-		/// Get or sets if  the <see cref="View"/> was already initialized.
-		/// This derived from <see cref="ISupportInitializeNotification"/> to allow notify all the views that are being initialized.
+		/// Get or sets if  the <see cref="View"/> has been initialized (via <see cref="ISupportInitialize.BeginInit"/> 
+		/// and <see cref="ISupportInitialize.EndInit"/>).
 		/// </summary>
+		/// <para>
+		///     If first-run-only initialization is preferred, overrides to <see cref="ISupportInitializeNotification.IsInitialized"/>
+		///     can be implemented, in which case the <see cref="ISupportInitialize"/>
+		///     methods will only be called if <see cref="ISupportInitializeNotification.IsInitialized"/>
+		///     is <see langword="false"/>. This allows proper <see cref="View"/> inheritance hierarchies
+		///     to override base class layout code optimally by doing so only on first run,
+		///     instead of on every run.
+		///   </para>
 		public virtual bool IsInitialized { get; set; }
 
 		/// <summary>
@@ -2727,15 +2782,21 @@ namespace Terminal.Gui {
 					Bounds = new Rect (Bounds.X, Bounds.Y, nBoundsSize.Width, nBoundsSize.Height);
 				}
 			}
-			TextFormatter.Size = GetBoundsTextFormatterSize ();
+			// BUGBUG: This call may be redundant
+			TextFormatter.Size = GetSizeNeededForTextAndHotKey ();
 			return aSize;
 		}
 
+		/// <summary>
+		/// Resizes the View to fit the specified <see cref="Bounds"/> size.
+		/// </summary>
+		/// <param name="nBounds"></param>
+		/// <returns></returns>
 		bool SetWidthHeight (Size nBounds)
 		{
 			var aSize = false;
-			var canSizeW = SetWidth (nBounds.Width - GetHotKeySpecifierLength (), out var rW);
-			var canSizeH = SetHeight (nBounds.Height - GetHotKeySpecifierLength (false), out var rH);
+			var canSizeW = TrySetWidth (nBounds.Width - GetHotKeySpecifierLength (), out var rW);
+			var canSizeH = TrySetHeight (nBounds.Height - GetHotKeySpecifierLength (false), out var rH);
 			if (canSizeW) {
 				aSize = true;
 				width = rW;
@@ -2746,7 +2807,6 @@ namespace Terminal.Gui {
 			}
 			if (aSize) {
 				Bounds = new Rect (Bounds.X, Bounds.Y, canSizeW ? rW : Bounds.Width, canSizeH ? rH : Bounds.Height);
-				TextFormatter.Size = GetBoundsTextFormatterSize ();
 			}
 
 			return aSize;
@@ -2792,8 +2852,12 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Gets the width or height of the <see cref="Terminal.Gui.TextFormatter.HotKeySpecifier"/> characters in the <see cref="Text"/> property.
+		/// Gets the width or height of the <see cref="Terminal.Gui.TextFormatter.HotKeySpecifier"/> characters 
+		/// in the <see cref="Text"/> property.
 		/// </summary>
+		/// <remarks>
+		/// Only the first hotkey specifier found in <see cref="Text"/> is supported.
+		/// </remarks>
 		/// <param name="isWidth">If <see langword="true"/> (the default) the width required for the hotkey specifier is returned. Otherwise the height is returned.</param>
 		/// <returns>The number of characters required for the <see cref="Terminal.Gui.TextFormatter.HotKeySpecifier"/>. If the text direction specified
 		/// by <see cref="TextDirection"/> does not match the <paramref name="isWidth"/> parameter, <c>0</c> is returned.</returns>
@@ -2811,24 +2875,27 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Gets the <see cref="TextFormatter.Size"/> minus the size required for the <see cref="Terminal.Gui.TextFormatter.HotKeySpecifier"/>.
-		/// </summary>
-		/// <returns>The bounds size minus the <see cref="Terminal.Gui.TextFormatter.HotKeySpecifier"/> length.</returns>
-		public Size GetTextFormatterBoundsSize ()
+		/// Gets the dimensions required for <see cref="Text"/> ignoring a <see cref="Terminal.Gui.TextFormatter.HotKeySpecifier"/>.
+		/// /// <summary/>
+		/// <returns></returns>
+		public Size GetSizeNeededForTextWithoutHotKey ()
 		{
 			return new Size (TextFormatter.Size.Width - GetHotKeySpecifierLength (),
 			    TextFormatter.Size.Height - GetHotKeySpecifierLength (false));
 		}
 
 		/// <summary>
-		/// Gets the text formatter size from a <see cref="Bounds"/> size.
-		/// </summary>
-		/// <returns>The text formatter size more the <see cref="Terminal.Gui.TextFormatter.HotKeySpecifier"/> length.</returns>
-		public Size GetBoundsTextFormatterSize ()
+		/// Gets the dimensions required for <see cref="Text"/> accounting for a <see cref="Terminal.Gui.TextFormatter.HotKeySpecifier"/> .
+		/// <summary/>
+		/// <returns></returns>
+		public Size GetSizeNeededForTextAndHotKey ()
 		{
-			if (ustring.IsNullOrEmpty (TextFormatter.Text))
+			if (ustring.IsNullOrEmpty (TextFormatter.Text)) {
 				return Bounds.Size;
+			}
 
+			// BUGBUG: This IGNORES what Text is set to, using on only the current View size. This doesn't seem to make sense.
+			// BUGBUG: This uses Frame; in v2 it should be Bounds
 			return new Size (frame.Size.Width + GetHotKeySpecifierLength (),
 			    frame.Size.Height + GetHotKeySpecifierLength (false));
 		}
@@ -2961,14 +3028,37 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// This derived from <see cref="ISupportInitializeNotification"/> to allow notify all the views that are beginning initialized.
+		///  Signals the View that initialization is starting. See <see cref="ISupportInitialize"/>.
 		/// </summary>
-		public void BeginInit ()
+		/// <remarks>
+		/// <para>
+		///     Views can opt-in to more sophisticated initialization
+		///     by implementing overrides to <see cref="ISupportInitialize.BeginInit"/> and
+		///     <see cref="ISupportInitialize.EndInit"/> which will be called
+		///     when the view is added to a <see cref="SuperView"/>. 
+		/// </para>
+		/// <para>
+		///     If first-run-only initialization is preferred, overrides to <see cref="ISupportInitializeNotification"/>
+		///     can be implemented too, in which case the <see cref="ISupportInitialize"/>
+		///     methods will only be called if <see cref="ISupportInitializeNotification.IsInitialized"/>
+		///     is <see langword="false"/>. This allows proper <see cref="View"/> inheritance hierarchies
+		///     to override base class layout code optimally by doing so only on first run,
+		///     instead of on every run.
+		///   </para>
+		/// </remarks>
+		public virtual void BeginInit ()
 		{
 			if (!IsInitialized) {
 				oldCanFocus = CanFocus;
 				oldTabIndex = tabIndex;
+
+				//UpdateTextFormatterText ();
+				//ProcessResizeView ();
+
+			} else {
+				//throw new InvalidOperationException ("The view is already initialized.");
 			}
+
 			if (subviews?.Count > 0) {
 				foreach (var view in subviews) {
 					if (!view.IsInitialized) {
@@ -2979,12 +3069,12 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// This derived from <see cref="ISupportInitializeNotification"/> to allow notify all the views that are ending initialized.
+		///  Signals the View that initialization is ending. See <see cref="ISupportInitialize"/>.
 		/// </summary>
 		public void EndInit ()
 		{
 			IsInitialized = true;
-			if (subviews?.Count > 0) {
+			if (subviews != null) {
 				foreach (var view in subviews) {
 					if (!view.IsInitialized) {
 						view.EndInit ();
@@ -3008,7 +3098,13 @@ namespace Terminal.Gui {
 			return true;
 		}
 
-		bool CanSetWidth (int desiredWidth, out int resultWidth)
+		/// <summary>
+		/// Determines if the View's <see cref="Width"/> can be set to a new value.
+		/// </summary>
+		/// <param name="desiredWidth"></param>
+		/// <param name="resultWidth">Contains the width that would result if <see cref="Width"/> were set to <paramref name="desiredWidth"/>"/> </param>
+		/// <returns><see langword="true"/> if the View's <see cref="Width"/> can be changed to the specified value. False otherwise.</returns>
+		internal bool TrySetWidth (int desiredWidth, out int resultWidth)
 		{
 			var w = desiredWidth;
 			bool canSetWidth;
@@ -3032,7 +3128,13 @@ namespace Terminal.Gui {
 			return canSetWidth;
 		}
 
-		bool CanSetHeight (int desiredHeight, out int resultHeight)
+		/// <summary>
+		/// Determines if the View's <see cref="Height"/> can be set to a new value.
+		/// </summary>
+		/// <param name="desiredHeight"></param>
+		/// <param name="resultHeight">Contains the width that would result if <see cref="Height"/> were set to <paramref name="desiredHeight"/>"/> </param>
+		/// <returns><see langword="true"/> if the View's <see cref="Height"/> can be changed to the specified value. False otherwise.</returns>
+		internal bool TrySetHeight (int desiredHeight, out int resultHeight)
 		{
 			var h = desiredHeight;
 			bool canSetHeight;
@@ -3062,54 +3164,6 @@ namespace Terminal.Gui {
 			return canSetHeight;
 		}
 
-		/// <summary>
-		/// Calculate the width based on the <see cref="Width"/> settings.
-		/// </summary>
-		/// <param name="desiredWidth">The desired width.</param>
-		/// <param name="resultWidth">The real result width.</param>
-		/// <returns><see langword="true"/> if the width can be directly assigned, <see langword="false"/> otherwise.</returns>
-		public bool SetWidth (int desiredWidth, out int resultWidth)
-		{
-			return CanSetWidth (desiredWidth, out resultWidth);
-		}
-
-		/// <summary>
-		/// Calculate the height based on the <see cref="Height"/> settings.
-		/// </summary>
-		/// <param name="desiredHeight">The desired height.</param>
-		/// <param name="resultHeight">The real result height.</param>
-		/// <returns><see langword="true"/> if the height can be directly assigned, <see langword="false"/> otherwise.</returns>
-		public bool SetHeight (int desiredHeight, out int resultHeight)
-		{
-			return CanSetHeight (desiredHeight, out resultHeight);
-		}
-
-		/// <summary>
-		/// Gets the current width based on the <see cref="Width"/> settings.
-		/// </summary>
-		/// <param name="currentWidth">The real current width.</param>
-		/// <returns><see langword="true"/> if the width can be directly assigned, <see langword="false"/> otherwise.</returns>
-		public bool GetCurrentWidth (out int currentWidth)
-		{
-			SetRelativeLayout (SuperView?.frame ?? frame);
-			currentWidth = frame.Width;
-
-			return CanSetWidth (0, out _);
-		}
-
-		/// <summary>
-		/// Calculate the height based on the <see cref="Height"/> settings.
-		/// </summary>
-		/// <param name="currentHeight">The real current height.</param>
-		/// <returns><see langword="true"/> if the height can be directly assigned, <see langword="false"/> otherwise.</returns>
-		public bool GetCurrentHeight (out int currentHeight)
-		{
-			SetRelativeLayout (SuperView?.frame ?? frame);
-			currentHeight = frame.Height;
-
-			return CanSetHeight (0, out _);
-		}
-
 		/// <summary>
 		/// Determines the current <see cref="ColorScheme"/> based on the <see cref="Enabled"/> value.
 		/// </summary>

+ 10 - 5
Terminal.Gui/Views/Button.cs

@@ -60,7 +60,7 @@ namespace Terminal.Gui {
 		/// </param>
 		public Button (ustring text, bool is_default = false) : base (text)
 		{
-			Initialize (text, is_default);
+			SetInitialProperties (text, is_default);
 		}
 
 		/// <summary>
@@ -92,10 +92,15 @@ namespace Terminal.Gui {
 		public Button (int x, int y, ustring text, bool is_default)
 		    : base (new Rect (x, y, text.RuneCount + 4 + (is_default ? 2 : 0), 1), text)
 		{
-			Initialize (text, is_default);
+			SetInitialProperties (text, is_default);
 		}
-
-		void Initialize (ustring text, bool is_default)
+		// TODO: v2 - Remove constructors with parameters
+		/// <summary>
+		/// Private helper to set the initial properties of the View that were provided via constructors.
+		/// </summary>
+		/// <param name="text"></param>
+		/// <param name="is_default"></param>
+		void SetInitialProperties (ustring text, bool is_default)
 		{
 			TextAlignment = TextAlignment.Centered;
 			VerticalTextAlignment = VerticalTextAlignment.Middle;
@@ -111,7 +116,7 @@ namespace Terminal.Gui {
 			AutoSize = true;
 			this.is_default = is_default;
 			Text = text ?? string.Empty;
-			UpdateTextFormatterText ();
+
 			ProcessResizeView ();
 
 			// Things this view knows how to do

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

@@ -49,7 +49,7 @@ namespace Terminal.Gui {
 		/// <param name="is_checked">If set to <c>true</c> is checked.</param>
 		public CheckBox (ustring s, bool is_checked = false) : base ()
 		{
-			Initialize (s, is_checked);
+			SetInitialProperties (s, is_checked);
 		}
 
 		/// <summary>
@@ -72,10 +72,16 @@ namespace Terminal.Gui {
 		/// </remarks>
 		public CheckBox (int x, int y, ustring s, bool is_checked) : base (new Rect (x, y, s.Length, 1))
 		{
-			Initialize (s, is_checked);
+			SetInitialProperties (s, is_checked);
 		}
 
-		void Initialize (ustring s, bool is_checked)
+		// TODO: v2 - Remove constructors with parameters
+		/// <summary>
+		/// Private helper to set the initial properties of the View that were provided via constructors.
+		/// </summary>
+		/// <param name="s"></param>
+		/// <param name="is_checked"></param>
+		void SetInitialProperties (ustring s, bool is_checked)
 		{
 			charNullChecked = new Rune (Driver != null ? Driver.NullChecked : '?');
 			charChecked = new Rune (Driver != null ? Driver.Checked : '√');
@@ -85,7 +91,7 @@ namespace Terminal.Gui {
 			CanFocus = true;
 			AutoSize = true;
 			Text = s;
-			UpdateTextFormatterText ();
+			
 			ProcessResizeView ();
 
 			// Things this view knows how to do

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

@@ -45,7 +45,7 @@ namespace Terminal.Gui {
 		/// <param name="frame"></param>
 		public ScrollView (Rect frame) : base (frame)
 		{
-			Initialize (frame);
+			SetInitialProperties (frame);
 		}
 
 
@@ -54,10 +54,10 @@ namespace Terminal.Gui {
 		/// </summary>
 		public ScrollView () : base ()
 		{
-			Initialize (Rect.Empty);
+			SetInitialProperties (Rect.Empty);
 		}
 
-		void Initialize (Rect frame)
+		void SetInitialProperties (Rect frame)
 		{
 			contentView = new ContentView (frame);
 			vertical = new ScrollBarView (1, 0, isVertical: true) {

+ 32 - 24
UnitTests/Core/LayoutTests.cs

@@ -48,7 +48,7 @@ namespace Terminal.Gui.CoreTests {
 		}
 
 		[Fact, AutoInitShutdown]
-		public void SetWidth_CanSetWidth_ForceValidatePosDim ()
+		public void TrySetWidth_ForceValidatePosDim ()
 		{
 			var top = new View () {
 				X = 0,
@@ -62,15 +62,15 @@ namespace Terminal.Gui.CoreTests {
 			};
 			top.Add (v);
 
-			Assert.False (v.SetWidth (70, out int rWidth));
+			Assert.False (v.TrySetWidth (70, out int rWidth));
 			Assert.Equal (70, rWidth);
 
 			v.Width = Dim.Fill (1);
-			Assert.False (v.SetWidth (70, out rWidth));
+			Assert.False (v.TrySetWidth (70, out rWidth));
 			Assert.Equal (69, rWidth);
 
 			v.Width = null;
-			Assert.True (v.SetWidth (70, out rWidth));
+			Assert.True (v.TrySetWidth (70, out rWidth));
 			Assert.Equal (70, rWidth);
 			Assert.False (v.IsInitialized);
 
@@ -82,12 +82,12 @@ namespace Terminal.Gui.CoreTests {
 			Assert.Throws<ArgumentException> (() => v.Width = 75);
 			v.LayoutStyle = LayoutStyle.Absolute;
 			v.Width = 75;
-			Assert.True (v.SetWidth (60, out rWidth));
+			Assert.True (v.TrySetWidth (60, out rWidth));
 			Assert.Equal (60, rWidth);
 		}
 
 		[Fact, AutoInitShutdown]
-		public void SetHeight_CanSetHeight_ForceValidatePosDim ()
+		public void TrySetHeight_ForceValidatePosDim ()
 		{
 			var top = new View () {
 				X = 0,
@@ -101,15 +101,15 @@ namespace Terminal.Gui.CoreTests {
 			};
 			top.Add (v);
 
-			Assert.False (v.SetHeight (10, out int rHeight));
+			Assert.False (v.TrySetHeight (10, out int rHeight));
 			Assert.Equal (10, rHeight);
 
 			v.Height = Dim.Fill (1);
-			Assert.False (v.SetHeight (10, out rHeight));
+			Assert.False (v.TrySetHeight (10, out rHeight));
 			Assert.Equal (9, rHeight);
 
 			v.Height = null;
-			Assert.True (v.SetHeight (10, out rHeight));
+			Assert.True (v.TrySetHeight (10, out rHeight));
 			Assert.Equal (10, rHeight);
 			Assert.False (v.IsInitialized);
 
@@ -122,12 +122,12 @@ namespace Terminal.Gui.CoreTests {
 			Assert.Throws<ArgumentException> (() => v.Height = 15);
 			v.LayoutStyle = LayoutStyle.Absolute;
 			v.Height = 15;
-			Assert.True (v.SetHeight (5, out rHeight));
+			Assert.True (v.TrySetHeight (5, out rHeight));
 			Assert.Equal (5, rHeight);
 		}
 
 		[Fact]
-		public void GetCurrentWidth_CanSetWidth ()
+		public void GetCurrentWidth_TrySetWidth ()
 		{
 			var top = new View () {
 				X = 0,
@@ -139,23 +139,27 @@ namespace Terminal.Gui.CoreTests {
 				Width = Dim.Fill ()
 			};
 			top.Add (v);
+			top.LayoutSubviews ();
 
 			Assert.False (v.AutoSize);
-			Assert.True (v.GetCurrentWidth (out int cWidth));
-			Assert.Equal (80, cWidth);
+			Assert.True (v.TrySetWidth (0, out _));
+			Assert.Equal (80, v.Frame.Width);
 
 			v.Width = Dim.Fill (1);
-			Assert.True (v.GetCurrentWidth (out cWidth));
-			Assert.Equal (79, cWidth);
+			top.LayoutSubviews ();
+
+			Assert.True (v.TrySetWidth (0, out _));
+			Assert.Equal (79, v.Frame.Width);
 
 			v.AutoSize = true;
+			top.LayoutSubviews ();
 
-			Assert.True (v.GetCurrentWidth (out cWidth));
-			Assert.Equal (79, cWidth);
+			Assert.True (v.TrySetWidth (0, out _));
+			Assert.Equal (79, v.Frame.Width);
 		}
 
 		[Fact]
-		public void GetCurrentHeight_CanSetHeight ()
+		public void GetCurrentHeight_TrySetHeight ()
 		{
 			var top = new View () {
 				X = 0,
@@ -167,19 +171,23 @@ namespace Terminal.Gui.CoreTests {
 				Height = Dim.Fill ()
 			};
 			top.Add (v);
+			top.LayoutSubviews ();
 
 			Assert.False (v.AutoSize);
-			Assert.True (v.GetCurrentHeight (out int cHeight));
-			Assert.Equal (20, cHeight);
+			Assert.True (v.TrySetHeight (0, out _));
+			Assert.Equal (20, v.Frame.Height);
 
 			v.Height = Dim.Fill (1);
-			Assert.True (v.GetCurrentHeight (out cHeight));
-			Assert.Equal (19, cHeight);
+			top.LayoutSubviews ();
+
+			Assert.True (v.TrySetHeight (0, out _));
+			Assert.Equal (19, v.Frame.Height);
 
 			v.AutoSize = true;
+			top.LayoutSubviews ();
 
-			Assert.True (v.GetCurrentHeight (out cHeight));
-			Assert.Equal (19, cHeight);
+			Assert.True (v.TrySetHeight (0, out _));
+			Assert.Equal (19, v.Frame.Height);
 		}
 
 		[Fact]

+ 17 - 17
UnitTests/Core/ViewTests.cs

@@ -2111,7 +2111,7 @@ namespace Terminal.Gui.CoreTests {
 		}
 
 		[Fact]
-		public void GetTextFormatterBoundsSize_GetBoundsTextFormatterSize_HotKeySpecifier ()
+		public void GetTextFormatterBoundsSize_GetSizeNeededForText_HotKeySpecifier ()
 		{
 			var text = "Say Hello 你";
 			var horizontalView = new View () { Text = text, AutoSize = true, HotKeySpecifier = '_' };
@@ -2124,17 +2124,17 @@ namespace Terminal.Gui.CoreTests {
 
 			Assert.True (horizontalView.AutoSize);
 			Assert.Equal (new Rect (0, 0, 12, 1), horizontalView.Frame);
-			Assert.Equal (new Size (12, 1), horizontalView.GetTextFormatterBoundsSize ());
-			Assert.Equal (new Size (12, 1), horizontalView.GetBoundsTextFormatterSize ());
-			Assert.Equal (horizontalView.TextFormatter.Size, horizontalView.GetBoundsTextFormatterSize ());
-			Assert.Equal (horizontalView.Frame.Size, horizontalView.GetTextFormatterBoundsSize ());
+			Assert.Equal (new Size (12, 1), horizontalView.GetSizeNeededForTextWithoutHotKey ());
+			Assert.Equal (new Size (12, 1), horizontalView.GetSizeNeededForTextAndHotKey ());
+			Assert.Equal (horizontalView.TextFormatter.Size, horizontalView.GetSizeNeededForTextAndHotKey ());
+			Assert.Equal (horizontalView.Frame.Size, horizontalView.GetSizeNeededForTextWithoutHotKey ());
 
 			Assert.True (verticalView.AutoSize);
 			Assert.Equal (new Rect (0, 0, 2, 11), verticalView.Frame);
-			Assert.Equal (new Size (2, 11), verticalView.GetTextFormatterBoundsSize ());
-			Assert.Equal (new Size (2, 11), verticalView.GetBoundsTextFormatterSize ());
-			Assert.Equal (verticalView.TextFormatter.Size, verticalView.GetBoundsTextFormatterSize ());
-			Assert.Equal (verticalView.Frame.Size, verticalView.GetTextFormatterBoundsSize ());
+			Assert.Equal (new Size (2, 11), verticalView.GetSizeNeededForTextWithoutHotKey ());
+			Assert.Equal (new Size (2, 11), verticalView.GetSizeNeededForTextAndHotKey ());
+			Assert.Equal (verticalView.TextFormatter.Size, verticalView.GetSizeNeededForTextAndHotKey ());
+			Assert.Equal (verticalView.Frame.Size, verticalView.GetSizeNeededForTextWithoutHotKey ());
 
 			text = "Say He_llo 你";
 			horizontalView.Text = text;
@@ -2142,17 +2142,17 @@ namespace Terminal.Gui.CoreTests {
 
 			Assert.True (horizontalView.AutoSize);
 			Assert.Equal (new Rect (0, 0, 12, 1), horizontalView.Frame);
-			Assert.Equal (new Size (12, 1), horizontalView.GetTextFormatterBoundsSize ());
-			Assert.Equal (new Size (13, 1), horizontalView.GetBoundsTextFormatterSize ());
-			Assert.Equal (horizontalView.TextFormatter.Size, horizontalView.GetBoundsTextFormatterSize ());
-			Assert.Equal (horizontalView.Frame.Size, horizontalView.GetTextFormatterBoundsSize ());
+			Assert.Equal (new Size (12, 1), horizontalView.GetSizeNeededForTextWithoutHotKey ());
+			Assert.Equal (new Size (13, 1), horizontalView.GetSizeNeededForTextAndHotKey ());
+			Assert.Equal (horizontalView.TextFormatter.Size, horizontalView.GetSizeNeededForTextAndHotKey ());
+			Assert.Equal (horizontalView.Frame.Size, horizontalView.GetSizeNeededForTextWithoutHotKey ());
 
 			Assert.True (verticalView.AutoSize);
 			Assert.Equal (new Rect (0, 0, 2, 11), verticalView.Frame);
-			Assert.Equal (new Size (2, 11), verticalView.GetTextFormatterBoundsSize ());
-			Assert.Equal (new Size (2, 12), verticalView.GetBoundsTextFormatterSize ());
-			Assert.Equal (verticalView.TextFormatter.Size, verticalView.GetBoundsTextFormatterSize ());
-			Assert.Equal (verticalView.Frame.Size, verticalView.GetTextFormatterBoundsSize ());
+			Assert.Equal (new Size (2, 11), verticalView.GetSizeNeededForTextWithoutHotKey ());
+			Assert.Equal (new Size (2, 12), verticalView.GetSizeNeededForTextAndHotKey ());
+			Assert.Equal (verticalView.TextFormatter.Size, verticalView.GetSizeNeededForTextAndHotKey ());
+			Assert.Equal (verticalView.Frame.Size, verticalView.GetSizeNeededForTextWithoutHotKey ());
 		}
 
 		[Fact]

+ 2 - 2
UnitTests/Views/ButtonTests.cs

@@ -30,8 +30,8 @@ namespace Terminal.Gui.ViewTests {
 [  ]
 ";
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
-
 			Application.End (rs);
+			
 			btn = new Button ("ARGS", true) { Text = "Test" };
 			Assert.Equal ("Test", btn.Text);
 			Application.Top.Add (btn);
@@ -48,8 +48,8 @@ namespace Terminal.Gui.ViewTests {
 [◦ Test ◦]
 ";
 			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
-
 			Application.End (rs);
+			
 			btn = new Button (3, 4, "Test", true);
 			Assert.Equal ("Test", btn.Text);
 			Application.Top.Add (btn);

+ 2 - 2
UnitTests/Views/CheckBoxTests.cs

@@ -452,7 +452,7 @@ namespace Terminal.Gui.ViewTests {
 				Y = Pos.Center (),
 				Text = "Check this out 你"
 			};
-			checkBox.X = Pos.AnchorEnd () - Pos.Function (() => checkBox.GetTextFormatterBoundsSize ().Width);
+			checkBox.X = Pos.AnchorEnd () - Pos.Function (() => checkBox.GetSizeNeededForTextWithoutHotKey ().Width);
 
 			var win = new Window () {
 				Width = Dim.Fill (),
@@ -498,7 +498,7 @@ namespace Terminal.Gui.ViewTests {
 				Y = Pos.Center (),
 				Text = "C_heck this out 你"
 			};
-			checkBox.X = Pos.AnchorEnd () - Pos.Function (() => checkBox.GetTextFormatterBoundsSize ().Width);
+			checkBox.X = Pos.AnchorEnd () - Pos.Function (() => checkBox.GetSizeNeededForTextWithoutHotKey ().Width);
 
 			var win = new Window () {
 				Width = Dim.Fill (),

+ 2 - 2
UnitTests/Views/ScrollViewTests.cs

@@ -324,8 +324,8 @@ namespace Terminal.Gui.ViewTests {
 			private Label labelFill;
 			private Label labelText;
 
-			public CustomButton (string fill, ustring text, int width, int height)
-			{
+			public CustomButton (string fill, ustring text, int width, int height) : base()
+			{				
 				Width = width;
 				Height = height;
 				labelFill = new Label () { AutoSize = false, Width = Dim.Fill (), Height = Dim.Fill (), Visible = false };

+ 0 - 2
UnitTests/Views/TableViewTests.cs

@@ -1655,8 +1655,6 @@ namespace Terminal.Gui.ViewTests {
 			Assert.Equal(1,tableView.GetAllSelectedCells().Count());
 		}
 
-
-
 		[Fact, AutoInitShutdown]
 		public void TestToggleCells_MultiSelectOn_Two_SquareSelects_BothToggled ()
 		{