Improve documentation theme.

This commit is contained in:
ArthurSonzogni 2025-05-20 14:35:17 +02:00
parent 08b8a3b28f
commit 22576bae6b
No known key found for this signature in database
GPG Key ID: 41D98248C074CD6C
29 changed files with 2338 additions and 1885 deletions

View File

@ -1,18 +1,4 @@
<p align="center">
<img src="https://github.com/ArthurSonzogni/FTXUI/assets/4759106/6925b6da-0a7e-49d9-883c-c890e1f36007" alt="Demo image"></img>
<br/>
<a href="#"><img src="https://img.shields.io/badge/c++-%2300599C.svg?style=flat&logo=c%2B%2B&logoColor=white"></img></a>
<a href="http://opensource.org/licenses/MIT"><img src="https://img.shields.io/github/license/arthursonzogni/FTXUI?color=black"></img></a>
<a href="#"><img src="https://img.shields.io/github/stars/ArthurSonzogni/FTXUI"></img></a>
<a href="#"><img src="https://img.shields.io/github/forks/ArthurSonzogni/FTXUI"></img></a>
<a href="#"><img src="https://img.shields.io/github/repo-size/ArthurSonzogni/FTXUI"></img></a>
<a href="https://github.com/ArthurSonzogni/FTXUI/graphs/contributors"><img src="https://img.shields.io/github/contributors/arthursonzogni/FTXUI?color=blue"></img></a>
<br/>
<a href="https://github.com/ArthurSonzogni/FTXUI/issues"><img src="https://img.shields.io/github/issues/ArthurSonzogni/FTXUI"></img></a>
<a href="https://repology.org/project/ftxui/versions"><img src="https://repology.org/badge/latest-versions/ftxui.svg" alt="latest packaged version(s)"></a>
<a href="https://codecov.io/gh/ArthurSonzogni/FTXUI">
<img src="https://codecov.io/gh/ArthurSonzogni/FTXUI/branch/master/graph/badge.svg?token=C41FdRpNVA"/>
</a>
<br/>
@ -22,7 +8,6 @@
<a href="https://github.com/ArthurSonzogni/FTXUI/issues">Request Feature</a> ·
<a href="https://github.com/ArthurSonzogni/FTXUI/pulls">Send a Pull Request</a>
</p>
# FTXUI

View File

@ -8,13 +8,54 @@ if (NOT DOXYGEN_FOUND)
return()
endif()
include(FetchContent)
FetchContent_Declare(
doxygen-awesome-css
GIT_REPOSITORY https://github.com/jothepro/doxygen-awesome-css.git
GIT_TAG v2.3.4
)
FetchContent_MakeAvailable(doxygen-awesome-css)
FetchContent_GetProperties(doxygen-awesome-css SOURCE_DIR AWESOME_CSS_DIR)
# Generate example list for documentation
set(EXAMPLE_LIST "${CMAKE_CURRENT_BINARY_DIR}/example_list.md")
file(WRITE ${EXAMPLE_LIST} "# Examples")
set(DOM_EXAMPLES "")
set(COMPONENT_EXAMPLES "")
get_property(EXAMPLES GLOBAL PROPERTY FTXUI::EXAMPLES)
foreach(EXAMPLE IN LISTS EXAMPLES)
file(APPEND ${EXAMPLE_LIST} "\n@example examples/${EXAMPLE}.cpp")
endforeach(EXAMPLE IN LISTS EXAMPLES)
message(STATUS "Initial FTXUI::EXAMPLES = '${EXAMPLES}'") # Check this value
foreach(example IN LISTS EXAMPLES)
if(example MATCHES "^dom/.*")
list(APPEND DOM_EXAMPLES "${example}")
elseif(example MATCHES "^component/.*")
list(APPEND COMPONENT_EXAMPLES "${example}")
else()
message(ERROR "Unknown example '${example}'")
endif()
endforeach()
macro(write_example_list file title page examples)
file(APPEND "${file}" "@page ${page} ${title}\n")
file(APPEND "${file}" "@tableofcontents\n")
foreach(example IN LISTS ${examples})
get_filename_component(name "${example}" NAME_WE)
file(APPEND "${file}" "# ${name}\n")
file(APPEND "${file}" "@include examples/${example}.cpp\n")
file(APPEND "${file}" "@example examples/${example}.cpp\n")
endforeach()
endmacro()
write_example_list("${CMAKE_CURRENT_BINARY_DIR}/dom_examples.md"
"Example"
module-dom-examples
DOM_EXAMPLES)
write_example_list("${CMAKE_CURRENT_BINARY_DIR}/component_examples.md"
"Example"
module-component-examples
COMPONENT_EXAMPLES)
configure_file(Doxyfile.in Doxyfile @ONLY)

File diff suppressed because it is too large Load Diff

View File

@ -1,323 +0,0 @@
/*
* GitHub Markdown style CSS for doxygen 1.8.14
* Source: https://github.com/sindresorhus/github-markdown-css
* License: MIT <EFBFBD> Sindre Sorhus
*/
* {
box-sizing: border-box;
}
body, table, div, p, dl {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
line-height: 1.5;
color: #24292e;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
font-size: 16px;
word-wrap: break-word;
}
b {
font-weight: 600;
}
/* @group Heading Levels */
h1, h2, h3, h4, h5, h6 {
font-weight: 600;
line-height: 1.25;
margin-top: 24px;
margin-bottom: 16px;
}
h1 {
font-size: 2em;
padding-bottom: 0.3em;
border-bottom: 1px solid #eaecef;
}
h2 {
padding-bottom: 0.3em;
font-size: 1.5em;
border-bottom: 1px solid #eaecef;
}
h3 {
font-size: 1.25em;
}
h4 {
font-size: 1em;
}
h5 {
font-size: 0.875em;
}
h6 {
font-size: 0.85em;
color: #6a737d;
}
a {
background-color: transparent;
color: #0366d6;
text-decoration: none;
font-weight: normal;
}
.contents a:visited {
color: #0366d6;
}
a:active, a:hover {
outline-width: 0;
}
a:hover {
text-decoration: underline;
}
a:not([href]) {
color: inherit;
text-decoration: none;
}
a.el {
font-weight: normal;
}
.image {
text-align: left;
}
.tip {
background-image: url(tip.png);
background-position: left center;
background-repeat: no-repeat;
padding-left: 30px;
margin-top: 1em;
margin-bottom: 1em;
min-height: 31px;
display: block;
font-style:italic;
}
.warn {
background-image: url(warn.png);
background-position: left center;
background-repeat: no-repeat;
padding-left: 48px;
margin-top: 1em;
margin-bottom: 1em;
min-height: 31px;
display: block;
font-style:italic;
}
#projectname {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
font-size: 2em;
font-weight: bold;
}
#projectbrief {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
font-size: 0.8em;
}
#projectnumber {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
font-size: 1em;
}
div.contents {
width: 980px;
padding: 40px;
margin-top: -1px;
margin-left: auto;
margin-right: auto;
margin-bottom: 10px;
border: 1px solid #d1d5da;
border-radius: 2px;
}
div.toc {
border: 0 none;
border-radius: 7px;
}
div.header {
width: 980px;
padding: 10px;
margin-top: 10px;
margin-left: auto;
margin-right: auto;
background-image: none;
background-repeat: none;
background-color: #f6f8fa;
border: 1px solid #d1d5da;
}
div.headertitle {
padding: 0;
}
.title ol {
margin: 0;
}
.title ol li {
list-style-type: none;
}
.ui-resizable-e {
background: none;
background-color: #E6E6E6;
}
div.fragment {
background-color: #f3f3f3;
border-radius:5px;
border: 0 solid;
border: none;
padding:16px;
transition: all 0.5s ease-in-out;
}
div.fragment:hover {
background-color: #e9e9e9;
box-shadow: 0 5px 10px -5px rgb(0,0,0,0.5) inset;
}
div.line {
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 90%;
font-variant-numeric: tabular-nums lining-nums;
font-kerning: none;
-webkit-transition-duration: 0;
-moz-transition-duration: 0;
-ms-transition-duration: 0;
-o-transition-duration: 0;
transition-duration: 0;
}
div.line.glow {
background-color: auto;
box-shadow: none;
}
/* @group Code Colorization */
span.keyword {
color: #808000
}
span.keywordtype {
color: #808000
}
span.keywordflow {
color: #808000
}
span.comment {
color: #008000
}
span.preprocessor {
color: #800000
}
span.stringliteral {
color: #000080
}
span.charliteral {
color: #000080
}
blockquote {
background-color: #EEEEEE;
border-left: 2px solid #606060;
margin: 0 24px 0 4px;
padding: 0 12px 0 16px;
}
/* @end */
.arrow {
box-sizing: content-box;
}
img {
max-width: 100%;
max-height: 100%;
}
#nav-tree {
background-image: none;
background-color: white;
}
#nav-tree .label {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
font-size: 14px;
}
#side-nav {
width: 25%;
max-width: 50%;
}
.memtitle {
background-image: none;
}
.memproto {
text-shadow: none;
/* opera specific markup */
box-shadow: none;
/* firefox specific markup */
-moz-box-shadow: none;
-moz-border-radius-topright: 4px;
/* webkit specific markup */
-webkit-box-shadow: none;
-webkit-border-top-right-radius: 4px;
}
.memdoc {
background-image:none;
background-repeat:repeat-x;
background-color: #FFFFFF;
/* opera specific markup */
box-shadow: none;
/* firefox specific markup */
-moz-box-shadow: none;
/* webkit specific markup */
-webkit-box-shadow: none;
}
#main-menu {
background: none;
border-bottom: 1px solid black;
}
#main-menu li {
border: none !important;
transition: all 0.1s ease-in-out;
}
#main-menu li:hover {
color:black;
background-color:black;
}
.sm-dox a, .sm-dox a:focus, .sm-dox a:active, .sm-dox a:hover, .sm-dox a.highlighted {
background-image:none;
}
#titlearea {
margin: 8px;
border: none;
}

