Back to Ftxui

Module Dom

doc/module-dom.md

6.1.915.1 KB
Original Source

@page module-dom ftxui / dom @tableofcontents

This module defines a hierarchical set of ftxui::Element. An element manages the layout and can be responsive to the terminal dimension changes. Note the following example where this module is used to create a simple layout with a number of operators:

The @subpage module-dom-examples section provides a collection of examples.

Example:

cpp
namespace ftxui {
    ...

// Define the document
Element document = vbox({
  text("The window") | bold | color(Color::Blue),
  gauge(0.5)
  text("The footer")
});

// Add a border, by calling the `ftxui::border` decorator function.
document = border(document);

// Add another border, using the pipe operator.
document = document | border.

// Add another border, using the |= operator.
document |= border

...
}

List of elements

The list of all elements are included and can be accessed by including the corresponding header file:

cpp
#include <ftxui/dom/elements.hpp>

\include{strip} "ftxui/dom/elements.hpp"

text # {#dom-text}

The most simple widget. It displays a text.

cpp
text("I am a piece of text");
bash
I am a piece of text.

vtext {#dom-vtext}

Identical to ftxui::text, but displayed vertically.

Code:

cpp
vtext("HELLO");

Terminal output:

bash
H
E
L
L
O

paragraph {#dom-paragraph}

Similar to ftxui::text, but the individual word are wrapped along multiple lines, depending on the width of its container.

Sample Code:

cpp
paragraph("A very long text")

For a more detailed example refer to detailed example. Paragraph also includes a number of other variants as shown below:

cpp
namespace ftxui {
    Element paragraph(std::string text);
    Element paragraphAlignLeft(std::string text);
    Element paragraphAlignRight(std::string text);
    Element paragraphAlignCenter(std::string text);
    Element paragraphAlignJustify(std::string text);
}

border {#dom-border}

Adds a border around an element.

Code:

cpp
border(text("The element"))

Terminal output:

bash
┌───────────┐
│The element│
└───────────┘

[!note] You can achieve the same behavior by using the pipe operator.

Code:

cpp
text("The element") | border

Border also comes in a variety of styles as shown below:

cpp
namespace ftxui {
    Element border(Element);
    Element borderLight(Element);
    Element borderHeavy(Element);
    Element borderDouble(Element);
    Element borderRounded(Element);
    Element borderEmpty(Element);
    Decorator borderStyled(BorderStyle);
    Decorator borderWith(Cell);
}

window # {#dom-window}

A ftxui::window is a ftxui::border, but with an additional header. To add a window around an element, wrap it and specify a string as the header. Code:

cpp
window("The window", text("The element"))

Terminal output:

bash
┌The window─┐
│The element│
└───────────┘

separator {#dom-separator}

Displays a vertical/horizontal line to visually split the content of a container in two.

Code:

cpp
border(
  hbox({
    text("Left"), 
    separator(),
    text("Right")
  })
)

Terminal output:

bash
┌────┬─────┐
│left│right│
└────┴─────┘

Separators come in a variety of flavors as shown below:

cpp
namespace ftxui {
    Element separator(void);
    Element separatorLight();
    Element separatorHeavy();
    Element separatorDouble();
    Element separatorEmpty();
    Element separatorStyled(BorderStyle);
    Element separator(Cell);
    Element separatorCharacter(std::string);
    Element separatorHSelector(float left,
                               float right,
                               Color background,
                               Color foreground);
    Element separatorVSelector(float up,
                               float down,
                               Color background,
                               Color foreground);
}

gauge {#dom-gauge}

This is a visual element that represents a ratio of progress.

Code:

cpp
border(gauge(0.5))

Terminal output:

bash
┌────────────────────────────────────────────────────────────────────────────┐
│██████████████████████████████████████                                      │
└────────────────────────────────────────────────────────────────────────────┘

Gauges can be displayed in many orientations as shown below:

cpp
namespace {
    Element gauge(float ratio);
    Element gaugeLeft(float ratio);
    Element gaugeRight(float ratio);
    Element gaugeUp(float ratio);
    Element gaugeDown(float ratio);
    Element gaugeDirection(float ratio, GaugeDirection);
}

graph {#dom-graph}

@htmlonly

<script id="asciicast-223726" src="https://asciinema.org/a/223726.js" async></script>

@endhtmlonly

See:

cpp
Element graph(GraphFunction);

Colors {#dom-colors}

Most terminal consoles can display colored text and colored backgrounds. FTXUI supports every color palette:

cpp
Decorator color(Color);
Decorator bgcolor(Color);

Color gallery:

Palette16 #{#dom-colors-palette-16}

On most terminals the following colors are supported:

  • Default

  • Black

  • GrayDark

  • GrayLight

  • White

  • Blue

  • BlueLight

  • Cyan

  • CyanLight

  • Green

  • GreenLight

  • Magenta

  • MagentaLight

  • Red

  • RedLight

  • Yellow

  • YellowLight

Example use of the above colors using the pipe operator:

cpp
text("Blue foreground") | color(Color::Blue);
text("Blue background") | bgcolor(Color::Blue);
text("Black on white") | color(Color::Black) | bgcolor(Color::White);

Palette256 #{#dom-colors-palette-256}

On terminal supporting 256 colors. @htmlonly

<script id="asciicast-OAUc3n6QrkmrLt7XEEb8AzbLt" src="https://asciinema.org/a/OAUc3n6QrkmrLt7XEEb8AzbLt.js" async></script>

@endhtmlonly

cpp
text("HotPink") | color(Color::HotPink);

TrueColor #{#dom-colors-true-color}

On terminal supporting trueColor, you can directly use the 24bit RGB color space:

Use the constructors below to specify the RGB or HSV values for your color:

There are two constructors:

cpp
ftxui::Color::RGB(uint8_t red, uint8_t green, uint8_t blue);
ftxui::Color::HSV(uint8_t hue, uint8_t saturation, uint8_t value);

@htmlonly

<script id="asciicast-dk5r8IcCH0aFIIgWG0keSEHMG" src="https://asciinema.org/a/dk5r8IcCH0aFIIgWG0keSEHMG.js" async></script> <script id="asciicast-xwzzghmqcqzIuyLwCpQFEqbEu" src="https://asciinema.org/a/xwzzghmqcqzIuyLwCpQFEqbEu.js" async></script>

@endhtmlonly

LinearGradient #{#dom-linear-gradient}

FTXUI supports linear gradient. Either on the foreground or the background.

cpp
Decorator color(const LinearGradient&);
Decorator bgcolor(const LinearGradient&);

A ftxui::LinearGradient is defined by an angle in degree, and a list of color stops.

cpp
auto gradient = LinearGradient()
  .Angle(45)
  .AddStop(0.0, Color::Red)
  .AddStop(0.5, Color::Green)
  .AddStop(1.0, Color::Blue);

You can also use simplified constructors:

cpp
LinearGradient(Color::Red, Color::Blue);
cpp
LinearGradient(45, Color::Red, Color::Blue);

See demo.

Style {#dom-style}

In addition to colored text and colored backgrounds. Many terminals support text effects such as: bold, italic, dim, underlined, inverted, blink.

cpp
Element bold(Element);
Element italic(Element);
Element dim(Element);
Element inverted(Element);
Element underlined(Element);
Element underlinedDouble(Element);
Element strikethrough(Element);
Element blink(Element);
Decorator color(Color);
Decorator bgcolor(Color);
Decorator colorgrad(LinearGradient);
Decorator bgcolorgrad(LinearGradient);

Example

To use these effects, simply wrap your elements with your desired effect:

cpp
underlined(bold(text("This text is bold and underlined")))

Alternatively, use the pipe operator to chain it on your element:

cpp
text("This text is bold") | bold | underlined

Layout {#dom-layout}

Enables elements to be arranged in the following ways:

  • Horizontally with ftxui::hbox
  • Vertically with ftxui::vbox
  • Inside a grid with ftxui::gridbox
  • Wrapped along one direction using the ftxui::flexbox.

Example using ftxui::hbox, ftxui::vbox and ftxui::filler.

Example using ftxui::gridbox:

Example using flexbox:

Checkout this example and the associated demo.

Element can also become flexible using the ftxui::flex decorator.

Code:

cpp
  hbox({
    text("left") | border ,
    text("middle") | border | flex,
    text("right") | border,
  });

Terminal output:

bash
┌────┐┌─────────────────────────────────────────────────────┐┌─────┐
│left││middle                                               ││right│
└────┘└─────────────────────────────────────────────────────┘└─────┘

Code:

cpp
  hbox({
    text("left") | border ,
    text("middle") | border | flex,
    text("right") | border | flex,
  });

Terminal output:

bash
┌────┐┌───────────────────────────────┐┌───────────────────────────────┐
│left││middle                         ││right                          │
└────┘└───────────────────────────────┘└───────────────────────────────┘

Table {#dom-table}

Enables easy formatting of data into a neat table like visual form.

Basic example:

cpp
auto table = Table({
  {"Planet", "Radius", "Mass"},
  {"Mercury", "2440", "0.330"},
  {"Venus", "6052", "4.87"},
  {"Earth", "6371", "5.97"},
  {"Mars", "3390", "0.642"},
});

table.SelectAll().Border(LIGHT);
table.SelectRow(0).Decorate(bold);
table.SelectRow(0).SeparatorVertical(LIGHT);
table.SelectRow(0).Border(DOUBLE);

auto document = table.Render();

Code example:

Selection and Styling

You can select parts of the table and apply decorators or borders to them. Selection methods include:

cpp
ftxui::TableSelection::SelectAll();
ftxui::TableSelection::SelectCell(column, row);
ftxui::TableSelection::SelectRow(row_index);
ftxui::TableSelection::SelectRows(row_min, row_max);
ftxui::TableSelection::SelectColumn(column_index);
ftxui::TableSelection::SelectColumns(column_min, column_max);
ftxui::TableSelection::SelectRectangle(column_min, column_max, row_min, row_max);

Once a selection is made, you can apply:

cpp
ftxui::TableSelection::Decorate(Decorator); // Apply a decorator to the whole selection (cells and borders).
ftxui::TableSelection::DecorateCells(Decorator); // Apply a decorator only to the cells.
ftxui::TableSelection::Border(BorderStyle); // Add a border around the selection.
ftxui::TableSelection::Separator(BorderStyle); // 

Colored borders

You can also apply decorators specifically to borders and separators:

cpp
// Apply a red border to the whole table.
table.SelectAll().Border(LIGHT, color(Color::Red));

// Apply a blue separator to the first row.
table.SelectRow(0).SeparatorVertical(LIGHT, color(Color::Blue));

The following methods are available for fine-grained border decoration:

cpp
ftxui::TableSelection::DecorateBorder(Decorator); // Apply a decorator to all borders of the selection.
ftxui::TableSelection::DecorateBorderLeft(Decorator); // Apply a decorator to the left border of the selection.
ftxui::TableSelection::DecorateBorderRight(Decorator); // Apply a decorator to the right border of the selection.
ftxui::TableSelection::DecorateBorderTop(Decorator); // Apply a decorator to the top border of the selection.
ftxui::TableSelection::DecorateBorderBottom(Decorator); // Apply a decorator to the bottom border of the selection.
ftxui::TableSelection::DecorateSeparator(Decorator); // Apply a decorator to all separators of the selection.
ftxui::TableSelection::DecorateSeparatorVertical(Decorator); // Apply a decorator to all vertical separators of the selection.
ftxui::TableSelection::DecorateSeparatorHorizontal(Decorator); // Apply a decorator to all horizontal separators of the selection.

Canvas {#dom-canvas}

See the API <ftxui/dom/canvas.hpp>

cpp
  auto c = Canvas(100, 100);
  c.DrawPointLine(10, 10, 80, 10, Color::Red);
  auto element = canvas(c);

Drawing can be performed on a ftxui::Canvas, using braille, block, or simple characters:

Simple example:

Complex example: