浏览代码

Merge branch 'v2' into v2_view2_experiment

Tig Kindel 2 年之前
父节点
当前提交
d7b1192ca5

+ 14 - 14
Terminal.Gui/Core/PosDim.cs

@@ -52,7 +52,7 @@ namespace Terminal.Gui {
 
 
 			public override string ToString ()
 			public override string ToString ()
 			{
 			{
-				return $"Pos.PosFunc({function ()})";
+				return $"PosFunc({function ()})";
 			}
 			}
 
 
 			public override int GetHashCode () => function.GetHashCode ();
 			public override int GetHashCode () => function.GetHashCode ();
@@ -85,7 +85,7 @@ namespace Terminal.Gui {
 
 
 			public override string ToString ()
 			public override string ToString ()
 			{
 			{
-				return $"Pos.Factor({factor})";
+				return $"Factor({factor})";
 			}
 			}
 
 
 			public override int GetHashCode () => factor.GetHashCode ();
 			public override int GetHashCode () => factor.GetHashCode ();
@@ -135,7 +135,7 @@ namespace Terminal.Gui {
 
 
 			public override string ToString ()
 			public override string ToString ()
 			{
 			{
-				return $"Pos.AnchorEnd(margin={n})";
+				return $"AnchorEnd({n})";
 			}
 			}
 		}
 		}
 
 
@@ -174,7 +174,7 @@ namespace Terminal.Gui {
 
 
 			public override string ToString ()
 			public override string ToString ()
 			{
 			{
-				return "Pos.Center";
+				return "Center";
 			}
 			}
 		}
 		}
 
 
@@ -209,7 +209,7 @@ namespace Terminal.Gui {
 
 
 			public override string ToString ()
 			public override string ToString ()
 			{
 			{
-				return $"Pos.Absolute({n})";
+				return $"Absolute({n})";
 			}
 			}
 
 
 			internal override int Anchor (int width)
 			internal override int Anchor (int width)
@@ -244,7 +244,7 @@ namespace Terminal.Gui {
 
 
 		internal class PosCombine : Pos {
 		internal class PosCombine : Pos {
 			internal Pos left, right;
 			internal Pos left, right;
-			bool add;
+			internal bool add;
 			public PosCombine (bool add, Pos left, Pos right)
 			public PosCombine (bool add, Pos left, Pos right)
 			{
 			{
 				this.left = left;
 				this.left = left;
@@ -264,7 +264,7 @@ namespace Terminal.Gui {
 
 
 			public override string ToString ()
 			public override string ToString ()
 			{
 			{
-				return $"Pos.Combine({left.ToString ()}{(add ? '+' : '-')}{right.ToString ()})";
+				return $"Combine({left}{(add ? '+' : '-')}{right})";
 			}
 			}
 
 
 		}
 		}
@@ -345,7 +345,7 @@ namespace Terminal.Gui {
 				case 3: tside = "bottom"; break;
 				case 3: tside = "bottom"; break;
 				default: tside = "unknown"; break;
 				default: tside = "unknown"; break;
 				}
 				}
-				return $"Pos.View(side={tside}, target={Target.ToString ()})";
+				return $"View({tside},{Target.ToString()})";
 			}
 			}
 
 
 			public override int GetHashCode () => Target.GetHashCode ();
 			public override int GetHashCode () => Target.GetHashCode ();
@@ -442,7 +442,7 @@ namespace Terminal.Gui {
 
 
 			public override string ToString ()
 			public override string ToString ()
 			{
 			{
-				return $"Dim.DimFunc({function ()})";
+				return $"DimFunc({function ()})";
 			}
 			}
 
 
 			public override int GetHashCode () => function.GetHashCode ();
 			public override int GetHashCode () => function.GetHashCode ();
@@ -482,7 +482,7 @@ namespace Terminal.Gui {
 
 
 			public override string ToString ()
 			public override string ToString ()
 			{
 			{
-				return $"Dim.Factor(factor={factor}, remaining={remaining})";
+				return $"Factor({factor},{remaining})";
 			}
 			}
 
 
 			public override int GetHashCode () => factor.GetHashCode ();
 			public override int GetHashCode () => factor.GetHashCode ();
@@ -522,7 +522,7 @@ namespace Terminal.Gui {
 
 
 			public override string ToString ()
 			public override string ToString ()
 			{
 			{
-				return $"Dim.Absolute({n})";
+				return $"Absolute({n})";
 			}
 			}
 
 
 			internal override int Anchor (int width)
 			internal override int Anchor (int width)
@@ -541,7 +541,7 @@ namespace Terminal.Gui {
 
 
 			public override string ToString ()
 			public override string ToString ()
 			{
 			{
-				return $"Dim.Fill(margin={margin})";
+				return $"Fill({margin})";
 			}
 			}
 
 
 			internal override int Anchor (int width)
 			internal override int Anchor (int width)
@@ -613,7 +613,7 @@ namespace Terminal.Gui {
 
 
 			public override string ToString ()
 			public override string ToString ()
 			{
 			{
-				return $"Dim.Combine({left.ToString ()}{(add ? '+' : '-')}{right.ToString ()})";
+				return $"Combine({left}{(add ? '+' : '-')}{right})";
 			}
 			}
 
 
 		}
 		}
@@ -691,7 +691,7 @@ namespace Terminal.Gui {
 				case 1: tside = "Width"; break;
 				case 1: tside = "Width"; break;
 				default: tside = "unknown"; break;
 				default: tside = "unknown"; break;
 				}
 				}
-				return $"DimView(side={tside}, target={Target.ToString ()})";
+				return $"DimView({tside},{Target.ToString ()})";
 			}
 			}
 
 
 			public override int GetHashCode () => Target.GetHashCode ();
 			public override int GetHashCode () => Target.GetHashCode ();

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

@@ -908,6 +908,12 @@ namespace Terminal.Gui {
 		{
 		{
 			if (!IsMdiContainer) {
 			if (!IsMdiContainer) {
 				base.PositionCursor ();
 				base.PositionCursor ();
+				if (Focused == null) {
+					EnsureFocus ();
+					if (Focused == null) {
+						Driver.SetCursorVisibility (CursorVisibility.Invisible);
+					}
+				}
 				return;
 				return;
 			}
 			}
 
 
@@ -920,6 +926,9 @@ namespace Terminal.Gui {
 				}
 				}
 			}
 			}
 			base.PositionCursor ();
 			base.PositionCursor ();
+			if (Focused == null) {
+				Driver.SetCursorVisibility (CursorVisibility.Invisible);
+			}
 		}
 		}
 
 
 		/// <summary>
 		/// <summary>

文件差异内容过多而无法显示
+ 318 - 518
Terminal.Gui/Core/View.cs


+ 2 - 2
UICatalog/Scenario.cs

@@ -205,8 +205,8 @@ namespace UICatalog {
 		}
 		}
 
 
 		/// <summary>
 		/// <summary>
-		/// Runs the <see cref="Scenario"/>. Override to start the <see cref="Scenario"/> using a <see cref="Toplevel"/> different than `Top`.
-		/// 
+		/// Runs the <see cref="Scenario"/>. Override to start the <see cref="Scenario"/> 
+		/// using a <see cref="Toplevel"/> different than `Top`.
 		/// </summary>
 		/// </summary>
 		/// <remarks>
 		/// <remarks>
 		/// Overrides that do not call the base.<see cref="Run"/>, must call <see cref="Application.Shutdown"/> before returning.
 		/// Overrides that do not call the base.<see cref="Run"/>, must call <see cref="Application.Shutdown"/> before returning.

+ 0 - 313
UICatalog/Scenarios/ASCIICustomButton.cs

@@ -1,313 +0,0 @@
-//using System;
-//using System.Collections.Generic;
-//using System.Diagnostics;
-//using Terminal.Gui;
-
-//namespace UICatalog.Scenarios {
-//	[ScenarioMetadata (Name: "ASCIICustomButtonTest", Description: "ASCIICustomButton sample")]
-//	[ScenarioCategory ("Controls")]
-//	public class ASCIICustomButtonTest : Scenario {
-//		private static bool smallerWindow;
-//		private ScrollViewTestWindow scrollViewTestWindow;
-//		private MenuItem miSmallerWindow;
-
-//		public override void Init (ColorScheme colorScheme)
-//		{
-//			Application.Init ();
-//			scrollViewTestWindow = new ScrollViewTestWindow ();
-//			var menu = new MenuBar (new MenuBarItem [] {
-//				new MenuBarItem("Window Size", new MenuItem [] {
-//					miSmallerWindow = new MenuItem ("Smaller Window", "", ChangeWindowSize) {
-//						CheckType = MenuItemCheckStyle.Checked
-//					},
-//					null,
-//					new MenuItem("Quit", "",() => Application.RequestStop(),null,null, Key.Q | Key.CtrlMask)
-//				})
-//			});
-//			Application.Top.Add (menu, scrollViewTestWindow);
-//			Application.Run ();
-//		}
-
-//		private void ChangeWindowSize ()
-//		{
-//			smallerWindow = (bool)(miSmallerWindow.Checked = !miSmallerWindow.Checked);
-//			scrollViewTestWindow.Dispose ();
-//			Application.Top.Remove (scrollViewTestWindow);
-//			scrollViewTestWindow = new ScrollViewTestWindow ();
-//			Application.Top.Add (scrollViewTestWindow);
-//		}
-
-//		public override void Run ()
-//		{
-//		}
-
-//		public class ASCIICustomButton : Button {
-//			public string Description => $"Description of: {id}";
-
-//			public event Action<ASCIICustomButton> PointerEnter;
-
-//			private Label fill;
-//			private FrameView border;
-//			private string id;
-
-//			public ASCIICustomButton (string text, Pos x, Pos y, int width, int height) : base (text)
-//			{
-//				CustomInitialize ("", text, x, y, width, height);
-//			}
-
-//			public ASCIICustomButton (string id, string text, Pos x, Pos y, int width, int height) : base (text)
-//			{
-//				CustomInitialize (id, text, x, y, width, height);
-//			}
-
-//			private void CustomInitialize (string id, string text, Pos x, Pos y, int width, int height)
-//			{
-//				this.id = id;
-//				X = x;
-//				Y = y;
-
-//				Frame = new Rect {
-//					Width = width,
-//					Height = height
-//				};
-
-//				border = new FrameView () {
-//					Width = width,
-//					Height = height
-//				};
-
-//				AutoSize = false;
-
-//				var fillText = new System.Text.StringBuilder ();
-//				for (int i = 0; i < Bounds.Height; i++) {
-//					if (i > 0) {
-//						fillText.AppendLine ("");
-//					}
-//					for (int j = 0; j < Bounds.Width; j++) {
-//						fillText.Append ("█");
-//					}
-//				}
-
-//				fill = new Label (fillText.ToString ()) {
-//					Visible = false,
-//					CanFocus = false
-//				};
-
-//				var title = new Label (text) {
-//					X = Pos.Center (),
-//					Y = Pos.Center (),
-//				};
-
-//				border.MouseClick += This_MouseClick;
-//				//border.Subviews [0].MouseClick += This_MouseClick;
-//				fill.MouseClick += This_MouseClick;
-//				title.MouseClick += This_MouseClick;
-
-//				Add (border, fill, title);
-//			}
-
-//			private void This_MouseClick (MouseEventArgs obj)
-//			{
-//				OnMouseEvent (obj.MouseEvent);
-//			}
-
-//			public override bool OnMouseEvent (MouseEvent mouseEvent)
-//			{
-//				Debug.WriteLine ($"{mouseEvent.Flags}");
-//				if (mouseEvent.Flags == MouseFlags.Button1Clicked) {
-//					if (!HasFocus && SuperView != null) {
-//						if (!SuperView.HasFocus) {
-//							SuperView.SetFocus ();
-//						}
-//						SetFocus ();
-//						SetNeedsDisplay ();
-//					}
-
-//					OnClicked ();
-//					return true;
-//				}
-//				return base.OnMouseEvent (mouseEvent);
-//			}
-
-//			public override bool OnEnter (View view)
-//			{
-//				border.Visible = false;
-//				fill.Visible = true;
-//				PointerEnter.Invoke (this);
-//				view = this;
-//				return base.OnEnter (view);
-//			}
-
-//			public override bool OnLeave (View view)
-//			{
-//				border.Visible = true;
-//				fill.Visible = false;
-//				if (view == null)
-//					view = this;
-//				return base.OnLeave (view);
-//			}
-//		}
-
-//		public class ScrollViewTestWindow : Window {
-//			private List<Button> buttons;
-//			private const int BUTTONS_ON_PAGE = 7;
-//			private const int BUTTON_HEIGHT = 3;
-
-//			private ScrollView scrollView;
-//			private ASCIICustomButton selected;
-
-//			public ScrollViewTestWindow ()
-//			{
-//				Title = "ScrollViewTestWindow";
-
-//				Label titleLabel = null;
-//				if (smallerWindow) {
-//					Width = 80;
-//					Height = 25;
-
-//					scrollView = new ScrollView () {
-//						X = 3,
-//						Y = 1,
-//						Width = 24,
-//						Height = BUTTONS_ON_PAGE * BUTTON_HEIGHT,
-//						ShowVerticalScrollIndicator = true,
-//						ShowHorizontalScrollIndicator = false
-//					};
-//				} else {
-//					Width = Dim.Fill ();
-//					Height = Dim.Fill ();
-
-//					titleLabel = new Label ("DOCUMENTS") {
-//						X = 0,
-//						Y = 0
-//					};
-
-//					scrollView = new ScrollView () {
-//						X = 0,
-//						Y = 1,
-//						Width = 27,
-//						Height = BUTTONS_ON_PAGE * BUTTON_HEIGHT,
-//						ShowVerticalScrollIndicator = true,
-//						ShowHorizontalScrollIndicator = false
-//					};
-//				}
-
-//				scrollView.ClearKeybindings ();
-
-//				buttons = new List<Button> ();
-//				Button prevButton = null;
-//				int count = 20;
-//				for (int j = 0; j < count; j++) {
-//					Pos yPos = prevButton == null ? 0 : Pos.Bottom (prevButton);
-//					var button = new ASCIICustomButton (j.ToString (), $"section {j}", 0, yPos, 25, BUTTON_HEIGHT);
-//					button.Id = $"button{j}";
-//					button.Clicked += Button_Clicked;
-//					button.PointerEnter += Button_PointerEnter;
-//					button.MouseClick += Button_MouseClick;
-//					button.KeyPress += Button_KeyPress;
-//					scrollView.Add (button);
-//					buttons.Add (button);
-//					prevButton = button;
-//				}
-
-//				var closeButton = new ASCIICustomButton ("close", "Close", 0, Pos.Bottom (prevButton), 25, BUTTON_HEIGHT);
-//				closeButton.Clicked += Button_Clicked;
-//				closeButton.PointerEnter += Button_PointerEnter;
-//				closeButton.MouseClick += Button_MouseClick;
-//				closeButton.KeyPress += Button_KeyPress;
-//				scrollView.Add (closeButton);
-//				buttons.Add (closeButton);
-
-//				var pages = buttons.Count / BUTTONS_ON_PAGE;
-//				if (buttons.Count % BUTTONS_ON_PAGE > 0)
-//					pages++;
-
-//				scrollView.ContentSize = new Size (25, pages * BUTTONS_ON_PAGE * BUTTON_HEIGHT);
-//				if (smallerWindow) {
-//					Add (scrollView);
-//				} else {
-//					Add (titleLabel, scrollView);
-//				}
-//			}
-
-//			private void Button_KeyPress (KeyEventEventArgs obj)
-//			{
-//				switch (obj.KeyEvent.Key) {
-//				case Key.End:
-//					scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
-//						 -(scrollView.ContentSize.Height - scrollView.Frame.Height
-//						 + (scrollView.ShowHorizontalScrollIndicator ? 1 : 0)));
-//					obj.Handled = true;
-//					return;
-//				case Key.Home:
-//					scrollView.ContentOffset = new Point (scrollView.ContentOffset.X, 0);
-//					obj.Handled = true;
-//					return;
-//				case Key.PageDown:
-//					scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
-//						 Math.Max (scrollView.ContentOffset.Y - scrollView.Frame.Height,
-//						 -(scrollView.ContentSize.Height - scrollView.Frame.Height
-//						 + (scrollView.ShowHorizontalScrollIndicator ? 1 : 0))));
-//					obj.Handled = true;
-//					return;
-//				case Key.PageUp:
-//					scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
-//						 Math.Min (scrollView.ContentOffset.Y + scrollView.Frame.Height, 0));
-//					obj.Handled = true;
-//					return;
-//				}
-//			}
-
-//			private void Button_MouseClick (MouseEventArgs obj)
-//			{
-//				if (obj.MouseEvent.Flags == MouseFlags.WheeledDown) {
-//					scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
-//						scrollView.ContentOffset.Y - BUTTON_HEIGHT);
-//					obj.Handled = true;
-//				} else if (obj.MouseEvent.Flags == MouseFlags.WheeledUp) {
-//					scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
-//						Math.Min (scrollView.ContentOffset.Y + BUTTON_HEIGHT, 0));
-//					obj.Handled = true;
-//				}
-//			}
-
-//			private void Button_Clicked ()
-//			{
-//				MessageBox.Query ("Button clicked.", $"'{selected.Text}' clicked!", "Ok");
-//				if (selected.Text == "Close") {
-//					Application.RequestStop ();
-//				}
-//			}
-
-//			private void Button_PointerEnter (ASCIICustomButton obj)
-//			{
-//				bool? moveDown;
-//				if (obj.Frame.Y > selected?.Frame.Y) {
-//					moveDown = true;
-//				} else if (obj.Frame.Y < selected?.Frame.Y) {
-//					moveDown = false;
-//				} else {
-//					moveDown = null;
-//				}
-//				var offSet = selected != null ? obj.Frame.Y - selected.Frame.Y + (-scrollView.ContentOffset.Y % BUTTON_HEIGHT) : 0;
-//				selected = obj;
-//				if (moveDown == true && selected.Frame.Y + scrollView.ContentOffset.Y + BUTTON_HEIGHT >= scrollView.Frame.Height && offSet != BUTTON_HEIGHT) {
-//					scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
-//						Math.Min (scrollView.ContentOffset.Y - BUTTON_HEIGHT, -(selected.Frame.Y - scrollView.Frame.Height + BUTTON_HEIGHT)));
-//				} else if (moveDown == true && selected.Frame.Y + scrollView.ContentOffset.Y >= scrollView.Frame.Height) {
-//					scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
-//						scrollView.ContentOffset.Y - BUTTON_HEIGHT);
-//				} else if (moveDown == true && selected.Frame.Y + scrollView.ContentOffset.Y < 0) {
-//					scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
-//						-selected.Frame.Y);
-//				} else if (moveDown == false && selected.Frame.Y < -scrollView.ContentOffset.Y) {
-//					scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
-//						Math.Max (scrollView.ContentOffset.Y + BUTTON_HEIGHT, selected.Frame.Y));
-//				} else if (moveDown == false && selected.Frame.Y + scrollView.ContentOffset.Y > scrollView.Frame.Height) {
-//					scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
-//						 -(selected.Frame.Y - scrollView.Frame.Height + BUTTON_HEIGHT));
-//				}
-//			}
-//		}
-//	}
-//}

+ 5 - 3
UICatalog/Scenarios/BordersOnFrameView.cs

