Browse Source

Fixed TabView

Tig Kindel 1 year ago
parent
commit
c4dc3fee29

+ 13 - 9
Terminal.Gui/View/Layout/ViewLayout.cs

@@ -66,7 +66,7 @@ public partial class View {
 			_y = _frame.Y;
 			_y = _frame.Y;
 			_width = _frame.Width;
 			_width = _frame.Width;
 			_height = _frame.Height;
 			_height = _frame.Height;
-			
+
 			// TODO: Figure out if the below can be optimized.
 			// TODO: Figure out if the below can be optimized.
 			if (IsInitialized /*|| LayoutStyle == LayoutStyle.Absolute*/) {
 			if (IsInitialized /*|| LayoutStyle == LayoutStyle.Absolute*/) {
 				LayoutFrames ();
 				LayoutFrames ();
@@ -615,10 +615,14 @@ public partial class View {
 
 
 		// First try SuperView.Bounds, then Application.Top, then Driver
 		// First try SuperView.Bounds, then Application.Top, then Driver
 		// Finally, if none of those are valid, use int.MaxValue (for Unit tests).
 		// Finally, if none of those are valid, use int.MaxValue (for Unit tests).
-		SetRelativeLayout (SuperView?.Bounds ?? Application.Top?.Bounds ?? Application.Driver?.Bounds ?? new Rect (0, 0, int.MaxValue, int.MaxValue));
+		var relativeBounds = SuperView is { IsInitialized: true } ? SuperView.Bounds :
+					((Application.Top != null && Application.Top.IsInitialized) ? Application.Top.Bounds : 
+					Application.Driver?.Bounds ?? 
+					new Rect (0, 0, int.MaxValue, int.MaxValue));
+		SetRelativeLayout (relativeBounds);
 
 
 		// TODO: Determine what, if any of the below is actually needed here.
 		// TODO: Determine what, if any of the below is actually needed here.
-		if (IsInitialized/* || LayoutStyle == LayoutStyle.Absolute*/) {
+		if (IsInitialized) {
 			SetFrameToFitText ();
 			SetFrameToFitText ();
 			LayoutFrames ();
 			LayoutFrames ();
 			TextFormatter.Size = GetTextFormatterSizeNeededForTextAndHotKey ();
 			TextFormatter.Size = GetTextFormatterSizeNeededForTextAndHotKey ();
@@ -874,16 +878,16 @@ public partial class View {
 			// Set the frame. Do NOT use `Frame` as it overwrites X, Y, Width, and Height, making
 			// Set the frame. Do NOT use `Frame` as it overwrites X, Y, Width, and Height, making
 			// the view LayoutStyle.Absolute.
 			// the view LayoutStyle.Absolute.
 			_frame = r;
 			_frame = r;
-			if (X is Pos.PosAbsolute) {
+			if (_x is Pos.PosAbsolute) {
 				_x = Frame.X;
 				_x = Frame.X;
 			}
 			}
-			if (Y is Pos.PosAbsolute) {
+			if (_y is Pos.PosAbsolute) {
 				_y = Frame.Y;
 				_y = Frame.Y;
 			}
 			}
-			if (Width is Dim.DimAbsolute) {
+			if (_width is Dim.DimAbsolute) {
 				_width = Frame.Width;
 				_width = Frame.Width;
 			}
 			}
-			if (Height is Dim.DimAbsolute) {
+			if (_height is Dim.DimAbsolute) {
 				_height = Frame.Height;
 				_height = Frame.Height;
 			}
 			}
 
 
@@ -894,7 +898,7 @@ public partial class View {
 				SetNeedsLayout ();
 				SetNeedsLayout ();
 				//SetNeedsDisplay ();
 				//SetNeedsDisplay ();
 			}
 			}
-			
+
 			// BUGBUG: Why is this AFTER setting Frame? Seems duplicative.
 			// BUGBUG: Why is this AFTER setting Frame? Seems duplicative.
 			if (!SetFrameToFitText ()) {
 			if (!SetFrameToFitText ()) {
 				TextFormatter.Size = GetTextFormatterSizeNeededForTextAndHotKey ();
 				TextFormatter.Size = GetTextFormatterSizeNeededForTextAndHotKey ();
@@ -1148,7 +1152,7 @@ public partial class View {
 	void LayoutSubview (View v, Rect contentArea)
 	void LayoutSubview (View v, Rect contentArea)
 	{
 	{
 		//if (v.LayoutStyle == LayoutStyle.Computed) {
 		//if (v.LayoutStyle == LayoutStyle.Computed) {
-			v.SetRelativeLayout (contentArea);
+		v.SetRelativeLayout (contentArea);
 		//}
 		//}
 
 
 		v.LayoutSubviews ();
 		v.LayoutSubviews ();

+ 708 - 700
Terminal.Gui/Views/ScrollBarView.cs

@@ -8,816 +8,824 @@
 using System;
 using System;
 using System.Text;
 using System.Text;
 
 
-namespace Terminal.Gui {
+namespace Terminal.Gui; 
+
+/// <summary>
+/// ScrollBarViews are views that display a 1-character scrollbar, either horizontal or vertical
+/// </summary>
+/// <remarks>
+///         <para>
+///         The scrollbar is drawn to be a representation of the Size, assuming that the
+///         scroll position is set at Position.
+///         </para>
+///         <para>
+///         If the region to display the scrollbar is larger than three characters,
+///         arrow indicators are drawn.
+///         </para>
+/// </remarks>
+public class ScrollBarView : View {
+	bool _autoHideScrollBars = true;
+	View _contentBottomRightCorner;
+	bool _hosted;
+	bool _keepContentAlwaysInViewport = true;
+
+	int _lastLocation = -1;
+	ScrollBarView _otherScrollBarView;
+	int _posBarOffset;
+	int _posBottomTee;
+	int _posLeftTee;
+	int _posRightTee;
+
+	int _posTopTee;
+	bool _showScrollIndicator;
+	int _size, _position;
+	bool _vertical;
+
 	/// <summary>
 	/// <summary>
-	/// ScrollBarViews are views that display a 1-character scrollbar, either horizontal or vertical
+	/// Initializes a new instance of the <see cref="Gui.ScrollBarView"/> class using <see cref="LayoutStyle.Absolute"/>
+	/// layout.
 	/// </summary>
 	/// </summary>
-	/// <remarks>
-	/// <para>
-	///   The scrollbar is drawn to be a representation of the Size, assuming that the 
-	///   scroll position is set at Position.
-	/// </para>
-	/// <para>
-	///   If the region to display the scrollbar is larger than three characters, 
-	///   arrow indicators are drawn.
-	/// </para>
-	/// </remarks>
-	public class ScrollBarView : View {
-		bool _vertical;
-		int _size, _position;
-		bool _showScrollIndicator;
-		bool _keepContentAlwaysInViewport = true;
-		bool _autoHideScrollBars = true;
-		bool _hosted;
-		ScrollBarView _otherScrollBarView;
-		View _contentBottomRightCorner;
-
-		bool _showBothScrollIndicator => OtherScrollBarView?._showScrollIndicator == true && _showScrollIndicator;
-
-		/// <summary>
-		/// Initializes a new instance of the <see cref="Gui.ScrollBarView"/> class using <see cref="LayoutStyle.Absolute"/> layout.
-		/// </summary>
-		/// <param name="rect">Frame for the scrollbar.</param>
-		public ScrollBarView (Rect rect) : this (rect, 0, 0, false) { }
-
-		/// <summary>
-		/// Initializes a new instance of the <see cref="Gui.ScrollBarView"/> class using <see cref="LayoutStyle.Absolute"/> layout.
-		/// </summary>
-		/// <param name="rect">Frame for the scrollbar.</param>
-		/// <param name="size">The size that this scrollbar represents. Sets the <see cref="Size"/> property.</param>
-		/// <param name="position">The position within this scrollbar. Sets the <see cref="Position"/> property.</param>
-		/// <param name="isVertical">If set to <c>true</c> this is a vertical scrollbar, otherwise, the scrollbar is horizontal. Sets the <see cref="IsVertical"/> property.</param>
-		public ScrollBarView (Rect rect, int size, int position, bool isVertical) : base (rect)
-		{
-			SetInitialProperties (size, position, isVertical);
-		}
-
-		/// <summary>
-		/// Initializes a new instance of the <see cref="Gui.ScrollBarView"/> class using <see cref="LayoutStyle.Computed"/> layout.
-		/// </summary>
-		public ScrollBarView () : this (0, 0, false) { }
-
-		/// <summary>
-		/// Initializes a new instance of the <see cref="Gui.ScrollBarView"/> class using <see cref="LayoutStyle.Computed"/> layout.
-		/// </summary>
-		/// <param name="size">The size that this scrollbar represents.</param>
-		/// <param name="position">The position within this scrollbar.</param>
-		/// <param name="isVertical">If set to <c>true</c> this is a vertical scrollbar, otherwise, the scrollbar is horizontal.</param>
-		public ScrollBarView (int size, int position, bool isVertical) : base ()
-		{
-			SetInitialProperties (size, position, isVertical);
-		}
-
-		/// <summary>
-		/// Initializes a new instance of the <see cref="Gui.ScrollBarView"/> class using <see cref="LayoutStyle.Computed"/> layout.
-		/// </summary>
-		/// <param name="host">The view that will host this scrollbar.</param>
-		/// <param name="isVertical">If set to <c>true</c> this is a vertical scrollbar, otherwise, the scrollbar is horizontal.</param>
-		/// <param name="showBothScrollIndicator">If set to <c>true (default)</c> will have the other scrollbar, otherwise will have only one.</param>
-		public ScrollBarView (View host, bool isVertical, bool showBothScrollIndicator = true) : this (0, 0, isVertical)
-		{
-			if (host == null) {
-				throw new ArgumentNullException ("The host parameter can't be null.");
-			} else if (host.SuperView == null) {
-				throw new ArgumentNullException ("The host SuperView parameter can't be null.");
-			}
-			_hosted = true;
-			ColorScheme = host.ColorScheme;
-			X = isVertical ? Pos.Right (host) - 1 : Pos.Left (host);
-			Y = isVertical ? Pos.Top (host) : Pos.Bottom (host) - 1;
-			Host = host;
-			CanFocus = false;
-			Enabled = host.Enabled;
-			Visible = host.Visible;
-			//Host.CanFocusChanged += Host_CanFocusChanged;
-			Host.EnabledChanged += Host_EnabledChanged;
-			Host.VisibleChanged += Host_VisibleChanged;
-			Host.SuperView.Add (this);
-			AutoHideScrollBars = true;
-			if (showBothScrollIndicator) {
-				OtherScrollBarView = new ScrollBarView (0, 0, !isVertical) {
-					Id = "OtherScrollBarView",
-					ColorScheme = host.ColorScheme,
-					Host = host,
-					CanFocus = false,
-					Enabled = host.Enabled,
-					Visible = host.Visible,
-					OtherScrollBarView = this
-				};
-				OtherScrollBarView._hosted = true;
-				OtherScrollBarView.X = OtherScrollBarView.IsVertical ? Pos.Right (host) - 1 : Pos.Left (host);
-				OtherScrollBarView.Y = OtherScrollBarView.IsVertical ? Pos.Top (host) : Pos.Bottom (host) - 1;
-				OtherScrollBarView.Host.SuperView.Add (OtherScrollBarView);
-				OtherScrollBarView.ShowScrollIndicator = true;
-			}
-			ShowScrollIndicator = true;
-			CreateBottomRightCorner ();
-			ClearOnVisibleFalse = false;
-		}
-
-		private void CreateBottomRightCorner ()
-		{
-			if (Host != null && (_contentBottomRightCorner == null && OtherScrollBarView == null
-				|| (_contentBottomRightCorner == null && OtherScrollBarView != null && OtherScrollBarView._contentBottomRightCorner == null))) {
-
-				_contentBottomRightCorner = new View () {
-					Id = "contentBottomRightCorner",
-					Visible = Host.Visible,
-					ClearOnVisibleFalse = false,
-					ColorScheme = ColorScheme
-				};
-				if (_hosted) {
-					Host.SuperView.Add (_contentBottomRightCorner);
-				} else {
-					Host.Add (_contentBottomRightCorner);
-				}
-				_contentBottomRightCorner.X = Pos.Right (Host) - 1;
-				_contentBottomRightCorner.Y = Pos.Bottom (Host) - 1;
-				_contentBottomRightCorner.Width = 1;
-				_contentBottomRightCorner.Height = 1;
-				_contentBottomRightCorner.MouseClick += ContentBottomRightCorner_MouseClick;
-				_contentBottomRightCorner.DrawContent += _contentBottomRightCorner_DrawContent;
-			}
-		}
-
-		private void _contentBottomRightCorner_DrawContent (object sender, DrawEventArgs e)
-		{
-			Driver.SetAttribute (Host.HasFocus ? ColorScheme.Focus : GetNormalColor ());
-		}
+	/// <param name="rect">Frame for the scrollbar.</param>
+	public ScrollBarView (Rect rect) : this (rect, 0, 0, false) { }
 
 
-		private void Host_VisibleChanged (object sender, EventArgs e)
-		{
-			if (!Host.Visible) {
-				Visible = Host.Visible;
-				if (_otherScrollBarView != null) {
-					_otherScrollBarView.Visible = Visible;
-				}
-				_contentBottomRightCorner.Visible = Visible;
-			} else {
-				ShowHideScrollBars ();
-			}
-		}
-
-		private void Host_EnabledChanged (object sender, EventArgs e)
-		{
-			Enabled = Host.Enabled;
-			if (_otherScrollBarView != null) {
-				_otherScrollBarView.Enabled = Enabled;
-			}
-			_contentBottomRightCorner.Enabled = Enabled;
-		}
-
-		//private void Host_CanFocusChanged ()
-		//{
-		//	CanFocus = Host.CanFocus;
-		//	if (otherScrollBarView != null) {
-		//		otherScrollBarView.CanFocus = CanFocus;
-		//	}
-		//}
+	/// <summary>
+	/// Initializes a new instance of the <see cref="Gui.ScrollBarView"/> class using <see cref="LayoutStyle.Absolute"/>
+	/// layout.
+	/// </summary>
+	/// <param name="rect">Frame for the scrollbar.</param>
+	/// <param name="size">The size that this scrollbar represents. Sets the <see cref="Size"/> property.</param>
+	/// <param name="position">The position within this scrollbar. Sets the <see cref="Position"/> property.</param>
+	/// <param name="isVertical">
+	/// If set to <c>true</c> this is a vertical scrollbar, otherwise, the scrollbar is horizontal. Sets the
+	/// <see cref="IsVertical"/> property.
+	/// </param>
+	public ScrollBarView (Rect rect, int size, int position, bool isVertical) : base (rect) => SetInitialProperties (size, position, isVertical);
 
 
-		void ContentBottomRightCorner_MouseClick (object sender, MouseEventEventArgs me)
-		{
-			if (me.MouseEvent.Flags == MouseFlags.WheeledDown || me.MouseEvent.Flags == MouseFlags.WheeledUp
-			    || me.MouseEvent.Flags == MouseFlags.WheeledRight || me.MouseEvent.Flags == MouseFlags.WheeledLeft) {
+	/// <summary>
+	/// Initializes a new instance of the <see cref="Gui.ScrollBarView"/> class using <see cref="LayoutStyle.Computed"/>
+	/// layout.
+	/// </summary>
+	public ScrollBarView () : this (0, 0, false) { }
 
 
-				MouseEvent (me.MouseEvent);
-			} else if (me.MouseEvent.Flags == MouseFlags.Button1Clicked) {
-				Host.SetFocus ();
-			}
+	/// <summary>
+	/// Initializes a new instance of the <see cref="Gui.ScrollBarView"/> class using <see cref="LayoutStyle.Computed"/>
+	/// layout.
+	/// </summary>
+	/// <param name="size">The size that this scrollbar represents.</param>
+	/// <param name="position">The position within this scrollbar.</param>
+	/// <param name="isVertical">If set to <c>true</c> this is a vertical scrollbar, otherwise, the scrollbar is horizontal.</param>
+	public ScrollBarView (int size, int position, bool isVertical) => SetInitialProperties (size, position, isVertical);
 
 
-			me.Handled = true;
+	/// <summary>
+	/// Initializes a new instance of the <see cref="Gui.ScrollBarView"/> class using <see cref="LayoutStyle.Computed"/>
+	/// layout.
+	/// </summary>
+	/// <param name="host">The view that will host this scrollbar.</param>
+	/// <param name="isVertical">If set to <c>true</c> this is a vertical scrollbar, otherwise, the scrollbar is horizontal.</param>
+	/// <param name="showBothScrollIndicator">
+	/// If set to <c>true (default)</c> will have the other scrollbar, otherwise will
+	/// have only one.
+	/// </param>
+	public ScrollBarView (View host, bool isVertical, bool showBothScrollIndicator = true) : this (0, 0, isVertical)
+	{
+		if (host == null) {
+			throw new ArgumentNullException ("The host parameter can't be null.");
 		}
 		}
+		if (host.SuperView == null) {
+			throw new ArgumentNullException ("The host SuperView parameter can't be null.");
+		}
+		_hosted = true;
+		ColorScheme = host.ColorScheme;
+		X = isVertical ? Pos.Right (host) - 1 : Pos.Left (host);
+		Y = isVertical ? Pos.Top (host) : Pos.Bottom (host) - 1;
+		Host = host;
+		CanFocus = false;
+		Enabled = host.Enabled;
+		Visible = host.Visible;
+		//Host.CanFocusChanged += Host_CanFocusChanged;
+		Host.EnabledChanged += Host_EnabledChanged;
+		Host.VisibleChanged += Host_VisibleChanged;
+		Host.SuperView.Add (this);
+		AutoHideScrollBars = true;
+		if (showBothScrollIndicator) {
+			OtherScrollBarView = new ScrollBarView (0, 0, !isVertical) {
+				Id = "OtherScrollBarView",
+				ColorScheme = host.ColorScheme,
+				Host = host,
+				CanFocus = false,
+				Enabled = host.Enabled,
+				Visible = host.Visible,
+				OtherScrollBarView = this
+			};
+			OtherScrollBarView._hosted = true;
+			OtherScrollBarView.X = OtherScrollBarView.IsVertical ? Pos.Right (host) - 1 : Pos.Left (host);
+			OtherScrollBarView.Y = OtherScrollBarView.IsVertical ? Pos.Top (host) : Pos.Bottom (host) - 1;
+			OtherScrollBarView.Host.SuperView.Add (OtherScrollBarView);
+			OtherScrollBarView.ShowScrollIndicator = true;
+		}
+		ShowScrollIndicator = true;
+		CreateBottomRightCorner ();
+		ClearOnVisibleFalse = false;
+	}
 
 
-		void SetInitialProperties (int size, int position, bool isVertical)
-		{
-			Id = "ScrollBarView";
-			_vertical = isVertical;
-			this._position = position;
-			this._size = size;
-			WantContinuousButtonPressed = true;
-			ClearOnVisibleFalse = false;
-
-			Added += (s, e) => CreateBottomRightCorner ();
+	bool _showBothScrollIndicator => OtherScrollBarView?._showScrollIndicator == true && _showScrollIndicator;
 
 
-			Initialized += (s, e) => {
+	/// <summary>
+	/// If set to <c>true</c> this is a vertical scrollbar, otherwise, the scrollbar is horizontal.
+	/// </summary>
+	public bool IsVertical {
+		get => _vertical;
+		set {
+			_vertical = value;
+			if (IsInitialized) {
 				SetWidthHeight ();
 				SetWidthHeight ();
-				SetRelativeLayout (SuperView?.Frame ?? Host?.Frame ?? Frame);
-				if (Id == "OtherScrollBarView" || OtherScrollBarView == null) {
-					// Only do this once if both scrollbars are enabled
-					ShowHideScrollBars ();
-				}
-				SetPosition (position);
-			};
+			}
 		}
 		}
+	}
 
 
-		/// <summary>
-		/// If set to <c>true</c> this is a vertical scrollbar, otherwise, the scrollbar is horizontal.
-		/// </summary>
-		public bool IsVertical {
-			get => _vertical;
-			set {
-				_vertical = value;
-				if (IsInitialized) {
-					SetWidthHeight ();
-				}
+	/// <summary>
+	/// The size of content the scrollbar represents.
+	/// </summary>
+	/// <value>The size.</value>
+	/// <remarks>
+	/// The <see cref="Size"/> is typically the size of the virtual content. E.g. when a Scrollbar is
+	/// part of a <see cref="View"/> the Size is set to the appropriate dimension of <see cref="Host"/>.
+	/// </remarks>
+	public int Size {
+		get => _size;
+		set {
+			_size = value;
+			if (IsInitialized) {
+				SetRelativeLayout (SuperView?.Frame ?? Host.Frame);
+				ShowHideScrollBars (false);
+				SetNeedsDisplay ();
 			}
 			}
 		}
 		}
+	}
 
 
-		/// <summary>
-		/// The size of content the scrollbar represents.
-		/// </summary>
-		/// <value>The size.</value>
-		/// <remarks>The <see cref="Size"/> is typically the size of the virtual content. E.g. when a Scrollbar is
-		/// part of a <see cref="View"/> the Size is set to the appropriate dimension of <see cref="Host"/>.</remarks>
-		public int Size {
-			get => _size;
-			set {
-				_size = value;
-				if (IsInitialized) {
-					SetRelativeLayout (SuperView?.Frame ?? Host.Frame);
-					ShowHideScrollBars (false);
-					SetNeedsDisplay ();
-				}
+	/// <summary>
+	/// The position, relative to <see cref="Size"/>, to set the scrollbar at.
+	/// </summary>
+	/// <value>The position.</value>
+	public int Position {
+		get => _position;
+		set {
+			_position = value;
+			if (IsInitialized) {
+				// We're not initialized so we can't do anything fancy. Just cache value.
+				SetPosition (value);
 			}
 			}
 		}
 		}
+	}
 
 
-		/// <summary>
-		/// This event is raised when the position on the scrollbar has changed.
-		/// </summary>
-		public event EventHandler ChangedPosition;
+	// BUGBUG: v2 - for consistency this should be named "Parent" not "Host"
+	/// <summary>
+	/// Get or sets the view that host this <see cref="ScrollBarView"/>
+	/// </summary>
+	public View Host { get; internal set; }
 
 
-		/// <summary>
-		/// The position, relative to <see cref="Size"/>, to set the scrollbar at.
-		/// </summary>
-		/// <value>The position.</value>
-		public int Position {
-			get => _position;
-			set {
-				_position = value;
-				if (IsInitialized) {
-					// We're not initialized so we can't do anything fancy. Just cache value.
-					SetPosition (value);
-				}
+	/// <summary>
+	/// Represent a vertical or horizontal ScrollBarView other than this.
+	/// </summary>
+	public ScrollBarView OtherScrollBarView {
+		get => _otherScrollBarView;
+		set {
+			if (value != null && (value.IsVertical && _vertical || !value.IsVertical && !_vertical)) {
+				throw new ArgumentException ($"There is already a {(_vertical ? "vertical" : "horizontal")} ScrollBarView.");
 			}
 			}
+			_otherScrollBarView = value;
 		}
 		}
+	}
 
 
-		// Helper to assist Initialized event handler
-		private void SetPosition (int newPosition)
-		{
-			if (CanScroll (newPosition - _position, out int max, _vertical)) {
-				if (max == newPosition - _position) {
-					_position = newPosition;
+	// BUGBUG: v2 - Why can't we get rid of this and just use Visible?
+	/// <summary>
+	/// Gets or sets the visibility for the vertical or horizontal scroll indicator.
+	/// </summary>
+	/// <value><c>true</c> if show vertical or horizontal scroll indicator; otherwise, <c>false</c>.</value>
+	public bool ShowScrollIndicator {
+		get => _showScrollIndicator;
+		set {
+			//if (value == showScrollIndicator) {
+			//	return;
+			//}
+
+			_showScrollIndicator = value;
+			if (IsInitialized) {
+				SetNeedsLayout ();
+				if (value) {
+					Visible = true;
 				} else {
 				} else {
-					_position = Math.Max (_position + max, 0);
-				}
-			} else if (max < 0) {
-				_position = Math.Max (_position + max, 0);
-			} else {
-				_position = Math.Max (newPosition, 0);
-			}
-			OnChangedPosition ();
-			SetNeedsDisplay ();
-		}
-
-		// BUGBUG: v2 - for consistency this should be named "Parent" not "Host"
-		/// <summary>
-		/// Get or sets the view that host this <see cref="ScrollBarView"/>
-		/// </summary>
-		public View Host { get; internal set; }
-
-		/// <summary>
-		/// Represent a vertical or horizontal ScrollBarView other than this.
-		/// </summary>
-		public ScrollBarView OtherScrollBarView {
-			get => _otherScrollBarView;
-			set {
-				if (value != null && (value.IsVertical && _vertical || !value.IsVertical && !_vertical)) {
-					throw new ArgumentException ($"There is already a {(_vertical ? "vertical" : "horizontal")} ScrollBarView.");
-				}
-				_otherScrollBarView = value;
-			}
-		}
-
-		// BUGBUG: v2 - Why can't we get rid of this and just use Visible?
-		/// <summary>
-		/// Gets or sets the visibility for the vertical or horizontal scroll indicator.
-		/// </summary>
-		/// <value><c>true</c> if show vertical or horizontal scroll indicator; otherwise, <c>false</c>.</value>
-		public bool ShowScrollIndicator {
-			get => _showScrollIndicator;
-			set {
-				//if (value == showScrollIndicator) {
-				//	return;
-				//}
-
-				_showScrollIndicator = value;
-				if (IsInitialized) {
-					SetNeedsLayout ();
-					if (value) {
-						Visible = true;
-					} else {
-						Visible = false;
-						Position = 0;
-					}
-					SetWidthHeight ();
+					Visible = false;
+					Position = 0;
 				}
 				}
+				SetWidthHeight ();
 			}
 			}
 		}
 		}
+	}
 
 
-		/// <summary>
-		/// Get or sets if the view-port is kept always visible in the area of this <see cref="ScrollBarView"/>
-		/// </summary>
-		public bool KeepContentAlwaysInViewport {
-			get { return _keepContentAlwaysInViewport; }
-			set {
-				if (_keepContentAlwaysInViewport != value) {
-					_keepContentAlwaysInViewport = value;
-					int pos = 0;
-					if (value && !_vertical && _position + Host.Bounds.Width > _size) {
-						pos = _size - Host.Bounds.Width + (_showBothScrollIndicator ? 1 : 0);
-					}
-					if (value && _vertical && _position + Host.Bounds.Height > _size) {
-						pos = _size - Host.Bounds.Height + (_showBothScrollIndicator ? 1 : 0);
-					}
-					if (pos != 0) {
-						Position = pos;
-					}
-					if (OtherScrollBarView != null && OtherScrollBarView._keepContentAlwaysInViewport != value) {
-						OtherScrollBarView.KeepContentAlwaysInViewport = value;
-					}
-					if (pos == 0) {
-						Refresh ();
-					}
+	/// <summary>
+	/// Get or sets if the view-port is kept always visible in the area of this <see cref="ScrollBarView"/>
+	/// </summary>
+	public bool KeepContentAlwaysInViewport {
+		get => _keepContentAlwaysInViewport;
+		set {
+			if (_keepContentAlwaysInViewport != value) {
+				_keepContentAlwaysInViewport = value;
+				var pos = 0;
+				if (value && !_vertical && _position + Host.Bounds.Width > _size) {
+					pos = _size - Host.Bounds.Width + (_showBothScrollIndicator ? 1 : 0);
+				}
+				if (value && _vertical && _position + Host.Bounds.Height > _size) {
+					pos = _size - Host.Bounds.Height + (_showBothScrollIndicator ? 1 : 0);
+				}
+				if (pos != 0) {
+					Position = pos;
+				}
+				if (OtherScrollBarView != null && OtherScrollBarView._keepContentAlwaysInViewport != value) {
+					OtherScrollBarView.KeepContentAlwaysInViewport = value;
+				}
+				if (pos == 0) {
+					Refresh ();
 				}
 				}
 			}
 			}
 		}
 		}
+	}
 
 
-		/// <summary>
-		/// If true the vertical/horizontal scroll bars won't be showed if it's not needed.
-		/// </summary>
-		public bool AutoHideScrollBars {
-			get => _autoHideScrollBars;
-			set {
-				if (_autoHideScrollBars != value) {
-					_autoHideScrollBars = value;
-					SetNeedsDisplay ();
-				}
+	/// <summary>
+	/// If true the vertical/horizontal scroll bars won't be showed if it's not needed.
+	/// </summary>
+	public bool AutoHideScrollBars {
+		get => _autoHideScrollBars;
+		set {
+			if (_autoHideScrollBars != value) {
+				_autoHideScrollBars = value;
+				SetNeedsDisplay ();
 			}
 			}
 		}
 		}
+	}
 
 
-		/// <summary>
-		/// Virtual method to invoke the <see cref="ChangedPosition"/> action event.
-		/// </summary>
-		public virtual void OnChangedPosition ()
-		{
-			ChangedPosition?.Invoke (this, EventArgs.Empty);
+	void CreateBottomRightCorner ()
+	{
+		if (Host != null &&
+		    (_contentBottomRightCorner == null && OtherScrollBarView == null ||
+		     _contentBottomRightCorner == null && OtherScrollBarView != null && OtherScrollBarView._contentBottomRightCorner == null)) {
+
+			_contentBottomRightCorner = new View {
+				Id = "contentBottomRightCorner",
+				Visible = Host.Visible,
+				ClearOnVisibleFalse = false,
+				ColorScheme = ColorScheme
+			};
+			if (_hosted) {
+				Host.SuperView.Add (_contentBottomRightCorner);
+			} else {
+				Host.Add (_contentBottomRightCorner);
+			}
+			_contentBottomRightCorner.X = Pos.Right (Host) - 1;
+			_contentBottomRightCorner.Y = Pos.Bottom (Host) - 1;
+			_contentBottomRightCorner.Width = 1;
+			_contentBottomRightCorner.Height = 1;
+			_contentBottomRightCorner.MouseClick += ContentBottomRightCorner_MouseClick;
+			_contentBottomRightCorner.DrawContent += _contentBottomRightCorner_DrawContent;
 		}
 		}
+	}
 
 
-		/// <summary>
-		/// Only used for a hosted view that will update and redraw the scrollbars.
-		/// </summary>
-		public virtual void Refresh ()
-		{
+	void _contentBottomRightCorner_DrawContent (object sender, DrawEventArgs e) => Driver.SetAttribute (Host.HasFocus ? ColorScheme.Focus : GetNormalColor ());
+
+	void Host_VisibleChanged (object sender, EventArgs e)
+	{
+		if (!Host.Visible) {
+			Visible = Host.Visible;
+			if (_otherScrollBarView != null) {
+				_otherScrollBarView.Visible = Visible;
+			}
+			_contentBottomRightCorner.Visible = Visible;
+		} else {
 			ShowHideScrollBars ();
 			ShowHideScrollBars ();
 		}
 		}
+	}
 
 
-		void ShowHideScrollBars (bool redraw = true)
-		{
-			if (!_hosted || (_hosted && !_autoHideScrollBars)) {
-				if (_contentBottomRightCorner != null && _contentBottomRightCorner.Visible) {
-					_contentBottomRightCorner.Visible = false;
-				} else if (_otherScrollBarView != null && _otherScrollBarView._contentBottomRightCorner != null && _otherScrollBarView._contentBottomRightCorner.Visible) {
-					_otherScrollBarView._contentBottomRightCorner.Visible = false;
-				}
-				return;
-			}
+	void Host_EnabledChanged (object sender, EventArgs e)
+	{
+		Enabled = Host.Enabled;
+		if (_otherScrollBarView != null) {
+			_otherScrollBarView.Enabled = Enabled;
+		}
+		_contentBottomRightCorner.Enabled = Enabled;
+	}
 
 
-			var pending = CheckBothScrollBars (this);
-			if (_otherScrollBarView != null) {
-				CheckBothScrollBars (_otherScrollBarView, pending);
-			}
+	//private void Host_CanFocusChanged ()
+	//{
+	//	CanFocus = Host.CanFocus;
+	//	if (otherScrollBarView != null) {
+	//		otherScrollBarView.CanFocus = CanFocus;
+	//	}
+	//}
+
+	void ContentBottomRightCorner_MouseClick (object sender, MouseEventEventArgs me)
+	{
+		if (me.MouseEvent.Flags == MouseFlags.WheeledDown ||
+		    me.MouseEvent.Flags == MouseFlags.WheeledUp ||
+		    me.MouseEvent.Flags == MouseFlags.WheeledRight ||
+		    me.MouseEvent.Flags == MouseFlags.WheeledLeft) {
+
+			MouseEvent (me.MouseEvent);
+		} else if (me.MouseEvent.Flags == MouseFlags.Button1Clicked) {
+			Host.SetFocus ();
+		}
 
 
+		me.Handled = true;
+	}
+
+	void SetInitialProperties (int size, int position, bool isVertical)
+	{
+		Id = "ScrollBarView";
+		_vertical = isVertical;
+		_position = position;
+		_size = size;
+		WantContinuousButtonPressed = true;
+		ClearOnVisibleFalse = false;
+
+		Added += (s, e) => CreateBottomRightCorner ();
+
+		Initialized += (s, e) => {
 			SetWidthHeight ();
 			SetWidthHeight ();
-			SetRelativeLayout (SuperView?.Frame ?? Host.Frame);
-			if (_otherScrollBarView != null) {
-				OtherScrollBarView.SetRelativeLayout (SuperView?.Frame ?? Host.Frame);
+			SetRelativeLayout (SuperView?.Frame ?? Host?.Frame ?? Frame);
+			// BUGBUG: We're not supposed to use Id internally!
+			if (Id == "OtherScrollBarView" || OtherScrollBarView == null) {
+				// Only do this once if both scrollbars are enabled
+				ShowHideScrollBars ();
 			}
 			}
+			SetPosition (position);
+		};
+	}
 
 
-			if (_showBothScrollIndicator) {
-				if (_contentBottomRightCorner != null) {
-					_contentBottomRightCorner.Visible = true;
-				} else if (_otherScrollBarView != null && _otherScrollBarView._contentBottomRightCorner != null) {
-					_otherScrollBarView._contentBottomRightCorner.Visible = true;
-				}
-			} else if (!_showScrollIndicator) {
-				if (_contentBottomRightCorner != null) {
-					_contentBottomRightCorner.Visible = false;
-				} else if (_otherScrollBarView != null && _otherScrollBarView._contentBottomRightCorner != null) {
-					_otherScrollBarView._contentBottomRightCorner.Visible = false;
-				}
-				if (Application.MouseGrabView != null && Application.MouseGrabView == this) {
-					Application.UngrabMouse ();
-				}
-			} else if (_contentBottomRightCorner != null) {
+	/// <summary>
+	/// This event is raised when the position on the scrollbar has changed.
+	/// </summary>
+	public event EventHandler ChangedPosition;
+
+	// Helper to assist Initialized event handler
+	void SetPosition (int newPosition)
+	{
+		if (CanScroll (newPosition - _position, out var max, _vertical)) {
+			if (max == newPosition - _position) {
+				_position = newPosition;
+			} else {
+				_position = Math.Max (_position + max, 0);
+			}
+		} else if (max < 0) {
+			_position = Math.Max (_position + max, 0);
+		} else {
+			_position = Math.Max (newPosition, 0);
+		}
+		OnChangedPosition ();
+		SetNeedsDisplay ();
+	}
+
+	/// <summary>
+	/// Virtual method to invoke the <see cref="ChangedPosition"/> action event.
+	/// </summary>
+	public virtual void OnChangedPosition () => ChangedPosition?.Invoke (this, EventArgs.Empty);
+
+	/// <summary>
+	/// Only used for a hosted view that will update and redraw the scrollbars.
+	/// </summary>
+	public virtual void Refresh () => ShowHideScrollBars ();
+
+	void ShowHideScrollBars (bool redraw = true)
+	{
+		if (!_hosted || _hosted && !_autoHideScrollBars) {
+			if (_contentBottomRightCorner != null && _contentBottomRightCorner.Visible) {
 				_contentBottomRightCorner.Visible = false;
 				_contentBottomRightCorner.Visible = false;
-			} else if (_otherScrollBarView != null && _otherScrollBarView._contentBottomRightCorner != null) {
+			} else if (_otherScrollBarView != null && _otherScrollBarView._contentBottomRightCorner != null && _otherScrollBarView._contentBottomRightCorner.Visible) {
 				_otherScrollBarView._contentBottomRightCorner.Visible = false;
 				_otherScrollBarView._contentBottomRightCorner.Visible = false;
 			}
 			}
-			if (Host?.Visible == true && _showScrollIndicator && !Visible) {
-				Visible = true;
-			}
-			if (Host?.Visible == true && _otherScrollBarView?._showScrollIndicator == true && !_otherScrollBarView.Visible) {
-				_otherScrollBarView.Visible = true;
-			}
+			return;
+		}
 
 
-			if (!redraw) {
-				return;
-			}
+		var pending = CheckBothScrollBars (this);
+		if (_otherScrollBarView != null) {
+			CheckBothScrollBars (_otherScrollBarView, pending);
+		}
+
+		SetWidthHeight ();
+		SetRelativeLayout (SuperView?.Frame ?? Host.Frame);
+		if (_otherScrollBarView != null) {
+			OtherScrollBarView.SetRelativeLayout (SuperView?.Frame ?? Host.Frame);
+		}
 
 
-			if (_showScrollIndicator) {
-				Draw ();
+		if (_showBothScrollIndicator) {
+			if (_contentBottomRightCorner != null) {
+				_contentBottomRightCorner.Visible = true;
+			} else if (_otherScrollBarView != null && _otherScrollBarView._contentBottomRightCorner != null) {
+				_otherScrollBarView._contentBottomRightCorner.Visible = true;
 			}
 			}
-			if (_otherScrollBarView != null && _otherScrollBarView._showScrollIndicator) {
-				_otherScrollBarView.Draw ();
+		} else if (!_showScrollIndicator) {
+			if (_contentBottomRightCorner != null) {
+				_contentBottomRightCorner.Visible = false;
+			} else if (_otherScrollBarView != null && _otherScrollBarView._contentBottomRightCorner != null) {
+				_otherScrollBarView._contentBottomRightCorner.Visible = false;
 			}
 			}
-			if (_contentBottomRightCorner != null && _contentBottomRightCorner.Visible) {
-				_contentBottomRightCorner.Draw ();
-			} else if (_otherScrollBarView != null && _otherScrollBarView._contentBottomRightCorner != null && _otherScrollBarView._contentBottomRightCorner.Visible) {
-				_otherScrollBarView._contentBottomRightCorner.Draw ();
+			if (Application.MouseGrabView != null && Application.MouseGrabView == this) {
+				Application.UngrabMouse ();
 			}
 			}
+		} else if (_contentBottomRightCorner != null) {
+			_contentBottomRightCorner.Visible = false;
+		} else if (_otherScrollBarView != null && _otherScrollBarView._contentBottomRightCorner != null) {
+			_otherScrollBarView._contentBottomRightCorner.Visible = false;
+		}
+		if (Host?.Visible == true && _showScrollIndicator && !Visible) {
+			Visible = true;
+		}
+		if (Host?.Visible == true && _otherScrollBarView?._showScrollIndicator == true && !_otherScrollBarView.Visible) {
+			_otherScrollBarView.Visible = true;
 		}
 		}
 
 
-		bool CheckBothScrollBars (ScrollBarView scrollBarView, bool pending = false)
-		{
-			int barsize = scrollBarView._vertical ? scrollBarView.Bounds.Height : scrollBarView.Bounds.Width;
+		if (!redraw) {
+			return;
+		}
 
 
-			if (barsize == 0 || barsize >= scrollBarView._size) {
-				if (scrollBarView._showScrollIndicator) {
-					scrollBarView.ShowScrollIndicator = false;
-				}
-				if (scrollBarView.Visible) {
-					scrollBarView.Visible = false;
-				}
-			} else if (barsize > 0 && barsize == scrollBarView._size && scrollBarView.OtherScrollBarView != null && pending) {
-				if (scrollBarView._showScrollIndicator) {
-					scrollBarView.ShowScrollIndicator = false;
-				}
-				if (scrollBarView.Visible) {
-					scrollBarView.Visible = false;
-				}
-				if (scrollBarView.OtherScrollBarView != null && scrollBarView._showBothScrollIndicator) {
-					scrollBarView.OtherScrollBarView.ShowScrollIndicator = false;
-				}
-				if (scrollBarView.OtherScrollBarView.Visible) {
-					scrollBarView.OtherScrollBarView.Visible = false;
-				}
-			} else if (barsize > 0 && barsize == _size && scrollBarView.OtherScrollBarView != null && !pending) {
-				pending = true;
-			} else {
-				if (scrollBarView.OtherScrollBarView != null && pending) {
-					if (!scrollBarView._showBothScrollIndicator) {
-						scrollBarView.OtherScrollBarView.ShowScrollIndicator = true;
-					}
-					if (!scrollBarView.OtherScrollBarView.Visible) {
-						scrollBarView.OtherScrollBarView.Visible = true;
-					}
-				}
-				if (!scrollBarView._showScrollIndicator) {
-					scrollBarView.ShowScrollIndicator = true;
+		if (_showScrollIndicator) {
+			Draw ();
+		}
+		if (_otherScrollBarView != null && _otherScrollBarView._showScrollIndicator) {
+			_otherScrollBarView.Draw ();
+		}
+		if (_contentBottomRightCorner != null && _contentBottomRightCorner.Visible) {
+			_contentBottomRightCorner.Draw ();
+		} else if (_otherScrollBarView != null && _otherScrollBarView._contentBottomRightCorner != null && _otherScrollBarView._contentBottomRightCorner.Visible) {
+			_otherScrollBarView._contentBottomRightCorner.Draw ();
+		}
+	}
+
+	bool CheckBothScrollBars (ScrollBarView scrollBarView, bool pending = false)
+	{
+		var barsize = scrollBarView._vertical ? scrollBarView.Bounds.Height : scrollBarView.Bounds.Width;
+
+		if (barsize == 0 || barsize >= scrollBarView._size) {
+			if (scrollBarView._showScrollIndicator) {
+				scrollBarView.ShowScrollIndicator = false;
+			}
+			if (scrollBarView.Visible) {
+				scrollBarView.Visible = false;
+			}
+		} else if (barsize > 0 && barsize == scrollBarView._size && scrollBarView.OtherScrollBarView != null && pending) {
+			if (scrollBarView._showScrollIndicator) {
+				scrollBarView.ShowScrollIndicator = false;
+			}
+			if (scrollBarView.Visible) {
+				scrollBarView.Visible = false;
+			}
+			if (scrollBarView.OtherScrollBarView != null && scrollBarView._showBothScrollIndicator) {
+				scrollBarView.OtherScrollBarView.ShowScrollIndicator = false;
+			}
+			if (scrollBarView.OtherScrollBarView.Visible) {
+				scrollBarView.OtherScrollBarView.Visible = false;
+			}
+		} else if (barsize > 0 && barsize == _size && scrollBarView.OtherScrollBarView != null && !pending) {
+			pending = true;
+		} else {
+			if (scrollBarView.OtherScrollBarView != null && pending) {
+				if (!scrollBarView._showBothScrollIndicator) {
+					scrollBarView.OtherScrollBarView.ShowScrollIndicator = true;
 				}
 				}
-				if (!scrollBarView.Visible) {
-					scrollBarView.Visible = true;
+				if (!scrollBarView.OtherScrollBarView.Visible) {
+					scrollBarView.OtherScrollBarView.Visible = true;
 				}
 				}
 			}
 			}
-
-			return pending;
+			if (!scrollBarView._showScrollIndicator) {
+				scrollBarView.ShowScrollIndicator = true;
+			}
+			if (!scrollBarView.Visible) {
+				scrollBarView.Visible = true;
+			}
 		}
 		}
 
 
-		// BUGBUG: v2 - rationalize this with View.SetMinWidthHeight
-		void SetWidthHeight ()
-		{
-			// BUGBUG: v2 - If Host is also the ScrollBarView's superview, this is all bogus because it's not
-			// supported that a view can reference it's superview's Dims. This code also assumes the host does 
-			//  not have a margin/borderframe/padding.
-			if (!IsInitialized) {
-				return;
-			}
+		return pending;
+	}
 
 
-			if (_showBothScrollIndicator) {
-				Width = _vertical ? 1 : Host != SuperView ? Dim.Width (Host) - 1 : Dim.Fill () - 1;
-				Height = _vertical ? Host != SuperView ? Dim.Height (Host) - 1 : Dim.Fill () - 1 : 1;
+	// BUGBUG: v2 - rationalize this with View.SetMinWidthHeight
+	void SetWidthHeight ()
+	{
+		// BUGBUG: v2 - If Host is also the ScrollBarView's superview, this is all bogus because it's not
+		// supported that a view can reference it's superview's Dims. This code also assumes the host does 
+		//  not have a margin/borderframe/padding.
+		if (!IsInitialized) {
+			return;
+		}
+
+		if (_showBothScrollIndicator) {
+			Width = _vertical ? 1 : Host != SuperView ? Dim.Width (Host) - 1 : Dim.Fill () - 1;
+			Height = _vertical ? Host != SuperView ? Dim.Height (Host) - 1 : Dim.Fill () - 1 : 1;
+
+			_otherScrollBarView.Width = _otherScrollBarView._vertical ? 1 : Host != SuperView ? Dim.Width (Host) - 1 : Dim.Fill () - 1;
+			_otherScrollBarView.Height = _otherScrollBarView._vertical ? Host != SuperView ? Dim.Height (Host) - 1 : Dim.Fill () - 1 : 1;
+		} else if (_showScrollIndicator) {
+			Width = _vertical ? 1 : Host != SuperView ? Dim.Width (Host) : Dim.Fill ();
+			Height = _vertical ? Host != SuperView ? Dim.Height (Host) : Dim.Fill () : 1;
+		} else if (_otherScrollBarView?._showScrollIndicator == true) {
+			_otherScrollBarView.Width = _otherScrollBarView._vertical ? 1 : Host != SuperView ? Dim.Width (Host) : Dim.Fill () - 0;
+			_otherScrollBarView.Height = _otherScrollBarView._vertical ? Host != SuperView ? Dim.Height (Host) : Dim.Fill () - 0 : 1;
+		}
+	}
 
 
-				_otherScrollBarView.Width = _otherScrollBarView._vertical ? 1 : Host != SuperView ? Dim.Width (Host) - 1 : Dim.Fill () - 1;
-				_otherScrollBarView.Height = _otherScrollBarView._vertical ? Host != SuperView ? Dim.Height (Host) - 1 : Dim.Fill () - 1 : 1;
-			} else if (_showScrollIndicator) {
-				Width = _vertical ? 1 : Host != SuperView ? Dim.Width (Host) : Dim.Fill ();
-				Height = _vertical ? Host != SuperView ? Dim.Height (Host) : Dim.Fill () : 1;
-			} else if (_otherScrollBarView?._showScrollIndicator == true) {
-				_otherScrollBarView.Width = _otherScrollBarView._vertical ? 1 : Host != SuperView ? Dim.Width (Host) : Dim.Fill () - 0;
-				_otherScrollBarView.Height = _otherScrollBarView._vertical ? Host != SuperView ? Dim.Height (Host) : Dim.Fill () - 0 : 1;
+	///<inheritdoc/>
+	public override void OnDrawContent (Rect contentArea)
+	{
+		if (ColorScheme == null || (!_showScrollIndicator || Size == 0) && AutoHideScrollBars && Visible) {
+			if ((!_showScrollIndicator || Size == 0) && AutoHideScrollBars && Visible) {
+				ShowHideScrollBars (false);
 			}
 			}
+			return;
 		}
 		}
 
 
-		int _posTopTee;
-		int _posLeftTee;
-		int _posBottomTee;
-		int _posRightTee;
+		if (Size == 0 || _vertical && Bounds.Height == 0 || !_vertical && Bounds.Width == 0) {
+			return;
+		}
 
 
-		///<inheritdoc/>
-		public override void OnDrawContent (Rect contentArea)
-		{
-			if (ColorScheme == null || ((!_showScrollIndicator || Size == 0) && AutoHideScrollBars && Visible)) {
-				if ((!_showScrollIndicator || Size == 0) && AutoHideScrollBars && Visible) {
-					ShowHideScrollBars (false);
-				}
-				return;
-			}
+		Driver.SetAttribute (Host.HasFocus ? ColorScheme.Focus : GetNormalColor ());
 
 
-			if (Size == 0 || (_vertical && Bounds.Height == 0) || (!_vertical && Bounds.Width == 0)) {
+		if (_vertical) {
+			if (Bounds.Right < Bounds.Width - 1) {
 				return;
 				return;
 			}
 			}
 
 
-			Driver.SetAttribute (Host.HasFocus ? ColorScheme.Focus : GetNormalColor ());
+			var col = Bounds.Width - 1;
+			var bh = Bounds.Height;
+			Rune special;
 
 
-			if (_vertical) {
-				if (Bounds.Right < Bounds.Width - 1) {
-					return;
-				}
-
-				var col = Bounds.Width - 1;
-				var bh = Bounds.Height;
-				Rune special;
+			if (bh < 4) {
+				var by1 = _position * bh / Size;
+				var by2 = (_position + bh) * bh / Size;
 
 
-				if (bh < 4) {
-					var by1 = _position * bh / Size;
-					var by2 = (_position + bh) * bh / Size;
-
-					Move (col, 0);
-					if (Bounds.Height == 1) {
-						Driver.AddRune (CM.Glyphs.Diamond);
-					} else {
-						Driver.AddRune (CM.Glyphs.UpArrow);
-					}
-					if (Bounds.Height == 3) {
-						Move (col, 1);
-						Driver.AddRune (CM.Glyphs.Diamond);
-					}
-					if (Bounds.Height > 1) {
-						Move (col, Bounds.Height - 1);
-						Driver.AddRune (CM.Glyphs.DownArrow);
-					}
+				Move (col, 0);
+				if (Bounds.Height == 1) {
+					Driver.AddRune (Glyphs.Diamond);
 				} else {
 				} else {
-					bh -= 2;
-					var by1 = KeepContentAlwaysInViewport ? _position * bh / Size : _position * bh / (Size + bh);
-					var by2 = KeepContentAlwaysInViewport ? Math.Min (((_position + bh) * bh / Size) + 1, bh - 1) : (_position + bh) * bh / (Size + bh);
-					if (KeepContentAlwaysInViewport && by1 == by2) {
-						by1 = Math.Max (by1 - 1, 0);
-					}
-
-					Move (col, 0);
-					Driver.AddRune (CM.Glyphs.UpArrow);
-
-					bool hasTopTee = false;
-					bool hasDiamond = false;
-					bool hasBottomTee = false;
-					for (int y = 0; y < bh; y++) {
-						Move (col, y + 1);
-						if ((y < by1 || y > by2) && ((_position > 0 && !hasTopTee) || (hasTopTee && hasBottomTee))) {
-							special = CM.Glyphs.Stipple;
+					Driver.AddRune (Glyphs.UpArrow);
+				}
+				if (Bounds.Height == 3) {
+					Move (col, 1);
+					Driver.AddRune (Glyphs.Diamond);
+				}
+				if (Bounds.Height > 1) {
+					Move (col, Bounds.Height - 1);
+					Driver.AddRune (Glyphs.DownArrow);
+				}
+			} else {
+				bh -= 2;
+				var by1 = KeepContentAlwaysInViewport ? _position * bh / Size : _position * bh / (Size + bh);
+				var by2 = KeepContentAlwaysInViewport ? Math.Min ((_position + bh) * bh / Size + 1, bh - 1) : (_position + bh) * bh / (Size + bh);
+				if (KeepContentAlwaysInViewport && by1 == by2) {
+					by1 = Math.Max (by1 - 1, 0);
+				}
+
+				Move (col, 0);
+				Driver.AddRune (Glyphs.UpArrow);
+
+				var hasTopTee = false;
+				var hasDiamond = false;
+				var hasBottomTee = false;
+				for (var y = 0; y < bh; y++) {
+					Move (col, y + 1);
+					if ((y < by1 || y > by2) && (_position > 0 && !hasTopTee || hasTopTee && hasBottomTee)) {
+						special = Glyphs.Stipple;
+					} else {
+						if (y != by2 && y > 1 && by2 - by1 == 0 && by1 < bh - 1 && hasTopTee && !hasDiamond) {
+							hasDiamond = true;
+							special = Glyphs.Diamond;
 						} else {
 						} else {
-							if (y != by2 && y > 1 && by2 - by1 == 0 && by1 < bh - 1 && hasTopTee && !hasDiamond) {
-								hasDiamond = true;
-								special = CM.Glyphs.Diamond;
+							if (y == by1 && !hasTopTee) {
+								hasTopTee = true;
+								_posTopTee = y;
+								special = Glyphs.TopTee;
+							} else if ((_position == 0 && y == bh - 1 || y >= by2 || by2 == 0) && !hasBottomTee) {
+								hasBottomTee = true;
+								_posBottomTee = y;
+								special = Glyphs.BottomTee;
 							} else {
 							} else {
-								if (y == by1 && !hasTopTee) {
-									hasTopTee = true;
-									_posTopTee = y;
-									special = CM.Glyphs.TopTee;
-								} else if ((_position == 0 && y == bh - 1 || y >= by2 || by2 == 0) && !hasBottomTee) {
-									hasBottomTee = true;
-									_posBottomTee = y;
-									special = CM.Glyphs.BottomTee;
-								} else {
-									special = CM.Glyphs.VLine;
-								}
+								special = Glyphs.VLine;
 							}
 							}
 						}
 						}
-						Driver.AddRune (special);
 					}
 					}
-					if (!hasTopTee) {
-						Move (col, Bounds.Height - 2);
-						Driver.AddRune (CM.Glyphs.TopTee);
-					}
-					Move (col, Bounds.Height - 1);
-					Driver.AddRune (CM.Glyphs.DownArrow);
+					Driver.AddRune (special);
 				}
 				}
-			} else {
-				if (Bounds.Bottom < Bounds.Height - 1) {
-					return;
+				if (!hasTopTee) {
+					Move (col, Bounds.Height - 2);
+					Driver.AddRune (Glyphs.TopTee);
 				}
 				}
+				Move (col, Bounds.Height - 1);
+				Driver.AddRune (Glyphs.DownArrow);
+			}
+		} else {
+			if (Bounds.Bottom < Bounds.Height - 1) {
+				return;
+			}
 
 
-				var row = Bounds.Height - 1;
-				var bw = Bounds.Width;
-				Rune special;
-
-				if (bw < 4) {
-					var bx1 = _position * bw / Size;
-					var bx2 = (_position + bw) * bw / Size;
-
-					Move (0, row);
-					Driver.AddRune (CM.Glyphs.LeftArrow);
-					Driver.AddRune (CM.Glyphs.RightArrow);
-				} else {
-					bw -= 2;
-					var bx1 = KeepContentAlwaysInViewport ? _position * bw / Size : _position * bw / (Size + bw);
-					var bx2 = KeepContentAlwaysInViewport ? Math.Min (((_position + bw) * bw / Size) + 1, bw - 1) : (_position + bw) * bw / (Size + bw);
-					if (KeepContentAlwaysInViewport && bx1 == bx2) {
-						bx1 = Math.Max (bx1 - 1, 0);
-					}
+			var row = Bounds.Height - 1;
+			var bw = Bounds.Width;
+			Rune special;
 
 
-					Move (0, row);
-					Driver.AddRune (CM.Glyphs.LeftArrow);
+			if (bw < 4) {
+				var bx1 = _position * bw / Size;
+				var bx2 = (_position + bw) * bw / Size;
 
 
-					bool hasLeftTee = false;
-					bool hasDiamond = false;
-					bool hasRightTee = false;
-					for (int x = 0; x < bw; x++) {
-						if ((x < bx1 || x >= bx2 + 1) && ((_position > 0 && !hasLeftTee) || (hasLeftTee && hasRightTee))) {
-							special = CM.Glyphs.Stipple;
+				Move (0, row);
+				Driver.AddRune (Glyphs.LeftArrow);
+				Driver.AddRune (Glyphs.RightArrow);
+			} else {
+				bw -= 2;
+				var bx1 = KeepContentAlwaysInViewport ? _position * bw / Size : _position * bw / (Size + bw);
+				var bx2 = KeepContentAlwaysInViewport ? Math.Min ((_position + bw) * bw / Size + 1, bw - 1) : (_position + bw) * bw / (Size + bw);
+				if (KeepContentAlwaysInViewport && bx1 == bx2) {
+					bx1 = Math.Max (bx1 - 1, 0);
+				}
+
+				Move (0, row);
+				Driver.AddRune (Glyphs.LeftArrow);
+
+				var hasLeftTee = false;
+				var hasDiamond = false;
+				var hasRightTee = false;
+				for (var x = 0; x < bw; x++) {
+					if ((x < bx1 || x >= bx2 + 1) && (_position > 0 && !hasLeftTee || hasLeftTee && hasRightTee)) {
+						special = Glyphs.Stipple;
+					} else {
+						if (x != bx2 && x > 1 && bx2 - bx1 == 0 && bx1 < bw - 1 && hasLeftTee && !hasDiamond) {
+							hasDiamond = true;
+							special = Glyphs.Diamond;
 						} else {
 						} else {
-							if (x != bx2 && x > 1 && bx2 - bx1 == 0 && bx1 < bw - 1 && hasLeftTee && !hasDiamond) {
-								hasDiamond = true;
-								special = CM.Glyphs.Diamond;
+							if (x == bx1 && !hasLeftTee) {
+								hasLeftTee = true;
+								_posLeftTee = x;
+								special = Glyphs.LeftTee;
+							} else if ((_position == 0 && x == bw - 1 || x >= bx2 || bx2 == 0) && !hasRightTee) {
+								hasRightTee = true;
+								_posRightTee = x;
+								special = Glyphs.RightTee;
 							} else {
 							} else {
-								if (x == bx1 && !hasLeftTee) {
-									hasLeftTee = true;
-									_posLeftTee = x;
-									special = CM.Glyphs.LeftTee;
-								} else if ((_position == 0 && x == bw - 1 || x >= bx2 || bx2 == 0) && !hasRightTee) {
-									hasRightTee = true;
-									_posRightTee = x;
-									special = CM.Glyphs.RightTee;
-								} else {
-									special = CM.Glyphs.HLine;
-								}
+								special = Glyphs.HLine;
 							}
 							}
 						}
 						}
-						Driver.AddRune (special);
 					}
 					}
-					if (!hasLeftTee) {
-						Move (Bounds.Width - 2, row);
-						Driver.AddRune (CM.Glyphs.LeftTee);
-					}
-
-					Driver.AddRune (CM.Glyphs.RightArrow);
+					Driver.AddRune (special);
+				}
+				if (!hasLeftTee) {
+					Move (Bounds.Width - 2, row);
+					Driver.AddRune (Glyphs.LeftTee);
 				}
 				}
-			}
-		}
-
-		int _lastLocation = -1;
-		int _posBarOffset;
-
-		///<inheritdoc/>
-		public override bool MouseEvent (MouseEvent mouseEvent)
-		{
-			if (mouseEvent.Flags != MouseFlags.Button1Pressed && mouseEvent.Flags != MouseFlags.Button1DoubleClicked &&
-				!mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) &&
-				mouseEvent.Flags != MouseFlags.Button1Released && mouseEvent.Flags != MouseFlags.WheeledDown &&
-				mouseEvent.Flags != MouseFlags.WheeledUp && mouseEvent.Flags != MouseFlags.WheeledRight &&
-				mouseEvent.Flags != MouseFlags.WheeledLeft && mouseEvent.Flags != MouseFlags.Button1TripleClicked) {
 
 
-				return false;
+				Driver.AddRune (Glyphs.RightArrow);
 			}
 			}
+		}
+	}
 
 
-			if (!Host.CanFocus) {
-				return true;
-			}
-			if (Host?.HasFocus == false) {
-				Host.SetFocus ();
-			}
+	///<inheritdoc/>
+	public override bool MouseEvent (MouseEvent mouseEvent)
+	{
+		if (mouseEvent.Flags != MouseFlags.Button1Pressed &&
+		    mouseEvent.Flags != MouseFlags.Button1DoubleClicked &&
+		    !mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) &&
+		    mouseEvent.Flags != MouseFlags.Button1Released &&
+		    mouseEvent.Flags != MouseFlags.WheeledDown &&
+		    mouseEvent.Flags != MouseFlags.WheeledUp &&
+		    mouseEvent.Flags != MouseFlags.WheeledRight &&
+		    mouseEvent.Flags != MouseFlags.WheeledLeft &&
+		    mouseEvent.Flags != MouseFlags.Button1TripleClicked) {
 
 
-			int location = _vertical ? mouseEvent.Y : mouseEvent.X;
-			int barsize = _vertical ? Bounds.Height : Bounds.Width;
-			int posTopLeftTee = _vertical ? _posTopTee + 1 : _posLeftTee + 1;
-			int posBottomRightTee = _vertical ? _posBottomTee + 1 : _posRightTee + 1;
-			barsize -= 2;
-			var pos = Position;
+			return false;
+		}
 
 
-			if (mouseEvent.Flags != MouseFlags.Button1Released
-				&& (Application.MouseGrabView == null || Application.MouseGrabView != this)) {
-				Application.GrabMouse (this);
-			} else if (mouseEvent.Flags == MouseFlags.Button1Released && Application.MouseGrabView != null && Application.MouseGrabView == this) {
-				_lastLocation = -1;
-				Application.UngrabMouse ();
-				return true;
-			}
-			if (_showScrollIndicator && (mouseEvent.Flags == MouseFlags.WheeledDown || mouseEvent.Flags == MouseFlags.WheeledUp ||
-				mouseEvent.Flags == MouseFlags.WheeledRight || mouseEvent.Flags == MouseFlags.WheeledLeft)) {
+		if (!Host.CanFocus) {
+			return true;
+		}
+		if (Host?.HasFocus == false) {
+			Host.SetFocus ();
+		}
 
 
-				return Host.MouseEvent (mouseEvent);
-			}
+		var location = _vertical ? mouseEvent.Y : mouseEvent.X;
+		var barsize = _vertical ? Bounds.Height : Bounds.Width;
+		var posTopLeftTee = _vertical ? _posTopTee + 1 : _posLeftTee + 1;
+		var posBottomRightTee = _vertical ? _posBottomTee + 1 : _posRightTee + 1;
+		barsize -= 2;
+		var pos = Position;
+
+		if (mouseEvent.Flags != MouseFlags.Button1Released && (Application.MouseGrabView == null || Application.MouseGrabView != this)) {
+			Application.GrabMouse (this);
+		} else if (mouseEvent.Flags == MouseFlags.Button1Released && Application.MouseGrabView != null && Application.MouseGrabView == this) {
+			_lastLocation = -1;
+			Application.UngrabMouse ();
+			return true;
+		}
+		if (_showScrollIndicator &&
+		    (mouseEvent.Flags == MouseFlags.WheeledDown ||
+		     mouseEvent.Flags == MouseFlags.WheeledUp ||
+		     mouseEvent.Flags == MouseFlags.WheeledRight ||
+		     mouseEvent.Flags == MouseFlags.WheeledLeft)) {
 
 
-			if (mouseEvent.Flags == MouseFlags.Button1Pressed && location == 0) {
-				if (pos > 0) {
-					Position = pos - 1;
-				}
-			} else if (mouseEvent.Flags == MouseFlags.Button1Pressed && location == barsize + 1) {
-				if (CanScroll (1, out _, _vertical)) {
-					Position = pos + 1;
-				}
-			} else if (location > 0 && location < barsize + 1) {
-				//var b1 = pos * (Size > 0 ? barsize / Size : 0);
-				//var b2 = Size > 0
-				//	? (KeepContentAlwaysInViewport ? Math.Min (((pos + barsize) * barsize / Size) + 1, barsize - 1) : (pos + barsize) * barsize / Size)
-				//	: 0;
-				//if (KeepContentAlwaysInViewport && b1 == b2) {
-				//	b1 = Math.Max (b1 - 1, 0);
-				//}
-
-				if (_lastLocation > -1 || (location >= posTopLeftTee && location <= posBottomRightTee
-				&& mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition))) {
-					if (_lastLocation == -1) {
-						_lastLocation = location;
-						_posBarOffset = _keepContentAlwaysInViewport ? Math.Max (location - posTopLeftTee, 1) : 0;
-						return true;
-					}
+			return Host.MouseEvent (mouseEvent);
+		}
 
 
-					if (location > _lastLocation) {
-						if (location - _posBarOffset < barsize) {
-							var np = ((location - _posBarOffset) * Size / barsize) + (Size / barsize);
-							if (CanScroll (np - pos, out int nv, _vertical)) {
-								Position = pos + nv;
-							}
-						} else if (CanScroll (Size - pos, out int nv, _vertical)) {
-							Position = Math.Min (pos + nv, Size);
-						}
-					} else if (location < _lastLocation) {
-						if (location - _posBarOffset > 0) {
-							var np = ((location - _posBarOffset) * Size / barsize) - (Size / barsize);
-							if (CanScroll (np - pos, out int nv, _vertical)) {
-								Position = pos + nv;
-							}
-						} else {
-							Position = 0;
+		if (mouseEvent.Flags == MouseFlags.Button1Pressed && location == 0) {
+			if (pos > 0) {
+				Position = pos - 1;
+			}
+		} else if (mouseEvent.Flags == MouseFlags.Button1Pressed && location == barsize + 1) {
+			if (CanScroll (1, out _, _vertical)) {
+				Position = pos + 1;
+			}
+		} else if (location > 0 && location < barsize + 1) {
+			//var b1 = pos * (Size > 0 ? barsize / Size : 0);
+			//var b2 = Size > 0
+			//	? (KeepContentAlwaysInViewport ? Math.Min (((pos + barsize) * barsize / Size) + 1, barsize - 1) : (pos + barsize) * barsize / Size)
+			//	: 0;
+			//if (KeepContentAlwaysInViewport && b1 == b2) {
+			//	b1 = Math.Max (b1 - 1, 0);
+			//}
+
+			if (_lastLocation > -1 || location >= posTopLeftTee && location <= posBottomRightTee && mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition)) {
+				if (_lastLocation == -1) {
+					_lastLocation = location;
+					_posBarOffset = _keepContentAlwaysInViewport ? Math.Max (location - posTopLeftTee, 1) : 0;
+					return true;
+				}
+
+				if (location > _lastLocation) {
+					if (location - _posBarOffset < barsize) {
+						var np = (location - _posBarOffset) * Size / barsize + Size / barsize;
+						if (CanScroll (np - pos, out var nv, _vertical)) {
+							Position = pos + nv;
 						}
 						}
-					} else if (location - _posBarOffset >= barsize && posBottomRightTee - posTopLeftTee >= 3 && CanScroll (Size - pos, out int nv, _vertical)) {
-						Position = Math.Min (pos + nv, Size);
-					} else if (location - _posBarOffset >= barsize - 1 && posBottomRightTee - posTopLeftTee <= 3 && CanScroll (Size - pos, out nv, _vertical)) {
+					} else if (CanScroll (Size - pos, out var nv, _vertical)) {
 						Position = Math.Min (pos + nv, Size);
 						Position = Math.Min (pos + nv, Size);
-					} else if (location - _posBarOffset <= 0 && posBottomRightTee - posTopLeftTee <= 3) {
-						Position = 0;
-					}
-				} else if (location > posBottomRightTee) {
-					if (CanScroll (barsize, out int nv, _vertical)) {
-						Position = pos + nv;
 					}
 					}
-				} else if (location < posTopLeftTee) {
-					if (CanScroll (-barsize, out int nv, _vertical)) {
-						Position = pos + nv;
+				} else if (location < _lastLocation) {
+					if (location - _posBarOffset > 0) {
+						var np = (location - _posBarOffset) * Size / barsize - Size / barsize;
+						if (CanScroll (np - pos, out var nv, _vertical)) {
+							Position = pos + nv;
+						}
+					} else {
+						Position = 0;
 					}
 					}
-				} else if (location == 1 && posTopLeftTee <= 3) {
+				} else if (location - _posBarOffset >= barsize && posBottomRightTee - posTopLeftTee >= 3 && CanScroll (Size - pos, out var nv, _vertical)) {
+					Position = Math.Min (pos + nv, Size);
+				} else if (location - _posBarOffset >= barsize - 1 && posBottomRightTee - posTopLeftTee <= 3 && CanScroll (Size - pos, out nv, _vertical)) {
+					Position = Math.Min (pos + nv, Size);
+				} else if (location - _posBarOffset <= 0 && posBottomRightTee - posTopLeftTee <= 3) {
 					Position = 0;
 					Position = 0;
-				} else if (location == barsize) {
-					if (CanScroll (Size - pos, out int nv, _vertical)) {
-						Position = Math.Min (pos + nv, Size);
-					}
+				}
+			} else if (location > posBottomRightTee) {
+				if (CanScroll (barsize, out var nv, _vertical)) {
+					Position = pos + nv;
+				}
+			} else if (location < posTopLeftTee) {
+				if (CanScroll (-barsize, out var nv, _vertical)) {
+					Position = pos + nv;
+				}
+			} else if (location == 1 && posTopLeftTee <= 3) {
+				Position = 0;
+			} else if (location == barsize) {
+				if (CanScroll (Size - pos, out var nv, _vertical)) {
+					Position = Math.Min (pos + nv, Size);
 				}
 				}
 			}
 			}
-
-			return true;
 		}
 		}
 
 
-		internal bool CanScroll (int n, out int max, bool isVertical = false)
-		{
-			if (Host?.Bounds.IsEmpty != false) {
-				max = 0;
-				return false;
-			}
-			int s = GetBarsize (isVertical);
-			var newSize = Math.Max (Math.Min (_size - s, _position + n), 0);
-			max = _size > s + newSize ? (newSize == 0 ? -_position : n) : _size - (s + _position) - 1;
-			if (_size >= s + newSize && max != 0) {
-				return true;
-			}
+		return true;
+	}
+
+	internal bool CanScroll (int n, out int max, bool isVertical = false)
+	{
+		if (Host?.Bounds.IsEmpty != false) {
+			max = 0;
 			return false;
 			return false;
 		}
 		}
+		var s = GetBarsize (isVertical);
+		var newSize = Math.Max (Math.Min (_size - s, _position + n), 0);
+		max = _size > s + newSize ? newSize == 0 ? -_position : n : _size - (s + _position) - 1;
+		if (_size >= s + newSize && max != 0) {
+			return true;
+		}
+		return false;
+	}
 
 
-		int GetBarsize (bool isVertical)
-		{
-			if (Host?.Bounds.IsEmpty != false) {
-				return 0;
-			}
-			return isVertical ?
-				(KeepContentAlwaysInViewport ? Host.Bounds.Height + (_showBothScrollIndicator ? -2 : -1) : 0) :
-				(KeepContentAlwaysInViewport ? Host.Bounds.Width + (_showBothScrollIndicator ? -2 : -1) : 0);
+	int GetBarsize (bool isVertical)
+	{
+		if (Host?.Bounds.IsEmpty != false) {
+			return 0;
 		}
 		}
+		return isVertical ?
+			KeepContentAlwaysInViewport ? Host.Bounds.Height + (_showBothScrollIndicator ? -2 : -1) : 0 :
+			KeepContentAlwaysInViewport ? Host.Bounds.Width + (_showBothScrollIndicator ? -2 : -1) : 0;
+	}
 
 
-		///<inheritdoc/>
-		public override bool OnEnter (View view)
-		{
-			Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
+	///<inheritdoc/>
+	public override bool OnEnter (View view)
+	{
+		Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
 
 
-			return base.OnEnter (view);
-		}
+		return base.OnEnter (view);
 	}
 	}
-}
+}

+ 0 - 1
Terminal.Gui/Views/TextField.cs

@@ -227,7 +227,6 @@ namespace Terminal.Gui {
 			if (Frame.Height > 1) {
 			if (Frame.Height > 1) {
 				Height = 1;
 				Height = 1;
 			} 
 			} 
-			Adjust ();
 		}
 		}
 
 
 
 

+ 1 - 1
UICatalog/Scenarios/TabViewExample.cs

@@ -59,7 +59,7 @@ namespace UICatalog.Scenarios {
 			};
 			};
 
 
 			tabView.AddTab (new Tab ("Tab1", new Label ("hodor!")), false);
 			tabView.AddTab (new Tab ("Tab1", new Label ("hodor!")), false);
-			tabView.AddTab (new Tab ("Tab2", new Label ("durdur")), false);
+			tabView.AddTab (new Tab ("Tab2", new TextField ("durdur")), false);
 			tabView.AddTab (new Tab ("Interactive Tab", GetInteractiveTab ()), false);
 			tabView.AddTab (new Tab ("Interactive Tab", GetInteractiveTab ()), false);
 			tabView.AddTab (new Tab ("Big Text", GetBigTextFileTab ()), false);
 			tabView.AddTab (new Tab ("Big Text", GetBigTextFileTab ()), false);
 			tabView.AddTab (new Tab (
 			tabView.AddTab (new Tab (

+ 1 - 1
UICatalog/Scenarios/Text.cs

@@ -233,7 +233,7 @@ namespace UICatalog.Scenarios {
 			};
 			};
 			var appendAutocompleteTextField = new TextField () {
 			var appendAutocompleteTextField = new TextField () {
 				X = Pos.Right (labelAppendAutocomplete),
 				X = Pos.Right (labelAppendAutocomplete),
-				Y = labelAppendAutocomplete.Y,
+				Y = Pos.Bottom (labelAppendAutocomplete),
 				Width = Dim.Fill ()
 				Width = Dim.Fill ()
 			};
 			};
 			appendAutocompleteTextField.Autocomplete = new AppendAutocomplete (appendAutocompleteTextField);
 			appendAutocompleteTextField.Autocomplete = new AppendAutocomplete (appendAutocompleteTextField);

+ 27 - 21
UnitTests/Dialogs/DialogTests.cs

@@ -181,18 +181,33 @@ namespace Terminal.Gui.DialogTests {
 
 
 					// This is because of PostionTopLevels and EnsureVisibleBounds
 					// This is because of PostionTopLevels and EnsureVisibleBounds
 					Assert.Equal (new Point (3, 2), d.Frame.Location);
 					Assert.Equal (new Point (3, 2), d.Frame.Location);
-					Assert.Equal (new Size (17, 8), d.Frame.Size);
+					// #3127: Before					
+					//					Assert.Equal (new Size (17, 8), d.Frame.Size);
+					//					TestHelpers.AssertDriverContentsWithFrameAre (@"
+					//╔══════════════════╗
+					//║                  ║
+					//║  ┌───────────────┐
+					//║  │               │
+					//║  │               │
+					//║  │               │
+					//║  │               │
+					//║  │               │
+					//║  │               │
+					//╚══└───────────────┘", output);
+
+					// #3127: After: Because Toplevel is now Width/Height = Dim.Filll
+					Assert.Equal (new Size (15, 6), d.Frame.Size);
 					TestHelpers.AssertDriverContentsWithFrameAre (@"
 					TestHelpers.AssertDriverContentsWithFrameAre (@"
 ╔══════════════════╗
 ╔══════════════════╗
 ║                  ║
 ║                  ║
-║  ┌───────────────┐
-║  │               │
-║  │               │
-║  │               │
-║  │               │
-║  │               │
-║  │               │
-╚══└───────────────┘", output);
+║  ┌─────────────┐
+║  │             │
+║  │             │
+║  │             │
+║  │             │
+║  └─────────────┘ ║
+║  
+╚══════════════════╝", output);
 
 
 				} else if (iterations > 0) {
 				} else if (iterations > 0) {
 					Application.RequestStop ();
 					Application.RequestStop ();
@@ -971,20 +986,11 @@ namespace Terminal.Gui.DialogTests {
 					Application.Refresh ();
 					Application.Refresh ();
 					Assert.Equal (new Rect (10, 0, 6, 1), btn.Frame);
 					Assert.Equal (new Rect (10, 0, 6, 1), btn.Frame);
 					Assert.Equal (new Rect (0, 0, 6, 1), btn.Bounds);
 					Assert.Equal (new Rect (0, 0, 6, 1), btn.Bounds);
-					// #3127: Before: This test was clearly wrong before. The math above is correct, but the result is wrong.
-					// var expected = @$"
-					//┌──────────────────┐
-					//│┌────────────────┐│
-					//││23456789  {b}││
-					//│└────────────────┘│
-					//└──────────────────┘";
-
-					// #3127: After: This test was clearly wrong before. The math above is correct, but the result is wrong.
-					// See also `PosDimFunction` in SetRelativeLayoutTests.cs
+
 					var expected = @$"
 					var expected = @$"
 ┌──────────────────┐
 ┌──────────────────┐
 │┌────────────────┐│
 │┌────────────────┐│
-││012345678 {b}││
+││23456789  {b}││
 │└────────────────┘│
 │└────────────────┘│
 └──────────────────┘";
 └──────────────────┘";
 
 
@@ -998,7 +1004,7 @@ namespace Terminal.Gui.DialogTests {
 					expected = @$"
 					expected = @$"
 ┌──────────────────┐
 ┌──────────────────┐
 │┌────────────────┐│
 │┌────────────────┐│
-││012345678 {b}││
+││23456789  {b}││
 │└────────────────┘│
 │└────────────────┘│
 └──────────────────┘";
 └──────────────────┘";
 					_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 					_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);

+ 8 - 8
UnitTests/View/ViewTests.cs

@@ -265,20 +265,20 @@ namespace Terminal.Gui.ViewTests {
 			int tc = 0, wc = 0, v1c = 0, v2c = 0, sv1c = 0;
 			int tc = 0, wc = 0, v1c = 0, v2c = 0, sv1c = 0;
 
 
 			winAddedToTop.Added += (s, e) => {
 			winAddedToTop.Added += (s, e) => {
-				Assert.Equal (e.Parent.Bounds.Width, winAddedToTop.Frame.Width);
-				Assert.Equal (e.Parent.Bounds.Height, winAddedToTop.Frame.Height);
+				Assert.Equal (e.Parent.Frame.Width,  winAddedToTop.Frame.Width);
+				Assert.Equal (e.Parent.Frame.Height, winAddedToTop.Frame.Height);
 			};
 			};
 			v1AddedToWin.Added += (s, e) => {
 			v1AddedToWin.Added += (s, e) => {
-				Assert.Equal (e.Parent.Bounds.Width, v1AddedToWin.Frame.Width);
-				Assert.Equal (e.Parent.Bounds.Height, v1AddedToWin.Frame.Height);
+				Assert.Equal (e.Parent.Frame.Width,  v1AddedToWin.Frame.Width);
+				Assert.Equal (e.Parent.Frame.Height, v1AddedToWin.Frame.Height);
 			};
 			};
 			v2AddedToWin.Added += (s, e) => {
 			v2AddedToWin.Added += (s, e) => {
-				Assert.Equal (e.Parent.Bounds.Width, v2AddedToWin.Frame.Width);
-				Assert.Equal (e.Parent.Bounds.Height, v2AddedToWin.Frame.Height);
+				Assert.Equal (e.Parent.Frame.Width,  v2AddedToWin.Frame.Width);
+				Assert.Equal (e.Parent.Frame.Height, v2AddedToWin.Frame.Height);
 			};
 			};
 			svAddedTov1.Added += (s, e) => {
 			svAddedTov1.Added += (s, e) => {
-				Assert.Equal (e.Parent.Bounds.Width, svAddedTov1.Frame.Width);
-				Assert.Equal (e.Parent.Bounds.Height, svAddedTov1.Frame.Height);
+				Assert.Equal (e.Parent.Frame.Width,  svAddedTov1.Frame.Width);
+				Assert.Equal (e.Parent.Frame.Height, svAddedTov1.Frame.Height);
 			};
 			};
 
 
 			top.Initialized += (s, e) => {
 			top.Initialized += (s, e) => {

+ 6 - 1
UnitTests/Views/ScrollViewTests.cs

@@ -188,6 +188,8 @@ namespace Terminal.Gui.ViewsTests {
 			Application.Top.Add (sv);
 			Application.Top.Add (sv);
 			Application.Begin (Application.Top);
 			Application.Begin (Application.Top);
 
 
+			Assert.Equal (new Rect (0, 0, 10, 10), sv.Bounds);
+
 			Assert.False (sv.AutoHideScrollBars);
 			Assert.False (sv.AutoHideScrollBars);
 			Assert.True (sv.ShowHorizontalScrollIndicator);
 			Assert.True (sv.ShowHorizontalScrollIndicator);
 			Assert.True (sv.ShowVerticalScrollIndicator);
 			Assert.True (sv.ShowVerticalScrollIndicator);
@@ -206,7 +208,9 @@ namespace Terminal.Gui.ViewsTests {
 ", output);
 ", output);
 
 
 			sv.ShowHorizontalScrollIndicator = false;
 			sv.ShowHorizontalScrollIndicator = false;
+			Assert.Equal (new Rect (0, 0, 10, 10), sv.Bounds);
 			sv.ShowVerticalScrollIndicator = true;
 			sv.ShowVerticalScrollIndicator = true;
+			Assert.Equal (new Rect (0, 0, 10, 10), sv.Bounds);
 
 
 			Assert.False (sv.AutoHideScrollBars);
 			Assert.False (sv.AutoHideScrollBars);
 			Assert.False (sv.ShowHorizontalScrollIndicator);
 			Assert.False (sv.ShowHorizontalScrollIndicator);
@@ -220,6 +224,7 @@ namespace Terminal.Gui.ViewsTests {
+         │
 ", output);
 ", output);
@@ -241,7 +246,7 @@ namespace Terminal.Gui.ViewsTests {
          
          
          
          
          
          
-◄├─────┤► 
+◄├─────┤► 
 ", output);
 ", output);
 
 
 			sv.ShowHorizontalScrollIndicator = false;
 			sv.ShowHorizontalScrollIndicator = false;

+ 1 - 1
UnitTests/Views/TabViewTests.cs

@@ -33,7 +33,7 @@ namespace Terminal.Gui.ViewsTests {
 			tv.BeginInit ();
 			tv.BeginInit ();
 			tv.EndInit ();
 			tv.EndInit ();
 			tv.ColorScheme = new ColorScheme ();
 			tv.ColorScheme = new ColorScheme ();
-			tv.AddTab (tab1 = new Tab ("Tab1", new TextField ("hi")), false);
+			tv.AddTab (tab1 = new Tab ("Tab1", new TextField ("hi") { Width = 2 }), false);
 			tv.AddTab (tab2 = new Tab ("Tab2", new Label ("hi2")), false);
 			tv.AddTab (tab2 = new Tab ("Tab2", new Label ("hi2")), false);
 			return tv;
 			return tv;
 		}
 		}