mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Merge branch 'v2_develop' of github.com:gui-cs/Terminal.Gui into v2_develop
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
BorderStyle = DefaultBorderStyle;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The default <see cref="LineStyle"/> for <see cref="FrameView"/>'s border. The default is
|
||||
/// <see cref="LineStyle.Single"/>.
|
||||
|
||||
@@ -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"/>.
|
||||
|
||||
@@ -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 ()
|
||||
|
||||
@@ -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];
|
||||
{
|
||||
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<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);
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user