Table of Contents

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.

See View Deep Dive, Arrangement Deep Dive, Scrolling Deep Dive, and Drawing Deep Dive for more.

Lexicon & Taxonomy

Term Meaning
Adornment The Thicknesses that separate the Frame from the Viewport. There are three Adornments: Margin, Padding, and Border. Adornments are not part of the View's content and are not clipped by the View's ClipArea.
Application-Relative The dimensions and characteristics of the application. Because only full-screen apps are currently supported, Application is effectively the same as Screen from a layout perspective. Application-Relative currently means an origin (0, 0) at the top-left corner of the terminal. Top is a View with a top-left corner fixed at the Application.Relative coordinate of (0, 0) and is the size of Screen.
Border The Adornment that resides in the inside of the Margin. The Border is where a visual border (drawn using line-drawing glyphs) and the Title are drawn, and where the user can interact with the mouse/keyboard to adjust the Views' Arrangement.
Content Area Describes the View's total content. The location of the content is always (0, 0) and the size is set by SetContentSize and defaults to the size of the Viewport. If the content size is larger than the Viewport, scrolling is enabled.
Content-Relative A rectangle, with an origin of (0, 0) and size, defined by GetContentSize, where the View's content exists. Content-Relative means a coordinate is relative to the top-left corner of the content, which is always (0,0). ContentToScreen and ScreenToContent are helper methods for translating coordinates.
Frame A Rectangle that defines the location and size of the View. The coordinates are relative to the SuperView of the View (or, in the case of Application.Top, the console size). Controlled by X, Y, Width, and Height.
Frame-Relative The Frame property of a View is a rectangle that describes the current location and size of the view relative to the Superview's content area. Frame-Relative means a coordinate is relative to the top-left corner of the View in question. FrameToScreen and ScreenToFrame are helper methods for translating coordinates.
Margin The outermost Adornment. The outside of the margin is a rectangle the same size as the Frame. By default Margin is {0,0,0,0}. When made thicker, Margins are visually transparent and transparent to mouse events by default.
Overlapped/Overlapping Refers to a form Layout where SubViews of a View are visually arranged such that their Frames overlap. In Overlap view arrangements there is a Z-axis (Z-order) in addition to the X and Y dimension.
Padding The Adornment resides in the inside of the Border and outside of the Viewport. Padding is {0, 0, 0, 0} by default. Padding is not part of the View's content and is not clipped by the View's Clip. When enabled, scroll bars reside within Padding.
Screen-Relative Describes the dimensions and characteristics of the underlying terminal. Currently Terminal.Gui only supports applications that run "full-screen", meaning they fill the entire terminal when running. Screen-Relative means an origin (0, 0) at the top-left corner of the terminal. ConsoleDriver implementations operate exclusively on Screen-Relative coordinates.
Thickness A smart record struct describing a rectangle where each of the four sides can have a width. Valid width values are >= 0. The inner area of a Thickness is the sum of the widths of the four sides minus the size of the rectangle.
Tiled/Tiling Refer to a form of Views that are visually arranged such that they abut each other and do not overlap. In a Tiled view arrangement, Z-ordering only comes into play when a developer intentionally causes views to be aligned such that they overlap.
Viewport The Rectangle that describes the portion of the View's Content Area that is currently visible to the user. If size of the Content Area is larger than the Viewport, scrolling is enabled and the Viewport location determines which portion of the content is visible.
Viewport-Relative A Content-Relative rectangle representing the subset of the View's content that is visible to the user: Viewport. Viewport-Relative means a coordinate that is bound by (0,0) and the size of the inner-rectangle of the View's Padding. The View drawing primitives (e.g. View.Move) take Viewport-Relative coordinates.

Arrangement Modes

See Arrangement Deep Dive for more.

Composition

View Composition Diagram

classDiagram
    class View {
        +Frame: Rectangle
        +Margin: Adornment - outermost
        +Border: Adornment - border lines and Title
        +Padding: Adornment - innermost - Scrollbars
        +Viewport: Rectangle describing portal into ContentArea
        +ContentArea: Rectangle with Location always 0,0
        +GetContentSize(): Size
        +SetContentSize(Size)
    }

    class Adornment {
        +Thickness: Thickness
    }

    class Thickness {
        +Top: int
        +Right: int
        +Bottom: int
        +Left: int
    }

    class Rectangle {
        +Location: Point
        +Size: Size
    }

    View --> Adornment : has
    Adornment --> Thickness : has
    View --> Rectangle : has

    note for View "Frame defines location and size relative to SuperView"
    note for Adornment "Separates Frame from Viewport"
    note for Rectangle "Defines location and size"

The diagram above shows the structure of a View's composition:

  1. Frame: The outermost rectangle defining the View's location and size
  2. Margin: Separates the View from other SubViews
  3. Border: Contains visual border and title
  4. Padding: Offsets the Viewport from the Border
  5. Viewport: The visible portion of the Content Area
  6. Content Area: Where the View's content is drawn (shown larger than Viewport to illustrate scrolling)