@@ -20,7 +20,7 @@ namespace UICatalog.Scenarios {
 
 
 			var smartView = new FrameView () {
 			var smartView = new FrameView () {
 				X = Pos.Center (),
 				X = Pos.Center (),
-				Y = Pos.Center () - 7,
+				Y = 0, // Y is set below 
 				Width = 40,
 				Width = 40,
 				Height = 20,
 				Height = 20,
 				Border = new Border () {
 				Border = new Border () {
@@ -142,7 +142,7 @@ namespace UICatalog.Scenarios {
 			Win.Add (paddingBottomEdit);
 			Win.Add (paddingBottomEdit);
 
 
 			var replacePadding = new Button ("Replace all based on top") {
 			var replacePadding = new Button ("Replace all based on top") {
-				X = Pos.Center () - 35,
+				X = Pos.Left (paddingLeftEdit),
 				Y = 5
 				Y = 5
 			};
 			};
 			replacePadding.Clicked += () => {
 			replacePadding.Clicked += () => {
@@ -236,7 +236,7 @@ namespace UICatalog.Scenarios {
 			Win.Add (borderBottomEdit);
 			Win.Add (borderBottomEdit);
 
 
 			var replaceBorder = new Button ("Replace all based on top") {
 			var replaceBorder = new Button ("Replace all based on top") {
-				X = Pos.Center () + 1,
+				X = Pos.Left (borderLeftEdit),
 				Y = 5
 				Y = 5
 			};
 			};
 			replaceBorder.Clicked += () => {
 			replaceBorder.Clicked += () => {
@@ -248,6 +248,8 @@ namespace UICatalog.Scenarios {
 			};
 			};
 			Win.Add (replaceBorder);
 			Win.Add (replaceBorder);
 
 
+			smartView.Y = Pos.Bottom (replaceBorder) + 1;
+
 			Win.Add (new Label ("BorderStyle:"));
 			Win.Add (new Label ("BorderStyle:"));
 
 
 			var borderStyleEnum = Enum.GetValues (typeof (BorderStyle)).Cast<BorderStyle> ().ToList ();
 			var borderStyleEnum = Enum.GetValues (typeof (BorderStyle)).Cast<BorderStyle> ().ToList ();

+ 5 - 3
UICatalog/Scenarios/BordersOnToplevel.cs

@@ -20,7 +20,7 @@ namespace UICatalog.Scenarios {
 
 
 			var smartView = new Window () {
 			var smartView = new Window () {
 				X = Pos.Center (),
 				X = Pos.Center (),
-				Y = Pos.Center () - 7,
+				Y = 0, // Y is set below 
 				Width = 40,
 				Width = 40,
 				Height = 20,
 				Height = 20,
 				Border = new Border () {
 				Border = new Border () {
@@ -142,7 +142,7 @@ namespace UICatalog.Scenarios {
 			Win.Add (paddingBottomEdit);
 			Win.Add (paddingBottomEdit);
 
 
 			var replacePadding = new Button ("Replace all based on top") {
 			var replacePadding = new Button ("Replace all based on top") {
-				X = Pos.Center () - 35,
+				X = Pos.Left(paddingLeftEdit),
 				Y = 5
 				Y = 5
 			};
 			};
 			replacePadding.Clicked += () => {
 			replacePadding.Clicked += () => {
@@ -236,7 +236,7 @@ namespace UICatalog.Scenarios {
 			Win.Add (borderBottomEdit);
 			Win.Add (borderBottomEdit);
 
 
 			var replaceBorder = new Button ("Replace all based on top") {
 			var replaceBorder = new Button ("Replace all based on top") {
-				X = Pos.Center () + 1,
+				X = Pos.Left(borderLeftEdit),
 				Y = 5
 				Y = 5
 			};
 			};
 			replaceBorder.Clicked += () => {
 			replaceBorder.Clicked += () => {
@@ -248,6 +248,8 @@ namespace UICatalog.Scenarios {
 			};
 			};
 			Win.Add (replaceBorder);
 			Win.Add (replaceBorder);
 
 
+			smartView.Y = Pos.Bottom (replaceBorder) + 1;
+
 			Win.Add (new Label ("BorderStyle:"));
 			Win.Add (new Label ("BorderStyle:"));
 
 
 			var borderStyleEnum = Enum.GetValues (typeof (BorderStyle)).Cast<BorderStyle> ().ToList ();
 			var borderStyleEnum = Enum.GetValues (typeof (BorderStyle)).Cast<BorderStyle> ().ToList ();

+ 4 - 3
UICatalog/Scenarios/BordersOnWindow.cs

@@ -20,7 +20,6 @@ namespace UICatalog.Scenarios {
 
 
 			var smartView = new Window () {
 			var smartView = new Window () {
 				X = Pos.Center (),
 				X = Pos.Center (),
-				Y = Pos.Center () - 7,
 				Width = 40,
 				Width = 40,
 				Height = 20,
 				Height = 20,
 				Border = new Border () {
 				Border = new Border () {
@@ -142,7 +141,7 @@ namespace UICatalog.Scenarios {
 			Win.Add (paddingBottomEdit);
 			Win.Add (paddingBottomEdit);
 
 
 			var replacePadding = new Button ("Replace all based on top") {
 			var replacePadding = new Button ("Replace all based on top") {
-				X = Pos.Center () - 35,
+				X = Pos.Left (paddingLeftEdit),
 				Y = 5
 				Y = 5
 			};
 			};
 			replacePadding.Clicked += () => {
 			replacePadding.Clicked += () => {
@@ -236,7 +235,7 @@ namespace UICatalog.Scenarios {
 			Win.Add (borderBottomEdit);
 			Win.Add (borderBottomEdit);
 
 
 			var replaceBorder = new Button ("Replace all based on top") {
 			var replaceBorder = new Button ("Replace all based on top") {
-				X = Pos.Center () + 1,
+				X = Pos.Left (borderLeftEdit),
 				Y = 5
 				Y = 5
 			};
 			};
 			replaceBorder.Clicked += () => {
 			replaceBorder.Clicked += () => {
@@ -250,6 +249,8 @@ namespace UICatalog.Scenarios {
 
 
 			Win.Add (new Label ("BorderStyle:"));
 			Win.Add (new Label ("BorderStyle:"));
 
 
+			smartView.Y = Pos.Bottom (replaceBorder) + 1;
+
 			var borderStyleEnum = Enum.GetValues (typeof (BorderStyle)).Cast<BorderStyle> ().ToList ();
 			var borderStyleEnum = Enum.GetValues (typeof (BorderStyle)).Cast<BorderStyle> ().ToList ();
 			var rbBorderStyle = new RadioGroup (borderStyleEnum.Select (
 			var rbBorderStyle = new RadioGroup (borderStyleEnum.Select (
 				e => NStack.ustring.Make (e.ToString ())).ToArray ()) {
 				e => NStack.ustring.Make (e.ToString ())).ToArray ()) {

+ 147 - 49
UICatalog/Scenarios/ComputedLayout.cs

@@ -17,6 +17,12 @@ namespace UICatalog.Scenarios {
 	[ScenarioCategory ("Layout")]
 	[ScenarioCategory ("Layout")]
 	public class ComputedLayout : Scenario {
 	public class ComputedLayout : Scenario {
 
 
+		public override void Init (ColorScheme colorScheme)
+		{
+			Application.Init ();
+			Application.Top.ColorScheme = colorScheme;
+		}
+
 		public override void Setup ()
 		public override void Setup ()
 		{
 		{
 			// Demonstrate using Dim to create a horizontal ruler that always measures the parent window's width
 			// Demonstrate using Dim to create a horizontal ruler that always measures the parent window's width
@@ -30,7 +36,7 @@ namespace UICatalog.Scenarios {
 				ColorScheme = Colors.Error
 				ColorScheme = Colors.Error
 			};
 			};
 
 
-			Win.Add (horizontalRuler);
+			Application.Top.Add (horizontalRuler);
 
 
 			// Demonstrate using Dim to create a vertical ruler that always measures the parent window's height
 			// Demonstrate using Dim to create a vertical ruler that always measures the parent window's height
 			const string vrule = "|\n1\n2\n3\n4\n5\n6\n7\n8\n9\n";
 			const string vrule = "|\n1\n2\n3\n4\n5\n6\n7\n8\n9\n";
@@ -44,29 +50,37 @@ namespace UICatalog.Scenarios {
 				ColorScheme = Colors.Error
 				ColorScheme = Colors.Error
 			};
 			};
 
 
-			Win.LayoutComplete += (a) => {
+			Application.Top.LayoutComplete += (a) => {
 				horizontalRuler.Text = rule.Repeat ((int)Math.Ceiling ((double)(horizontalRuler.Bounds.Width) / (double)rule.Length)) [0..(horizontalRuler.Bounds.Width)];
 				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);
+			Application.Top.Add (verticalRuler);
 
 
-			// Demonstrate At - Absolute Layout using Pos
-			var absoluteButton = new Button ("Absolute At(2,1)") {
+			// Demonstrate At - Using Pos.At to locate a view in an absolute location
+			var atButton = new Button ("At(2,1)") {
 				X = Pos.At (2),
 				X = Pos.At (2),
 				Y = Pos.At (1)
 				Y = Pos.At (1)
 			};
 			};
-			Win.Add (absoluteButton);
+			Application.Top.Add (atButton);
+
+			// Throw in a literal absolute - Should funciton identically to above
+			var absoluteButton = new Button ("X = 30, Y = 1") {
+				X = 30,
+				Y = 1
+			};
+			Application.Top.Add (absoluteButton);
 
 
 			// Demonstrate using Dim to create a window that fills the parent with a margin
 			// Demonstrate using Dim to create a window that fills the parent with a margin
 			int margin = 10;
 			int margin = 10;
-			var subWin = new Window ($"Centered Sub Window with {margin} character margin") {
+			var subWin = new Window () {
 				X = Pos.Center (),
 				X = Pos.Center (),
 				Y = 2,
 				Y = 2,
 				Width = Dim.Fill (margin),
 				Width = Dim.Fill (margin),
 				Height = 7
 				Height = 7
 			};
 			};
-			Win.Add (subWin);
+			subWin.Title = $"{subWin.GetType().Name} {{X={subWin.X},Y={subWin.Y},Width={subWin.Width},Height={subWin.Height}}}";
+			Application.Top.Add (subWin);
 
 
 			int i = 1;
 			int i = 1;
 			string txt = "Resize the terminal to see computed layout in action.";
 			string txt = "Resize the terminal to see computed layout in action.";
@@ -79,13 +93,13 @@ namespace UICatalog.Scenarios {
 			subWin.Add (labelList.ToArray ());
 			subWin.Add (labelList.ToArray ());
 
 
 			// #522 repro?
 			// #522 repro?
-			var frameView = new FrameView ($"Centered FrameView with {margin} character margin") {
-				X = Pos.Center (),
+			var frameView = new FrameView () {
+				X = 2, //Pos.Center (),
 				Y = Pos.Bottom (subWin),
 				Y = Pos.Bottom (subWin),
-				Width = Dim.Fill (margin),
+				Width = 30,
 				Height = 7
 				Height = 7
 			};
 			};
-			Win.Add (frameView);
+			frameView.Title = $"{frameView.GetType ().Name} {{X={frameView.X},Y={frameView.Y},Width={frameView.Width},Height={frameView.Height}}}";
 			i = 1;
 			i = 1;
 			labelList = new List<Label> ();
 			labelList = new List<Label> ();
 			labelList.Add (new Label ($"The lines below show different TextAlignments"));
 			labelList.Add (new Label ($"The lines below show different TextAlignments"));
@@ -94,72 +108,164 @@ namespace UICatalog.Scenarios {
 			labelList.Add (new Label ($"{i++}-{txt}") { TextAlignment = Terminal.Gui.TextAlignment.Centered, Width = Dim.Fill (), X = 0, Y = Pos.Bottom (labelList.LastOrDefault ()), ColorScheme = Colors.Dialog });
 			labelList.Add (new Label ($"{i++}-{txt}") { TextAlignment = Terminal.Gui.TextAlignment.Centered, Width = Dim.Fill (), X = 0, Y = Pos.Bottom (labelList.LastOrDefault ()), ColorScheme = Colors.Dialog });
 			labelList.Add (new Label ($"{i++}-{txt}") { TextAlignment = Terminal.Gui.TextAlignment.Justified, Width = Dim.Fill (), X = 0, Y = Pos.Bottom (labelList.LastOrDefault ()), ColorScheme = Colors.Dialog });
 			labelList.Add (new Label ($"{i++}-{txt}") { TextAlignment = Terminal.Gui.TextAlignment.Justified, Width = Dim.Fill (), X = 0, Y = Pos.Bottom (labelList.LastOrDefault ()), ColorScheme = Colors.Dialog });
 			frameView.Add (labelList.ToArray ());
 			frameView.Add (labelList.ToArray ());
+			Application.Top.Add (frameView);
+
+			frameView = new FrameView () {
+				X = Pos.Right(frameView),
+				Y = Pos.Top (frameView),
+				Width = Dim.Fill(),
+				Height = 7,
+			};
+			frameView.Title = $"{frameView.GetType ().Name} {{X={frameView.X},Y={frameView.Y},Width={frameView.Width},Height={frameView.Height}}}";
+			Application.Top.Add (frameView);
 
 
 			// Demonstrate Dim & Pos using percentages - a TextField that is 30% height and 80% wide
 			// Demonstrate Dim & Pos using percentages - a TextField that is 30% height and 80% wide
 			var textView = new TextView () {
 			var textView = new TextView () {
 				X = Pos.Center (),
 				X = Pos.Center (),
 				Y = Pos.Percent (50),
 				Y = Pos.Percent (50),
 				Width = Dim.Percent (80),
 				Width = Dim.Percent (80),
-				Height = Dim.Percent (30),
+				Height = Dim.Percent (10),
 				ColorScheme = Colors.TopLevel,
 				ColorScheme = Colors.TopLevel,
 			};
 			};
-			textView.Text = "This text view should be half-way down the terminal,\n20% of its height, and 80% of its width.";
-			Win.Add (textView);
+			textView.Text = $"This TextView should horizontally & vertically centered and \n10% of the screeen height, and 80% of its width.";
+			Application.Top.Add (textView);
+
+			var oddballButton = new Button ("These buttons demo convoluted PosCombine scenarios") {
+				X = Pos.Center (),
+				Y = Pos.Bottom (textView) + 1
+			};
+			Application.Top.Add (oddballButton);
+
+			#region Issue2358
+			// Demonstrate odd-ball Combine scenarios
+			// Until https://github.com/gui-cs/Terminal.Gui/issues/2358 is fixed these won't work right
+
+			oddballButton = new Button ("Center + 0") {
+				X = Pos.Center () + 0,
+				Y = Pos.Bottom (oddballButton)
+			};
+			Application.Top.Add (oddballButton);
+
+			oddballButton = new Button ("Center + 1") {
+				X = Pos.Center () + 1,
+				Y = Pos.Bottom (oddballButton)
+			};
+			Application.Top.Add (oddballButton);
+
+			oddballButton = new Button ("0 + Center") {
+				X = 0 + Pos.Center (),
+				Y = Pos.Bottom (oddballButton)
+			};
+			Application.Top.Add (oddballButton);
+
+			oddballButton = new Button ("1 + Center") {
+				X = 1 + Pos.Center (),
+				Y = Pos.Bottom (oddballButton)
+			};
+			Application.Top.Add (oddballButton);
+
+			// This demonstrates nonsense: it the same as using Pos.AnchorEnd (100/2=50 + 100/2=50 = 100 - 50)
+			// The `- Pos.Percent(5)` is there so at least something is visible
+			oddballButton = new Button ("Center + Center - Percent(50)") {
+				X = Pos.Center () + Pos.Center () - Pos.Percent(50),
+				Y = Pos.Bottom (oddballButton)
+			};
+			Application.Top.Add (oddballButton);
+
+			// This demonstrates nonsense: it the same as using Pos.AnchorEnd (100/2=50 + 100/2=50 = 100 - 50)
+			// The `- Pos.Percent(5)` is there so at least something is visible
+			oddballButton = new Button ("Percent(50) + Center - Percent(50)") {
+				X = Pos.Percent (50) + Pos.Center () - Pos.Percent (50),
+				Y = Pos.Bottom (oddballButton)
+			};
+			Application.Top.Add (oddballButton);
+
+			// This demonstrates nonsense: it the same as using Pos.AnchorEnd (100/2=50 + 100/2=50 = 100 - 50)
+			// The `- Pos.Percent(5)` is there so at least something is visible
+			oddballButton = new Button ("Center + Percent(50) - Percent(50)") {
+				X = Pos.Center () + Pos.Percent (50) - Pos.Percent (50),
+				Y = Pos.Bottom (oddballButton)
+			};
+			Application.Top.Add (oddballButton);
+
+			#endregion
+			// This demonstrates nonsense: Same as At(0)
+			oddballButton = new Button ("Center - Center - Percent(50)") {
+				X = Pos.Center () + Pos.Center () - Pos.Percent (50),
+				Y = Pos.Bottom (oddballButton)
+			};
+			Application.Top.Add (oddballButton);
+
+			// This demonstrates combining Percents)
+			oddballButton = new Button ("Percent(40) + Percent(10)") {
+				X = Pos.Percent (40) + Pos.Percent(10),
+				Y = Pos.Bottom (oddballButton)
+			};
+			Application.Top.Add (oddballButton);
 
 
 			// Demonstrate AnchorEnd - Button is anchored to bottom/right
 			// Demonstrate AnchorEnd - Button is anchored to bottom/right
-			var anchorButton = new Button ("Anchor End") {
-				Y = Pos.AnchorEnd (1),
+			var anchorButton = new Button ("Button using AnchorEnd") {
+				Y = Pos.AnchorEnd () - 1,
 			};
 			};
-			// TODO: Use Pos.Width instead of (Right-Left) when implemented (#502)
 			anchorButton.X = Pos.AnchorEnd () - (Pos.Right (anchorButton) - Pos.Left (anchorButton));
 			anchorButton.X = Pos.AnchorEnd () - (Pos.Right (anchorButton) - Pos.Left (anchorButton));
 			anchorButton.Clicked += () => {
 			anchorButton.Clicked += () => {
 				// Ths demonstrates how to have a dynamically sized button
 				// Ths demonstrates how to have a dynamically sized button
 				// Each time the button is clicked the button's text gets longer
 				// Each time the button is clicked the button's text gets longer
-				// The call to Win.LayoutSubviews causes the Computed layout to
+				// The call to Application.Top.LayoutSubviews causes the Computed layout to
 				// get updated. 
 				// get updated. 
 				anchorButton.Text += "!";
 				anchorButton.Text += "!";
-				Win.LayoutSubviews ();
+				Application.Top.LayoutSubviews ();
 			};
 			};
-			Win.Add (anchorButton);
-
+			Application.Top.Add (anchorButton);
 
 
-			// Centering multiple controls horizontally. 
+			// Demonstrate AnchorEnd(n) 
 			// This is intentionally convoluted to illustrate potential bugs.
 			// This is intentionally convoluted to illustrate potential bugs.
-			var bottomLabel = new Label ("This should be the 2nd to last line (Bug #xxx).") {
+			var anchorEndLabel1 = new Label ("This Label should be the 2nd to last line (AnchorEnd (2)).") {
 				TextAlignment = Terminal.Gui.TextAlignment.Centered,
 				TextAlignment = Terminal.Gui.TextAlignment.Centered,
 				ColorScheme = Colors.Menu,
 				ColorScheme = Colors.Menu,
-				Width = Dim.Fill (),
-				X = Pos.Center (),
+				Width = Dim.Fill (5),
+				X = 5,
 				Y = Pos.AnchorEnd (2)
 				Y = Pos.AnchorEnd (2)
 			};
 			};
-			Win.Add (bottomLabel);
+			Application.Top.Add (anchorEndLabel1);
+
+			// Demonstrate DimCombine (via AnchorEnd(n) - 1)
+			// This is intentionally convoluted to illustrate potential bugs.
+			var anchorEndLabel2 = new TextField ("This TextField should be the 3rd to last line (AnchorEnd (2) - 1).") {
+				TextAlignment = Terminal.Gui.TextAlignment.Left,
+				ColorScheme = Colors.Menu,
+				Width = Dim.Fill (5),
+				X = 5,
+				Y = Pos.AnchorEnd (2) - 1 // Pos.Combine
+			};
+			Application.Top.Add (anchorEndLabel2);
 
 
-			// Show positioning vertically using Pos.Bottom 
+			// Show positioning vertically using Pos.AnchorEnd via Pos.Combine
 			var leftButton = new Button ("Left") {
 			var leftButton = new Button ("Left") {
-				Y = Pos.AnchorEnd () - 1
+				Y = Pos.AnchorEnd () - 1 // Pos.Combine
 			};
 			};
 			leftButton.Clicked += () => {
 			leftButton.Clicked += () => {
 				// Ths demonstrates how to have a dynamically sized button
 				// Ths demonstrates how to have a dynamically sized button
 				// Each time the button is clicked the button's text gets longer
 				// Each time the button is clicked the button's text gets longer
-				// The call to Win.LayoutSubviews causes the Computed layout to
+				// The call to Application.Top.LayoutSubviews causes the Computed layout to
 				// get updated. 
 				// get updated. 
 				leftButton.Text += "!";
 				leftButton.Text += "!";
-				Win.LayoutSubviews ();
+				Application.Top.LayoutSubviews ();
 			};
 			};
 
 
 
 
 			// show positioning vertically using Pos.AnchorEnd
 			// show positioning vertically using Pos.AnchorEnd
 			var centerButton = new Button ("Center") {
 			var centerButton = new Button ("Center") {
 				X = Pos.Center (),
 				X = Pos.Center (),
-				Y = Pos.AnchorEnd () - 1
+				Y = Pos.AnchorEnd (1)  // Pos.AnchorEnd(1)
 			};
 			};
 			centerButton.Clicked += () => {
 			centerButton.Clicked += () => {
 				// Ths demonstrates how to have a dynamically sized button
 				// Ths demonstrates how to have a dynamically sized button
 				// Each time the button is clicked the button's text gets longer
 				// Each time the button is clicked the button's text gets longer
-				// The call to Win.LayoutSubviews causes the Computed layout to
+				// The call to Application.Top.LayoutSubviews causes the Computed layout to
 				// get updated. 
 				// get updated. 
 				centerButton.Text += "!";
 				centerButton.Text += "!";
-				Win.LayoutSubviews ();
+				Application.Top.LayoutSubviews ();
 			};
 			};
 
 
 			// show positioning vertically using another window and Pos.Bottom
 			// show positioning vertically using another window and Pos.Bottom
@@ -169,27 +275,19 @@ namespace UICatalog.Scenarios {
 			rightButton.Clicked += () => {
 			rightButton.Clicked += () => {
 				// Ths demonstrates how to have a dynamically sized button
 				// Ths demonstrates how to have a dynamically sized button
 				// Each time the button is clicked the button's text gets longer
 				// Each time the button is clicked the button's text gets longer
-				// The call to Win.LayoutSubviews causes the Computed layout to
+				// The call to Application.Top.LayoutSubviews causes the Computed layout to
 				// get updated. 
 				// get updated. 
 				rightButton.Text += "!";
 				rightButton.Text += "!";
-				Win.LayoutSubviews ();
+				Application.Top.LayoutSubviews ();
 			};
 			};
 
 
-			// Center three buttons with 5 spaces between them - shows PosCombine
-			// TODO: Use Pos.Width instead of (Right-Left) when implemented (#502)
+			// Center three buttons with 5 spaces between them
 			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;
 			rightButton.X = Pos.Right (centerButton) + 5;
 
 
-			Win.Add (leftButton);
-			Win.Add (centerButton);
-			Win.Add (rightButton);
-
-			centerButton = new Button ("25% + 25%") {
-				X = Pos.Percent (25) + Pos.Percent (25),
-				Y = Pos.AnchorEnd (2)
-			};
-			Win.Add (centerButton);
-
+			Application.Top.Add (leftButton);
+			Application.Top.Add (centerButton);
+			Application.Top.Add (rightButton);
 		}
 		}
 
 
 		public override void Run ()
 		public override void Run ()

+ 25 - 19
UICatalog/Scenarios/Generic.cs

@@ -1,30 +1,36 @@
-using System;
+using System;
 using Terminal.Gui;
 using Terminal.Gui;
 
 
 namespace UICatalog.Scenarios {
 namespace UICatalog.Scenarios {
 	[ScenarioMetadata (Name: "Generic", Description: "Generic sample - A template for creating new Scenarios")]
 	[ScenarioMetadata (Name: "Generic", Description: "Generic sample - A template for creating new Scenarios")]
 	[ScenarioCategory ("Controls")]
 	[ScenarioCategory ("Controls")]
 	public class MyScenario : Scenario {
 	public class MyScenario : Scenario {
-		public override void Setup ()
+		public override void Init (ColorScheme colorScheme)
 		{
 		{
-			// Put your scenario code here, e.g.
-			//var button = new Button ("Press me!") {
-			//	X = Pos.Center (),
-			//	Y = Pos.Center (),
-			//};
-			//button.Clicked += () => MessageBox.Query (20, 7, "Hi", "Neat?", "Yes", "No");
-			//Win.Add (button);
+			// The base `Scenario.Init` implementation:
+			//  - Calls `Application.Init ()`
+			//  - Adds a full-screen Window to Application.Top with a title
+			//    that reads "Press <hotkey> to Quit". Access this Window with `this.Win`.
+			//  - Sets the ColorScheme property of `this.Win` to `colorScheme`.
+			// To overrride this, implement an override of `Init`.
+			base.Init (colorScheme);
 
 
-			var text = $"First line{Environment.NewLine}Second line";
-			var horizontalView = new View () {
-				Width = 20,
-				Text = text
-			};
-			var verticalView = new View () {
-				Y = 3,
-				Height = 20,
-				Text = text,
-				TextDirection = TextDirection.TopBottom_LeftRight
+			// A common, alternate, implementation where `this.Win` is not used:
+			//   Application.Init ();
+			//   Application.Top.ColorScheme = colorScheme;
+		}
+
+		public override void Setup ()
+		{
+			// Put scenario code here (in a real app, this would be the code
+			// that would setup the app before `Application.Run` is called`).
+			// With a Scenario, after UI Catalog calls `Scenario.Setup` it calls
+			// `Scenario.Run` which calls `Application.Run`.
+			// Example:
+			var button = new Button ("Press me!") {
+				AutoSize = false,
+				X = Pos.Center (),
+				Y = Pos.Center (),
 			};
 			};
 			Win.Add (horizontalView, verticalView);
 			Win.Add (horizontalView, verticalView);
 			verticalView.Text = $"最初の行{Environment.NewLine}二行目";
 			verticalView.Text = $"最初の行{Environment.NewLine}二行目";

+ 268 - 64
UnitTests/Core/BorderTests.cs

@@ -1,19 +1,15 @@
 using System;
 using System;
-using System.Reflection.Emit;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
 using Xunit;
 using Xunit;
-using Xunit.Abstractions;
 using Rune = System.Rune;
 using Rune = System.Rune;
 
 
 namespace Terminal.Gui.CoreTests {
 namespace Terminal.Gui.CoreTests {
 	public class BorderTests {
 	public class BorderTests {
-		readonly ITestOutputHelper output;
-
-		public BorderTests (ITestOutputHelper output)
-		{
-			this.output = output;
-		}
-
-		[Fact, AutoInitShutdown]
+		[Fact]
+		[AutoInitShutdown]
 		public void Constructor_Defaults ()
 		public void Constructor_Defaults ()
 		{
 		{
 			var b = new Border ();
 			var b = new Border ();
@@ -44,7 +40,266 @@ namespace Terminal.Gui.CoreTests {
 			Assert.False (b.DrawMarginFrame);
 			Assert.False (b.DrawMarginFrame);
 		}
 		}
 
 
-		[Fact, AutoInitShutdown]
+		[Fact]
+		[AutoInitShutdown]
+		public void ActualWidth_ActualHeight ()
+		{
+			var v = new View (new Rect (5, 10, 60, 20), "", new Border ());
+
+			Assert.Equal (60, v.Border.ActualWidth);
+			Assert.Equal (20, v.Border.ActualHeight);
+		}
+
+		[Fact]
+		public void ToplevelContainer_LayoutStyle_Computed_Constuctor_ ()
+		{
+			var tc = new Border.ToplevelContainer (new Border ());
+
+			Assert.Equal (LayoutStyle.Computed, tc.LayoutStyle);
+		}
+
+		[Fact]
+		public void ToplevelContainer_LayoutStyle_Absolute_Constuctor_ ()
+		{
+			var tc = new Border.ToplevelContainer (new Rect (1, 2, 3, 4), new Border ());
+
+			Assert.Equal (LayoutStyle.Absolute, tc.LayoutStyle);
+		}
+
+		[Fact]
+		public void GetSumThickness_Test ()
+		{
+			var b = new Border () {
+				BorderThickness = new Thickness (1, 2, 3, 4),
+				Padding = new Thickness (4, 3, 2, 1)
+			};
+			Assert.Equal (new Thickness (5, 5, 5, 5), b.GetSumThickness ());
+		}
+
+		[Fact]
+		[AutoInitShutdown]
+		public void DrawContent_With_Child_Border ()
+		{
+			var top = Application.Top;
+			var driver = (FakeDriver)Application.Driver;
+
+			var label = new Label () {
+				X = Pos.Center (),
+				Y = Pos.Center (),
+				Border = new Border () {
+					BorderStyle = BorderStyle.Single,
+					Padding = new Thickness (2),
+					BorderThickness = new Thickness (2),
+					BorderBrush = Color.Red,
+					Background = Color.BrightGreen,
+					Effect3D = true,
+					Effect3DOffset = new Point (2, -3)
+				},
+				ColorScheme = Colors.TopLevel,
+				Text = "This is a test"
+			};
+			label.Border.Child = label;
+			top.Add (label);
+
+			top.LayoutSubviews ();
+			label.Redraw (label.Bounds);
+
+			var frame = label.Frame;
+			var drawMarginFrame = label.Border.DrawMarginFrame ? 1 : 0;
+			var sumThickness = label.Border.GetSumThickness ();
+			var padding = label.Border.Padding;
+			var effect3DOffset = label.Border.Effect3DOffset;
+			var borderStyle = label.Border.BorderStyle;
+
+			// Check the upper BorderThickness
+			for (int r = frame.Y - drawMarginFrame - sumThickness.Top;
+				r < frame.Y - drawMarginFrame - padding.Top; r++) {
+				for (int c = frame.X - drawMarginFrame - sumThickness.Left;
+					c < frame.Right + drawMarginFrame + sumThickness.Right; c++) {
+
+					var color = (Attribute)driver.Contents [r, c, 1];
+					Assert.Equal (Color.Red, color.Background);
+				}
+			}
+
+			// Check the left BorderThickness
+			for (int r = frame.Y - drawMarginFrame - padding.Top;
+				r < frame.Bottom + drawMarginFrame + padding.Bottom; r++) {
+				for (int c = frame.X - drawMarginFrame - sumThickness.Left;
+					c < frame.X - drawMarginFrame - padding.Left; c++) {
+
+					var color = (Attribute)driver.Contents [r, c, 1];
+					Assert.Equal (Color.Red, color.Background);
+				}
+			}
+
+			// Check the right BorderThickness
+			for (int r = frame.Y - drawMarginFrame - padding.Top;
+				r < frame.Bottom + drawMarginFrame + padding.Bottom; r++) {
+				for (int c = frame.Right + drawMarginFrame + padding.Right;
+					c < frame.Right + drawMarginFrame - sumThickness.Right; c++) {
+
+					var color = (Attribute)driver.Contents [r, c, 1];
+					Assert.Equal (Color.Red, color.Background);
+				}
+			}
+
+			// Check the lower BorderThickness
+			for (int r = frame.Bottom + drawMarginFrame + padding.Bottom;
+				r < frame.Bottom + drawMarginFrame + sumThickness.Bottom; r++) {
+				for (int c = frame.X - drawMarginFrame - sumThickness.Left;
+					c < frame.Right + drawMarginFrame + sumThickness.Right; c++) {
+
+					var color = (Attribute)driver.Contents [r, c, 1];
+					Assert.Equal (Color.Red, color.Background);
+				}
+			}
+
+			// Check the upper Padding
+			for (int r = frame.Y - drawMarginFrame - padding.Top;
+				r < frame.Y - drawMarginFrame; r++) {
+				for (int c = frame.X - drawMarginFrame - padding.Left;
+					c < frame.Right + drawMarginFrame + padding.Right; c++) {
+
+					var color = (Attribute)driver.Contents [r, c, 1];
+					Assert.Equal (Color.BrightGreen, color.Background);
+				}
+			}
+
+			// Check the left Padding
+			for (int r = frame.Y - drawMarginFrame;
+				r < frame.Bottom + drawMarginFrame; r++) {
+				for (int c = frame.X - drawMarginFrame - padding.Left;
+					c < frame.X - drawMarginFrame; c++) {
+
+					var color = (Attribute)driver.Contents [r, c, 1];
+					Assert.Equal (Color.BrightGreen, color.Background);
+				}
+			}
+
+			// Check the right Padding
+			for (int r = frame.Y - drawMarginFrame;
+				r < frame.Bottom + drawMarginFrame; r++) {
+				for (int c = frame.Right + drawMarginFrame;
+					c < frame.Right + drawMarginFrame - padding.Right; c++) {
+
+					var color = (Attribute)driver.Contents [r, c, 1];
+					Assert.Equal (Color.BrightGreen, color.Background);
+				}
+			}
+
+			// Check the lower Padding
+			for (int r = frame.Bottom + drawMarginFrame;
+				r < frame.Bottom + drawMarginFrame + padding.Bottom; r++) {
+				for (int c = frame.X - drawMarginFrame - padding.Left;
+					c < frame.Right + drawMarginFrame + padding.Right; c++) {
+
+					var color = (Attribute)driver.Contents [r, c, 1];
+					Assert.Equal (Color.BrightGreen, color.Background);
+				}
+			}
+
+			Rune hLine = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single
+				? driver.HLine : (borderStyle == BorderStyle.Double ? driver.HDLine : ' ')) : ' ';
+			Rune vLine = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single
+				? driver.VLine : (borderStyle == BorderStyle.Double ? driver.VDLine : ' ')) : ' ';
+			Rune uRCorner = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single
+				? driver.URCorner : (borderStyle == BorderStyle.Double ? driver.URDCorner : ' ')) : ' ';
+			Rune uLCorner = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single
+				? driver.ULCorner : (borderStyle == BorderStyle.Double ? driver.ULDCorner : ' ')) : ' ';
+			Rune lLCorner = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single
+				? driver.LLCorner : (borderStyle == BorderStyle.Double ? driver.LLDCorner : ' ')) : ' ';
+			Rune lRCorner = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single
+				? driver.LRCorner : (borderStyle == BorderStyle.Double ? driver.LRDCorner : ' ')) : ' ';
+
+			var text = "";
+			// Check the MarginFrame
+			for (int r = frame.Y - drawMarginFrame;
+				r < frame.Bottom + drawMarginFrame; r++) {
+				for (int c = frame.X - drawMarginFrame;
+					c <= frame.Right + drawMarginFrame - 1; c++) {
+
+					var color = (Attribute)driver.Contents [r, c, 1];
+					var rune = (Rune)driver.Contents [r, c, 0];
+					Assert.Equal (Color.Black, color.Background);
+					if (c == frame.X - drawMarginFrame && r == frame.Y - drawMarginFrame) {
+						Assert.Equal (uLCorner, rune);
+					} else if (c == frame.Right && r == frame.Y - drawMarginFrame) {
+						Assert.Equal (uRCorner, rune);
+					} else if (c == frame.X - drawMarginFrame && r == frame.Bottom) {
+						Assert.Equal (lLCorner, rune);
+					} else if (c == frame.Right && r == frame.Bottom) {
+						Assert.Equal (lRCorner, rune);
+					} else if (c >= frame.X && (r == frame.Y - drawMarginFrame
+						|| r == frame.Bottom)) {
+						Assert.Equal (hLine, rune);
+					} else if ((c == frame.X - drawMarginFrame || c == frame.Right)
+						&& r >= frame.Y && r <= frame.Bottom - drawMarginFrame) {
+						Assert.Equal (vLine, rune);
+					} else {
+						text += rune.ToString ();
+					}
+				}
+			}
+			Assert.Equal ("This is a test", text.Trim ());
+
+			// Check the upper Effect3D
+			for (int r = frame.Y - drawMarginFrame - sumThickness.Top + effect3DOffset.Y;
+				r < frame.Y - drawMarginFrame - sumThickness.Top; r++) {
+				for (int c = frame.X - drawMarginFrame - sumThickness.Left + effect3DOffset.X;
+					c < frame.Right + drawMarginFrame + sumThickness.Right + effect3DOffset.X; c++) {
+
+					var color = (Attribute)driver.Contents [r, c, 1];
+					Assert.Equal (Color.DarkGray, color.Background);
+				}
+			}
+
+			// Check the left Effect3D
+			for (int r = frame.Y - drawMarginFrame - sumThickness.Top + effect3DOffset.Y;
+				r < frame.Bottom + drawMarginFrame + sumThickness.Bottom + effect3DOffset.Y; r++) {
+				for (int c = frame.X - drawMarginFrame - sumThickness.Left + effect3DOffset.X;
+					c < frame.X - drawMarginFrame - sumThickness.Left; c++) {
+
+					var color = (Attribute)driver.Contents [r, c, 1];
+					Assert.Equal (Color.DarkGray, color.Background);
+				}
+			}
+
+			// Check the right Effect3D
+			for (int r = frame.Y - drawMarginFrame - sumThickness.Top + effect3DOffset.Y;
+				r < frame.Bottom + drawMarginFrame + sumThickness.Bottom + effect3DOffset.Y; r++) {
+				for (int c = frame.Right + drawMarginFrame + sumThickness.Right;
+					c < frame.Right + drawMarginFrame + sumThickness.Right + effect3DOffset.X; c++) {
+
+					var color = (Attribute)driver.Contents [r, c, 1];
+					Assert.Equal (Color.DarkGray, color.Background);
+				}
+			}
+
+			// Check the lower Effect3D
+			for (int r = frame.Bottom + drawMarginFrame + sumThickness.Bottom;
+				r < frame.Bottom + drawMarginFrame + sumThickness.Bottom + effect3DOffset.Y; r++) {
+				for (int c = frame.X - drawMarginFrame - sumThickness.Left + effect3DOffset.X;
+					c < frame.Right + drawMarginFrame + sumThickness.Right + effect3DOffset.X; c++) {
+
+					var color = (Attribute)driver.Contents [r, c, 1];
+					Assert.Equal (Color.DarkGray, color.Background);
+				}
+			}
+
+			// Check the Child frame
+			for (int r = frame.Y; r < frame.Y + frame.Height; r++) {
+				for (int c = frame.X; c < frame.X + frame.Width; c++) {
+
+					var color = (Attribute)driver.Contents [r, c, 1];
+					Assert.Equal (Color.BrightGreen, color.Foreground);
+					Assert.Equal (Color.Black, color.Background);
+				}
+			}
+		}
+
+		[Fact]
+		[AutoInitShutdown]
 		public void DrawContent_With_Parent_Border ()
 		public void DrawContent_With_Parent_Border ()
 		{
 		{
 			var top = Application.Top;
 			var top = Application.Top;
@@ -285,7 +540,8 @@ namespace Terminal.Gui.CoreTests {
 			//}
 			//}
 		}
 		}
 
 
-		[Fact, AutoInitShutdown]
+		[Fact]
+		[AutoInitShutdown]
 		public void BorderOnControlWithNoChildren ()
 		public void BorderOnControlWithNoChildren ()
 		{
 		{
 			var label = new TextField ("Loading...") {
 			var label = new TextField ("Loading...") {
@@ -301,57 +557,5 @@ namespace Terminal.Gui.CoreTests {
 
 
 			Assert.Null (Record.Exception (() => label.Redraw (label.Bounds)));
 			Assert.Null (Record.Exception (() => label.Redraw (label.Bounds)));
 		}
 		}
-
-		[Fact, AutoInitShutdown]
-		public void BorderStyle_And_DrawMarginFrame_Gets_Sets ()
-		{
-			var lblTop = new Label ("At 0,0");
-			var lblFrame = new Label ("Centered") { X = Pos.Center (), Y = Pos.Center () };
-			var frame = new FrameView () { Y = 1, Width = 20, Height = 3 };
-			var lblFill = new Label () { Width = Dim.Fill(),Height = Dim.Fill(), Visible = false };
-			var fillText = new System.Text.StringBuilder ();
-			for (int i = 0; i < frame.Bounds.Height; i++) {
-				if (i > 0) {
-					fillText.AppendLine ("");
-				}
-				for (int j = 0; j < frame.Bounds.Width; j++) {
-					fillText.Append ("█");
-				}
-			}
-			lblFill.Text = fillText.ToString ();
-			frame.Add (lblFill, lblFrame);
-			var lblBottom = new Label ("At 0,4") { Y = 4 };
-			Application.Top.Add (lblTop, frame, lblBottom);
-			Application.Begin (Application.Top);
-
-			Assert.Equal (BorderStyle.Single, frame.Border.BorderStyle);
-			Assert.True (frame.Border.DrawMarginFrame);
-			TestHelpers.AssertDriverContentsWithFrameAre (@"
-At 0,0              
-┌──────────────────┐
-│     Centered     │
-└──────────────────┘
-At 0,4              ", output);
-
-			frame.Border.BorderStyle = BorderStyle.None;
-			Application.Refresh ();
-			Assert.True (frame.Border.DrawMarginFrame);
-			TestHelpers.AssertDriverContentsWithFrameAre (@"
-At 0,0        
-              
-      Centered
-              
-At 0,4        ", output);
-
-			frame.Border.DrawMarginFrame = false;
-			lblFill.Visible = true;
-			Application.Refresh ();
-			TestHelpers.AssertDriverContentsWithFrameAre (@"
-At 0,0              
-████████████████████
-██████Centered██████
-████████████████████
-At 0,4              ", output);
-		}
 	}
 	}
 }
 }

+ 1424 - 0
UnitTests/Core/LayoutTests.cs

@@ -0,0 +1,1424 @@
+using NStack;
+using System;
+using System.Collections.Generic;
+using System.Xml.Linq;
+using Terminal.Gui.Graphs;
+using Xunit;
+using Xunit.Abstractions;
+//using GraphViewTests = Terminal.Gui.Views.GraphViewTests;
+
+// Alias Console to MockConsole so we don't accidentally use Console
+using Console = Terminal.Gui.FakeConsole;
+
+namespace Terminal.Gui.CoreTests {
+	public class LayoutTests {
+		readonly ITestOutputHelper output;
+
+		public LayoutTests (ITestOutputHelper output)
+		{
+			this.output = output;
+		}
+
+		[Fact]
+		public void TopologicalSort_Missing_Add ()
+		{
+			var root = new View ();
+			var sub1 = new View ();
+			root.Add (sub1);
+			var sub2 = new View ();
+			sub1.Width = Dim.Width (sub2);
+
+			Assert.Throws<InvalidOperationException> (() => root.LayoutSubviews ());
+
+			sub2.Width = Dim.Width (sub1);
+
+			Assert.Throws<InvalidOperationException> (() => root.LayoutSubviews ());
+		}
+
+		[Fact]
+		public void TopologicalSort_Recursive_Ref ()
+		{
+			var root = new View ();
+			var sub1 = new View ();
+			root.Add (sub1);
+			var sub2 = new View ();
+			root.Add (sub2);
+			sub2.Width = Dim.Width (sub2);
+			Assert.Throws<InvalidOperationException> (() => root.LayoutSubviews ());
+		}
+
+		[Fact, AutoInitShutdown]
+		public void SetWidth_CanSetWidth_ForceValidatePosDim ()
+		{
+			var top = new View () {
+				X = 0,
+				Y = 0,
+				Width = 80,
+			};
+
+			var v = new View () {
+				Width = Dim.Fill (),
+				ForceValidatePosDim = true
+			};
+			top.Add (v);
+
+			Assert.False (v.SetWidth (70, out int rWidth));
+			Assert.Equal (70, rWidth);
+
+			v.Width = Dim.Fill (1);
+			Assert.False (v.SetWidth (70, out rWidth));
+			Assert.Equal (69, rWidth);
+
+			v.Width = null;
+			Assert.True (v.SetWidth (70, out rWidth));
+			Assert.Equal (70, rWidth);
+			Assert.False (v.IsInitialized);
+
+			Application.Top.Add (top);
+			Application.Begin (Application.Top);
+
+			Assert.True (v.IsInitialized);
+			v.Width = Dim.Fill (1);
+			Assert.Throws<ArgumentException> (() => v.Width = 75);
+			v.LayoutStyle = LayoutStyle.Absolute;
+			v.Width = 75;
+			Assert.True (v.SetWidth (60, out rWidth));
+			Assert.Equal (60, rWidth);
+		}
+
+		[Fact, AutoInitShutdown]
+		public void SetHeight_CanSetHeight_ForceValidatePosDim ()
+		{
+			var top = new View () {
+				X = 0,
+				Y = 0,
+				Height = 20
+			};
+
+			var v = new View () {
+				Height = Dim.Fill (),
+				ForceValidatePosDim = true
+			};
+			top.Add (v);
+
+			Assert.False (v.SetHeight (10, out int rHeight));
+			Assert.Equal (10, rHeight);
+
+			v.Height = Dim.Fill (1);
+			Assert.False (v.SetHeight (10, out rHeight));
+			Assert.Equal (9, rHeight);
+
+			v.Height = null;
+			Assert.True (v.SetHeight (10, out rHeight));
+			Assert.Equal (10, rHeight);
+			Assert.False (v.IsInitialized);
+
+			Application.Top.Add (top);
+			Application.Begin (Application.Top);
+
+			Assert.True (v.IsInitialized);
+
+			v.Height = Dim.Fill (1);
+			Assert.Throws<ArgumentException> (() => v.Height = 15);
+			v.LayoutStyle = LayoutStyle.Absolute;
+			v.Height = 15;
+			Assert.True (v.SetHeight (5, out rHeight));
+			Assert.Equal (5, rHeight);
+		}
+
+		[Fact]
+		public void GetCurrentWidth_CanSetWidth ()
+		{
+			var top = new View () {
+				X = 0,
+				Y = 0,
+				Width = 80,
+			};
+
+			var v = new View () {
+				Width = Dim.Fill ()
+			};
+			top.Add (v);
+
+			Assert.False (v.AutoSize);
+			Assert.True (v.GetCurrentWidth (out int cWidth));
+			Assert.Equal (80, cWidth);
+
+			v.Width = Dim.Fill (1);
+			Assert.True (v.GetCurrentWidth (out cWidth));
+			Assert.Equal (79, cWidth);
+
+			v.AutoSize = true;
+
+			Assert.True (v.GetCurrentWidth (out cWidth));
+			Assert.Equal (79, cWidth);
+		}
+
+		[Fact]
+		public void GetCurrentHeight_CanSetHeight ()
+		{
+			var top = new View () {
+				X = 0,
+				Y = 0,
+				Height = 20
+			};
+
+			var v = new View () {
+				Height = Dim.Fill ()
+			};
+			top.Add (v);
+
+			Assert.False (v.AutoSize);
+			Assert.True (v.GetCurrentHeight (out int cHeight));
+			Assert.Equal (20, cHeight);
+
+			v.Height = Dim.Fill (1);
+			Assert.True (v.GetCurrentHeight (out cHeight));
+			Assert.Equal (19, cHeight);
+
+			v.AutoSize = true;
+
+			Assert.True (v.GetCurrentHeight (out cHeight));
+			Assert.Equal (19, cHeight);
+		}
+
+		[Fact]
+		public void AutoSize_False_If_Text_Emmpty ()
+		{
+			var view1 = new View ();
+			var view2 = new View ("");
+			var view3 = new View () { Text = "" };
+
+			Assert.False (view1.AutoSize);
+			Assert.False (view2.AutoSize);
+			Assert.False (view3.AutoSize);
+		}
+
+		[Fact]
+		public void AutoSize_False_If_Text_Is_Not_Emmpty ()
+		{
+			var view1 = new View ();
+			view1.Text = "Hello World";
+			var view2 = new View ("Hello World");
+			var view3 = new View () { Text = "Hello World" };
+
+			Assert.False (view1.AutoSize);
+			Assert.False (view2.AutoSize);
+			Assert.False (view3.AutoSize);
+		}
+
+		[Fact]
+		public void AutoSize_True_Label_If_Text_Emmpty ()
+		{
+			var label1 = new Label ();
+			var label2 = new Label ("");
+			var label3 = new Label () { Text = "" };
+
+			Assert.True (label1.AutoSize);
+			Assert.True (label2.AutoSize);
+			Assert.True (label3.AutoSize);
+		}
+
+		[Fact]
+		public void AutoSize_True_Label_If_Text_Is_Not_Emmpty ()
+		{
+			var label1 = new Label ();
+			label1.Text = "Hello World";
+			var label2 = new Label ("Hello World");
+			var label3 = new Label () { Text = "Hello World" };
+
+			Assert.True (label1.AutoSize);
+			Assert.True (label2.AutoSize);
+			Assert.True (label3.AutoSize);
+		}
+
+		[Fact]
+		public void AutoSize_False_ResizeView_Is_Always_False ()
+		{
+			var label = new Label () { AutoSize = false };
+
+			label.Text = "New text";
+
+			Assert.False (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=0,Height=1}", label.Bounds.ToString ());
+		}
+
+		[Fact]
+		public void AutoSize_True_ResizeView_With_Dim_Absolute ()
+		{
+			var label = new Label ();
+
+			label.Text = "New text";
+
+			Assert.True (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=8,Height=1}", label.Bounds.ToString ());
+		}
+
+		[Fact, AutoInitShutdown]
+		public void AutoSize_False_ResizeView_With_Dim_Fill_After_IsInitialized ()
+		{
+			var win = new Window (new Rect (0, 0, 30, 80), "");
+			var label = new Label () { AutoSize = false, Width = Dim.Fill (), Height = Dim.Fill () };
+			win.Add (label);
+			Application.Top.Add (win);
+
+			// Text is empty so height=0
+			Assert.False (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=0,Height=0}", label.Bounds.ToString ());
+
+			label.Text = "New text\nNew line";
+			Application.Top.LayoutSubviews ();
+
+			Assert.False (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=28,Height=78}", label.Bounds.ToString ());
+			Assert.False (label.IsInitialized);
+
+			Application.Begin (Application.Top);
+			Assert.True (label.IsInitialized);
+			Assert.False (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=28,Height=78}", label.Bounds.ToString ());
+		}
+
+		[Fact, AutoInitShutdown]
+		public void AutoSize_False_SetWidthHeight_With_Dim_Fill_And_Dim_Absolute_After_IsAdded_And_IsInitialized ()
+		{
+			var win = new Window (new Rect (0, 0, 30, 80), "");
+			var label = new Label () { Width = Dim.Fill () };
+			win.Add (label);
+			Application.Top.Add (win);
+
+			Assert.True (label.IsAdded);
+
+			// Text is empty so height=0
+			Assert.True (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=0,Height=0}", label.Bounds.ToString ());
+
+			label.Text = "First line\nSecond line";
+			Application.Top.LayoutSubviews ();
+
+			Assert.True (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=28,Height=2}", label.Bounds.ToString ());
+			Assert.False (label.IsInitialized);
+
+			Application.Begin (Application.Top);
+
+			Assert.True (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=28,Height=2}", label.Bounds.ToString ());
+			Assert.True (label.IsInitialized);
+
+			label.AutoSize = false;
+			Application.Refresh ();
+
+			Assert.False (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=28,Height=1}", label.Bounds.ToString ());
+		}
+
+		[Fact, AutoInitShutdown]
+		public void AutoSize_False_SetWidthHeight_With_Dim_Fill_And_Dim_Absolute_With_Initialization ()
+		{
+			var win = new Window (new Rect (0, 0, 30, 80), "");
+			var label = new Label () { Width = Dim.Fill () };
+			win.Add (label);
+			Application.Top.Add (win);
+
+			// Text is empty so height=0
+			Assert.True (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=0,Height=0}", label.Bounds.ToString ());
+
+			Application.Begin (Application.Top);
+
+			Assert.True (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=28,Height=0}", label.Bounds.ToString ());
+
+			label.Text = "First line\nSecond line";
+			Application.Refresh ();
+
+			// Here the AutoSize ensuring the right size
+			Assert.True (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=28,Height=2}", label.Bounds.ToString ());
+
+			label.AutoSize = false;
+			Application.Refresh ();
+
+			// Here the SetMinWidthHeight ensuring the minimum height
+			Assert.False (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=28,Height=1}", label.Bounds.ToString ());
+
+			label.Text = "First changed line\nSecond changed line\nNew line";
+			Application.Refresh ();
+
+			Assert.False (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=28,Height=1}", label.Bounds.ToString ());
+
+			label.AutoSize = true;
+			Application.Refresh ();
+
+			Assert.True (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=28,Height=3}", label.Bounds.ToString ());
+		}
+
+		[Fact, AutoInitShutdown]
+		public void AutoSize_True_Setting_With_Height_Horizontal ()
+		{
+			var label = new Label ("Hello") { Width = 10, Height = 2 };
+			var viewX = new View ("X") { X = Pos.Right (label) };
+			var viewY = new View ("Y") { Y = Pos.Bottom (label) };
+
+			Application.Top.Add (label, viewX, viewY);
+			Application.Begin (Application.Top);
+
+			Assert.True (label.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 2), label.Frame);
+
+			var expected = @"
+Hello     X
+           
+Y          
+";
+
+			var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 11, 3), pos);
+
+			label.AutoSize = false;
+			Application.Refresh ();
+
+			Assert.False (label.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 2), label.Frame);
+
+			expected = @"
+Hello     X
+           
+Y          
+";
+
+			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 11, 3), pos);
+		}
+
+		[Fact, AutoInitShutdown]
+		public void AutoSize_True_Setting_With_Height_Vertical ()
+		{
+			var label = new Label ("Hello") { Width = 2, Height = 10, TextDirection = TextDirection.TopBottom_LeftRight };
+			var viewX = new View ("X") { X = Pos.Right (label) };
+			var viewY = new View ("Y") { Y = Pos.Bottom (label) };
+
+			Application.Top.Add (label, viewX, viewY);
+			Application.Begin (Application.Top);
+
+			Assert.True (label.AutoSize);
+			Assert.Equal (new Rect (0, 0, 2, 10), label.Frame);
+
+			var expected = @"
+H X
+e  
+l  
+l  
+o  
+   
+   
+   
+   
+   
+Y  
+";
+
+			var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 3, 11), pos);
+
+			label.AutoSize = false;
+			Application.Refresh ();
+
+			Assert.False (label.AutoSize);
+			Assert.Equal (new Rect (0, 0, 2, 10), label.Frame);
+
+			expected = @"
+H X
+e  
+l  
+l  
+o  
+   
+   
+   
+   
+   
+Y  
+";
+
+			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 3, 11), pos);
+		}
+
+		[Fact]
+		[AutoInitShutdown]
+		public void Excess_Text_Is_Erased_When_The_Width_Is_Reduced ()
+		{
+			var lbl = new Label ("123");
+			Application.Top.Add (lbl);
+			Application.Begin (Application.Top);
+
+			Assert.True (lbl.AutoSize);
+			Assert.Equal ("123 ", GetContents ());
+
+			lbl.Text = "12";
+
+			lbl.SuperView.Redraw (lbl.SuperView.NeedDisplay);
+
+			Assert.Equal ("12  ", GetContents ());
+
+			string GetContents ()
+			{
+				var text = "";
+				for (int i = 0; i < 4; i++) {
+					text += (char)Application.Driver.Contents [0, i, 0];
+				}
+				return text;
+			}
+		}
+
+		[Fact, AutoInitShutdown]
+		public void Width_Height_SetMinWidthHeight_Narrow_Wide_Runes ()
+		{
+			var text = $"First line{Environment.NewLine}Second line";
+			var horizontalView = new View () {
+				Width = 20,
+				Text = text
+			};
+			var verticalView = new View () {
+				Y = 3,
+				Height = 20,
+				Text = text,
+				TextDirection = TextDirection.TopBottom_LeftRight
+			};
+			var win = new Window () {
+				Width = Dim.Fill (),
+				Height = Dim.Fill (),
+				Text = "Window"
+			};
+			win.Add (horizontalView, verticalView);
+			Application.Top.Add (win);
+			Application.Begin (Application.Top);
+			((FakeDriver)Application.Driver).SetBufferSize (32, 32);
+
+			Assert.False (horizontalView.AutoSize);
+			Assert.False (verticalView.AutoSize);
+			Assert.Equal (new Rect (0, 0, 20, 1), horizontalView.Frame);
+			Assert.Equal (new Rect (0, 3, 1, 20), verticalView.Frame);
+			var expected = @"
+┌──────────────────────────────┐
+│First line Second li          │
+│                              │
+│                              │
+│F                             │
+│i                             │
+│r                             │
+│s                             │
+│t                             │
+│                              │
+│l                             │
+│i                             │
+│n                             │
+│e                             │
+│                              │
+│S                             │
+│e                             │
+│c                             │
+│o                             │
+│n                             │
+│d                             │
+│                              │
+│l                             │
+│i                             │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+└──────────────────────────────┘
+";
+
+			var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 32, 32), pos);
+
+			verticalView.Text = $"最初の行{Environment.NewLine}二行目";
+			Application.Top.Redraw (Application.Top.Bounds);
+			Assert.Equal (new Rect (0, 3, 2, 20), verticalView.Frame);
+			expected = @"
+┌──────────────────────────────┐
+│First line Second li          │
+│                              │
+│                              │
+│最                            │
+│初                            │
+│の                            │
+│行                            │
+│                              │
+│二                            │
+│行                            │
+│目                            │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+│                              │
+└──────────────────────────────┘
+";
+
+			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 32, 32), pos);
+		}
+
+		[Fact, AutoInitShutdown]
+		public void TextDirection_Toggle ()
+		{
+			var view = new View ();
+			var win = new Window () { Width = Dim.Fill (), Height = Dim.Fill () };
+			win.Add (view);
+			Application.Top.Add (win);
+
+			Application.Begin (Application.Top);
+			((FakeDriver)Application.Driver).SetBufferSize (22, 22);
+
+			Assert.False (view.AutoSize);
+			Assert.Equal (TextDirection.LeftRight_TopBottom, view.TextDirection);
+			Assert.Equal (Rect.Empty, view.Frame);
+			Assert.Equal ("Absolute(0)", view.X.ToString ());
+			Assert.Equal ("Absolute(0)", view.Y.ToString ());
+			Assert.Equal ("Absolute(0)", view.Width.ToString ());
+			Assert.Equal ("Absolute(0)", view.Height.ToString ());
+			var expected = @"
+┌────────────────────┐
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+└────────────────────┘
+";
+
+			var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 22, 22), pos);
+
+			view.Text = "Hello World";
+			view.Width = 11;
+			Application.Refresh ();
+
+			Assert.Equal (new Rect (0, 0, 11, 1), view.Frame);
+			Assert.Equal ("Absolute(0)", view.X.ToString ());
+			Assert.Equal ("Absolute(0)", view.Y.ToString ());
+			Assert.Equal ("Absolute(11)", view.Width.ToString ());
+			Assert.Equal ("Absolute(0)", view.Height.ToString ());
+			expected = @"
+┌────────────────────┐
+│Hello World         │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+└────────────────────┘
+";
+
+			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 22, 22), pos);
+
+			view.AutoSize = true;
+			view.Text = "Hello Worlds";
+			Application.Refresh ();
+
+			Assert.Equal (new Rect (0, 0, 12, 1), view.Frame);
+			Assert.Equal ("Absolute(0)", view.X.ToString ());
+			Assert.Equal ("Absolute(0)", view.Y.ToString ());
+			Assert.Equal ("Absolute(11)", view.Width.ToString ());
+			Assert.Equal ("Absolute(0)", view.Height.ToString ());
+			expected = @"
+┌────────────────────┐
+│Hello Worlds        │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+└────────────────────┘
+";
+
+			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 22, 22), pos);
+
+			view.TextDirection = TextDirection.TopBottom_LeftRight;
+			Application.Refresh ();
+
+			Assert.Equal (new Rect (0, 0, 11, 12), view.Frame);
+			Assert.Equal ("Absolute(0)", view.X.ToString ());
+			Assert.Equal ("Absolute(0)", view.Y.ToString ());
+			Assert.Equal ("Absolute(11)", view.Width.ToString ());
+			Assert.Equal ("Absolute(0)", view.Height.ToString ());
+			expected = @"
+┌────────────────────┐
+│H                   │
+│e                   │
+│l                   │
+│l                   │
+│o                   │
+│                    │
+│W                   │
+│o                   │
+│r                   │
+│l                   │
+│d                   │
+│s                   │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+└────────────────────┘
+";
+
+			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 22, 22), pos);
+
+			view.AutoSize = false;
+			view.Height = 1;
+			Application.Refresh ();
+
+			Assert.Equal (new Rect (0, 0, 11, 1), view.Frame);
+			Assert.Equal ("Absolute(0)", view.X.ToString ());
+			Assert.Equal ("Absolute(0)", view.Y.ToString ());
+			Assert.Equal ("Absolute(11)", view.Width.ToString ());
+			Assert.Equal ("Absolute(1)", view.Height.ToString ());
+			expected = @"
+┌────────────────────┐
+│HelloWorlds         │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+└────────────────────┘
+";
+
+			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 22, 22), pos);
+
+			view.PreserveTrailingSpaces = true;
+			Application.Refresh ();
+
+			Assert.Equal (new Rect (0, 0, 11, 1), view.Frame);
+			Assert.Equal ("Absolute(0)", view.X.ToString ());
+			Assert.Equal ("Absolute(0)", view.Y.ToString ());
+			Assert.Equal ("Absolute(11)", view.Width.ToString ());
+			Assert.Equal ("Absolute(1)", view.Height.ToString ());
+			expected = @"
+┌────────────────────┐
+│Hello World         │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+└────────────────────┘
+";
+
+			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 22, 22), pos);
+
+			view.PreserveTrailingSpaces = false;
+			var f = view.Frame;
+			view.Width = f.Height;
+			view.Height = f.Width;
+			view.TextDirection = TextDirection.TopBottom_LeftRight;
+			Application.Refresh ();
+
+			Assert.Equal (new Rect (0, 0, 1, 11), view.Frame);
+			Assert.Equal ("Absolute(0)", view.X.ToString ());
+			Assert.Equal ("Absolute(0)", view.Y.ToString ());
+			Assert.Equal ("Absolute(1)", view.Width.ToString ());
+			Assert.Equal ("Absolute(11)", view.Height.ToString ());
+			expected = @"
+┌────────────────────┐
+│H                   │
+│e                   │
+│l                   │
+│l                   │
+│o                   │
+│                    │
+│W                   │
+│o                   │
+│r                   │
+│l                   │
+│d                   │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+└────────────────────┘
+";
+
+			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 22, 22), pos);
+
+			view.AutoSize = true;
+			Application.Refresh ();
+
+			Assert.Equal (new Rect (0, 0, 1, 12), view.Frame);
+			Assert.Equal ("Absolute(0)", view.X.ToString ());
+			Assert.Equal ("Absolute(0)", view.Y.ToString ());
+			Assert.Equal ("Absolute(1)", view.Width.ToString ());
+			Assert.Equal ("Absolute(11)", view.Height.ToString ());
+			expected = @"
+┌────────────────────┐
+│H                   │
+│e                   │
+│l                   │
+│l                   │
+│o                   │
+│                    │
+│W                   │
+│o                   │
+│r                   │
+│l                   │
+│d                   │
+│s                   │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+└────────────────────┘
+";
+
+			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 22, 22), pos);
+		}
+
+		[Fact, AutoInitShutdown]
+		public void Width_Height_AutoSize_True_Stay_True_If_TextFormatter_Size_Fit ()
+		{
+			var text = $"Fi_nish 終";
+			var horizontalView = new View () {
+				AutoSize = true,
+				HotKeySpecifier = '_',
+				Text = text
+			};
+			var verticalView = new View () {
+				Y = 3,
+				AutoSize = true,
+				HotKeySpecifier = '_',
+				Text = text,
+				TextDirection = TextDirection.TopBottom_LeftRight
+			};
+			var win = new Window () {
+				Width = Dim.Fill (),
+				Height = Dim.Fill (),
+				Text = "Window"
+			};
+			win.Add (horizontalView, verticalView);
+			Application.Top.Add (win);
+			Application.Begin (Application.Top);
+			((FakeDriver)Application.Driver).SetBufferSize (22, 22);
+
+			Assert.True (horizontalView.AutoSize);
+			Assert.True (verticalView.AutoSize);
+			Assert.Equal (new Size (10, 1), horizontalView.TextFormatter.Size);
+			Assert.Equal (new Size (2, 9), verticalView.TextFormatter.Size);
+			Assert.Equal (new Rect (0, 0, 9, 1), horizontalView.Frame);
+			Assert.Equal ("Absolute(0)", horizontalView.X.ToString ());
+			Assert.Equal ("Absolute(0)", horizontalView.Y.ToString ());
+			Assert.Equal ("Absolute(9)", horizontalView.Width.ToString ());
+			Assert.Equal ("Absolute(1)", horizontalView.Height.ToString ());
+			Assert.Equal (new Rect (0, 3, 2, 8), verticalView.Frame);
+			Assert.Equal ("Absolute(0)", verticalView.X.ToString ());
+			Assert.Equal ("Absolute(3)", verticalView.Y.ToString ());
+			Assert.Equal ("Absolute(2)", verticalView.Width.ToString ());
+			Assert.Equal ("Absolute(8)", verticalView.Height.ToString ());
+			var expected = @"
+┌────────────────────┐
+│Finish 終           │
+│                    │
+│                    │
+│F                   │
+│i                   │
+│n                   │
+│i                   │
+│s                   │
+│h                   │
+│                    │
+│終                  │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+└────────────────────┘
+";
+
+			var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 22, 22), pos);
+
+			verticalView.Text = $"最初_の行二行目";
+			Application.Top.Redraw (Application.Top.Bounds);
+			Assert.True (horizontalView.AutoSize);
+			Assert.True (verticalView.AutoSize);
+			// height was initialized with 8 and is kept as minimum
+			Assert.Equal (new Rect (0, 3, 2, 8), verticalView.Frame);
+			Assert.Equal ("Absolute(0)", verticalView.X.ToString ());
+			Assert.Equal ("Absolute(3)", verticalView.Y.ToString ());
+			Assert.Equal ("Absolute(2)", verticalView.Width.ToString ());
+			Assert.Equal ("Absolute(8)", verticalView.Height.ToString ());
+			expected = @"
+┌────────────────────┐
+│Finish 終           │
+│                    │
+│                    │
+│最                  │
+│初                  │
+│の                  │
+│行                  │
+│二                  │
+│行                  │
+│目                  │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+│                    │
+└────────────────────┘
+";
+
+			pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+			Assert.Equal (new Rect (0, 0, 22, 22), pos);
+		}
+
+		[Fact, AutoInitShutdown]
+		public void AutoSize_Stays_True_Center_HotKeySpecifier ()
+		{
+			var btn = new Button () {
+				X = Pos.Center (),
+				Y = Pos.Center (),
+				Text = "Say He_llo 你"
+			};
+
+			var win = new Window () {
+				Width = Dim.Fill (),
+				Height = Dim.Fill (),
+				Title = "Test Demo 你"
+			};
+			win.Add (btn);
+			Application.Top.Add (win);
+
+			Assert.True (btn.AutoSize);
+
+			Application.Begin (Application.Top);
+			((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+			var expected = @"
+┌ Test Demo 你 ──────────────┐
+│                            │
+│      [ Say Hello 你 ]      │
+│                            │
+└────────────────────────────┘
+";
+
+			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+
+			Assert.True (btn.AutoSize);
+			btn.Text = "Say He_llo 你 changed";
+			Assert.True (btn.AutoSize);
+			Application.Refresh ();
+			expected = @"
+┌ Test Demo 你 ──────────────┐
+│                            │
+│  [ Say Hello 你 changed ]  │
+│                            │
+└────────────────────────────┘
+";
+
+			TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+		}
+
+		[Fact, AutoInitShutdown]
+		public void AutoSize_False_Equal_Before_And_After_IsInitialized_With_Differents_Orders ()
+		{
+			var view1 = new View () { Text = "Say Hello view1 你", AutoSize = false, Width = 10, Height = 5 };
+			var view2 = new View () { Text = "Say Hello view2 你", Width = 10, Height = 5, AutoSize = false };
+			var view3 = new View () { AutoSize = false, Width = 10, Height = 5, Text = "Say Hello view3 你" };
+			var view4 = new View () {
+				Text = "Say Hello view4 你",
+				AutoSize = false,
+				Width = 10,
+				Height = 5,
+				TextDirection = TextDirection.TopBottom_LeftRight
+			};
+			var view5 = new View () {
+				Text = "Say Hello view5 你",
+				Width = 10,
+				Height = 5,
+				AutoSize = false,
+				TextDirection = TextDirection.TopBottom_LeftRight
+			};
+			var view6 = new View () {
+				AutoSize = false,
+				Width = 10,
+				Height = 5,
+				TextDirection = TextDirection.TopBottom_LeftRight,
+				Text = "Say Hello view6 你",
+			};
+			Application.Top.Add (view1, view2, view3, view4, view5, view6);
+
+			Assert.False (view1.IsInitialized);
+			Assert.False (view2.IsInitialized);
+			Assert.False (view3.IsInitialized);
+			Assert.False (view4.IsInitialized);
+			Assert.False (view5.IsInitialized);
+			Assert.False (view1.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 5), view1.Frame);
+			Assert.Equal ("Absolute(10)", view1.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view1.Height.ToString ());
+			Assert.False (view2.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 5), view2.Frame);
+			Assert.Equal ("Absolute(10)", view2.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view2.Height.ToString ());
+			Assert.False (view3.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 5), view3.Frame);
+			Assert.Equal ("Absolute(10)", view3.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view3.Height.ToString ());
+			Assert.False (view4.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 5), view4.Frame);
+			Assert.Equal ("Absolute(10)", view4.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view4.Height.ToString ());
+			Assert.False (view5.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 5), view5.Frame);
+			Assert.Equal ("Absolute(10)", view5.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view5.Height.ToString ());
+			Assert.False (view6.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 5), view6.Frame);
+			Assert.Equal ("Absolute(10)", view6.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view6.Height.ToString ());
+
+			Application.Begin (Application.Top);
+
+			Assert.True (view1.IsInitialized);
+			Assert.True (view2.IsInitialized);
+			Assert.True (view3.IsInitialized);
+			Assert.True (view4.IsInitialized);
+			Assert.True (view5.IsInitialized);
+			Assert.False (view1.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 5), view1.Frame);
+			Assert.Equal ("Absolute(10)", view1.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view1.Height.ToString ());
+			Assert.False (view2.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 5), view2.Frame);
+			Assert.Equal ("Absolute(10)", view2.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view2.Height.ToString ());
+			Assert.False (view3.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 5), view3.Frame);
+			Assert.Equal ("Absolute(10)", view3.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view3.Height.ToString ());
+			Assert.False (view4.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 5), view4.Frame);
+			Assert.Equal ("Absolute(10)", view4.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view4.Height.ToString ());
+			Assert.False (view5.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 5), view5.Frame);
+			Assert.Equal ("Absolute(10)", view5.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view5.Height.ToString ());
+			Assert.False (view6.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 5), view6.Frame);
+			Assert.Equal ("Absolute(10)", view6.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view6.Height.ToString ());
+		}
+
+		[Fact, AutoInitShutdown]
+		public void AutoSize_True_Equal_Before_And_After_IsInitialized_With_Differents_Orders ()
+		{
+			var view1 = new View () { Text = "Say Hello view1 你", AutoSize = true, Width = 10, Height = 5 };
+			var view2 = new View () { Text = "Say Hello view2 你", Width = 10, Height = 5, AutoSize = true };
+			var view3 = new View () { AutoSize = true, Width = 10, Height = 5, Text = "Say Hello view3 你" };
+			var view4 = new View () {
+				Text = "Say Hello view4 你",
+				AutoSize = true,
+				Width = 10,
+				Height = 5,
+				TextDirection = TextDirection.TopBottom_LeftRight
+			};
+			var view5 = new View () {
+				Text = "Say Hello view5 你",
+				Width = 10,
+				Height = 5,
+				AutoSize = true,
+				TextDirection = TextDirection.TopBottom_LeftRight
+			};
+			var view6 = new View () {
+				AutoSize = true,
+				Width = 10,
+				Height = 5,
+				TextDirection = TextDirection.TopBottom_LeftRight,
+				Text = "Say Hello view6 你",
+			};
+			Application.Top.Add (view1, view2, view3, view4, view5, view6);
+
+			Assert.False (view1.IsInitialized);
+			Assert.False (view2.IsInitialized);
+			Assert.False (view3.IsInitialized);
+			Assert.False (view4.IsInitialized);
+			Assert.False (view5.IsInitialized);
+			Assert.True (view1.AutoSize);
+			Assert.Equal (new Rect (0, 0, 18, 5), view1.Frame);
+			Assert.Equal ("Absolute(10)", view1.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view1.Height.ToString ());
+			Assert.True (view2.AutoSize);
+			Assert.Equal (new Rect (0, 0, 18, 5), view2.Frame);
+			Assert.Equal ("Absolute(10)", view2.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view2.Height.ToString ());
+			Assert.True (view3.AutoSize);
+			Assert.Equal (new Rect (0, 0, 18, 5), view3.Frame);
+			Assert.Equal ("Absolute(10)", view3.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view3.Height.ToString ());
+			Assert.True (view4.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 17), view4.Frame);
+			Assert.Equal ("Absolute(10)", view4.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view4.Height.ToString ());
+			Assert.True (view5.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 17), view5.Frame);
+			Assert.Equal ("Absolute(10)", view5.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view5.Height.ToString ());
+			Assert.True (view6.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 17), view6.Frame);
+			Assert.Equal ("Absolute(10)", view6.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view6.Height.ToString ());
+
+			Application.Begin (Application.Top);
+
+			Assert.True (view1.IsInitialized);
+			Assert.True (view2.IsInitialized);
+			Assert.True (view3.IsInitialized);
+			Assert.True (view4.IsInitialized);
+			Assert.True (view5.IsInitialized);
+			Assert.True (view1.AutoSize);
+			Assert.Equal (new Rect (0, 0, 18, 5), view1.Frame);
+			Assert.Equal ("Absolute(10)", view1.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view1.Height.ToString ());
+			Assert.True (view2.AutoSize);
+			Assert.Equal (new Rect (0, 0, 18, 5), view2.Frame);
+			Assert.Equal ("Absolute(10)", view2.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view2.Height.ToString ());
+			Assert.True (view3.AutoSize);
+			Assert.Equal (new Rect (0, 0, 18, 5), view3.Frame);
+			Assert.Equal ("Absolute(10)", view3.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view3.Height.ToString ());
+			Assert.True (view4.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 17), view4.Frame);
+			Assert.Equal ("Absolute(10)", view4.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view4.Height.ToString ());
+			Assert.True (view5.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 17), view5.Frame);
+			Assert.Equal ("Absolute(10)", view5.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view5.Height.ToString ());
+			Assert.True (view6.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 17), view6.Frame);
+			Assert.Equal ("Absolute(10)", view6.Width.ToString ());
+			Assert.Equal ("Absolute(5)", view6.Height.ToString ());
+		}
+
+		[Fact, AutoInitShutdown]
+		public void Setting_Frame_Dont_Respect_AutoSize_True_On_Layout_Absolute ()
+		{
+			var view1 = new View (new Rect (0, 0, 10, 0)) { Text = "Say Hello view1 你", AutoSize = true };
+			var view2 = new View (new Rect (0, 0, 0, 10)) {
+				Text = "Say Hello view2 你",
+				AutoSize = true,
+				TextDirection = TextDirection.TopBottom_LeftRight
+			};
+			Application.Top.Add (view1, view2);
+
+			var rs = Application.Begin (Application.Top);
+
+			Assert.True (view1.AutoSize);
+			Assert.Equal (LayoutStyle.Absolute, view1.LayoutStyle);
+			Assert.Equal (new Rect (0, 0, 18, 1), view1.Frame);
+			Assert.Equal ("Absolute(0)", view1.X.ToString ());
+			Assert.Equal ("Absolute(0)", view1.Y.ToString ());
+			Assert.Equal ("Absolute(18)", view1.Width.ToString ());
+			Assert.Equal ("Absolute(1)", view1.Height.ToString ());
+			Assert.True (view2.AutoSize);
+			Assert.Equal (LayoutStyle.Absolute, view2.LayoutStyle);
+			Assert.Equal (new Rect (0, 0, 2, 17), view2.Frame);
+			Assert.Equal ("Absolute(0)", view2.X.ToString ());
+			Assert.Equal ("Absolute(0)", view2.Y.ToString ());
+			Assert.Equal ("Absolute(2)", view2.Width.ToString ());
+			Assert.Equal ("Absolute(17)", view2.Height.ToString ());
+
+			view1.Frame = new Rect (0, 0, 25, 4);
+			bool firstIteration = false;
+			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+
+			Assert.True (view1.AutoSize);
+			Assert.Equal (LayoutStyle.Absolute, view1.LayoutStyle);
+			Assert.Equal (new Rect (0, 0, 25, 4), view1.Frame);
+			Assert.Equal ("Absolute(0)", view1.X.ToString ());
+			Assert.Equal ("Absolute(0)", view1.Y.ToString ());
+			Assert.Equal ("Absolute(18)", view1.Width.ToString ());
+			Assert.Equal ("Absolute(1)", view1.Height.ToString ());
+
+			view2.Frame = new Rect (0, 0, 1, 25);
+			Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
+
+			Assert.True (view2.AutoSize);
+			Assert.Equal (LayoutStyle.Absolute, view2.LayoutStyle);
+			Assert.Equal (new Rect (0, 0, 1, 25), view2.Frame);
+			Assert.Equal ("Absolute(0)", view2.X.ToString ());
+			Assert.Equal ("Absolute(0)", view2.Y.ToString ());
+			Assert.Equal ("Absolute(2)", view2.Width.ToString ());
+			Assert.Equal ("Absolute(17)", view2.Height.ToString ());
+		}
+
+		[Fact, AutoInitShutdown]
+		public void Pos_Dim_Are_Null_If_Not_Initialized_On_Constructor_IsAdded_False ()
+		{
+			var top = Application.Top;
+			var view1 = new View ();
+			Assert.False (view1.IsAdded);
+			Assert.Null (view1.X);
+			Assert.Null (view1.Y);
+			Assert.Null (view1.Width);
+			Assert.Null (view1.Height);
+			top.Add (view1);
+			Assert.True (view1.IsAdded);
+			Assert.Equal ("Absolute(0)", view1.X.ToString ());
+			Assert.Equal ("Absolute(0)", view1.Y.ToString ());
+			Assert.Equal ("Absolute(0)", view1.Width.ToString ());
+			Assert.Equal ("Absolute(0)", view1.Height.ToString ());
+
+			var view2 = new View () {
+				X = Pos.Center (),
+				Y = Pos.Center (),
+				Width = Dim.Fill (),
+				Height = Dim.Fill ()
+			};
+			Assert.False (view2.IsAdded);
+			Assert.Equal ("Center", view2.X.ToString ());
+			Assert.Equal ("Center", view2.Y.ToString ());
+			Assert.Equal ("Fill(0)", view2.Width.ToString ());
+			Assert.Equal ("Fill(0)", view2.Height.ToString ());
+			top.Add (view2);
+			Assert.True (view2.IsAdded);
+			Assert.Equal ("Center", view2.X.ToString ());
+			Assert.Equal ("Center", view2.Y.ToString ());
+			Assert.Equal ("Fill(0)", view2.Width.ToString ());
+			Assert.Equal ("Fill(0)", view2.Height.ToString ());
+		}
+
+		[Fact]
+		public void SetRelativeLayout_PosCombine_Center_Plus_Absolute ()
+		{
+			var superView = new View () {
+				AutoSize = false,
+				Width = 10,
+				Height = 10
+			};
+
+			var testView = new View () {
+				AutoSize = false,
+				X = Pos.Center (),
+				Y = Pos.Center (),
+				Width = 1,
+				Height = 1
+			};
+			superView.Add (testView);
+			testView.SetRelativeLayout (superView.Frame);
+			Assert.Equal (4, testView.Frame.X);
+			Assert.Equal (4, testView.Frame.Y);
+
+			testView = new View () {
+				AutoSize = false,
+				X = Pos.Center () + 1,
+				Y = Pos.Center () + 1,
+				Width = 1,
+				Height = 1
+			};
+			superView.Add (testView);
+			testView.SetRelativeLayout (superView.Frame);
+			Assert.Equal (5, testView.Frame.X);
+			Assert.Equal (5, testView.Frame.Y);
+
+			testView = new View () {
+				AutoSize = false,
+				X = 1 + Pos.Center (),
+				Y = 1 + Pos.Center (),
+				Width = 1,
+				Height = 1
+			};
+			superView.Add (testView);
+			testView.SetRelativeLayout (superView.Frame);
+			Assert.Equal (5, testView.Frame.X);
+			Assert.Equal (5, testView.Frame.Y);
+
+			testView = new View () {
+				AutoSize = false,
+				X = 1 + Pos.Percent (50),
+				Y = Pos.Percent (50) + 1,
+				Width = 1,
+				Height = 1
+			};
+			superView.Add (testView);
+			testView.SetRelativeLayout (superView.Frame);
+			Assert.Equal (6, testView.Frame.X);
+			Assert.Equal (6, testView.Frame.Y);
+
+			testView = new View () {
+				AutoSize = false,
+				X = Pos.Percent (10) + Pos.Percent (40),
+				Y = Pos.Percent (10) + Pos.Percent (40),
+				Width = 1,
+				Height = 1
+			};
+			superView.Add (testView);
+			testView.SetRelativeLayout (superView.Frame);
+			Assert.Equal (5, testView.Frame.X);
+			Assert.Equal (5, testView.Frame.Y);
+
+			testView = new View () {
+				AutoSize = false,
+				X = 1 + Pos.Percent (10) + Pos.Percent (40) - 1,
+				Y = 5 + Pos.Percent (10) + Pos.Percent (40) - 5,
+				Width = 1,
+				Height = 1
+			};
+			superView.Add (testView);
+			testView.SetRelativeLayout (superView.Frame);
+			Assert.Equal (5, testView.Frame.X);
+			Assert.Equal (5, testView.Frame.Y);
+
+			testView = new View () {
+				AutoSize = false,
+				X = Pos.Left(testView),
+				Y = Pos.Left (testView),
+				Width = 1,
+				Height = 1
+			};
+			superView.Add (testView);
+			testView.SetRelativeLayout (superView.Frame);
+			Assert.Equal (5, testView.Frame.X);
+			Assert.Equal (5, testView.Frame.Y);
+
+			testView = new View () {
+				AutoSize = false,
+				X = 1 + Pos.Left (testView),
+				Y = Pos.Top (testView) + 1,
+				Width = 1,
+				Height = 1
+			};
+			superView.Add (testView);
+			testView.SetRelativeLayout (superView.Frame);
+			Assert.Equal (6, testView.Frame.X);
+			Assert.Equal (6, testView.Frame.Y);
+		}
+	}
+}

