diff --git a/Terminal.Gui/View/View.cs b/Terminal.Gui/View/View.cs
index 35de80f2b..095ca31ad 100644
--- a/Terminal.Gui/View/View.cs
+++ b/Terminal.Gui/View/View.cs
@@ -8,8 +8,13 @@ namespace Terminal.Gui;
///
/// 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
+///
+/// View
+/// Deep Dive
+///
+/// for more.
///
///
///
@@ -27,73 +32,222 @@ namespace Terminal.Gui;
///
/// SuperViewThe View that is a container for SubViews.
///
+///
+/// Input
+///
+///
+/// Key Bindings is the preferred way of handling keyboard input in View implementations.
+/// The View calls
+/// to declare
+/// it supports a particular command and then uses
+/// to indicate which key presses will invoke the command.
+///
+///
+/// Mouse Bindings is the preferred way of handling mouse input in View implementations. The View calls
+/// to declare
+/// it supports a
+/// particular command and then uses to indicate which mouse events will
+/// invoke the command.
+///
+///
+/// See the
+///
+/// Mouse
+/// Deep Dive
+///
+/// and
+///
+/// Keyboard
+/// Deep Dive
+///
+/// for more information.
+///
+///
+///
+///
+/// Layout
+///
+///
+/// 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.
+///
+///
+/// The , , , and properties are
+/// and objects that dynamically update the position of a view. The
+/// X and Y properties are of type and you can use either absolute positions,
+/// percentages, or anchor points. The Width and Height properties are of type 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.
+///
+///
+/// See the
+///
+/// Layout
+/// Deep Dive
+///
+/// for more information.
+///
+///
+///
+///
+/// Arrangement
+///
+///
+/// Complimenting the Layout system, controls how the user can use the mouse
+/// and keyboard to arrange views and enables either Tiled or Overlapped layouts.
+///
+///
+/// See the
+///
+/// Arrangement
+/// Deep Dive
+///
+/// for more information.
+///
+///
+///
+///
+/// Drawing
+///
+///
+/// Apps draw using the and APIs. Move selects the
+/// column and row of the Cell and AddRune places
+/// the specified glyph in that cell using the that was most recently set via
+/// .
+/// 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.
+///
+///
+/// The View draw APIs all take coordinates specified in Viewport-Relative coordinates. That is,
+/// (0,0) is the top-left cell visible to the user.
+///
+///
+/// If a View need to redraw because something changed within it's Content Area it can call
+/// .
+///
+///
+/// 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.
+///
+///
+/// The provides consistent colors across all views. The
+/// is inherited from the . The
+/// is used to set the for drawing.
+///
+/// The 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
+/// to change the colors used when drawing.
+///
+///
+///
+/// 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
+/// .
+/// There is an -managed clip region. Developers cannot change this directly,
+/// but can use , , and to
+/// modify the clip region.
+///
+///
+/// provides auto join, a smart TUI drawing system that automatically selects
+/// the correct line/box drawing glyphs for intersections making drawing complex shapes easy.
+///
+///
+/// A set of static properties are provided for the common glyphs used in TUI apps. See
+/// .
+///
+///
+/// See the
+///
+/// Drawing
+/// Deep Dive
+///
+/// for more information.
+///
+///
+///
+///
+/// Text
+///
+///
+/// A rich text formatting engine is provided in . TextFormatter provides
+/// methods for formatting text with horizontal and vertical alignment, word wrapping, and hotkeys.
+///
+///
+/// See the
+///
+/// Navigation
+/// Deep Dive
+///
+/// for more information.
+///
+///
+///
+///
+/// Navigation
+///
+///
+/// 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
+/// , , and will receive focus. NOTE:
+/// is by default.
+///
+///
+/// Views that are focusable should override 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
+/// will place the
+/// cursor at either the hotkey (if defined) or 0,0.
+///
+///
+/// See the
+///
+/// Navigation
+/// Deep Dive
+///
+/// for more information.
+///
+///
+///
+///
+/// Scrolling
+///
+///
+/// The ability to scroll content is built into View. The represents the
+/// scrollable "viewport" into the View's Content Area (which is defined by the return value of
+/// ).
+///
+///
+/// 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 and to enable this feature.
+///
+///
+/// Use to adjust the behavior of scrolling.
+///
+///
+/// See the
+///
+/// Scrolling
+/// Deep Dive
+///
+/// for more information.
+///
+///
+///
///
///
-/// Focus is a concept that is used to describe which View is currently receiving user input. Only Views that are
-/// , , and will receive focus.
-///
-///
-/// Views that are focusable should override 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 will place the
-/// cursor at either the hotkey (if defined) or 0,0.
-///
-///
-/// 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.
-///
-///
-/// 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 ). 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 of the
-/// the View is added to.
-///
-///
-/// 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 , ,
-/// , and properties are and objects
-/// that dynamically update the position of a view. The X and Y properties are of type and you
-/// can use either absolute positions, percentages, or anchor points. The Width and Height properties are of type
-/// 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.
-///
-///
-/// 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 property.
-///
-///
-/// Subviews (child views) can be added to a View by calling the method. The container of
-/// a View can be accessed with the property.
-///
-///
-/// To flag a region of the View's to be redrawn call
-///
-/// .
-/// To flag the entire view for redraw call .
-///
-///
-/// The method is called when the size or layout of a view has changed. The
-/// will
-/// cause to be called on the next so there is normally
-/// no reason to direclty call
-/// see .
-///
-///
-/// Views have a 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.
-///
-///
-/// Subclasses should not rely on being set at construction time. If a
-/// is not set on a view, the view will inherit the value from its
-/// and the value might only be valid once a view has been added to a SuperView.
-///
-/// By using applications will work both in color as well as black and white displays.
-///
-/// 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
/// and which will be called
/// when the view is added to a .
///
@@ -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
}
///
- /// Riased when the is being disposed.
+ /// Riased when the is being disposed.
///
public event EventHandler? Disposing;
diff --git a/Terminal.Gui/Views/FrameView.cs b/Terminal.Gui/Views/FrameView.cs
index 20bbbec46..886c9ca1f 100644
--- a/Terminal.Gui/Views/FrameView.cs
+++ b/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.
+
///
-/// The FrameView is a container View with a border around it.
+/// A non-overlapped container for other views with a border and optional title.
///
+///
+///
+/// FrameView has set to and
+/// inherits it's color scheme from the .
+///
+///
+///
+///
+///
+///
public class FrameView : View
{
///
@@ -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;
+ BorderStyle = DefaultBorderStyle;
}
- private void FrameView_MouseClick (object sender, MouseEventArgs e)
- {
- // base sets focus on HotKey
- e.Handled = InvokeCommand (Command.HotKey, new ([Command.HotKey], this, this)) == true;
- }
-
-
///
/// The default for 's border. The default is
/// .
diff --git a/Terminal.Gui/Views/Window.cs b/Terminal.Gui/Views/Window.cs
index 51cebd300..2bbfc701c 100644
--- a/Terminal.Gui/Views/Window.cs
+++ b/Terminal.Gui/Views/Window.cs
@@ -1,25 +1,22 @@
-namespace Terminal.Gui;
+#nullable enable
+namespace Terminal.Gui;
///
-/// A with set to
-/// . Provides a container for other views.
+/// An overlapped container for other views with a border and optional title.
///
///
///
-/// If any subview is a button and the property is set to true, the Enter key will
-/// invoke the command on that subview.
+/// Window has set to ,
+/// set to , and
+/// uses the Base color scheme by default.
+///
+///
+/// To enable Window to be sized and moved by the user, adjust .
///
///
+///
public class Window : Toplevel
{
-
- ///
- /// Gets or sets whether all s are shown with a shadow effect by default.
- ///
- [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
- public static ShadowStyle DefaultShadow { get; set; } = ShadowStyle.None;
-
-
///
/// Initializes a new instance of the class.
///
@@ -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;
}
+ ///
+ /// Gets or sets whether all s are shown with a shadow effect by default.
+ ///
+ [SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
+ public static ShadowStyle DefaultShadow { get; set; } = ShadowStyle.None;
+
// TODO: enable this
/////
///// The default for 's border. The default is .
diff --git a/UICatalog/Scenarios/Adornments.cs b/UICatalog/Scenarios/Adornments.cs
index 55feb28ec..f2e664f9c 100644
--- a/UICatalog/Scenarios/Adornments.cs
+++ b/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 ()
diff --git a/UICatalog/Scenarios/ComputedLayout.cs b/UICatalog/Scenarios/ComputedLayout.cs
index c27eabdb3..4eb15e4af 100644
--- a/UICatalog/Scenarios/ComputedLayout.cs
+++ b/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;
///
-/// 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.
///
[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];
+ {
+ if (horizontalRuler.Viewport.Width == 0 || horizontalRuler.Viewport.Height == 0)
+ {
+ return;
+ }
- verticalRuler.Text =
- vrule.Repeat ((int)Math.Ceiling (verticalRuler.Viewport.Height * 2 / (double)rule.Length))
- [..(verticalRuler.Viewport.Height * 2)];
- };
+ 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