浏览代码

Makes `Window` default `Arrangement` not be movable/resizable (#3931)

* Window -> not sizeable/movable by default.
Window: Code cleanup.
Frameview: Code cleanup.

* View API docs updates

* View API docs updates
Tig 5 月之前
父节点
当前提交
c00de4a092

+ 223 - 68
Terminal.Gui/View/View.cs

@@ -8,8 +8,13 @@ namespace Terminal.Gui;
 
 /// <summary>
 ///     View is the base class all visible elements. View can render itself and
-///     contains zero or more nested views, called SubViews. View provides basic functionality for layout, positioning, and
-///     drawing. In addition, View provides keyboard and mouse event handling.
+///     contains zero or more nested views, called SubViews. View provides basic functionality for layout, arrangement, and
+///     drawing. In addition, View provides keyboard and mouse event handling. See the
+///     <see href="../docs/view.html">
+///         View
+///         Deep Dive
+///     </see>
+///     for more.
 /// </summary>
 /// <remarks>
 ///     <list type="table">
@@ -27,73 +32,222 @@ namespace Terminal.Gui;
 ///         <item>
 ///             <term>SuperView</term><description>The View that is a container for SubViews.</description>
 ///         </item>
+///         <item>
+///             <term>Input</term>
+///             <description>
+///                 <para>
+///                     Key Bindings is the preferred way of handling keyboard input in View implementations.
+///                     The View calls
+///                     <see cref="AddCommand(Terminal.Gui.Command,Terminal.Gui.View.CommandImplementation)"/> to declare
+///                     it supports a particular command and then uses <see cref="KeyBindings"/>
+///                     to indicate which key presses will invoke the command.
+///                 </para>
+///                 <para>
+///                     Mouse Bindings is the preferred way of handling mouse input in View implementations. The View calls
+///                     <see cref="AddCommand(Terminal.Gui.Command,Terminal.Gui.View.CommandImplementation)"/> to declare
+///                     it supports a
+///                     particular command and then uses <see cref="MouseBindings"/> to indicate which mouse events will
+///                     invoke the command.
+///                 </para>
+///                 <para>
+///                     See the
+///                     <see href="../docs/mouse.html">
+///                         Mouse
+///                         Deep Dive
+///                     </see>
+///                     and
+///                     <see href="../docs/keyboard.html">
+///                         Keyboard
+///                         Deep Dive
+///                     </see>
+///                     for more information.
+///                 </para>
+///             </description>
+///         </item>
+///         <item>
+///             <term>Layout</term>
+///             <description>
+///                 <para>
+///                     Terminal.Gui provides a rich system for how View objects are laid out relative to each other. The
+///                     layout system also defines how coordinates are specified.
+///                 </para>
+///                 <para>
+///                     The <see cref="X"/>, <see cref="Y"/>, <see cref="Width"/>, and <see cref="Height"/> properties are
+///                     <see cref="Dim"/> and <see cref="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 views when view's adornments are resized or if the terminal size changes.
+///                 </para>
+///                 <para>
+///                     See the
+///                     <see href="../docs/layout.html">
+///                         Layout
+///                         Deep Dive
+///                     </see>
+///                     for more information.
+///                 </para>
+///             </description>
+///         </item>
+///         <item>
+///             <term>Arrangement</term>
+///             <description>
+///                 <para>
+///                     Complimenting the Layout system, <see cref="Arrangement"/> controls how the user can use the mouse
+///                     and keyboard to arrange views and enables either Tiled or Overlapped layouts.
+///                 </para>
+///                 <para>
+///                     See the
+///                     <see href="../docs/arrangement.html">
+///                         Arrangement
+///                         Deep Dive
+///                     </see>
+///                     for more information.
+///                 </para>
+///             </description>
+///         </item>
+///         <item>
+///             <term>Drawing</term>
+///             <description>
+///                 <para>
+///                     Apps draw using the <see cref="Move"/> and <see cref="AddRune(Rune)"/> APIs. Move selects the
+///                     column and row of the Cell and AddRune places
+///                     the specified glyph in that cell using the <see cref="Attribute"/> that was most recently set via
+///                     <see cref="SetAttribute"/>.
+///                     The ConsoleDriver caches all changed Cells and efficiently outputs them to the terminal each
+///                     iteration of the Application. In other words, Terminal.Gui uses deferred rendering.
+///                 </para>
+///                 <para>
+///                     The View draw APIs all take coordinates specified in Viewport-Relative coordinates. That is,
+///                     <c>(0,0)</c> is the top-left cell visible to the user.
+///                 </para>
+///                 <para>
+///                     If a View need to redraw because something changed within it's Content Area it can call
+///                     <see cref="SetNeedsDraw()"/>.
+///                 </para>
+///                 <para>
+///                     Terminal.Gui supports the full range of Unicode/wide characters.
+///                     This includes emoji, CJK characters, and other wide characters. For Unicode characters that require
+///                     more than one cell,
+///                     AddRune and the ConsoleDriver automatically manage the cells. Extension methods to Rune are
+///                     provided to determine if a Rune is a wide character and to get the width of a Rune.
+///                 </para>
+///                 <para>
+///                     The <see cref="ColorScheme"/> provides consistent colors across all views. The
+///                     <see cref="ColorScheme"/> is inherited from the <see cref="SuperView"/>. The
+///                     <see cref="ColorScheme"/> is used to set the <see cref="Attribute"/> for drawing.
+///                 </para>
+///                 The <see cref="Color"/> class represents a color. It provides automatic mapping between the legacy
+///                 4-bit (16-color) system and 24-bit colors. It contains properties for the red, green, and blue
+///                 components of the color.
+///                 The Color class also contains a static property for each of the 16 ANSI colors. Use
+///                 <see cref="SetAttribute"/> to change the colors used when drawing.</para>
+///                 <para>
+///                 </para>
+///                 <para>
+///                     Clipping enables better performance by ensuring on regions of the terminal that need to be drawn
+///                     actually get drawn by the ConsoleDriver. Terminal.Gui supports non-rectangular clip regions with
+///                     <see cref="Region"/>.
+///                     There is an <see cref="Application"/>-managed clip region. Developers cannot change this directly,
+///                     but can use <see cref="ClipFrame"/>, <see cref="ClipViewport"/>, and <see cref="SetClip"/> to
+///                     modify the clip region.
+///                 </para>
+///                 <para>
+///                     <see cref="LineCanvas"/> provides auto join, a smart TUI drawing system that automatically selects
+///                     the correct line/box drawing glyphs for intersections making drawing complex shapes easy.
+///                 </para>
+///                 <para>
+///                     A set of static properties are provided for the common glyphs used in TUI apps. See
+///                     <see cref="Glyphs"/>.
+///                 </para>
+///                 <para>
+///                     See the
+///                     <see href="../docs/drawing.html">
+///                         Drawing
+///                         Deep Dive
+///                     </see>
+///                     for more information.
+///                 </para>
+///             </description>
+///         </item>
+///         <item>
+///             <term>Text</term>
+///             <description>
+///                 <para>
+///                     A rich text formatting engine is provided in <see cref="TextFormatter"/>. TextFormatter provides
+///                     methods for formatting text with horizontal and vertical alignment, word wrapping, and hotkeys.
+///                 </para>
+///                 <para>
+///                     See the
+///                     <see href="../docs/navigation.html">
+///                         Navigation
+///                         Deep Dive
+///                     </see>
+///                     for more information.
+///                 </para>
+///             </description>
+///         </item>
+///         <item>
+///             <term>Navigation</term>
+///             <description>
+///                 <para>
+///                     Navigation refers to the user experience for moving focus between views in the application
+///                     view-hierarchy. Focus is a concept that is used to describe which View is currently receiving user
+///                     input. Only
+///                     Views that are
+///                     <see cref="Enabled"/>, <see cref="Visible"/>, and <see cref="CanFocus"/> will receive focus. NOTE:
+///                     <see cref="CanFocus"/> is <see langword="false"/> by default.
+///                 </para>
+///                 <para>
+///                     Views that are focusable should override <see cref="PositionCursor"/> to make sure that the cursor
+///                     is
+///                     placed in a location that makes sense. Some 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. The default implementation of <see cref="PositionCursor"/>
+///                     will place the
+///                     cursor at either the hotkey (if defined) or <c>0,0</c>.
+///                 </para>
+///                 <para>
+///                     See the
+///                     <see href="../docs/navigation.html">
+///                         Navigation
+///                         Deep Dive
+///                     </see>
+///                     for more information.
+///                 </para>
+///             </description>
+///         </item>
+///         <item>
+///             <term>Scrolling</term>
+///             <description>
+///                 <para>
+///                     The ability to scroll content is built into View. The <see cref="Viewport"/> represents the
+///                     scrollable "viewport" into the View's Content Area (which is defined by the return value of
+///                     <see cref="GetContentSize"/>).
+///                 </para>
+///                 <para>
+///                     Terminal.Gui also provides the ability show a visual scroll bar that responds to mouse input. This
+///                     ability is not enabled by default given how precious TUI screen real estate is.
+///                     Use <see cref="VerticalScrollBar"/> and <see cref="HorizontalScrollBar"/> to enable this feature.
+///                 </para>
+///                 <para>
+///                     Use <see cref="ViewportSettings"/> to adjust the behavior of scrolling.
+///                 </para>
+///                 <para>
+///                     See the
+///                     <see href="../docs/scrolling.html">
+///                         Scrolling
+///                         Deep Dive
+///                     </see>
+///                     for more information.
+///                 </para>
+///             </description>
+///         </item>
 ///     </list>
 ///     <para>
-///         Focus is a concept that is used to describe which View is currently receiving user input. Only Views that are
-///         <see cref="Enabled"/>, <see cref="Visible"/>, and <see cref="CanFocus"/> will receive focus.
-///     </para>
-///     <para>
-///         Views that are focusable should override <see cref="PositionCursor"/> to make sure that the cursor is
-///         placed in a location that makes sense. Some 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. The default implementation of <see cref="PositionCursor"/> will place the
-///         cursor at either the hotkey (if defined) or <c>0,0</c>.
-///     </para>
-///     <para>
-///         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>
-///         To create a View using Absolute layout, call a constructor that takes a Rect parameter to specify the
-///         absolute position and size or simply set <see cref="View.Frame "/>). To create a View using Computed layout use
-///         a constructor that does not take a Rect parameter and set the X, Y, Width and Height properties on the view to
-///         non-absolute values. Both approaches use coordinates that are relative to the <see cref="Viewport"/> of the
-///         <see cref="SuperView"/> the View is added to.
-///     </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 <see cref="X"/>, <see cref="Y"/>,
-///         <see cref="Width"/>, and <see cref="Height"/> properties are <see cref="Dim"/> and <see cref="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 views when view's adornments are resized or if the terminal size changes.
-///     </para>
-///     <para>
-///         Absolute layout requires specifying coordinates and sizes of Views explicitly, and the View will typically
-///         stay in a fixed position and size. To change the position and size use the <see cref="Frame"/> property.
-///     </para>
-///     <para>
-///         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>
-///         To flag a region of the View's <see cref="Viewport"/> to be redrawn call
-///         <see cref="SetNeedsDraw(System.Drawing.Rectangle)"/>
-///         .
-///         To flag the entire view for redraw call <see cref="SetNeedsDraw()"/>.
-///     </para>
-///     <para>
-///         The <see cref="SetNeedsLayout"/> method is called when the size or layout of a view has changed. The
-///         <see cref="MainLoop"/> will
-///         cause <see cref="Layout()"/> to be called on the next <see cref="Application.Iteration"/> so there is normally
-///         no reason to direclty call
-///         see <see cref="Layout()"/>.
-///     </para>
-///     <para>
-///         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>
-///         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>By using  <see cref="ColorScheme"/> applications will work both in color as well as black and white displays.</para>
-///     <para>
-///         Views can also opt-in to more sophisticated initialization by implementing overrides to
+///         Views can opt in to more sophisticated initialization by implementing overrides to
 ///         <see cref="ISupportInitialize.BeginInit"/> and <see cref="ISupportInitialize.EndInit"/> which will be called
 ///         when the view is added to a <see cref="SuperView"/>.
 ///     </para>
@@ -369,6 +523,7 @@ public partial class View : IDisposable, ISupportInitializeNotification
             SetNeedsLayout ();
             SuperView?.SetNeedsLayout ();
             SetNeedsDraw ();
+
             if (SuperView is { })
             {
                 SuperView?.SetNeedsDraw ();
@@ -576,7 +731,7 @@ public partial class View : IDisposable, ISupportInitializeNotification
     }
 
     /// <summary>
-    ///     Riased when the <see cref="View"/> is being disposed. 
+    ///     Riased when the <see cref="View"/> is being disposed.
     /// </summary>
     public event EventHandler? Disposing;
 

+ 15 - 15
Terminal.Gui/Views/FrameView.cs

@@ -1,9 +1,21 @@
-namespace Terminal.Gui;
+#nullable enable
+namespace Terminal.Gui;
 
 // TODO: FrameView is mis-named, really. It's far more about it being a TabGroup than a frame. 
+
 /// <summary>
-///     The FrameView is a container View with a border around it. 
+///     A non-overlapped container for other views with a border and optional title.
 /// </summary>
+/// <remarks>
+///     <para>
+///         FrameView has <see cref="View.BorderStyle"/> set to <see cref="LineStyle.Single"/> and
+///         inherits it's color scheme from the <see cref="SuperView"/>.
+///     </para>
+///     <para>
+///         
+///     </para>
+/// </remarks>
+/// <seealso cref="Window"/>
 public class FrameView : View
 {
     /// <summary>
@@ -14,21 +26,9 @@ public class FrameView : View
     {
         CanFocus = true;
         TabStop = TabBehavior.TabGroup;
-        Border.Thickness = new Thickness (1);
-        Border.LineStyle = DefaultBorderStyle;
-
-        //Border.ColorScheme = ColorScheme;
-        Border.Data = "Border";
-        MouseClick += FrameView_MouseClick;
-    }
-
-    private void FrameView_MouseClick (object sender, MouseEventArgs e)
-    {
-        // base sets focus on HotKey
-        e.Handled = InvokeCommand<KeyBinding> (Command.HotKey, new ([Command.HotKey], this, this)) == true;
+        BorderStyle = DefaultBorderStyle;
     }
 
-
     /// <summary>
     ///     The default <see cref="LineStyle"/> for <see cref="FrameView"/>'s border. The default is
     ///     <see cref="LineStyle.Single"/>.

+ 19 - 16
Terminal.Gui/Views/Window.cs

@@ -1,25 +1,22 @@
-namespace Terminal.Gui;
+#nullable enable
+namespace Terminal.Gui;
 
 /// <summary>
-///     A <see cref="Toplevel"/> <see cref="View"/> with <see cref="View.BorderStyle"/> set to
-///     <see cref="LineStyle.Single"/>. Provides a container for other views.
+///     An overlapped container for other views with a border and optional title.
 /// </summary>
 /// <remarks>
 ///     <para>
-///         If any subview is a button and the <see cref="Button.IsDefault"/> property is set to true, the Enter key will
-///         invoke the <see cref="Command.Accept"/> command on that subview.
+///         Window has <see cref="View.BorderStyle"/> set to <see cref="LineStyle.Single"/>, <see cref="View.Arrangement"/>
+///         set to <see cref="ViewArrangement.Overlapped"/>, and
+///         uses the Base <see cref="Colors.ColorSchemes"/> color scheme by default.
+///     </para>
+///     <para>
+///         To enable Window to be sized and moved by the user, adjust <see cref="View.Arrangement"/>.
 ///     </para>
 /// </remarks>
+/// <seealso cref="FrameView"/>
 public class Window : Toplevel
 {
-
-    /// <summary>
-    /// Gets or sets whether all <see cref="Window"/>s are shown with a shadow effect by default.
-    /// </summary>
-    [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
-    public static ShadowStyle DefaultShadow { get; set; } = ShadowStyle.None;
-
-
     /// <summary>
     ///     Initializes a new instance of the <see cref="Window"/> class.
     /// </summary>
@@ -27,12 +24,18 @@ public class Window : Toplevel
     {
         CanFocus = true;
         TabStop = TabBehavior.TabGroup;
-        Arrangement = ViewArrangement.Movable | ViewArrangement.Overlapped | ViewArrangement.Resizable;
-        ColorScheme = Colors.ColorSchemes ["Base"]; // TODO: make this a theme property
+        Arrangement = ViewArrangement.Overlapped;
+        base.ColorScheme = Colors.ColorSchemes ["Base"]; // TODO: make this a theme property
         BorderStyle = DefaultBorderStyle;
-        ShadowStyle = DefaultShadow;
+        base.ShadowStyle = DefaultShadow;
     }
 
+    /// <summary>
+    ///     Gets or sets whether all <see cref="Window"/>s are shown with a shadow effect by default.
+    /// </summary>
+    [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
+    public static ShadowStyle DefaultShadow { get; set; } = ShadowStyle.None;
+
     // TODO: enable this
     ///// <summary>
     ///// The default <see cref="LineStyle"/> for <see cref="Window"/>'s border. The default is <see cref="LineStyle.Single"/>.

+ 1 - 1
UICatalog/Scenarios/Adornments.cs

@@ -34,7 +34,7 @@ public class Adornments : Scenario
         var window = new Window
         {
             Title = "The _Window",
-            Arrangement = ViewArrangement.Movable,
+            Arrangement = ViewArrangement.Overlapped | ViewArrangement.Movable,
 
             Width = Dim.Fill (Dim.Func (() => editor.Frame.Width )),
             Height = Dim.Fill ()

+ 73 - 68
UICatalog/Scenarios/ComputedLayout.cs

@@ -2,12 +2,11 @@
 using System.Collections.Generic;
 using System.Linq;
 using Terminal.Gui;
-using static Terminal.Gui.Dialog;
 
 namespace UICatalog.Scenarios;
 
 /// <summary>
-///     This Scenario demonstrates how to use Terminal.Gui's Dim and Pos Layout System. 
+///     This Scenario demonstrates how to use Terminal.Gui's Dim and Pos Layout System.
 /// </summary>
 [ScenarioMetadata ("Computed Layout", "Demonstrates the Computed (Dim and Pos) Layout System.")]
 [ScenarioCategory ("Layout")]
@@ -19,7 +18,7 @@ public class ComputedLayout : Scenario
 
         Window app = new ()
         {
-            Title = GetQuitKeyAndName (),
+            Title = GetQuitKeyAndName ()
         };
 
         // Demonstrate using Dim to create a horizontal ruler that always measures the parent window's width
@@ -51,19 +50,20 @@ public class ComputedLayout : Scenario
         };
 
         app.SubviewsLaidOut += (s, a) =>
-                                          {
-                                              if (horizontalRuler.Viewport.Width == 0 || horizontalRuler.Viewport.Height == 0)
-                                              {
-                                                  return;
-                                              }
-                                              horizontalRuler.Text =
-                                                  rule.Repeat ((int)Math.Ceiling (horizontalRuler.Viewport.Width / (double)rule.Length)) [
-                                                   ..horizontalRuler.Viewport.Width];
-
-                                              verticalRuler.Text =
-                                                  vrule.Repeat ((int)Math.Ceiling (verticalRuler.Viewport.Height * 2 / (double)rule.Length))
-                                                      [..(verticalRuler.Viewport.Height * 2)];
-                                          };
+                               {
+                                   if (horizontalRuler.Viewport.Width == 0 || horizontalRuler.Viewport.Height == 0)
+                                   {
+                                       return;
+                                   }
+
+                                   horizontalRuler.Text =
+                                       rule.Repeat ((int)Math.Ceiling (horizontalRuler.Viewport.Width / (double)rule.Length)) [
+                                        ..horizontalRuler.Viewport.Width];
+
+                                   verticalRuler.Text =
+                                       vrule.Repeat ((int)Math.Ceiling (verticalRuler.Viewport.Height * 2 / (double)rule.Length))
+                                           [..(verticalRuler.Viewport.Height * 2)];
+                               };
 
         app.Add (verticalRuler);
 
@@ -77,7 +77,12 @@ public class ComputedLayout : Scenario
 
         // Demonstrate using Dim to create a window that fills the parent with a margin
         var margin = 10;
-        var subWin = new Window { X = Pos.Center (), Y = 2, Width = Dim.Fill (margin), Height = 7 };
+
+        var subWin = new Window
+        {
+            X = Pos.Center (), Y = 2, Width = Dim.Fill (margin), Height = 7,
+            Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable | ViewArrangement.Overlapped
+        };
 
         subWin.Initialized += (s, a) =>
                               {
@@ -89,10 +94,10 @@ public class ComputedLayout : Scenario
         var i = 1;
         var txt = "Resize the terminal to see computed layout in action.";
         List<Label> labelList = new ();
-        labelList.Add (new Label { Text = "The lines below show different alignment" });
+        labelList.Add (new() { Text = "The lines below show different alignment" });
 
         labelList.Add (
-                       new Label
+                       new()
                        {
                            TextAlignment = Alignment.Start,
                            Width = Dim.Fill (),
@@ -104,7 +109,7 @@ public class ComputedLayout : Scenario
                       );
 
         labelList.Add (
-                       new Label
+                       new()
                        {
                            TextAlignment = Alignment.End,
                            Width = Dim.Fill (),
@@ -116,7 +121,7 @@ public class ComputedLayout : Scenario
                       );
 
         labelList.Add (
-                       new Label
+                       new()
                        {
                            TextAlignment = Alignment.Center,
                            Width = Dim.Fill (),
@@ -128,7 +133,7 @@ public class ComputedLayout : Scenario
                       );
 
         labelList.Add (
-                       new Label
+                       new()
                        {
                            TextAlignment = Alignment.Fill,
                            Width = Dim.Fill (),
@@ -150,11 +155,11 @@ public class ComputedLayout : Scenario
                                          $"{frameView.GetType ().Name} {{X={fv.X},Y={fv.Y},Width={fv.Width},Height={fv.Height}}}";
                                  };
         i = 1;
-        labelList = new List<Label> ();
-        labelList.Add (new Label { Text = "The lines below show different alignment" });
+        labelList = new ();
+        labelList.Add (new() { Text = "The lines below show different alignment" });
 
         labelList.Add (
-                       new Label
+                       new()
                        {
                            TextAlignment = Alignment.Start,
                            Width = Dim.Fill (),
@@ -166,7 +171,7 @@ public class ComputedLayout : Scenario
                       );
 
         labelList.Add (
-                       new Label
+                       new()
                        {
                            TextAlignment = Alignment.End,
                            Width = Dim.Fill (),
@@ -178,7 +183,7 @@ public class ComputedLayout : Scenario
                       );
 
         labelList.Add (
-                       new Label
+                       new()
                        {
                            TextAlignment = Alignment.Center,
                            Width = Dim.Fill (),
@@ -190,7 +195,7 @@ public class ComputedLayout : Scenario
                       );
 
         labelList.Add (
-                       new Label
+                       new()
                        {
                            TextAlignment = Alignment.Fill,
                            Width = Dim.Fill (),
@@ -203,7 +208,7 @@ public class ComputedLayout : Scenario
         frameView.Add (labelList.ToArray ());
         app.Add (frameView);
 
-        frameView = new FrameView
+        frameView = new()
         {
             X = Pos.Right (frameView), Y = Pos.Top (frameView), Width = Dim.Fill (), Height = 7
         };
@@ -216,11 +221,11 @@ public class ComputedLayout : Scenario
                                          $"{frameView.GetType ().Name} {{X={fv.X},Y={fv.Y},Width={fv.Width},Height={fv.Height}}}";
                                  };
 
-        labelList = new List<Label> ();
-        labelList.Add (new Label { Text = "The lines below show different alignment" });
+        labelList = new ();
+        labelList.Add (new() { Text = "The lines below show different alignment" });
 
         labelList.Add (
-                       new Label
+                       new()
                        {
                            TextAlignment = Alignment.Start,
                            Width = Dim.Fill (),
@@ -232,7 +237,7 @@ public class ComputedLayout : Scenario
                       );
 
         labelList.Add (
-                       new Label
+                       new()
                        {
                            TextAlignment = Alignment.End,
                            Width = Dim.Fill (),
@@ -244,7 +249,7 @@ public class ComputedLayout : Scenario
                       );
 
         labelList.Add (
-                       new Label
+                       new()
                        {
                            TextAlignment = Alignment.Center,
                            Width = Dim.Fill (),
@@ -256,7 +261,7 @@ public class ComputedLayout : Scenario
                       );
 
         labelList.Add (
-                       new Label
+                       new()
                        {
                            TextAlignment = Alignment.Fill,
                            Width = Dim.Fill (),
@@ -296,24 +301,24 @@ public class ComputedLayout : Scenario
         // Demonstrate odd-ball Combine scenarios
         // Until https://github.com/gui-cs/Terminal.Gui/issues/2358 is fixed these won't work right
 
-        oddballButton = new Button { Text = "Center + 0", X = Pos.Center () + 0, Y = Pos.Bottom (oddballButton) };
+        oddballButton = new() { Text = "Center + 0", X = Pos.Center () + 0, Y = Pos.Bottom (oddballButton) };
         app.Add (oddballButton);
 
-        oddballButton = new Button { Text = "Center + 1", X = Pos.Center () + 1, Y = Pos.Bottom (oddballButton) };
+        oddballButton = new() { Text = "Center + 1", X = Pos.Center () + 1, Y = Pos.Bottom (oddballButton) };
         app.Add (oddballButton);
 
-        oddballButton = new Button { Text = "0 + Center", X = 0 + Pos.Center (), Y = Pos.Bottom (oddballButton) };
+        oddballButton = new() { Text = "0 + Center", X = 0 + Pos.Center (), Y = Pos.Bottom (oddballButton) };
         app.Add (oddballButton);
 
-        oddballButton = new Button { Text = "1 + Center", X = 1 + Pos.Center (), Y = Pos.Bottom (oddballButton) };
+        oddballButton = new() { Text = "1 + Center", X = 1 + Pos.Center (), Y = Pos.Bottom (oddballButton) };
         app.Add (oddballButton);
 
-        oddballButton = new Button { Text = "Center - 1", X = Pos.Center () - 1, Y = Pos.Bottom (oddballButton) };
+        oddballButton = new() { Text = "Center - 1", X = Pos.Center () - 1, Y = Pos.Bottom (oddballButton) };
         app.Add (oddballButton);
 
         // This demonstrates nonsense: it the same as using Pos.AnchorEnd (100/2=50 + 100/2=50 = 100 - 50)
         // The `- Pos.Percent(5)` is there so at least something is visible
-        oddballButton = new Button
+        oddballButton = new()
         {
             Text = "Center + Center - Percent(50)",
             X = Pos.Center () + Pos.Center () - Pos.Percent (50),
@@ -323,7 +328,7 @@ public class ComputedLayout : Scenario
 
         // This demonstrates nonsense: it the same as using Pos.AnchorEnd (100/2=50 + 100/2=50 = 100 - 50)
         // The `- Pos.Percent(5)` is there so at least something is visible
-        oddballButton = new Button
+        oddballButton = new()
         {
             Text = "Percent(50) + Center - Percent(50)",
             X = Pos.Percent (50) + Pos.Center () - Pos.Percent (50),
@@ -333,7 +338,7 @@ public class ComputedLayout : Scenario
 
         // This demonstrates nonsense: it the same as using Pos.AnchorEnd (100/2=50 + 100/2=50 = 100 - 50)
         // The `- Pos.Percent(5)` is there so at least something is visible
-        oddballButton = new Button
+        oddballButton = new()
         {
             Text = "Center + Percent(50) - Percent(50)",
             X = Pos.Center () + Pos.Percent (50) - Pos.Percent (50),
@@ -344,7 +349,7 @@ public class ComputedLayout : Scenario
         #endregion
 
         // This demonstrates nonsense: Same as At(0)
-        oddballButton = new Button
+        oddballButton = new()
         {
             Text = "Center - Center - Percent(50)",
             X = Pos.Center () + Pos.Center () - Pos.Percent (50),
@@ -353,7 +358,7 @@ public class ComputedLayout : Scenario
         app.Add (oddballButton);
 
         // This demonstrates combining Percents)
-        oddballButton = new Button
+        oddballButton = new()
         {
             Text = "Percent(40) + Percent(10)", X = Pos.Percent (40) + Pos.Percent (10), Y = Pos.Bottom (oddballButton)
         };
@@ -364,13 +369,13 @@ public class ComputedLayout : Scenario
         anchorButton.X = Pos.AnchorEnd ();
 
         anchorButton.Accepting += (s, e) =>
-                                {
-                                    // This demonstrates how to have a dynamically sized button
-                                    // Each time the button is clicked the button's text gets longer
-                                    // The call to app.LayoutSubviews causes the Computed layout to
-                                    // get updated. 
-                                    anchorButton.Text += "!";
-                                };
+                                  {
+                                      // This demonstrates how to have a dynamically sized button
+                                      // Each time the button is clicked the button's text gets longer
+                                      // The call to app.LayoutSubviews causes the Computed layout to
+                                      // get updated. 
+                                      anchorButton.Text += "!";
+                                  };
         app.Add (anchorButton);
 
         // Demonstrate AnchorEnd(n) 
@@ -411,26 +416,26 @@ public class ComputedLayout : Scenario
         };
 
         leftButton.Accepting += (s, e) =>
-                              {
-                                  // This demonstrates how to have a dynamically sized button
-                                  // Each time the button is clicked the button's text gets longer
-                                  leftButton.Text += "!";
-                              };
+                                {
+                                    // This demonstrates how to have a dynamically sized button
+                                    // Each time the button is clicked the button's text gets longer
+                                    leftButton.Text += "!";
+                                };
 
         // show positioning vertically using Pos.AnchorEnd
         var centerButton = new Button
         {
             Text = "Center",
             X = Pos.Align (Alignment.Center),
-            Y = Pos.AnchorEnd (2),
+            Y = Pos.AnchorEnd (2)
         };
 
         centerButton.Accepting += (s, e) =>
-                                {
-                                    // This demonstrates how to have a dynamically sized button
-                                    // Each time the button is clicked the button's text gets longer
-                                    centerButton.Text += "!";
-                                };
+                                  {
+                                      // This demonstrates how to have a dynamically sized button
+                                      // Each time the button is clicked the button's text gets longer
+                                      centerButton.Text += "!";
+                                  };
 
         // show positioning vertically using another window and Pos.Bottom
         var rightButton = new Button
@@ -441,11 +446,11 @@ public class ComputedLayout : Scenario
         };
 
         rightButton.Accepting += (s, e) =>
-                               {
-                                   // This demonstrates how to have a dynamically sized button
-                                   // Each time the button is clicked the button's text gets longer
-                                   rightButton.Text += "!";
-                               };
+                                 {
+                                     // This demonstrates how to have a dynamically sized button
+                                     // Each time the button is clicked the button's text gets longer
+                                     rightButton.Text += "!";
+                                 };
 
         View [] buttons = { leftButton, centerButton, rightButton };
         app.Add (leftButton);

+ 11 - 5
UICatalog/Scenarios/WindowsAndFrameViews.cs

@@ -40,7 +40,8 @@ public class WindowsAndFrameViews : Scenario
             Y = 1,
             Width = Dim.Fill (15),
             Height = 10,
-            ColorScheme = Colors.ColorSchemes ["Dialog"]
+            ColorScheme = Colors.ColorSchemes ["Dialog"],
+            Arrangement = ViewArrangement.Overlapped | ViewArrangement.Movable | ViewArrangement.Resizable
         };
         win.Padding.Thickness = new (padding);
         win.Margin.Thickness = new (margin);
@@ -86,7 +87,8 @@ public class WindowsAndFrameViews : Scenario
                 X = margin,
                 Y = Pos.Bottom (listWin.Last ()) + margin,
                 Width = Dim.Fill (margin),
-                Height = contentHeight + pad * 2 + 2
+                Height = contentHeight + pad * 2 + 2,
+                Arrangement = ViewArrangement.Overlapped | ViewArrangement.Movable | ViewArrangement.Resizable
             };
             loopWin.Padding.Thickness = new (pad);
 
@@ -94,7 +96,7 @@ public class WindowsAndFrameViews : Scenario
 
             var pressMeButton = new Button
             {
-                X = Pos.Center (), Y = 0, ColorScheme = Colors.ColorSchemes ["Error"], Text = "Press me! (Y = 0)"
+                X = Pos.Center (), Y = 0, ColorScheme = Colors.ColorSchemes ["Error"], Text = "Press me! (Y = 0)",
             };
 
             pressMeButton.Accepting += (s, e) =>
@@ -109,7 +111,9 @@ public class WindowsAndFrameViews : Scenario
                 Width = Dim.Percent (50),
                 Height = 5,
                 ColorScheme = Colors.ColorSchemes ["Base"],
-                Text = "The Text in the Window"
+                Text = "The Text in the Window",
+                Arrangement = ViewArrangement.Overlapped | ViewArrangement.Movable | ViewArrangement.Resizable
+
             };
 
             subWin.Add (
@@ -164,7 +168,9 @@ public class WindowsAndFrameViews : Scenario
             Width = Dim.Percent (50),
             Height = Dim.Fill () - 1,
             ColorScheme = Colors.ColorSchemes ["Base"],
-            Text = "The Text in the Window"
+            Text = "The Text in the Window",
+            Arrangement = ViewArrangement.Overlapped | ViewArrangement.Movable | ViewArrangement.Resizable
+
         };
 
         subWinofFV.Add (

+ 2 - 0
UnitTests/Views/WindowTests.cs

@@ -147,6 +147,8 @@ public class WindowTests
         Assert.Null (defaultWindow.MostFocused);
         Assert.Equal (TextDirection.LeftRight_TopBottom, defaultWindow.TextDirection);
 
+        Assert.Equal (ViewArrangement.Overlapped, defaultWindow.Arrangement);
+
         // Empty Rect
         using var windowWithFrameRectEmpty = new Window { Frame = Rectangle.Empty, Title = "title" };
         windowWithFrameRectEmpty.Layout ();

+ 2 - 2
docfx/docs/scrolling.md

@@ -24,7 +24,7 @@ Scrolling with the mouse and keyboard are enabled by:
 1) Making the [View.Viewport](~/api/Terminal.Gui.View.Viewport.yml) size smaller than the size returned by [View.GetContentSize()](~/api/Terminal.Gui.View.GetContentSize.yml). 
 2) Creating key bindings for the appropriate directional keys (e.g. [Key.CursorDown](~/api/Terminal.Gui.Key)), and calling [View.ScrollHorizontal()](~/api/Terminal.Gui.View.ScrollHorizontal.yml)/[ScrollVertical()](~/api/Terminal.Gui.View.ScrollVertical.yml) as needed.
 3) Subscribing to [View.MouseEvent](~/api/Terminal.Gui.View.MouseEvent.yml) and calling calling [View.ScrollHorizontal()](~/api/Terminal.Gui.View.ScrollHorizontal.yml)/[ScrollVertical()](~/api/Terminal.Gui.View.ScrollVertical.yml) as needed.
-4) Enabling the [ScrollBar](~/api/Terminal.Gui.ScrollBar.yml)s built into View ([View.HorizontalScrollBar/VerticalScrollBar](~/api/Terminal.Gui.View.HorizontalScrollBar.yml)) by either enabling automatic show/hide behavior (@Terminal.Gui.ScrollBar.AutoShow) or explicitly making them visible (@Terminal.Gui.View.Visible).
+4) Enabling the [ScrollBar](~/api/Terminal.Gui.ScrollBar.yml)s built into View ([View.HorizontalScrollBar/VerticalScrollBar](~/api/Terminal.Gui.View.HorizontalScrollBar.yml)) by either enabling automatic show/hide behavior (see @Terminal.Gui.ScrollBar.AutoShow) or explicitly making them visible (see @Terminal.Gui.View.Visible).
 
 While *[ScrollBar](~/api/Terminal.Gui.ScrollBar.yml)* can be used in a standalone manner to provide proportional scrolling, it is typically enabled automatically via the [View.HorizontalScrollBar](~/api/Terminal.Gui.View.HorizontalScrollBar.yml) and  [View.VerticalScrollBar](~/api/Terminal.Gui.View.VerticalScrollBar.yml) properties.
 
@@ -40,7 +40,7 @@ These Scenarios illustrate Terminal.Gui scrolling:
 
 ## [Viewport Settings](~/api/Terminal.Gui.ViewportSettings.yml)
 
-Use  @Terminal.Gui.ViewporSettings to adjust the behavior of scrolling. 
+Use @Terminal.Gui.ViewportSettings to adjust the behavior of scrolling. 
 
 * `AllowNegativeX/Y` - If set, Viewport.Size can be set to negative coordinates enabling scrolling beyond the top-left of the content area.