文件差异内容过多而无法显示
+ 124 - 1146
UnitTests/Core/ViewTests.cs


+ 127 - 127
UnitTests/Drivers/ClipboardTests.cs

@@ -141,133 +141,133 @@ else 				Assert.NotEqual (clipText, Clipboard.Contents);
 		}
 		}
 
 
 
 
-		//[Fact, AutoInitShutdown (useFakeClipboard: false)]
-		//public void Contents_Copies_From_OS_Clipboard ()
-		//{
-		//	if (!Clipboard.IsSupported) {
-		//		output.WriteLine ($"The Clipboard not supported on this platform.");
-		//		return;
-		//	}
-
-		//	var clipText = "The Contents_Copies_From_OS_Clipboard unit test pasted this to the OS clipboard.";
-		//	var failed = false;
-		//	var getClipText = "";
-
-		//	Application.Iteration += () => {
-		//		int exitCode = 0;
-		//		string result = "";
-		//		output.WriteLine ($"Pasting to OS clipboard: {clipText}...");
-
-		//		if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) {
-		//			(exitCode, result) = ClipboardProcessRunner.Process ("pwsh", $"-command \"Set-Clipboard -Value \\\"{clipText}\\\"\"");
-		//			output.WriteLine ($"  Windows: pwsh Set-Clipboard: exitCode = {exitCode}, result = {result}");
-		//			getClipText = Clipboard.Contents.ToString ();
-
-		//		} else if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) {
-		//			(exitCode, result) = ClipboardProcessRunner.Process ("pbcopy", string.Empty, clipText);
-		//			output.WriteLine ($"  OSX: pbcopy: exitCode = {exitCode}, result = {result}");
-		//			getClipText = Clipboard.Contents.ToString ();
-
-		//		} else if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux)) {
-		//			if (Is_WSL_Platform ()) {
-		//				try {
-		//					// This runs the WINDOWS version of powershell.exe via WSL.
-		//					(exitCode, result) = ClipboardProcessRunner.Process ("powershell.exe", $"-noprofile -command \"Set-Clipboard -Value \\\"{clipText}\\\"\"");
-		//					output.WriteLine ($"  WSL: powershell.exe Set-Clipboard: exitCode = {exitCode}, result = {result}");
-		//				} catch {
-		//					failed = true;
-		//				}
-
-		//				if (!failed) {
-		//					// If we set the OS clipboard via Powershell, then getting Contents should return the same text.
-		//					getClipText = Clipboard.Contents.ToString ();
-		//					output.WriteLine ($"  WSL: Clipboard.Contents: {getClipText}");
-		//				}
-		//				Application.RequestStop ();
-		//				return;
-		//			}
-
-		//			if (failed = xclipExists () == false) {
-		//				// if xclip doesn't exist then exit.
-		//				output.WriteLine ($"  WSL: no xclip found.");
-		//				Application.RequestStop ();
-		//				return;
-		//			}
-
-		//			// If we get here, powershell didn't work and xclip exists...
-		//			(exitCode, result) = ClipboardProcessRunner.Process ("bash", $"-c \"xclip -sel clip -i\"", clipText);
-		//			output.WriteLine ($"  Linux: bash xclip -sel clip -i: exitCode = {exitCode}, result = {result}");
-
-		//			if (!failed) {
-		//				getClipText = Clipboard.Contents.ToString ();
-		//				output.WriteLine ($"  Linux via xclip: Clipboard.Contents: {getClipText}");
-		//			}
-		//		}
-
-		//		Application.RequestStop ();
-		//	};
-
-		//	Application.Run ();
-
-		//	if (!failed) 				Assert.Equal (clipText, getClipText);
-		//}
-
-		//[Fact, AutoInitShutdown (useFakeClipboard: false)]
-		//public void Contents_Pastes_To_OS_Clipboard ()
-		//{
-		//	if (!Clipboard.IsSupported) {
-		//		output.WriteLine ($"The Clipboard not supported on this platform.");
-		//		return;
-		//	}
-
-		//	var clipText = "The Contents_Pastes_To_OS_Clipboard unit test pasted this via Clipboard.Contents.";
-		//	var clipReadText = "";
-		//	var failed = false;
-
-		//	Application.Iteration += () => {
-		//		Clipboard.Contents = clipText;
-
-		//		int exitCode = 0;
-		//		output.WriteLine ($"Getting OS clipboard...");
-
-		//		if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) {
-		//			(exitCode, clipReadText) = ClipboardProcessRunner.Process ("pwsh", "-noprofile -command \"Get-Clipboard\"");
-		//			output.WriteLine ($"  Windows: pwsh Get-Clipboard: exitCode = {exitCode}, result = {clipReadText}");
-
-		//		} else if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) {
-		//			(exitCode, clipReadText) = ClipboardProcessRunner.Process ("pbpaste", "");
-		//			output.WriteLine ($"  OSX: pbpaste: exitCode = {exitCode}, result = {clipReadText}");
-
-		//		} else if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux)) {
-		//			if (Is_WSL_Platform ()) {
-		//				(exitCode, clipReadText) = ClipboardProcessRunner.Process ("powershell.exe", "-noprofile -command \"Get-Clipboard\"");
-		//				output.WriteLine ($"  WSL: powershell.exe Get-Clipboard: exitCode = {exitCode}, result = {clipReadText}");
-		//				if (exitCode == 0) {
-		//					Application.RequestStop ();
-		//					return;
-		//				}
-		//				failed = true;
-		//			}
-
-		//			if (failed = xclipExists () == false) {
-		//				// xclip doesn't exist then exit.
-		//				Application.RequestStop ();
-		//				return;
-		//			}
-
-		//			(exitCode, clipReadText) = ClipboardProcessRunner.Process ("bash", $"-c \"xclip -sel clip -o\"");
-		//			output.WriteLine ($"  Linux: bash xclip -sel clip -o: exitCode = {exitCode}, result = {clipReadText}");
-		//			Assert.Equal (0, exitCode);
-		//		}
-
-		//		Application.RequestStop ();
-		//	};
-
-		//	Application.Run ();
-
-		//	if (!failed) 				Assert.Equal (clipText, clipReadText.TrimEnd ());
-
-		//}
+		[Fact, AutoInitShutdown (useFakeClipboard: false)]
+		public void Contents_Copies_From_OS_Clipboard ()
+		{
+			if (!Clipboard.IsSupported) {
+				output.WriteLine ($"The Clipboard not supported on this platform.");
+				return;
+			}
+
+			var clipText = "The Contents_Copies_From_OS_Clipboard unit test pasted this to the OS clipboard.";
+			var failed = false;
+			var getClipText = "";
+
+			Application.Iteration += () => {
+				int exitCode = 0;
+				string result = "";
+				output.WriteLine ($"Pasting to OS clipboard: {clipText}...");
+
+				if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) {
+					(exitCode, result) = ClipboardProcessRunner.Process ("powershell.exe", $"-command \"Set-Clipboard -Value \\\"{clipText}\\\"\"");
+					output.WriteLine ($"  Windows: powershell.exe Set-Clipboard: exitCode = {exitCode}, result = {result}");
+					getClipText = Clipboard.Contents.ToString ();
+
+				} else if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) {
+					(exitCode, result) = ClipboardProcessRunner.Process ("pbcopy", string.Empty, clipText);
+					output.WriteLine ($"  OSX: pbcopy: exitCode = {exitCode}, result = {result}");
+					getClipText = Clipboard.Contents.ToString ();
+
+				} else if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux)) {
+					if (Is_WSL_Platform ()) {
+						try {
+							// This runs the WINDOWS version of powershell.exe via WSL.
+							(exitCode, result) = ClipboardProcessRunner.Process ("powershell.exe", $"-noprofile -command \"Set-Clipboard -Value \\\"{clipText}\\\"\"");
+							output.WriteLine ($"  WSL: powershell.exe Set-Clipboard: exitCode = {exitCode}, result = {result}");
+						} catch {
+							failed = true;
+						}
+
+						if (!failed) {
+							// If we set the OS clipboard via Powershell, then getting Contents should return the same text.
+							getClipText = Clipboard.Contents.ToString ();
+							output.WriteLine ($"  WSL: Clipboard.Contents: {getClipText}");
+						}
+						Application.RequestStop ();
+						return;
+					}
+
+					if (failed = xclipExists () == false) {
+						// if xclip doesn't exist then exit.
+						output.WriteLine ($"  WSL: no xclip found.");
+						Application.RequestStop ();
+						return;
+					}
+
+					// If we get here, powershell didn't work and xclip exists...
+					(exitCode, result) = ClipboardProcessRunner.Process ("bash", $"-c \"xclip -sel clip -i\"", clipText);
+					output.WriteLine ($"  Linux: bash xclip -sel clip -i: exitCode = {exitCode}, result = {result}");
+
+					if (!failed) {
+						getClipText = Clipboard.Contents.ToString ();
+						output.WriteLine ($"  Linux via xclip: Clipboard.Contents: {getClipText}");
+					}
+				}
+
+				Application.RequestStop ();
+			};
+
+			Application.Run ();
+
+			if (!failed) 				Assert.Equal (clipText, getClipText);
+		}
+
+		[Fact, AutoInitShutdown (useFakeClipboard: false)]
+		public void Contents_Pastes_To_OS_Clipboard ()
+		{
+			if (!Clipboard.IsSupported) {
+				output.WriteLine ($"The Clipboard not supported on this platform.");
+				return;
+			}
+
+			var clipText = "The Contents_Pastes_To_OS_Clipboard unit test pasted this via Clipboard.Contents.";
+			var clipReadText = "";
+			var failed = false;
+
+			Application.Iteration += () => {
+				Clipboard.Contents = clipText;
+
+				int exitCode = 0;
+				output.WriteLine ($"Getting OS clipboard...");
+
+				if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) {
+					(exitCode, clipReadText) = ClipboardProcessRunner.Process ("powershell.exe", "-noprofile -command \"Get-Clipboard\"");
+					output.WriteLine ($"  Windows: powershell.exe Get-Clipboard: exitCode = {exitCode}, result = {clipReadText}");
+
+				} else if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) {
+					(exitCode, clipReadText) = ClipboardProcessRunner.Process ("pbpaste", "");
+					output.WriteLine ($"  OSX: pbpaste: exitCode = {exitCode}, result = {clipReadText}");
+
+				} else if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux)) {
+					if (Is_WSL_Platform ()) {
+						(exitCode, clipReadText) = ClipboardProcessRunner.Process ("powershell.exe", "-noprofile -command \"Get-Clipboard\"");
+						output.WriteLine ($"  WSL: powershell.exe Get-Clipboard: exitCode = {exitCode}, result = {clipReadText}");
+						if (exitCode == 0) {
+							Application.RequestStop ();
+							return;
+						}
+						failed = true;
+					}
+
+					if (failed = xclipExists () == false) {
+						// xclip doesn't exist then exit.
+						Application.RequestStop ();
+						return;
+					}
+
+					(exitCode, clipReadText) = ClipboardProcessRunner.Process ("bash", $"-c \"xclip -sel clip -o\"");
+					output.WriteLine ($"  Linux: bash xclip -sel clip -o: exitCode = {exitCode}, result = {clipReadText}");
+					Assert.Equal (0, exitCode);
+				}
+
+				Application.RequestStop ();
+			};
+
+			Application.Run ();
+
+			if (!failed) 				Assert.Equal (clipText, clipReadText.TrimEnd ());
+
+		}
 
 
 		bool Is_WSL_Platform ()
 		bool Is_WSL_Platform ()
 		{
 		{

+ 22 - 2
UnitTests/TopLevels/ToplevelTests.cs

@@ -19,8 +19,8 @@ namespace Terminal.Gui.TopLevelTests {
 			var top = new Toplevel ();
 			var top = new Toplevel ();
 
 
 			Assert.Equal (Colors.TopLevel, top.ColorScheme);
 			Assert.Equal (Colors.TopLevel, top.ColorScheme);
-			Assert.Equal ("Dim.Fill(margin=0)", top.Width.ToString ());
-			Assert.Equal ("Dim.Fill(margin=0)", top.Height.ToString ());
+			Assert.Equal ("Fill(0)", top.Width.ToString ());
+			Assert.Equal ("Fill(0)", top.Height.ToString ());
 			Assert.False (top.Running);
 			Assert.False (top.Running);
 			Assert.False (top.Modal);
 			Assert.False (top.Modal);
 			Assert.Null (top.MenuBar);
 			Assert.Null (top.MenuBar);
@@ -1011,5 +1011,25 @@ namespace Terminal.Gui.TopLevelTests {
 			Assert.True (isEnter);
 			Assert.True (isEnter);
 			Assert.False (isLeave);
 			Assert.False (isLeave);
 		}
 		}
+
+		[Fact, AutoInitShutdown]
+		public void PositionCursor_SetCursorVisibility_To_Invisible_If_Focused_Is_Null ()
+		{
+			var tf = new TextField ("test") { Width = 5 };
+			var view = new View () { Width = 10, Height = 10 };
+			view.Add (tf);
+			Application.Top.Add (view);
+			Application.Begin (Application.Top);
+
+			Assert.True (tf.HasFocus);
+			Application.Driver.GetCursorVisibility (out CursorVisibility cursor);
+			Assert.Equal (CursorVisibility.Default, cursor);
+
+			view.Enabled = false;
+			Assert.False (tf.HasFocus);
+			Application.Refresh ();
+			Application.Driver.GetCursorVisibility (out cursor);
+			Assert.Equal (CursorVisibility.Invisible, cursor);
+		}
 	}
 	}
 }
 }

