Compare commits

..

No commits in common. "main" and "v6.1.5" have entirely different histories.
main ... v6.1.5

130 changed files with 2126 additions and 4640 deletions

View File

@ -1,7 +0,0 @@
build --features=layering_check
build --enable_bzlmod
build --enable_platform_specific_config
build:linux --cxxopt=-std=c++20
build:macos --cxxopt=-std=c++20
build:windows --cxxopt=-std:c++20

View File

@ -1,36 +1,24 @@
# Copyright 2025 Arthur Sonzogni. All rights reserved.
# Use of this source code is governed by the MIT license that can be found in
# the LICENSE file.
matrix:
bazel:
- 7.x
- 8.x
- rolling
unix_platform:
- debian11
- ubuntu2204
- macos
- macos_arm64
win_platform:
- windows
platform:
- centos7
- debian10
- ubuntu2004
- macos
- windows
bazel: [6.x, 7.x, 8.x]
tasks:
unix_test:
name: Verify build targets on Unix
platform: ${{ unix_platform }}
verify_targets:
name: Build and test.
platform: ${{ platform }}
bazel: ${{ bazel }}
build_flags:
- --cxxopt=-std=c++20
build_targets:
- '@ftxui//:ftxui'
- '@ftxui//:screen'
- '@ftxui//:dom'
- '@ftxui//:component'
- '@ftxui//:screen'
test_targets:
- '@ftxui//:tests'
windows_test:
name: Verify build targets
platform: ${{ win_platform }}
bazel: ${{ bazel }}
build_flags:
- --cxxopt=/std:c++20
build_targets:
- '@ftxui//:dom'
- '@ftxui//:component'
- '@ftxui//:screen'

View File

@ -14,30 +14,25 @@ on:
jobs:
test_bazel:
name: "Bazel, ${{ matrix.cxx }}, ${{ matrix.os }}"
name: "Bazel, ${{ matrix.compiler }}, ${{ matrix.os }}"
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
cxx: g++
cc: gcc
compiler: gcc
- os: ubuntu-latest
cxx: clang++
cc: clang
compiler: llvm
- os: macos-latest
cxx: g++
cc: gcc
compiler: llvm
- os: macos-latest
cxx: clang++
cc: clang
compiler: gcc
- os: windows-latest
cxx: cl
cc: cl
compiler: cl
runs-on: ${{ matrix.os }}
steps:
@ -45,16 +40,10 @@ jobs:
uses: actions/checkout@v3
- name: "Build with Bazel"
env:
CC: ${{ matrix.cc }}
CXX: ${{ matrix.cxx }}
run: bazel build ...
- name: "Tests with Bazel"
env:
CC: ${{ matrix.cc }}
CXX: ${{ matrix.cxx }}
run: bazel test --test_output=all ...
run: bazel run tests
test_cmake:
name: "CMake, ${{ matrix.compiler }}, ${{ matrix.os }}"
@ -165,47 +154,3 @@ jobs:
flags: ${{ runner.os }}
name: ${{ runner.os }}-coverage
files: ./build/coverage.xml
test_modules:
name: "Test modules"
strategy:
matrix:
include:
- os: ubuntu-latest
compiler: llvm
# TODO add gcc / msvc
runs-on: ${{ matrix.os }}
steps:
- name: "Checkout repository"
uses: actions/checkout@v3
- name: "Setup Cpp"
uses: aminya/setup-cpp@v1
with:
compiler: ${{ matrix.compiler }}
vcvarsall: ${{ contains(matrix.os, 'windows' )}}
cmake: true
ninja: true
clangtidy: false
cppcheck: false
opencppcoverage: false
- name: "Generate ./examples_modules"
run: >
./tools/generate_examples_modules.sh
- name: "Build modules"
run: >
mkdir build;
cd build;
cmake ..
-DCMAKE_GENERATOR=Ninja
-DFTXUI_BUILD_MODULES=ON
-DFTXUI_BUILD_EXAMPLES=ON
-DCMAKE_BUILD_TYPE=Debug
-DFTXUI_BUILD_DOCS=OFF
-DFTXUI_BUILD_TESTS=OFF
-DFTXUI_BUILD_TESTS_FUZZER=OFF
-DFTXUI_ENABLE_INSTALL=ON
-DFTXUI_DEV_WARNINGS=ON ;
cmake --build .

View File

@ -19,15 +19,10 @@ jobs:
- name: "Install emsdk"
uses: mymindstorm/setup-emsdk@v7
- name: "Install Doxygen"
uses: ssciwr/doxygen-install@v1
with:
version: '1.12.0'
- name: "Install Graphviz"
- name: "Install Doxygen/Graphviz"
run: >
sudo apt-get update;
sudo apt-get install graphviz;
sudo apt-get install doxygen graphviz;
- name: "Build documentation"
run: >
@ -40,7 +35,7 @@ jobs:
-DFTXUI_BUILD_TESTS=OFF
-DFTXUI_BUILD_TESTS_FUZZER=OFF
-DFTXUI_ENABLE_INSTALL=OFF
-DFTXUI_DEV_WARNINGS=OFF;
-DFTXUI_DEV_WARNINGS=ON ;
cmake --build . --target doc;
cmake --build . ;
rsync -amv

View File

@ -9,16 +9,33 @@ on:
required: true
type: string
# Fire as soon as the Release workflow completes
workflow_run:
workflows:
- Release
types:
- completed
permissions:
attestations: write
contents: write
id-token: write
jobs:
publish:
uses: bazel-contrib/publish-to-bcr/.github/workflows/publish.yaml@v0.0.4
# Only run on manual dispatch, or when Release finishes successfully
if: |
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')
with:
tag_name: ${{ github.event.inputs.tag_name }}
# If manual: use the input, otherwise grab the tag from the completed run
tag_name: ${{
github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name ||
github.event_name == 'workflow_run' && github.event.workflow_run.head_branch
}}
registry_fork: ArthurSonzogni/bazel-central-registry
attest: false
secrets:
publish_token: ${{ secrets.PUBLISH_TOKEN }}

View File

@ -92,9 +92,27 @@ jobs:
run: >
git archive --format=tar.gz -o source.tar.gz HEAD
- name: Generate source attestation
id: attest_source
uses: actions/attest-build-provenance@v2
with:
subject-path: source.tar.gz
- name: Write source.intoto.jsonl
run:
jq --compact-output < "${{ steps.attest_source.outputs.bundle-path }}" \
> source.tar.gz.intoto.jsonl
- name: "Upload source package"
uses: shogo82148/actions-upload-release-asset@v1
with:
upload_url: ${{ needs.release.outputs.upload_url }}
asset_path: source.tar.gz
overwrite: true
- name: "Upload source attestation"
uses: shogo82148/actions-upload-release-asset@v1
with:
upload_url: ${{ needs.release.outputs.upload_url }}
asset_path: source.tar.gz.intoto.jsonl
overwrite: true

2
.gitignore vendored
View File

@ -62,10 +62,8 @@ out/
!include/ftxui/**/*.cpp
# src directory:
!src/ftxui/*.cppm
!src/ftxui/**/*.hpp
!src/ftxui/**/*.cpp
!src/ftxui/**/*.cppm
# tools directory:
!tools/**/*.sh

View File

@ -12,19 +12,23 @@
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
load(":bazel/ftxui.bzl", "ftxui_cc_library")
load(":bazel/ftxui.bzl", "generate_examples")
load(":bazel/ftxui.bzl", "cpp20")
load(":bazel/ftxui.bzl", "windows_copts")
load(":bazel/ftxui.bzl", "pthread_linkopts")
# A meta target depending on all of the ftxui submodules.
# Note that component depends on dom and screen, so ftxui is just an alias for
# component.
# ┌component──┐
# │┌dom──────┐│
# ││┌screen─┐││
# └┴┴───────┴┴┘
alias(name = "ftxui", actual = ":component")
package(default_visibility = ["//visibility:public"])
# @ftxui:screen is a module that provides a screen buffer and color management
# A meta target that depends on all the ftxui sub modules.
alias(
name = "ftxui",
# Note that :component depends on :dom, which depends on :screen. Bazel
# doesn't really support "public" and "private" dependencies. They are all
# public. This is equivalent to depending on all the submodules.
actual = ":component",
visibility = ["//visibility:public"],
)
# ftxui:screen is a module that provides a screen buffer and color management
# for terminal applications. A screen is a 2D array of cells, each cell can
# contain a glyph, a color, and other attributes. The library also provides
# functions to manipulate the screen.
@ -56,7 +60,7 @@ ftxui_cc_library(
],
)
# @ftxui:dom is a library that provides a way to create and manipulate a
# ftxui:dom is a library that provides a way to create and manipulate a
# "document" that can be rendered to a screen. The document is a tree of nodes.
# Nodes can be text, layouts, or various decorators. Users needs to compose
# nodes to create a document. A document is responsive to the size of the
@ -126,7 +130,7 @@ ftxui_cc_library(
deps = [":screen"],
)
# @ftxui:component is a library to create "dynamic" component renderering and
# ftxui:component is a library to create "dynamic" component renderering and
# updating a ftxui::dom document on the screen. It is a higher level API than
# ftxui:dom.
#
@ -163,13 +167,6 @@ ftxui_cc_library(
"src/ftxui/component/terminal_input_parser.hpp",
"src/ftxui/component/util.cpp",
"src/ftxui/component/window.cpp",
# Private header from ftxui:dom.
"src/ftxui/dom/node_decorator.hpp",
# Private header from ftxui:screen.
"src/ftxui/screen/string_internal.hpp",
"src/ftxui/screen/util.hpp",
],
hdrs = [
"include/ftxui/component/animation.hpp",
@ -185,10 +182,7 @@ ftxui_cc_library(
"include/ftxui/component/task.hpp",
],
linkopts = pthread_linkopts(),
deps = [
":dom",
":screen",
],
deps = [":dom"],
)
# FTXUI's tests
@ -211,6 +205,7 @@ cc_test(
"src/ftxui/component/resizable_split_test.cpp",
"src/ftxui/component/slider_test.cpp",
"src/ftxui/component/terminal_input_parser_test.cpp",
"src/ftxui/component/terminal_input_parser_test_fuzzer.cpp",
"src/ftxui/component/toggle_test.cpp",
"src/ftxui/dom/blink_test.cpp",
"src/ftxui/dom/bold_test.cpp",
@ -238,17 +233,6 @@ cc_test(
"src/ftxui/screen/string_test.cpp",
"src/ftxui/util/ref_test.cpp",
# Private header from ftxui:screen for string_test.cpp.
"src/ftxui/screen/string_internal.hpp",
# Private header from ftxui::component for
# terminal_input_parser_test.cpp.
"src/ftxui/component/terminal_input_parser.hpp",
# Private header from ftxui::dom for
# flexbox_helper_test.cpp.
"src/ftxui/dom/flexbox_helper.hpp",
# TODO: Enable the two tests timing out with Bazel:
# - "src/ftxui/component/screen_interactive_test.cpp",
# - "src/ftxui/dom/selection_test.cpp",
@ -257,12 +241,9 @@ cc_test(
"include",
"src",
],
copts = windows_copts(),
copts = cpp20() + windows_copts(),
deps = [
":screen",
":dom",
":component",
"@googletest//:gtest",
"//:ftxui",
"@googletest//:gtest_main",
],
)

View File

@ -1,59 +1,22 @@
Changelog
=========
Next
====
### Doc
- Fix broken Doxygen output. See @markmandel in #1029.
- Use Doxygen awesome. Add our own theme.
- Break the documentation into several pages.
### Build
- Feature: Support C++20 modules.
This requires:
- Using the Ninja or MSVC generator
- A recent Clang/GCC/MSVC compiler.
- Cmake 3.28 or higher.
Usage:
```cpp
import ftxui;
import ftxui.component;
import ftxui.dom;
import ftxui.screen;
import ftxui.util;
```
Thanks @mikomikotaishi for PR #1015.
### Component
- Fix ScreenInteractive::FixedSize screen stomps on the preceding terminal
output. Thanks @zozowell in #1064.
6.1.9 (2025-05-07)
Future release
------------
### Build
If all goes well (pending), ftxui should appear in the Bazel central repository.
It can be imported into your project using the following lines:
**MODULE.bazel**
```bazel
bazel_dep(name = "ftxui", version = "6.1.9")
```
Thanks @robinlinden and @kcc for the reviews.
### dom
- Bugfix: Restore the `dbox` behavior from ftxui 5.0.0. To apply bgcolor
blending between the two layers, a new `dboxBlend` will be added.
6.1.8 (2025-05-01)
6.1.4 (2025-05-01)
------------------
### Build
- Feature: Support `bazel` build system. See #1032.
Proposed by Kostya Serebryany @kcc
If all goes well (pending), it should appear in the Bazel central repository.
It can be imported into your project using the following lines:
**MODULE.bazel**
```bazel
bazel_dep(name = "ftxui", version = "6.1.4")
```
**BUILD.bazel**
```bazel

View File

@ -1,26 +1,20 @@
option(FTXUI_BUILD_DOCS "Set to ON to build docs" OFF)
option(FTXUI_BUILD_EXAMPLES "Set to ON to build examples" OFF)
option(FTXUI_BUILD_MODULES "Build the C++20 modules" OFF)
option(FTXUI_BUILD_TESTS "Set to ON to build tests" OFF)
option(FTXUI_BUILD_TESTS_FUZZER "Set to ON to enable fuzzing" OFF)
option(FTXUI_CLANG_TIDY "Execute clang-tidy" OFF)
option(FTXUI_DEV_WARNINGS "Enable more compiler warnings and warnings as errors" OFF)
option(FTXUI_ENABLE_COVERAGE "Execute code coverage" OFF)
option(FTXUI_ENABLE_INSTALL "Generate the install target" ON)
option(FTXUI_QUIET "Set to ON for FTXUI to be quiet" OFF)
if (FTXUI_BUILD_MODULES)
cmake_minimum_required(VERSION 3.28.2)
else()
cmake_minimum_required(VERSION 3.12)
endif()
cmake_minimum_required(VERSION 3.12)
project(ftxui
LANGUAGES CXX
VERSION 6.1.9
VERSION 6.1.4
DESCRIPTION "C++ Functional Terminal User Interface."
)
option(FTXUI_QUIET "Set to ON for FTXUI to be quiet" OFF)
option(FTXUI_BUILD_EXAMPLES "Set to ON to build examples" OFF)
option(FTXUI_BUILD_DOCS "Set to ON to build docs" OFF)
option(FTXUI_BUILD_TESTS "Set to ON to build tests" OFF)
option(FTXUI_BUILD_TESTS_FUZZER "Set to ON to enable fuzzing" OFF)
option(FTXUI_ENABLE_INSTALL "Generate the install target" ON)
option(FTXUI_CLANG_TIDY "Execute clang-tidy" OFF)
option(FTXUI_ENABLE_COVERAGE "Execute code coverage" OFF)
option(FTXUI_DEV_WARNINGS "Enable more compiler warnings and warnings as errors" OFF)
set(FTXUI_MICROSOFT_TERMINAL_FALLBACK_HELP_TEXT "On windows, assume the \
terminal used will be one of Microsoft and use a set of reasonnable fallback \
@ -182,13 +176,6 @@ include(cmake/iwyu.cmake)
include(cmake/ftxui_export.cmake)
include(cmake/ftxui_install.cmake)
include(cmake/ftxui_package.cmake)
include(cmake/ftxui_modules.cmake)
add_subdirectory(doc)
add_subdirectory(examples)
# You can generate ./examples_modules/ by running
# ./tools/generate_examples_modules.sh
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/examples_modules/CMakeLists.txt")
add_subdirectory(examples_modules)
endif()
add_subdirectory(doc)

View File

@ -1,13 +1,13 @@
# FTXUI module.
module(
name = "ftxui",
version = "6.1.9",
compatibility_level = 6,
)
# Copyright 2025 Arthur Sonzogni. All rights reserved.
# Use of this source code is governed by the MIT license that can be found in
# the LICENSE file.
# Build dependencies.
# FTXUI Module.
module(name = "ftxui", version = "6.1.4")
# Build deps.
bazel_dep(name = "rules_cc", version = "0.1.1")
bazel_dep(name = "platforms", version = "0.0.10")
bazel_dep(name = "platforms", version = "0.0.11")
# Test dependencies.
bazel_dep(name = "googletest", version = "1.14.0.bcr.1", dev_dependency = True)
# Test deps.
bazel_dep(name = "googletest", version = "1.16.0.bcr.1")

View File

@ -39,30 +39,18 @@ A simple cross-platform C++ library for terminal based user interfaces!
* 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)
* No dependencies.
* [C++20 Module support](https://arthursonzogni.github.io/FTXUI/cpp20-modules.html)
* No dependencies
* **Cross platform**: Linux/MacOS (main target), WebAssembly, Windows (Thanks to contributors!).
* Learn by [examples](#documentation), and [tutorials](#documentation)
* Multiple packages:
- CMake [FetchContent]([https://bewagner.net/programming/2020/05/02/cmake-fetchcontent/](https://cmake.org/cmake/help/latest/module/FetchContent.html)) (preferred)
- [Bazel](https://registry.bazel.build/modules/ftxui)
- [vcpkg](https://vcpkg.link/ports/ftxui)
- [Conan](https://conan.io/center/recipes/ftxui) [Debian package](https://tracker.debian.org/pkg/ftxui)
- [Ubuntu package](https://launchpad.net/ubuntu/+source/ftxui)
- [Arch Linux](https://aur.archlinux.org/packages/ftxui/)
- [OpenSUSE](https://build.opensuse.org/package/show/devel:libraries:c_c++/ftxui)
- [XMake](https://xmake.io) repository [package](https://github.com/xmake-io/xmake-repo/blob/dev/packages/f/ftxui/xmake.lua)
- [Nix](https://github.com/ArthurSonzogni/FTXUI/blob/main/flake.nix)
* Multiple packages: CMake [FetchContent]([https://bewagner.net/programming/2020/05/02/cmake-fetchcontent/](https://cmake.org/cmake/help/latest/module/FetchContent.html)) (preferred),Bazel, vcpkg, pkgbuild, conan.
* Good practices: documentation, tests, fuzzers, performance tests, automated CI, automated packaging, etc...
## Documentation
- [Starter CMake](https://github.com/ArthurSonzogni/ftxui-starter)
- [Starter Bazel](https://github.com/ArthurSonzogni/ftxui-bazel)
- [Starter example project](https://github.com/ArthurSonzogni/ftxui-starter)
- [Documentation](https://arthursonzogni.github.io/FTXUI/)
- [Examples (WebAssembly)](https://arthursonzogni.github.io/FTXUI/examples/)
- [Build using CMake](https://arthursonzogni.github.io/FTXUI/#build-cmake)
- [Build using Bazel](https://arthursonzogni.github.io/FTXUI/#build-bazel)
## Example
~~~cpp
@ -98,7 +86,7 @@ Element can be arranged together:
- inside a grid with `gridbox`
- wrap along one direction using the `flexbox`.
Element can become flexible using the `flex` decorator.
Element can become flexible using the the `flex` decorator.
[Example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2vbox_hbox_8cpp-example.html) using `hbox`, `vbox` and `filler`.
@ -360,8 +348,6 @@ Feel free to add your projects here:
- [terminal-rain](https://github.com/Oakamoore/terminal-rain)
- [keywords](https://github.com/Oakamoore/keywords) ([Play web version :heart:](https://oakamoore.itch.io/keywords))
- [FTB - tertminal file browser](https://github.com/Cyxuan0311/FTB)
- [openJuice](https://github.com/mikomikotaishi/openJuice)
- [SHOOT!](https://github.com/ShingZhanho/ENGG1340-Project-25Spring)
### [cpp-best-practices/game_jam](https://github.com/cpp-best-practices/game_jam)
@ -378,70 +364,38 @@ Several games using the FTXUI have been made during the Game Jam:
- [smoothlife](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/smoothlife.md)
- [Consu](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/consu.md)
## Build using CMake
## Utilization
It is **highly** recommended to use CMake FetchContent to depend on FTXUI so you may specify which commit you would like to depend on.
```cmake
include(FetchContent)
FetchContent_Declare(ftxui
GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui
GIT_TAG v6.1.9
GIT_TAG v6.1.4
)
FetchContent_MakeAvailable(ftxui)
target_link_libraries(your_target PRIVATE
# Chose a submodule
ftxui::component
ftxui::dom
ftxui::screen
)
FetchContent_GetProperties(ftxui)
if(NOT ftxui_POPULATED)
FetchContent_Populate(ftxui)
add_subdirectory(${ftxui_SOURCE_DIR} ${ftxui_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()
```
# Build using Bazel
**MODULE.bazel**
```starlark
bazel_dep(
name = "ftxui",
version = "v6.1.9",
)
```
**BUILD.bazel**
```starlark
cc_binary(
name = "your_target",
srcs = ["your_source.cc"],
deps = [
"@ftxui//:ftxui_component",
"@ftxui//:ftxui_dom",
"@ftxui//:ftxui_screen",
],
)
```
# Build with something else:
If you don't, FTXUI may be used from the following packages:
- CMake [FetchContent]([https://bewagner.net/programming/2020/05/02/cmake-fetchcontent/](https://cmake.org/cmake/help/latest/module/FetchContent.html)) (preferred),
- [Bazel](https://registry.bazel.build/modules/ftxui),
- [vcpkg](https://vcpkg.link/ports/ftxui),
- [Conan](https://conan.io/center/recipes/ftxui)
- [Debian package](https://tracker.debian.org/pkg/ftxui),
- [Ubuntu package](https://launchpad.net/ubuntu/+source/ftxui),
- [Arch Linux](https://aur.archlinux.org/packages/ftxui/),
- [OpenSUSE](https://build.opensuse.org/package/show/devel:libraries:c_c++/ftxui),
[Nix](https://github.com/ArthurSonzogni/FTXUI/blob/main/flake.nix),
- [bazel](...)
- [vcpkg](https://vcpkgx.com/details.html?package=ftxui)
- [Arch Linux PKGBUILD](https://aur.archlinux.org/packages/ftxui-git/).
- [conan.io](https://conan.io/center/ftxui)
- [openSUSE](https://build.opensuse.org/package/show/devel:libraries:c_c++/ftxui)
-
[![Packaging status](https://repology.org/badge/vertical-allrepos/libftxui.svg)](https://repology.org/project/libftxui/versions)
If you choose to build and link FTXUI yourself, `ftxui-component` must be first in the linking order relative to the other FTXUI libraries, i.e.
```bash
g++ . . . -lftxui-component -lftxui-dom -lftxui-screen . . .
```
To build FTXUI with modules, check [documentation](https://arthursonzogni.github.io/FTXUI/cpp20-modules.html)
## Contributors
<a href="https://github.com/ArthurSonzogni/FTXUI/graphs/contributors">

View File

@ -1,7 +1,24 @@
# ftxui_common.bzl
load("@rules_cc//cc:defs.bzl", "cc_library")
load("@rules_cc//cc:defs.bzl", "cc_binary")
def cpp17():
return select({
"@rules_cc//cc/compiler:msvc-cl": ["/std:c++17"],
"@rules_cc//cc/compiler:clang-cl": ["/std:c++17"],
"@rules_cc//cc/compiler:clang": ["-std=c++17"],
"@rules_cc//cc/compiler:gcc": ["-std=c++17"],
"//conditions:default": ["-std=c++17"],
})
def cpp20():
return select({
"@rules_cc//cc/compiler:msvc-cl": ["/std:c++20"],
"@rules_cc//cc/compiler:clang-cl": ["/std:c++20"],
"@rules_cc//cc/compiler:clang": ["-std=c++20"],
"@rules_cc//cc/compiler:gcc": ["-std=c++20"],
"//conditions:default": ["-std=c++20"],
})
# Microsoft terminal is a bit buggy ¯\_(ツ)_/¯ and MSVC uses bad defaults.
def windows_copts():
@ -28,8 +45,7 @@ def windows_copts():
# This
# - Replace missing font symbols by others.
# - Reduce screen position pooling frequency to deals against a Microsoft
# race condition. This was fixed in 2020, but clients are still using
# old versions.
# race condition. This was fixed in 2020, but clients never not updated.
# - https://github.com/microsoft/terminal/pull/7583
# - https://github.com/ArthurSonzogni/FTXUI/issues/136
"-DFTXUI_MICROSOFT_TERMINAL_FALLBACK",
@ -55,8 +71,8 @@ def pthread_linkopts():
def ftxui_cc_library(
name,
srcs = [],
hdrs = [],
srcs,
hdrs,
linkopts = [],
deps = []):
@ -72,13 +88,12 @@ def ftxui_cc_library(
"include",
"src",
],
copts = windows_copts(),
copts = cpp17() + windows_copts(),
visibility = ["//visibility:public"],
)
# Compile all the examples in the examples/ directory.
# This is useful to check the Bazel is always synchronized against CMake
# definitions.
# This is useful to check the Bazel is synchronized with CMake definitions.
def generate_examples():
cpp_files = native.glob(["examples/**/*.cpp"])
@ -92,13 +107,9 @@ def generate_examples():
# Turn "examples/component/button.cpp" → "example_component_button"
name = src.replace("/", "_").replace(".cpp", "")
cc_binary(
native.cc_binary(
name = name,
srcs = [src],
deps = [
":component",
":dom",
":screen",
],
copts = windows_copts(),
deps = ["//:component"],
copts = cpp20() + windows_copts(),
)

View File

@ -5,14 +5,13 @@ function(ftxui_message msg)
endfunction()
ftxui_message("┌─ FTXUI options ─────────────────────")
ftxui_message("│ FTXUI_BUILD_DOCS : ${FTXUI_BUILD_DOCS}")
ftxui_message("│ FTXUI_ENABLE_INSTALL : ${FTXUI_ENABLE_INSTALL}")
ftxui_message("│ FTXUI_BUILD_EXAMPLES : ${FTXUI_BUILD_EXAMPLES}")
ftxui_message("│ FTXUI_BUILD_MODULES : ${FTXUI_BUILD_MODULES}")
ftxui_message("│ FTXUI_QUIET : ${FTXUI_QUIET}")
ftxui_message("│ FTXUI_BUILD_DOCS : ${FTXUI_BUILD_DOCS}")
ftxui_message("│ FTXUI_BUILD_TESTS : ${FTXUI_BUILD_TESTS}")
ftxui_message("│ FTXUI_BUILD_TESTS_FUZZER : ${FTXUI_BUILD_TESTS_FUZZER}")
ftxui_message("│ FTXUI_CLANG_TIDY : ${FTXUI_CLANG_TIDY}")
ftxui_message("│ FTXUI_DEV_WARNINGS : ${FTXUI_DEV_WARNINGS}")
ftxui_message("│ FTXUI_ENABLE_COVERAGE : ${FTXUI_ENABLE_COVERAGE}")
ftxui_message("│ FTXUI_ENABLE_INSTALL : ${FTXUI_ENABLE_INSTALL}")
ftxui_message("│ FTXUI_QUIET : ${FTXUI_QUIET}")
ftxui_message("│ FTXUI_DEV_WARNINGS : ${FTXUI_DEV_WARNINGS}")
ftxui_message("│ FTXUI_CLANG_TIDY : ${FTXUI_CLANG_TIDY}")
ftxui_message("└─────────────────────────────────────")

View File

@ -1,82 +0,0 @@
if (NOT FTXUI_BUILD_MODULES)
return()
endif()
add_library(ftxui-modules)
target_sources(ftxui-modules
PUBLIC FILE_SET CXX_MODULES FILES
src/ftxui/component.cppm
src/ftxui/component/animation.cppm
src/ftxui/component/captured_mouse.cppm
src/ftxui/component/component.cppm
src/ftxui/component/component_base.cppm
src/ftxui/component/component_options.cppm
src/ftxui/component/event.cppm
src/ftxui/component/loop.cppm
src/ftxui/component/mouse.cppm
src/ftxui/component/receiver.cppm
src/ftxui/component/screen_interactive.cppm
src/ftxui/component/task.cppm
src/ftxui/dom.cppm
src/ftxui/dom/canvas.cppm
src/ftxui/dom/deprecated.cppm
src/ftxui/dom/direction.cppm
src/ftxui/dom/elements.cppm
src/ftxui/dom/flexbox_config.cppm
src/ftxui/dom/linear_gradient.cppm
src/ftxui/dom/node.cppm
src/ftxui/dom/requirement.cppm
src/ftxui/dom/selection.cppm
src/ftxui/dom/table.cppm
src/ftxui/screen.cppm
src/ftxui/screen/box.cppm
src/ftxui/screen/color.cppm
src/ftxui/screen/color_info.cppm
src/ftxui/screen/deprecated.cppm
src/ftxui/screen/image.cppm
src/ftxui/screen/pixel.cppm
src/ftxui/screen/screen.cppm
src/ftxui/screen/string.cppm
src/ftxui/screen/terminal.cppm
src/ftxui/util.cppm
src/ftxui/util/autoreset.cppm
src/ftxui/util/ref.cppm
)
target_link_libraries(ftxui-modules
PUBLIC
ftxui::screen
ftxui::dom
ftxui::component
)
target_compile_features(ftxui-modules PUBLIC cxx_std_20)
# TODO: Explain why this is needed.
if (CMAKE_COMPILER_IS_GNUCXX)
target_compile_options(ftxui-modules PUBLIC -fmodules-ts)
endif ()
add_library(ftxui::modules ALIAS ftxui-modules)
if(FTXUI_ENABLE_INSTALL)
include(GNUInstallDirs)
install(TARGETS ftxui-modules
EXPORT ftxui-targets
FILE_SET CXX_MODULES
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ftxui
FILE_SET HEADERS
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ftxui
INCLUDES
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ftxui
)
install(EXPORT ftxui-targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ftxui
CXX_MODULES_DIRECTORY ${CMAKE_INSTALL_LIBDIR}/cmake/ftxui
)
install(FILES my_package-config.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ftxui
)
endif()

View File

@ -8,63 +8,13 @@ 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(DOM_EXAMPLES "")
set(COMPONENT_EXAMPLES "")
set(EXAMPLE_LIST "${CMAKE_CURRENT_BINARY_DIR}/example_list.md")
file(WRITE ${EXAMPLE_LIST} "# Examples")
get_property(EXAMPLES GLOBAL PROPERTY FTXUI::EXAMPLES)
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(WRITE "${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")
# Add a markdown to the demo. URL example:
# https://arthursonzogni.github.io/FTXUI/examples/?file=component/canvas_animated
file(APPEND "${file}" "[Demo](https://arthursonzogni.github.io/FTXUI/examples/?file=${example})\n")
file(APPEND "${file}" "@include examples/${example}.cpp\n")
file(APPEND "${file}" "\n")
endforeach()
# Reference to the examples
foreach(example IN LISTS ${examples})
get_filename_component(name "${example}" NAME_WE)
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)
foreach(EXAMPLE IN LISTS EXAMPLES)
file(APPEND ${EXAMPLE_LIST} "\n@example examples/${EXAMPLE}.cpp")
endforeach(EXAMPLE IN LISTS EXAMPLES)
configure_file(Doxyfile.in Doxyfile @ONLY)

File diff suppressed because it is too large Load Diff

View File

@ -1,84 +0,0 @@
@page cpp20-modules C++20 Modules
> [!WARNING]
> This feature is still in development, and the API may change in future releases.
> Your contribution is needed to help us improve the compatibility and usability
> of C++20 modules in FTXUI. If you encounter any issues or have suggestions,
> please open an issue.
FTXUI experimentally supports
[C++20 modules](https://en.cppreference.com/w/cpp/language/modules) to reduce
compilation times and improve code organization. Each header has a
corresponding module.
**Example with CMake and Ninja**
```cpp
import ftxui;
int main() {
auto screen = ftxui::ScreenInteractive::TerminalOutput();
auto button = ftxui::Button("Click me", screen.QuitClosure());
screen.Loop(button);
return 0;
}
```
```sh
cmake \
-DCMAKE_GENERATOR=Ninja \
-DFTXUI_BUILD_MODULES=ON \
..
ninja
```
> [!NOTE]
> To use modules, you need a C++20 compatible compiler, CMake version 3.20 or
> higher, and use a compatible generator like Ninja. Note that Makefile
> generators **do not support modules**.
### Module list
The modules directly reference the corresponding header, or a group of related
headers to provide a more convenient interface. The following modules
are available:
- `ftxui`
- `ftxui.component`
- `ftxui.component.Animation`
- `ftxui.component.CapturedMouse`
- `ftxui.component.Component`
- `ftxui.component.ComponentBase`
- `ftxui.component.ComponentOptions`
- `ftxui.component.Event`
- `ftxui.component.Loop`
- `ftxui.component.Mouse`
- `ftxui.component.Receiver`
- `ftxui.component.ScreenInteractive`
- `ftxui.component.Task`
- `ftxui.dom`
- `ftxui.dom.Canvas`
- `ftxui.dom.Deprecated`
- `ftxui.dom.Direction`
- `ftxui.dom.Elements`
- `ftxui.dom.FlexboxConfig`
- `ftxui.dom.LinearGradient`
- `ftxui.dom.Node`
- `ftxui.dom.Requirement`
- `ftxui.dom.Selection`
- `ftxui.dom.Table`
- `ftxui.screen`
- `ftxui.screen.Box`
- `ftxui.screen.Color`
- `ftxui.screen.ColorInfo`
- `ftxui.screen.Deprecated`
- `ftxui.screen.Image`
- `ftxui.screen.Pixel`
- `ftxui.screen.Screen`
- `ftxui.screen.String`
- `ftxui.screen.Terminal`
- `ftxui.util`
- `ftxui.util.AutoReset`
- `ftxui.util.Ref`

323
doc/doxygen_extra.css Executable file
View File

@ -0,0 +1,323 @@
/*
* 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;
}

10
doc/doxygen_footer.html Normal file
View File

@ -0,0 +1,10 @@
<!-- 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>

59
doc/doxygen_header.html Normal file
View File

@ -0,0 +1,59 @@
<!-- 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,56 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<doxygenlayout version="1.0">
<!-- Generated by doxygen 1.12.0 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="no" title=""/>
<tab type="pages" visible="yes" title="Pages" intro=""/>
<tab type="topics" visible="yes" title="Reference" intro=""/>
<tab type="modules" visible="yes" title="" intro="">
<tab type="modulelist" visible="yes" title="" intro=""/>
<tab type="modulemembers" visible="yes" title="" intro=""/>
</tab>
<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="concepts" visible="yes" title="">
</tab>
<tab type="interfaces" visible="yes" title="">
<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="yes" title="">
<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="yes" title="">
<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="yes" title="">
<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>
<tab type="files" visible="yes" title="">
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_HEADERFILE"/>
<inheritancegraph visible="yes"/>
<collaborationgraph visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
@ -108,20 +96,19 @@
<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=""/>
<classes visible="yes" title=""/>
<concepts visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<properties title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
@ -133,26 +120,16 @@
<enums title=""/>
<functions title=""/>
<variables title=""/>
<properties title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a concept page -->
<concept>
<briefdescription visible="yes"/>
<includes visible="$SHOW_HEADERFILE"/>
<definition visible="yes" title=""/>
<detaileddescription title=""/>
<authorsection visible="yes"/>
</concept>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="yes"/>
<includedbygraph visible="yes"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<interfaces visible="yes" title=""/>
@ -160,7 +137,6 @@
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
@ -169,7 +145,6 @@
<enums title=""/>
<functions title=""/>
<variables title=""/>
<properties title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
@ -182,24 +157,19 @@
<enums title=""/>
<functions title=""/>
<variables title=""/>
<properties title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="no"/>
<authorsection visible="no"/>
<detaileddescription title=""/>
<groupgraph visible="yes"/>
<briefdescription visible="yes"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<modules visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
@ -218,6 +188,7 @@
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
@ -237,27 +208,9 @@
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a C++20 module page -->
<module>
<briefdescription visible="yes"/>
<exportedmodules visible="yes"/>
<memberdecl>
<concepts visible="yes" title=""/>
<classes visible="yes" title=""/>
<enums title=""/>
<typedefs title=""/>
<functions title=""/>
<variables title=""/>
<membergroups title=""/>
</memberdecl>
<detaileddescription title=""/>
<memberdecl>
<files visible="yes"/>
</memberdecl>
</module>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>

View File

@ -1,17 +0,0 @@
<!-- 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>

View File

@ -1,62 +0,0 @@
@page getting-started Getting Started
@tableofcontents
![title-img](https://nsm09.casimages.com/img/2025/05/30//2505300816063242518595256.jpg)
# 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>

View File

@ -1,183 +0,0 @@
<!-- 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="module">
DoxygenAwesomeFragmentCopyButton.init()
DoxygenAwesomeParagraphLink.init()
DoxygenAwesomeInteractiveToc.init()
DoxygenAwesomeTabs.init()
await new Promise(r => window.addEventListener('DOMContentLoaded', r));
// Remove title when a img[alt='title-img'] is present.
// Find an image with the alt "img-title".
const img = document.querySelector("img[alt='title-img']");
const header = document.querySelector(".headertitle");
if (img && header) {
// Hide the header title progressively.
header.style.display = "none";
// Show progressively the image.
img.style.maxHeight = "40vh";
img.style.maxWidth = "100%";
img.style.objectFit = "contain";
}
// In the "examples.html" page. Turn every link with text
// "examples/<...>
//
// Add a "demo" link toward.
// https://arthursonzogni.github.io/FTXUI/examples/?file=<...>
const examples = document.querySelectorAll("a")
examples.forEach((example) => {
if (!example.textContent.startsWith("examples/")) {
return;
}
// Remove the ".cpp" extension from the example name.
const exampleName = example.textContent.replace("examples/", "").replace(".cpp", "");
const a = document.createElement("a");
a.textContent = "[demo]";
a.href = "https://arthursonzogni.github.io/FTXUI/examples/?file=" + exampleName;
a.style.marginRight= "1em";
a.style.fontWeight = "bold";
example.parentElement.insertBefore(a, example)
});
// If the current URL ends with -example.html, we can add a link to the demo
// as well using the div.title textContent.
const url = new URL(window.location.href);
if (url.pathname.endsWith("-example.html")) {
// Get the title text.
const title = document.querySelector("div.title").textContent;
const example = title.replace("examples/", "").replace(".cpp", "");
// Create a link to the demo.
const a = document.createElement("a");
a.textContent = "[demo]";
a.href = "https://arthursonzogni.github.io/FTXUI/examples/?file=" + example;
a.style.marginLeft = "1em";
a.style.fontWeight = "bold";
a.style.display = "inline-block";
// Insert the link after the title.
const titleDiv = document.querySelector("div.title");
if (titleDiv) {
titleDiv.insertBefore(a, titleDiv.nextSibling);
}
}
</script>
<script type="module">
// Click on the navtree, except for the main page where this is already done
// automatically.
let delay = 0;
while(true) {
const navtree = document.querySelector("div.item.selected");
if (!navtree) {
delay *= 2;
delay += 1;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
// Include only selected navtree items.
console.log("navtree.textContent", navtree.textContent);
if (!navtree.textContent.includes("Getting Started") &&
!navtree.textContent.includes("Installation") &&
!navtree.textContent.includes("ftxui / screen") &&
!navtree.textContent.includes("ftxui / dom") &&
!navtree.textContent.includes("ftxui / component") &&
!navtree.textContent.includes("Reference")) {
break;
}
// Find the first link inside the navtree.
const link = navtree.querySelector("a");
if (link) {
// Simulate a click on the link.
link.click();
break;
}
}
</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 -->

View File

@ -1,47 +0,0 @@
@page installation Installation
@tableofcontents
![title-img](https://nsm09.casimages.com/img/2025/05/30//2505300816063242518595255.jpg)
## 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
- @subpage installation_nix
- @subpage installation_debian
- @subpage installation_arch
- @subpage installation_opensuse
- @subpage installation_xmake
## 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>

View File

@ -1,34 +0,0 @@
@page installation_arch Arch Linux
FTXUI is packaged on the AUR. Install using an AUR helper:
```bash
yay -S ftxui
```
You can also manually download the PKGBUILD from <https://aur.archlinux.org/packages/ftxui>.
Once installed, you can use it in your CMake projects by adding the following to your `CMakeLists.txt`:
```cmake
find_package(ftxui REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main
PRIVATE ftxui::screen
PRIVATE ftxui::dom
PRIVATE ftxui::component
)
```
> [!note]
> This is an unofficial package. That means it is not maintained by the FTXUI
> team, but by the community. The package maintainers seems to actively update
> the package to the latest version. Thanks to the maintainers for their work!
<div class="section_buttons">
| Previous |
|:------------------|
| [Getting Started](getting-started.html) |
</div>

View File

@ -1,38 +0,0 @@
@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>

View File

@ -1,111 +0,0 @@
@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.
```cmake
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:
```cmake
find_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:
```cmake
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`:
```cmake
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>

View File

@ -1,24 +0,0 @@
@page installation_conan Conan
Unofficial recipe for FTXUI exists on Conan Center:
<https://conan.io/center/recipes/ftxui>
> [!note]
> This is an unofficial recipe. That means it is not maintained by the FTXUI
> team, but by the community. The package maintainers seems to actively update
> the package to the latest version. Thanks to the maintainers for their work!
@todo Add instructions on how to use the conan recipe.
@todo Please consider adding an "official" recipe to Conan Center if know how.
It could be a github action that will automatically update the conan center
when a new release is made.
<div class="section_buttons">
| Previous |
|:------------------|
| [Getting Started](getting-started.html) |
</div>

View File

@ -1,42 +0,0 @@
@page installation_debian Debian/Ubuntu
## Debian and Ubuntu Packages (Unofficial)
Pre-built packages are provided by the distributions. Install with:
```bash
sudo apt install libftxui-dev
```
The following packages are available:
- `ftxui-doc`
- `ftxui-examples`
- `libftxui-component<version>`
- `libftxui-dev`
- `libftxui-dom<version>`
- `libftxui-screen<version>`
Once installed, you can use it in your CMake projects by adding the following to
your `CMakeLists.txt`:
```cmake
find_package(ftxui REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main
PRIVATE ftxui::screen
PRIVATE ftxui::dom
PRIVATE ftxui::component
)
```
> [!note]
> This is an **unofficial** package. That means it is not maintained by the FTXUI
> team, but by the community.
<div class="section_buttons">
| Previous |
|:------------------|
| [Getting Started](getting-started.html) |
</div>

View File

@ -1,35 +0,0 @@
@page installation_manual Manual
@tableofcontents
## Building from Source (Official)
Clone and build the project using CMake:
```bash
git clone https://github.com/ArthurSonzogni/FTXUI.git
cd FTXUI
cmake -S . -B build -DFTXUI_ENABLE_INSTALL=ON -D
cmake --build build -j
sudo cmake --install build
```
Once installed you can use it in your CMake projects by adding the following to your `CMakeLists.txt`:
```cmake
find_package(ftxui REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main
PRIVATE ftxui::screen
PRIVATE ftxui::dom
PRIVATE ftxui::component
)
```
<div class="section_buttons">
| Previous |
|:------------------|
| [Getting Started](getting-started.html) |
</div>

View File

@ -1,38 +0,0 @@
@page installation_nix Nix
> [!note]
> FTXUI author is not very knowledgeable about Nix. This page has been mostly
> generated by AI. If you have any suggestions to improve it, please open a
> PR.
## Nix Flake
FTXUI ships with a `flake.nix` providing both packages and a development shell.
### Build the Library
```bash
nix build github:ArthurSonzogni/FTXUI
```
The resulting package is accessible via the `result` link.
### Use as a Dependency
Add FTXUI to your flake inputs:
```nix
{
inputs.ftxui.url = "github:ArthurSonzogni/FTXUI";
}
```
Then reference `ftxui.packages.<system>.ftxui` in your outputs.
<div class="section_buttons">
| Previous |
|:------------------|
| [Getting Started](getting-started.html) |
</div>

View File

@ -1,32 +0,0 @@
@page installation_opensuse openSUSE
## openSUSE Package (Unofficial)
FTXUI seems to be available from the `devel:libraries:c_c++` repository.
```bash
sudo zypper addrepo https://download.opensuse.org/repositories/devel:libraries:c_c++/openSUSE_Leap_$releasever/devel:libraries:c_c++.repo
sudo zypper install ftxui
```
See <https://build.opensuse.org/package/show/devel:libraries:c_c++/ftxui> for details.
> [!note]
> This is an **unofficial** package. That means it is not maintained by the FTXUI
> team, but by the community.
--
> [!note]
> The FTXUI author is not very knowledgeable about openSUSE. This page has been
> mostly generated by AI. If you have any suggestions to improve it, please open
> a PR.
<div class="section_buttons">
| Previous |
|:------------------|
| [Getting Started](getting-started.html) |
</div>

View File

@ -1,79 +0,0 @@
@page installation_vcpkg Vcpkg
@tableofcontents
# Vcpkg Package
FTXUI is available in the [Vcpkg registry](https://vcpkg.link/ports/ftxui)
To use it, you can add the following to your `vcpkg.json`:
```json
{
"name": "your-project",
"version-string": "0.1.0",
"dependencies": [
{
"name": "ftxui",
"version>=": "6.1.9"
}
]
}
```
# Install FTXUI using Vcpkg
```bash
vcpkg install --triplet x64-linux # or x64-windows / arm64-osx etc.
```
# Configure your build system.
If you are using CMake, you can use the following in your `CMakeLists.txt`:
**CMakeLists.txt**
```cmake
cmake_minimum_required(VERSION 3.15)
project(my_project)
# Make sure vcpkg toolchain file is passed at configure time
find_package(ftxui CONFIG REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main
PRIVATE ftxui::screen
PRIVATE ftxui::dom
PRIVATE ftxui::component
)
```
**main.cpp**
```cpp
#include <ftxui/component/screen_interactive.hpp>
#include <ftxui/component/component.hpp>
#include <ftxui/component/component_options.hpp>
int main() {
using namespace ftxui;
auto screen = ScreenInteractive::TerminalOutput();
auto button = Button("Click me", [] { std::cout << "Clicked!\n"; });
screen.Loop(button);
}
```
**Configure and build the project**
```bash
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build build
./build/main
```
<div class="section_buttons">
| Previous |
|:------------------|
| [Getting Started](getting-started.html) |
</div>

View File

@ -1,40 +0,0 @@
@page installation_xmake XMake
@tableofcontents
## XMake Package (Unofficial)
FTXUI is available in the [xmake-repo](https://github.com/xmake-io/xmake-repo/blob/dev/packages/f/ftxui/xmake.lua)
Example `xmake.lua` snippet:
```lua
add_requires("ftxui", {system = false})
target("demo")
set_kind("binary")
add_files("src/*.cpp")
add_packages("ftxui")
```
Refer to the [XMake documentation](https://xmake.io) for further options.
> [!note]
> This is an **unofficial** package. That means it is not maintained by the FTXUI
> team, but by the community.
---
> [!note]
> The FTXUI author is not very knowledgeable about openSUSE. This page has been
> mostly generated by AI. If you have any suggestions to improve it, please open
> a PR.
---
<div class="section_buttons">
| Previous |
|:------------------|
| [Getting Started](getting-started.html) |
</div>

View File

@ -1,88 +0,0 @@
@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>
@defgroup screen ftxui/screen
Please check the [tutorial](module-screen.html) of the `ftxui/screen` module.
@defgroup dom ftxui/dom
Please check the [tutorial](module-dom.html) of the `ftxui/dom` module.
@defgroup component ftxui/component
Please check the [tutorial](module-component.html) of the `ftxui/component`
module.

895
doc/mainpage.md Normal file
View File

@ -0,0 +1,895 @@
\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 main # Important: Specify a version or a commit hash here.
)
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.
)
```
## Build
```bash
mkdir build && cd build
cmake ..
make
./main
```
# 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);
```

View File

@ -1,308 +0,0 @@
@page module-component ftxui / component
@tableofcontents
![title-img](https://nsm09.casimages.com/img/2025/05/31//2505310207423242518595349.png)
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 components 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
One 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 opened, displays a list of elements
for the user to select from.
[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 toggled on or off by the
user. Essentially, this is the combination of the `ftxui::Checkbox()` and
`ftxui::Maybe()` components.
```cpp
auto collapsible = 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 handles 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 takes a list of components and displays
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.

View File

@ -1,470 +0,0 @@
@page module-dom ftxui / dom
@tableofcontents
![title-img](https://nsm09.casimages.com/img/2025/05/31//2505310207423242518595347.png)
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))
```
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](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 `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)

View File

@ -1,202 +0,0 @@
@page module-screen ftxui / screen
@tableofcontents
![title-img](https://nsm09.casimages.com/img/2025/05/31//2505310207423242518595348.png)
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().

View File

@ -1,74 +0,0 @@
# ftxui {#ftxui}
![title-img](https://nsm09.casimages.com/img/2025/05/30//2505300816063242518595251.jpg)
FTXUI is organized into three modules, each building upon the previous:
1. [ftxui/screen](#module-screen) - Low-level rendering
2. [ftxui/dom](#module-dom) - Layout and composition
3. [ftxui/component](#module-component) - User interaction
---
# ftxui/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.
<div class="section_buttons">
| Next |
|--------------------------------------:|
| [Documentation](module-screen.html) |
</div>
---
# ftxui/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.
<div class="section_buttons">
| Next |
|--------------------------------------:|
| [Documentation](module-dom.html) |
</div>
---
# ftxui/component
Adds:
- **`ftxui::Component`**: stateful, interactive widgets.
- Built-ins: `Checkbox`, `Input`, `Menu`, `Button`.
- Supports keyboard/cursor input and composition.
Use for interactive apps.
<div class="section_buttons">
| Next |
|--------------------------------------:|
| [Documentation](module-component.html) |
</div>
---
Modules can be used independently, or together: `screen → dom → component`.

View File

@ -1,119 +0,0 @@
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: #222222;
--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;
--fragment-lineheight: 1.125em;
}
/* 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

@ -3,7 +3,6 @@
// the LICENSE file.
#include <ftxui/component/component.hpp>
#include <ftxui/component/screen_interactive.hpp>
#include <string>
using namespace ftxui;

View File

@ -3,7 +3,6 @@
// the LICENSE file.
#include <ftxui/component/component.hpp>
#include <ftxui/component/screen_interactive.hpp>
#include <string>
using namespace ftxui;

View File

@ -8,21 +8,11 @@
#include <functional> // for function
namespace ftxui::animation {
/// @brief RequestAnimationFrame is a function that requests a new frame to be
/// drawn in the next animation cycle.
///
/// @note This function is typically called by components that need to
/// update their state or appearance over time, such as animations or
/// transitions. This is useful when the change doesn't depend depend on the
/// events seen by the terminal, but rather on the passage of time.
///
/// Components who haven't completed their animation can call this function to
/// request a new frame to be drawn later.
///
/// When there is no new events and no animations to complete, no new frame is
/// drawn.
///
/// @ingroup component
// Components who haven't completed their animation can call this function to
// request a new frame to be drawn later.
//
// When there is no new events and no animations to complete, no new frame is
// drawn.
void RequestAnimationFrame();
using Clock = std::chrono::steady_clock;

View File

@ -7,7 +7,6 @@
#include <memory>
namespace ftxui {
class CapturedMouseInterface {
public:
CapturedMouseInterface() = default;

View File

@ -17,8 +17,9 @@
namespace ftxui {
/// @brief arguments for transform from |ButtonOption|, |CheckboxOption|,
/// |RadioboxOption|, |MenuEntryOption|, |MenuOption|.
/// @brief arguments for |ButtonOption::transform|, |CheckboxOption::transform|,
/// |Radiobox::transform|, |MenuEntryOption::transform|,
/// |MenuOption::transform|.
struct EntryState {
std::string label; ///< The label to display.
bool state; ///< The state of the button/checkbox/radiobox
@ -27,8 +28,6 @@ struct EntryState {
int index; ///< Index of the entry when applicable or -1.
};
/// @brief Option for the underline effect.
/// @ingroup component
struct UnderlineOption {
bool enabled = false;
@ -232,8 +231,7 @@ struct SliderOption {
std::function<void()> on_change; ///> Called when `value` is updated.
};
/// @brief State passed to the `Window` component's render function.
/// @ingroup component
// Parameter pack used by `WindowOptions::render`.
struct WindowRenderState {
Element inner; ///< The element wrapped inside this window.
const std::string& title; ///< The title of the window.

View File

@ -24,8 +24,6 @@ class ComponentBase;
///
/// Useful documentation about xterm specification:
/// https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
///
/// @ingroup component
struct Event {
// --- Constructor section ---------------------------------------------------
static Event Character(std::string);

View File

@ -14,45 +14,6 @@ class ComponentBase;
using Component = std::shared_ptr<ComponentBase>;
class ScreenInteractive;
/// @brief Loop is a class that manages the event loop for a component.
///
/// It is responsible for running the component, handling events, and
/// updating the screen.
///
/// The Loop class is designed to be used with a ScreenInteractive object,
/// which represents the terminal screen.
///
/// **Example**
/// ```cpp
/// #include <ftxui/component/component.hpp>
/// #include <ftxui/component/screen_interactive.hpp>
/// #include <ftxui/component/loop.hpp>
///
/// int main() {
/// auto screen = ftxui::ScreenInteractive::TerminalOutput();
/// auto component = ftxui::Button("Click me", [] { ... });
///
/// ftxui::Loop loop(screen.get(), component);
///
/// // Either
/// loop.Run(); // Blocking until the component quits.
///
/// // Or
/// loop.RunOnce(); // Non-blocking, returns immediately.
///
/// // Or
/// loop.RunOnceBlocking(); // Blocking until handling one event.
///
/// // Or in a loop:
/// while (!loop.HasQuitted()) {
/// loop.RunOnce();
///
/// // Do something else like running a different library loop function.
/// }
/// }
/// ```
///
/// @ingroup component
class Loop {
public:
Loop(ScreenInteractive* screen, Component component);

View File

@ -10,6 +10,7 @@
#include <memory> // for shared_ptr
#include <string> // for string
#include <thread> // for thread
#include <variant> // for variant
#include "ftxui/component/animation.hpp" // for TimePoint
#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse
@ -26,10 +27,6 @@ struct Event;
using Component = std::shared_ptr<ComponentBase>;
class ScreenInteractivePrivate;
/// @brief ScreenInteractive is a `Screen` that can handle events, run a main
/// loop, and manage components.
///
/// @ingroup component
class ScreenInteractive : public Screen {
public:
// Constructors:
@ -104,12 +101,12 @@ class ScreenInteractive : public Screen {
Fullscreen,
TerminalOutput,
};
ScreenInteractive(Dimension dimension,
int dimx,
Dimension dimension_ = Dimension::Fixed;
bool use_alternative_screen_ = false;
ScreenInteractive(int dimx,
int dimy,
Dimension dimension,
bool use_alternative_screen);
const Dimension dimension_;
const bool use_alternative_screen_;
bool track_mouse_ = true;
@ -128,7 +125,6 @@ class ScreenInteractive : public Screen {
int cursor_x_ = 1;
int cursor_y_ = 1;
std::uint64_t frame_count_ = 0;
bool mouse_captured = false;
bool previous_frame_resized_ = false;

View File

@ -20,21 +20,6 @@
namespace ftxui {
/// @brief Canvas is a drawable buffer associated with drawing operations.
///
/// Canvas is a drawable area that can be used to create complex graphics. It
/// supports drawing points, lines, circles, ellipses, text, and images using
/// braille, block, or normal characters.
///
/// Note: A terminal contains cells. A cells is a unit of:
/// - 2x4 braille characters (1x1 pixel)
/// - 2x2 block characters (2x2 pixels)
/// - 2x4 normal characters (2x4 pixels)
///
/// You need to multiply the x coordinate by 2 and the y coordinate by 4 to
/// get the correct position in the terminal.
///
/// @ingroup dom
struct Canvas {
public:
Canvas() = default;

View File

@ -5,11 +5,6 @@
#define FTXUI_DOM_DIRECTION_HPP
namespace ftxui {
/// @brief Direction is an enumeration that represents the four cardinal
/// directions.
///
/// @ingroup dom
enum class Direction {
Up = 0,
Down = 1,

View File

@ -24,14 +24,6 @@ using Elements = std::vector<Element>;
using Decorator = std::function<Element(Element)>;
using GraphFunction = std::function<std::vector<int>(int, int)>;
/// @brief BorderStyle is an enumeration that represents the different styles
/// of borders that can be applied to elements in the terminal UI.
///
/// BorderStyle is an enumeration that represents the different styles of
/// borders that can be applied to elements in the terminal UI.
/// It is used to define the visual appearance of borders around elements,
/// such as windows, frames, or separators.
/// @ingroup dom
enum BorderStyle {
LIGHT,
DASHED,

View File

@ -12,19 +12,6 @@
namespace ftxui {
/// @brief FlexboxConfig is a configuration structure that defines the layout
/// properties for a flexbox container.
//
/// It allows you to specify the direction of the flex items, whether they
/// should wrap, how they should be justified along the main axis, and how
/// they should be aligned along the cross axis.
/// It also includes properties for gaps between flex items in both the
/// main and cross axes.
/// This structure is used to configure the layout behavior of flexbox
/// containers in a terminal user interface.
///
/// @ingroup dom
struct FlexboxConfig {
/// This establishes the main-axis, thus defining the direction flex items are
/// placed in the flex container. Flexbox is (aside wrapping) single-direction

View File

@ -27,15 +27,8 @@ namespace ftxui {
/// LinearGradient(Color::Red, Color::Blue);
/// LinearGradient(45, Color::Red, Color::Blue);
/// ```
///
/// @ingroup dom
struct LinearGradient {
float angle = 0.f;
/// A stop is a color at a specific position in the gradient.
/// The position is a value between 0.0 and 1.0,
/// where 0.0 is the start of the gradient
/// and 1.0 is the end of the gradient.
struct Stop {
Color color = Color::Default;
std::optional<float> position;

View File

@ -20,20 +20,6 @@ class Screen;
using Element = std::shared_ptr<Node>;
using Elements = std::vector<Element>;
/// @brief Node is the base class for all elements in the DOM tree.
///
/// It represents a single node in the document object model (DOM) and provides
/// the basic structure for layout and rendering.
/// It contains methods for computing layout requirements, setting the box
/// dimensions, selecting content, rendering to the screen, and checking the
/// layout status.
/// It typically contains child elements, which are also instances of Node.
///
/// Users are expected to derive from this class to create custom elements.
///
/// A list of builtin elements can be found in the `elements.hpp` file.
///
/// @ingroup dom
class Node {
public:
Node();

View File

@ -10,11 +10,6 @@
namespace ftxui {
class Node;
/// @brief Requirement is a structure that defines the layout requirements for a
/// Node in the terminal user interface.
///
/// It specifies the minimum size required to fully draw the element,
/// @ingroup dom
struct Requirement {
// The required size to fully draw the element.
int min_x = 0;

View File

@ -13,12 +13,7 @@
namespace ftxui {
/// @brief Represents a selection in a terminal user interface.
///
/// Selection is a class that represents the two endpoints of a selection in a
/// terminal user interface.
///
/// @ingroup dom
/// @brief Represent a selection in the terminal.
class Selection {
public:
Selection(); // Empty selection.

View File

@ -11,28 +11,28 @@
namespace ftxui {
// Usage:
//
// Initialization:
// ---------------
//
// auto table = Table({
// {"X", "Y"},
// {"-1", "1"},
// {"+0", "0"},
// {"+1", "1"},
// });
//
// table.SelectAll().Border(LIGHT);
//
// table.SelectRow(1).Border(DOUBLE);
// table.SelectRow(1).SeparatorInternal(Light);
//
// std::move(table).Element();
class Table;
class TableSelection;
/// @brief Table is a utility to draw tables.
///
/// **example**
/// ```cpp
/// auto table = Table({
/// {"X", "Y"},
/// {"-1", "1"},
/// {"+0", "0"},
/// {"+1", "1"},
/// });
///
/// table.SelectAll().Border(LIGHT);
/// table.SelectRow(1).Border(DOUBLE);
/// table.SelectRow(1).SeparatorInternal(LIGHT);
///
/// std::move(table).Render();
/// ```
///
/// @ingroup dom
class Table {
public:
Table();

View File

@ -6,13 +6,6 @@
namespace ftxui {
/// @brief Box is a structure that represents a rectangular area in a 2D space.
///
/// It is defined by its minimum and maximum coordinates along the x and y axes.
/// Note that the coordinates are inclusive, meaning that the box includes both
/// the minimum and maximum values.
///
/// @ingroup screen
struct Box {
int x_min = 0;
int x_max = 0;

View File

@ -15,9 +15,7 @@
namespace ftxui {
/// @brief Color is a class that represents a color in the terminal user
/// interface.
///
/// @brief A class representing terminal colors.
/// @ingroup screen
class Color {
public:

View File

@ -9,10 +9,6 @@
namespace ftxui {
/// @brief ColorInfo is a structure that contains information about the terminal
/// color palette.
///
/// @ingroup screen
struct ColorInfo {
const char* name;
uint8_t index_256;

View File

@ -5,9 +5,6 @@
#define FTXUI_SCREEN_TERMINAL_HPP
namespace ftxui {
/// @brief Dimensions is a structure that represents the size of the terminal
/// @ingroup screen
struct Dimensions {
int dimx;
int dimy;
@ -17,9 +14,6 @@ namespace Terminal {
Dimensions Size();
void SetFallbackSize(const Dimensions& fallbackSize);
/// @brief Color is an enumeration that represents the color support of the
/// terminal.
/// @ingroup screen
enum Color {
Palette1,
Palette16,

View File

@ -1,16 +0,0 @@
/// @module ftxui.component
/// @brief Module file for FTXUI component operations.
export module ftxui.component;
export import ftxui.component.animation;
export import ftxui.component.captured_mouse;
export import ftxui.component.component;
export import ftxui.component.component_base;
export import ftxui.component.component_options;
export import ftxui.component.event;
export import ftxui.component.loop;
export import ftxui.component.mouse;
export import ftxui.component.receiver;
export import ftxui.component.screen_interactive;
export import ftxui.component.task;

View File

@ -1,65 +0,0 @@
/// @module ftxui.component.animation
/// @brief C++20 module interface for the Animation namespace of the Component module.
///
module;
#include <ftxui/component/animation.hpp>
export module ftxui.component.animation;
/**
* @namespace ftxui::animation
* @brief The FTXUI ftxui::animation:: namespace
*/
export namespace ftxui::animation {
using ftxui::animation::RequestAnimationFrame;
using ftxui::animation::Clock;
using ftxui::animation::TimePoint;
using ftxui::animation::Duration;
using ftxui::animation::Params;
/**
* @namespace easing
* @brief The FTXUI sf::animation::easing:: namespace
*/
namespace easing {
using ftxui::animation::easing::Function;
using ftxui::animation::easing::Linear;
using ftxui::animation::easing::QuadraticIn;
using ftxui::animation::easing::QuadraticOut;
using ftxui::animation::easing::QuadraticInOut;
using ftxui::animation::easing::CubicIn;
using ftxui::animation::easing::CubicOut;
using ftxui::animation::easing::CubicInOut;
using ftxui::animation::easing::QuarticIn;
using ftxui::animation::easing::QuarticOut;
using ftxui::animation::easing::QuarticInOut;
using ftxui::animation::easing::QuinticIn;
using ftxui::animation::easing::QuinticOut;
using ftxui::animation::easing::QuinticInOut;
using ftxui::animation::easing::SineIn;
using ftxui::animation::easing::SineOut;
using ftxui::animation::easing::SineInOut;
using ftxui::animation::easing::CircularIn;
using ftxui::animation::easing::CircularOut;
using ftxui::animation::easing::CircularInOut;
using ftxui::animation::easing::ExponentialIn;
using ftxui::animation::easing::ExponentialOut;
using ftxui::animation::easing::ExponentialInOut;
using ftxui::animation::easing::ElasticIn;
using ftxui::animation::easing::ElasticOut;
using ftxui::animation::easing::ElasticInOut;
using ftxui::animation::easing::BackIn;
using ftxui::animation::easing::BackOut;
using ftxui::animation::easing::BackInOut;
using ftxui::animation::easing::BounceIn;
using ftxui::animation::easing::BounceOut;
using ftxui::animation::easing::BounceInOut;
}
using ftxui::animation::Animator;
}

View File

@ -1,16 +0,0 @@
/// @module ftxui.component.captured_mouse
/// @brief Module file for the CapturedMouseInterface class of the Component module
module;
#include <ftxui/component/captured_mouse.hpp>
export module ftxui.component.captured_mouse;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::CapturedMouseInterface;
}

View File

@ -12,11 +12,11 @@
namespace ftxui {
/// @brief A collapsible component. It displays a checkbox with an arrow. Once
/// activated, the child is displayed.
/// @brief A collapsible component. It display a checkbox with an arrow. Once
/// activated, the children is displayed.
/// @param label The label of the checkbox.
/// @param child The child to display.
/// @param show Hold the state about whether the child is displayed or not.
/// @param child The children to display.
/// @param show Hold the state about whether the children is displayed or not.
///
/// ### Example
/// ```cpp
@ -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

@ -35,22 +35,26 @@ ComponentBase::~ComponentBase() {
/// @brief Return the parent ComponentBase, or nul if any.
/// @see Detach
/// @see Parent
/// @ingroup component
ComponentBase* ComponentBase::Parent() const {
return parent_;
}
/// @brief Access the child at index `i`.
/// @ingroup component
Component& ComponentBase::ChildAt(size_t i) {
assert(i < ChildCount()); // NOLINT
return children_[i];
}
/// @brief Returns the number of children.
/// @ingroup component
size_t ComponentBase::ChildCount() const {
return children_.size();
}
/// @brief Return index of the component in its parent. -1 if no parent.
/// @ingroup component
int ComponentBase::Index() const {
if (parent_ == nullptr) {
return -1;
@ -67,6 +71,7 @@ int ComponentBase::Index() const {
/// @brief Add a child.
/// @@param child The child to be attached.
/// @ingroup component
void ComponentBase::Add(Component child) {
child->Detach();
child->parent_ = this;
@ -76,6 +81,7 @@ void ComponentBase::Add(Component child) {
/// @brief Detach this child from its parent.
/// @see Detach
/// @see Parent
/// @ingroup component
void ComponentBase::Detach() {
if (parent_ == nullptr) {
return;
@ -91,6 +97,7 @@ void ComponentBase::Detach() {
}
/// @brief Remove all children.
/// @ingroup component
void ComponentBase::DetachAllChildren() {
while (!children_.empty()) {
children_[0]->Detach();
@ -100,6 +107,7 @@ void ComponentBase::DetachAllChildren() {
/// @brief Draw the component.
/// Build a ftxui::Element to be drawn on the ftxui::Screen representing this
/// ftxui::ComponentBase. Please override OnRender() to modify the rendering.
/// @ingroup component
Element ComponentBase::Render() {
// Some users might call `ComponentBase::Render()` from
// `T::OnRender()`. To avoid infinite recursion, we use a flag.
@ -135,6 +143,7 @@ Element ComponentBase::Render() {
/// @brief Draw the component.
/// Build a ftxui::Element to be drawn on the ftxi::Screen representing this
/// ftxui::ComponentBase. This function is means to be overridden.
/// @ingroup component
Element ComponentBase::OnRender() {
if (children_.size() == 1) {
return children_.front()->Render();
@ -148,6 +157,7 @@ Element ComponentBase::OnRender() {
/// @return True when the event has been handled.
/// The default implementation called OnEvent on every child until one return
/// true. If none returns true, return false.
/// @ingroup component
bool ComponentBase::OnEvent(Event event) { // NOLINT
for (Component& child : children_) { // NOLINT
if (child->OnEvent(event)) {
@ -160,6 +170,7 @@ bool ComponentBase::OnEvent(Event event) { // NOLINT
/// @brief Called in response to an animation event.
/// @param params the parameters of the animation
/// The default implementation dispatch the event to every child.
/// @ingroup component
void ComponentBase::OnAnimation(animation::Params& params) {
for (const Component& child : children_) {
child->OnAnimation(params);
@ -168,6 +179,7 @@ void ComponentBase::OnAnimation(animation::Params& params) {
/// @brief Return the currently Active child.
/// @return the currently Active child.
/// @ingroup component
Component ComponentBase::ActiveChild() {
for (auto& child : children_) {
if (child->Focusable()) {
@ -180,6 +192,7 @@ Component ComponentBase::ActiveChild() {
/// @brief Return true when the component contains focusable elements.
/// The non focusable Components will be skipped when navigating using the
/// keyboard.
/// @ingroup component
bool ComponentBase::Focusable() const {
for (const Component& child : children_) { // NOLINT
if (child->Focusable()) {
@ -190,6 +203,7 @@ bool ComponentBase::Focusable() const {
}
/// @brief Returns if the element if the currently active child of its parent.
/// @ingroup component
bool ComponentBase::Active() const {
return parent_ == nullptr || parent_->ActiveChild().get() == this;
}
@ -198,6 +212,7 @@ bool ComponentBase::Active() const {
/// True when the ComponentBase is focused by the user. An element is Focused
/// when it is with all its ancestors the ActiveChild() of their parents, and it
/// Focusable().
/// @ingroup component
bool ComponentBase::Focused() const {
const auto* current = this;
while (current && current->Active()) {
@ -208,15 +223,18 @@ bool ComponentBase::Focused() const {
/// @brief Make the |child| to be the "active" one.
/// @param child the child to become active.
/// @ingroup component
void ComponentBase::SetActiveChild([[maybe_unused]] ComponentBase* child) {}
/// @brief Make the |child| to be the "active" one.
/// @param child the child to become active.
/// @ingroup component
void ComponentBase::SetActiveChild(Component child) { // NOLINT
SetActiveChild(child.get());
}
/// @brief Configure all the ancestors to give focus to this component.
/// @ingroup component
void ComponentBase::TakeFocus() {
ComponentBase* child = this;
while (ComponentBase* parent = child->parent_) {
@ -228,6 +246,7 @@ void ComponentBase::TakeFocus() {
/// @brief Take the CapturedMouse if available. There is only one component of
/// them. It represents a component taking priority over others.
/// @param event The event
/// @ingroup component
CapturedMouse ComponentBase::CaptureMouse(const Event& event) { // NOLINT
if (event.screen_) {
return event.screen_->CaptureMouse();

View File

@ -1,59 +0,0 @@
/// @module ftxui.component.component
/// @brief Module file for the Component classes of the Component module
module;
#include <ftxui/component/component.hpp>
export module ftxui.component.component;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::ButtonOption;
using ftxui::CheckboxOption;
using ftxui::Event;
using ftxui::InputOption;
using ftxui::MenuOption;
using ftxui::RadioboxOption;
using ftxui::MenuEntryOption;
using ftxui::Make;
using ftxui::ComponentDecorator;
using ftxui::ElementDecorator;
using ftxui::operator|;
using ftxui::operator|=;
namespace Container {
using ftxui::Container::Vertical;
using ftxui::Container::Horizontal;
using ftxui::Container::Tab;
using ftxui::Container::Stacked;
}
using ftxui::Button;
using ftxui::Checkbox;
using ftxui::Input;
using ftxui::Menu;
using ftxui::MenuEntry;
using ftxui::Radiobox;
using ftxui::Dropdown;
using ftxui::Toggle;
using ftxui::Slider;
using ftxui::ResizableSplit;
using ftxui::ResizableSplitLeft;
using ftxui::ResizableSplitRight;
using ftxui::ResizableSplitTop;
using ftxui::ResizableSplitBottom;
using ftxui::Renderer;
using ftxui::CatchEvent;
using ftxui::Maybe;
using ftxui::Modal;
using ftxui::Collapsible;
using ftxui::Hoverable;
using ftxui::Window;
}

View File

@ -1,26 +0,0 @@
/// @module ftxui.component.component_base
/// @brief Module file for the ComponentBase class of the Component module
module;
#include <ftxui/component/component_base.hpp>
export module ftxui.component.component_base;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::Delegate;
using ftxui::Focus;
using ftxui::Event;
namespace animation {
using ftxui::animation::Params;
}
using ftxui::ComponentBase;
using ftxui::Component;
using ftxui::Components;
}

View File

@ -17,6 +17,7 @@ namespace ftxui {
/// @params _active The color when the component is active.
/// @params _duration The duration of the animation.
/// @params _function The easing function of the animation.
/// @ingroup component
void AnimatedColorOption::Set(Color _inactive,
Color _active,
animation::Duration _duration,
@ -31,6 +32,7 @@ void AnimatedColorOption::Set(Color _inactive,
/// @brief Set how the underline should animate.
/// @param d The duration of the animation.
/// @param f The easing function of the animation.
/// @ingroup component
void UnderlineOption::SetAnimation(animation::Duration d,
animation::easing::Function f) {
SetAnimationDuration(d);
@ -39,6 +41,7 @@ void UnderlineOption::SetAnimation(animation::Duration d,
/// @brief Set how the underline should animate.
/// @param d The duration of the animation.
/// @ingroup component
void UnderlineOption::SetAnimationDuration(animation::Duration d) {
leader_duration = d;
follower_duration = d;
@ -46,6 +49,7 @@ void UnderlineOption::SetAnimationDuration(animation::Duration d) {
/// @brief Set how the underline should animate.
/// @param f The easing function of the animation.
/// @ingroup component
void UnderlineOption::SetAnimationFunction(animation::easing::Function f) {
leader_function = f;
follower_function = std::move(f);
@ -56,6 +60,7 @@ void UnderlineOption::SetAnimationFunction(animation::easing::Function f) {
/// follower.
/// @param f_leader The duration of the animation for the leader.
/// @param f_follower The duration of the animation for the follower.
/// @ingroup component
void UnderlineOption::SetAnimationFunction(
animation::easing::Function f_leader,
animation::easing::Function f_follower) {
@ -63,8 +68,9 @@ void UnderlineOption::SetAnimationFunction(
follower_function = std::move(f_follower);
}
/// @brief Standard options for a horizontal menu.
/// @brief Standard options for an horizontal menu.
/// This can be useful to implement a tab bar.
/// @ingroup component
// static
MenuOption MenuOption::Horizontal() {
MenuOption option;
@ -89,6 +95,7 @@ MenuOption MenuOption::Horizontal() {
/// @brief Standard options for an animated horizontal menu.
/// This can be useful to implement a tab bar.
/// @ingroup component
// static
MenuOption MenuOption::HorizontalAnimated() {
auto option = Horizontal();
@ -98,6 +105,7 @@ MenuOption MenuOption::HorizontalAnimated() {
/// @brief Standard options for a vertical menu.
/// This can be useful to implement a list of selectable items.
/// @ingroup component
// static
MenuOption MenuOption::Vertical() {
MenuOption option;
@ -119,6 +127,7 @@ MenuOption MenuOption::Vertical() {
/// @brief Standard options for an animated vertical menu.
/// This can be useful to implement a list of selectable items.
/// @ingroup component
// static
MenuOption MenuOption::VerticalAnimated() {
auto option = MenuOption::Vertical();
@ -139,8 +148,9 @@ MenuOption MenuOption::VerticalAnimated() {
return option;
}
/// @brief Standard options for a horizontal menu with some separator.
/// @brief Standard options for a horitontal menu with some separator.
/// This can be useful to implement a tab bar.
/// @ingroup component
// static
MenuOption MenuOption::Toggle() {
auto option = MenuOption::Horizontal();
@ -149,6 +159,7 @@ MenuOption MenuOption::Toggle() {
}
/// @brief Create a ButtonOption, highlighted using [] characters.
/// @ingroup component
// static
ButtonOption ButtonOption::Ascii() {
ButtonOption option;
@ -161,6 +172,7 @@ ButtonOption ButtonOption::Ascii() {
}
/// @brief Create a ButtonOption, inverted when focused.
/// @ingroup component
// static
ButtonOption ButtonOption::Simple() {
ButtonOption option;
@ -176,6 +188,7 @@ ButtonOption ButtonOption::Simple() {
/// @brief Create a ButtonOption. The button is shown using a border, inverted
/// when focused. This is the current default.
/// @ingroup component
ButtonOption ButtonOption::Border() {
ButtonOption option;
option.transform = [](const EntryState& s) {
@ -192,6 +205,7 @@ ButtonOption ButtonOption::Border() {
}
/// @brief Create a ButtonOption, using animated colors.
/// @ingroup component
// static
ButtonOption ButtonOption::Animated() {
return Animated(Color::Black, Color::GrayLight, //
@ -199,6 +213,7 @@ ButtonOption ButtonOption::Animated() {
}
/// @brief Create a ButtonOption, using animated colors.
/// @ingroup component
// static
ButtonOption ButtonOption::Animated(Color color) {
return ButtonOption::Animated(
@ -209,6 +224,7 @@ ButtonOption ButtonOption::Animated(Color color) {
}
/// @brief Create a ButtonOption, using animated colors.
/// @ingroup component
// static
ButtonOption ButtonOption::Animated(Color background, Color foreground) {
// NOLINTBEGIN
@ -221,6 +237,7 @@ ButtonOption ButtonOption::Animated(Color background, Color foreground) {
}
/// @brief Create a ButtonOption, using animated colors.
/// @ingroup component
// static
ButtonOption ButtonOption::Animated(Color background,
Color foreground,
@ -240,6 +257,7 @@ ButtonOption ButtonOption::Animated(Color background,
}
/// @brief Option for standard Checkbox.
/// @ingroup component
// static
CheckboxOption CheckboxOption::Simple() {
auto option = CheckboxOption();
@ -264,6 +282,7 @@ CheckboxOption CheckboxOption::Simple() {
}
/// @brief Option for standard Radiobox
/// @ingroup component
// static
RadioboxOption RadioboxOption::Simple() {
auto option = RadioboxOption();
@ -288,6 +307,7 @@ RadioboxOption RadioboxOption::Simple() {
}
/// @brief Standard options for the input component.
/// @ingroup component
// static
InputOption InputOption::Default() {
InputOption option;
@ -310,6 +330,7 @@ InputOption InputOption::Default() {
}
/// @brief Standard options for a more beautiful input component.
/// @ingroup component
// static
InputOption InputOption::Spacious() {
InputOption option;

View File

@ -1,31 +0,0 @@
/// @module ftxui.component.component_options
/// @brief Module file for options for the Component class of the Component module
module;
#include <ftxui/component/component_options.hpp>
export module ftxui.component.component_options;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::EntryState;
using ftxui::UnderlineOption;
using ftxui::AnimatedColorOption;
using ftxui::AnimatedColorsOption;
using ftxui::MenuEntryOption;
using ftxui::MenuOption;
using ftxui::ButtonOption;
using ftxui::CheckboxOption;
using ftxui::InputState;
using ftxui::InputOption;
using ftxui::RadioboxOption;
using ftxui::ResizableSplitOption;
using ftxui::SliderOption;
using ftxui::WindowRenderState;
using ftxui::WindowOptions;
using ftxui::DropdownOption;
}

View File

@ -24,6 +24,7 @@ namespace ftxui {
/// @brief An event corresponding to a given typed character.
/// @param input The character typed by the user.
/// @ingroup component
// static
Event Event::Character(std::string input) {
Event event;
@ -34,6 +35,7 @@ Event Event::Character(std::string input) {
/// @brief An event corresponding to a given typed character.
/// @param c The character typed by the user.
/// @ingroup component
// static
Event Event::Character(char c) {
return Event::Character(std::string{c});
@ -41,6 +43,7 @@ Event Event::Character(char c) {
/// @brief An event corresponding to a given typed character.
/// @param c The character typed by the user.
/// @ingroup component
// static
Event Event::Character(wchar_t c) {
return Event::Character(to_string(std::wstring{c}));
@ -49,6 +52,7 @@ Event Event::Character(wchar_t c) {
/// @brief An event corresponding to a given typed character.
/// @param input The sequence of character send by the terminal.
/// @param mouse The mouse state.
/// @ingroup component
// static
Event Event::Mouse(std::string input, struct Mouse mouse) {
Event event;
@ -70,6 +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.
// static
Event Event::Special(std::string input) {
Event event;

View File

@ -1,19 +0,0 @@
/// @module ftxui.component.event
/// @brief Module file for the Event struct of the Component module
module;
#include <ftxui/component/event.hpp>
export module ftxui.component.event;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::ScreenInteractive;
using ftxui::ComponentBase;
using ftxui::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,7 +603,6 @@ 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

@ -11,6 +11,7 @@ namespace ftxui {
/// @brief A Loop is a wrapper around a Component and a ScreenInteractive.
/// It is used to run a Component in a terminal.
/// @ingroup component
/// @see Component, ScreenInteractive.
/// @see ScreenInteractive::Loop().
/// @see ScreenInteractive::ExitLoop().
@ -27,6 +28,7 @@ Loop::~Loop() {
}
/// @brief Whether the loop has quitted.
/// @ingroup component
bool Loop::HasQuitted() {
return screen_->HasQuitted();
}

View File

@ -1,20 +0,0 @@
/// @module ftxui.component.loop
/// @brief Module file for the Loop class of the Component module
module;
#include <ftxui/component/loop.hpp>
export module ftxui.component.loop;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::ComponentBase;
using ftxui::Component;
using ftxui::ScreenInteractive;
using ftxui::Loop;
}

View File

@ -15,7 +15,7 @@ namespace ftxui {
/// @brief Decorate a component |child|. It is shown only when |show| returns
/// true.
/// @param child the component to decorate.
/// @param child the compoenent to decorate.
/// @param show a function returning whether |child| should shown.
/// @ingroup component
Component Maybe(Component child, std::function<bool()> show) {
@ -61,7 +61,7 @@ ComponentDecorator Maybe(std::function<bool()> show) {
}
/// @brief Decorate a component |child|. It is shown only when |show| is true.
/// @param child the component to decorate.
/// @param child the compoennt to decorate.
/// @param show a boolean. |child| is shown when |show| is true.
/// @ingroup component
///

View File

@ -1,16 +0,0 @@
/// @module ftxui.component.mouse
/// @brief Module file for the Mouse struct of the Component module
module;
#include <ftxui/component/mouse.hpp>
export module ftxui.component.mouse;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::Mouse;
}

View File

@ -1,20 +0,0 @@
/// @module ftxui.component.receiver
/// @brief Module file for the Receiver class of the Component module
module;
#include <ftxui/component/receiver.hpp>
export module ftxui.component.receiver;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::SenderImpl;
using ftxui::ReceiverImpl;
using ftxui::Sender;
using ftxui::Receiver;
using ftxui::MakeReceiver;
}

View File

@ -346,9 +346,9 @@ void AnimationListener(std::atomic<bool>* quit, Sender<Task> out) {
} // namespace
ScreenInteractive::ScreenInteractive(Dimension dimension,
int dimx,
ScreenInteractive::ScreenInteractive(int dimx,
int dimy,
Dimension dimension,
bool use_alternative_screen)
: Screen(dimx, dimy),
dimension_(dimension),
@ -359,13 +359,14 @@ ScreenInteractive::ScreenInteractive(Dimension dimension,
// static
ScreenInteractive ScreenInteractive::FixedSize(int dimx, int dimy) {
return {
Dimension::Fixed,
dimx,
dimy,
/*use_alternative_screen=*/false,
Dimension::Fixed,
false,
};
}
/// @ingroup component
/// Create a ScreenInteractive taking the full terminal size. This is using the
/// alternate screen buffer to avoid messing with the terminal content.
/// @note This is the same as `ScreenInteractive::FullscreenAlternateScreen()`
@ -374,59 +375,54 @@ ScreenInteractive ScreenInteractive::Fullscreen() {
return FullscreenAlternateScreen();
}
/// @ingroup component
/// Create a ScreenInteractive taking the full terminal size. The primary screen
/// buffer is being used. It means if the terminal is resized, the previous
/// content might mess up with the terminal content.
// static
ScreenInteractive ScreenInteractive::FullscreenPrimaryScreen() {
auto terminal = Terminal::Size();
return {
Dimension::Fullscreen,
terminal.dimx,
terminal.dimy,
/*use_alternative_screen=*/false,
};
}
/// Create a ScreenInteractive taking the full terminal size. This is using the
/// alternate screen buffer to avoid messing with the terminal content.
// static
ScreenInteractive ScreenInteractive::FullscreenAlternateScreen() {
auto terminal = Terminal::Size();
return {
0,
0,
Dimension::Fullscreen,
terminal.dimx,
terminal.dimy,
/*use_alternative_screen=*/true,
};
}
/// Create a ScreenInteractive whose width match the terminal output width and
/// the height matches the component being drawn.
// static
ScreenInteractive ScreenInteractive::TerminalOutput() {
auto terminal = Terminal::Size();
return {
Dimension::TerminalOutput,
terminal.dimx,
terminal.dimy, // Best guess.
/*use_alternative_screen=*/false,
};
}
/// Create a ScreenInteractive whose width and height match the component being
/// drawn.
// static
ScreenInteractive ScreenInteractive::FitComponent() {
auto terminal = Terminal::Size();
return {
Dimension::FitComponent,
terminal.dimx, // Best guess.
terminal.dimy, // Best guess.
false,
};
}
/// @ingroup component
/// Create a ScreenInteractive taking the full terminal size. This is using the
/// alternate screen buffer to avoid messing with the terminal content.
// static
ScreenInteractive ScreenInteractive::FullscreenAlternateScreen() {
return {
0,
0,
Dimension::Fullscreen,
true,
};
}
// static
ScreenInteractive ScreenInteractive::TerminalOutput() {
return {
0,
0,
Dimension::TerminalOutput,
false,
};
}
// static
ScreenInteractive ScreenInteractive::FitComponent() {
return {
0,
0,
Dimension::FitComponent,
false,
};
}
/// @ingroup component
/// @brief Set whether mouse is tracked and events reported.
/// called outside of the main loop. E.g `ScreenInteractive::Loop(...)`.
/// @param enable Whether to enable mouse event tracking.
@ -448,6 +444,7 @@ void ScreenInteractive::TrackMouse(bool enable) {
/// @brief Add a task to the main loop.
/// It will be executed later, after every other scheduled tasks.
/// @ingroup component
void ScreenInteractive::Post(Task task) {
// Task/Events sent toward inactive screen or screen waiting to become
// inactive are dropped.
@ -460,6 +457,7 @@ void ScreenInteractive::Post(Task task) {
/// @brief Add an event to the main loop.
/// It will be executed later, after every other scheduled events.
/// @ingroup component
void ScreenInteractive::PostEvent(Event event) {
Post(event);
}
@ -481,6 +479,7 @@ void ScreenInteractive::RequestAnimationFrame() {
/// @brief Try to get the unique lock about behing able to capture the mouse.
/// @return A unique lock if the mouse is not already captured, otherwise a
/// null.
/// @ingroup component
CapturedMouse ScreenInteractive::CaptureMouse() {
if (mouse_captured) {
return nullptr;
@ -492,12 +491,14 @@ CapturedMouse ScreenInteractive::CaptureMouse() {
/// @brief Execute the main loop.
/// @param component The component to draw.
/// @ingroup component
void ScreenInteractive::Loop(Component component) { // NOLINT
class Loop loop(this, std::move(component));
loop.Run();
}
/// @brief Return whether the main loop has been quit.
/// @ingroup component
bool ScreenInteractive::HasQuitted() {
return task_receiver_->HasQuitted();
}
@ -929,7 +930,7 @@ void ScreenInteractive::Draw(Component component) {
break;
}
const bool resized = frame_count_ == 0 || (dimx != dimx_) || (dimy != dimy_);
const bool resized = (dimx != dimx_) || (dimy != dimy_);
ResetCursorPosition();
std::cout << ResetPosition(/*clear=*/resized);
@ -1012,7 +1013,6 @@ void ScreenInteractive::Draw(Component component) {
Flush();
Clear();
frame_valid_ = true;
frame_count_++;
}
// private
@ -1022,11 +1022,13 @@ void ScreenInteractive::ResetCursorPosition() {
}
/// @brief Return a function to exit the main loop.
/// @ingroup component
Closure ScreenInteractive::ExitLoopClosure() {
return [this] { Exit(); };
}
/// @brief Exit the main loop.
/// @ingroup component
void ScreenInteractive::Exit() {
Post([this] { ExitNow(); });
}

View File

@ -1,23 +0,0 @@
/// @module ftxui.component.screen_interactive
/// @brief Module file for the ScreenInteractive class of the Component module
module;
#include <ftxui/component/screen_interactive.hpp>
export module ftxui.component.screen_interactive;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::ComponentBase;
using ftxui::Loop;
using ftxui::Event;
using ftxui::Component;
using ftxui::Screen;
using ftxui::ScreenInteractivePrivate;
using ftxui::ScreenInteractive;
}

View File

@ -10,57 +10,9 @@
#include "ftxui/component/screen_interactive.hpp"
#include "ftxui/dom/elements.hpp" // for text, Element
#if defined(__unix__)
#include <fcntl.h>
#include <unistd.h>
#include <array>
#include <cstdio>
#include <ftxui/component/loop.hpp>
#include <string>
#endif
namespace ftxui {
namespace {
#if defined(__unix__)
// Capture the standard output (stdout) to a string.
class StdCapture {
public:
explicit StdCapture(std::string* captured)
: captured_(captured) {
if (pipe(pipefd_) != 0) return;
old_stdout_ = dup(fileno(stdout));
fflush(stdout);
dup2(pipefd_[1], fileno(stdout));
close(pipefd_[1]); // Close the write end in the parent
}
~StdCapture() {
fflush(stdout);
dup2(old_stdout_, fileno(stdout));
close(old_stdout_);
char buffer[1024];
ssize_t count;
while ((count = read(pipefd_[0], buffer, sizeof(buffer))) > 0) {
captured_->append(buffer, count);
}
close(pipefd_[0]);
}
StdCapture(const StdCapture&) = delete;
StdCapture& operator=(const StdCapture&) = delete;
private:
int pipefd_[2]{-1, -1};
int old_stdout_{-1};
std::string* const captured_;
};
#endif
bool TestSignal(int signal) {
int called = 0;
// The tree of components. This defines how to navigate using the keyboard.
@ -179,69 +131,4 @@ TEST(ScreenInteractive, CtrlC_NotForced) {
ASSERT_GE(ctrl_c_count, 50);
}
// Regression test for:
// https://github.com/ArthurSonzogni/FTXUI/pull/1064/files
TEST(ScreenInteractive, FixedSizeInitialFrame) {
#if defined(__unix__)
std::string output;
{
auto capture = StdCapture(&output);
auto screen = ScreenInteractive::FixedSize(2, 2);
auto component = Renderer([&] {
return text("AB");
});
Loop loop(&screen, component);
loop.RunOnce();
}
using namespace std::string_view_literals;
auto expected =
// Install the ScreenInteractive.
"\0" // Flush stdout.
"\x1BP$q q" // Set cursor shape to 1 (block).
"\x1B\\" // Reset cursor position.
"\x1B[?7l" // Disable line wrapping.
"\x1B[?1000h" // Enable mouse tracking.
"\x1B[?1003h" // Enable mouse motion tracking.
"\x1B[?1015h" // Enable mouse wheel tracking.
"\x1B[?1006h" // Enable SGR mouse tracking.
"\0" // Flush stdout.
// Reset the screen.
"\r" // Reset cursor position.
"\x1B[2K" // Clear the line.
"\x1B[1A" // Move cursor up one line.
"\x1B[2K" // Clear the line.
// Print the document.
"AB\r\n" // Print "AB" and move to the next line.
" " // Print two spaces to fill the line.
// Set cursor position.
"\x1B[1D" // Move cursor left one character.
"\x1B[?25l" // Hide cursor.
// Flush
"\0" // Flush stdout.
// Uninstall the ScreenInteractive.
"\x1B[1C" // Move cursor right one character.
"\x1B[?1006l" // Disable SGR mouse tracking.
"\x1B[?1015l" // Disable mouse wheel tracking.
"\x1B[?1003l" // Disable mouse motion tracking.
"\x1B[?1000l" // Disable mouse tracking.
"\x1B[?7h" // Enable line wrapping.
"\x1B[?25h" // Show cursor.
"\x1B[1 q" // Set cursor shape to 1 (block).
"\0" // Flush stdout.
// Skip one line to avoid the prompt to be printed over the last drawing.
"\r\n"sv;
ASSERT_EQ(expected, output);
#endif
}
} // namespace ftxui

View File

@ -1,18 +0,0 @@
/// @module ftxui.component.task
/// @brief Module file for the Task class of the Component module
module;
#include <ftxui/component/task.hpp>
export module ftxui.component.task;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::AnimationTask;
using ftxui::Closure;
using ftxui::Task;
}

View File

@ -1,15 +0,0 @@
/// @module ftxui.dom
/// @brief Module file for FTXUI main operations.
export module ftxui.dom;
export import ftxui.dom.canvas;
export import ftxui.dom.deprecated;
export import ftxui.dom.direction;
export import ftxui.dom.elements;
export import ftxui.dom.flexbox_config;
export import ftxui.dom.linear_gradient;
export import ftxui.dom.node;
export import ftxui.dom.requirement;
export import ftxui.dom.selection;
export import ftxui.dom.table;

View File

@ -1,16 +0,0 @@
/// @module ftxui.dom.canvas
/// @brief Module file for the Canvas struct of the Dom module
module;
#include <ftxui/dom/canvas.hpp>
export module ftxui.dom.canvas;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::Canvas;
}

View File

@ -32,7 +32,7 @@ class ClearUnder : public NodeDecorator {
} // namespace
/// @brief Before drawing |child|, clear the pixels below. This is useful in
/// combination with dbox.
// combinaison with dbox.
/// @see ftxui::dbox
/// @ingroup dom
Element clear_under(Element element) {

View File

@ -45,6 +45,59 @@ class DBox : public Node {
child->SetBox(box);
}
}
void Render(Screen& screen) override {
if (children_.size() <= 1) {
Node::Render(screen);
return;
}
const int width = box_.x_max - box_.x_min + 1;
const int height = box_.y_max - box_.y_min + 1;
std::vector<Pixel> pixels(std::size_t(width * height));
for (auto& child : children_) {
child->Render(screen);
// Accumulate the pixels
Pixel* acc = pixels.data();
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
auto& pixel = screen.PixelAt(x + box_.x_min, y + box_.y_min);
acc->background_color =
Color::Blend(acc->background_color, pixel.background_color);
acc->automerge = pixel.automerge || acc->automerge;
if (pixel.character.empty()) {
acc->foreground_color =
Color::Blend(acc->foreground_color, pixel.background_color);
} else {
acc->blink = pixel.blink;
acc->bold = pixel.bold;
acc->dim = pixel.dim;
acc->inverted = pixel.inverted;
acc->italic = pixel.italic;
acc->underlined = pixel.underlined;
acc->underlined_double = pixel.underlined_double;
acc->strikethrough = pixel.strikethrough;
acc->hyperlink = pixel.hyperlink;
acc->character = pixel.character;
acc->foreground_color = pixel.foreground_color;
}
++acc; // NOLINT
pixel = Pixel();
}
}
}
// Render the accumulated pixels:
Pixel* acc = pixels.data();
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
screen.PixelAt(x + box_.x_min, y + box_.y_min) = *acc++; // NOLINT
}
}
}
};
} // namespace

View File

@ -1,18 +0,0 @@
/// @module ftxui.dom.deprecated
/// @brief Module file for deprecated parts of the Dom module
module;
#include <ftxui/dom/deprecated.hpp>
export module ftxui.dom.deprecated;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::text;
using ftxui::vtext;
using ftxui::paragraph;
}

View File

@ -1,16 +0,0 @@
/// @module ftxui.dom.direction
/// @brief Module file for the Direction enum of the Dom module
module;
#include <ftxui/dom/direction.hpp>
export module ftxui.dom.direction;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::Direction;
}

View File

@ -1,135 +0,0 @@
/// @module ftxui.dom.elements
/// @brief Module file for the Element classes and functions of the Dom module
module;
#include <ftxui/dom/elements.hpp>
export module ftxui.dom.elements;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::Node;
using ftxui::Element;
using ftxui::Elements;
using ftxui::Decorator;
using ftxui::GraphFunction;
using ftxui::BorderStyle;
using ftxui::operator|;
using ftxui::operator|=;
using ftxui::text;
using ftxui::vtext;
using ftxui::separator;
using ftxui::separatorLight;
using ftxui::separatorDashed;
using ftxui::separatorHeavy;
using ftxui::separatorDouble;
using ftxui::separatorEmpty;
using ftxui::separatorStyled;
using ftxui::separatorCharacter;
using ftxui::separatorHSelector;
using ftxui::separatorVSelector;
using ftxui::gauge;
using ftxui::gaugeLeft;
using ftxui::gaugeRight;
using ftxui::gaugeUp;
using ftxui::gaugeDown;
using ftxui::gaugeDirection;
using ftxui::border;
using ftxui::borderLight;
using ftxui::borderDashed;
using ftxui::borderHeavy;
using ftxui::borderDouble;
using ftxui::borderRounded;
using ftxui::borderEmpty;
using ftxui::borderStyled;
using ftxui::borderWith;
using ftxui::window;
using ftxui::spinner;
using ftxui::paragraph;
using ftxui::paragraphAlignLeft;
using ftxui::paragraphAlignRight;
using ftxui::paragraphAlignCenter;
using ftxui::paragraphAlignJustify;
using ftxui::graph;
using ftxui::emptyElement;
using ftxui::canvas;
using ftxui::bold;
using ftxui::dim;
using ftxui::italic;
using ftxui::inverted;
using ftxui::underlined;
using ftxui::underlinedDouble;
using ftxui::blink;
using ftxui::strikethrough;
using ftxui::color;
using ftxui::bgcolor;
using ftxui::focusPosition;
using ftxui::focusPositionRelative;
using ftxui::automerge;
using ftxui::hyperlink;
using ftxui::selectionStyleReset;
using ftxui::selectionColor;
using ftxui::selectionBackgroundColor;
using ftxui::selectionForegroundColor;
using ftxui::selectionStyle;
using ftxui::hbox;
using ftxui::vbox;
using ftxui::dbox;
using ftxui::flexbox;
using ftxui::gridbox;
using ftxui::hflow;
using ftxui::vflow;
using ftxui::flex;
using ftxui::flex_grow;
using ftxui::flex_shrink;
using ftxui::xflex;
using ftxui::xflex_grow;
using ftxui::xflex_shrink;
using ftxui::yflex;
using ftxui::yflex_grow;
using ftxui::yflex_shrink;
using ftxui::notflex;
using ftxui::filler;
using ftxui::WidthOrHeight;
using ftxui::Constraint;
using ftxui::size;
using ftxui::frame;
using ftxui::xframe;
using ftxui::yframe;
using ftxui::focus;
using ftxui::select;
using ftxui::focusCursorBlock;
using ftxui::focusCursorBlockBlinking;
using ftxui::focusCursorBar;
using ftxui::focusCursorBarBlinking;
using ftxui::focusCursorUnderline;
using ftxui::focusCursorUnderlineBlinking;
using ftxui::vscroll_indicator;
using ftxui::hscroll_indicator;
using ftxui::reflect;
using ftxui::clear_under;
using ftxui::hcenter;
using ftxui::vcenter;
using ftxui::center;
using ftxui::align_right;
using ftxui::nothing;
namespace Dimension {
using ftxui::Dimension::Fit;
}
}

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

@ -6,36 +6,42 @@
namespace ftxui {
/// @brief Set the flexbox direction.
/// @ingroup dom
FlexboxConfig& FlexboxConfig::Set(FlexboxConfig::Direction d) {
this->direction = d;
return *this;
}
/// @brief Set the flexbox wrap.
/// @ingroup dom
FlexboxConfig& FlexboxConfig::Set(FlexboxConfig::Wrap w) {
this->wrap = w;
return *this;
}
/// @brief Set the flexbox justify content.
/// @ingroup dom
FlexboxConfig& FlexboxConfig::Set(FlexboxConfig::JustifyContent j) {
this->justify_content = j;
return *this;
}
/// @brief Set the flexbox align items.
/// @ingroup dom
FlexboxConfig& FlexboxConfig::Set(FlexboxConfig::AlignItems a) {
this->align_items = a;
return *this;
}
/// @brief Set the flexbox align content.
/// @ingroup dom
FlexboxConfig& FlexboxConfig::Set(FlexboxConfig::AlignContent a) {
this->align_content = a;
return *this;
}
/// @brief Set the flexbox flex direction.
/// @ingroup dom
FlexboxConfig& FlexboxConfig::SetGap(int x, int y) {
this->gap_x = x;
this->gap_y = y;

View File

@ -1,16 +0,0 @@
/// @module ftxui.dom.flexbox_config
/// @brief Module file for the FlexboxConfig struct of the Dom module
module;
#include <ftxui/dom/flexbox_config.hpp>
export module ftxui.dom.flexbox_config;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::FlexboxConfig;
}

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);

View File

@ -34,8 +34,8 @@ class Hyperlink : public NodeDecorator {
} // namespace
/// @brief Make the rendered area clickable using a web browser.
/// The link will be opened when the user clicks on it.
/// This is supported only on a limited set of terminal emulators.
/// The link will be opened when the user click on it.
/// This is supported only on a limited set of terminal emulator.
/// List: https://github.com/Alhadis/OSC8-Adoption/
/// @param link The link
/// @param child The input element.
@ -52,9 +52,9 @@ Element hyperlink(std::string link, Element child) {
return std::make_shared<Hyperlink>(std::move(child), std::move(link));
}
/// @brief Decorate using a hyperlink.
/// The link will be opened when the user clicks on it.
/// This is supported only on a limited set of terminal emulators.
/// @brief Decorate using an hyperlink.
/// The link will be opened when the user click on it.
/// This is supported only on a limited set of terminal emulator.
/// List: https://github.com/Alhadis/OSC8-Adoption/
/// @param link The link to redirect the users to.
/// @return The Decorator applying the hyperlink.

View File

@ -189,11 +189,13 @@ class LinearGradientColor : public NodeDecorator {
/// .Stop(Color::Green, 0.5)
/// .Stop(Color::Blue, 1.0);;
/// ```
/// @ingroup dom
LinearGradient::LinearGradient() = default;
/// @brief Build a gradient with two colors.
/// @param begin The color at the beginning of the gradient.
/// @param end The color at the end of the gradient.
/// @ingroup dom
LinearGradient::LinearGradient(Color begin, Color end)
: LinearGradient(0, begin, end) {}
@ -201,6 +203,7 @@ LinearGradient::LinearGradient(Color begin, Color end)
/// @param a The angle of the gradient.
/// @param begin The color at the beginning of the gradient.
/// @param end The color at the end of the gradient.
/// @ingroup dom
LinearGradient::LinearGradient(float a, Color begin, Color end) : angle(a) {
stops.push_back({begin, {}});
stops.push_back({end, {}});
@ -209,6 +212,7 @@ LinearGradient::LinearGradient(float a, Color begin, Color end) : angle(a) {
/// @brief Set the angle of the gradient.
/// @param a The angle of the gradient.
/// @return The gradient.
/// @ingroup dom
LinearGradient& LinearGradient::Angle(float a) {
angle = a;
return *this;
@ -217,6 +221,7 @@ LinearGradient& LinearGradient::Angle(float a) {
/// @brief Add a color stop to the gradient.
/// @param c The color of the stop.
/// @param p The position of the stop.
/// @return The gradient.
LinearGradient& LinearGradient::Stop(Color c, float p) {
stops.push_back({c, p});
return *this;
@ -225,6 +230,7 @@ LinearGradient& LinearGradient::Stop(Color c, float p) {
/// @brief Add a color stop to the gradient.
/// @param c The color of the stop.
/// @return The gradient.
/// @ingroup dom
/// @note The position of the stop is interpolated from nearby stops.
LinearGradient& LinearGradient::Stop(Color c) {
stops.push_back({c, {}});

View File

@ -1,16 +0,0 @@
/// @module ftxui.dom.linear_gradient
/// @brief Module file for the LinearGradient struct of the Dom module
module;
#include <ftxui/dom/linear_gradient.hpp>
export module ftxui.dom.linear_gradient;
/**
* @namespace ftxui
* @brief The FTXUI ftxui:: namespace
*/
export namespace ftxui {
using ftxui::LinearGradient;
}

Some files were not shown because too many files have changed in this diff Show More