浏览代码

WIP - futzing with different layout math ideas

Tig Kindel 2 年之前
父节点
当前提交
16f8ab89be
共有 3 个文件被更改,包括 255 次插入202 次删除
  1. 70 27
      Terminal.Gui/Core/Container.cs
  2. 147 140
      Terminal.Gui/Core/View.cs
  3. 38 35
      UICatalog/Scenarios/TileViewExperiment.cs

+ 70 - 27
Terminal.Gui/Core/Container.cs

@@ -9,31 +9,69 @@ namespace Terminal.Gui {
 
 	public class Frame : View {
 
+		/// <summary>
+		/// Frames are a special form of <see cref="View"/> that act as adornments; they appear outside of the <see cref="View>Bounds"/>
+		/// eanbling borders, menus, etc... 
+		/// </summary>
 		public Frame ()
 		{
 			IgnoreBorderPropertyOnRedraw = true;
 		}
 
-		public virtual void OnDrawSubViews (Rect clipRect)
+		/// <summary>
+		/// The Parent of this Frame (Adornment). 
+		/// </summary>
+		public View Parent { get; set; }
+
+		/// <summary>
+		/// Frames cannot be used as sub-views, so this method always throws an <see cref="InvalidOperationException"/>.
+		/// TODO: Are we sure?
+		/// </summary>
+		public override View SuperView {
+			get {
+				return null;
+			}
+			set {
+				throw new NotImplementedException ();
+			}
+		}
+
+		/// <inheritdoc/>
+		public override void ViewToScreen (int col, int row, out int rcol, out int rrow, bool clipped = true)
 		{
-		//	if (Subviews == null) {
-		//		return;
-		//	}
+			// Frames are children of a View, not SubViews. Thus ViewToScreen will not work.
+			// To get the screen-relative coordinates of a Frame, we need to know who
+			// the Parent is
 
-		//	foreach (var view in Subviews) {
-		//		// BUGBUG: v2 - shouldn't this be !view.LayoutNeeded? Why draw if layout is going to happen and we'll just draw again?
-		//		if (view.LayoutNeeded) {
-		//			view.LayoutSubviews ();
-		//		}
-		//		if ((view.Visible && !view.NeedDisplay.IsEmpty && view.Frame.Width > 0 && view.Frame.Height > 0) || view.ChildNeedsDisplay) {
-		//			view.Redraw (view.Bounds);
+			// Computes the real row, col relative to the screen.
+			var inner = Parent?.Bounds ?? Bounds;
+			rrow = row - inner.Y;
+			rcol = col - inner.X;
 
-		//			view.NeedDisplay = Rect.Empty;
-		//			// BUGBUG - v2 why does this need to be set to false?
-		//			// Shouldn't it be set when the subviews draw?
-		//			view.ChildNeedsDisplay = false;
-		//		}
-		//	}
+			Parent?.ViewToScreen (rcol, rrow, out rcol, out rrow, clipped);
+
+		}
+
+		public virtual void OnDrawSubViews (Rect clipRect)
+		{
+			//	if (Subviews == null) {
+			//		return;
+			//	}
+
+			//	foreach (var view in Subviews) {
+			//		// BUGBUG: v2 - shouldn't this be !view.LayoutNeeded? Why draw if layout is going to happen and we'll just draw again?
+			//		if (view.LayoutNeeded) {
+			//			view.LayoutSubviews ();
+			//		}
+			//		if ((view.Visible && !view.NeedDisplay.IsEmpty && view.Frame.Width > 0 && view.Frame.Height > 0) || view.ChildNeedsDisplay) {
+			//			view.Redraw (view.Bounds);
+
+			//			view.NeedDisplay = Rect.Empty;
+			//			// BUGBUG - v2 why does this need to be set to false?
+			//			// Shouldn't it be set when the subviews draw?
+			//			view.ChildNeedsDisplay = false;
+			//		}
+			//	}
 
 		}
 
@@ -53,9 +91,13 @@ namespace Terminal.Gui {
 			}
 		}
 
-		public override void Redraw (Rect bounds)
+		/// <summary>
+		/// Redraws the Frames that comprise the <see cref="Frame"/>.
+		/// </summary>
+		/// <param name="clipRect"></param>
+		public override void Redraw (Rect clipRect)
 		{
-			
+
 			//OnDrawContent (bounds);
 			//OnDrawSubViews (bounds);
 			//OnDrawContentComplete (bounds);
@@ -64,24 +106,25 @@ namespace Terminal.Gui {
 				Driver.SetAttribute (ColorScheme.Normal);
 			}
 
-			Thickness.Draw (Frame, (string)Data);
+			var screenBounds = ViewToScreen (Frame);
+			Thickness.Draw (screenBounds, (string)Data);
 
 			//OnDrawContent (bounds); 
 
 			if (BorderStyle != BorderStyle.None) {
 				var lc = new LineCanvas ();
-				lc.AddLine (Frame.Location, Frame.Width - 1, Orientation.Horizontal, BorderStyle);
-				lc.AddLine (Frame.Location, Frame.Height - 1, Orientation.Vertical, BorderStyle);
+				lc.AddLine (screenBounds.Location, Frame.Width - 1, Orientation.Horizontal, BorderStyle);
+				lc.AddLine (screenBounds.Location, Frame.Height - 1, Orientation.Vertical, BorderStyle);
 
-				lc.AddLine (new Point (Frame.X, Frame.Y + Frame.Height - 1), Frame.Width - 1, Orientation.Horizontal, BorderStyle);
-				lc.AddLine (new Point (Frame.X + Frame.Width - 1, Frame.Y), Frame.Height - 1, Orientation.Vertical, BorderStyle);
-				foreach (var p in lc.GenerateImage (Frame)) {
+				lc.AddLine (new Point (screenBounds.X, screenBounds.Y + screenBounds.Height - 1), screenBounds.Width - 1, Orientation.Horizontal, BorderStyle);
+				lc.AddLine (new Point (screenBounds.X + screenBounds.Width - 1, screenBounds.Y), screenBounds.Height - 1, Orientation.Vertical, BorderStyle);
+				foreach (var p in lc.GenerateImage (screenBounds)) {
 					Driver.Move (p.Key.X, p.Key.Y);
 					Driver.AddRune (p.Value);
 				}
 
 				if (!ustring.IsNullOrEmpty (Title)) {
-					Driver.DrawWindowTitle (Frame, Title, 0, 0, 0, 0);
+					Driver.DrawWindowTitle (screenBounds, Title, 0, 0, 0, 0);
 				}
 			}
 		}
@@ -100,7 +143,7 @@ namespace Terminal.Gui {
 		/// <summary>
 		/// Gets the rectangle that describes the inner area of the frame. The Location is always 0, 0.
 		/// </summary>
-		public new Rect Bounds {
+		public Rect Bounds {
 			get {
 				if (Thickness != null) {
 					new Rect (Point.Empty, Frame.Size);

+ 147 - 140
Terminal.Gui/Core/View.cs

@@ -467,22 +467,34 @@ namespace Terminal.Gui {
 			IgnoreBorderPropertyOnRedraw = true;
 			Margin?.Dispose ();
 			Margin = new Frame () {
+				X = 0,
+				Y = 0,
 				Thickness = new Thickness (0),
-				ColorScheme = SuperView?.ColorScheme ?? ColorScheme
+				ColorScheme = SuperView?.ColorScheme ?? ColorScheme,
+				// TODO: Create View.AddAdornment
+				Parent = this
 			};
 			//Margin.DiagnosticsLabel.Text = "Margin";
 
 			BorderFrame?.Dispose ();
 			BorderFrame = new Frame () {
+				X = 0,
+				Y = 0,
 				BorderStyle = BorderStyle.Single,
 				Thickness = new Thickness (0),
-				ColorScheme = ColorScheme
+				ColorScheme = ColorScheme,
+				// TODO: Create View.AddAdornment
+				Parent = this
 			};
 
 			Padding?.Dispose ();
 			Padding = new Frame () {
+				X = 0,
+				Y = 0,
 				Thickness = new Thickness (0),
-				ColorScheme = ColorScheme
+				ColorScheme = ColorScheme,
+				// TODO: Create View.AddAdornment
+				Parent = this
 			};
 		}
 
@@ -539,8 +551,8 @@ namespace Terminal.Gui {
 				if (Padding == null || BorderFrame == null || Margin == null) {
 					return new Rect (Point.Empty, Frame.Size);
 				}
-				var frameRelativeBounds = Padding.Thickness.GetInnerRect (BorderFrame.Thickness.GetInnerRect (Margin.Thickness.GetInnerRect (new Rect (Point.Empty, Frame.Size))));
-				return frameRelativeBounds;
+				var superviewRelativeBounds = Padding.Thickness.GetInnerRect (BorderFrame.Thickness.GetInnerRect (Margin.Thickness.GetInnerRect (Frame)));
+				return new Rect (Point.Empty, superviewRelativeBounds.Size);
 			}
 			set {
 				Debug.WriteLine ($"It makes no sense to set Bounds. Use Frame instead. Bounds: {value}");
@@ -548,15 +560,6 @@ namespace Terminal.Gui {
 			}
 		}
 
-		public Rect ScreenRelativeBounds {
-			get {
-				if (Padding == null || BorderFrame == null || Margin == null) {
-					return Frame;
-				}
-				return Padding.Thickness.GetInnerRect (BorderFrame.Thickness.GetInnerRect (Margin.Thickness.GetInnerRect (Frame)));
-			}
-		}
-
 		Pos x, y;
 
 		/// <summary>
@@ -727,7 +730,14 @@ namespace Terminal.Gui {
 		/// Returns the container for this view, or null if this view has not been added to a container.
 		/// </summary>
 		/// <value>The super view.</value>
-		public View SuperView => container;
+		public virtual View SuperView {
+			get {
+				return container;
+			}
+			set {
+				throw new NotImplementedException ();
+			}
+		}
 
 		/// <summary>
 		/// Initializes a new instance of a <see cref="Terminal.Gui.LayoutStyle.Absolute"/> <see cref="View"/> class with the absolute
@@ -1200,8 +1210,8 @@ namespace Terminal.Gui {
 		public virtual void ViewToScreen (int col, int row, out int rcol, out int rrow, bool clipped = true)
 		{
 			// Computes the real row, col relative to the screen.
-			rrow = row + frame.Y;
-			rcol = col + frame.X;
+			rrow = row + Frame.Y;
+			rcol = col + Frame.X;
 
 			var curContainer = container;
 			while (curContainer != null) {
@@ -1537,8 +1547,9 @@ namespace Terminal.Gui {
 			ChildNeedsDisplay = false;
 		}
 
-		public virtual bool OnDrawFrames (Rect frame)
+		public virtual bool OnDrawFrames ()
 		{
+			// TODO: add cancellable event
 			//if (!DrawFrames?.Invoke (frame)) {
 			//	return false;
 			//}
@@ -1547,24 +1558,80 @@ namespace Terminal.Gui {
 				return false;
 			}
 			
-			Margin.Redraw (Margin.Bounds);
+			Margin.Redraw (Margin.Frame);
 			BorderFrame.Title = Title;
-			BorderFrame.Redraw (BorderFrame.Bounds);
-			Padding.Redraw (BorderFrame.Bounds);
+			BorderFrame.Redraw (BorderFrame.Frame);
+			Padding.Redraw (Padding.Frame);
 
-			var border = Margin.Thickness.GetInnerRect (frame);
-			var padding = BorderFrame.Thickness.GetInnerRect (border);
-			var content = Padding.Thickness.GetInnerRect (padding);
+			return true;
+		}
 
-			//// Draw the diagnostics label on the bottom of the content
-			//var tf = new TextFormatter () {
-			//	Text = $"Content {Bounds}",
-			//	Alignment = TextAlignment.Centered,
-			//	VerticalAlignment = VerticalTextAlignment.Bottom
-			//};
-			//tf.Draw (content, ColorScheme.Normal, ColorScheme.Normal);
 
-			return true;
+		/// <summary>
+		/// Event invoked when the content area of the View is to be drawn.
+		/// </summary>
+		/// <remarks>
+		/// <para>
+		/// Will be invoked before any subviews added with <see cref="Add(View)"/> have been drawn.
+		/// </para>
+		/// <para>
+		/// Rect provides the view-relative rectangle describing the currently visible viewport into the <see cref="View"/>.
+		/// </para>
+		/// </remarks>
+		public event Action<Rect> DrawContent;
+
+		/// <summary>
+		/// Enables overrides to draw infinitely scrolled content and/or a background behind added controls. 
+		/// </summary>
+		/// <param name="contentArea">The view-relative rectangle describing the currently visible viewport into the <see cref="View"/></param>
+		/// <remarks>
+		/// This method will be called before any subviews added with <see cref="Add(View)"/> have been drawn. 
+		/// </remarks>
+		public virtual void OnDrawContent (Rect contentArea)
+		{
+			// TODO: Make DrawContent a cancelable event
+			DrawContent?.Invoke (contentArea);
+
+			// if (!DrawContent?.Invoke(viewport)) {
+			if (!ustring.IsNullOrEmpty (TextFormatter.Text)) {
+				//Rect containerBounds = GetContainerBounds ();
+				//Clear (ViewToScreen (GetNeedDisplay (containerBounds)));
+				SetChildNeedsDisplay ();
+				// Draw any Text
+				if (TextFormatter != null) {
+					TextFormatter.NeedsFormat = true;
+				}
+				TextFormatter?.Draw (ViewToScreen(Bounds), HasFocus ? ColorScheme.Focus : GetNormalColor (),
+				    HasFocus ? ColorScheme.HotFocus : Enabled ? ColorScheme.HotNormal : ColorScheme.Disabled,
+				    contentArea, false);
+			}
+			// }
+
+		}
+
+		/// <summary>
+		/// Event invoked when the content area of the View is completed drawing.
+		/// </summary>
+		/// <remarks>
+		/// <para>
+		/// Will be invoked after any subviews removed with <see cref="Remove(View)"/> have been completed drawing.
+		/// </para>
+		/// <para>
+		/// Rect provides the view-relative rectangle describing the currently visible viewport into the <see cref="View"/>.
+		/// </para>
+		/// </remarks>
+		public event Action<Rect> DrawContentComplete;
+
+		/// <summary>
+		/// Enables overrides after completed drawing infinitely scrolled content and/or a background behind removed controls.
+		/// </summary>
+		/// <param name="viewport">The view-relative rectangle describing the currently visible viewport into the <see cref="View"/></param>
+		/// <remarks>
+		/// This method will be called after any subviews removed with <see cref="Remove(View)"/> have been completed drawing.
+		/// </remarks>
+		public virtual void OnDrawContentComplete (Rect viewport)
+		{
+			DrawContentComplete?.Invoke (viewport);
 		}
 
 		/// <summary>
@@ -1590,53 +1657,37 @@ namespace Terminal.Gui {
 				return;
 			}
 
-			OnDrawFrames (Frame);
+			OnDrawFrames ();
+
+			// TODO: Implement complete event
 			// OnDrawFramesComplete (Frame)
 
 			if (ColorScheme != null) {
 				Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
 			}
 
-			var clipRect = new Rect (Point.Empty, frame.Size);
+			var prevClip = Driver.Clip;
+			Driver.Clip = ViewToScreen(Bounds);
 
-			var boundsAdjustedForBorder = Bounds;
+			// TODO: Remove once new v2 api is complete
 			if (!IgnoreBorderPropertyOnRedraw && Border != null) {
 				throw new InvalidOperationException ("Don't use Border!");
-				//Border.DrawContent (this);
-				//boundsAdjustedForBorder = new Rect (bounds.X + 1, bounds.Y + 1, Math.Max (0, bounds.Width - 2), Math.Max (0, bounds.Height - 2));
-			} else if (ustring.IsNullOrEmpty (TextFormatter.Text) &&
-				(GetType ().IsNestedPublic) && !IsOverridden (this, "Redraw") &&
-				(!NeedDisplay.IsEmpty || ChildNeedsDisplay || LayoutNeeded)) {
-
-				Clear ();
-				SetChildNeedsDisplay ();
-			}
-
-			if (!ustring.IsNullOrEmpty (TextFormatter.Text)) {
-				Rect containerBounds = GetContainerBounds ();
-				Clear (ViewToScreen (GetNeedDisplay (containerBounds)));
-				SetChildNeedsDisplay ();
-				// Draw any Text
-				if (TextFormatter != null) {
-					TextFormatter.NeedsFormat = true;
-				}
-				TextFormatter?.Draw (ViewToScreen (boundsAdjustedForBorder), HasFocus ? ColorScheme.Focus : GetNormalColor (),
-				    HasFocus ? ColorScheme.HotFocus : Enabled ? ColorScheme.HotNormal : ColorScheme.Disabled,
-				    containerBounds);
-			}
-
-			// Invoke DrawContentEvent
-			OnDrawContent (boundsAdjustedForBorder);
+			} 
 
+			// Draw content
+			OnDrawContent (Bounds);
+			
+			// Draw subviews
+			// TODO: Implement OnDrawSubviews (cancelable);		
 			if (subviews != null) {
 				foreach (var view in subviews) {
 					if (!view.NeedDisplay.IsEmpty || view.ChildNeedsDisplay || view.LayoutNeeded) {
-						if (view.Frame.IntersectsWith (clipRect) && (view.Frame.IntersectsWith (boundsAdjustedForBorder) || boundsAdjustedForBorder.X < 0 || bounds.Y < 0)) {
-							if (view.LayoutNeeded)
+						if (view.Frame.IntersectsWith (Driver.Clip) && (view.Frame.IntersectsWith (Bounds) || Bounds.X < 0 || Bounds.Y < 0)) {
+							if (view.LayoutNeeded) {
 								view.LayoutSubviews ();
+							}
 
 							// Draw the subview
-							// Use the view's bounds (view-relative; Location will always be (0,0)
 							if (view.Visible && view.Frame.Width > 0 && view.Frame.Height > 0) {
 								var rect = view.Bounds;
 								view.OnDrawContent (rect);
@@ -1651,8 +1702,9 @@ namespace Terminal.Gui {
 			}
 
 			// Invoke DrawContentCompleteEvent
-			OnDrawContentComplete (boundsAdjustedForBorder);
+			OnDrawContentComplete (Bounds);
 
+			Driver.Clip = prevClip;
 			ClearLayoutNeeded ();
 			ClearNeedsDisplay ();
 		}
@@ -1689,56 +1741,6 @@ namespace Terminal.Gui {
 			return containerBounds;
 		}
 
-		/// <summary>
-		/// Event invoked when the content area of the View is to be drawn.
-		/// </summary>
-		/// <remarks>
-		/// <para>
-		/// Will be invoked before any subviews added with <see cref="Add(View)"/> have been drawn.
-		/// </para>
-		/// <para>
-		/// Rect provides the view-relative rectangle describing the currently visible viewport into the <see cref="View"/>.
-		/// </para>
-		/// </remarks>
-		public event Action<Rect> DrawContent;
-
-		/// <summary>
-		/// Enables overrides to draw infinitely scrolled content and/or a background behind added controls. 
-		/// </summary>
-		/// <param name="viewport">The view-relative rectangle describing the currently visible viewport into the <see cref="View"/></param>
-		/// <remarks>
-		/// This method will be called before any subviews added with <see cref="Add(View)"/> have been drawn. 
-		/// </remarks>
-		public virtual void OnDrawContent (Rect viewport)
-		{
-			DrawContent?.Invoke (viewport);
-		}
-
-		/// <summary>
-		/// Event invoked when the content area of the View is completed drawing.
-		/// </summary>
-		/// <remarks>
-		/// <para>
-		/// Will be invoked after any subviews removed with <see cref="Remove(View)"/> have been completed drawing.
-		/// </para>
-		/// <para>
-		/// Rect provides the view-relative rectangle describing the currently visible viewport into the <see cref="View"/>.
-		/// </para>
-		/// </remarks>
-		public event Action<Rect> DrawContentComplete;
-
-		/// <summary>
-		/// Enables overrides after completed drawing infinitely scrolled content and/or a background behind removed controls.
-		/// </summary>
-		/// <param name="viewport">The view-relative rectangle describing the currently visible viewport into the <see cref="View"/></param>
-		/// <remarks>
-		/// This method will be called after any subviews removed with <see cref="Remove(View)"/> have been completed drawing.
-		/// </remarks>
-		public virtual void OnDrawContentComplete (Rect viewport)
-		{
-			DrawContentComplete?.Invoke (viewport);
-		}
-
 		/// <summary>
 		/// Causes the specified subview to have focus.
 		/// </summary>
@@ -2269,8 +2271,8 @@ namespace Terminal.Gui {
 		/// <param name="superviewRelativeBounds">The superview-relative bounds for <see cref="SuperView"/>. </param>
 		/// <remarks>
 		/// <see cref="Frame"/> is screen-relative; <see cref="Bounds"/> is view-relative. 
-		/// In v1, <see cref="Bounds"/> always has a location of {0, 0}. In v2, <see cref="Bounds"/> can be non-zero, 
-		/// refelcting the Margin, Border, and Padding.
+		///// In v1, <see cref="Bounds"/> always has a location of {0, 0}. In v2, <see cref="Bounds"/> can be non-zero, 
+		///// refelcting the Margin, Border, and Padding.
 		/// </remarks>
 		internal void SetRelativeLayout (Rect superviewRelativeBounds)
 		{
@@ -2281,7 +2283,11 @@ namespace Terminal.Gui {
 				autosize = GetAutoSize ();
 			}
 
-			bool hasFrame = SuperView?.Margin != null || SuperView?.BorderFrame != null || SuperView?.Padding != null;
+			bool superviewHasFrame = SuperView?.Margin != null || SuperView?.BorderFrame != null || SuperView?.Padding != null;
+			var contentArea = superviewRelativeBounds;
+			if (superviewHasFrame) {
+				contentArea = SuperView.Padding.Thickness.GetInnerRect (SuperView.BorderFrame.Thickness.GetInnerRect (SuperView.Margin.Thickness.GetInnerRect (superviewRelativeBounds)));
+			}
 
 			actX = x?.Anchor (superviewRelativeBounds.Width) ?? 0;
 			actW = Math.Max (CalculateActualWidth (width, superviewRelativeBounds, actX, autosize), 0);
@@ -2295,45 +2301,45 @@ namespace Terminal.Gui {
 					actW = !autosize.IsEmpty && autosize.Width > actW ? autosize.Width : actW;
 				}
 				actX = x.Anchor (superviewRelativeBounds.Width - actW);
-				if (hasFrame) {
-					actX += superviewRelativeBounds.X;
+				if (superviewHasFrame) {
+					actX += contentArea.X;
 				}
 				break;
 
 			case Pos.PosAbsolute:
 
-				if (hasFrame) {
-					actX += superviewRelativeBounds.X;
+				if (superviewHasFrame) {
+					actX += contentArea.X;
 				}
 				break;
 
 			case Pos.PosAnchorEnd:
 
-				if (hasFrame) {
-					actX += superviewRelativeBounds.X;
+				if (superviewHasFrame) {
+					actX += contentArea.X;
 				}
 				break;
 
 			case Pos.PosCombine:
 
-				if (hasFrame) {
+				if (superviewHasFrame) {
 					var pc = x as Pos.PosCombine;
 					switch (pc.left) {
 					case Pos.PosAbsolute:
-						actX += superviewRelativeBounds.X;
+						actX += contentArea.X;
 						break;
 
 					case Pos.PosAnchorEnd:
-						actX += superviewRelativeBounds.X;
+						actX -= contentArea.X;
 						break;
 
 					case Pos.PosCenter:
 						actX = x.Anchor (superviewRelativeBounds.Width - actW);
-						actX += superviewRelativeBounds.X;
+						actX += contentArea.X;
 						break;
 
 					case Pos.PosFactor:
-						actX += superviewRelativeBounds.X;
+						actX += contentArea.X;
 						break;
 
 					}
@@ -2342,8 +2348,8 @@ namespace Terminal.Gui {
 
 			case Pos.PosFactor:
 
-				if (hasFrame) {
-					actX += superviewRelativeBounds.X;// - SuperView.Frame.X;
+				if (superviewHasFrame) {
+					actX += contentArea.X;// - SuperView.Frame.X;
 				}
 				break;
 
@@ -2357,7 +2363,7 @@ namespace Terminal.Gui {
 
 			if (y is Pos.PosCenter) {
 				if (height == null) {
-					actH = !autosize.IsEmpty ? autosize.Height : superviewRelativeBounds.Height;
+					actH = !autosize.IsEmpty ? autosize.Height : contentArea.Height;
 				} else {
 					actH = height.Anchor (superviewRelativeBounds.Height);
 					actH = !autosize.IsEmpty && autosize.Height > actH ? autosize.Height : actH;
@@ -2370,14 +2376,14 @@ namespace Terminal.Gui {
 
 
 
-			if ((y is Pos.PosAbsolute || y is Pos.PosCenter) && (hasFrame)) {
-				actY += superviewRelativeBounds.Y;
+			if ((y is Pos.PosAbsolute || y is Pos.PosCenter) && (superviewHasFrame)) {
+				actY += contentArea.Y;
 			}
-			if ((y is Pos.PosAnchorEnd) && (hasFrame)) {
-				actY += superviewRelativeBounds.Y;// - SuperView.Frame.Y;
+			if ((y is Pos.PosAnchorEnd) && (superviewHasFrame)) {
+				actY -= contentArea.Y;// - SuperView.Frame.Y;
 			}
-			if ((y is Pos.PosFactor) && (hasFrame)) {
-				actY += superviewRelativeBounds.Y;// - SuperView.Frame.Y;
+			if ((y is Pos.PosFactor) && (superviewHasFrame)) {
+				actY += contentArea.Y;// - SuperView.Frame.Y;
 			}
 
 			var r = new Rect (actX, actY, actW, actH);
@@ -2559,9 +2565,10 @@ namespace Terminal.Gui {
 				return;
 			}
 
+			// TODO: Move to new method: LayoutAdornments
 			if (Margin != null) {
-				Margin.X = Frame.Location.X;
-				Margin.Y = Frame.Location.Y;
+				Margin.X = 0; // Adornment location is parent-relative
+				Margin.Y = 0;
 				Margin.Width = Frame.Size.Width;
 				Margin.Height = Frame.Size.Height;
 				Margin.SetNeedsLayout ();
@@ -2665,7 +2672,7 @@ namespace Terminal.Gui {
 
 			if (hasFrame) {
 				// in v2 Bounds really is Frame-relative			
-				bounds = Bounds;
+				bounds = new Rect (Point.Empty, Frame.Size);
 			}
 
 			foreach (var v in ordered) {

+ 38 - 35
UICatalog/Scenarios/TileViewExperiment.cs

@@ -20,51 +20,54 @@ namespace UICatalog.Scenarios {
 		/// </summary>
 		public override void Setup ()
 		{
-			var menu = new MenuBar (new MenuBarItem [] {
-			new MenuBarItem ("_File", new MenuItem [] {
-				new MenuItem ("_Quit", "", () => Application.RequestStop()),
-			}) });
+			//var menu = new MenuBar (new MenuBarItem [] {
+			//new MenuBarItem ("_File", new MenuItem [] {
+			//	new MenuItem ("_Quit", "", () => Application.RequestStop()),
+			//}) });
 
-			Application.Top.Add (menu);
+			//Application.Top.Add (menu);
 
 			var frame1 = new FrameView () {
+				Title = "frame1",
 				X = 0,
-				Y = 1,
-				Width = 15, //Dim.Fill (),
+				Y = 0,
+				Width = 70, //Dim.Fill (),
 				Height = 15, //Dim.Fill (),
 				//IgnoreBorderPropertyOnRedraw = true
 
 			};
 			frame1.Border.BorderStyle = BorderStyle.Double;
 
-			var frame2 = new FrameView () {
-				X = 0,
-				Y = Pos.Bottom (frame1) + 1,
-				Width = 15, //Dim.Fill (),
-				Height = 15, //Dim.Fill (),
-					     //IgnoreBorderPropertyOnRedraw = true
+			//var frame2 = new FrameView () {
+			//	Title = "frame2",
+			//	X = 0,
+			//	Y = Pos.Bottom (frame1) + 1,
+			//	Width = 20, //Dim.Fill (),
+			//	Height = 15, //Dim.Fill (),
+			//		     //IgnoreBorderPropertyOnRedraw = true
 
-			};
-			frame2.Border.BorderStyle = BorderStyle.Single;
+			//};
+			//frame2.Border.BorderStyle = BorderStyle.Single;
 
 			//ConsoleDriver.Diagnostics ^= ConsoleDriver.DiagnosticFlags.FrameRuler;
 
 			Application.Top.Add (frame1);
-			Application.Top.Add (frame2);
+			//Application.Top.Add (frame2);
 
-			var view1 = new TextField () {
-				//Title = "View 1",
+			var view1 = new View () {
+				AutoSize = false,
+				Title = "view1",
 				Text = "View1 30%/50% Single",
 				X = 0,
 				Y = 0,
-				Width = 14, //Dim.Percent (30) - 5,
-				Height = 14, //Dim.Percent (50) - 5,
+				Width = 30, //Dim.Percent (30) - 5,
+				Height = 10, //Dim.Percent (50) - 5,
 				ColorScheme = Colors.ColorSchemes ["Dialog"],
-				Border = new Border () { 
-					BorderStyle = BorderStyle.Single, 
+				Border = new Border () {
+					BorderStyle = BorderStyle.Single,
 					//BorderThickness = new Thickness (1), 
-					DrawMarginFrame = true,
-					Padding = new Thickness(1),
+					//DrawMarginFrame = true,
+					//Padding = new Thickness (1),
 					BorderBrush = Color.BrightMagenta,
 				}
 			};
@@ -73,18 +76,18 @@ namespace UICatalog.Scenarios {
 
 			//var view12splitter = new SplitterEventArgs
 
-			//var view2 = new FrameView () {
-			//	Title = "View 2",
-			//	Text = "View2 right of view1, 30%/70% Single.",
-			//	X = Pos.Right (view1) - 1,
-			//	Y = -1,
-			//	Width = Dim.Percent (30),
-			//	Height = Dim.Percent (70),
-			//	ColorScheme = Colors.ColorSchemes ["Error"],
-			//	Border = new Border () { BorderStyle = BorderStyle.Single }
-			//};
+			var view2 = new FrameView () {
+				Title = "view2",
+				Text = "View2 right of view1, 30%/70% Single.",
+				X = Pos.Right (view1) - 1,
+				Y = 0,
+				Width = Dim.Percent (30),
+				Height = Dim.Percent (70),
+				ColorScheme = Colors.ColorSchemes ["Error"],
+				Border = new Border () { BorderStyle = BorderStyle.Single }
+			};
 
-			//frame.Add (view2);
+			frame1.Add (view2);
 
 			//var view3 = new FrameView () {
 			//	Title = "View 3",