+ 74 - 75
UnitTests/Types/DimTests.cs

@@ -37,15 +37,15 @@ namespace Terminal.Gui.TypeTests {
 		public void Sized_SetsValue ()
 		public void Sized_SetsValue ()
 		{
 		{
 			var dim = Dim.Sized (0);
 			var dim = Dim.Sized (0);
-			Assert.Equal ("Dim.Absolute(0)", dim.ToString ());
+			Assert.Equal ("Absolute(0)", dim.ToString ());
 
 
 			int testVal = 5;
 			int testVal = 5;
 			dim = Dim.Sized (testVal);
 			dim = Dim.Sized (testVal);
-			Assert.Equal ($"Dim.Absolute({testVal})", dim.ToString ());
+			Assert.Equal ($"Absolute({testVal})", dim.ToString ());
 
 
 			testVal = -1;
 			testVal = -1;
 			dim = Dim.Sized (testVal);
 			dim = Dim.Sized (testVal);
-			Assert.Equal ($"Dim.Absolute({testVal})", dim.ToString ());
+			Assert.Equal ($"Absolute({testVal})", dim.ToString ());
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -83,11 +83,11 @@ namespace Terminal.Gui.TypeTests {
 			var testVal = Rect.Empty;
 			var testVal = Rect.Empty;
 			testVal = Rect.Empty;
 			testVal = Rect.Empty;
 			dim = Dim.Width (new View (testVal));
 			dim = Dim.Width (new View (testVal));
-			Assert.Equal ($"DimView(side=Width, target=View()({{X={testVal.X},Y={testVal.Y},Width={testVal.Width},Height={testVal.Height}}}))", dim.ToString ());
+			Assert.Equal ($"DimView(Width,View()({{X={testVal.X},Y={testVal.Y},Width={testVal.Width},Height={testVal.Height}}}))", dim.ToString ());
 
 
 			testVal = new Rect (1, 2, 3, 4);
 			testVal = new Rect (1, 2, 3, 4);
 			dim = Dim.Width (new View (testVal));
 			dim = Dim.Width (new View (testVal));
-			Assert.Equal ($"DimView(side=Width, target=View()({{X={testVal.X},Y={testVal.Y},Width={testVal.Width},Height={testVal.Height}}}))", dim.ToString ());
+			Assert.Equal ($"DimView(Width,View()({{X={testVal.X},Y={testVal.Y},Width={testVal.Width},Height={testVal.Height}}}))", dim.ToString ());
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -141,11 +141,11 @@ namespace Terminal.Gui.TypeTests {
 			var testVal = Rect.Empty;
 			var testVal = Rect.Empty;
 			testVal = Rect.Empty;
 			testVal = Rect.Empty;
 			dim = Dim.Height (new View (testVal));
 			dim = Dim.Height (new View (testVal));
-			Assert.Equal ($"DimView(side=Height, target=View()({{X={testVal.X},Y={testVal.Y},Width={testVal.Width},Height={testVal.Height}}}))", dim.ToString ());
+			Assert.Equal ($"DimView(Height,View()({{X={testVal.X},Y={testVal.Y},Width={testVal.Width},Height={testVal.Height}}}))", dim.ToString ());
 
 
 			testVal = new Rect (1, 2, 3, 4);
 			testVal = new Rect (1, 2, 3, 4);
 			dim = Dim.Height (new View (testVal));
 			dim = Dim.Height (new View (testVal));
-			Assert.Equal ($"DimView(side=Height, target=View()({{X={testVal.X},Y={testVal.Y},Width={testVal.Width},Height={testVal.Height}}}))", dim.ToString ());
+			Assert.Equal ($"DimView(Height,View()({{X={testVal.X},Y={testVal.Y},Width={testVal.Width},Height={testVal.Height}}}))", dim.ToString ());
 		}
 		}
 
 
 		// TODO: Other Dim.Height tests (e.g. Equal?)
 		// TODO: Other Dim.Height tests (e.g. Equal?)
@@ -155,15 +155,15 @@ namespace Terminal.Gui.TypeTests {
 		{
 		{
 			var testMargin = 0;
 			var testMargin = 0;
 			var dim = Dim.Fill ();
 			var dim = Dim.Fill ();
-			Assert.Equal ($"Dim.Fill(margin={testMargin})", dim.ToString ());
+			Assert.Equal ($"Fill({testMargin})", dim.ToString ());
 
 
 			testMargin = 0;
 			testMargin = 0;
 			dim = Dim.Fill (testMargin);
 			dim = Dim.Fill (testMargin);
-			Assert.Equal ($"Dim.Fill(margin={testMargin})", dim.ToString ());
+			Assert.Equal ($"Fill({testMargin})", dim.ToString ());
 
 
 			testMargin = 5;
 			testMargin = 5;
 			dim = Dim.Fill (testMargin);
 			dim = Dim.Fill (testMargin);
-			Assert.Equal ($"Dim.Fill(margin={testMargin})", dim.ToString ());
+			Assert.Equal ($"Fill({testMargin})", dim.ToString ());
 		}
 		}
 
 
 
 
@@ -182,13 +182,13 @@ namespace Terminal.Gui.TypeTests {
 		{
 		{
 			float f = 0;
 			float f = 0;
 			var dim = Dim.Percent (f);
 			var dim = Dim.Percent (f);
-			Assert.Equal ($"Dim.Factor(factor={f / 100:0.###}, remaining={false})", dim.ToString ());
+			Assert.Equal ($"Factor({f / 100:0.###},{false})", dim.ToString ());
 			f = 0.5F;
 			f = 0.5F;
 			dim = Dim.Percent (f);
 			dim = Dim.Percent (f);
-			Assert.Equal ($"Dim.Factor(factor={f / 100:0.###}, remaining={false})", dim.ToString ());
+			Assert.Equal ($"Factor({f / 100:0.###},{false})", dim.ToString ());
 			f = 100;
 			f = 100;
 			dim = Dim.Percent (f);
 			dim = Dim.Percent (f);
-			Assert.Equal ($"Dim.Factor(factor={f / 100:0.###}, remaining={false})", dim.ToString ());
+			Assert.Equal ($"Factor({f / 100:0.###},{false})", dim.ToString ());
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -420,112 +420,111 @@ namespace Terminal.Gui.TypeTests {
 			t.Add (w);
 			t.Add (w);
 
 
 			t.Ready += () => {
 			t.Ready += () => {
-				Assert.Equal ("Dim.Absolute(100)", w.Width.ToString ());
-				Assert.Equal ("Dim.Absolute(100)", w.Height.ToString ());
+				Assert.Equal ("Absolute(100)", w.Width.ToString ());
+				Assert.Equal ("Absolute(100)", w.Height.ToString ());
 				Assert.Equal (100, w.Frame.Width);
 				Assert.Equal (100, w.Frame.Width);
 				Assert.Equal (100, w.Frame.Height);
 				Assert.Equal (100, w.Frame.Height);
 
 
-				Assert.Equal ("Dim.Factor(factor=0.5, remaining=False)", f1.Width.ToString ());
-				Assert.Equal ("Dim.Absolute(5)", f1.Height.ToString ());
+				Assert.Equal ("Factor(0.5,False)", f1.Width.ToString ());
+				Assert.Equal ("Absolute(5)", f1.Height.ToString ());
 				Assert.Equal (49, f1.Frame.Width); // 50-1=49
 				Assert.Equal (49, f1.Frame.Width); // 50-1=49
 				Assert.Equal (5, f1.Frame.Height);
 				Assert.Equal (5, f1.Frame.Height);
 
 
-				Assert.Equal ("Dim.Fill(margin=0)", f2.Width.ToString ());
-				Assert.Equal ("Dim.Absolute(5)", f2.Height.ToString ());
+				Assert.Equal ("Fill(0)", f2.Width.ToString ());
+				Assert.Equal ("Absolute(5)", f2.Height.ToString ());
 				Assert.Equal (49, f2.Frame.Width); // 50-1=49
 				Assert.Equal (49, f2.Frame.Width); // 50-1=49
 				Assert.Equal (5, f2.Frame.Height);
 				Assert.Equal (5, f2.Frame.Height);
-
-				Assert.Equal ("Dim.Combine(DimView(side=Width, target=FrameView()({X=0,Y=0,Width=49,Height=5}))-Dim.Absolute(2))", v1.Width.ToString ());
-				Assert.Equal ("Dim.Combine(Dim.Fill(margin=0)-Dim.Absolute(2))", v1.Height.ToString ());
+	
+				Assert.Equal ("Combine(DimView(Width,FrameView()({X=0,Y=0,Width=49,Height=5}))-Absolute(2))", v1.Width.ToString ());
+				Assert.Equal ("Combine(Fill(0)-Absolute(2))", v1.Height.ToString ());
 				Assert.Equal (47, v1.Frame.Width); // 49-2=47
 				Assert.Equal (47, v1.Frame.Width); // 49-2=47
 				Assert.Equal (89, v1.Frame.Height); // 98-5-2-2=89
 				Assert.Equal (89, v1.Frame.Height); // 98-5-2-2=89
 
 
-				Assert.Equal ("Dim.Combine(DimView(side=Width, target=FrameView()({X=49,Y=0,Width=49,Height=5}))-Dim.Absolute(2))", v2.Width.ToString ());
-				Assert.Equal ("Dim.Combine(Dim.Fill(margin=0)-Dim.Absolute(2))", v2.Height.ToString ());
+				Assert.Equal ("Combine(DimView(Width,FrameView()({X=49,Y=0,Width=49,Height=5}))-Absolute(2))", v2.Width.ToString ());
+				Assert.Equal ("Combine(Fill(0)-Absolute(2))", v2.Height.ToString ());
 				Assert.Equal (47, v2.Frame.Width); // 49-2=47
 				Assert.Equal (47, v2.Frame.Width); // 49-2=47
 				Assert.Equal (89, v2.Frame.Height); // 98-5-2-2=89
 				Assert.Equal (89, v2.Frame.Height); // 98-5-2-2=89
 
 
-				Assert.Equal ("Dim.Factor(factor=0.1, remaining=False)", v3.Width.ToString ());
-				Assert.Equal ("Dim.Factor(factor=0.1, remaining=False)", v3.Height.ToString ());
+				Assert.Equal ("Factor(0.1,False)", v3.Width.ToString ());
+				Assert.Equal ("Factor(0.1,False)", v3.Height.ToString ());
 				Assert.Equal (9, v3.Frame.Width); // 98*10%=9
 				Assert.Equal (9, v3.Frame.Width); // 98*10%=9
 				Assert.Equal (9, v3.Frame.Height); // 98*10%=9
 				Assert.Equal (9, v3.Frame.Height); // 98*10%=9
 
 
-				Assert.Equal ("Dim.Absolute(50)", v4.Width.ToString ());
-				Assert.Equal ("Dim.Absolute(50)", v4.Height.ToString ());
+				Assert.Equal ("Absolute(50)", v4.Width.ToString ());
+				Assert.Equal ("Absolute(50)", v4.Height.ToString ());
 				Assert.Equal (50, v4.Frame.Width);
 				Assert.Equal (50, v4.Frame.Width);
 				Assert.Equal (50, v4.Frame.Height);
 				Assert.Equal (50, v4.Frame.Height);
 
 
-				Assert.Equal ("Dim.Combine(DimView(side=Width, target=Button()({X=2,Y=7,Width=47,Height=89}))-DimView(side=Width, target=Button()({X=0,Y=0,Width=9,Height=9})))", v5.Width.ToString ());
-				Assert.Equal ("Dim.Combine(DimView(side=Height, target=Button()({X=2,Y=7,Width=47,Height=89}))-DimView(side=Height, target=Button()({X=0,Y=0,Width=9,Height=9})))", v5.Height.ToString ());
+				Assert.Equal ("Combine(DimView(Width,Button()({X=2,Y=7,Width=47,Height=89}))-DimView(Width,Button()({X=0,Y=0,Width=9,Height=9})))", v5.Width.ToString ());
+				Assert.Equal ("Combine(DimView(Height,Button()({X=2,Y=7,Width=47,Height=89}))-DimView(Height,Button()({X=0,Y=0,Width=9,Height=9})))", v5.Height.ToString ());
 				Assert.Equal (38, v5.Frame.Width); // 47-9=38
 				Assert.Equal (38, v5.Frame.Width); // 47-9=38
 				Assert.Equal (80, v5.Frame.Height); // 89-9=80
 				Assert.Equal (80, v5.Frame.Height); // 89-9=80
 
 
-				Assert.Equal ("Dim.Factor(factor=0.2, remaining=True)", v6.Width.ToString ());
-				Assert.Equal ("Dim.Factor(factor=0.2, remaining=True)", v6.Height.ToString ());
+				Assert.Equal ("Factor(0.2,True)", v6.Width.ToString ());
+				Assert.Equal ("Factor(0.2,True)", v6.Height.ToString ());
 				Assert.Equal (9, v6.Frame.Width); // 47*20%=9
 				Assert.Equal (9, v6.Frame.Width); // 47*20%=9
 				Assert.Equal (18, v6.Frame.Height); // 89*20%=18
 				Assert.Equal (18, v6.Frame.Height); // 89*20%=18
 
 
-
 				w.Width = 200;
 				w.Width = 200;
 				w.Height = 200;
 				w.Height = 200;
 				t.LayoutSubviews ();
 				t.LayoutSubviews ();
 
 
-				Assert.Equal ("Dim.Absolute(200)", w.Width.ToString ());
-				Assert.Equal ("Dim.Absolute(200)", w.Height.ToString ());
+				Assert.Equal ("Absolute(200)", w.Width.ToString ());
+				Assert.Equal ("Absolute(200)", w.Height.ToString ());
 				Assert.Equal (200, w.Frame.Width);
 				Assert.Equal (200, w.Frame.Width);
 				Assert.Equal (200, w.Frame.Height);
 				Assert.Equal (200, w.Frame.Height);
 
 
 				f1.Text = "Frame1";
 				f1.Text = "Frame1";
-				Assert.Equal ("Dim.Factor(factor=0.5, remaining=False)", f1.Width.ToString ());
-				Assert.Equal ("Dim.Absolute(5)", f1.Height.ToString ());
+				Assert.Equal ("Factor(0.5,False)", f1.Width.ToString ());
+				Assert.Equal ("Absolute(5)", f1.Height.ToString ());
 				Assert.Equal (99, f1.Frame.Width); // 100-1=99
 				Assert.Equal (99, f1.Frame.Width); // 100-1=99
 				Assert.Equal (5, f1.Frame.Height);
 				Assert.Equal (5, f1.Frame.Height);
 
 
 				f2.Text = "Frame2";
 				f2.Text = "Frame2";
-				Assert.Equal ("Dim.Fill(margin=0)", f2.Width.ToString ());
-				Assert.Equal ("Dim.Absolute(5)", f2.Height.ToString ());
+				Assert.Equal ("Fill(0)", f2.Width.ToString ());
+				Assert.Equal ("Absolute(5)", f2.Height.ToString ());
 				Assert.Equal (99, f2.Frame.Width); // 100-1=99
 				Assert.Equal (99, f2.Frame.Width); // 100-1=99
 				Assert.Equal (5, f2.Frame.Height);
 				Assert.Equal (5, f2.Frame.Height);
 
 
 				v1.Text = "Button1";
 				v1.Text = "Button1";
-				Assert.Equal ("Dim.Combine(DimView(side=Width, target=FrameView()({X=0,Y=0,Width=99,Height=5}))-Dim.Absolute(2))", v1.Width.ToString ());
-				Assert.Equal ("Dim.Combine(Dim.Fill(margin=0)-Dim.Absolute(2))", v1.Height.ToString ());
+				Assert.Equal ("Combine(DimView(Width,FrameView()({X=0,Y=0,Width=99,Height=5}))-Absolute(2))", v1.Width.ToString ());
+				Assert.Equal ("Combine(Fill(0)-Absolute(2))", v1.Height.ToString ());
 				Assert.Equal (97, v1.Frame.Width); // 99-2=97
 				Assert.Equal (97, v1.Frame.Width); // 99-2=97
 				Assert.Equal (189, v1.Frame.Height); // 198-2-7=189
 				Assert.Equal (189, v1.Frame.Height); // 198-2-7=189
 
 
 				v2.Text = "Button2";
 				v2.Text = "Button2";
-				Assert.Equal ("Dim.Combine(DimView(side=Width, target=FrameView()({X=99,Y=0,Width=99,Height=5}))-Dim.Absolute(2))", v2.Width.ToString ());
-				Assert.Equal ("Dim.Combine(Dim.Fill(margin=0)-Dim.Absolute(2))", v2.Height.ToString ());
+				Assert.Equal ("Combine(DimView(Width,FrameView()({X=99,Y=0,Width=99,Height=5}))-Absolute(2))", v2.Width.ToString ());
+				Assert.Equal ("Combine(Fill(0)-Absolute(2))", v2.Height.ToString ());
 				Assert.Equal (97, v2.Frame.Width); // 99-2=97
 				Assert.Equal (97, v2.Frame.Width); // 99-2=97
 				Assert.Equal (189, v2.Frame.Height); // 198-2-7=189
 				Assert.Equal (189, v2.Frame.Height); // 198-2-7=189
 
 
 				v3.Text = "Button3";
 				v3.Text = "Button3";
-				Assert.Equal ("Dim.Factor(factor=0.1, remaining=False)", v3.Width.ToString ());
-				Assert.Equal ("Dim.Factor(factor=0.1, remaining=False)", v3.Height.ToString ());
+				Assert.Equal ("Factor(0.1,False)", v3.Width.ToString ());
+				Assert.Equal ("Factor(0.1,False)", v3.Height.ToString ());
 				Assert.Equal (19, v3.Frame.Width); // 198*10%=19 * Percent is related to the super-view if it isn't null otherwise the view width
 				Assert.Equal (19, v3.Frame.Width); // 198*10%=19 * Percent is related to the super-view if it isn't null otherwise the view width
 				Assert.Equal (19, v3.Frame.Height); // 199*10%=19
 				Assert.Equal (19, v3.Frame.Height); // 199*10%=19
 
 
 				v4.Text = "Button4";
 				v4.Text = "Button4";
 				v4.AutoSize = false;
 				v4.AutoSize = false;
-				Assert.Equal ("Dim.Absolute(50)", v4.Width.ToString ());
-				Assert.Equal ("Dim.Absolute(50)", v4.Height.ToString ());
+				Assert.Equal ("Absolute(50)", v4.Width.ToString ());
+				Assert.Equal ("Absolute(50)", v4.Height.ToString ());
 				Assert.Equal (50, v4.Frame.Width);
 				Assert.Equal (50, v4.Frame.Width);
 				Assert.Equal (50, v4.Frame.Height);
 				Assert.Equal (50, v4.Frame.Height);
 				v4.AutoSize = true;
 				v4.AutoSize = true;
-				Assert.Equal ("Dim.Absolute(11)", v4.Width.ToString ());
-				Assert.Equal ("Dim.Absolute(1)", v4.Height.ToString ());
+				Assert.Equal ("Absolute(11)", v4.Width.ToString ());
+				Assert.Equal ("Absolute(1)", v4.Height.ToString ());
 				Assert.Equal (11, v4.Frame.Width); // 11 is the text length and because is Dim.DimAbsolute
 				Assert.Equal (11, v4.Frame.Width); // 11 is the text length and because is Dim.DimAbsolute
 				Assert.Equal (1, v4.Frame.Height); // 1 because is Dim.DimAbsolute
 				Assert.Equal (1, v4.Frame.Height); // 1 because is Dim.DimAbsolute
 
 
 				v5.Text = "Button5";
 				v5.Text = "Button5";
-				Assert.Equal ("Dim.Combine(DimView(side=Width, target=Button()({X=2,Y=7,Width=97,Height=189}))-DimView(side=Width, target=Button()({X=0,Y=0,Width=19,Height=19})))", v5.Width.ToString ());
-				Assert.Equal ("Dim.Combine(DimView(side=Height, target=Button()({X=2,Y=7,Width=97,Height=189}))-DimView(side=Height, target=Button()({X=0,Y=0,Width=19,Height=19})))", v5.Height.ToString ());
+				Assert.Equal ("Combine(DimView(Width,Button()({X=2,Y=7,Width=97,Height=189}))-DimView(Width,Button()({X=0,Y=0,Width=19,Height=19})))", v5.Width.ToString ());
+				Assert.Equal ("Combine(DimView(Height,Button()({X=2,Y=7,Width=97,Height=189}))-DimView(Height,Button()({X=0,Y=0,Width=19,Height=19})))", v5.Height.ToString ());
 				Assert.Equal (78, v5.Frame.Width); // 97-19=78
 				Assert.Equal (78, v5.Frame.Width); // 97-19=78
 				Assert.Equal (170, v5.Frame.Height); // 189-19=170
 				Assert.Equal (170, v5.Frame.Height); // 189-19=170
 
 
 				v6.Text = "Button6";
 				v6.Text = "Button6";
-				Assert.Equal ("Dim.Factor(factor=0.2, remaining=True)", v6.Width.ToString ());
-				Assert.Equal ("Dim.Factor(factor=0.2, remaining=True)", v6.Height.ToString ());
+				Assert.Equal ("Factor(0.2,True)", v6.Width.ToString ());
+				Assert.Equal ("Factor(0.2,True)", v6.Height.ToString ());
 				Assert.Equal (19, v6.Frame.Width); // 99*20%=19
 				Assert.Equal (19, v6.Frame.Width); // 99*20%=19
 				Assert.Equal (38, v6.Frame.Height); // 198-7*20=38
 				Assert.Equal (38, v6.Frame.Height); // 198-7*20=38
 			};
 			};
@@ -635,12 +634,12 @@ namespace Terminal.Gui.TypeTests {
 					var label = new Label (field.Text) { X = 0, Y = view.Bounds.Height, Width = 20 };
 					var label = new Label (field.Text) { X = 0, Y = view.Bounds.Height, Width = 20 };
 					view.Add (label);
 					view.Add (label);
 					Assert.Equal ($"Label {count}", label.Text);
 					Assert.Equal ($"Label {count}", label.Text);
-					Assert.Equal ($"Pos.Absolute({count})", label.Y.ToString ());
+					Assert.Equal ($"Absolute({count})", label.Y.ToString ());
 
 
-					Assert.Equal ($"Dim.Absolute({count})", view.Height.ToString ());
+					Assert.Equal ($"Absolute({count})", view.Height.ToString ());
 					view.Height += 1;
 					view.Height += 1;
 					count++;
 					count++;
-					Assert.Equal ($"Dim.Absolute({count})", view.Height.ToString ());
+					Assert.Equal ($"Absolute({count})", view.Height.ToString ());
 				}
 				}
 			};
 			};
 
 
@@ -1007,18 +1006,18 @@ namespace Terminal.Gui.TypeTests {
 						var label = new Label (field.Text) { X = 0, Y = view.Bounds.Height, Width = 10 };
 						var label = new Label (field.Text) { X = 0, Y = view.Bounds.Height, Width = 10 };
 						view.Add (label);
 						view.Add (label);
 						Assert.Equal ($"Label {count}", label.Text);
 						Assert.Equal ($"Label {count}", label.Text);
-						Assert.Equal ($"Pos.Absolute({count + 1})", label.Y.ToString ());
+						Assert.Equal ($"Absolute({count + 1})", label.Y.ToString ());
 						listLabels.Add (label);
 						listLabels.Add (label);
 						if (count == 0) {
 						if (count == 0) {
-							Assert.Equal ($"Dim.Absolute({count})", view.Height.ToString ());
+							Assert.Equal ($"Absolute({count})", view.Height.ToString ());
 							view.Height += 2;
 							view.Height += 2;
 						} else {
 						} else {
-							Assert.Equal ($"Dim.Absolute({count + 1})", view.Height.ToString ());
+							Assert.Equal ($"Absolute({count + 1})", view.Height.ToString ());
 							view.Height += 1;
 							view.Height += 1;
 						}
 						}
 						count++;
 						count++;
 					}
 					}
-					Assert.Equal ($"Dim.Absolute({count + 1})", view.Height.ToString ());
+					Assert.Equal ($"Absolute({count + 1})", view.Height.ToString ());
 				}
 				}
 			};
 			};
 
 