Each layer is defined by a Thickness that specifies the width of each side (top, right, bottom, left). The Content Area is shown as a separate container that the Viewport "looks into" - this illustrates how scrolling works. In this example, the Viewport is positioned at (5,5) relative to the Content Area, showing how scrolling works.

The Content Area

Content Area refers to the rectangle with a location of 0,0 with the size returned by GetContentSize.

The content area is the area where the view's content is drawn. Content can be any combination of the Text property, SubViews, and other content drawn by the View. The GetContentSize method gets the size of the content area of the view.

The Content Area size tracks the size of the Viewport by default. If the content size is set via SetContentSize, the content area is the provided size. If the content size is larger than the Viewport, scrolling is enabled.

The Viewport

The Viewport is a rectangle describing the portion of the Content Area that is visible to the user. It is a "portal" into the content. The Viewport.Location is relative to the top-left corner of the inner rectangle of View.Padding. If Viewport.Size is the same as View.GetContentSize(), Viewport.Location will be 0,0.

To enable scrolling call View.SetContentSize() and then set Viewport.Location to positive values. Making Viewport.Location positive moves the Viewport down and to the right in the content.

See the Scrolling Deep Dive for details on how to enable scrolling.

The ViewportSettings property controls how the Viewport is constrained. By default, the ViewportSettings is set to ViewportSettings.None. To enable the viewport to be moved up-and-to-the-left of the content, use ViewportSettings.AllowNegativeX and or ViewportSettings.AllowNegativeY.

The default ViewportSettings also constrains the Viewport to the size of the content, ensuring the right-most column or bottom-most row of the content will always be visible (in v1 the equivalent concept was ScrollBarView.AlwaysKeepContentInViewport). To allow the Viewport to be smaller than the content, set ViewportSettings.AllowXGreaterThanContentWidth and/or ViewportSettings.AllowXGreaterThanContentHeight.

Layout Engine

Terminal.Gui provides a rich system for how views are laid out relative to each other. The position of a view is set by setting the X and Y properties, which are of time Pos. The size is set via Width and Height, which are of type Dim.

var label1 = new Label () { X = 1, Y = 2, Width = 3, Height = 4, Title = "Absolute")

var label2 = new Label () {
    Title = "Computed",
    X = Pos.Right (otherView),
    Y = Pos.Center (),
    Width = Dim.Fill (),
    Height = Dim.Percent (50)
};

Pos

Pos is the type of View.X and View.Y and supports the following sub-types:

  • Absolute position, by passing an integer - Absolute.
  • Percentage of the parent's view size - Percent(int)
  • Anchored from the end of the dimension - AnchorEnd(int)
  • Centered, using Center
  • The Left, Right, Top, and Bottom tracks the position of another view.
  • Aligned (left, right, center, etc...) with other views - Align
  • An arbitrary function - Func

All Pos coordinates are relative to the SuperView's content area.

Pos values can be combined using addition or subtraction:

// Set the X coordinate to 10 characters left from the center
view.X = Pos.Center () - 10;
view.Y = Pos.Percent (20);

anotherView.X = AnchorEnd (10);
anotherView.Width = 9;

myView.X = Pos.X (view);
myView.Y = Pos.Bottom (anotherView) + 5;

Dim

Dim is the type of View.Width and View.Height and supports the following sub-types:

  • Automatic size based on the View's content (either SubViews or Text) - Auto - See Dim.Auto Deep Dive.
  • Absolute size, by passing an integer - Absolute(int).
  • Percentage of the SuperView's Content Area - @Terminal.Gui.ViewBase.Dim.Percent(System.Int32).
  • Fill to the end of the SuperView's Content Area - Fill.
  • Reference the Width or Height of another view - Width(View?), Height(View?).
  • An arbitrary function - Func(Func<int>).

All Dim dimensions are relative to the SuperView's content area.

Like, Pos, objects of type Dim can be combined using addition or subtraction, like this:

// Set the Width to be 10 characters less than filling 
// the remaining portion of the screen
view.Width = Dim.Fill () - 10;

view.Height = Dim.Percent(20) - 1;

anotherView.Height = Dim.Height (view) + 1;
classDiagram
    class View {
    }

    View --> Frame : is Rectangle
    View --> Viewport : is Rectangle

    class Border {
    }

    class Adornment {
    }

    class Thickness {
    }


    Margin --> Adornment : is
    Border --> Adornment : is
    Padding --> Adornment : is
    Adornment --> Thickness : has

    View --> Margin : has
    View --> Border : has
    View --> Padding : has

    note for View "Defines location and size relative to SuperView"
    note for Viewport "Defines the visible portion of the Content Area"
    note for Margin "Where Shadows live"
    note for Border "Where Border, Title, and Arrangement controls live"
    note for Padding "Where ScrollBars live"
    note for Thickness "A rectangle where each side can have a width"