Browse Source

Merge branch 'more_clip' into mondo_onlayoutcomplete_clip_msgboxdlg

Charlie Kindel 5 years ago
parent
commit
ecec2c9312

+ 4 - 1
.gitignore

@@ -8,4 +8,7 @@ packages
 # User-specific files
 *.user
 
-docfx/api
+docfx/api
+
+#git merge files
+*.orig

+ 3 - 3
Example/demo.cs

@@ -30,7 +30,7 @@ static class Demo {
 			throw new NotImplementedException ();
 		}
 
-		public override void Redraw (Rect region)
+		public override void Redraw (Rect bounds)
 		{
 			//Point pos = new Point (region.X, region.Y);
 			Driver.SetAttribute (ColorScheme.Focus);
@@ -53,7 +53,7 @@ static class Demo {
 		{
 		}
 
-		public override void Redraw (Rect region)
+		public override void Redraw (Rect bounds)
 		{
 			Driver.SetAttribute (ColorScheme.Focus);
 			var f = Frame;
@@ -509,7 +509,7 @@ static class Demo {
 
 		//Application.UseSystemConsole = true;
 
-		Application.Init ();
+		Application.Init();
 
 		var top = Application.Top;
 

+ 2 - 2
Terminal.Gui/Core/Application.cs

@@ -434,7 +434,7 @@ namespace Terminal.Gui {
 			Current = toplevel;
 			Driver.PrepareToRun (MainLoop, ProcessKeyEvent, ProcessKeyDownEvent, ProcessKeyUpEvent, ProcessMouseEvent);
 			if (toplevel.LayoutStyle == LayoutStyle.Computed)
-				toplevel.RelativeLayout (new Rect (0, 0, Driver.Cols, Driver.Rows));
+				toplevel.SetRelativeLayout (new Rect (0, 0, Driver.Cols, Driver.Rows));
 			toplevel.LayoutSubviews ();
 			Loaded?.Invoke (null, new ResizedEventArgs () { Rows = Driver.Rows, Cols = Driver.Cols });
 			toplevel.WillPresent ();
@@ -670,7 +670,7 @@ namespace Terminal.Gui {
 			Driver.Clip = full;
 			foreach (var t in toplevels) {
 				t.PositionToplevels ();
-				t.RelativeLayout (full);
+				t.SetRelativeLayout (full);
 				t.LayoutSubviews ();
 			}
 			Refresh ();

+ 1 - 1
Terminal.Gui/Core/ConsoleDriver.cs

@@ -5,7 +5,7 @@
 //   Miguel de Icaza ([email protected])
 //
 // Define this to enable diagnostics drawing for Window Frames
-#define DRAW_WINDOW_FRAME_DIAGNOSTICS
+//#define DRAW_WINDOW_FRAME_DIAGNOSTICS
 using NStack;
 using System;
 using System.Runtime.CompilerServices;

+ 23 - 22
Terminal.Gui/Core/Toplevel.cs

@@ -13,19 +13,18 @@ namespace Terminal.Gui {
 	/// </summary>
 	/// <remarks>
 	///   <para>
-	///     Toplevels can be modally executing views, and they return control
-	///     to the caller when the "Running" property is set to false, or
-	///     by calling <see cref="M:Terminal.Gui.Application.RequestStop()"/>
+	///     Toplevels can be modally executing views, started by calling <see cref="Application.Run(Toplevel, bool)"/>. 
+	///     They return control to the caller when <see cref="Application.RequestStop()"/> has 
+	///     been called (which sets the <see cref="Toplevel.Running"/> property to false). 
 	///   </para>
 	///   <para>
-	///     There will be a toplevel created for you on the first time use
-	///     and can be accessed from the property <see cref="P:Terminal.Gui.Application.Top"/>,
-	///     but new toplevels can be created and ran on top of it.   To run, create the
-	///     toplevel and then invoke <see cref="M:Terminal.Gui.Application.Run"/> with the
-	///     new toplevel.
+	///     A Toplevel is created when an application initialzies Terminal.Gui by callling <see cref="Application.Init()"/>.
+	///     The application Toplevel can be accessed via <see cref="Application.Top"/>. Additional Toplevels can be created 
+	///     and run (e.g. <see cref="Dialog"/>s. To run a Toplevel, create the <see cref="Toplevel"/> and 
+	///     call <see cref="Application.Run(Toplevel, bool)"/>.
 	///   </para>
 	///   <para>
-	///     TopLevels can also opt-in to more sophisticated initialization
+	///     Toplevels can also opt-in to more sophisticated initialization
 	///     by implementing <see cref="ISupportInitialize"/>. When they do
 	///     so, the <see cref="ISupportInitialize.BeginInit"/> and
 	///     <see cref="ISupportInitialize.EndInit"/> methods will be called
@@ -33,27 +32,29 @@ namespace Terminal.Gui {
 	///     If first-run-only initialization is preferred, the <see cref="ISupportInitializeNotification"/>
 	///     can be implemented too, in which case the <see cref="ISupportInitialize"/>
 	///     methods will only be called if <see cref="ISupportInitializeNotification.IsInitialized"/>
-	///     is <see langword="false"/>. This allows proper View inheritance hierarchies
+	///     is <see langword="false"/>. This allows proper <see cref="View"/> inheritance hierarchies
 	///     to override base class layout code optimally by doing so only on first run,
 	///     instead of on every run.
 	///   </para>
 	/// </remarks>
 	public class Toplevel : View {
 		/// <summary>
-		/// Gets or sets whether the Mainloop for this <see cref="Toplevel"/> is running or not. Setting
-		/// this property to false will cause the MainLoop to exit. 
+		/// Gets or sets whether the <see cref="MainLoop"/> for this <see cref="Toplevel"/> is running or not. 
 		/// </summary>
+		/// <remarks>
+		///    Setting this property directly is discouraged. Use <see cref="Application.RequestStop"/> instead. 
+		/// </remarks>
 		public bool Running { get; set; }
 
 		/// <summary>
-		/// Fired once the Toplevel's MainLoop has started it's first iteration. 
+		/// Fired once the Toplevel's <see cref="MainLoop"/> has started it's first iteration. 
 		/// Subscribe to this event to perform tasks when the <see cref="Toplevel"/> has been laid out and focus has been set.
 		/// changes. A Ready event handler is a good place to finalize initialization after calling `<see cref="Application.Run()"/>(topLevel)`. 
 		/// </summary>
 		public event EventHandler Ready;
 
 		/// <summary>
-		/// Called from Application.RunLoop after the <see cref="Toplevel"/> has entered it's first iteration of the loop. 
+		/// Called from <see cref="Application.RunLoop"/> after the <see cref="Toplevel"/> has entered it's first iteration of the loop. 
 		/// </summary>
 		internal virtual void OnReady ()
 		{
@@ -70,7 +71,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Initializes a new instance of the <see cref="Toplevel"/> class with Computed layout, defaulting to <see langword="async"/> full screen.
+		/// Initializes a new instance of the <see cref="Toplevel"/> class with <see cref="LayoutStyle.Computed"/> layout, defaulting to full screen.
 		/// </summary>
 		public Toplevel () : base ()
 		{
@@ -85,7 +86,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Convenience factory method that creates a new toplevel with the current terminal dimensions.
+		/// Convenience factory method that creates a new Toplevel with the current terminal dimensions.
 		/// </summary>
 		/// <returns>The create.</returns>
 		public static Toplevel Create ()
@@ -109,12 +110,12 @@ namespace Terminal.Gui {
 		public bool Modal { get; set; }
 
 		/// <summary>
-		/// Check id current toplevel has menu bar
+		/// Gets or sets the menu for this Toplevel
 		/// </summary>
 		public MenuBar MenuBar { get; set; }
 
 		/// <summary>
-		/// Check id current toplevel has status bar
+		/// Gets or sets the status bar for this Toplevel
 		/// </summary>
 		public StatusBar StatusBar { get; set; }
 
@@ -256,18 +257,18 @@ namespace Terminal.Gui {
 		}
 
 		///<inheritdoc cref="Redraw"/>
-		public override void Redraw (Rect region)
+		public override void Redraw (Rect bounds)
 		{
 			Application.CurrentView = this;
 
 			if (IsCurrentTop || this == Application.Top) {
 				if (NeedDisplay != null && !NeedDisplay.IsEmpty) {
 					Driver.SetAttribute (Colors.TopLevel.Normal);
-					Clear (region);
+					Clear (bounds);
 					Driver.SetAttribute (Colors.Base.Normal);
 				}
 				foreach (var view in Subviews) {
-					if (view.Frame.IntersectsWith (region)) {
+					if (view.Frame.IntersectsWith (bounds)) {
 						view.SetNeedsLayout ();
 						view.SetNeedsDisplay (view.Bounds);
 					}
@@ -280,7 +281,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// This method is invoked by Application.Begin as part of the Application.Run after
+		/// Invoked by <see cref="Application.Begin"/> as part of the <see cref="Application.Run(Toplevel, bool)"/> after
 		/// the views have been laid out, and before the views are drawn for the first time.
 		/// </summary>
 		public virtual void WillPresent ()

+ 172 - 129
Terminal.Gui/Core/View.cs

@@ -20,7 +20,7 @@ namespace Terminal.Gui {
 
 	/// <summary>
 	/// Determines the LayoutStyle for a view, if Absolute, during LayoutSubviews, the
-	/// value from the Frame will be used, if the value is Computer, then the Frame
+	/// value from the Frame will be used, if the value is Computed, then the Frame
 	/// will be updated from the X, Y Pos objects and the Width and Height Dim objects.
 	/// </summary>
 	public enum LayoutStyle {
@@ -41,68 +41,73 @@ namespace Terminal.Gui {
 	/// </summary>
 	/// <remarks>
 	/// <para>
-	///    The View defines the base functionality for user interface elements in Terminal/gui.cs.  Views
+	///    The View defines the base functionality for user interface elements in Terminal.Gui.  Views
 	///    can contain one or more subviews, can respond to user input and render themselves on the screen.
 	/// </para>
 	/// <para>
-	///    Views can either be created with an absolute position, by calling the constructor that takes a
-	///    Rect parameter to specify the absolute position and size (the Frame of the View) or by setting the
-	///    X, Y, Width and Height properties on the view.    Both approaches use coordinates that are relative
-	///    to the container they are being added to.
+	///    Views supports two layout styles: Absolute or Computed. The choice as to which layout style is used by the View 
+	///    is determined when the View is initizlied. To create a View using Absolute layout, call a constructor that takes a
+	///    Rect parameter to specify the absolute position and size (the <c>View.<see cref="Frame "/></c>)/. To create a View 
+	///    using Computed layout use a constructor that does not take a Rect parametr and set the X, Y, Width and Height 
+	///    properties on the view. Both approaches use coordinates that are relative to the container they are being added to. 
 	/// </para>
 	/// <para>
-	///    When you do not specify a Rect frame you can use the more flexible
-	///    Dim and Pos objects that can dynamically update the position of a view.
+	///    To switch between Absolute and Computed layout, use the <see cref="LayoutStyle"/> property. 
+	/// </para>
+	/// <para>
+	///    Computed layout is more flexible and supports dynamic console apps where controls adjust layout
+	///    as the terminal resizes or other Views change size or position. The X, Y, Width and Height 
+	///    properties are Dim and Pos objects that dynamically update the position of a view.
 	///    The X and Y properties are of type <see cref="Pos"/>
 	///    and you can use either absolute positions, percentages or anchor
 	///    points.   The Width and Height properties are of type
 	///    <see cref="Dim"/> and can use absolute position,
 	///    percentages and anchors.  These are useful as they will take
-	///    care of repositioning your views if your view's frames are resized
-	///    or if the terminal size changes.
+	///    care of repositioning views when view's frames are resized or
+	///    if the terminal size changes.
 	/// </para>
 	/// <para>
-	///    When you specify the Rect parameter to a view, you are setting the LayoutStyle to Absolute, and the
-	///    view will always stay in the position that you placed it.   To change the position change the
-	///    Frame property to the new position.
+	///    Absolute layout requires specifying coordiantes and sizes of Views explicitly, and the
+	///    View will typcialy stay in a fixed position and size. To change the position and size use the
+	///    <see cref="Frame"/> property.
 	/// </para>
 	/// <para>
-	///    Subviews can be added to a View by calling the Add method.   The container of a view is the
-	///    Superview.
+	///    Subviews (child views) can be added to a View by calling the <see cref="Add(View)"/> method.   
+	///    The container of a View can be accessed with the <see cref="SuperView"/> property.
 	/// </para>
 	/// <para>
-	///    Developers can call the SetNeedsDisplay method on the view to flag a region or the entire view
+	///    The <see cref="SetNeedsDisplay(Rect)"/> method flags a region or the entire view
 	///    as requiring to be redrawn.
 	/// </para>
 	/// <para>
-	///    Views have a ColorScheme property that defines the default colors that subviews
+	///    Views have a <see cref="ColorScheme"/> property that defines the default colors that subviews
 	///    should use for rendering.   This ensures that the views fit in the context where
 	///    they are being used, and allows for themes to be plugged in.   For example, the
 	///    default colors for windows and toplevels uses a blue background, while it uses
 	///    a white background for dialog boxes and a red background for errors.
 	/// </para>
 	/// <para>
-	///    If a ColorScheme is not set on a view, the result of the ColorScheme is the
-	///    value of the SuperView and the value might only be valid once a view has been
-	///    added to a SuperView, so your subclasses should not rely on ColorScheme being
-	///    set at construction time.
+	///    Subclasses should not rely on <see cref="ColorScheme"/> being
+	///    set at construction time. If a <see cref="ColorScheme"/> is not set on a view, the view will inherit the
+	///    value from its <see cref="SuperView"/> and the value might only be valid once a view has been
+	///    added to a SuperView. 
 	/// </para>
 	/// <para>
-	///    Using ColorSchemes has the advantage that your application will work both
+	///    By using  <see cref="ColorScheme"/> applications will work both
 	///    in color as well as black and white displays.
 	/// </para>
 	/// <para>
-	///    Views that are focusable should implement the PositionCursor to make sure that
-	///    the cursor is placed in a location that makes sense.   Unix terminals do not have
+	///    Views that are focusable should implement the <see cref="PositionCursor"/> to make sure that
+	///    the cursor is placed in a location that makes sense.  Unix terminals do not have
 	///    a way of hiding the cursor, so it can be distracting to have the cursor left at
 	///    the last focused view.   So views should make sure that they place the cursor
 	///    in a visually sensible place.
 	/// </para>
 	/// <para>
-	///    The metnod LayoutSubviews is invoked when the size or layout of a view has
+	///    The <see cref="LayoutSubviews"/> method is invoked when the size or layout of a view has
 	///    changed.   The default processing system will keep the size and dimensions
-	///    for views that use the LayoutKind.Absolute, and will recompute the
-	///    frames for the vies that use LayoutKind.Computed.
+	///    for views that use the <see cref="LayoutStyle.Absolute"/>, and will recompute the
+	///    frames for the vies that use <see cref="LayoutStyle.Computed"/>.
 	/// </para>
 	/// </remarks>
 	public class View : Responder, IEnumerable {
@@ -111,17 +116,18 @@ namespace Terminal.Gui {
 			Backward
 		}
 
+		// container == SuperView
 		View container = null;
 		View focused = null;
 		Direction focusDirection;
 
 		/// <summary>
-		/// Event fired when the view get focus.
+		/// Event fired when the view gets focus.
 		/// </summary>
 		public event EventHandler<FocusEventArgs> Enter;
 
 		/// <summary>
-		/// Event fired when the view lost focus.
+		/// Event fired when the view looses focus.
 		/// </summary>
 		public event EventHandler<FocusEventArgs> Leave;
 
@@ -131,7 +137,7 @@ namespace Terminal.Gui {
 		public event EventHandler<MouseEventEventArgs> MouseEnter;
 
 		/// <summary>
-		/// Event fired when the view loses mouse event for the last time.
+		/// Event fired when the view receives a mouse event for the last time.
 		/// </summary>
 		public event EventHandler<MouseEventEventArgs> MouseLeave;
 
@@ -173,13 +179,14 @@ namespace Terminal.Gui {
 
 		internal Rect NeedDisplay { get; private set; } = Rect.Empty;
 
-		// The frame for the object
+		// The frame for the object. Superview relative.
 		Rect frame;
 
 		/// <summary>
 		/// Gets or sets an identifier for the view;
 		/// </summary>
 		/// <value>The identifier.</value>
+		/// <remarks>The id should be unique across all Views that share a SuperView.</remarks>
 		public ustring Id { get; set; } = "";
 
 		/// <summary>
@@ -192,7 +199,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Gets or sets a value indicating whether this <see cref="View"/> want mouse position reports.
+		/// Gets or sets a value indicating whether this <see cref="View"/> wants mouse position reports.
 		/// </summary>
 		/// <value><c>true</c> if want mouse position reports; otherwise, <c>false</c>.</value>
 		public virtual bool WantMousePositionReports { get; set; } = false;
@@ -201,13 +208,19 @@ namespace Terminal.Gui {
 		/// Gets or sets a value indicating whether this <see cref="View"/> want continuous button pressed event.
 		/// </summary>
 		public virtual bool WantContinuousButtonPressed { get; set; } = false;
+
 		/// <summary>
-		/// Gets or sets the frame for the view.
+		/// Gets or sets the frame for the view. The frame is relative to the <see cref="SuperView"/>.
 		/// </summary>
 		/// <value>The frame.</value>
 		/// <remarks>
+		/// <para>
+		///    Change the Frame when using the <see cref="LayoutStyle.Absolute"/> layout style to move or resize views. 
+		/// </para>
+		/// <para>
 		///    Altering the Frame of a view will trigger the redrawing of the
-		///    view as well as the redrawing of the affected regions in the superview.
+		///    view as well as the redrawing of the affected regions in the <see cref="SuperView"/>.
+		/// </para>
 		/// </remarks>
 		public virtual Rect Frame {
 			get => frame;
@@ -236,9 +249,9 @@ namespace Terminal.Gui {
 		LayoutStyle layoutStyle;
 
 		/// <summary>
-		/// Controls how the view's Frame is computed during the LayoutSubviews method, if Absolute, then
-		/// LayoutSubviews does not change the Frame properties, otherwise the Frame is updated from the
-		/// values in X, Y, Width and Height properties.
+		/// Controls how the View's <see cref="Frame"/> is computed during the LayoutSubviews method, if the style is set to <see cref="LayoutStyle.Absolute"/>, 
+		/// LayoutSubviews does not change the <see cref="Frame"/>. If the style is <see cref="LayoutStyle.Computed"/> the <see cref="Frame"/> is updated using
+		/// the <see cref="X"/>, <see cref="Y"/>, <see cref="Width"/>, and <see cref="Height"/> properties.
 		/// </summary>
 		/// <value>The layout style.</value>
 		public LayoutStyle LayoutStyle {
@@ -250,7 +263,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// The bounds represent the View-relative rectangle used for this view.   Updates to the Bounds update the Frame, and has the same side effects as updating the frame.
+		/// The bounds represent the View-relative rectangle used for this view. Updates to the Bounds update the <see cref="Frame"/>, and has the same side effects as updating the <see cref="Frame"/>.
 		/// </summary>
 		/// <value>The bounds.</value>
 		public Rect Bounds {
@@ -262,10 +275,12 @@ namespace Terminal.Gui {
 
 		Pos x, y;
 		/// <summary>
-		/// Gets or sets the X position for the view (the column).  This is only used when the LayoutStyle is Computed, if the
-		/// LayoutStyle is set to Absolute, this value is ignored.
+		/// Gets or sets the X position for the view (the column). Only used whe <see cref="LayoutStyle"/> is <see cref="LayoutStyle.Computed"/>.
 		/// </summary>
 		/// <value>The X Position.</value>
+		/// <remarks>
+		/// If <see cref="LayoutStyle"/> is <see cref="LayoutStyle.Absolute"/> changing this property has no effect and its value is indeterminate. 
+		/// </remarks>
 		public Pos X {
 			get => x;
 			set {
@@ -275,10 +290,12 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Gets or sets the Y position for the view (line).  This is only used when the LayoutStyle is Computed, if the
-		/// LayoutStyle is set to Absolute, this value is ignored.
+		/// Gets or sets the Y position for the view (the row). Only used whe <see cref="LayoutStyle"/> is <see cref="LayoutStyle.Computed"/>.
 		/// </summary>
 		/// <value>The y position (line).</value>
+		/// <remarks>
+		/// If <see cref="LayoutStyle"/> is <see cref="LayoutStyle.Absolute"/> changing this property has no effect and its value is indeterminate. 
+		/// </remarks>
 		public Pos Y {
 			get => y;
 			set {
@@ -290,10 +307,12 @@ namespace Terminal.Gui {
 		Dim width, height;
 
 		/// <summary>
-		/// Gets or sets the width for the view. This is only used when the LayoutStyle is Computed, if the
-		/// LayoutStyle is set to Absolute, this value is ignored.
+		/// Gets or sets the width of the view. Only used whe <see cref="LayoutStyle"/> is <see cref="LayoutStyle.Computed"/>.
 		/// </summary>
 		/// <value>The width.</value>
+		/// <remarks>
+		/// If <see cref="LayoutStyle"/> is <see cref="LayoutStyle.Absolute"/> changing this property has no effect and its value is indeterminate. 
+		/// </remarks>
 		public Dim Width {
 			get => width;
 			set {
@@ -303,10 +322,10 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Gets or sets the height for the view. This is only used when the LayoutStyle is Computed, if the
-		/// LayoutStyle is set to Absolute, this value is ignored.
+		/// Gets or sets the height of the view. Only used whe <see cref="LayoutStyle"/> is <see cref="LayoutStyle.Computed"/>.
 		/// </summary>
 		/// <value>The height.</value>
+		/// If <see cref="LayoutStyle"/> is <see cref="LayoutStyle.Absolute"/> changing this property has no effect and its value is indeterminate. 
 		public Dim Height {
 			get => height;
 			set {
@@ -322,11 +341,14 @@ namespace Terminal.Gui {
 		public View SuperView => container;
 
 		/// <summary>
-		/// Initializes a new instance of the <see cref="View"/> class with the absolute
-		/// dimensions specified in the frame.   If you want to have Views that can be positioned with
-		/// Pos and Dim properties on X, Y, Width and Height, use the empty constructor.
+		/// Initializes a new instance of a <see cref="LayoutStyle.Absolute"/> <see cref="View"/> class with the absolute
+		/// dimensions specified in the <c>frame</c> parameter. 
 		/// </summary>
 		/// <param name="frame">The region covered by this view.</param>
+		/// <remarks>
+		/// This constructor intitalize a View with a <see cref="LayoutStyle"/> of <see cref="LayoutStyle.Absolute"/>. Use <see cref="View()"/> to 
+		/// initialize a View with  <see cref="LayoutStyle"/> of <see cref="LayoutStyle.Computed"/> 
+		/// </remarks>
 		public View (Rect frame)
 		{
 			this.Frame = frame;
@@ -335,10 +357,15 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Initializes a new instance of the <see cref="View"/> class and sets the
-		/// view up for Computed layout, which will use the values in X, Y, Width and Height to
-		/// compute the View's Frame.
+		/// Initializes a new instance of <see cref="LayoutStyle.Computed"/> <see cref="View"/> class.
 		/// </summary>
+		/// <remarks>
+		///   Use <see cref="X"/>, <see cref="Y"/>, <see cref="Width"/>, and <see cref="Height"/> properties to dynamically control the size and location of the view.
+		/// </remarks>
+		/// <remarks>
+		///   This constructor intitalize a View with a <see cref="LayoutStyle"/> of <see cref="LayoutStyle.Computed"/>. 
+		///   Use <see cref="X"/>, <see cref="Y"/>, <see cref="Width"/>, and <see cref="Height"/> properties to dynamically control the size and location of the view.
+		/// </remarks>
 		public View ()
 		{
 			CanFocus = false;
@@ -346,8 +373,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Invoke to flag that this view needs to be redisplayed, by any code
-		/// that alters the state of the view.
+		/// Sets a flag indicating this view needs to be redisplayed because its state has changed.
 		/// </summary>
 		public void SetNeedsDisplay ()
 		{
@@ -367,9 +393,9 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Flags the specified rectangle region on this view as needing to be repainted.
+		/// Flags the view-relative region on this View as needing to be repainted.
 		/// </summary>
-		/// <param name="region">The region that must be flagged for repaint.</param>
+		/// <param name="region">The view-relative region that must be flagged for repaint.</param>
 		public void SetNeedsDisplay (Rect region)
 		{
 			if (NeedDisplay == null || NeedDisplay.IsEmpty)
@@ -397,7 +423,7 @@ namespace Terminal.Gui {
 		internal bool childNeedsDisplay;
 
 		/// <summary>
-		/// Flags this view for requiring the children views to be repainted.
+		/// Indicates that any child views (in the <see cref="Subviews"/> list) need to be repainted.
 		/// </summary>
 		public void ChildNeedsDisplay ()
 		{
@@ -407,9 +433,10 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		///   Adds a subview to this view.
+		///   Adds a subview (child) to this view.
 		/// </summary>
 		/// <remarks>
+		/// The Views that have been added to this view can be retrieved via the <see cref="Subviews"/> property. See also <seealso cref="Remove(View)"/> <seealso cref="RemoveAll"/> 
 		/// </remarks>
 		public virtual void Add (View view)
 		{
@@ -426,9 +453,12 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Adds the specified views to the view.
+		/// Adds the specified views (children) to the view.
 		/// </summary>
 		/// <param name="views">Array of one or more views (can be optional parameter).</param>
+		/// <remarks>
+		/// The Views that have been added to this view can be retrieved via the <see cref="Subviews"/> property. See also <seealso cref="Remove(View)"/> <seealso cref="RemoveAll"/> 
+		/// </remarks>
 		public void Add (params View [] views)
 		{
 			if (views == null)
@@ -438,10 +468,8 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		///   Removes all the widgets from this container.
+		///   Removes all subviews (children) added via <see cref="Add(View)"/> or <see cref="Add(View[])"/> from this View.
 		/// </summary>
-		/// <remarks>
-		/// </remarks>
 		public virtual void RemoveAll ()
 		{
 			if (subviews == null)
@@ -453,7 +481,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		///   Removes a widget from this container.
+		///   Removes a subview added via <see cref="Add(View)"/> or <see cref="Add(View[])"/> from this View.
 		/// </summary>
 		/// <remarks>
 		/// </remarks>
@@ -573,27 +601,30 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		///   Clears the specified rectangular region with the current color
+		///   Clears the specified region with the current color. 
 		/// </summary>
-		public void Clear (Rect r)
+		/// <remarks>
+		/// </remarks>
+		/// <param name="regionScreen">The screen-relative region to clear.</param>
+		public void Clear (Rect regionScreen)
 		{
-			var h = r.Height;
-			var w = r.Width;
-			for (int line = r.Y; line < r.Y + h; line++) {
-				Driver.Move (r.X, line);
+			var h = regionScreen.Height;
+			var w = regionScreen.Width;
+			for (int line = regionScreen.Y; line < regionScreen.Y + h; line++) {
+				Driver.Move (regionScreen.X, line);
 				for (int col = 0; col < w; col++)
 					Driver.AddRune (' ');
 			}
 		}
 
 		/// <summary>
-		/// Converts the (col,row) position from the view into a screen (col,row).  The values are clamped to (0..ScreenDim-1)
+		/// Converts a view-relative (col,row) position to a screen-relative position (col,row). The values are optionally clamped to the screen dimensions.
 		/// </summary>
-		/// <param name="col">View-based column.</param>
-		/// <param name="row">View-based row.</param>
-		/// <param name="rcol">Absolute column, display relative.</param>
-		/// <param name="rrow">Absolute row, display relative.</param>
-		/// <param name="clipped">Whether to clip the result of the ViewToScreen method, if set to true, the rcol, rrow values are clamped to the screen dimensions.</param>
+		/// <param name="col">View-relative column.</param>
+		/// <param name="row">View-relative row.</param>
+		/// <param name="rcol">Absolute column; screen-relative.</param>
+		/// <param name="rrow">Absolute row; screen-relative.</param>
+		/// <param name="clipped">Whether to clip the result of the ViewToScreen method, if set to <c>true</c>, the rcol, rrow values are clamped to the screen (terminal) dimensions (0..TerminalDim-1).</param>
 		internal void ViewToScreen (int col, int row, out int rcol, out int rrow, bool clipped = true)
 		{
 			// Computes the real row, col relative to the screen.
@@ -614,7 +645,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Converts a point from screen coordinates into the view coordinate space.
+		/// Converts a point from screen-relative coordinates to view-relative coordinates.
 		/// </summary>
 		/// <returns>The mapped point.</returns>
 		/// <param name="x">X screen-coordinate point.</param>
@@ -629,66 +660,72 @@ namespace Terminal.Gui {
 			}
 		}
 
-		// Converts a rectangle in view coordinates to screen coordinates.
-		internal Rect RectToScreen (Rect rect)
+		/// <summary>
+		/// Converts a region in view-relative coordinates to screen-relative coordinates.
+		/// </summary>
+		internal Rect ViewToScreen (Rect region)
 		{
-			ViewToScreen (rect.X, rect.Y, out var x, out var y, clipped: false);
-			return new Rect (x, y, rect.Width, rect.Height);
+			ViewToScreen (region.X, region.Y, out var x, out var y, clipped: false);
+			return new Rect (x, y, region.Width, region.Height);
 		}
 
 		// Clips a rectangle in screen coordinates to the dimensions currently available on the screen
-		internal Rect ScreenClip (Rect rect)
+		internal Rect ScreenClip (Rect regionScreen)
 		{
-			var x = rect.X < 0 ? 0 : rect.X;
-			var y = rect.Y < 0 ? 0 : rect.Y;
-			var w = rect.X + rect.Width >= Driver.Cols ? Driver.Cols - rect.X : rect.Width;
-			var h = rect.Y + rect.Height >= Driver.Rows ? Driver.Rows - rect.Y : rect.Height;
+			var x = regionScreen.X < 0 ? 0 : regionScreen.X;
+			var y = regionScreen.Y < 0 ? 0 : regionScreen.Y;
+			var w = regionScreen.X + regionScreen.Width >= Driver.Cols ? Driver.Cols - regionScreen.X : regionScreen.Width;
+			var h = regionScreen.Y + regionScreen.Height >= Driver.Rows ? Driver.Rows - regionScreen.Y : regionScreen.Height;
 
 			return new Rect (x, y, w, h);
 		}
 
 		/// <summary>
-		/// Sets the Console driver's clip region to the current View's Bounds.
+		/// Sets the <see cref="ConsoleDriver"/>'s clip region to the current View's <see cref="Bounds"/>.
 		/// </summary>
-		/// <returns>The existing driver's Clip region, which can be then set by setting the Driver.Clip property.</returns>
+		/// <returns>The existing driver's clip region, which can be then re-eapplied by setting <c><see cref="Driver"/>.Clip</c> (<see cref="ConsoleDriver.Clip"/>).</returns>
+		/// <remarks>
+		/// <see cref="Bounds"/> is View-relative.
+		/// </remarks>
 		public Rect ClipToBounds ()
 		{
 			return SetClip (Bounds);
 		}
 
 		/// <summary>
-		/// Sets the clipping region to the specified region, the region is view-relative
+		/// Sets the clip region to the specified view-relative region.
 		/// </summary>
-		/// <returns>The previous clip region.</returns>
-		/// <param name="rect">Rectangle region to clip into, the region is view-relative.</param>
-		public Rect SetClip (Rect rect)
+		/// <returns>The previous screen-relative clip region.</returns>
+		/// <param name="region">View-relative clip region.</param>
+		public Rect SetClip (Rect region)
 		{
-			var bscreen = RectToScreen (rect);
 			var previous = Driver.Clip;
-			Driver.Clip = ScreenClip (RectToScreen (Bounds)); 
+			Driver.Clip = Rect.Intersect (previous, ViewToScreen (region));
 			return previous;
 		}
 
 		/// <summary>
 		/// Draws a frame in the current view, clipped by the boundary of this view
 		/// </summary>
-		/// <param name="rect">Rectangular region for the frame to be drawn.</param>
-		/// <param name="padding">The padding to add to the drawn frame.</param>
+		/// <param name="region">View-relative region for the frame to be drawn.</param>
+		/// <param name="padding">The padding to add around the outside of the drawn frame.</param>
 		/// <param name="fill">If set to <c>true</c> it fill will the contents.</param>
-		public void DrawFrame (Rect rect, int padding = 0, bool fill = false)
+		public void DrawFrame (Rect region, int padding = 0, bool fill = false)
 		{
-			var scrRect = RectToScreen (rect);
+			var scrRect = ViewToScreen (region);
 			var savedClip = ClipToBounds ();
 			Driver.DrawFrame (scrRect, padding, fill);
 			Driver.Clip = savedClip;
 		}
 
 		/// <summary>
-		/// Utility function to draw strings that contain a hotkey
+		/// Utility function to draw strings that contain a hotkey.
 		/// </summary>
 		/// <param name="text">String to display, the underscoore before a letter flags the next letter as the hotkey.</param>
 		/// <param name="hotColor">Hot color.</param>
 		/// <param name="normalColor">Normal color.</param>
+		/// <remarks>
+		/// The hotkey is any character following an underscore ('_') character.</remarks>
 		public void DrawHotString (ustring text, Attribute hotColor, Attribute normalColor)
 		{
 			Driver.SetAttribute (normalColor);
@@ -703,7 +740,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Utility function to draw strings that contains a hotkey using a colorscheme and the "focused" state.
+		/// Utility function to draw strings that contains a hotkey using a <see cref="ColorScheme"/> and the "focused" state.
 		/// </summary>
 		/// <param name="text">String to display, the underscoore before a letter flags the next letter as the hotkey.</param>
 		/// <param name="focused">If set to <c>true</c> this uses the focused colors from the color scheme, otherwise the regular ones.</param>
@@ -720,8 +757,8 @@ namespace Terminal.Gui {
 		/// This moves the cursor to the specified column and row in the view.
 		/// </summary>
 		/// <returns>The move.</returns>
-		/// <param name="col">Col.</param>
-		/// <param name="row">Row.</param>
+		/// <param name="col">Col (view-relative).</param>
+		/// <param name="row">Row (view-relative).</param>
 		public void Move (int col, int row)
 		{
 			ViewToScreen (col, row, out var rcol, out var rrow);
@@ -731,6 +768,11 @@ namespace Terminal.Gui {
 		/// <summary>
 		///   Positions the cursor in the right position based on the currently focused view in the chain.
 		/// </summary>
+		///    Views that are focusable should override <see cref="PositionCursor"/> to ensure
+		///    the cursor is placed in a location that makes sense. Unix terminals do not have
+		///    a way of hiding the cursor, so it can be distracting to have the cursor left at
+		///    the last focused view. Views should make sure that they place the cursor
+		///    in a visually sensible place.
 		public virtual void PositionCursor ()
 		{
 			if (focused != null)
@@ -763,7 +805,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Specifies the event arguments for <see cref="SetFocus(View)"/>
+		/// Defines the event arguments for <see cref="SetFocus(View)"/>
 		/// </summary>
 		public class FocusEventArgs : EventArgs {
 			/// <summary>
@@ -825,7 +867,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// The color scheme for this view, if it is not defined, it returns the parent's
+		/// The color scheme for this view, if it is not defined, it returns the <see cref="SuperView"/>'s
 		/// color scheme.
 		/// </summary>
 		public ColorScheme ColorScheme {
@@ -842,10 +884,10 @@ namespace Terminal.Gui {
 		ColorScheme colorScheme;
 
 		/// <summary>
-		/// Displays the specified character in the specified column and row.
+		/// Displays the specified character in the specified column and row of the View.
 		/// </summary>
-		/// <param name="col">Col.</param>
-		/// <param name="row">Row.</param>
+		/// <param name="col">Column (view-relative).</param>
+		/// <param name="row">Row (view-relative).</param>
 		/// <param name="ch">Ch.</param>
 		public void AddRune (int col, int row, Rune ch)
 		{
@@ -858,7 +900,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Removes the SetNeedsDisplay and the ChildNeedsDisplay setting on this view.
+		/// Removes the <see cref="SetNeedsDisplay()"/> and the <see cref="ChildNeedsDisplay"/> setting on this view.
 		/// </summary>
 		protected void ClearNeedsDisplay ()
 		{
@@ -867,38 +909,37 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Performs a redraw of this view and its subviews, only redraws the views that have been flagged for a re-display.
+		/// Redraws this view and its subviews; only redraws the views that have been flagged for a re-display.
 		/// </summary>
-		/// <param name="region">The region to redraw, this is relative to the view itself.</param>
+		/// <param name="bounds">The view-relative region to redraw.</param>
 		/// <remarks>
 		/// <para>
 		///    Views should set the color that they want to use on entry, as otherwise this will inherit
 		///    the last color that was set globaly on the driver.
 		/// </para>
+		/// <para>
+		///    Overrides of <see cref="Redraw"/> must ensure they do not set <c>Driver.Clip</c> to a clip region
+		///    larger than the <c>region</c> parameter.
+		/// </para>
 		/// </remarks>
-		public virtual void Redraw (Rect region)
+		public virtual void Redraw (Rect bounds)
 		{
 			var clipRect = new Rect (Point.Empty, frame.Size);
 
 			if (subviews != null) {
 				foreach (var view in subviews) {
 					if (view.NeedDisplay != null && (!view.NeedDisplay.IsEmpty || view.childNeedsDisplay)) {
-						if (view.Frame.IntersectsWith (clipRect) && view.Frame.IntersectsWith (region)) {
+						if (view.Frame.IntersectsWith (clipRect) && view.Frame.IntersectsWith (bounds)) {
 
 							// FIXED: optimize this by computing the intersection of region and view.Bounds
 							if (view.layoutNeeded)
 								view.LayoutSubviews ();
 							Application.CurrentView = view;
 
-							// Ensure we don't make the Driver's clip rect any bigger
-							if (SuperView != null && SuperView.Bounds.Contains (RectToScreen (Frame))) {
-							//if (Driver.Clip.IsEmpty || Driver.Clip.Contains(RectToScreen (view.Frame))) {
-								var savedClip = view.ClipToBounds ();
-								view.Redraw (view.Bounds);
-								Driver.Clip = savedClip;
-							} else {
-								view.Redraw (view.Bounds);
-							}
+							// Clip the sub-view
+							var savedClip = ClipToBounds ();
+							view.Redraw (view.Bounds);
+							Driver.Clip = savedClip;
 						}
 						view.NeedDisplay = Rect.Empty;
 						view.childNeedsDisplay = false;
@@ -909,7 +950,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Focuses the specified sub-view.
+		/// Causes the specified subview to have focus.
 		/// </summary>
 		/// <param name="view">View.</param>
 		public void SetFocus (View view)
@@ -942,7 +983,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Specifies the event arguments for <see cref="KeyEvent"/>
+		/// Defines the event arguments for <see cref="KeyEvent"/>
 		/// </summary>
 		public class KeyEventEventArgs : EventArgs {
 			/// <summary>
@@ -1188,10 +1229,13 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Computes the RelativeLayout for the view, given the frame for its container.
+		/// Sets the View's <see cref="Frame"/> to the relative coordinates if its container, given the <see cref="Frame"/> for its container.
 		/// </summary>
-		/// <param name="hostFrame">The Frame for the host.</param>
-		internal void RelativeLayout (Rect hostFrame)
+		/// <param name="hostFrame">The screen-relative frame for the host.</param>
+		/// <remarks>
+		/// Reminder: <see cref="Frame"/> is superview-relative; <see cref="Bounds"/> is view-relative.
+		/// </remarks>
+		internal void SetRelativeLayout (Rect hostFrame)
 		{
 			int w, h, _x, _y;
 
@@ -1229,7 +1273,6 @@ namespace Terminal.Gui {
 					h = height.Anchor (hostFrame.Height - _y);
 			}
 			Frame = new Rect (_x, _y, w, h);
-			// layoutNeeded = false;
 		}
 
 		// https://en.wikipedia.org/wiki/Topological_sorting
@@ -1275,7 +1318,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// This virtual method is invoked when a view starts executing or
+		/// Invoked when a view starts executing or
 		/// when the dimensions of the view have changed, for example in
 		/// response to the container view or terminal resizing.
 		/// </summary>
@@ -1308,7 +1351,7 @@ namespace Terminal.Gui {
 
 			foreach (var v in ordered) {
 				if (v.LayoutStyle == LayoutStyle.Computed)
-					v.RelativeLayout (Frame);
+					v.SetRelativeLayout (Frame);
 
 				v.LayoutSubviews ();
 				v.layoutNeeded = false;
@@ -1316,7 +1359,7 @@ namespace Terminal.Gui {
 			}
 
 			if (SuperView == Application.Top && layoutNeeded && ordered.Count == 0 && LayoutStyle == LayoutStyle.Computed) {
-				RelativeLayout (Frame);
+				SetRelativeLayout (Frame);
 			}
 
 			layoutNeeded = false;

+ 32 - 32
Terminal.Gui/Core/Window.cs

@@ -7,7 +7,7 @@ using NStack;
 
 namespace Terminal.Gui {
 	/// <summary>
-	/// A <see cref="Toplevel"/> <see cref="View"/> that draws a frame around its region and has a "ContentView" subview where the contents are added.
+	/// A <see cref="Toplevel"/> <see cref="View"/> that draws a frame around its region and has a "Content" subview where the contents are added.
 	/// </summary>
 	public class Window : Toplevel, IEnumerable {
 		View contentView;
@@ -29,7 +29,7 @@ namespace Terminal.Gui {
 			public ContentView (Rect frame) : base (frame) { }
 			public ContentView () : base () { }
 #if false
-			public override void Redraw (Rect region)
+			public override void Redraw (Rect bounds)
 			{
 				Driver.SetAttribute (ColorScheme.Focus);
 
@@ -50,6 +50,10 @@ namespace Terminal.Gui {
 		/// </summary>
 		/// <param name="frame">Frame.</param>
 		/// <param name="title">Title.</param>
+		/// <remarks>
+		/// This constructor intitalizes a Window with a <see cref="LayoutStyle"/> of <see cref="LayoutStyle.Absolute"/>. Use constructors
+		/// that do not take <c>Rect</c> parameters to initialize a Window with  <see cref="LayoutStyle"/> of <see cref="LayoutStyle.Computed"/> 
+		/// </remarks>
 		public Window (Rect frame, ustring title = null) : this (frame, title, padding: 0)
 		{
 		}
@@ -58,19 +62,26 @@ namespace Terminal.Gui {
 		/// Initializes a new instance of the <see cref="Window"/> class with an optional title.
 		/// </summary>
 		/// <param name="title">Title.</param>
+		/// <remarks>
+		///   This constructor intitalize a View with a <see cref="LayoutStyle"/> of <see cref="LayoutStyle.Computed"/>. 
+		///   Use <see cref="View.X"/>, <see cref="View.Y"/>, <see cref="View.Width"/>, and <see cref="View.Height"/> properties to dynamically control the size and location of the view.
+		/// </remarks>
 		public Window (ustring title = null) : this (title, padding: 0)
 		{
 		}
 
 		int padding;
 		/// <summary>
-		/// Initializes a new instance of the <see cref="Window"/> with
-		/// the specified frame for its location, with the specified border
-		/// an optional title.
+		/// Initializes a new instance of the <see cref="Window"/> with the specified frame for its location, with the specified border,
+		/// and an optional title.
 		/// </summary>
 		/// <param name="frame">Frame.</param>
 		/// <param name="padding">Number of characters to use for padding of the drawn frame.</param>
 		/// <param name="title">Title.</param>
+		/// <remarks>
+		/// This constructor intitalizes a Window with a <see cref="LayoutStyle"/> of <see cref="LayoutStyle.Absolute"/>. Use constructors
+		/// that do not take <c>Rect</c> parameters to initialize a Window with  <see cref="LayoutStyle"/> of <see cref="LayoutStyle.Computed"/> 
+		/// </remarks>
 		public Window (Rect frame, ustring title = null, int padding = 0) : base (frame)
 		{
 			this.Title = title;
@@ -82,12 +93,15 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Initializes a new instance of the <see cref="Window"/> with
-		/// the specified frame for its location, with the specified border
-		/// an optional title.
+		/// Initializes a new instance of the <see cref="Window"/> with the specified frame for its location, with the specified border,
+		/// and an optional title.
 		/// </summary>
 		/// <param name="padding">Number of characters to use for padding of the drawn frame.</param>
 		/// <param name="title">Title.</param>
+		/// <remarks>
+		///   This constructor intitalize a View with a <see cref="LayoutStyle"/> of <see cref="LayoutStyle.Computed"/>. 
+		///   Use <see cref="View.X"/>, <see cref="View.Y"/>, <see cref="View.Width"/>, and <see cref="View.Height"/> properties to dynamically control the size and location of the view.
+		/// </remarks>
 		public Window (ustring title = null, int padding = 0) : base ()
 		{
 			this.Title = title;
@@ -111,10 +125,7 @@ namespace Terminal.Gui {
 			return contentView.GetEnumerator ();
 		}
 
-		/// <summary>
-		/// Add the specified view to the <see cref="ContentView"/>.
-		/// </summary>
-		/// <param name="view">View to add to the window.</param>
+		/// <inheritdoc cref="Add(View)"/>
 		public override void Add (View view)
 		{
 			contentView.Add (view);
@@ -123,11 +134,7 @@ namespace Terminal.Gui {
 		}
 
 
-		/// <summary>
-		///   Removes a widget from this container.
-		/// </summary>
-		/// <remarks>
-		/// </remarks>
+		/// <inheritdoc cref="Remove(View)"/>
 		public override void Remove (View view)
 		{
 			if (view == null)
@@ -141,11 +148,7 @@ namespace Terminal.Gui {
 				this.CanFocus = false;
 		}
 
-		/// <summary>
-		///   Removes all widgets from this container.
-		/// </summary>
-		/// <remarks>
-		/// </remarks>
+		/// <inheritdoc cref="RemoveAll()"/>
 		public override void RemoveAll ()
 		{
 			contentView.RemoveAll ();
@@ -156,7 +159,7 @@ namespace Terminal.Gui {
 		{
 			//var padding = 0;
 			Application.CurrentView = this;
-			var scrRect = RectToScreen (new Rect (0, 0, Frame.Width, Frame.Height));
+			var scrRect = ViewToScreen (new Rect (0, 0, Frame.Width, Frame.Height));
 
 			// BUGBUG: Why do we draw the frame twice? This call is here to clear the content area, I think. Why not just clear that area?
 			if (NeedDisplay != null && !NeedDisplay.IsEmpty) {
@@ -164,13 +167,10 @@ namespace Terminal.Gui {
 				Driver.DrawFrame (scrRect, padding, true);
 			}
 
-			if (Driver.Clip.IsEmpty || Driver.Clip.Contains (contentView.RectToScreen (contentView.Frame))) { 
-				var savedClip = ClipToBounds ();
-				contentView.Redraw (contentView.Bounds);
-				Driver.Clip = savedClip;
-			} else {
-				contentView.Redraw (contentView.Bounds);
-			}
+			var savedClip = ClipToBounds ();
+			contentView.Redraw (contentView.Bounds);
+			Driver.Clip = savedClip;
+
 			ClearNeedsDisplay ();
 			Driver.SetAttribute (ColorScheme.Normal);
 			Driver.DrawFrame (scrRect, padding, false);
@@ -187,6 +187,7 @@ namespace Terminal.Gui {
 		//
 		internal static Point? dragPosition;
 		Point start;
+
 		///<inheritdoc cref="MouseEvent(Gui.MouseEvent)"/>
 		public override bool MouseEvent (MouseEvent mouseEvent)
 		{
@@ -200,7 +201,7 @@ namespace Terminal.Gui {
 				if (dragPosition.HasValue) {
 					if (SuperView == null) {
 						Application.Top.SetNeedsDisplay (Frame);
-						Application.Top.Redraw (Frame);
+						Application.Top.Redraw (Bounds);
 					} else {
 						SuperView.SetNeedsDisplay (Frame);
 					}
@@ -241,6 +242,5 @@ namespace Terminal.Gui {
 			//Demo.ml.Text = me.ToString ();
 			return false;
 		}
-
 	}
 }

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

@@ -152,7 +152,7 @@ namespace Terminal.Gui {
 		}
 
 		///<inheritdoc cref="Redraw(Rect)"/>
-		public override void Redraw (Rect region)
+		public override void Redraw (Rect bounds)
 		{
 			Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
 			Move (0, 0);

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

@@ -98,7 +98,7 @@ namespace Terminal.Gui {
 		}
 
 		///<inheritdoc cref="Redraw"/>
-		public override void Redraw (Rect region)
+		public override void Redraw (Rect bounds)
 		{
 			Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
 			Move (0, 0);

+ 5 - 8
Terminal.Gui/Views/FrameView.cs

@@ -136,20 +136,17 @@ namespace Terminal.Gui {
 		{
 			var padding = 0;
 			Application.CurrentView = this;
-			var scrRect = RectToScreen (new Rect (0, 0, Frame.Width, Frame.Height));
+			var scrRect = ViewToScreen (new Rect (0, 0, Frame.Width, Frame.Height));
 
 			if (NeedDisplay != null && !NeedDisplay.IsEmpty) {
 				Driver.SetAttribute (ColorScheme.Normal);
 				Driver.DrawFrame (scrRect, padding, true);
 			}
 
-			if (Driver.Clip.IsEmpty || Driver.Clip.Contains (contentView.RectToScreen (contentView.Frame))) {
-				var savedClip = ClipToBounds (); 
-				contentView.Redraw (contentView.Bounds);
-				Driver.Clip = savedClip;
-			} else {
-				contentView.Redraw (contentView.Bounds);
-			}
+			var savedClip = ClipToBounds ();
+			contentView.Redraw (contentView.Bounds);
+			Driver.Clip = savedClip;
+
 			ClearNeedsDisplay ();
 			Driver.SetAttribute (ColorScheme.Normal);
 			Driver.DrawFrame (scrRect, padding, false);

+ 2 - 2
Terminal.Gui/Views/HexView.cs

@@ -130,7 +130,7 @@ namespace Terminal.Gui {
 		}
 
 		///<inheritdoc cref="Redraw"/>
-		public override void Redraw (Rect region)
+		public override void Redraw (Rect bounds)
 		{
 			Attribute currentAttribute;
 			var current = ColorScheme.Focus;
@@ -149,7 +149,7 @@ namespace Terminal.Gui {
 
 			for (int line = 0; line < frame.Height; line++) {
 				var lineRect = new Rect (0, line, frame.Width, 1);
-				if (!region.Contains (lineRect))
+				if (!bounds.Contains (lineRect))
 					continue;
 				
 				Move (0, line);

+ 2 - 2
Terminal.Gui/Views/Label.cs

@@ -161,7 +161,7 @@ namespace Terminal.Gui {
 		}
 
 		///<inheritdoc cref="Redraw"/>
-		public override void Redraw (Rect region)
+		public override void Redraw (Rect bounds)
 		{
 			if (recalcPending)
 				Recalc ();
@@ -173,7 +173,7 @@ namespace Terminal.Gui {
 
 			Clear ();
 			for (int line = 0; line < lines.Count; line++) {
-				if (line < region.Top || line > region.Bottom)
+				if (line < bounds.Top || line > bounds.Bottom)
 					continue;
 				var str = lines [line];
 				int x;

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

@@ -272,7 +272,7 @@ namespace Terminal.Gui {
 		}
 
 		///<inheritdoc cref="Redraw(Rect)"/>
-		public override void Redraw (Rect region)
+		public override void Redraw (Rect bounds)
 		{
 			var current = ColorScheme.Focus;
 			Driver.SetAttribute (current);

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

@@ -276,10 +276,10 @@ namespace Terminal.Gui {
 			return ColorScheme.Normal;
 		}
 
-		public override void Redraw (Rect region)
+		public override void Redraw (Rect bounds)
 		{
 			Driver.SetAttribute (ColorScheme.Normal);
-			DrawFrame (region, padding: 0, fill: true);
+			DrawFrame (bounds, padding: 0, fill: true);
 
 			for (int i = 0; i < barItems.Children.Length; i++) {
 				var item = barItems.Children [i];
@@ -624,7 +624,7 @@ namespace Terminal.Gui {
 		}
 
 		///<inheritdoc cref="Redraw"/>
-		public override void Redraw (Rect region)
+		public override void Redraw (Rect bounds)
 		{
 			Move (0, 0);
 			Driver.SetAttribute (Colors.Menu.Normal);

+ 2 - 2
Terminal.Gui/Views/RadioGroup.cs

@@ -108,7 +108,7 @@ namespace Terminal.Gui {
 		}
 
 		///<inheritdoc cref="Redraw(Rect)"/>
-		public override void Redraw (Rect region)
+		public override void Redraw (Rect bounds)
 		{
 			for (int i = 0; i < radioLabels.Length; i++) {
 				Move (0, i);
@@ -116,7 +116,7 @@ namespace Terminal.Gui {
 				Driver.AddStr (i == selected ? "(o) " : "( ) ");
 				DrawHotString (radioLabels [i], HasFocus && i == cursor, ColorScheme);
 			}
-			base.Redraw (region);
+			base.Redraw (bounds);
 		}
 
 		///<inheritdoc cref="PositionCursor"/>

+ 2 - 6
Terminal.Gui/Views/ScrollView.cs

@@ -397,20 +397,16 @@ namespace Terminal.Gui {
 		/// This event is raised when the contents have scrolled
 		/// </summary>
 		//public event Action<ScrollView> Scrolled;
-
 		public override void Redraw(Rect region)
 		{
 			SetViewsNeedsDisplay ();
 			Driver.SetAttribute (ColorScheme.Normal);
 			Clear ();
 
-			if (Driver.Clip.IsEmpty || Driver.Clip.Contains (RectToScreen (Frame))) {
 			var savedClip = ClipToBounds ();
-			contentView.Redraw (contentView.Frame);
+			contentView.Redraw (contentView.Bounds);
 			Driver.Clip = savedClip;
-			} else {
-				contentView.Redraw (contentView.Bounds);
-			}
+
 			vertical.Redraw (vertical.Bounds);
 			horizontal.Redraw (vertical.Bounds);
 			Driver.SetAttribute (ColorScheme.Normal);

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

@@ -151,7 +151,7 @@ namespace Terminal.Gui {
 		}
 
 		///<inheritdoc cref="Redraw"/>
-		public override void Redraw (Rect region)
+		public override void Redraw (Rect bounds)
 		{
 			//if (Frame.Y != Driver.Rows - 1) {
 			//	Frame = new Rect (Frame.X, Driver.Rows - 1, Frame.Width, Frame.Height);

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

@@ -184,7 +184,7 @@ namespace Terminal.Gui {
 		}
 
 		///<inheritdoc cref="Redraw(Rect)"/>
-		public override void Redraw (Rect region)
+		public override void Redraw (Rect bounds)
 		{
 			ColorScheme color = Colors.Menu;
 			SetSelectedStartSelectedLength ();

+ 9 - 9
Terminal.Gui/Views/TextView.cs

@@ -525,31 +525,31 @@ namespace Terminal.Gui {
 		}
 
 		///<inheritdoc cref="Redraw(Rect)"/>
-		public override void Redraw (Rect region)
+		public override void Redraw (Rect bounds)
 		{
 			ColorNormal ();
 
-			int bottom = region.Bottom;
-			int right = region.Right;
-			for (int row = region.Top; row < bottom; row++) 
+			int bottom = bounds.Bottom;
+			int right = bounds.Right;
+			for (int row = bounds.Top; row < bottom; row++) 
 			{
 				int textLine = topRow + row;
 				if (textLine >= model.Count) 
 				{
 					ColorNormal ();
-					ClearRegion (region.Left, row, region.Right, row + 1);
+					ClearRegion (bounds.Left, row, bounds.Right, row + 1);
 					continue;
 				}
 				var line = model.GetLine (textLine);
 				int lineRuneCount = line.Count;
-				if (line.Count < region.Left)
+				if (line.Count < bounds.Left)
 				{
-					ClearRegion (region.Left, row, region.Right, row + 1);
+					ClearRegion (bounds.Left, row, bounds.Right, row + 1);
 					continue;
 				}
 
-				Move (region.Left, row);
-				for (int col = region.Left; col < right; col++) 
+				Move (bounds.Left, row);
+				for (int col = bounds.Left; col < right; col++) 
 				{
 					var lineCol = leftColumn + col;
 					var rune = lineCol >= lineRuneCount ? ' ' : line [lineCol];

+ 8 - 5
Terminal.Gui/Windows/FileDialog.cs

@@ -159,7 +159,7 @@ namespace Terminal.Gui {
 
 			Move (allowsMultipleSelection ? 3 : 2, line);
 			int byteLen = ustr.Length;
-			int used = 0;
+			int used = allowsMultipleSelection ? 2 : 1;
 			for (int i = 0; i < byteLen;) {
 				(var rune, var size) = Utf8.DecodeRune (ustr, i, i - byteLen);
 				var count = Rune.ColumnWidth (rune);
@@ -169,12 +169,12 @@ namespace Terminal.Gui {
 				used += count;
 				i += size;
 			}
-			for (; used < width; used++) {
+			for (; used < width - 1; used++) {
 				Driver.AddRune (' ');
 			}
 		}
 
-		public override void Redraw (Rect region)
+		public override void Redraw (Rect bounds)
 		{
 			var current = ColorScheme.Focus;
 			Driver.SetAttribute (current);
@@ -182,7 +182,7 @@ namespace Terminal.Gui {
 			var f = Frame;
 			var item = top;
 			bool focused = HasFocus;
-			var width = region.Width;
+			var width = bounds.Width;
 
 			for (int row = 0; row < f.Height; row++, item++) {
 				bool isSelected = item == selected;
@@ -463,7 +463,7 @@ namespace Terminal.Gui {
 			dirListView = new DirListView (this) {
 				X = 1,
 				Y = 3 + msgLines + 2,
-				Width = Dim.Fill () - 3,
+				Width = Dim.Fill () - 1,
 				Height = Dim.Fill () - 2,
 			};
 			DirectoryPath = Path.GetFullPath (Environment.CurrentDirectory);
@@ -488,6 +488,9 @@ namespace Terminal.Gui {
 			};
 			AddButton (this.prompt);
 
+			Width = Dim.Percent (80);
+			Height = Dim.Percent (80);
+
 			// On success, we will set this to false.
 			canceled = true;
 		}

+ 22 - 5
UICatalog/Scenarios/Buttons.cs

@@ -13,11 +13,8 @@ namespace UICatalog {
 				Y = 0,
 			};
 			Win.Add (editLabel);
-			var edit = new TextField ("") {
-				X = Pos.Right (editLabel) + 1,
-				Y = Pos.Top (editLabel),
-				Width = Dim.Fill (2),
-			};
+			// Add a TextField using Absolute layout. Use buttons to move/grow.
+			var edit = new TextField (31, 0, 25, "");
 			Win.Add (edit);
 
 			// This is the default button (IsDefault = true); if user presses ENTER in the TextField
@@ -100,6 +97,26 @@ namespace UICatalog {
 				},
 			});
 
+			// Demonstrates how changing the View.Frame property can move Views
+			y += 2;
+			var moveBtn = new Button (10, y, "Move TextField via Frame") {
+				ColorScheme = Colors.Error,
+			};
+			moveBtn.Clicked = () => {
+				edit.Frame = new Rect (edit.Frame.X + 5, edit.Frame.Y, edit.Frame.Width, edit.Frame.Height);
+			};
+			Win.Add (moveBtn);
+
+			// Demonstrates how changing the View.Frame property can NOT resize Views
+			y += 2;
+			var sizeBtn = new Button (10, y, "Grow TextField via Frame") {
+				ColorScheme = Colors.Error,
+			};
+			sizeBtn.Clicked = () => {
+				edit.Frame = new Rect (edit.Frame.X, edit.Frame.Y, edit.Frame.Width + 2, edit.Frame.Height);
+				Win.LayoutSubviews ();
+			};
+			Win.Add (sizeBtn);
 
 		}
 	}

+ 79 - 0
UICatalog/Scenarios/Clipping.cs

@@ -0,0 +1,79 @@
+using System;
+using Terminal.Gui;
+
+namespace UICatalog {
+	[ScenarioMetadata (Name: "Clipping", Description: "Used to test that things clip correctly")]
+	[ScenarioCategory ("Bug Repro")]
+
+	class Clipping : Scenario {
+
+		public override void Init (Toplevel top)
+		{
+			Application.Init ();
+
+			Top = top;
+			if (Top == null) {
+				Top = Application.Top;
+			}
+
+			Top.ColorScheme = Colors.Base;
+			//Win = new TopLevel($"CTRL-Q to Close - Scenario: {GetName ()}") {
+			//	X = 0,
+			//	Y = 0,
+			//	Width = Dim.Fill (),
+			//	Height = Dim.Fill ()
+			//};
+			//Top.Add (Win);
+		}
+
+		public override void Setup ()
+		{
+			//Win.X = 1;
+			//Win.Y = 2;
+			//Win.Width = Dim.Fill () - 4;
+			//Win.Height = Dim.Fill () - 2;
+			var label = new Label ("ScrollView (new Rect (5, 5, 100, 60)) with a 200, 100 ContentSize...") {
+				X = 0, Y = 0,
+				ColorScheme = Colors.Dialog
+			};
+			Top.Add (label);
+
+			var scrollView = new ScrollView (new Rect (3, 3, 50, 20));
+			scrollView.ColorScheme = Colors.Menu;
+			scrollView.ContentSize = new Size (100, 60);
+			//ContentOffset = new Point (0, 0),
+			scrollView.ShowVerticalScrollIndicator = true;
+			scrollView.ShowHorizontalScrollIndicator = true;
+
+			var embedded1 = new Window ("1") {
+				X = 3,
+				Y = 3,
+				Width = Dim.Fill (3),
+				Height = Dim.Fill (3),
+				ColorScheme = Colors.Dialog
+			};
+
+			var embedded2 = new Window ("2") {
+				X = 3,
+				Y = 3,
+				Width = Dim.Fill (3),
+				Height = Dim.Fill (3),
+				ColorScheme = Colors.Error
+			};
+			embedded1.Add (embedded2);
+
+			var embedded3 = new Window ("3") {
+				X = 3,
+				Y = 3,
+				Width = Dim.Fill (3),
+				Height = Dim.Fill (3),
+				ColorScheme = Colors.TopLevel
+			};
+			embedded2.Add (embedded3);
+
+			scrollView.Add (embedded1);
+					
+			Top.Add (scrollView);
+		}
+	}
+}

+ 119 - 7
UICatalog/Scenarios/Scrolling.cs

@@ -7,14 +7,89 @@ namespace UICatalog {
 	[ScenarioCategory ("Bug Repro")]
 
 	class Scrolling : Scenario {
+
+		//class Box10x : View, IScrollView {
+		class Box10x : View {
+			int w = 40;
+			int h = 50;
+
+			public bool WantCursorPosition { get; set; } = false;
+
+			public Box10x (int x, int y) : base (new Rect (x, y, 20, 10))
+			{
+			}
+
+			public Size GetContentSize ()
+			{
+				return new Size (w, h);
+			}
+
+			public void SetCursorPosition (Point pos)
+			{
+				throw new NotImplementedException ();
+			}
+
+			public override void Redraw (Rect bounds)
+			{
+				//Point pos = new Point (region.X, region.Y);
+				Driver.SetAttribute (ColorScheme.Focus);
+
+				for (int y = 0; y < h; y++) {
+					Move (0, y);
+					Driver.AddStr (y.ToString ());
+					for (int x = 0; x < w - y.ToString ().Length; x++) {
+						//Driver.AddRune ((Rune)('0' + (x + y) % 10));
+						if (y.ToString ().Length < w)
+							Driver.AddStr (" ");
+					}
+				}
+				//Move (pos.X, pos.Y);
+			}
+		}
+
+		class Filler : View {
+			public Filler (Rect rect) : base (rect)
+			{
+			}
+
+			public override void Redraw (Rect bounds)
+			{
+				Driver.SetAttribute (ColorScheme.Focus);
+				var f = Frame;
+
+				for (int y = 0; y < f.Width; y++) {
+					Move (0, y);
+					for (int x = 0; x < f.Height; x++) {
+						Rune r;
+						switch (x % 3) {
+						case 0:
+							Driver.AddRune (y.ToString ().ToCharArray (0, 1) [0]);
+							if (y > 9)
+								Driver.AddRune (y.ToString ().ToCharArray (1, 1) [0]);
+							r = '.';
+							break;
+						case 1:
+							r = 'o';
+							break;
+						default:
+							r = 'O';
+							break;
+						}
+						Driver.AddRune (r);
+					}
+				}
+			}
+		}
+
 		public override void Setup ()
 		{
-			Win.X = 1;
-			Win.Y = 2;
-			Win.Width = Dim.Fill () - 4;
-			Win.Height = Dim.Fill () - 2;
+			Win.X = 3;
+			Win.Y = 3;
+			Win.Width = Dim.Fill () - 3;
+			Win.Height = Dim.Fill () - 3;
 			var label = new Label ("ScrollView (new Rect (2, 2, 50, 20)) with a 200, 100 ContentSize...") {
-				X = 0, Y = 0,
+				X = 0,
+				Y = 0,
 				ColorScheme = Colors.Dialog
 			};
 			Win.Add (label);
@@ -60,7 +135,7 @@ namespace UICatalog {
 			scrollView.Add (new Button ("A very long button. Should be wide enough to demo clipping!") {
 				X = 3,
 				Y = 4,
-				Width = 50,
+				Width = Dim.Fill (6),
 				Clicked = () => MessageBox.Query (20, 7, "MessageBox", "Neat?", "Yes", "No")
 			});
 
@@ -101,7 +176,44 @@ namespace UICatalog {
 			};
 			scrollView.Add (anchorButton);
 
-			Win.Add (scrollView);
+			var scrollView2 = new ScrollView (new Rect (55, 2, 20, 8)) {
+				ContentSize = new Size (20, 50),
+				//ContentOffset = new Point (0, 0),
+				ShowVerticalScrollIndicator = true,
+				ShowHorizontalScrollIndicator = true
+			};
+			scrollView2.Add (new Filler(new Rect (0, 0, 60, 40)));
+
+			// This is just to debug the visuals of the scrollview when small
+			var scrollView3 = new ScrollView (new Rect (55, 15, 3, 3)) {
+				ContentSize = new Size (100, 100),
+				ShowVerticalScrollIndicator = true,
+				ShowHorizontalScrollIndicator = true
+			};
+			scrollView3.Add (new Box10x (0, 0));
+
+			int count = 0;
+			var mousePos = new Label ("Mouse: ");
+			mousePos.X = Pos.Center ();
+			mousePos.Y = Pos.AnchorEnd (1);
+			mousePos.Width = 50;
+			Application.RootMouseEvent += delegate (MouseEvent me) {
+				mousePos.TextColor = Colors.TopLevel.Normal;
+				mousePos.Text = $"Mouse: ({me.X},{me.Y}) - {me.Flags} {count++}";
+			};
+
+			var progress = new ProgressBar ();
+			progress.X = 5;
+			progress.Y = Pos.AnchorEnd (3);
+			progress.Width = 50;
+			bool timer (MainLoop caller)
+			{
+				progress.Pulse ();
+				return true;
+			}
+			Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (300), timer);
+
+			Win.Add (scrollView, scrollView2, scrollView3, mousePos, progress);
 		}
 	}
 }