@@ -1067,12 +1066,12 @@ namespace Terminal.Gui.TypeTests {
 				var label = new Label (field.Text) { X = 0, Y = view.Bounds.Height, Width = 20 };
 				var label = new Label (field.Text) { X = 0, Y = view.Bounds.Height, Width = 20 };
 				view.Add (label);
 				view.Add (label);
 				Assert.Equal ($"Label {i}", label.Text);
 				Assert.Equal ($"Label {i}", label.Text);
-				Assert.Equal ($"Pos.Absolute({i})", label.Y.ToString ());
+				Assert.Equal ($"Absolute({i})", label.Y.ToString ());
 				listLabels.Add (label);
 				listLabels.Add (label);
 
 
-				Assert.Equal ($"Dim.Absolute({i})", view.Height.ToString ());
+				Assert.Equal ($"Absolute({i})", view.Height.ToString ());
 				view.Height += 1;
 				view.Height += 1;
-				Assert.Equal ($"Dim.Absolute({i + 1})", view.Height.ToString ());
+				Assert.Equal ($"Absolute({i + 1})", view.Height.ToString ());
 			}
 			}
 
 
 			field.KeyDown += (k) => {
 			field.KeyDown += (k) => {
@@ -1080,10 +1079,10 @@ namespace Terminal.Gui.TypeTests {
 					Assert.Equal ($"Label {count - 1}", listLabels [count - 1].Text);
 					Assert.Equal ($"Label {count - 1}", listLabels [count - 1].Text);
 					view.Remove (listLabels [count - 1]);
 					view.Remove (listLabels [count - 1]);
 
 
-					Assert.Equal ($"Dim.Absolute({count})", view.Height.ToString ());
+					Assert.Equal ($"Absolute({count})", view.Height.ToString ());
 					view.Height -= 1;
 					view.Height -= 1;
 					count--;
 					count--;
-					Assert.Equal ($"Dim.Absolute({count})", view.Height.ToString ());
+					Assert.Equal ($"Absolute({count})", view.Height.ToString ());
 				}
 				}
 			};
 			};
 
 
@@ -1126,17 +1125,17 @@ namespace Terminal.Gui.TypeTests {
 				var label = new Label (field.Text) { X = 0, Y = view.Bounds.Height, Width = 10 };
 				var label = new Label (field.Text) { X = 0, Y = view.Bounds.Height, Width = 10 };
 				view.Add (label);
 				view.Add (label);
 				Assert.Equal ($"Label {i}", label.Text);
 				Assert.Equal ($"Label {i}", label.Text);
-				Assert.Equal ($"Pos.Absolute({i + 1})", label.Y.ToString ());
+				Assert.Equal ($"Absolute({i + 1})", label.Y.ToString ());
 				listLabels.Add (label);
 				listLabels.Add (label);
 
 
 				if (i == 0) {
 				if (i == 0) {
-					Assert.Equal ($"Dim.Absolute({i})", view.Height.ToString ());
+					Assert.Equal ($"Absolute({i})", view.Height.ToString ());
 					view.Height += 2;
 					view.Height += 2;
-					Assert.Equal ($"Dim.Absolute({i + 2})", view.Height.ToString ());
+					Assert.Equal ($"Absolute({i + 2})", view.Height.ToString ());
 				} else {
 				} else {
-					Assert.Equal ($"Dim.Absolute({i + 1})", view.Height.ToString ());
+					Assert.Equal ($"Absolute({i + 1})", view.Height.ToString ());
 					view.Height += 1;
 					view.Height += 1;
-					Assert.Equal ($"Dim.Absolute({i + 2})", view.Height.ToString ());
+					Assert.Equal ($"Absolute({i + 2})", view.Height.ToString ());
 				}
 				}
 			}
 			}
 
 
@@ -1150,7 +1149,7 @@ namespace Terminal.Gui.TypeTests {
 						Assert.Equal ($"Label {count - 1}", listLabels [count - 1].Text);
 						Assert.Equal ($"Label {count - 1}", listLabels [count - 1].Text);
 						view.Remove (listLabels [count - 1]);
 						view.Remove (listLabels [count - 1]);
 						listLabels.RemoveAt (count - 1);
 						listLabels.RemoveAt (count - 1);
-						Assert.Equal ($"Dim.Absolute({count + 1})", view.Height.ToString ());
+						Assert.Equal ($"Absolute({count + 1})", view.Height.ToString ());
 						view.Height -= 1;
 						view.Height -= 1;
 						count--;
 						count--;
 						if (listLabels.Count > 0)
 						if (listLabels.Count > 0)
@@ -1158,7 +1157,7 @@ namespace Terminal.Gui.TypeTests {
 						else
 						else
 							field.Text = NStack.ustring.Empty;
 							field.Text = NStack.ustring.Empty;
 					}
 					}
-					Assert.Equal ($"Dim.Absolute({count + 1})", view.Height.ToString ());
+					Assert.Equal ($"Absolute({count + 1})", view.Height.ToString ());
 				}
 				}
 			};
 			};
 
 