View File

@ -1,10 +0,0 @@
<!-- HTML footer for doxygen 1.8.14-->
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<!--END !GENERATE_TREEVIEW-->
</body>
</html>

View File

@ -1,59 +0,0 @@
<!-- HTML header for doxygen 1.8.14-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="cache-control" content="max-age=86400"/>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
$treeview
$search
$mathjax
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<!--BEGIN TITLEAREA-->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<!--BEGIN PROJECT_LOGO-->
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
<!--END PROJECT_LOGO-->
<!--BEGIN PROJECT_NAME-->
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">$projectname
<!--BEGIN PROJECT_NUMBER-->&#160;<span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
</div>
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
</td>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME-->
<!--BEGIN PROJECT_BRIEF-->
<td style="padding-left: 0.5em;">
<div id="projectbrief">$projectbrief</div>
</td>
<!--END PROJECT_BRIEF-->
<!--END !PROJECT_NAME-->
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN SEARCHENGINE-->
<td>$searchbox</td>
<!--END SEARCHENGINE-->
<!--END DISABLE_INDEX-->
</tr>
</tbody>
</table>
</div>
<!--END TITLEAREA-->
<!-- end header part -->

View File

@ -1,224 +0,0 @@
<doxygenlayout version="1.0">
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title="Tutorial"/>
<tab type="examples" visible="yes" title="" intro=""/>
<tab type="filelist" visible="yes" title=""/>
<tab type="pages" visible="no" title="" intro=""/>
<tab type="modules" visible="yes" title="" intro=""/>
<tab type="namespaces" visible="yes" title="">
<tab type="namespacelist" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="interfaces" visible="no" title="">
<tab type="interfacelist" visible="yes" title="" intro=""/>
<tab type="interfaceindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="interfacehierarchy" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="no" title="">
<tab type="classlist" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
<tab type="structs" visible="no" title="">
<tab type="structlist" visible="yes" title="" intro=""/>
<tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/>
</tab>
<tab type="exceptions" visible="no" title="">
<tab type="exceptionlist" visible="yes" title="" intro=""/>
<tab type="exceptionindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="exceptionhierarchy" visible="yes" title="" intro=""/>
</tab>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<services title=""/>
<interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<services title=""/>
<interfaces title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<functions title=""/>
<enums title=""/>
<typedefs title=""/>
<classes visible="yes" title=""/>
<structs visible="yes" title=""/>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<interfaces visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<sequences title=""/>
<dictionaries title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="yes"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

17
doc/footer.html Normal file
View File

@ -0,0 +1,17 @@
<!-- HTML footer for doxygen 1.9.8-->
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
$navpath
<li class="footer">$generatedby <a href="https://www.doxygen.org/index.html"><img class="footer" src="$relpath^doxygen.svg" width="104" height="31" alt="doxygen"/></a> $doxygenversion </li>
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<hr class="footer"/><address class="footer"><small>
$generatedby&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="$relpath^doxygen.svg" width="104" height="31" alt="doxygen"/></a> $doxygenversion
</small></address>
<!--END !GENERATE_TREEVIEW-->
</body>
</html>

60
doc/getting-started.md Normal file
View File

@ -0,0 +1,60 @@
@page getting-started Getting Started
@tableofcontents
# Install FTXUI
To set up FTXUI in your project, follow the [installation guide](installation.html), which provides instructions for multiple build systems and package managers.
# Minimal Example
Save the following code as `main.cpp`:
```cpp
#include <ftxui/dom/elements.hpp>
#include <ftxui/screen/screen.hpp>
#include <iostream>
int main() {
using namespace ftxui;
Element document = hbox({
text("left") | border,
text("middle") | border | flex,
text("right") | border,
});
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
screen.Print();
}
```
Build and run it using your preferred build system.
If unsure, start with one of the methods described in the [installation page](installation.html).
Expected output:
```
┌────┐┌────────────────────────────────────┐┌─────┐
│left││middle ││right│
└────┘└────────────────────────────────────┘└─────┘
```
# Starter Template
For a complete working project, clone the official starter repository:
```bash
git clone https://github.com/ArthurSonzogni/ftxui-starter
```
Follow the build instructions in the `README.md` of that repository.
<div class="section_buttons">
| Previous | Next |
|:----------------------------------|------------------------:|
| [Introduction](index.html) | [Modules](modules.html) |
</div>

84
doc/header.html Normal file
View File

@ -0,0 +1,84 @@
<!-- HTML header for doxygen 1.9.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="$langISO">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN FULL_SIDEBAR-->
<script type="text/javascript">var page_layout=1;</script>
<!--END FULL_SIDEBAR-->
<!--END DISABLE_INDEX-->
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
<script type="text/javascript" src="$relpath^doxygen-awesome-fragment-copy-button.js"></script>
<script type="text/javascript" src="$relpath^doxygen-awesome-paragraph-link.js"></script>
<script type="text/javascript" src="$relpath^doxygen-awesome-interactive-toc.js"></script>
<script type="text/javascript" src="$relpath^doxygen-awesome-tabs.js"></script>
<script type="text/javascript">
DoxygenAwesomeFragmentCopyButton.init()
DoxygenAwesomeParagraphLink.init()
DoxygenAwesomeInteractiveToc.init()
DoxygenAwesomeTabs.init()
</script>
$treeview
$search
$mathjax
$darkmode
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
</head>
<body>
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN FULL_SIDEBAR-->
<div id="side-nav" class="ui-resizable side-nav-resizable"><!-- do not remove this div, it is closed by doxygen! -->
<!--END FULL_SIDEBAR-->
<!--END DISABLE_INDEX-->
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<!--BEGIN TITLEAREA-->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<!--BEGIN PROJECT_LOGO-->
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
<!--END PROJECT_LOGO-->
<!--BEGIN PROJECT_NAME-->
<td id="projectalign">
<div id="projectname">$projectname<!--BEGIN PROJECT_NUMBER--><span id="projectnumber">&#160;$projectnumber</span><!--END PROJECT_NUMBER-->
</div>
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
</td>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME-->
<!--BEGIN PROJECT_BRIEF-->
<td>
<div id="projectbrief">$projectbrief</div>
</td>
<!--END PROJECT_BRIEF-->
<!--END !PROJECT_NAME-->
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN SEARCHENGINE-->
<!--BEGIN !FULL_SIDEBAR-->
<td>$searchbox</td>
<!--END !FULL_SIDEBAR-->
<!--END SEARCHENGINE-->
<!--END DISABLE_INDEX-->
</tr>
<!--BEGIN SEARCHENGINE-->
<!--BEGIN FULL_SIDEBAR-->
<tr><td colspan="2">$searchbox</td></tr>
<!--END FULL_SIDEBAR-->
<!--END SEARCHENGINE-->
</tbody>
</table>
</div>
<!--END TITLEAREA-->
<!-- end header part -->