@@ -1218,13 +1217,13 @@ namespace Terminal.Gui.TypeTests {
 		{
 		{
 			var text = "Test";
 			var text = "Test";
 			var dim = Dim.Function (() => text.Length);
 			var dim = Dim.Function (() => text.Length);
-			Assert.Equal ("Dim.DimFunc(4)", dim.ToString ());
+			Assert.Equal ("DimFunc(4)", dim.ToString ());
 
 
 			text = "New Test";
 			text = "New Test";
-			Assert.Equal ("Dim.DimFunc(8)", dim.ToString ());
+			Assert.Equal ("DimFunc(8)", dim.ToString ());
 
 
 			text = "";
 			text = "";
-			Assert.Equal ("Dim.DimFunc(0)", dim.ToString ());
+			Assert.Equal ("DimFunc(0)", dim.ToString ());
 		}
 		}
 
 
 		[Fact]
 		[Fact]

+ 55 - 50
UnitTests/Types/PosTests.cs

@@ -32,11 +32,11 @@ namespace Terminal.Gui.TypeTests {
 		{
 		{
 			var n = 0;
 			var n = 0;
 			var pos = Pos.AnchorEnd ();
 			var pos = Pos.AnchorEnd ();
-			Assert.Equal ($"Pos.AnchorEnd(margin={n})", pos.ToString ());
+			Assert.Equal ($"AnchorEnd({n})", pos.ToString ());
 
 
 			n = 5;
 			n = 5;
 			pos = Pos.AnchorEnd (n);
 			pos = Pos.AnchorEnd (n);
-			Assert.Equal ($"Pos.AnchorEnd(margin={n})", pos.ToString ());
+			Assert.Equal ($"AnchorEnd({n})", pos.ToString ());
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -351,13 +351,13 @@ namespace Terminal.Gui.TypeTests {
 		public void At_SetsValue ()
 		public void At_SetsValue ()
 		{
 		{
 			var pos = Pos.At (0);
 			var pos = Pos.At (0);
-			Assert.Equal ("Pos.Absolute(0)", pos.ToString ());
+			Assert.Equal ("Absolute(0)", pos.ToString ());
 
 
 			pos = Pos.At (5);
 			pos = Pos.At (5);
-			Assert.Equal ("Pos.Absolute(5)", pos.ToString ());
+			Assert.Equal ("Absolute(5)", pos.ToString ());
 
 
 			pos = Pos.At (-1);
 			pos = Pos.At (-1);
-			Assert.Equal ("Pos.Absolute(-1)", pos.ToString ());
+			Assert.Equal ("Absolute(-1)", pos.ToString ());
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -411,140 +411,140 @@ namespace Terminal.Gui.TypeTests {
 			testInt = 0;
 			testInt = 0;
 			testRect = Rect.Empty;
 			testRect = Rect.Empty;
 			pos = Pos.Left (new View ());
 			pos = Pos.Left (new View ());
-			Assert.Equal ($"Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			pos = Pos.Left (new View (testRect));
 			pos = Pos.Left (new View (testRect));
-			Assert.Equal ($"Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			testRect = new Rect (1, 2, 3, 4);
 			testRect = new Rect (1, 2, 3, 4);
 			pos = Pos.Left (new View (testRect));
 			pos = Pos.Left (new View (testRect));
-			Assert.Equal ($"Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			// Pos.Left(win) + 0
 			// Pos.Left(win) + 0
 			pos = Pos.Left (new View (testRect)) + testInt;
 			pos = Pos.Left (new View (testRect)) + testInt;
-			Assert.Equal ($"Pos.Combine(Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Pos.Absolute(0)){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			testInt = 1;
 			testInt = 1;
 			// Pos.Left(win) +1
 			// Pos.Left(win) +1
 			pos = Pos.Left (new View (testRect)) + testInt;
 			pos = Pos.Left (new View (testRect)) + testInt;
-			Assert.Equal ($"Pos.Combine(Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Pos.Absolute(0)){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			testInt = -1;
 			testInt = -1;
 			// Pos.Left(win) -1
 			// Pos.Left(win) -1
 			pos = Pos.Left (new View (testRect)) - testInt;
 			pos = Pos.Left (new View (testRect)) - testInt;
-			Assert.Equal ($"Pos.Combine(Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Pos.Absolute(0)){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			// Pos.X
 			// Pos.X
 			side = "x";
 			side = "x";
 			testInt = 0;
 			testInt = 0;
 			testRect = Rect.Empty;
 			testRect = Rect.Empty;
 			pos = Pos.X (new View ());
 			pos = Pos.X (new View ());
-			Assert.Equal ($"Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			pos = Pos.X (new View (testRect));
 			pos = Pos.X (new View (testRect));
-			Assert.Equal ($"Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			testRect = new Rect (1, 2, 3, 4);
 			testRect = new Rect (1, 2, 3, 4);
 			pos = Pos.X (new View (testRect));
 			pos = Pos.X (new View (testRect));
-			Assert.Equal ($"Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			// Pos.X(win) + 0
 			// Pos.X(win) + 0
 			pos = Pos.X (new View (testRect)) + testInt;
 			pos = Pos.X (new View (testRect)) + testInt;
-			Assert.Equal ($"Pos.Combine(Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Pos.Absolute(0)){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			testInt = 1;
 			testInt = 1;
 			// Pos.X(win) +1
 			// Pos.X(win) +1
 			pos = Pos.X (new View (testRect)) + testInt;
 			pos = Pos.X (new View (testRect)) + testInt;
-			Assert.Equal ($"Pos.Combine(Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Pos.Absolute(0)){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			testInt = -1;
 			testInt = -1;
 			// Pos.X(win) -1
 			// Pos.X(win) -1
 			pos = Pos.X (new View (testRect)) - testInt;
 			pos = Pos.X (new View (testRect)) - testInt;
-			Assert.Equal ($"Pos.Combine(Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Pos.Absolute(0)){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			// Pos.Top
 			// Pos.Top
 			side = "y";
 			side = "y";
 			testInt = 0;
 			testInt = 0;
 			testRect = Rect.Empty;
 			testRect = Rect.Empty;
 			pos = Pos.Top (new View ());
 			pos = Pos.Top (new View ());
-			Assert.Equal ($"Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			pos = Pos.Top (new View (testRect));
 			pos = Pos.Top (new View (testRect));
-			Assert.Equal ($"Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			testRect = new Rect (1, 2, 3, 4);
 			testRect = new Rect (1, 2, 3, 4);
 			pos = Pos.Top (new View (testRect));
 			pos = Pos.Top (new View (testRect));
-			Assert.Equal ($"Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			// Pos.Top(win) + 0
 			// Pos.Top(win) + 0
 			pos = Pos.Top (new View (testRect)) + testInt;
 			pos = Pos.Top (new View (testRect)) + testInt;
-			Assert.Equal ($"Pos.Combine(Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Pos.Absolute(0)){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			testInt = 1;
 			testInt = 1;
 			// Pos.Top(win) +1
 			// Pos.Top(win) +1
 			pos = Pos.Top (new View (testRect)) + testInt;
 			pos = Pos.Top (new View (testRect)) + testInt;
-			Assert.Equal ($"Pos.Combine(Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Pos.Absolute(0)){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			testInt = -1;
 			testInt = -1;
 			// Pos.Top(win) -1
 			// Pos.Top(win) -1
 			pos = Pos.Top (new View (testRect)) - testInt;
 			pos = Pos.Top (new View (testRect)) - testInt;
-			Assert.Equal ($"Pos.Combine(Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Pos.Absolute(0)){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			// Pos.Y
 			// Pos.Y
 			side = "y";
 			side = "y";
 			testInt = 0;
 			testInt = 0;
 			testRect = Rect.Empty;
 			testRect = Rect.Empty;
 			pos = Pos.Y (new View ());
 			pos = Pos.Y (new View ());
-			Assert.Equal ($"Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			pos = Pos.Y (new View (testRect));
 			pos = Pos.Y (new View (testRect));
-			Assert.Equal ($"Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			testRect = new Rect (1, 2, 3, 4);
 			testRect = new Rect (1, 2, 3, 4);
 			pos = Pos.Y (new View (testRect));
 			pos = Pos.Y (new View (testRect));
-			Assert.Equal ($"Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			// Pos.Y(win) + 0
 			// Pos.Y(win) + 0
 			pos = Pos.Y (new View (testRect)) + testInt;
 			pos = Pos.Y (new View (testRect)) + testInt;
-			Assert.Equal ($"Pos.Combine(Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Pos.Absolute(0)){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			testInt = 1;
 			testInt = 1;
 			// Pos.Y(win) +1
 			// Pos.Y(win) +1
 			pos = Pos.Y (new View (testRect)) + testInt;
 			pos = Pos.Y (new View (testRect)) + testInt;
-			Assert.Equal ($"Pos.Combine(Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Pos.Absolute(0)){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			testInt = -1;
 			testInt = -1;
 			// Pos.Y(win) -1
 			// Pos.Y(win) -1
 			pos = Pos.Y (new View (testRect)) - testInt;
 			pos = Pos.Y (new View (testRect)) - testInt;
-			Assert.Equal ($"Pos.Combine(Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Pos.Absolute(0)){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			// Pos.Bottom
 			// Pos.Bottom
 			side = "bottom";
 			side = "bottom";
 			testRect = Rect.Empty;
 			testRect = Rect.Empty;
 			testInt = 0;
 			testInt = 0;
 			pos = Pos.Bottom (new View ());
 			pos = Pos.Bottom (new View ());
-			Assert.Equal ($"Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			pos = Pos.Bottom (new View (testRect));
 			pos = Pos.Bottom (new View (testRect));
-			Assert.Equal ($"Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			testRect = new Rect (1, 2, 3, 4);
 			testRect = new Rect (1, 2, 3, 4);
 			pos = Pos.Bottom (new View (testRect));
 			pos = Pos.Bottom (new View (testRect));
-			Assert.Equal ($"Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}})){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			// Pos.Bottom(win) + 0
 			// Pos.Bottom(win) + 0
 			pos = Pos.Bottom (new View (testRect)) + testInt;
 			pos = Pos.Bottom (new View (testRect)) + testInt;
-			Assert.Equal ($"Pos.Combine(Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Pos.Absolute(0)){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			testInt = 1;
 			testInt = 1;
 			// Pos.Bottom(win) +1
 			// Pos.Bottom(win) +1
 			pos = Pos.Bottom (new View (testRect)) + testInt;
 			pos = Pos.Bottom (new View (testRect)) + testInt;
-			Assert.Equal ($"Pos.Combine(Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Pos.Absolute(0)){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 
 
 			testInt = -1;
 			testInt = -1;
 			// Pos.Bottom(win) -1
 			// Pos.Bottom(win) -1
 			pos = Pos.Bottom (new View (testRect)) - testInt;
 			pos = Pos.Bottom (new View (testRect)) - testInt;
-			Assert.Equal ($"Pos.Combine(Pos.Combine(Pos.View(side={side}, target=View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Pos.Absolute(0)){(testInt < 0 ? '-' : '+')}Pos.Absolute({testInt}))", pos.ToString ());
+			Assert.Equal ($"Combine(Combine(View({side},View()({{X={testRect.X},Y={testRect.Y},Width={testRect.Width},Height={testRect.Height}}}))+Absolute(0)){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString ());
 		}
 		}
 
 
 		// See: https://github.com/gui-cs/Terminal.Gui/issues/504
 		// See: https://github.com/gui-cs/Terminal.Gui/issues/504
@@ -632,7 +632,7 @@ namespace Terminal.Gui.TypeTests {
 		public void Center_SetsValue ()
 		public void Center_SetsValue ()
 		{
 		{
 			var pos = Pos.Center ();
 			var pos = Pos.Center ();
-			Assert.Equal ("Pos.Center", pos.ToString ());
+			Assert.Equal ("Center", pos.ToString ());
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -640,13 +640,13 @@ namespace Terminal.Gui.TypeTests {
 		{
 		{
 			float f = 0;
 			float f = 0;
 			var pos = Pos.Percent (f);
 			var pos = Pos.Percent (f);
-			Assert.Equal ($"Pos.Factor({f / 100:0.###})", pos.ToString ());
+			Assert.Equal ($"Factor({f / 100:0.###})", pos.ToString ());
 			f = 0.5F;
 			f = 0.5F;
 			pos = Pos.Percent (f);
 			pos = Pos.Percent (f);
-			Assert.Equal ($"Pos.Factor({f / 100:0.###})", pos.ToString ());
+			Assert.Equal ($"Factor({f / 100:0.###})", pos.ToString ());
 			f = 100;
 			f = 100;
 			pos = Pos.Percent (f);
 			pos = Pos.Percent (f);
-			Assert.Equal ($"Pos.Factor({f / 100:0.###})", pos.ToString ());
+			Assert.Equal ($"Factor({f / 100:0.###})", pos.ToString ());
 		}
 		}
 
 
 		[Fact]
 		[Fact]
@@ -881,12 +881,12 @@ namespace Terminal.Gui.TypeTests {
 					var label = new Label (field.Text) { X = 0, Y = field.Y, Width = 20 };
 					var label = new Label (field.Text) { X = 0, Y = field.Y, Width = 20 };
 					view.Add (label);
 					view.Add (label);
 					Assert.Equal ($"Label {count}", label.Text);
 					Assert.Equal ($"Label {count}", label.Text);
-					Assert.Equal ($"Pos.Absolute({count})", label.Y.ToString ());
+					Assert.Equal ($"Absolute({count})", label.Y.ToString ());
 
 
-					Assert.Equal ($"Pos.Absolute({count})", field.Y.ToString ());
+					Assert.Equal ($"Absolute({count})", field.Y.ToString ());
 					field.Y += 1;
 					field.Y += 1;
 					count++;
 					count++;
-					Assert.Equal ($"Pos.Absolute({count})", field.Y.ToString ());
+					Assert.Equal ($"Absolute({count})", field.Y.ToString ());
 				}
 				}
 			};
 			};
 
 
@@ -928,12 +928,12 @@ namespace Terminal.Gui.TypeTests {
 				var label = new Label (field.Text) { X = 0, Y = field.Y, Width = 20 };
 				var label = new Label (field.Text) { X = 0, Y = field.Y, Width = 20 };
 				view.Add (label);
 				view.Add (label);
 				Assert.Equal ($"Label {i}", label.Text);
 				Assert.Equal ($"Label {i}", label.Text);
-				Assert.Equal ($"Pos.Absolute({i})", field.Y.ToString ());
+				Assert.Equal ($"Absolute({i})", field.Y.ToString ());
 				listLabels.Add (label);
 				listLabels.Add (label);
 
 
-				Assert.Equal ($"Pos.Absolute({i})", field.Y.ToString ());
+				Assert.Equal ($"Absolute({i})", field.Y.ToString ());
 				field.Y += 1;
 				field.Y += 1;
-				Assert.Equal ($"Pos.Absolute({i + 1})", field.Y.ToString ());
+				Assert.Equal ($"Absolute({i + 1})", field.Y.ToString ());
 			}
 			}
 
 
 			field.KeyDown += (k) => {
 			field.KeyDown += (k) => {
@@ -941,10 +941,10 @@ namespace Terminal.Gui.TypeTests {
 					Assert.Equal ($"Label {count - 1}", listLabels [count - 1].Text);
 					Assert.Equal ($"Label {count - 1}", listLabels [count - 1].Text);
 					view.Remove (listLabels [count - 1]);
 					view.Remove (listLabels [count - 1]);
 
 
-					Assert.Equal ($"Pos.Absolute({count})", field.Y.ToString ());
+					Assert.Equal ($"Absolute({count})", field.Y.ToString ());
 					field.Y -= 1;
 					field.Y -= 1;
 					count--;
 					count--;
-					Assert.Equal ($"Pos.Absolute({count})", field.Y.ToString ());
+					Assert.Equal ($"Absolute({count})", field.Y.ToString ());
 				}
 				}
 			};
 			};
 
 
@@ -988,6 +988,11 @@ namespace Terminal.Gui.TypeTests {
 			Assert.Equal (posCombine.right, posAbsolute);
 			Assert.Equal (posCombine.right, posAbsolute);
 			Assert.Equal (20, posCombine.Anchor (100));
 			Assert.Equal (20, posCombine.Anchor (100));
 
 
+			posCombine = new Pos.PosCombine (true, posAbsolute, posFactor);
+			Assert.Equal (posCombine.left, posAbsolute);
+			Assert.Equal (posCombine.right, posFactor);
+			Assert.Equal (20, posCombine.Anchor (100));
+
 			var view = new View (new Rect (20, 10, 20, 1));
 			var view = new View (new Rect (20, 10, 20, 1));
 			var posViewX = new Pos.PosView (view, 0);
 			var posViewX = new Pos.PosView (view, 0);
 			Assert.Equal (20, posViewX.Anchor (0));
 			Assert.Equal (20, posViewX.Anchor (0));
@@ -1004,13 +1009,13 @@ namespace Terminal.Gui.TypeTests {
 		{
 		{
 			var text = "Test";
 			var text = "Test";
 			var pos = Pos.Function (() => text.Length);
 			var pos = Pos.Function (() => text.Length);
-			Assert.Equal ("Pos.PosFunc(4)", pos.ToString ());
+			Assert.Equal ("PosFunc(4)", pos.ToString ());
 
 
 			text = "New Test";
 			text = "New Test";
-			Assert.Equal ("Pos.PosFunc(8)", pos.ToString ());
+			Assert.Equal ("PosFunc(8)", pos.ToString ());
 
 
 			text = "";
 			text = "";
-			Assert.Equal ("Pos.PosFunc(0)", pos.ToString ());
+			Assert.Equal ("PosFunc(0)", pos.ToString ());
 		}
 		}
 
 
 		[Fact]
 		[Fact]

+ 20 - 20
UnitTests/Views/ScrollBarViewTests.cs

@@ -362,85 +362,85 @@ namespace Terminal.Gui.ViewTests {
 			_hostView.Redraw (_hostView.Bounds);
 			_hostView.Redraw (_hostView.Bounds);
 			Assert.True (_scrollBar.ShowScrollIndicator);
 			Assert.True (_scrollBar.ShowScrollIndicator);
 			Assert.True (_scrollBar.Visible);
 			Assert.True (_scrollBar.Visible);
-			Assert.Equal ("Dim.Absolute(1)", _scrollBar.Width.ToString ());
+			Assert.Equal ("Absolute(1)", _scrollBar.Width.ToString ());
 			Assert.Equal (1, _scrollBar.Bounds.Width);
 			Assert.Equal (1, _scrollBar.Bounds.Width);
-			Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))",
+			Assert.Equal ("Combine(DimView(Height,HostView()({X=0,Y=0,Width=80,Height=25}))-Absolute(1))",
 				_scrollBar.Height.ToString ());
 				_scrollBar.Height.ToString ());
 			Assert.Equal (24, _scrollBar.Bounds.Height);
 			Assert.Equal (24, _scrollBar.Bounds.Height);
 			Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
 			Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
 			Assert.True (_scrollBar.OtherScrollBarView.Visible);
 			Assert.True (_scrollBar.OtherScrollBarView.Visible);
-			Assert.Equal ("Dim.Combine(DimView(side=Width, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))",
+			Assert.Equal ("Combine(DimView(Width,HostView()({X=0,Y=0,Width=80,Height=25}))-Absolute(1))",
 				_scrollBar.OtherScrollBarView.Width.ToString ());
 				_scrollBar.OtherScrollBarView.Width.ToString ());
 			Assert.Equal (79, _scrollBar.OtherScrollBarView.Bounds.Width);
 			Assert.Equal (79, _scrollBar.OtherScrollBarView.Bounds.Width);
-			Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
+			Assert.Equal ("Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
 			Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
 			Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
 
 
 			_hostView.Lines = 10;
 			_hostView.Lines = 10;
 			_hostView.Redraw (_hostView.Bounds);
 			_hostView.Redraw (_hostView.Bounds);
 			Assert.False (_scrollBar.ShowScrollIndicator);
 			Assert.False (_scrollBar.ShowScrollIndicator);
 			Assert.False (_scrollBar.Visible);
 			Assert.False (_scrollBar.Visible);
-			Assert.Equal ("Dim.Absolute(1)", _scrollBar.Width.ToString ());
+			Assert.Equal ("Absolute(1)", _scrollBar.Width.ToString ());
 			Assert.Equal (1, _scrollBar.Bounds.Width);
 			Assert.Equal (1, _scrollBar.Bounds.Width);
-			Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))",
+			Assert.Equal ("Combine(DimView(Height,HostView()({X=0,Y=0,Width=80,Height=25}))-Absolute(1))",
 				_scrollBar.Height.ToString ());
 				_scrollBar.Height.ToString ());
 			Assert.Equal (24, _scrollBar.Bounds.Height);
 			Assert.Equal (24, _scrollBar.Bounds.Height);
 			Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
 			Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
 			Assert.True (_scrollBar.OtherScrollBarView.Visible);
 			Assert.True (_scrollBar.OtherScrollBarView.Visible);
-			Assert.Equal ("Dim.Combine(DimView(side=Width, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(0))",
+			Assert.Equal ("Combine(DimView(Width,HostView()({X=0,Y=0,Width=80,Height=25}))-Absolute(0))",
 				_scrollBar.OtherScrollBarView.Width.ToString ());
 				_scrollBar.OtherScrollBarView.Width.ToString ());
 			Assert.Equal (80, _scrollBar.OtherScrollBarView.Bounds.Width);
 			Assert.Equal (80, _scrollBar.OtherScrollBarView.Bounds.Width);
-			Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
+			Assert.Equal ("Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
 			Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
 			Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
 
 
 			_hostView.Cols = 60;
 			_hostView.Cols = 60;
 			_hostView.Redraw (_hostView.Bounds);
 			_hostView.Redraw (_hostView.Bounds);
 			Assert.False (_scrollBar.ShowScrollIndicator);
 			Assert.False (_scrollBar.ShowScrollIndicator);
 			Assert.False (_scrollBar.Visible);
 			Assert.False (_scrollBar.Visible);
-			Assert.Equal ("Dim.Absolute(1)", _scrollBar.Width.ToString ());
+			Assert.Equal ("Absolute(1)", _scrollBar.Width.ToString ());
 			Assert.Equal (1, _scrollBar.Bounds.Width);
 			Assert.Equal (1, _scrollBar.Bounds.Width);
-			Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))",
+			Assert.Equal ("Combine(DimView(Height,HostView()({X=0,Y=0,Width=80,Height=25}))-Absolute(1))",
 				_scrollBar.Height.ToString ());
 				_scrollBar.Height.ToString ());
 			Assert.Equal (24, _scrollBar.Bounds.Height);
 			Assert.Equal (24, _scrollBar.Bounds.Height);
 			Assert.False (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
 			Assert.False (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
 			Assert.False (_scrollBar.OtherScrollBarView.Visible);
 			Assert.False (_scrollBar.OtherScrollBarView.Visible);
-			Assert.Equal ("Dim.Combine(DimView(side=Width, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(0))",
+			Assert.Equal ("Combine(DimView(Width,HostView()({X=0,Y=0,Width=80,Height=25}))-Absolute(0))",
 				_scrollBar.OtherScrollBarView.Width.ToString ());
 				_scrollBar.OtherScrollBarView.Width.ToString ());
 			Assert.Equal (80, _scrollBar.OtherScrollBarView.Bounds.Width);
 			Assert.Equal (80, _scrollBar.OtherScrollBarView.Bounds.Width);
-			Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
+			Assert.Equal ("Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
 			Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
 			Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
 
 
 			_hostView.Lines = 40;
 			_hostView.Lines = 40;
 			_hostView.Redraw (_hostView.Bounds);
 			_hostView.Redraw (_hostView.Bounds);
 			Assert.True (_scrollBar.ShowScrollIndicator);
 			Assert.True (_scrollBar.ShowScrollIndicator);
 			Assert.True (_scrollBar.Visible);
 			Assert.True (_scrollBar.Visible);
-			Assert.Equal ("Dim.Absolute(1)", _scrollBar.Width.ToString ());
+			Assert.Equal ("Absolute(1)", _scrollBar.Width.ToString ());
 			Assert.Equal (1, _scrollBar.Bounds.Width);
 			Assert.Equal (1, _scrollBar.Bounds.Width);
-			Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(0))",
+			Assert.Equal ("Combine(DimView(Height,HostView()({X=0,Y=0,Width=80,Height=25}))-Absolute(0))",
 				_scrollBar.Height.ToString ());
 				_scrollBar.Height.ToString ());
 			Assert.Equal (25, _scrollBar.Bounds.Height);
 			Assert.Equal (25, _scrollBar.Bounds.Height);
 			Assert.False (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
 			Assert.False (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
 			Assert.False (_scrollBar.OtherScrollBarView.Visible);
 			Assert.False (_scrollBar.OtherScrollBarView.Visible);
-			Assert.Equal ("Dim.Combine(DimView(side=Width, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(0))",
+			Assert.Equal ("Combine(DimView(Width,HostView()({X=0,Y=0,Width=80,Height=25}))-Absolute(0))",
 				_scrollBar.OtherScrollBarView.Width.ToString ());
 				_scrollBar.OtherScrollBarView.Width.ToString ());
 			Assert.Equal (80, _scrollBar.OtherScrollBarView.Bounds.Width);
 			Assert.Equal (80, _scrollBar.OtherScrollBarView.Bounds.Width);
-			Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
+			Assert.Equal ("Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
 			Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
 			Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
 
 
 			_hostView.Cols = 120;
 			_hostView.Cols = 120;
 			_hostView.Redraw (_hostView.Bounds);
 			_hostView.Redraw (_hostView.Bounds);
 			Assert.True (_scrollBar.ShowScrollIndicator);
 			Assert.True (_scrollBar.ShowScrollIndicator);
 			Assert.True (_scrollBar.Visible);
 			Assert.True (_scrollBar.Visible);
-			Assert.Equal ("Dim.Absolute(1)", _scrollBar.Width.ToString ());
+			Assert.Equal ("Absolute(1)", _scrollBar.Width.ToString ());
 			Assert.Equal (1, _scrollBar.Bounds.Width);
 			Assert.Equal (1, _scrollBar.Bounds.Width);
-			Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))",
+			Assert.Equal ("Combine(DimView(Height,HostView()({X=0,Y=0,Width=80,Height=25}))-Absolute(1))",
 				_scrollBar.Height.ToString ());
 				_scrollBar.Height.ToString ());
 			Assert.Equal (24, _scrollBar.Bounds.Height);
 			Assert.Equal (24, _scrollBar.Bounds.Height);
 			Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
 			Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
 			Assert.True (_scrollBar.OtherScrollBarView.Visible);
 			Assert.True (_scrollBar.OtherScrollBarView.Visible);
-			Assert.Equal ("Dim.Combine(DimView(side=Width, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))",
+			Assert.Equal ("Combine(DimView(Width,HostView()({X=0,Y=0,Width=80,Height=25}))-Absolute(1))",
 				_scrollBar.OtherScrollBarView.Width.ToString ());
 				_scrollBar.OtherScrollBarView.Width.ToString ());
 			Assert.Equal (79, _scrollBar.OtherScrollBarView.Bounds.Width);
 			Assert.Equal (79, _scrollBar.OtherScrollBarView.Bounds.Width);
-			Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
+			Assert.Equal ("Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
 			Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
 			Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
 		}
 		}
 
 

+ 5 - 223
UnitTests/Views/ScrollViewTests.cs

@@ -1,4 +1,8 @@
-using NStack;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
 using Xunit;
 using Xunit;
 using Xunit.Abstractions;
 using Xunit.Abstractions;
 
 
@@ -276,227 +280,5 @@ namespace Terminal.Gui.ViewTests {
 ◄░░░├─┤░► 
 ◄░░░├─┤░► 
 ", output);
 ", output);
 		}
 		}
-
-		[Fact, AutoInitShutdown]
-		public void Frame_And_Labels_Does_Not_Overspill_ScrollView ()
-		{
-			var sv = new ScrollView {
-				X = 3,
-				Y = 3,
-				Width = 10,
-				Height = 10,
-				ContentSize = new Size (50, 50)
-			};
-			for (int i = 0; i < 8; i++) {
-				sv.Add (new CustomButton ("█", $"Button {i}", 20, 3) { Y = i * 3 });
-			}
-			Application.Top.Add (sv);
-			Application.Begin (Application.Top);
-
-			TestHelpers.AssertDriverContentsWithFrameAre (@"
-   █████████▲
-   ██████But┬
-   █████████┴
-   ┌────────░
-   │     But░
-   └────────░
-   ┌────────░
-   │     But░
-   └────────▼
-   ◄├┤░░░░░► ", output);
-
-			sv.ContentOffset = new Point (5, 5);
-			Application.Refresh ();
-			TestHelpers.AssertDriverContentsWithFrameAre (@"
-   ─────────▲
-   ─────────┬
-    Button 2│
-   ─────────┴
-   ─────────░
-    Button 3░
-   ─────────░
-   ─────────░
-    Button 4▼
-   ◄├─┤░░░░► ", output);
-		}
-
-		private class CustomButton : FrameView {
-			private Label labelFill;
-			private Label labelText;
-
-			public CustomButton (string fill, ustring text, int width, int height)
-			{
-				Width = width;
-				Height = height;
-				labelFill = new Label () { AutoSize = false, Width = Dim.Fill (), Height = Dim.Fill (), Visible = false };
-				var fillText = new System.Text.StringBuilder ();
-				for (int i = 0; i < Bounds.Height; i++) {
-					if (i > 0) {
-						fillText.AppendLine ("");
-					}
-					for (int j = 0; j < Bounds.Width; j++) {
-						fillText.Append (fill);
-					}
-				}
-				labelFill.Text = fillText.ToString ();
-				labelText = new Label (text) { X = Pos.Center (), Y = Pos.Center () };
-				Add (labelFill, labelText);
-				CanFocus = true;
-			}
-
-			public override bool OnEnter (View view)
-			{
-				Border.BorderStyle = BorderStyle.None;
-				Border.DrawMarginFrame = false;
-				labelFill.Visible = true;
-				view = this;
-				return base.OnEnter (view);
-			}
-
-			public override bool OnLeave (View view)
-			{
-				Border.BorderStyle = BorderStyle.Single;
-				Border.DrawMarginFrame = true;
-				labelFill.Visible = false;
-				if (view == null)
-					view = this;
-				return base.OnLeave (view);
-			}
-		}
-
-		[Fact, AutoInitShutdown]
-		public void Clear_Window_Inside_ScrollView ()
-		{
-			var topLabel = new Label ("At 15,0") { X = 15 };
-			var sv = new ScrollView {
-				X = 3,
-				Y = 3,
-				Width = 10,
-				Height = 10,
-				ContentSize = new Size (23, 23),
-				KeepContentAlwaysInViewport = false
-			};
-			var bottomLabel = new Label ("At 15,15") { X = 15, Y = 15 };
-			Application.Top.Add (topLabel, sv, bottomLabel);
-			Application.Begin (Application.Top);
-
-			TestHelpers.AssertDriverContentsWithFrameAre (@"
-               At 15,0 
-                       
-                       
-            ▲          
-            ┬          
-            ┴          
-            ░          
-            ░          
-            ░          
-            ░          
-            ░          
-            ▼          
-   ◄├┤░░░░░►           
-                       
-                       
-               At 15,15", output);
-
-			var attributes = new Attribute [] {
-				Colors.TopLevel.Normal,
-				Colors.TopLevel.Focus,
-				Colors.Base.Normal
-			};
-
-			TestHelpers.AssertDriverColorsAre (@"
-00000000000000000000000
-00000000000000000000000
-00000000000000000000000
-00000000000010000000000
-00000000000010000000000
-00000000000010000000000
-00000000000010000000000
-00000000000010000000000
-00000000000010000000000
-00000000000010000000000
-00000000000010000000000
-00000000000010000000000
-00011111111110000000000
-00000000000000000000000
-00000000000000000000000
-00000000000000000000000", attributes);
-
-			sv.Add (new Window ("1") { X = 3, Y = 3, Width = 20, Height = 20 });
-			Application.Refresh ();
-			TestHelpers.AssertDriverContentsWithFrameAre (@"
-               At 15,0 
-                       
-                       
-            ▲          
-            ┬          
-            ┴          
-      ┌ 1 ──░          
-      │     ░          
-      │     ░          
-      │     ░          
-      │     ░          
-      │     ▼          
-   ◄├┤░░░░░►           
-                       
-                       
-               At 15,15", output);
-
-			TestHelpers.AssertDriverColorsAre (@"
-00000000000000000000000
-00000000000000000000000
-00000000000000000000000
-00000000000010000000000
-00000000000010000000000
-00000000000010000000000
-00000022222210000000000
-00000022222210000000000
-00000022222210000000000
-00000022222210000000000
-00000022222210000000000
-00000022222210000000000
-00011111111110000000000
-00000000000000000000000
-00000000000000000000000
-00000000000000000000000", attributes);
-
-			sv.ContentOffset = new Point (20, 20);
-			Application.Refresh ();
-			TestHelpers.AssertDriverContentsWithFrameAre (@"
-               At 15,0 
-                       
-                       
-     │      ▲          
-     │      ░          
-   ──┘      ░          
-            ░          
-            ░          
-            ┬          
-            │          
-            ┴          
-            ▼          
-   ◄░░░░├─┤►           
-                       
-                       
-               At 15,15", output);
-
-			TestHelpers.AssertDriverColorsAre (@"
-00000000000000000000000
-00000000000000000000000
-00000000000000000000000
-00022200000010000000000
-00022200000010000000000
-00022200000010000000000
-00000000000010000000000
-00000000000010000000000
-00000000000010000000000
-00000000000010000000000
-00000000000010000000000
-00000000000010000000000
-00011111111110000000000
-00000000000000000000000
-00000000000000000000000
-00000000000000000000000", attributes);
-		}
 	}
 	}
 }
 }

+ 1 - 1
UnitTests/Views/StatusBarTests.cs

@@ -31,7 +31,7 @@ namespace Terminal.Gui.ViewTests {
 			Assert.False (sb.CanFocus);
 			Assert.False (sb.CanFocus);
 			Assert.Equal (Colors.Menu, sb.ColorScheme);
 			Assert.Equal (Colors.Menu, sb.ColorScheme);
 			Assert.Equal (0, sb.X);
 			Assert.Equal (0, sb.X);
-			Assert.Equal ("Pos.AnchorEnd(margin=1)", sb.Y.ToString ());
+			Assert.Equal ("AnchorEnd(1)", sb.Y.ToString ());
 			Assert.Equal (Dim.Fill (), sb.Width);
 			Assert.Equal (Dim.Fill (), sb.Width);
 			Assert.Equal (1, sb.Height);
 			Assert.Equal (1, sb.Height);
 
 

+ 6 - 6
UnitTests/Views/TextViewTests.cs

@@ -1524,8 +1524,8 @@ namespace Terminal.Gui.ViewTests {
 			Assert.True (_textView.AllowsReturn);
 			Assert.True (_textView.AllowsReturn);
 			Assert.Equal (4, _textView.TabWidth);
 			Assert.Equal (4, _textView.TabWidth);
 			Assert.True (_textView.AllowsTab);
 			Assert.True (_textView.AllowsTab);
-			Assert.Equal ("Dim.Absolute(30)", _textView.Width.ToString ());
-			Assert.Equal ("Dim.Absolute(10)", _textView.Height.ToString ());
+			Assert.Equal ("Absolute(30)", _textView.Width.ToString ());
+			Assert.Equal ("Absolute(10)", _textView.Height.ToString ());
 			Assert.False (_textView.WordWrap);
 			Assert.False (_textView.WordWrap);
 
 
 			_textView.WordWrap = true;
 			_textView.WordWrap = true;
@@ -1535,8 +1535,8 @@ namespace Terminal.Gui.ViewTests {
 			Assert.False (_textView.AllowsReturn);
 			Assert.False (_textView.AllowsReturn);
 			Assert.Equal (0, _textView.TabWidth);
 			Assert.Equal (0, _textView.TabWidth);
 			Assert.False (_textView.AllowsTab);
 			Assert.False (_textView.AllowsTab);
-			Assert.Equal ("Dim.Absolute(30)", _textView.Width.ToString ());
-			Assert.Equal ("Dim.Absolute(1)", _textView.Height.ToString ());
+			Assert.Equal ("Absolute(30)", _textView.Width.ToString ());
+			Assert.Equal ("Absolute(1)", _textView.Height.ToString ());
 			Assert.False (_textView.WordWrap);
 			Assert.False (_textView.WordWrap);
 
 
 			_textView.WordWrap = true;
 			_textView.WordWrap = true;
@@ -1546,8 +1546,8 @@ namespace Terminal.Gui.ViewTests {
 			Assert.True (_textView.AllowsReturn);
 			Assert.True (_textView.AllowsReturn);
 			Assert.Equal (4, _textView.TabWidth);
 			Assert.Equal (4, _textView.TabWidth);
 			Assert.True (_textView.AllowsTab);
 			Assert.True (_textView.AllowsTab);
-			Assert.Equal ("Dim.Absolute(30)", _textView.Width.ToString ());
-			Assert.Equal ("Dim.Absolute(10)", _textView.Height.ToString ());
+			Assert.Equal ("Absolute(30)", _textView.Width.ToString ());
+			Assert.Equal ("Absolute(10)", _textView.Height.ToString ());
 			Assert.False (_textView.WordWrap);
 			Assert.False (_textView.WordWrap);
 		}
 		}
 
 

+ 3 - 1
docfx/v2specs/View.md

@@ -23,7 +23,7 @@ This covers my thinking on how we will refactor `View` and the classes in the `V
   * *View* - A base-class for implementing higher level visual/interactive Terminal.Gui elements. Implemented in the `View` base-class, which is a `Responder` and a `Container`. 
   * *View* - A base-class for implementing higher level visual/interactive Terminal.Gui elements. Implemented in the `View` base-class, which is a `Responder` and a `Container`. 
     * In v2 we will move all logic for rendering out of `View` and `Window` and into `View`.
     * In v2 we will move all logic for rendering out of `View` and `Window` and into `View`.
   * *SubView* - A View that is contained in antoher view and will be rendered as part of the containing view's *ContentArea*. SubViews are added to another view via the `View.Add` method. A View may only be a SubView of a single View. 
   * *SubView* - A View that is contained in antoher view and will be rendered as part of the containing view's *ContentArea*. SubViews are added to another view via the `View.Add` method. A View may only be a SubView of a single View. 
-  * *SuperView* - The View that a *SubView* was added to. 
+  * *SuperView* - The View that is a container for SubViews. Referrs to the View another View was was added to as *SubView*. 
   * *Child View* - A view that is held by another view in a parent/child relationshiop, but is NOT a SubView. Examples of this are sub-menus of `MenuBar`. 
   * *Child View* - A view that is held by another view in a parent/child relationshiop, but is NOT a SubView. Examples of this are sub-menus of `MenuBar`. 
   * *Parent View* - A view that holds a reference to another view in a parent/child relationship, but is NOT a SuperView of the child. 
   * *Parent View* - A view that holds a reference to another view in a parent/child relationship, but is NOT a SuperView of the child. 
   * *Thickness* - Describes rectangle where each of the four sides can have a width. Valid width values are >= 0. The inner area of a Thickness is the sum of the widths of the four sides minus the size of the rectangle.
   * *Thickness* - Describes rectangle where each of the four sides can have a width. Valid width values are >= 0. The inner area of a Thickness is the sum of the widths of the four sides minus the size of the rectangle.
@@ -55,6 +55,8 @@ This covers my thinking on how we will refactor `View` and the classes in the `V
 * PanelView (done)
 * PanelView (done)
 * FrameView (almost done)
 * FrameView (almost done)
 * Window?
 * Window?
+  * *Tile*, *Tiled*, *Tiling* - Refers to a form of layout where the SubViews of a View are visually arranged such that their Frames abut each other and do not overlap. In a Tiled view arragnement there is no Z-ordering.
+  * *Overlap*, *Overlapped*, *Overlapping* - Refers to a form of layout where the SubViews of a View are visually arranged such that their Frames can overlap. In Overlap view arragements there is a Z-axis (Z-order) in addition to the X and Y dimension. The Z-order indicates which Views are shown above other views.
 
 
 
 
   ### Questions
   ### Questions

部分文件因为文件数量过多而无法显示