39
doc/installation.md Normal file
View File

@ -0,0 +1,39 @@
@page installation Installation
@tableofcontents
## Overview
FTXUI can be integrated into your project using several build systems and package managers.
This page serves as an entry point for the available integration methods.
## Supported Methods
- @subpage installation_cmake
- @subpage installation_bazel
- @subpage installation_vcpkg
- @subpage installation_conan
- @subpage installation_manual
## Next Steps
Once FTXUI is installed:
- [Getting Started](getting-started.html): Write and run your first program
- [Examples](examples.html): See what FTXUI can do
- Modules:
- [DOM](module-dom.html)
- [Component](module-component.html)
- [Screen](module-screen.html)
## Contributions
If you use another build system or package manager, feel free to contribute a guide.
You can also open a feature request on the [GitHub issue tracker](https://github.com/ArthurSonzogni/FTXUI/issues).
<div class="section_buttons">
| Previous |
|:------------------|
| [Getting Started](getting-started.html) |
</div>

38
doc/installation_bazel.md Normal file
View File

@ -0,0 +1,38 @@
@page installation_bazel Bazel
FTXUI can be integrated into your project using [Bazel](https://bazel.build)
with Bzlmod (Bazel modules).
The library is registered in the [Bazel Central Registry](https://registry.bazel.build/modules/ftxui)
**MODULE.bazel**
```starlark
bazel_dep(name = "ftxui", version = "6.1.9")
```
**BUILD.bazel**
```starlark
cc_binary(
name = "main",
srcs = ["main.cpp"],
deps = [
"@ftxui//:component",
"@ftxui//:dom",
"@ftxui//:screen",
],
)
```
## Starter Project
You can use the official Bazel starter project for a minimal working setup:
- [ftxui-bazel (starter)](https://github.com/ArthurSonzogni/ftxui-bazel)
<div class="section_buttons">
| Previous |
|:------------------|
| [Getting Started](getting-started.html) |
</div>

111
doc/installation_cmake.md Normal file
View File

@ -0,0 +1,111 @@
@page installation_cmake CMake
@tableofcontents
This page explains how to depend on FTXUI using [CMake](https://cmake.org).
# Methods of Integration
## Using FetchContent
This approach downloads FTXUI at configure time and doesn't require a system-wide install.
```fortran
include(FetchContent)
FetchContent_Declare(ftxui
GIT_REPOSITORY https://github.com/ArthurSonzogni/FTXUI
GIT_TAG v6.1.9 # Replace with a version, tag, or commit hash
)
FetchContent_MakeAvailable(ftxui)
add_executable(main main.cpp)
target_link_libraries(main
PRIVATE ftxui::screen
PRIVATE ftxui::dom
PRIVATE ftxui::component
)
```
This ensures reproducible builds and easy dependency management.
## Using find_package
If FTXUI is installed system-wide or via a package manager (e.g. vcpkg or Conan), you can use:
```fortran
fortranind_package(ftxui REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main
PRIVATE ftxui::screen
PRIVATE ftxui::dom
PRIVATE ftxui::component
)
```
Make sure the package is visible in your `CMAKE_PREFIX_PATH`.
## Using git submodule
You can also add FTXUI as a [Git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules), keeping it as part of your repository:
```fortran
git submodule add https://github.com/ArthurSonzogni/FTXUI external/ftxui
git submodule update --init --recursive
```
When cloning a repository that already includes FTXUI as a submodule, make sure to fetch submodules with:
```
git clone --recurse-submodules <your-repo>
# Or, if already cloned:
git submodule update --init --recursive
```
Then in your `CMakeLists.txt`:
```fortran
add_subdirectory(external/ftxui)
add_executable(main main.cpp)
target_link_libraries(main
PRIVATE ftxui::screen
PRIVATE ftxui::dom
PRIVATE ftxui::component
)
```
This approach works well if you want to vendor FTXUI in your own repository.
# Optional CMake Flags
FTXUI supports the following CMake options:
| Option | Description | Default |
| --------------------------------- | ----------------------------- | ------- |
| FTXUI_BUILD_EXAMPLES | Build bundled examples | OFF |
| FTXUI_BUILD_DOCS | Build the documentation | OFF |
| FTXUI_BUILD_TESTS | Enable tests | OFF |
| FTXUI_ENABLE_INSTALL | Generate install targets | ON |
| FTXUI_MICROSOFT_TERMINAL_FALLBACK | Improve Windows compatibility | ON/OFF |
To enable an option:
```
cmake -DFTXUI_BUILD_EXAMPLES=ON ..
```
# Verifying Integration
To confirm the setup is working, build and run a minimal example.
If you need a complete template, see: [ftxui-starter](https://github.com/ArthurSonzogni/ftxui-starter)
<div class="section_buttons">
| Previous |
|:------------------|
| [Getting Started](getting-started.html) |
</div>

20
doc/installation_conan.md Normal file
View File

@ -0,0 +1,20 @@
@page installation_conan Conan
@tableofcontents
## Conan Package
Unofficial support for FTXUI exists on Conan Center:
- https://conan.io/center/recipes/ftxui
## TODO
This page is incomplete. If you use FTXUI with Conan and can provide a minimal working setup, feel free to contribute.
<div class="section_buttons">
| Previous |
|:------------------|
| [Getting Started](getting-started.html) |
</div>

20
doc/installation_vcpkg.md Normal file
View File

@ -0,0 +1,20 @@
@page installation_vcpkg Vcpkg
@tableofcontents
## Vcpkg Package
FTXUI is available in the Vcpkg registry:
- https://vcpkg.link/ports/ftxui
## TODO
This page is incomplete. If you use FTXUI with Vcpkg, please help improve this page by contributing working configuration examples.
<div class="section_buttons">
| Previous |
|:------------------|
| [Getting Started](getting-started.html) |
</div>

75
doc/introduction.md Normal file
View File

@ -0,0 +1,75 @@
@mainpage Introduction
@tableofcontents
<img src="https://github.com/ArthurSonzogni/FTXUI/assets/4759106/6925b6da-0a7e-49d9-883c-c890e1f36007" alt="Demo image"></img>
**FTXUI** is simple cross-platform C++ library for terminal based user interfaces!
# Feature
* Functional style. Inspired by
[1](https://hackernoon.com/building-reactive-terminal-interfaces-in-c-d392ce34e649?gi=d9fb9ce35901)
and [React](https://reactjs.org/)
* No dependencies
* **Cross platform**.
* Simple and elegant syntax (in my opinion)
* Keyboard & mouse navigation.
* Support for [UTF8](https://en.wikipedia.org/wiki/UTF-8) and [fullwidth chars](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms) (→ 测试)
* Support for animations. [Demo 1](https://arthursonzogni.github.io/FTXUI/examples/?file=component/menu_underline_animated_gallery), [Demo 2](https://arthursonzogni.github.io/FTXUI/examples/?file=component/button_style)
* Support for drawing. [Demo](https://arthursonzogni.github.io/FTXUI/examples/?file=component/canvas_animated)
* Learn by [examples](#documentation), and [tutorials](#documentation)
* Multiple build system and packages:
* Good practices: documentation, tests, fuzzers, performance tests, automated CI, automated packaging, etc...
# Example
```cpp
#include <ftxui/dom/elements.hpp>
#include <ftxui/screen/screen.hpp>
#include <iostream>
int main() {
using namespace ftxui;
// Create a simple document with three text elements.
Element document = hbox({
text("left") | border,
text("middle") | border | flex,
text("right") | border,
});
// Create a screen with full width and height fitting the document.
auto screen = Screen::Create(
Dimension::Full(), // Width
Dimension::Fit(document) // Height
);
// Render the document onto the screen.
Render(screen, document);
// Print the screen to the console.
screen.Print();
}
```
Expected output:
```
┌────┐┌────────────────────────────────────┐┌─────┐
│left││middle ││right│
└────┘└────────────────────────────────────┘└─────┘
```
# Supported Platforms
- Linux
- MacOS
- Windows
- WebAssembly
<div class="section_buttons">
| Next |
|--------------------------------------:|
| [Getting Started](getting-started.html) |
</div>

View File

@ -1,915 +0,0 @@
\mainpage
# Introduction {#introduction}
Welcome to the FTXUI documentation!
This is a brief tutorial. You are also encouraged to self-learn by reading the
[examples](./examples.html).
@tableofcontents
**Short example**
To build a single frame, you need create an `ftxui::Element`, and display it on
a `ftxui::Screen`.
**main.cpp**
```cpp
#include <ftxui/dom/elements.hpp>
#include <ftxui/screen/screen.hpp>
#include <iostream>
int main(void) {
using namespace ftxui;
// Define the document
Element document =
hbox({
text("left") | border,
text("middle") | border | flex,
text("right") | border,
});
auto screen = Screen::Create(
Dimension::Full(), // Width
Dimension::Fit(document) // Height
);
Render(screen, document);
screen.Print();
return EXIT_SUCCESS;
}
```
**output**
```bash
┌────┐┌────────────────────────────────────┐┌─────┐
│left││middle ││right│
└────┘└────────────────────────────────────┘└─────┘
```
## Configure {#configure}
### Using CMake and find_package {#build-cmake-find-package}
Assuming FTXUI is available or installed on the system.
**CMakeLists.txt**
```cmake
cmake_minimum_required (VERSION 3.11)
find_package(ftxui 5 REQUIRED)
project(ftxui-starter LANGUAGES CXX VERSION 1.0.0)
add_executable(ftxui-starter src/main.cpp)
target_link_libraries(ftxui-starter
PRIVATE ftxui::screen
PRIVATE ftxui::dom
PRIVATE ftxui::component # Not needed for this example.
)
```
### Using CMake and FetchContent {#build-cmake}
If you want to fetch FTXUI using cmake:
**CMakeLists.txt**
```cmake
cmake_minimum_required (VERSION 3.11)
include(FetchContent)
set(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)
FetchContent_Declare(ftxui
GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui
GIT_TAG 6.1.9
)
FetchContent_MakeAvailable(ftxui)
project(ftxui-starter LANGUAGES CXX VERSION 1.0.0)
add_executable(ftxui-starter src/main.cpp)
target_link_libraries(ftxui-starter
PRIVATE ftxui::screen
PRIVATE ftxui::dom
PRIVATE ftxui::component # Not needed for this example.
)
```
### Using Bazel {#build-bazel}
See [ftxui module](https://registry.bazel.build/modules/ftxui) from the Bazel
Central Registry.
See also this [starter](https://github.com/ArthurSonzogni/ftxui-bazel) project.
**Module.bazel**
```starlark
bazel_dep(
name = "ftxui",
version = "6.1.9",
)
```
**BUILD.bazel**
```starlark
cc_binary(
name = "main",
srcs = ["main.cpp"],
deps = [
# Choose one of the following:
"@ftxui//:dom",
"@ftxui//:screen",
"@ftxui//:component",
],
)
```
# List of modules. {#modules}
The project is comprised of 3 modules:
1. **ftxui/screen** defines a `ftxui::Screen`, a grid of `ftxui::Pixel`.
2. **ftxui/dom** is the main module. It defines a hierarchical set of
`ftxui::Element`. An element draws something on the `ftxui::Screen`. It is
responsive to the size of its container.
3. **ftxui/component** The module is required if your program needs to respond
to user input. It defines a set of `ftxui::Component`. These components can
be utilized to navigate using the arrow keys *and/or* cursor. There are
several builtin widgets like checkbox/inputbox/etc to interact with. You can
combine them, or even define your own custom components.
# screen {#module-screen}
This is the visual element of the program. It defines a `ftxui::Screen`, which
is a grid of `ftxui::Pixel`. A Pixel represents a Unicode character and its
associated style (bold, italic, colors, etc.). The screen can be printed as a
string using `ftxui::Screen::ToString()`. The following example highlights this
process:
```cpp
#include <ftxui/screen/screen.hpp>
#include <iostream>
int main(void) {
using namespace ftxui;
auto screen = Screen::Create(Dimension::Fixed(32), Dimension::Fixed(10));
auto& pixel = screen.PixelAt(9,9);
pixel.character = U'A';
pixel.bold = true;
pixel.foreground_color = Color::Blue;
std::cout << screen.ToString();
return EXIT_SUCCESS;
}
```
# dom {#module-dom}
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:
**Example:**
```cpp
// 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 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")
```
![ezgif com-gif-maker (4)](https://user-images.githubusercontent.com/4759106/147251370-983a06e7-6f41-4113-92b8-942f43d34d06.gif)
For a more detailed example refer to [detailed example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2paragraph_8cpp-example.html). Paragraph also includes a number of other variants as shown below:
```cpp
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│
└───────────┘
```
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
Element border(Element);
Element borderLight(Element);
Element borderHeavy(Element);
Element borderDouble(Element);
Element borderRounded(Element);
Element borderEmpty(Element);
Decorator borderStyled(BorderStyle);
Decorator borderWith(Pixel);
```
## 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
Element separator(void);
Element separatorLight();
Element separatorHeavy();
Element separatorDouble();
Element separatorEmpty();
Element separatorStyled(BorderStyle);
Element separator(Pixel);
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}
It constitutes a gauge. It can be used to represent a progress bar.
Code:
```cpp
border(gauge(0.5))
```
Teminal output:
```bash
┌────────────────────────────────────────────────────────────────────────────┐
│██████████████████████████████████████ │
└────────────────────────────────────────────────────────────────────────────┘
```
Gauges can be displayed in many orientations as shown below:
```cpp
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](https://arthursonzogni.github.io/FTXUI/examples_2dom_2color_gallery_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147248595-04c7245a-5b85-4544-809d-a5984fc6f9e7.png)
### 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](https://arthursonzogni.github.io/FTXUI/examples/?file=component/linear_gradient_gallery).
## 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](https://arthursonzogni.github.io/FTXUI/examples_2dom_2style_gallery_8cpp-example.html)
![image](https://user-images.githubusercontent.com/4759106/147244118-380bf834-9e33-40df-9ff0-07c10f2598ef.png)
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](https://arthursonzogni.github.io/FTXUI/examples_2dom_2vbox_hbox_8cpp-example.html) using `ftxui::hbox`, `ftxui::vbox` and `ftxui::filler`.
![image](https://user-images.githubusercontent.com/4759106/147242524-7103b5d9-1a92-4e2d-ac70-b3d6740061e3.png)
[Example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2gridbox_8cpp-example.htmlp)
using `ftxui::gridbox`:
![image](https://user-images.githubusercontent.com/4759106/147242972-0db1f2e9-0790-496f-86e6-ed2c604f7a73.png)
[Example](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/dom/hflow.cpp)
using flexbox:
![image](https://user-images.githubusercontent.com/4759106/147243064-780ac7cc-605b-475f-94b8-cf7c4aed03a5.png)
Checkout this
[example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2hflow_8cpp-example.html)
and the associated
[demo](https://arthursonzogni.github.io/FTXUI/examples/?file=component/flexbox).
Element can also become flexible using the 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.
[Code example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2table_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147250766-77d8ec9e-cf2b-486d-9866-1fd9f1bd2e6b.png)
## Canvas {#dom-canvas}
See the API [<ftxui/dom/canvas.hpp>](./canvas_8hpp_source.html)
```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](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/dom/canvas.cpp):
![image](https://user-images.githubusercontent.com/4759106/147245843-76cc62fb-ccb4-421b-aacf-939f9afb42fe.png)
Complex [example](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/component/canvas_animated.cpp):
![ezgif com-gif-maker (3)](https://user-images.githubusercontent.com/4759106/147250538-783a8246-98e0-4a25-b032-3bd3710549d1.gif)
# component {#module-component}
The `ftxui::component` module defines the logic that produces interactive
components that respond to user events (keyboard, mouse, etc.).
A `ftxui::ScreenInteractive` defines a main loop that renders a component.
A `ftxui::Component` is a shared pointer to a `ftxui::ComponentBase`. The latter defines:
- `ftxui::ComponentBase::Render()`: How to render the interface.
- `ftxui::ComponentBase::OnEvent()`: How to react to events.
- `ftxui::ComponentBase::Add()`: Construct a parent/child relationship
between two components. The tree of component is used to define how to
navigate using the keyboard.
`ftxui::Element` are used to render a single frame.
`ftxui::Component` are used to render dynamic user interface, producing multiple
frame, and updating its state on events.
[Gallery](https://arthursonzogni.github.io/FTXUI/examples_2component_2gallery_8cpp-example.html) of multiple components. ([demo](https://arthursonzogni.github.io/FTXUI/examples/?file=component/gallery))
![image](https://user-images.githubusercontent.com/4759106/147247330-b60beb9f-e665-48b4-81c0-4b01ee95bc66.png)
All predefined components are available in
["ftxui/dom/component.hpp"](./component_8hpp.html)
\include ftxui/component/component.hpp
## Input {#component-input}
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2input_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147247671-f1d6f606-1845-4e94-a4a0-d4273e9ae6bd.png)
Produced by: `ftxui::Input()` from "ftxui/component/component.hpp"
@htmlonly
<script id="asciicast-223719" src="https://asciinema.org/a/223719.js" async></script>
@endhtmlonly
### Filtered input
On can filter out the characters received by the input component, using
`ftxui::CatchEvent`.
```cpp
std::string phone_number;
Component input = Input(&phone_number, "phone number");
// Filter out non-digit characters.
input |= CatchEvent([&](Event event) {
return event.is_character() && !std::isdigit(event.character()[0]);
});
// Filter out characters past the 10th one.
input |= CatchEvent([&](Event event) {
return event.is_character() && phone_number.size() >= 10;
});
```
## Menu {#component-menu}
Defines a menu object. It contains a list of entries, one of them is selected.
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2menu_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147247822-0035fd6f-bb13-4b3a-b057-77eb9291582f.png)
Produced by: `ftxui::Menu()` from "ftxui/component/component.hpp"
@htmlonly
<script id="asciicast-223720" src="https://asciinema.org/a/223720.js" async></script>
@endhtmlonly
## Toggle {#component-toggle}
A special kind of menu. The entries are displayed horizontally.
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2toggle_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147249383-e2201cf1-b7b8-4a5a-916f-d761e3e7ae40.png)
Produced by: `ftxui::Toggle()` from "ftxui/component/component.hpp"
@htmlonly
<script id="asciicast-223722" src="https://asciinema.org/a/223722.js" async></script>
@endhtmlonly
## CheckBox {#component-checkbox}
This component defines a checkbox. It is a single entry that can be turned
on/off.
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2checkbox_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147246646-b86926a9-1ef9-4efb-af98-48a9b62acd81.png)
Produced by: `ftxui::Checkbox()` from "ftxui/component/component.hpp"
@htmlonly
<script id="asciicast-223724" src="https://asciinema.org/a/223724.js" async></script>
@endhtmlonly
## RadioBox {#component-radiobox}
A radiobutton component. This is a list of entries, where one can be turned on.
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2radiobox_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147246401-809d14a5-6621-4e36-8dd9-a2d75ef2a94e.png)
Produced by: `ftxui::Radiobox()` from "ftxui/component/component.hpp"
@htmlonly
<script id="asciicast-223725" src="https://asciinema.org/a/223725.js" async></script>
@endhtmlonly
## Dropdown {#component-dropdown}
A drop down menu is a component that when checked display a list of element for
the user to select one.
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2dropdown_8cpp-example.html):
![youtube-video-gif (3)](https://user-images.githubusercontent.com/4759106/147246982-1e821751-531c-4e1f-bc37-2fa290e143cd.gif)
Produced by: `ftxui::Dropdown()` from "ftxui/component/component.hpp"
## Slider {#component-slider}
Represents a slider object that consists of a range with binned intermediate
intervals. It can be created by `ftxui::Slider()`.
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2slider_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147249265-7e2cad75-082c-436e-affe-44a550c480ab.png)
Produced by: `ftxui::Slider()` from "ftxui/component/component.hpp"
## Renderer {#component-renderer}
Produced by: `ftxui::Renderer()` from \ref ftxui/component/component.hpp. This
component decorate another one by using a different function to render an
interface.
Example:
```cpp
auto inner = [...]
auto renderer = Renderer(inner, [&] {
return inner->Render() | border
});
```
`ftxui::Renderer` also supports the component decorator pattern:
```cpp
auto component = [...]
component = component
| Renderer([](Element e) { return e | border))
| Renderer(bold)
```
As a short hand, you can also compose a component with an element decorator:
```cpp
auto component = [...]
component = component | border | bold;
```
## CatchEvent {#component-catchevent}
Produced by: `ftxui::CatchEvent()` from \ref ftxui/component/component.hpp.
This component decorate others, catching events before the underlying component.
Examples:
```cpp
auto screen = ScreenInteractive::TerminalOutput();
auto renderer = Renderer([] {
return text("My interface");
});
auto component = CatchEvent(renderer, [&](Event event) {
if (event == Event::Character('q')) {
screen.ExitLoopClosure()();
return true;
}
return false;
});
screen.Loop(component);
```
The `ftxui::CatchEvent` can also be used as a decorator:
```cpp
component = component
| CatchEvent(handler_1)
| CatchEvent(handler_2)
| CatchEvent(handler_3)
;
```
## Collapsible {#component-collapsible}
Useful for visual elements whose visibility can be toggle on/off by the user.
Essentially, this the combination of the `ftxui::Checkbox()` and
`ftxui::Maybe()` components.
```cpp
auto collabsible = Collapsible("Show more", inner_element);
```
## Maybe {#component-maybe}
Produced by: `ftxui::Maybe()` from \ref ftxui/component/component.hpp.
This component can be utilized to show/hide any other component via a boolean or
a predicate.
Example with a boolean:
```cpp
bool show = true;
auto component = Renderer([]{ return "Hello World!"; });
auto maybe_component = Maybe(component, &show)
```
Example with a predicate:
```cpp
auto component = Renderer([]{ return "Hello World!"; });
auto maybe_component = Maybe(component, [&] { return time > 10; })
```
As usual, `ftxui::Maybe` can also be used as a decorator:
```cpp
component = component
| Maybe(&a_boolean)
| Maybe([&] { return time > 10; })
;
```
## Container {#component-container}
### Horizontal {#component-horizontal}
Produced by: `ftxui::Container::Horizontal()` from
"ftxui/component/component.hpp". It displays a list of components horizontally
and handle keyboard/mouse navigation.
### Vertical {#component-vertical}
Produced by: `ftxui::Container::Vertical()` from
"ftxui/component/component.hpp". It displays a list of components vertically
and handles keyboard/mouse navigation.
### Tab {#component-tab}
Produced by: `ftxui::Container::Tab()` from
"ftxui/component/component.hpp". It take a list of component and display only
one of them. This is useful for implementing a tab bar.
[Vertical](https://arthursonzogni.github.io/FTXUI/examples_2component_2tab_vertical_8cpp-example.html):
![ezgif com-gif-maker (1)](https://user-images.githubusercontent.com/4759106/147250144-22ff044a-4773-4ff7-a49c-12ba4034acb4.gif)
[Horizontal](https://arthursonzogni.github.io/FTXUI/examples_2component_2tab_horizontal_8cpp-example.html):
![ezgif com-gif-maker (2)](https://user-images.githubusercontent.com/4759106/147250217-fe447e0f-7a99-4e08-948a-995087d9b40e.gif)
## ResizableSplit {#component-resizable-split}
It defines a horizontal or vertical separation between two children components.
The position of the split is variable and controllable using the mouse.
There are four possible splits:
- `ftxui::ResizableSplitLeft()`
- `ftxui::ResizableSplitRight()`
- `ftxui::ResizableSplitTop()`
- `ftxui::ResizableSplitBottom()`
from "ftxui/component/component.hpp"
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2resizable_split_8cpp-example.html):
![ezgif com-gif-maker](https://user-images.githubusercontent.com/4759106/147248372-c55512fe-9b96-4b08-a1df-d05cf2cae431.gif)
@htmlonly
<script id="asciicast-tprMH2EdkUoMb7D2YxgMGgpzx" src="https://asciinema.org/a/tprMH2EdkUoMb7D2YxgMGgpzx.js" async></script>
@endhtmlonly
## Force a frame redraw. {#component-force-redraw}
Typically, `ftxui::ScreenInteractive::Loop()` is responsible for drawing a new
frame whenever a new group of events (e.g keyboard, mouse, window resize, etc.)
has been processed. However, you might want to react to arbitrary events that
are unknown to FTXUI. To accomplish this, you must post events using
`ftxui::ScreenInteractive::PostEvent` (**this is thread safe**) via a thread.
You will have to post the event `ftxui::Event::Custom`.
Example:
```cpp
screen->PostEvent(Event::Custom);
```

306
doc/module-component.md Normal file
View File

@ -0,0 +1,306 @@
@page module-component Module component
@tableofcontents
The `ftxui::component` module defines the logic that produces interactive
components that respond to user events (keyboard, mouse, etc.).
The @subpage module-component-examples section provides a collection of examples.
A `ftxui::ScreenInteractive` defines a main loop that renders a component.
A `ftxui::Component` is a shared pointer to a `ftxui::ComponentBase`. The latter defines:
- `ftxui::ComponentBase::Render()`: How to render the interface.
- `ftxui::ComponentBase::OnEvent()`: How to react to events.
- `ftxui::ComponentBase::Add()`: Construct a parent/child relationship
between two components. The tree of component is used to define how to
navigate using the keyboard.
`ftxui::Element` are used to render a single frame.
`ftxui::Component` are used to render dynamic user interface, producing multiple
frame, and updating its state on events.
[Gallery](https://arthursonzogni.github.io/FTXUI/examples_2component_2gallery_8cpp-example.html) of multiple components. ([demo](https://arthursonzogni.github.io/FTXUI/examples/?file=component/gallery))
![image](https://user-images.githubusercontent.com/4759106/147247330-b60beb9f-e665-48b4-81c0-4b01ee95bc66.png)
All predefined components are available in
["ftxui/dom/component.hpp"](./component_8hpp.html)
\include{strip ftxui/component/component.hpp
## Input {#component-input}
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2input_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147247671-f1d6f606-1845-4e94-a4a0-d4273e9ae6bd.png)
Produced by: `ftxui::Input()` from "ftxui/component/component.hpp"
@htmlonly
<script id="asciicast-223719" src="https://asciinema.org/a/223719.js" async></script>
@endhtmlonly
### Filtered input
On can filter out the characters received by the input component, using
`ftxui::CatchEvent`.
```cpp
std::string phone_number;
Component input = Input(&phone_number, "phone number");
// Filter out non-digit characters.
input |= CatchEvent([&](Event event) {
return event.is_character() && !std::isdigit(event.character()[0]);
});
// Filter out characters past the 10th one.
input |= CatchEvent([&](Event event) {
return event.is_character() && phone_number.size() >= 10;
});
```
## Menu {#component-menu}
Defines a menu object. It contains a list of entries, one of them is selected.
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2menu_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147247822-0035fd6f-bb13-4b3a-b057-77eb9291582f.png)
Produced by: `ftxui::Menu()` from "ftxui/component/component.hpp"
@htmlonly
<script id="asciicast-223720" src="https://asciinema.org/a/223720.js" async></script>
@endhtmlonly
## Toggle {#component-toggle}
A special kind of menu. The entries are displayed horizontally.
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2toggle_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147249383-e2201cf1-b7b8-4a5a-916f-d761e3e7ae40.png)
Produced by: `ftxui::Toggle()` from "ftxui/component/component.hpp"
@htmlonly
<script id="asciicast-223722" src="https://asciinema.org/a/223722.js" async></script>
@endhtmlonly
## CheckBox {#component-checkbox}
This component defines a checkbox. It is a single entry that can be turned
on/off.
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2checkbox_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147246646-b86926a9-1ef9-4efb-af98-48a9b62acd81.png)
Produced by: `ftxui::Checkbox()` from "ftxui/component/component.hpp"
@htmlonly
<script id="asciicast-223724" src="https://asciinema.org/a/223724.js" async></script>
@endhtmlonly
## RadioBox {#component-radiobox}
A radiobutton component. This is a list of entries, where one can be turned on.
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2radiobox_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147246401-809d14a5-6621-4e36-8dd9-a2d75ef2a94e.png)
Produced by: `ftxui::Radiobox()` from "ftxui/component/component.hpp"
@htmlonly
<script id="asciicast-223725" src="https://asciinema.org/a/223725.js" async></script>
@endhtmlonly
## Dropdown {#component-dropdown}
A drop down menu is a component that when checked display a list of element for
the user to select one.
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2dropdown_8cpp-example.html):
![youtube-video-gif (3)](https://user-images.githubusercontent.com/4759106/147246982-1e821751-531c-4e1f-bc37-2fa290e143cd.gif)
Produced by: `ftxui::Dropdown()` from "ftxui/component/component.hpp"
## Slider {#component-slider}
Represents a slider object that consists of a range with binned intermediate
intervals. It can be created by `ftxui::Slider()`.
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2slider_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147249265-7e2cad75-082c-436e-affe-44a550c480ab.png)
Produced by: `ftxui::Slider()` from "ftxui/component/component.hpp"
## Renderer {#component-renderer}
Produced by: `ftxui::Renderer()` from \ref ftxui/component/component.hpp. This
component decorate another one by using a different function to render an
interface.
Example:
```cpp
auto inner = [...]
auto renderer = Renderer(inner, [&] {
return inner->Render() | border
});
```
`ftxui::Renderer` also supports the component decorator pattern:
```cpp
auto component = [...]
component = component
| Renderer([](Element e) { return e | border))
| Renderer(bold)
```
As a short hand, you can also compose a component with an element decorator:
```cpp
auto component = [...]
component = component | border | bold;
```
## CatchEvent {#component-catchevent}
Produced by: `ftxui::CatchEvent()` from \ref ftxui/component/component.hpp.
This component decorate others, catching events before the underlying component.
Examples:
```cpp
auto screen = ScreenInteractive::TerminalOutput();
auto renderer = Renderer([] {
return text("My interface");
});
auto component = CatchEvent(renderer, [&](Event event) {
if (event == Event::Character('q')) {
screen.ExitLoopClosure()();
return true;
}
return false;
});
screen.Loop(component);
```
The `ftxui::CatchEvent` can also be used as a decorator:
```cpp
component = component
| CatchEvent(handler_1)
| CatchEvent(handler_2)
| CatchEvent(handler_3)
;
```
## Collapsible {#component-collapsible}
Useful for visual elements whose visibility can be toggle on/off by the user.
Essentially, this the combination of the `ftxui::Checkbox()` and
`ftxui::Maybe()` components.
```cpp
auto collabsible = Collapsible("Show more", inner_element);
```
## Maybe {#component-maybe}
Produced by: `ftxui::Maybe()` from \ref ftxui/component/component.hpp.
This component can be utilized to show/hide any other component via a boolean or
a predicate.
Example with a boolean:
```cpp
bool show = true;
auto component = Renderer([]{ return "Hello World!"; });
auto maybe_component = Maybe(component, &show)
```
Example with a predicate:
```cpp
auto component = Renderer([]{ return "Hello World!"; });
auto maybe_component = Maybe(component, [&] { return time > 10; })
```
As usual, `ftxui::Maybe` can also be used as a decorator:
```cpp
component = component
| Maybe(&a_boolean)
| Maybe([&] { return time > 10; })
;
```
## Container {#component-container}
### Horizontal {#component-horizontal}
Produced by: `ftxui::Container::Horizontal()` from
"ftxui/component/component.hpp". It displays a list of components horizontally
and handle keyboard/mouse navigation.
### Vertical {#component-vertical}
Produced by: `ftxui::Container::Vertical()` from
"ftxui/component/component.hpp". It displays a list of components vertically
and handles keyboard/mouse navigation.
### Tab {#component-tab}
Produced by: `ftxui::Container::Tab()` from
"ftxui/component/component.hpp". It take a list of component and display only
one of them. This is useful for implementing a tab bar.
[Vertical](https://arthursonzogni.github.io/FTXUI/examples_2component_2tab_vertical_8cpp-example.html):
![ezgif com-gif-maker (1)](https://user-images.githubusercontent.com/4759106/147250144-22ff044a-4773-4ff7-a49c-12ba4034acb4.gif)
[Horizontal](https://arthursonzogni.github.io/FTXUI/examples_2component_2tab_horizontal_8cpp-example.html):
![ezgif com-gif-maker (2)](https://user-images.githubusercontent.com/4759106/147250217-fe447e0f-7a99-4e08-948a-995087d9b40e.gif)
## ResizableSplit {#component-resizable-split}
It defines a horizontal or vertical separation between two children components.
The position of the split is variable and controllable using the mouse.
There are four possible splits:
- `ftxui::ResizableSplitLeft()`
- `ftxui::ResizableSplitRight()`
- `ftxui::ResizableSplitTop()`
- `ftxui::ResizableSplitBottom()`
from "ftxui/component/component.hpp"
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2resizable_split_8cpp-example.html):
![ezgif com-gif-maker](https://user-images.githubusercontent.com/4759106/147248372-c55512fe-9b96-4b08-a1df-d05cf2cae431.gif)
@htmlonly
<script id="asciicast-tprMH2EdkUoMb7D2YxgMGgpzx" src="https://asciinema.org/a/tprMH2EdkUoMb7D2YxgMGgpzx.js" async></script>
@endhtmlonly
## Force a frame redraw. {#component-force-redraw}
Typically, `ftxui::ScreenInteractive::Loop()` is responsible for drawing a new
frame whenever a new group of events (e.g keyboard, mouse, window resize, etc.)
has been processed. However, you might want to react to arbitrary events that
are unknown to FTXUI. To accomplish this, you must post events using
`ftxui::ScreenInteractive::PostEvent` (**this is thread safe**) via a thread.
You will have to post the event `ftxui::Event::Custom`.
Example:
```cpp
screen->PostEvent(Event::Custom);
```
If you don't need to process a new Event, you can use:
```cpp
screen->RequestAnimationFrame();
```
instead.

468
doc/module-dom.md Normal file
View File

@ -0,0 +1,468 @@
@page module-dom Module 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")
```
![ezgif com-gif-maker (4)](https://user-images.githubusercontent.com/4759106/147251370-983a06e7-6f41-4113-92b8-942f43d34d06.gif)
For a more detailed example refer to [detailed example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2paragraph_8cpp-example.html). 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(Pixel);
}
```
## 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(Pixel);
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))
```
Teminal 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](https://arthursonzogni.github.io/FTXUI/examples_2dom_2color_gallery_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147248595-04c7245a-5b85-4544-809d-a5984fc6f9e7.png)
### 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](https://arthursonzogni.github.io/FTXUI/examples/?file=component/linear_gradient_gallery).
## 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](https://arthursonzogni.github.io/FTXUI/examples_2dom_2style_gallery_8cpp-example.html)
![image](https://user-images.githubusercontent.com/4759106/147244118-380bf834-9e33-40df-9ff0-07c10f2598ef.png)
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](https://arthursonzogni.github.io/FTXUI/examples_2dom_2vbox_hbox_8cpp-example.html) using `ftxui::hbox`, `ftxui::vbox` and `ftxui::filler`.
![image](https://user-images.githubusercontent.com/4759106/147242524-7103b5d9-1a92-4e2d-ac70-b3d6740061e3.png)
[Example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2gridbox_8cpp-example.htmlp)
using `ftxui::gridbox`:
![image](https://user-images.githubusercontent.com/4759106/147242972-0db1f2e9-0790-496f-86e6-ed2c604f7a73.png)
[Example](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/dom/hflow.cpp)
using flexbox:
![image](https://user-images.githubusercontent.com/4759106/147243064-780ac7cc-605b-475f-94b8-cf7c4aed03a5.png)
Checkout this
[example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2hflow_8cpp-example.html)
and the associated
[demo](https://arthursonzogni.github.io/FTXUI/examples/?file=component/flexbox).
Element can also become flexible using the 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.
[Code example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2table_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147250766-77d8ec9e-cf2b-486d-9866-1fd9f1bd2e6b.png)
## Canvas {#dom-canvas}
See the API [<ftxui/dom/canvas.hpp>](./canvas_8hpp_source.html)
```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](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/dom/canvas.cpp):
![image](https://user-images.githubusercontent.com/4759106/147245843-76cc62fb-ccb4-421b-aacf-939f9afb42fe.png)
Complex [example](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/component/canvas_animated.cpp):
![ezgif com-gif-maker (3)](https://user-images.githubusercontent.com/4759106/147250538-783a8246-98e0-4a25-b032-3bd3710549d1.gif)

200
doc/module-screen.md Normal file
View File

@ -0,0 +1,200 @@
@page module-screen Module screen
@tableofcontents
The `ftxui::screen` module is the low-level foundation. It can be used
standalone, but it is primarily designed to be used together by
[ftxui::dom](module-dom.html) and [ftxui::component](module-component.html)
modules.
It provides a @ref ftxui::Screen.
---
# ftxui::Screen
The @ref ftxui::Screen class represents a 2D grid of styled characters that can
be rendered to a terminal.
It provides methods to create a screen, access pixels, and render elements.
You can access the individual cells (@ref ftxui::Pixel) of the screen using
the @ref ftxui::Screen::PixelAt method, which returns a reference
to the pixel at the specified coordinates.
**Example**
```cpp
#include <ftxui/screen/screen.hpp>
#include <ftxui/screen/color.hpp>
void main() {
auto screen = ftxui::Screen::Create(
ftxui::Dimension::Full(), // Use full terminal width
ftxui::Dimension::Fixed(10) // Fixed height of 10 rows
);
// Access a specific pixel at (10, 5)
auto& pixel = screen.PixelAt(10, 5);
// Set properties of the pixel.
pixel.character = U'X';
pixel.foreground_color = ftxui::Color::Red;
pixel.background_color = ftxui::Color::RGB(0, 255, 0);
pixel.bold = true; // Set bold style
screen.Print(); // Print the screen to the terminal
}
```
> [!note]
> If the coordinates are out of bounds, a dummy pixel is returned.
The screen can be printed to the terminal using @ref ftxui::Screen::Print() or
converted to a std::string with @ref ftxui::Screen::ToString().
<div class="tabbed">
- <b class="tab-title">Print()</b>
```cpp
auto screen = ...;
screen.Print();
```
- <b class="tab-title">ToString()</b>
```cpp
auto screen = ...;
std::cout << screen.ToString();
```
</div>
Note that you can reset the cursor position to the top-left corner of the
screen after printing by calling @ref ftxui::Screen::ResetCursorPosition().
**Example**
```cpp
auto screen = ...;
while(true) {
// Drawing operations:
...
// Print the screen to the terminal. Then reset the cursor position and the
// screen content.
std::cout << screen.ToString();
std::cout << screen.ResetCursorPosition(/*clear=*/true);
std::cout << std::flush;
// Sleep for a short duration to control the refresh rate.
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
```
---
# ftxui::Dimension
The @ref ftxui::Dimension utility controls screen sizing:
* `Dimension::Full()` — use full terminal width or height
* `Dimension::Fit(element)` — size to fit the rendered @ref ftxui::Element
* `Dimension::Fixed(n)` — use exactly `n` columns or rows
These values are to be passed to `ftxui::Screen::Create()`.
@ref ftxui::Screen::Create() provides two overloads:
- `Screen::Create(Dimension)` sets both width and height to the same kind of dimension
- `Screen::Create(Dimension width, Dimension height)` allows distinct control per axis
```cpp
auto screen = ftxui::Screen::Create(
ftxui::Dimension::Full(), // width
ftxui::Dimension::Fixed(10) // height
);
```
Once created, render an element and display the result:
```cpp
ftxui::Render(screen, element);
screen.Print();
```
---
# ftxui::Pixel
Each cell in the screen grid is a @ref ftxui::Pixel, which holds:
- Unicode codepoint.
- `character`
- @ref ftxui::Color:
- `foreground_color`
- `background_color`
- Booleans:
- `blink`
- `bold`
- `dim`
- `italic`
- `inverted` (swap foreground and background colors)
- `underlined`
- `underlined_double`
- `strikethrough`
```cpp
auto screen = ftxui::Screen::Create(
ftxui::Dimension::Fixed(5),
ftxui::Dimension::Fixed(5),
);
auto& pixel = screen.PixelAt(3, 3);
pixel.character = U'X';
pixel.bold = true;
pixel.foreground_color = ftxui::Color::Red;
pixel.background_color = ftxui::Color::RGB(0, 255, 0);
screen.Print();
```
> [!note]
> `PixelAt(x, y)` performs bounds checking and returns a reference to the pixel
> at the specified coordinate. If out-of-bounds, a dummy pixel reference is
> returned.
Each cell in the screen is a @ref ftxui::Pixel. You can modify them using:
```cpp
auto& pixel = screen.PixelAt(x, y);
pixel.character = U'X';
pixel.bold = true;
pixel.foreground_color = Color::Red;
```
---
# ftxui::Color
The @ref ftxui::Color class is used to define foreground and background colors for each @ref ftxui::Pixel.
It supports various color spaces and predefined palettes. FTXUI will
dynamically fallback to the closest available color in the terminal if the
requested color is not supported by the terminal.
**Color Spaces**
- **Default**: `ftxui::Color::Default` (terminal's default color)
- **16-color palette** [Demo](https://arthursonzogni.github.io/FTXUI/examples/?file=dom/color_gallery):
- `ftxui::Color::Black`,
- `ftxui::Color::Red`,
- ...
- **256-color palette** [Demo](https://arthursonzogni.github.io/FTXUI/examples/?file=dom/color_palette256):
- `ftxui::Color::Chartreuse1`,
- `ftxui::Color::DarkViolet`,
- ...
- **True color** (24bit) [Demo](https://arthursonzogni.github.io/FTXUI/examples/?file=dom/color_truecolor_HSV:
- `ftxui::Color::RGB(uint8_t red, uint8_t green, uint8_t blue)`
- `ftxui::Color::HSV(uint8_t h, uint8_t s, uint8_t v)`.
> [!note]
> You can query the terminal capability using @ref ftxui::Terminal::ColorSupport();
>
> This can manually be set using @ref ftxui::Terminal::SetColorSupport().

47
doc/module.md Normal file
View File

@ -0,0 +1,47 @@
# Modules {#modules}
FTXUI is organized into three modules, each building upon the previous:
1. @subpage module-screen — low-level rendering
2. @subpage module-dom — layout and composition
3. @subpage module-component — user interaction
---
[ @subpage module-screen ]
Defines:
- **`ftxui::Screen`**: a 2D grid of styled characters.
- **`ftxui::Pixel`**: the unit of rendering.
- Helpers like `ftxui::Color` and `Dimension`.
Use for direct terminal drawing and styling.
---
[ @subpage module-dom ]
Provides:
- **`ftxui::Element`**: a tree structure for layout and UI.
- Composable and responsive elements.
- `Render()` to draw onto a `Screen`.
Ideal for structured, styled UIs.
---
[ @subpage module-component ]
Adds:
- **`ftxui::Component`**: stateful, interactive widgets.
- Built-ins: `Checkbox`, `Input`, `Menu`, `Button`.
- Supports keyboard/cursor input and composition.
Use for interactive apps.
---
Modules can be used independently, or together: `screen → dom → component`.

118
doc/stylesheet.css Normal file
View File

@ -0,0 +1,118 @@
html {
--primary-color: #9ed072; /* green (identifier, strings) */
--primary-dark-color: #f39660; /* orange (functions, tags) */
--primary-light-color: #7fbbb3; /* teal (types, decorators) */
--page-background-color: #2c2e34; /* main background */
--page-foreground-color: #e2e2e3; /* main text */
--page-secondary-foreground-color: #9aa5ce; /* dim text */
--separator-color: #3b3e48;
--side-nav-background: #1a1b26;
--code-background: #2a2e38;
--code-foreground: #e2e2e3;
--tablehead-background: #1f1f28;
--blockquote-background: #3a3e44;
--blockquote-foreground: #d4bfff;
--warning-color: #e0af68;
--warning-color-dark: #ff9e64;
--warning-color-darker: #f7768e;
--bug-color: #f7768e;
--fragment-background: #2c2e34;
--fragment-foreground: #e2e2e3;
--fragment-keyword: #f7768e; /* pink */
--fragment-keywordtype: #7fbbb3; /* teal */
--fragment-keywordflow: #e0af68; /* orange-yellow */
--fragment-token: #9ed072; /* green */
--fragment-comment: #5c6370;
--fragment-link: #7aa2f7; /* blue link */
--fragment-preprocessor: #f39660; /* orange */
--fragment-linenumber-color: #414868;
--fragment-linenumber-background: #2c2e34;
--fragment-linenumber-border: #1a1b26;
}
/* Base style for all sections */
.section.note,
.section.warning,
.section.remark,
.section.attention,
.section.important {
border-left: 4px solid var(--primary-dark-color);
border-radius: 6px;
padding: 0.9em 1.2em;
margin: 1.5em 0;
background-color: #2e303e;
color: var(--page-foreground-color);
font-size: 0.95em;
}
/* Section title */
.section.note dt,
.section.warning dt,
.section.remark dt,
.section.attention dt,
.section.important dt {
font-weight: bold;
display: block;
margin-bottom: 0.35em;
}
/* Section body */
.section.note dd,
.section.warning dd,
.section.remark dd,
.section.attention dd,
.section.important dd {
margin: 0;
}
/* Note - soft cyan */
.section.note {
border-left-color: #7fbbb3;
background-color: #263640;
}
.section.note dt {
color: #7fbbb3;
}
/* Warning - amber */
.section.warning {
border-left-color: #e0af68;
background-color: #3d2f1f;
}
.section.warning dt {
color: #e0af68;
}
/* Tip (Remark) - green */
.section.remark {
border-left-color: #9ed072;
background-color: #2d3a2d;
}
.section.remark dt {
color: #9ed072;
}
/* Caution (Attention) - bold red-orange */
.section.attention {
border-left-color: #f7768e;
background-color: #3d2a2e;
}
.section.attention dt {
color: #f7768e;
}
/* Important - purple */
.section.important {
border-left-color: #ab9df2;
background-color: #2f2a3a;
}
.section.important dt {
color: #ab9df2;
}

View File

@ -17,9 +17,8 @@
namespace ftxui {
/// @brief arguments for |ButtonOption::transform|, |CheckboxOption::transform|,
/// |Radiobox::transform|, |MenuEntryOption::transform|,
/// |MenuOption::transform|.
/// @brief arguments for transform from |ButtonOption|, |CheckboxOption|,
/// |RadioboxOption|, |MenuEntryOption|, |MenuOption|.
struct EntryState {
std::string label; ///< The label to display.
bool state; ///< The state of the button/checkbox/radiobox

View File

@ -28,7 +28,7 @@ namespace ftxui {
///
/// ▼ Show details
/// <details component>
///  ```
/// ```
// NOLINTNEXTLINE
Component Collapsible(ConstStringRef label, Component child, Ref<bool> show) {
class Impl : public ComponentBase {

View File

@ -74,7 +74,7 @@ Event Event::CursorShape(std::string input, int shape) {
/// @brief An custom event whose meaning is defined by the user of the library.
/// @param input An arbitrary sequence of character defined by the developer.
/// @ingroup component.
/// @ingroup component
// static
Event Event::Special(std::string input) {
Event event;

View File

@ -159,7 +159,7 @@ ComponentDecorator Hoverable(bool* hover) {
/// button |= Hoverable(
/// [&]{ on_enter_cnt++; },
/// [&]{ on_leave_cnt++; }
// );
/// );
/// ```
// NOLINTNEXTLINE
ComponentDecorator Hoverable(std::function<void()> on_enter,
@ -182,7 +182,7 @@ ComponentDecorator Hoverable(std::function<void()> on_enter,
/// auto button = Button("exit", screen.ExitLoopClosure());
/// bool hovered = false;
/// auto button_hoverable = Hoverable(button,
// [&](bool hover) { hovered = hover;});
/// [&](bool hover) { hovered = hover;});
/// ```
// NOLINTNEXTLINE
Component Hoverable(Component component, std::function<void(bool)> on_change) {

View File

@ -603,6 +603,7 @@ Component Input(StringRef content, InputOption option) {
/// @brief An input box for editing text.
/// @param content The editable content.
/// @param placeholder The placeholder text.
/// @param option Additional optional parameters.
/// @ingroup component
/// @see InputBase

View File

@ -242,11 +242,11 @@ class Flexbox : public Node {
/// text("element 2"),
/// text("element 3"),
/// }, FlexboxConfig()
// .Set(FlexboxConfig::Direction::Column)
// .Set(FlexboxConfig::Wrap::WrapInversed)
// .SetGapMainAxis(1)
// .SetGapCrossAxis(1)
// )
/// .Set(FlexboxConfig::Direction::Column)
/// .Set(FlexboxConfig::Wrap::WrapInversed)
/// .SetGapMainAxis(1)
/// .SetGapCrossAxis(1)
/// )
/// ```
Element flexbox(Elements children, FlexboxConfig config) {
return std::make_shared<Flexbox>(std::move(children), config);

View File

@ -164,7 +164,7 @@ class Gauge : public Node {
/// @brief Draw a high definition progress bar progressing in specified
/// direction.
/// @param progress The proportion of the area to be filled. Belong to [0,1].
// @param direction Direction of progress bars progression.
/// @param direction Direction of progress bars progression.
/// @ingroup dom
Element gaugeDirection(float progress, Direction direction) {
return std::make_shared<Gauge>(progress, direction);