start doing wraps and subprojects

This commit is contained in:
Mars 2025-02-20 14:49:18 -05:00
parent ea13e2fc57
commit 24416c338c
Signed by: pupbrained
GPG key ID: 0FF5B8826803F895
11013 changed files with 3703981 additions and 25 deletions

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "subprojects/reflectcpp"]
path = subprojects/reflectcpp
url = https://github.com/getml/reflect-cpp

View file

@ -73,15 +73,14 @@
deps = with pkgs.pkgsStatic;
[
curl
fmt
libiconv
tomlplusplus
yyjson
reflect-cpp
# curl
# fmt
# libiconv
# tomlplusplus
# yyjson
# reflect-cpp
sqlitecpp
ftxui
libunistring
# ftxui
]
++ linuxPkgs
++ darwinPkgs;

View file

@ -81,23 +81,34 @@ endforeach
deps = [
dependency('fmt', include_type: 'system', static: true),
dependency('openssl', include_type: 'system', static: true),
dependency('libcurl', include_type: 'system', static: true),
dependency('yyjson', include_type: 'system', static: true),
dependency(
dependency('tomlplusplus', include_type: 'system', static: true),
]
ftxui_dep = dependency(
'ftxui',
modules: ['ftxui::screen', 'ftxui::dom', 'ftxui::component'],
include_type: 'system',
static: true,
),
dependency('reflectcpp', include_type: 'system', static: true),
]
required: false,
)
if host_machine.system() == 'windows'
deps += cpp.find_library('tomlplusplus', static: true, dirs: 'C:/msys64/usr/lib')
else
deps += dependency('tomlplusplus', static: true)
if not ftxui_dep.found()
ftxui_dom = dependency('ftxui-dom', fallback: ['ftxui', 'dom_dep'])
ftxui_screen = dependency('ftxui-screen', fallback: ['ftxui', 'screen_dep'])
ftxui_component = dependency('ftxui-component', fallback: ['ftxui', 'component_dep'])
ftxui_dep = declare_dependency(dependencies: [ftxui_dom, ftxui_screen, ftxui_component])
endif
deps += ftxui_dep
cmake = import('cmake')
reflectcpp_proj = cmake.subproject('reflectcpp')
reflectcpp_dep = reflectcpp_proj.dependency('reflectcpp')
deps += reflectcpp_dep
if host_machine.system() == 'darwin'
deps += dependency('Foundation')
deps += dependency('MediaPlayer')

View file

@ -35,7 +35,7 @@ fn Config::getInstance() -> Config {
const Result<Config> result = rfl::toml::load<Config>(configPath.string());
if (!result) {
ERROR_LOG("Failed to load config file: {}", result.error()->what());
ERROR_LOG("Failed to load config file: {}", result.error().what());
exit(1);
}

View file

@ -44,7 +44,7 @@ namespace {
rfl::Result<WeatherOutput> result = rfl::json::read<WeatherOutput>(content);
if (!result)
return std::unexpected(result.error()->what());
return std::unexpected(result.error().what());
DEBUG_LOG("Successfully read from cache file.");
return *result;
@ -115,9 +115,11 @@ namespace {
DEBUG_LOG("API response size: {}", responseBuffer.size());
DEBUG_LOG("API response: {}", responseBuffer);
rfl::Result<WeatherOutput> output = rfl::json::read<WeatherOutput>(responseBuffer);
if (!output)
return std::unexpected(output.error()->what());
return std::unexpected(output.error().what());
return *output;
}

View file

@ -33,8 +33,8 @@ struct Wind {
};
struct Precipitation {
rfl::Rename<"1h", f64> one_hour;
rfl::Rename<"3h", f64> three_hours;
rfl::Rename<"1h", std::optional<f64>> one_hour;
rfl::Rename<"3h", std::optional<f64>> three_hours;
};
struct Sys {

View file

@ -0,0 +1,4 @@
# Defines the Chromium style for automatic reformatting.
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: Chromium
Standard: Cpp11

View file

@ -0,0 +1,33 @@
---
Checks: "*,
-*-macro-usage,
-*-magic-numbers,
-*-narrowing-conversions
-*-unnecessary-value-param,
-*-uppercase-literal-suffix,
-abseil-*,
-altera-*,
-android-*,
-bugprone-easily-swappable-parameters,
-cppcoreguidelines-non-private-member-variables-in-classes,
-fuchsia-*,
-google-*,
-hicpp-signed-bitwise,
-llvm*,
-misc-no-recursion,
-misc-non-private-member-variables-in-classes,
-modernize-use-nodiscard,
-modernize-use-trailing-return-type,
-readability-avoid-const-params-in-decls,
-readability-else-after-return,
-readability-identifier-length,
-readability-implicit-bool-conversion,
-readability-non-const-parameter,
-readability-simplify-boolean-expr,
-readability-static-accessed-through-instance,
-readability-use-anyofallof,
-zircon-*,
"
WarningsAsErrors: ''
HeaderFilterRegex: ''
FormatStyle: none

View file

@ -0,0 +1 @@
github: [ArthurSonzogni]

View file

@ -0,0 +1,233 @@
name: Build
on:
create:
tags:
-v*
push:
branches:
- main
pull_request:
branches:
- main
jobs:
test:
name: "Tests"
strategy:
fail-fast: false
matrix:
include:
- name: Linux GCC
os: ubuntu-latest
compiler: gcc
gcov_executable: gcov
- name: Linux Clang
os: ubuntu-latest
compiler: llvm
gcov_executable: "llvm-cov gcov"
- name: MacOS clang
os: macos-latest
compiler: llvm
gcov_executable: "llvm-cov gcov"
- name: Windows MSVC
os: windows-latest
compiler: cl
runs-on: ${{ matrix.os }}
steps:
- name: Get number of CPU cores
uses: SimenB/github-actions-cpu-cores@v1
id: cpu-cores
- name: "Checkout repository"
uses: actions/checkout@v2
- 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
gcovr: "5.0"
opencppcoverage: true
# make sure coverage is only enabled for Debug builds, since it sets -O0
# to make sure coverage has meaningful results
- name: "Configure CMake"
run: >
cmake -S .
-B ./build
-DCMAKE_BUILD_TYPE:STRING=Debug
-DCMAKE_BUILD_PARALLEL_LEVEL=${{ steps.cpu-cores.outputs.count }}
-DFTXUI_ENABLE_COVERAGE:BOOL=ON
-DFTXUI_BUILD_DOCS:BOOL=OFF
-DFTXUI_BUILD_EXAMPLES:BOOL=ON
-DFTXUI_BUILD_TESTS:BOOL=ON
-DFTXUI_BUILD_TESTS_FUZZER:BOOL=OFF
-DFTXUI_ENABLE_INSTALL:BOOL=ON
-DFTXUI_DEV_WARNINGS:BOOL=ON ;
- name: "Build"
run: >
cmake
--build ./build
- name: Unix - Test and coverage
if: runner.os != 'Windows'
working-directory: ./build
run: >
ctest -C Debug --rerun-failed --output-on-failure;
gcovr
-j ${{env.nproc}}
--delete
--root ../
--exclude "../examples"
--exclude ".*google.*"
--exclude ".*test.*"
--exclude-unreachable-branches
--exclude-throw-branches
--sort-uncovered
--print-summary
--xml-pretty
--xml
coverage.xml
.
--gcov-executable '${{ matrix.gcov_executable }}';
- name: Windows - Test and coverage
if: runner.os == 'Windows'
working-directory: ./build
run: >
OpenCppCoverage.exe
--export_type cobertura:coverage.xml
--cover_children
--
ctest -C Debug --rerun-failed --output-on-failure;
- name: Publish to codecov
uses: codecov/codecov-action@v3
with:
flags: ${{ runner.os }}
name: ${{ runner.os }}-coverage
files: ./build/coverage.xml
# Create a release on new v* tags
release:
needs: test
if: ${{ github.event_name == 'create' && startsWith(github.ref, 'refs/tags/v') }}
name: "Create release"
runs-on: ubuntu-latest
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
steps:
- name: "Create release"
uses: softprops/action-gh-release@v1
id: create_release
with:
draft: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Build artifact for the release
package:
name: "Build packages"
needs: release
strategy:
matrix:
include:
- os: ubuntu-latest
asset_path: build/ftxui*Linux*
- os: macos-latest
asset_path: build/ftxui*Darwin*
- os: windows-latest
asset_path: build/ftxui*Win64*
runs-on: ${{ matrix.os }}
steps:
- name: Get number of CPU cores
uses: SimenB/github-actions-cpu-cores@v1
id: cpu-cores
- name: "Checkout repository"
uses: actions/checkout@v2
- name: "Install cmake"
uses: lukka/get-cmake@latest
- name: "Build packages"
run: >
mkdir build;
cd build;
cmake ..
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_BUILD_PARALLEL_LEVEL=${{ steps.cpu-cores.outputs.count }}
-DFTXUI_BUILD_DOCS=OFF
-DFTXUI_BUILD_EXAMPLES=OFF
-DFTXUI_BUILD_TESTS=OFF
-DFTXUI_BUILD_TESTS_FUZZER=OFF
-DFTXUI_ENABLE_INSTALL=ON
-DFTXUI_DEV_WARNINGS=ON ;
cmake --build . --target package;
- uses: shogo82148/actions-upload-release-asset@v1
with:
upload_url: ${{ needs.release.outputs.upload_url }}
asset_path: ${{ matrix.asset_path }}
overwrite: true
documentation:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: "Checkout repository"
uses: actions/checkout@v2
- name: "Install cmake"
uses: lukka/get-cmake@latest
- name: "Install emsdk"
uses: mymindstorm/setup-emsdk@v7
- name: "Install Doxygen/Graphviz"
run: >
sudo apt-get update;
sudo apt-get install doxygen graphviz;
- name: "Build documentation"
run: >
mkdir build;
cd build;
emcmake cmake ..
-DCMAKE_BUILD_TYPE=Release
-DFTXUI_BUILD_DOCS=ON
-DFTXUI_BUILD_EXAMPLES=ON
-DFTXUI_BUILD_TESTS=OFF
-DFTXUI_BUILD_TESTS_FUZZER=OFF
-DFTXUI_ENABLE_INSTALL=OFF
-DFTXUI_DEV_WARNINGS=ON ;
cmake --build . --target doc;
cmake --build . ;
rsync -amv
--include='*/'
--include='*.html'
--include='*.js'
--include='*.wasm'
--exclude='*'
examples
doc/doxygen/html;
- name: "Deploy"
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: build/doc/doxygen/html/
enable_jekyll: false
allow_empty_commit: false
force_orphan: true
publish_branch: gh-pages

View file

@ -0,0 +1,76 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ "main" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
schedule:
- cron: '45 22 * * 5'
jobs:
analyze:
name: Analyze
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Use only 'java' to analyze code written in Java, Kotlin or both
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"

56
subprojects/FTXUI-5.0.0/.gitignore vendored Normal file
View file

@ -0,0 +1,56 @@
# Ignore all the files, except the ones we expect.
# See https://jasonstitt.com/gitignore-whitelisting-patterns
*
!*/
# Allowed top-level files:
!.clang-format
!.clang-tidy
!.gitignore
!CHANGELOG.md
!CMakeLists.txt
!LICENSE
!README.md
!codecov.yml
!flake.lock
!flake.nix
!ftxui.pc.in
!iwyu.imp
# .github directory:
!.github/**/*.yaml
!.github/**/*.yml
# cmake directory:
!cmake/**/*.in
!cmake/**/*.cmake
# doc directory:
!doc/**/Doxyfile.in
!doc/**/*.txt
!doc/**/*.css
!doc/**/*.html
!doc/**/*.xml
!doc/**/*.md
# examples directory:
!examples/**/*.txt
!examples/**/*.cpp
!examples/**/*.hpp
!examples/**/*.ipp
!examples/**/*.html
!examples/**/*.py
!examples/**/*.js
!examples/**/*.html.disabled
# include directory:
!include/ftxui/**/*.hpp
!include/ftxui/**/*.cpp
# src directory:
!src/ftxui/**/*.hpp
!src/ftxui/**/*.cpp
# tools directory:
!tools/**/*.sh
!tools/**/*.cpp

View file

@ -0,0 +1,355 @@
Changelog
=========
current (development)
---------------------
5.0.0
-----
### Component
- Breaking: MenuDirection enum is renamed Direction
- Breaking: GaugeDirection enum is renamed Direction
- Breaking: Direction enum is renamed WidthOrHeight
- Breaking: Remove `ComponentBase` copy constructor/assignment.
- Breaking: MenuOption::entries is renamed MenuOption::entries_option.
- Breaking: `Ref<{Component}Option>` becomes `{Component}Option` in component constructors.
- Feature: `ResizeableSplit` now support arbitrary element as a separator.
- Feature: `input` is now supporting multiple lines.
- Feature: `input` style is now customizeable.
- Bugfix: Support F1-F5 from OS terminal.
- Feature: Add struct based constructor:
```cpp
Component Button(ButtonOption options);
Component Checkbox(CheckboxOption options);
Component Input(InputOption options);
Component Menu(MenuOption options);
Component MenuEntry(MenuEntryOption options);
Component Radiobox(RadioboxOption options);
Component Slider(SliderOption<T> options);
Component ResizableSplit(ResizableSplitOption options);
```
- Feature: Add `ScreenInteractive::TrackMouse(false)` disable mouse support.
### Dom
- Feature: Add `hyperlink` decorator. For instance:
```cpp
auto link = text("Click here") | hyperlink("https://github.com/FTXUI")
```
See the [OSC 8 page](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda).
FTXUI support proposed by @aaleino in [#662](https://github.com/ArthurSonzogni/FTXUI/issues/662).
### Screen
- Breaking: `WordBreakProperty` becomes a uint8_t enum. This yields a 0.8%
performance improvement.
- Breaking: Remove user defined Pixel constructor and equality operator.
- Performance: 19% faster on benchmarks.
### Build
- Check version compatibility when using cmake find_package()
- Add `FTXUI_DEV_WARNING` options to turn on warnings when building FTXUI
- Turn OFF by default `FTXUI_BUILD_DOCS`
- Turn OFF by default `FTXUI_BUILD_EXAMPLE`
4.1.1
-----
### Component
- Fix: Support arrow keys in application mode
- Fix: Remove useless new line when using an alternative screen.
### Dom
- Feature: Add the dashed style for border and separator:
- See `DASHED` enum, and `separatorDashed()`, `borderDashed()` functions.
- Feature: Add colored borders.
- See functions: `borderStyled(BorderStyle, Color)` and `borderStyled(Color)`.
- Feature: Add `LinearGradient`. It can be used in `color` and `bgColor`.
- Improvement: Color::Interpolate() uses gamma correction.
- Fix: Check the `graph` area is positive.
### Build/Install
- Use globally set CMAKE_CXX_STANDARD if it is set.
- Expose the pkg-config file
- Check version compatibility when using cmake find_package()
4.1.0 (Abandonned)
-----
This version is abandonned and must not be used. It introduced a breaking change in the API.
4.0.0
-----
### DOM
- Feature: more styles:
- `strikethrough`
- `underlinedDouble`
- Feature: Customize the cursor. Add the following decorators:
- `focusCursorBlock`
- `focusCursorBlockBlinking`
- `focusCursorBar`
- `focusCursorBarBlinking`
- `focusCursorUnderline`
- `focusCursorUnderlineBlinking`
- Bugfix: Fix `focus`/`select` when the `vbox`/`hbox`/`dbox` contains a
`flexbox`
- Bugfix: Fix the selected/focused area. It used to be 1 cell larger/longer than
requested
- Bugfix: Forward the selected/focused area from the child in gridbox.
- Bugfix: Fix incorrect Canvas computed dimensions.
- Bugfix: Support `vscroll_indicator` with a zero inner size.
- Bugfix: Fix `vscroll_indicator` hidding the last column.
### Component:
- Feature: Add the `Modal` component.
- Feature: `Slider` supports taking references for all its arguments.
- Feature: `Slider` supports `SliderOption`. It supports:
- multiple directions.
- multiple colors.
- various values (value, min, max, increment).
- Feature: Define `ScreenInteractive::Exit()`.
- Feature: Add `Loop` to give developers a better control on the main loop. This
can be used to integrate FTXUI into another main loop, without taking the full
control.
- Feature: `Input` supports CTRL+Left and CTRL+Right
- Feature: Use a blinking bar in the `Input` component.
- Improvement: The `Menu` keeps the focus when an entry is selected with the
mouse.
- Bugfix: Add implementation of `ButtonOption::Border()`. It was missing.
- Bugfix: Provide the correct key for F1-F4 and F11.
- Feature: Add the `Hoverable` component decorators.
### Screen
- Feature: add `Box::Union(a,b) -> Box`
- Bugfix: Fix resetting `dim` clashing with resetting of `bold`.
- Feature: Add emscripten screen resize support.
- Bugfix: Add unicode 13 support for full width characters.
- Bugfix: Fix MSVC treating codecvt C++17 deprecated function as an error.
### Build
- Support using the google test version provided by the package manager.
3.0.0
-----
### Build
- **breaking**: The library prefix is now back to "lib" (the default). This
means non-cmake users should not link against "libftxui-dom" for instance.
### Component
- **Animations** module! Components can implement the `OnAnimation` method and
the animation::Animator to define some animated properties.
- `Menu` now support animations.
- `Button` now supports animations.
- Support SIGTSTP. (ctrl+z).
- Support task posting. `ScreenInteractive::Post(Task)`.
- `Menu` can now be used in the 4 directions, using `MenuOption.direction`.
- `Menu` can display an animated underline, using
`MenuOption.underline.enabled`.
- `Button` is now taking the focus in frame.
- **breaking** All the options are now using a transform function.
- **breaking** The `Toggle` component is now implemented using `Menu`.
- **bugfix** Container::Tab implements `Focusable()`.
- **bugfix** Improved default implementations of ComponentBase `Focusable()` and
`ActiveChild()` methods.
- **bugfix** Automatically convert '\r' keys into '\n' for Linux programs that
do not send the correct code for the return key, like the 'bind'.
https://github.com/ArthurSonzogni/FTXUI/issues/337
- Add decorator for components:
- `operator|(Component, ComponentDecorator)`
- `operator|(Component, ElementDecorator)`
- `operator|=(Component, ComponentDecorator)`
- `operator|=(Component, ElementDecorator)`
- Add the `Maybe` decorator.
- Add the `CatchEvent` decorator.
- Add the `Renderer` decorator.
- **breaking** remove the "deprectated.hpp" header and Input support for wide
string.
### DOM:
- **breaking**: The `inverted` decorator now toggle in the inverted attribute.
- Add `gauge` for the 4 directions. Expose the following API:
```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);
```
- Add `separatorHSelector` and `separatorVSelector` elements. This can be used
to highlight an area.
- Add the `automerge` decorator. This makes separator characters to be merged
with others nearby.
- Fix the `Table` rendering function, to allow automerging characters.
- **Bugfix**: The `vscroll_indicator` now computes its offset and size
correctly.
- Add the `operator|=(Element, Decorator)`
### Screen:
- Add: `Color::Interpolate(lambda, color_a, color_b)`.
2.0.0
-----
### Features:
#### Screen
- Add the `automerge` to the Pixel bit field. This now controls which pixels are
automatically merged.
#### DOM:
- Add the `Canvas` class and `ElementFrom('canvas')` function. Together users of
the library can draw using braille and block characters.
- Support `flexbox` dom elements. This is build symmetrically to the HTML one.
All the following attributes are supported: direction, wrap, justify-content,
align-items, align-content, gap
- Add the dom elements helper based on `flexbox`:
- `paragraph`
- `paragraphAlignLeft`
- `paragraphAlignCenter`
- `paragraphAlignRight`
- `paragraphAlignJustify`
- Add the helper elements based on `flexbox`: `hflow()`, `vflow()`.
- Add: `focusPositionRelative` and `focusPosition`
- Add `Table` constructor from 2D vector of Element, instead of string.
#### Component
- Add the `collapsible` component.
- Add the `ScreenInteractive::WithRestoredIO`. This decorates a callback. This
runs it with the terminal hooks temporarilly uninstalled. This is useful if
you want to execute command using directly stdin/stdout/sterr.
### Bug
#### Table
- The `table` horizontal and vertical separator are now correctly expanded.
#### Component
- `Input` shouldn't take focus when hovered by the mouse.
- Modifying `Input`'s during on_enter/on_change event is now working correctly.
### Breaking changes:
- The behavior of `paragraph` has been modified. It now returns en Element,
instead of a list of elements.
0.11.1
------
# Component
- Feature: Support for PageUp/PageDown/Home/End buttons.
- Bugfix: Check the selected element are within bounds for Dropdown.
# Build
- Bugfix: Package library using the "Release config". Not debug.
0.11
----
## github workflow
- Add Windows ad MacOS artefacts.
- Merge all the workflows.
## Bug
- On Unix system, fallback to {80,25} screen dimension on failure.
## CMake
- Support for shared library, via `BUILD_SHARED_LIBS` option.
- Add library version and symlinks.
0.10 (2021-09-30)
--------------------
## Bug
- Fix the automated merge of borders.
### Dom
- `Table()` class to build stylised table.
See https://github.com/ArthurSonzogni/FTXUI/discussions/228
- `vscroll_indicator`. Show a scrollbar indicator on the right.
- `separatorEmpty`. A separator drawing nothing.
- `separatorFixed`. A separator drawing the provided character.
### Component
- `Maybe`: Display an component conditionnally based on a boolean.
- `Dropdown`: A dropdown select list.
0.9 (2021-09-26)
----------------
The initial release where changelog where written.
This version includes:
### screen
- Style:
- Bold.
- Blink.
- Dim.
- Inverted.
- Underlined.
- Foreground color.
- Background color.
- Support for UTF8 unicode.
- Full wide character: 测试.
- Combining characters: a⃒
- A Stencil buffer.
- Automatically merge box drawing characters.
- Detect terminal dimension.
### DOM
- Element:
- `text` & `vtext`
- `separator` and 5 variations.
- `gauge`
- `border` and 6 variations.
- `window`
- `spinner`
- `paragraph` and `hflow`.
- Layout:
- `hbox`
- `vbox`
- `dbox`
- `gridbox`
- `frame`: Drawing inside a virtual area, potentially larger than the real
one.
- `focus`, `select`: scroll the inner view of a frame, to be in view.
- `flex` & 8 variations. `filler`
- Decorators:
- `bold`
- `dim`
- `inverted`
- `blink`
- `color`
- `bgcolor`
- `clearunder`
### Component
- Container:
- `Container::Vertical`
- `Container::Horizontal`
- `Container::Tab`
- `Button`
- `Checkbox`
- `Input`
- `Menu`
- `MenuEntry`
- `Radiobox`
- `Toggle`
- `Slider`
- `Renderer` & variations
- `CatchEvent`
### MISC
- Fuzzer
- Tests using gtest.
- Doxygen documentation
- IWYU
- 52 examples.
- Support for WebAssembly.
- Support for Window and fallback for broken terminal.

View file

@ -0,0 +1,172 @@
cmake_minimum_required(VERSION 3.12)
project(ftxui
LANGUAGES CXX
VERSION 5.0.0
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 \
to counteract its implementations problems.")
if (WIN32)
option(FTXUI_MICROSOFT_TERMINAL_FALLBACK
${FTXUI_MICROSOFT_TERMINAL_FALLBACK_HELP_TEXT} ON)
else()
option(FTXUI_MICROSOFT_TERMINAL_FALLBACK
${FTXUI_MICROSOFT_TERMINAL_FALLBACK_HELP_TEXT} OFF)
endif()
include(cmake/ftxui_message.cmake)
add_library(screen
include/ftxui/screen/box.hpp
include/ftxui/screen/color.hpp
include/ftxui/screen/color_info.hpp
include/ftxui/screen/screen.hpp
include/ftxui/screen/string.hpp
src/ftxui/screen/box.cpp
src/ftxui/screen/color.cpp
src/ftxui/screen/color_info.cpp
src/ftxui/screen/screen.cpp
src/ftxui/screen/string.cpp
src/ftxui/screen/terminal.cpp
src/ftxui/screen/util.hpp
)
add_library(dom
include/ftxui/dom/canvas.hpp
include/ftxui/dom/direction.hpp
include/ftxui/dom/elements.hpp
include/ftxui/dom/flexbox_config.hpp
include/ftxui/dom/node.hpp
include/ftxui/dom/requirement.hpp
include/ftxui/dom/take_any_args.hpp
src/ftxui/dom/automerge.cpp
src/ftxui/dom/blink.cpp
src/ftxui/dom/bold.cpp
src/ftxui/dom/hyperlink.cpp
src/ftxui/dom/border.cpp
src/ftxui/dom/box_helper.cpp
src/ftxui/dom/box_helper.hpp
src/ftxui/dom/canvas.cpp
src/ftxui/dom/clear_under.cpp
src/ftxui/dom/color.cpp
src/ftxui/dom/composite_decorator.cpp
src/ftxui/dom/dbox.cpp
src/ftxui/dom/dim.cpp
src/ftxui/dom/flex.cpp
src/ftxui/dom/flexbox.cpp
src/ftxui/dom/flexbox_config.cpp
src/ftxui/dom/flexbox_helper.cpp
src/ftxui/dom/flexbox_helper.hpp
src/ftxui/dom/focus.cpp
src/ftxui/dom/frame.cpp
src/ftxui/dom/gauge.cpp
src/ftxui/dom/graph.cpp
src/ftxui/dom/gridbox.cpp
src/ftxui/dom/hbox.cpp
src/ftxui/dom/inverted.cpp
src/ftxui/dom/linear_gradient.cpp
src/ftxui/dom/node.cpp
src/ftxui/dom/node_decorator.cpp
src/ftxui/dom/paragraph.cpp
src/ftxui/dom/reflect.cpp
src/ftxui/dom/scroll_indicator.cpp
src/ftxui/dom/separator.cpp
src/ftxui/dom/size.cpp
src/ftxui/dom/spinner.cpp
src/ftxui/dom/strikethrough.cpp
src/ftxui/dom/table.cpp
src/ftxui/dom/text.cpp
src/ftxui/dom/underlined.cpp
src/ftxui/dom/underlined_double.cpp
src/ftxui/dom/util.cpp
src/ftxui/dom/vbox.cpp
)
add_library(component
include/ftxui/component/animation.hpp
include/ftxui/component/captured_mouse.hpp
include/ftxui/component/component.hpp
include/ftxui/component/component_base.hpp
include/ftxui/component/component_options.hpp
include/ftxui/component/event.hpp
include/ftxui/component/loop.hpp
include/ftxui/component/mouse.hpp
include/ftxui/component/receiver.hpp
include/ftxui/component/screen_interactive.hpp
include/ftxui/component/task.hpp
src/ftxui/component/animation.cpp
src/ftxui/component/button.cpp
src/ftxui/component/catch_event.cpp
src/ftxui/component/checkbox.cpp
src/ftxui/component/collapsible.cpp
src/ftxui/component/component.cpp
src/ftxui/component/component_options.cpp
src/ftxui/component/container.cpp
src/ftxui/component/dropdown.cpp
src/ftxui/component/event.cpp
src/ftxui/component/hoverable.cpp
src/ftxui/component/input.cpp
src/ftxui/component/loop.cpp
src/ftxui/component/maybe.cpp
src/ftxui/component/menu.cpp
src/ftxui/component/modal.cpp
src/ftxui/component/radiobox.cpp
src/ftxui/component/radiobox.cpp
src/ftxui/component/renderer.cpp
src/ftxui/component/resizable_split.cpp
src/ftxui/component/screen_interactive.cpp
src/ftxui/component/slider.cpp
src/ftxui/component/terminal_input_parser.cpp
src/ftxui/component/terminal_input_parser.hpp
src/ftxui/component/util.cpp
src/ftxui/component/window.cpp
)
target_link_libraries(dom
PUBLIC screen
)
target_link_libraries(component
PUBLIC dom
)
if (NOT EMSCRIPTEN)
find_package(Threads)
target_link_libraries(component
PUBLIC Threads::Threads
)
endif()
include(cmake/ftxui_set_options.cmake)
ftxui_set_options(screen)
ftxui_set_options(dom)
ftxui_set_options(component)
include(cmake/ftxui_coverage.cmake)
ftxui_check_coverage(screen)
ftxui_check_coverage(dom)
ftxui_check_coverage(component)
include(cmake/ftxui_test.cmake)
include(cmake/ftxui_benchmark.cmake)
include(cmake/ftxui_fuzzer.cmake)
include(cmake/iwyu.cmake)
include(cmake/ftxui_export.cmake)
include(cmake/ftxui_install.cmake)
include(cmake/ftxui_package.cmake)
add_subdirectory(examples)
add_subdirectory(doc)

View file

@ -0,0 +1,22 @@
The MIT License
Copyright (c) 2019 Arthur Sonzogni.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -0,0 +1,373 @@
<p align="center">
<img src="https://github.com/ArthurSonzogni/FTXUI/assets/4759106/6925b6da-0a7e-49d9-883c-c890e1f36007" alt="Demo image"></img>
<br/>
<a href="#"><img src="https://img.shields.io/badge/c++-%2300599C.svg?style=flat&logo=c%2B%2B&logoColor=white"></img></a>
<a href="http://opensource.org/licenses/MIT"><img src="https://img.shields.io/github/license/arthursonzogni/FTXUI?color=black"></img></a>
<a href="#"><img src="https://img.shields.io/github/stars/ArthurSonzogni/FTXUI"></img></a>
<a href="#"><img src="https://img.shields.io/github/forks/ArthurSonzogni/FTXUI"></img></a>
<a href="#"><img src="https://img.shields.io/github/repo-size/ArthurSonzogni/FTXUI"></img></a>
<a href="https://github.com/ArthurSonzogni/FTXUI/graphs/contributors"><img src="https://img.shields.io/github/contributors/arthursonzogni/FTXUI?color=blue"></img></a>
<br/>
<a href="https://github.com/ArthurSonzogni/FTXUI/issues"><img src="https://img.shields.io/github/issues/ArthurSonzogni/FTXUI"></img></a>
<a href="https://repology.org/project/ftxui/versions"><img src="https://repology.org/badge/latest-versions/ftxui.svg" alt="latest packaged version(s)"></a>
<a href="https://codecov.io/gh/ArthurSonzogni/FTXUI">
<img src="https://codecov.io/gh/ArthurSonzogni/FTXUI/branch/master/graph/badge.svg?token=C41FdRpNVA"/>
</a>
<br/>
<a href="https://arthursonzogni.github.io/FTXUI/">Documentation</a> ·
<a href="https://github.com/ArthurSonzogni/FTXUI/issues">Report a Bug</a> ·
<a href="https://arthursonzogni.github.io/FTXUI/examples.html">Examples</a> .
<a href="https://github.com/ArthurSonzogni/FTXUI/issues">Request Feature</a> ·
<a href="https://github.com/ArthurSonzogni/FTXUI/pulls">Send a Pull Request</a>
</p>
# FTXUI
<i>Functional Terminal (X) User interface</i>
A 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/)
* 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)
* 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), vcpkg, pkgbuild, conan.
* Good practises: documentation, tests, fuzzers, performance tests, automated CI, automated packaging, etc...
## Documentation
- [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)
## Example
~~~cpp
vbox({
hbox({
text("one") | border,
text("two") | border | flex,
text("three") | border | flex,
}),
gauge(0.25) | color(Color::Red),
gauge(0.50) | color(Color::White),
gauge(0.75) | color(Color::Blue),
});
~~~
![image](https://github.com/ArthurSonzogni/FTXUI/assets/4759106/569bf043-4e85-4245-aad5-2324572135c4)
## Short gallery
#### DOM
This module defines a hierarchical set of Element. An element manages layout and can be responsive to the terminal dimensions.
They are declared in [<ftxui/dom/elements.hpp>](https://arthursonzogni.github.io/FTXUI/elements_8hpp_source.html
)
<details><summary>Layout</summary>
Element can be arranged together:
- horizontally with `hbox`
- vertically with `vbox`
- inside a grid with `gridbox`
- wrap along one direction using the `flexbox`.
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`.
![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.html) using 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)
[See](https://arthursonzogni.github.io/FTXUI/examples_2dom_2hflow_8cpp-example.html) also this [demo](https://arthursonzogni.github.io/FTXUI/examples/?file=component/flexbox).
</details>
<details><summary>Style</summary>
An element can be decorated using the functions:
- `bold`
- `dim`
- `inverted`
- `underlined`
- `underlinedDouble`
- `blink`
- `strikethrough`
- `color`
- `bgcolor`
- `hyperlink`
[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)
FTXUI supports the pipe operator. It means: `decorator1(decorator2(element))` and `element | decorator1 | decorator2` can be used.
</details>
<details><summary>Colors</summary>
FTXUI support every color palette:
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)
</details>
<details><summary>Border and separator</summary>
Use decorator border and element separator() to subdivide your UI:
```cpp
auto document = vbox({
text("top"),
separator(),
text("bottom"),
}) | border;
```
[Demo](https://arthursonzogni.github.io/FTXUI/examples_2dom_2separator_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147244514-4135f24b-fb8e-4067-8896-bc53545583f7.png)
</details>
<details><summary>Text and paragraph</summary>
A simple piece of text is represented using `text("content")`.
To support text wrapping following spaces the following functions are provided:
```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);
```
[Paragraph example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2paragraph_8cpp-example.html)
![ezgif com-gif-maker (4)](https://user-images.githubusercontent.com/4759106/147251370-983a06e7-6f41-4113-92b8-942f43d34d06.gif)
</details>
<details><summary>Table</summary>
A class to easily style a table of data.
[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)
</details>
<details><summary>Canvas</summary>
Drawing can be made on a 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 [examples](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)
</details>
#### Component
The ftxui/component is needed when you want to produce dynamic UI, reactive to the user's input. It defines a set of ftxui::Component. A component reacts to Events (keyboard, mouse, resize, ...) and Render Element (see previous section).
Prebuilt components are declared in [<ftxui/component/component.hpp>](https://arthursonzogni.github.io/FTXUI/component_8hpp_source.html)
<details><summary>Gallery</summary>
[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)
</details>
<details><summary>Radiobox</summary>
[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)
</details>
<details><summary>Checkbox</summary>
[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)
</details>
<details><summary>Input</summary>
[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)
</details>
<details><summary>Toggle</summary>
[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)
</details>
<details><summary>Slider</summary>
[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)
</details>
<details><summary>Menu</summary>
[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)
</details>
<details><summary>ResizableSplit</summary>
[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)
</details>
<details><summary>Dropdown</summary>
[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)
</details>
<details><summary>Tab</summary>
[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)
</details>
## Libraries for FTXUI
- *Want to share a useful component using FTXUI? Feel free adding yours here*
## Project using FTXUI
Feel free to add your projects here:
- [json-tui](https://github.com/ArthurSonzogni/json-tui)
- [git-tui](https://github.com/ArthurSonzogni/git-tui)
- [rgb-tui](https://github.com/ArthurSonzogni/rgb-tui)
- [chrome-log-beautifier](https://github.com/ArthurSonzogni/chrome-log-beautifier)
- [x86-64 CPU Architecture Simulation](https://github.com/AnisBdz/CPU)
- [ltuiny](https://github.com/adrianoviana87/ltuiny)
- [i3-termdialogs](https://github.com/mibli/i3-termdialogs)
- [Just-Fast](https://github.com/GiuseppeCesarano/just-fast)
- [simpPRU](https://github.com/VedantParanjape/simpPRU)
- [Pigeon ROS TUI](https://github.com/PigeonSensei/Pigeon_ros_tui)
- [hastur](https://github.com/robinlinden/hastur)
- [CryptoCalculator](https://github.com/brevis/CryptoCalculator)
- [todoman](https://github.com/aaleino/todoman)
- [TimeAccumulator](https://github.com/asari555/TimeAccumulator)
- [vantage](https://github.com/gokulmaxi/vantage)
- [tabdeeli](https://github.com/typon/tabdeeli)
- [tiles](https://github.com/tusharpm/tiles)
- [cachyos-cli-installer](https://github.com/cachyos/new-cli-installer)
- [beagle-config](https://github.com/SAtacker/beagle-config)
- [turing_cmd](https://github.com/DanArmor/turing_cmd)
- [StartUp](https://github.com/StubbornVegeta/StartUp)
- [eCAL monitor](https://github.com/eclipse-ecal/ecal)
- [Path Finder](https://github.com/Ruebled/Path_Finder)
- [rw-tui](https://github.com/LeeKyuHyuk/rw-tui)
### [cpp-best-practices/game_jam](https://github.com/cpp-best-practices/game_jam)
Several games using the FTXUI have been made during the Game Jam:
- [TermBreaker](https://github.com/ArthurSonzogni/termBreaker) [**[Play web version]**](https://arthursonzogni.com/TermBreaker/)
- [Minesweeper Marathon](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/minesweeper_marathon.md) [**[Play web version]**](https://barlasgarden.com/minesweeper/index.html)
- [Grand Rounds](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/grandrounds.md)
- [LightsRound](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/LightsRound.v.0.1.0.md)
- [DanteO](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/danteo.md)
- [Sumo](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/sumo.md)
- [Drag Me aROUND](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/drag_me_around.md)
- [DisarmSelfDestruct](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/DisarmSelfDestruct.md)
- [TheWorld](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/TheWorld.md)
- [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)
## External package
It is **highly** recommended to use CMake FetchContent to depend on FTXUI. This
way you can specify which commit you would like to depend on.
```cmake
include(FetchContent)
FetchContent_Declare(ftxui
GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui
GIT_TAG v3.0.0
)
FetchContent_GetProperties(ftxui)
if(NOT ftxui_POPULATED)
FetchContent_Populate(ftxui)
add_subdirectory(${ftxui_SOURCE_DIR} ${ftxui_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()
```
If you don't, the following packages have been created:
- [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/ftxui.svg)](https://repology.org/project/ftxui/versions)
## Contributors
<a href="https://github.com/ArthurSonzogni/FTXUI/graphs/contributors">
<img src="https://contrib.rocks/image?repo=ArthurSonzogni/FTXUI" />
</a>

View file

@ -0,0 +1,6 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(Threads)
include("${CMAKE_CURRENT_LIST_DIR}/ftxui-targets.cmake")

View file

@ -0,0 +1,21 @@
if (NOT FTXUI_BUILD_TESTS OR
NOT ${CMAKE_VERSION} VERSION_GREATER "3.11.4" OR
WIN32
)
return()
endif()
include(cmake/ftxui_find_google_benchmark.cmake)
add_executable(ftxui-benchmark
src/ftxui/dom/benchmark_test.cpp
)
ftxui_set_options(ftxui-benchmark)
target_link_libraries(ftxui-benchmark
PRIVATE dom
PRIVATE benchmark::benchmark
PRIVATE benchmark::benchmark_main
)
target_include_directories(ftxui-benchmark
PRIVATE src
)

View file

@ -0,0 +1,8 @@
function(ftxui_check_coverage library)
if (FTXUI_ENABLE_COVERAGE)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
target_compile_options(${library} INTERFACE --coverage -O0 -g)
target_link_libraries(${library} INTERFACE --coverage)
endif()
endif()
endfunction()

View file

@ -0,0 +1,8 @@
add_library(ftxui::screen ALIAS screen)
add_library(ftxui::dom ALIAS dom)
add_library(ftxui::component ALIAS component)
export(
TARGETS screen dom component
NAMESPACE ftxui::
FILE "${PROJECT_BINARY_DIR}/ftxui-targets.cmake"
)

View file

@ -0,0 +1,32 @@
# Some developers would be happier with the google benchmark version provided
# from their package manager. Use it if it is installed the package provide
# cmake support.
# https://github.com/ArthurSonzogni/FTXUI/issues/551
find_package(benchmark QUIET)
if (benchmark_FOUND)
return()
endif()
option(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)
option(FETCHCONTENT_QUIET FALSE)
include(FetchContent)
FetchContent_Declare(googlebenchmark
GIT_REPOSITORY "https://github.com/google/benchmark"
GIT_TAG "015d1a091af6937488242b70121858bce8fd40e9" # v1.8.2
GIT_PROGRESS TRUE
)
FetchContent_GetProperties(googlebenchmark)
set (BENCHMARK_ENABLE_GTEST_TESTS OFF CACHE INTERNAL "")
set (BENCHMARK_ENABLE_TESTING OFF CACHE INTERNAL "")
if(googlebenchmark_POPULATED)
return()
endif()
FetchContent_Populate(googlebenchmark)
add_subdirectory(
${googlebenchmark_SOURCE_DIR}
${googlebenchmark_BINARY_DIR}
EXCLUDE_FROM_ALL
)

View file

@ -0,0 +1,33 @@
# Some developers would be happier with the gtest version provided from their
# package manager. Use it if it is installed the package provide cmake support.
# https://github.com/ArthurSonzogni/FTXUI/issues/551
find_package(GTest QUIET)
if (GTest_FOUND)
return()
endif()
option(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)
option(FETCHCONTENT_QUIET FALSE)
include(FetchContent)
FetchContent_Declare(googletest
GIT_REPOSITORY "https://github.com/google/googletest"
GIT_TAG 23ef29555ef4789f555f1ba8c51b4c52975f0907
GIT_PROGRESS TRUE
)
FetchContent_GetProperties(googletest)
if(googletest_POPULATED)
return()
endif()
FetchContent_Populate(googletest)
set(BUILD_GMOCK OFF CACHE INTERNAL "")
set(INSTALL_GTEST OFF CACHE INTERNAL "")
set(gtest_force_shared_crt ON CACHE INTERNAL "")
add_subdirectory(
"${googletest_SOURCE_DIR}"
"${googletest_BINARY_DIR}"
EXCLUDE_FROM_ALL
)

View file

@ -0,0 +1,21 @@
if (NOT FTXUI_BUILD_TESTS_FUZZER)
return()
endif()
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
function(fuzz source)
set(name "ftxui-${source}")
add_executable(${name}
src/ftxui/component/${source}.cpp
)
target_include_directories(${name} PRIVATE src)
target_link_libraries(${name} PRIVATE component)
target_compile_options(${name} PRIVATE -fsanitize=fuzzer,address)
target_link_libraries(${name} PRIVATE -fsanitize=fuzzer,address)
target_compile_features(${name} PRIVATE cxx_std_17)
endfunction(fuzz)
fuzz(terminal_input_parser_test_fuzzer)
fuzz(component_fuzzer)

View file

@ -0,0 +1,60 @@
if(NOT FTXUI_ENABLE_INSTALL)
return()
endif()
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
# ------------------------------------------------------------------------------
# Install the library and its public headers into the standard subdirectories
# ------------------------------------------------------------------------------
install(
TARGETS screen dom component
EXPORT ftxui-targets
)
install(
DIRECTORY include/ftxui
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
# ------------------------------------------------------------------------------
# Install the exported cmake targets for use in other CMake projects.
# ------------------------------------------------------------------------------
install(
EXPORT ftxui-targets
NAMESPACE ftxui::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ftxui"
)
# ------------------------------------------------------------------------------
# Create and install the ftuxi-config.cmake and ftuxi-config-version.cmake files
# needed to support users of find_package()
# ------------------------------------------------------------------------------
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/ftxui-config.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake/ftxui-config.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/ftxui/cmake"
PATH_VARS CMAKE_INSTALL_INCLUDEDIR
)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/cmake/ftxui-config-version.cmake"
VERSION ${PACKAGE_VERSION}
COMPATIBILITY SameMajorVersion
)
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/cmake/ftxui-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cmake/ftxui-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ftxui"
)
# ------------------------------------------------------------------------------
# Create and install pkg-config file for easy use of library in build systems
# other than CMake:
# ------------------------------------------------------------------------------
configure_file(ftxui.pc.in ${CMAKE_CURRENT_BINARY_DIR}/ftxui.pc @ONLY)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/ftxui.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
)

View file

@ -0,0 +1,17 @@
function(ftxui_message msg)
if (NOT FTXUI_QUIET)
message(STATUS "${msg}")
endif()
endfunction()
ftxui_message("┌─ FTXUI options ─────────────────────")
ftxui_message("│ FTXUI_ENABLE_INSTALL : ${FTXUI_ENABLE_INSTALL}")
ftxui_message("│ FTXUI_BUILD_EXAMPLES : ${FTXUI_BUILD_EXAMPLES}")
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_ENABLE_COVERAGE : ${FTXUI_ENABLE_COVERAGE}")
ftxui_message("│ FTXUI_DEV_WARNINGS : ${FTXUI_DEV_WARNINGS}")
ftxui_message("│ FTXUI_CLANG_TIDY : ${FTXUI_CLANG_TIDY}")
ftxui_message("└─────────────────────────────────────")

View file

@ -0,0 +1,28 @@
if(NOT FTXUI_ENABLE_INSTALL)
return()
endif()
if (UNIX AND NOT APPLE)
set(CPACK_GENERATOR "DEB;External;RPM;STGZ;TBZ2;TGZ;TXZ;TZ;TZST;ZIP")
elseif (UNIX AND APPLE)
set(CPACK_GENERATOR "DragNDrop;NuGet;TGZ;ZIP")
elseif (WIN32)
set(CPACK_GENERATOR "DEB;NuGet;TGZ;ZIP")
else()
set(CPACK_GENERATOR "ZIP")
endif()
set(CPACK_DEBIAN_PACKAGE_DEPENDS " ")
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE_URL "https://github.com/ArthurSonzogni/FTXUI/")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Arthur Sonzogni")
set(CPACK_DEBIAN_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A simple C++ Terminal UI library")
set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/ArthurSonzogni/FTXUI/")
set(CPACK_PACKAGE_NAME "ftxui")
set(CPACK_PACKAGE_VENDOR "Arthur Sonzogni")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
include(CPack)

View file

@ -0,0 +1,104 @@
find_program(CLANG_TIDY_EXE NAMES "clang-tidy" DOC "Path to clang-tidy executable" )
function(ftxui_set_options library)
set_target_properties(${library} PROPERTIES VERSION ${PROJECT_VERSION})
if (NOT ${library} MATCHES "ftxui-*")
set_target_properties(${library} PROPERTIES OUTPUT_NAME "ftxui-${library}")
endif()
if (FTXUI_CLANG_TIDY)
if (NOT CLANG_TIDY_EXE)
message(FATAL_ERROR "clang-tidy requested but executable not found")
endif()
set_target_properties(${library}
PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_EXE};-warnings-as-errors=*"
)
# By using "PUBLIC" as opposed to "SYSTEM INTERFACE", the compiler warning
# are enforced on the headers. This is behind "FTXUI_CLANG_TIDY", so that it
# applies only when developing FTXUI and on the CI. User's of the library
# get only the SYSTEM INTERFACE instead.
target_include_directories(${library}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)
else()
target_include_directories(${library} SYSTEM
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)
endif()
target_include_directories(${library} SYSTEM
INTERFACE
$<INSTALL_INTERFACE:include>
)
target_include_directories(${library}
PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)
target_compile_features(${library} PUBLIC cxx_std_17)
# Force Microsoft Visual Studio to decode sources files in UTF-8. This applies
# to the library and the library users.
if (MSVC)
target_compile_options(${library} PUBLIC "/utf-8")
endif()
# Add as many warning as possible:
if (WIN32)
if (MSVC)
if(FTXUI_DEV_WARNINGS)
target_compile_options(${library} PRIVATE "/W3")
target_compile_options(${library} PRIVATE "/WX")
endif()
target_compile_options(${library} PRIVATE "/wd4244")
target_compile_options(${library} PRIVATE "/wd4267")
target_compile_options(${library} PRIVATE "/D_CRT_SECURE_NO_WARNINGS")
endif()
# Force Win32 to UNICODE
target_compile_definitions(${library} PRIVATE UNICODE _UNICODE)
else()
if(FTXUI_DEV_WARNINGS)
target_compile_options(${library} PRIVATE "-Wall")
target_compile_options(${library} PRIVATE "-Werror")
target_compile_options(${library} PRIVATE "-Wextra")
target_compile_options(${library} PRIVATE "-Wcast-align")
target_compile_options(${library} PRIVATE "-Wdeprecated")
target_compile_options(${library} PRIVATE "-Wmissing-declarations")
target_compile_options(${library} PRIVATE "-Wnon-virtual-dtor")
target_compile_options(${library} PRIVATE "-Wnull-dereference")
target_compile_options(${library} PRIVATE "-Woverloaded-virtual")
target_compile_options(${library} PRIVATE "-Wpedantic")
target_compile_options(${library} PRIVATE "-Wshadow")
target_compile_options(${library} PRIVATE "-Wunused")
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(${library} PRIVATE "-Wuseless-cast")
endif()
endif()
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(FTXUI_DEV_WARNINGS)
target_compile_options(${library} PRIVATE "-Wdocumentation")
endif()
endif()
if (FTXUI_MICROSOFT_TERMINAL_FALLBACK)
target_compile_definitions(${library}
PRIVATE "FTXUI_MICROSOFT_TERMINAL_FALLBACK")
endif()
endfunction()
if (EMSCRIPTEN)
string(APPEND CMAKE_CXX_FLAGS " -s USE_PTHREADS")
string(APPEND CMAKE_EXE_LINKER_FLAGS " -s ASYNCIFY")
string(APPEND CMAKE_EXE_LINKER_FLAGS " -s PROXY_TO_PTHREAD")
endif()

View file

@ -0,0 +1,74 @@
if (NOT FTXUI_BUILD_TESTS)
return()
endif()
enable_testing()
include(cmake/ftxui_find_google_test.cmake)
add_executable(ftxui-tests
src/ftxui/component/animation_test.cpp
src/ftxui/component/button_test.cpp
src/ftxui/component/collapsible_test.cpp
src/ftxui/component/component_test.cpp
src/ftxui/component/component_test.cpp
src/ftxui/component/container_test.cpp
src/ftxui/component/hoverable_test.cpp
src/ftxui/component/input_test.cpp
src/ftxui/component/menu_test.cpp
src/ftxui/component/modal_test.cpp
src/ftxui/component/radiobox_test.cpp
src/ftxui/component/receiver_test.cpp
src/ftxui/component/resizable_split_test.cpp
src/ftxui/component/screen_interactive_test.cpp
src/ftxui/component/slider_test.cpp
src/ftxui/component/terminal_input_parser_test.cpp
src/ftxui/component/toggle_test.cpp
src/ftxui/dom/blink_test.cpp
src/ftxui/dom/bold_test.cpp
src/ftxui/dom/border_test.cpp
src/ftxui/dom/canvas_test.cpp
src/ftxui/dom/color_test.cpp
src/ftxui/dom/dbox_test.cpp
src/ftxui/dom/dim_test.cpp
src/ftxui/dom/flexbox_helper_test.cpp
src/ftxui/dom/flexbox_test.cpp
src/ftxui/dom/gauge_test.cpp
src/ftxui/dom/gridbox_test.cpp
src/ftxui/dom/hbox_test.cpp
src/ftxui/dom/hyperlink_test.cpp
src/ftxui/dom/linear_gradient_test.cpp
src/ftxui/dom/scroll_indicator_test.cpp
src/ftxui/dom/separator_test.cpp
src/ftxui/dom/spinner_test.cpp
src/ftxui/dom/table_test.cpp
src/ftxui/dom/text_test.cpp
src/ftxui/dom/underlined_test.cpp
src/ftxui/dom/vbox_test.cpp
src/ftxui/screen/color_test.cpp
src/ftxui/screen/string_test.cpp
)
target_link_libraries(ftxui-tests
PRIVATE component
PRIVATE GTest::gtest
PRIVATE GTest::gtest_main
)
target_include_directories(ftxui-tests
PRIVATE src
)
target_compile_features(ftxui-tests PRIVATE cxx_std_20)
if (FTXUI_MICROSOFT_TERMINAL_FALLBACK)
target_compile_definitions(ftxui-tests
PRIVATE "FTXUI_MICROSOFT_TERMINAL_FALLBACK")
endif()
include(GoogleTest)
gtest_discover_tests(ftxui-tests
DISCOVERY_TIMEOUT 600
)
#set(CMAKE_CTEST_ARGUMENTS "--rerun-failed --output-on-failure")
#set_tests_properties(gen_init_queries PROPERTIES FIXTURES_SETUP f_init_queries)
#set_tests_properties(test PROPERTIES FIXTURES_REQUIRED f_init_queries)

View file

@ -0,0 +1,7 @@
find_program(iwyu_path NAMES include-what-you-use iwyu)
if(iwyu_path)
set_property(TARGET ${lib}
PROPERTY "${iwyu_path}" -Xiwyu
--mapping_file "${CMAKE_CURRENT_SOURCE_DIR}/iwyu.imp"
)
endif()

View file

@ -0,0 +1,12 @@
codecov:
require_ci_to_pass: no
notify:
after_n_builds: 4
wait_for_ci: yes
coverage:
precision: 2
round: down
range: "50...100"
comment: false

View file

@ -0,0 +1,27 @@
if(NOT FTXUI_BUILD_DOCS)
return()
endif()
find_package(Doxygen)
if (NOT DOXYGEN_FOUND)
message("Doxygen need to be installed to generate the doxygen documentation")
return()
endif()
# Generate example list for documentation
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)
file(APPEND ${EXAMPLE_LIST} "\n@example examples/${EXAMPLE}.cpp")
endforeach(EXAMPLE IN LISTS EXAMPLES)
configure_file(Doxyfile.in Doxyfile @ONLY)
# note the option ALL which allows to build the docs together with the application
add_custom_target(doc
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM
)

File diff suppressed because it is too large Load diff

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

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>

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

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

View file

@ -0,0 +1,872 @@
\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│
└────┘└────────────────────────────────────┘└─────┘
```
# Build {#build}
## Using CMake {#build-cmake}
This is an example configuration for your **CMakeLists.txt**
CMakeLists.txt
```cmake
cmake_minimum_required (VERSION 3.11)
# --- Fetch FTXUI --------------------------------------------------------------
include(FetchContent)
set(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)
FetchContent_Declare(ftxui
GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui
# Important: Specify a GIT_TAG XXXXX here.
)
FetchContent_GetProperties(ftxui)
if(NOT ftxui_POPULATED)
FetchContent_Populate(ftxui)
add_subdirectory(${ftxui_SOURCE_DIR} ${ftxui_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()
# ------------------------------------------------------------------------------
project(ftxui-starter
LANGUAGES CXX
VERSION 1.0.0
)
add_executable(ftxui-starter src/main.cpp)
target_include_directories(ftxui-starter PRIVATE src)
target_link_libraries(ftxui-starter
PRIVATE ftxui::screen
PRIVATE ftxui::dom
PRIVATE ftxui::component # Not needed for this example.
)
```
Subsequently, you build the project in the standard fashion as follows:
```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, 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`, `dim`, `underlined`, `inverted`, `blink`.
```cpp
Element bold(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
## 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

@ -0,0 +1,28 @@
if(NOT FTXUI_BUILD_EXAMPLES)
return()
endif()
set(EXAMPLES_DIR ${CMAKE_CURRENT_SOURCE_DIR})
function(example name)
add_executable(ftxui_example_${name} ${name}.cpp)
target_link_libraries(ftxui_example_${name} PUBLIC ${DIRECTORY_LIB})
file(RELATIVE_PATH dir ${EXAMPLES_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
set_property(GLOBAL APPEND PROPERTY FTXUI::EXAMPLES ${dir}/${name})
target_compile_features(ftxui_example_${name} PRIVATE cxx_std_20)
endfunction(example)
add_subdirectory(component)
add_subdirectory(dom)
if (EMSCRIPTEN)
string(APPEND CMAKE_EXE_LINKER_FLAGS " -s ALLOW_MEMORY_GROWTH=1")
target_link_options(component PUBLIC "SHELL: -s ALLOW_MEMORY_GROWTH=1")
get_property(EXAMPLES GLOBAL PROPERTY FTXUI::EXAMPLES)
foreach(file
"index.html"
"sw.js"
"run_webassembly.py")
configure_file(${file} ${file})
endforeach(file)
endif()

View file

@ -0,0 +1,47 @@
set(DIRECTORY_LIB component)
example(button)
example(button_animated)
example(button_in_frame)
example(button_style)
example(canvas_animated)
example(checkbox)
example(checkbox_in_frame)
example(collapsible)
example(composition)
example(custom_loop)
example(dropdown)
example(flexbox_gallery)
example(focus)
example(focus_cursor)
example(gallery)
example(homescreen)
example(input)
example(input_style)
example(linear_gradient_gallery)
example(maybe)
example(menu)
example(menu2)
example(menu_entries)
example(menu_entries_animated)
example(menu_in_frame)
example(menu_multiple)
example(menu_style)
example(menu_underline_animated_gallery)
example(modal_dialog)
example(modal_dialog_custom)
example(nested_screen)
example(print_key_press)
example(radiobox)
example(radiobox_in_frame)
example(renderer)
example(resizable_split)
example(slider)
example(slider_direction)
example(slider_rgb)
example(tab_horizontal)
example(tab_vertical)
example(textarea)
example(toggle)
example(window)
example(with_restored_io)

View file

@ -0,0 +1,39 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for shared_ptr, __shared_ptr_access
#include <string> // for operator+, to_string
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Button, Horizontal, Renderer
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for separator, gauge, text, Element, operator|, vbox, border
using namespace ftxui;
int main() {
int value = 50;
// The tree of components. This defines how to navigate using the keyboard.
auto buttons = Container::Horizontal({
Button("Decrease", [&] { value--; }),
Button("Increase", [&] { value++; }),
});
// Modify the way to render them on screen:
auto component = Renderer(buttons, [&] {
return vbox({
text("value = " + std::to_string(value)),
separator(),
gauge(value * 0.01f),
separator(),
buttons->Render(),
}) |
border;
});
auto screen = ScreenInteractive::FitComponent();
screen.Loop(component);
return 0;
}

View file

@ -0,0 +1,45 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for shared_ptr, __shared_ptr_access
#include <string> // for operator+, to_string
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Button, Horizontal, Renderer
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/component_options.hpp" // for ButtonOption
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for gauge, separator, text, vbox, operator|, Element, border
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::Green, Color::Red
using namespace ftxui;
int main() {
int value = 50;
// The tree of components. This defines how to navigate using the keyboard.
auto buttons = Container::Horizontal({
Button(
"Decrease", [&] { value--; }, ButtonOption::Animated(Color::Red)),
Button(
"Reset", [&] { value = 50; }, ButtonOption::Animated(Color::Green)),
Button(
"Increase", [&] { value++; }, ButtonOption::Animated(Color::Blue)),
});
// Modify the way to render them on screen:
auto component = Renderer(buttons, [&] {
return vbox({
vbox({
text("value = " + std::to_string(value)),
separator(),
gauge(value * 0.01f),
}) | border,
buttons->Render(),
});
});
auto screen = ScreenInteractive::FitComponent();
screen.Loop(component);
return 0;
}

View file

@ -0,0 +1,47 @@
// Copyright 2022 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for allocator, __shared_ptr_access, shared_ptr
#include <string> // for to_string, operator+
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Button, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/component_options.hpp" // for ButtonOption
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for operator|, text, Element, hbox, separator, size, vbox, border, frame, vscroll_indicator, HEIGHT, LESS_THAN
#include "ftxui/screen/color.hpp" // for Color, Color::Default, Color::GrayDark, Color::White
using namespace ftxui;
int main() {
int counter = 0;
auto on_click = [&] { counter++; };
auto style = ButtonOption::Animated(Color::Default, Color::GrayDark,
Color::Default, Color::White);
auto container = Container::Vertical({});
for (int i = 0; i < 30; ++i) {
auto button = Button("Button " + std::to_string(i), on_click, style);
container->Add(button);
}
auto renderer = Renderer(container, [&] {
return vbox({
hbox({
text("Counter:"),
text(std::to_string(counter)),
}),
separator(),
container->Render() | vscroll_indicator | frame |
size(HEIGHT, LESS_THAN, 20),
}) |
border;
});
auto screen = ScreenInteractive::FitComponent();
screen.Loop(renderer);
return 0;
}

View file

@ -0,0 +1,60 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <string> // for operator+, to_string
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Button, Vertical, Renderer, Horizontal, operator|
#include "ftxui/component/component_base.hpp" // for Component
#include "ftxui/component/component_options.hpp" // for ButtonOption
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for Element, separator, text, border
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::Green, Color::Red
using namespace ftxui;
int main() {
int value = 0;
auto action = [&] { value++; };
auto action_renderer =
Renderer([&] { return text("count = " + std::to_string(value)); });
auto buttons =
Container::Vertical({
action_renderer,
Renderer([] { return separator(); }),
Container::Horizontal({
Container::Vertical({
Button("Ascii 1", action, ButtonOption::Ascii()),
Button("Ascii 2", action, ButtonOption::Ascii()),
Button("Ascii 3", action, ButtonOption::Ascii()),
}),
Renderer([] { return separator(); }),
Container::Vertical({
Button("Simple 1", action, ButtonOption::Simple()),
Button("Simple 2", action, ButtonOption::Simple()),
Button("Simple 3", action, ButtonOption::Simple()),
}),
Renderer([] { return separator(); }),
Container::Vertical({
Button("Animated 1", action, ButtonOption::Animated()),
Button("Animated 2", action, ButtonOption::Animated()),
Button("Animated 3", action, ButtonOption::Animated()),
}),
Renderer([] { return separator(); }),
Container::Vertical({
Button("Animated 4", action,
ButtonOption::Animated(Color::Red)),
Button("Animated 5", action,
ButtonOption::Animated(Color::Green)),
Button("Animated 6", action,
ButtonOption::Animated(Color::Blue)),
}),
}),
}) |
border;
auto screen = ScreenInteractive::FitComponent();
screen.Loop(buttons);
return 0;
}

View file

@ -0,0 +1,262 @@
// Copyright 2021 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSED file.
#include <cmath> // for sin, cos
#include <ftxui/dom/elements.hpp> // for canvas, Element, separator, hbox, operator|, border
#include <ftxui/screen/screen.hpp> // for Pixel
#include <memory> // for allocator, shared_ptr, __shared_ptr_access
#include <string> // for string, basic_string
#include <utility> // for move
#include <vector> // for vector, __alloc_traits<>::value_type
#include "ftxui/component/component.hpp" // for Renderer, CatchEvent, Horizontal, Menu, Tab
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/event.hpp" // for Event
#include "ftxui/component/mouse.hpp" // for Mouse
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/canvas.hpp" // for Canvas
#include "ftxui/screen/color.hpp" // for Color, Color::Red, Color::Blue, Color::Green, ftxui
int main() {
using namespace ftxui;
int mouse_x = 0;
int mouse_y = 0;
// A triangle following the mouse, using braille characters.
auto renderer_line_braille = Renderer([&] {
auto c = Canvas(100, 100);
c.DrawText(0, 0, "Several lines (braille)");
c.DrawPointLine(mouse_x, mouse_y, 80, 10, Color::Red);
c.DrawPointLine(80, 10, 80, 40, Color::Blue);
c.DrawPointLine(80, 40, mouse_x, mouse_y, Color::Green);
return canvas(std::move(c));
});
// A triangle following the mouse, using block characters.
auto renderer_line_block = Renderer([&] {
auto c = Canvas(100, 100);
c.DrawText(0, 0, "Several lines (block)");
c.DrawBlockLine(mouse_x, mouse_y, 80, 10, Color::Red);
c.DrawBlockLine(80, 10, 80, 40, Color::Blue);
c.DrawBlockLine(80, 40, mouse_x, mouse_y, Color::Green);
return canvas(std::move(c));
});
// A circle following the mouse, using braille characters.
auto renderer_circle_braille = Renderer([&] {
auto c = Canvas(100, 100);
c.DrawText(0, 0, "A circle (braille)");
c.DrawPointCircle(mouse_x, mouse_y, 30);
return canvas(std::move(c));
});
// A circle following the mouse, using block characters.
auto renderer_circle_block = Renderer([&] {
auto c = Canvas(100, 100);
c.DrawText(0, 0, "A circle (block)");
c.DrawBlockCircle(mouse_x, mouse_y, 30);
return canvas(std::move(c));
});
// A filled circle following the mouse, using braille characters.
auto renderer_circle_filled_braille = Renderer([&] {
auto c = Canvas(100, 100);
c.DrawText(0, 0, "A circle filled (braille)");
c.DrawPointCircleFilled(mouse_x, mouse_y, 30);
return canvas(std::move(c));
});
// A filled circle following the mouse, using block characters.
auto renderer_circle_filled_block = Renderer([&] {
auto c = Canvas(100, 100);
c.DrawText(0, 0, "A circle filled (block)");
c.DrawBlockCircleFilled(mouse_x, mouse_y, 30);
return canvas(std::move(c));
});
// An ellipse following the mouse, using braille characters.
auto renderer_ellipse_braille = Renderer([&] {
auto c = Canvas(100, 100);
c.DrawText(0, 0, "An ellipse (braille)");
c.DrawPointEllipse(mouse_x / 2, mouse_y / 2, mouse_x / 2, mouse_y / 2);
return canvas(std::move(c));
});
// An ellipse following the mouse, using block characters.
auto renderer_ellipse_block = Renderer([&] {
auto c = Canvas(100, 100);
c.DrawText(0, 0, "An ellipse (block)");
c.DrawBlockEllipse(mouse_x / 2, mouse_y / 2, mouse_x / 2, mouse_y / 2);
return canvas(std::move(c));
});
// An ellipse following the mouse filled, using braille characters.
auto renderer_ellipse_filled_braille = Renderer([&] {
auto c = Canvas(100, 100);
c.DrawText(0, 0, "A filled ellipse (braille)");
c.DrawPointEllipseFilled(mouse_x / 2, mouse_y / 2, mouse_x / 2,
mouse_y / 2);
return canvas(std::move(c));
});
// An ellipse following the mouse filled, using block characters.
auto renderer_ellipse_filled_block = Renderer([&] {
auto c = Canvas(100, 100);
c.DrawText(0, 0, "A filled ellipse (block)");
c.DrawBlockEllipseFilled(mouse_x / 2, mouse_y / 2, mouse_x / 2,
mouse_y / 2);
c.DrawBlockEllipse(mouse_x / 2, mouse_y / 2, mouse_x / 2, mouse_y / 2);
return canvas(std::move(c));
});
// A text following the mouse
auto renderer_text = Renderer([&] {
auto c = Canvas(100, 100);
c.DrawText(0, 0, "A piece of text");
c.DrawText(mouse_x, mouse_y, "This is a piece of text with effects",
[](Pixel& p) {
p.foreground_color = Color::Red;
p.underlined = true;
p.bold = true;
});
return canvas(std::move(c));
});
auto renderer_plot_1 = Renderer([&] {
auto c = Canvas(100, 100);
c.DrawText(0, 0, "A graph");
std::vector<int> ys(100);
for (int x = 0; x < 100; x++) {
float dx = float(x - mouse_x);
float dy = 50.f;
ys[x] = int(dy + 20 * cos(dx * 0.14) + 10 * sin(dx * 0.42));
}
for (int x = 1; x < 99; x++)
c.DrawPointLine(x, ys[x], x + 1, ys[x + 1]);
return canvas(std::move(c));
});
auto renderer_plot_2 = Renderer([&] {
auto c = Canvas(100, 100);
c.DrawText(0, 0, "A symmetrical graph filled");
std::vector<int> ys(100);
for (int x = 0; x < 100; x++) {
ys[x] = int(30 + //
10 * cos(x * 0.2 - mouse_x * 0.05) + //
5 * sin(x * 0.4) + //
5 * sin(x * 0.3 - mouse_y * 0.05)); //
}
for (int x = 0; x < 100; x++) {
c.DrawPointLine(x, 50 + ys[x], x, 50 - ys[x], Color::Red);
}
return canvas(std::move(c));
});
auto renderer_plot_3 = Renderer([&] {
auto c = Canvas(100, 100);
c.DrawText(0, 0, "A 2D gaussian plot");
int size = 15;
// mouse_x = 5mx + 3*my
// mouse_y = 0mx + -5my + 90
float my = (mouse_y - 90) / -5.f;
float mx = (mouse_x - 3 * my) / 5.f;
std::vector<std::vector<float>> ys(size, std::vector<float>(size));
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
float dx = x - mx;
float dy = y - my;
ys[y][x] = -1.5 + 3.0 * std::exp(-0.2f * (dx * dx + dy * dy));
}
}
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
if (x != 0) {
c.DrawPointLine(
5 * (x - 1) + 3 * (y - 0), 90 - 5 * (y - 0) - 5 * ys[y][x - 1],
5 * (x - 0) + 3 * (y - 0), 90 - 5 * (y - 0) - 5 * ys[y][x]);
}
if (y != 0) {
c.DrawPointLine(
5 * (x - 0) + 3 * (y - 1), 90 - 5 * (y - 1) - 5 * ys[y - 1][x],
5 * (x - 0) + 3 * (y - 0), 90 - 5 * (y - 0) - 5 * ys[y][x]);
}
}
}
return canvas(std::move(c));
});
int selected_tab = 12;
auto tab = Container::Tab(
{
renderer_line_braille,
renderer_line_block,
renderer_circle_braille,
renderer_circle_block,
renderer_circle_filled_braille,
renderer_circle_filled_block,
renderer_ellipse_braille,
renderer_ellipse_block,
renderer_ellipse_filled_braille,
renderer_ellipse_filled_block,
renderer_plot_1,
renderer_plot_2,
renderer_plot_3,
renderer_text,
},
&selected_tab);
// This capture the last mouse position.
auto tab_with_mouse = CatchEvent(tab, [&](Event e) {
if (e.is_mouse()) {
mouse_x = (e.mouse().x - 1) * 2;
mouse_y = (e.mouse().y - 1) * 4;
}
return false;
});
std::vector<std::string> tab_titles = {
"line (braille)",
"line (block)",
"circle (braille)",
"circle (block)",
"circle filled (braille)",
"circle filled (block)",
"ellipse (braille)",
"ellipse (block)",
"ellipse filled (braille)",
"ellipse filled (block)",
"plot_1 simple",
"plot_2 filled",
"plot_3 3D",
"text",
};
auto tab_toggle = Menu(&tab_titles, &selected_tab);
auto component = Container::Horizontal({
tab_with_mouse,
tab_toggle,
});
// Add some separator to decorate the whole component:
auto component_renderer = Renderer(component, [&] {
return hbox({
tab_with_mouse->Render(),
separator(),
tab_toggle->Render(),
}) |
border;
});
auto screen = ScreenInteractive::FitComponent();
screen.Loop(component_renderer);
return 0;
}

View file

@ -0,0 +1,30 @@
// Copyright 2021 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for allocator, __shared_ptr_access
#include <string> // for string, basic_string, operator+, to_string
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Input, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
#include "ftxui/dom/elements.hpp" // for operator|, Element, size, border, frame, vscroll_indicator, HEIGHT, LESS_THAN
int main() {
using namespace ftxui;
Component input_list = Container::Vertical({});
std::vector<std::string> items(100, "");
for (size_t i = 0; i < items.size(); ++i) {
input_list->Add(Input(&(items[i]), "placeholder " + std::to_string(i)));
}
auto renderer = Renderer(input_list, [&] {
return input_list->Render() | vscroll_indicator | frame | border |
size(HEIGHT, LESS_THAN, 10);
});
auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(renderer);
}

View file

@ -0,0 +1,34 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <array> // for array
#include <memory> // for shared_ptr, __shared_ptr_access
#include <string> // for operator+, to_string
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Checkbox, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for operator|, Element, size, border, frame, vscroll_indicator, HEIGHT, LESS_THAN
using namespace ftxui;
int main() {
std::array<bool, 30> states;
auto container = Container::Vertical({});
for (int i = 0; i < 30; ++i) {
states[i] = false;
container->Add(Checkbox("Checkbox" + std::to_string(i), &states[i]));
}
auto renderer = Renderer(container, [&] {
return container->Render() | vscroll_indicator | frame |
size(HEIGHT, LESS_THAN, 10) | border;
});
auto screen = ScreenInteractive::FitComponent();
screen.Loop(renderer);
return 0;
}

View file

@ -0,0 +1,57 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for allocator, make_shared, __shared_ptr_access
#include <utility> // for move
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Collapsible, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
#include "ftxui/dom/elements.hpp" // for text, hbox, Element
using namespace ftxui;
// Take a list of component, display them vertically, one column shifted to the
// right.
Component Inner(std::vector<Component> children) {
Component vlist = Container::Vertical(std::move(children));
return Renderer(vlist, [vlist] {
return hbox({
text(" "),
vlist->Render(),
});
});
}
Component Empty() {
return std::make_shared<ComponentBase>();
}
int main() {
auto component =
Collapsible("Collapsible 1",
Inner({
Collapsible("Collapsible 1.1",
Inner({
Collapsible("Collapsible 1.1.1", Empty()),
Collapsible("Collapsible 1.1.2", Empty()),
Collapsible("Collapsible 1.1.3", Empty()),
})),
Collapsible("Collapsible 1.2",
Inner({
Collapsible("Collapsible 1.2.1", Empty()),
Collapsible("Collapsible 1.2.2", Empty()),
Collapsible("Collapsible 1.2.3", Empty()),
})),
Collapsible("Collapsible 1.3",
Inner({
Collapsible("Collapsible 1.3.1", Empty()),
Collapsible("Collapsible 1.3.2", Empty()),
Collapsible("Collapsible 1.3.3", Empty()),
})),
}));
ScreenInteractive::FitComponent().Loop(component);
}

View file

@ -0,0 +1,63 @@
// Copyright 2021 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for allocator, shared_ptr, __shared_ptr_access
#include <string> // for operator+, to_string
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Button, Horizontal, Renderer
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for text, separator, Element, operator|, vbox, border
using namespace ftxui;
// An example of how to compose multiple components into one and maintain their
// interactiveness.
int main() {
auto left_count = 0;
auto right_count = 0;
auto left_buttons = Container::Horizontal({
Button("Decrease", [&] { left_count--; }),
Button("Increase", [&] { left_count++; }),
});
auto right_buttons = Container::Horizontal({
Button("Decrease", [&] { right_count--; }),
Button("Increase", [&] { right_count++; }),
});
// Renderer decorates its child with a new rendering function. The way the
// children reacts to events is maintained.
auto leftpane = Renderer(left_buttons, [&] {
return vbox({
text("This is the left control"),
separator(),
text("Left button count: " + std::to_string(left_count)),
left_buttons->Render(),
}) |
border;
});
auto rightpane = Renderer(right_buttons, [&] {
return vbox({
text("This is the right control"),
separator(),
text("Right button count: " + std::to_string(right_count)),
right_buttons->Render(),
}) |
border;
});
// Container groups components togethers. To render a Container::Horizontal,
// it render its children side by side. It maintains their interactiveness and
// provide the logic to navigate from one to the other using the arrow keys.
auto composition = Container::Horizontal({leftpane, rightpane});
auto screen = ScreenInteractive::FitComponent();
screen.Loop(composition);
return 0;
}
// Thanks to Chris Morgan for this example!

View file

@ -0,0 +1,54 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <stdlib.h> // for EXIT_SUCCESS
#include <chrono> // for milliseconds
#include <ftxui/component/event.hpp> // for Event
#include <ftxui/component/mouse.hpp> // for ftxui
#include <ftxui/dom/elements.hpp> // for text, separator, Element, operator|, vbox, border
#include <memory> // for allocator, shared_ptr
#include <string> // for operator+, to_string
#include <thread> // for sleep_for
#include "ftxui/component/component.hpp" // for CatchEvent, Renderer, operator|=
#include "ftxui/component/loop.hpp" // for Loop
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
int main() {
using namespace ftxui;
auto screen = ScreenInteractive::FitComponent();
// Create a component counting the number of frames drawn and event handled.
int custom_loop_count = 0;
int frame_count = 0;
int event_count = 0;
auto component = Renderer([&] {
frame_count++;
return vbox({
text("This demonstrates using a custom ftxui::Loop. It "),
text("runs at 100 iterations per seconds. The FTXUI events "),
text("are all processed once per iteration and a new frame "),
text("is rendered as needed"),
separator(),
text("ftxui event count: " + std::to_string(event_count)),
text("ftxui frame count: " + std::to_string(frame_count)),
text("Custom loop count: " + std::to_string(custom_loop_count)),
}) |
border;
});
component |= CatchEvent([&](Event) -> bool {
event_count++;
return false;
});
Loop loop(&screen, component);
while (!loop.HasQuitted()) {
custom_loop_count++;
loop.RunOnce();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,44 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <string> // for basic_string, string, allocator
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Dropdown, Horizontal, Vertical
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
int main() {
using namespace ftxui;
std::vector<std::string> entries = {
"tribute", "clearance", "ally", "bend", "electronics",
"module", "era", "cultural", "sniff", "nationalism",
"negotiation", "deliver", "figure", "east", "tribute",
"clearance", "ally", "bend", "electronics", "module",
"era", "cultural", "sniff", "nationalism", "negotiation",
"deliver", "figure", "east", "tribute", "clearance",
"ally", "bend", "electronics", "module", "era",
"cultural", "sniff", "nationalism", "negotiation", "deliver",
"figure", "east",
};
int selected_1 = 0;
int selected_2 = 0;
int selected_3 = 0;
int selected_4 = 0;
auto layout = Container::Vertical({
Container::Horizontal({
Dropdown(&entries, &selected_1),
Dropdown(&entries, &selected_2),
}),
Container::Horizontal({
Dropdown(&entries, &selected_3),
Dropdown(&entries, &selected_4),
}),
});
auto screen = ScreenInteractive::FitComponent();
screen.Loop(layout);
}

View file

@ -0,0 +1,191 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <stddef.h> // for size_t
#include <memory> // for shared_ptr, __shared_ptr_access, allocator
#include <string> // for string, basic_string, to_string, operator+, char_traits
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Radiobox, Vertical, Checkbox, Horizontal, Renderer, ResizableSplitBottom, ResizableSplitRight
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for text, window, operator|, vbox, hbox, Element, flexbox, bgcolor, filler, flex, size, border, hcenter, color, EQUAL, bold, dim, notflex, xflex_grow, yflex_grow, HEIGHT, WIDTH
#include "ftxui/dom/flexbox_config.hpp" // for FlexboxConfig, FlexboxConfig::AlignContent, FlexboxConfig::JustifyContent, FlexboxConfig::AlignContent::Center, FlexboxConfig::AlignItems, FlexboxConfig::Direction, FlexboxConfig::JustifyContent::Center, FlexboxConfig::Wrap
#include "ftxui/screen/color.hpp" // for Color, Color::Black
using namespace ftxui;
int main() {
auto screen = ScreenInteractive::Fullscreen();
int direction_index = 0;
int wrap_index = 0;
int justify_content_index = 0;
int align_items_index = 0;
int align_content_index = 0;
std::vector<std::string> directions = {
"Row",
"RowInversed",
"Column",
"ColumnInversed",
};
std::vector<std::string> wraps = {
"NoWrap",
"Wrap",
"WrapInversed",
};
std::vector<std::string> justify_content = {
"FlexStart", "FlexEnd", "Center", "Stretch",
"SpaceBetween", "SpaceAround", "SpaceEvenly",
};
std::vector<std::string> align_items = {
"FlexStart",
"FlexEnd",
"Center",
"Stretch",
};
std::vector<std::string> align_content = {
"FlexStart", "FlexEnd", "Center", "Stretch",
"SpaceBetween", "SpaceAround", "SpaceEvenly",
};
auto radiobox_direction = Radiobox(&directions, &direction_index);
auto radiobox_wrap = Radiobox(&wraps, &wrap_index);
auto radiobox_justify_content =
Radiobox(&justify_content, &justify_content_index);
auto radiobox_align_items = Radiobox(&align_items, &align_items_index);
auto radiobox_align_content = Radiobox(&align_content, &align_content_index);
bool element_xflex_grow = false;
bool element_yflex_grow = false;
bool group_xflex_grow = true;
bool group_yflex_grow = true;
auto checkbox_element_xflex_grow =
Checkbox("element |= xflex_grow", &element_xflex_grow);
auto checkbox_element_yflex_grow =
Checkbox("element |= yflex_grow", &element_yflex_grow);
auto checkbox_group_xflex_grow =
Checkbox("group |= xflex_grow", &group_xflex_grow);
auto checkbox_group_yflex_grow =
Checkbox("group |= yflex_grow", &group_yflex_grow);
auto make_box = [&](size_t dimx, size_t dimy, size_t index) {
std::string title = std::to_string(dimx) + "x" + std::to_string(dimy);
auto element = window(text(title) | hcenter | bold,
text(std::to_string(index)) | hcenter | dim) |
size(WIDTH, EQUAL, dimx) | size(HEIGHT, EQUAL, dimy) |
bgcolor(Color::HSV(index * 25, 255, 255)) |
color(Color::Black);
if (element_xflex_grow)
element = element | xflex_grow;
if (element_yflex_grow)
element = element | yflex_grow;
return element;
};
auto content_renderer = Renderer([&] {
FlexboxConfig config;
config.direction = static_cast<FlexboxConfig::Direction>(direction_index);
config.wrap = static_cast<FlexboxConfig::Wrap>(wrap_index);
config.justify_content =
static_cast<FlexboxConfig::JustifyContent>(justify_content_index);
config.align_items =
static_cast<FlexboxConfig::AlignItems>(align_items_index);
config.align_content =
static_cast<FlexboxConfig::AlignContent>(align_content_index);
auto group = flexbox(
{
make_box(8, 4, 0),
make_box(9, 6, 1),
make_box(11, 6, 2),
make_box(10, 4, 3),
make_box(13, 7, 4),
make_box(12, 4, 5),
make_box(12, 5, 6),
make_box(10, 4, 7),
make_box(12, 4, 8),
make_box(10, 5, 9),
},
config);
group = group | bgcolor(Color::Black);
group = group | notflex;
if (!group_xflex_grow)
group = hbox(group, filler());
if (!group_yflex_grow)
group = vbox(group, filler());
group = group | flex;
return group;
});
auto center = FlexboxConfig()
.Set(FlexboxConfig::JustifyContent::Center)
.Set(FlexboxConfig::AlignContent::Center);
int space_right = 10;
int space_bottom = 1;
content_renderer = ResizableSplitRight(
Renderer([&] { return flexbox({text("resizable")}, center); }),
content_renderer, &space_right);
content_renderer = ResizableSplitBottom(
Renderer([&] { return flexbox({text("resizable")}, center); }),
content_renderer, &space_bottom);
auto main_container = Container::Vertical({
Container::Horizontal({
radiobox_direction,
radiobox_wrap,
Container::Vertical({
checkbox_element_xflex_grow,
checkbox_element_yflex_grow,
checkbox_group_xflex_grow,
checkbox_group_yflex_grow,
}),
}),
Container::Horizontal({
radiobox_justify_content,
radiobox_align_items,
radiobox_align_content,
}),
content_renderer,
});
auto main_renderer = Renderer(main_container, [&] {
return vbox({
vbox({hbox({
window(text("FlexboxConfig::Direction"),
radiobox_direction->Render()),
window(text("FlexboxConfig::Wrap"), radiobox_wrap->Render()),
window(text("Misc:"),
vbox({
checkbox_element_xflex_grow->Render(),
checkbox_element_yflex_grow->Render(),
checkbox_group_xflex_grow->Render(),
checkbox_group_yflex_grow->Render(),
})),
}),
hbox({
window(text("FlexboxConfig::JustifyContent"),
radiobox_justify_content->Render()),
window(text("FlexboxConfig::AlignItems"),
radiobox_align_items->Render()),
window(text("FlexboxConfig::AlignContent"),
radiobox_align_content->Render()),
})}),
content_renderer->Render() | flex | border,
});
});
screen.Loop(main_renderer);
return 0;
}

View file

@ -0,0 +1,69 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for allocator, shared_ptr, __shared_ptr_access
#include <string> // for operator+, char_traits, to_string, string
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Slider, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for Elements, Element, operator|, separator, text, focusPositionRelative, size, border, flex, frame, bgcolor, gridbox, vbox, EQUAL, center, HEIGHT, WIDTH
#include "ftxui/screen/color.hpp" // for Color
using namespace ftxui;
Element make_box(int x, int y) {
std::string title = "(" + std::to_string(x) + ", " + std::to_string(y) + ")";
return text(title) | center | size(WIDTH, EQUAL, 18) |
size(HEIGHT, EQUAL, 9) | border |
bgcolor(Color::HSV(x * 255 / 15, 255, y * 255 / 15));
};
Element make_grid() {
std::vector<Elements> rows;
for (int i = 0; i < 15; i++) {
std::vector<Element> cols;
for (int j = 0; j < 15; j++) {
cols.push_back(make_box(i, j));
}
rows.push_back(cols);
}
return gridbox(rows);
};
int main() {
float focus_x = 0.5f;
float focus_y = 0.5f;
auto slider_x = Slider("x", &focus_x, 0.f, 1.f, 0.01f);
auto slider_y = Slider("y", &focus_y, 0.f, 1.f, 0.01f);
auto renderer = Renderer(
Container::Vertical({
slider_x,
slider_y,
}),
[&] {
auto title = "focusPositionRelative(" + //
std::to_string(focus_x) + ", " + //
std::to_string(focus_y) + ")"; //
return vbox({
text(title),
separator(),
slider_x->Render(),
slider_y->Render(),
separator(),
make_grid() | focusPositionRelative(focus_x, focus_y) |
frame | flex,
}) |
border;
});
auto screen = ScreenInteractive::Fullscreen();
screen.Loop(renderer);
return 0;
}

View file

@ -0,0 +1,37 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <ftxui/component/captured_mouse.hpp> // for ftxui
#include <string> // for allocator, operator+, char_traits, string
#include "ftxui/component/component.hpp" // for Renderer, Vertical
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive, Component
#include "ftxui/dom/elements.hpp" // for text, Decorator, focus, focusCursorBar, focusCursorBarBlinking, focusCursorBlock, focusCursorBlockBlinking, focusCursorUnderline, focusCursorUnderlineBlinking, hbox, Element
using namespace ftxui;
Component Instance(std::string label, Decorator focusCursor) {
return Renderer([=](bool focused) {
if (focused) {
return hbox({
text("> " + label + " "),
focusCursor(text(" ")),
});
}
return text(" " + label + " ");
});
};
int main() {
auto screen = ScreenInteractive::Fullscreen();
screen.Loop(Container::Vertical({
Instance("focus", focus),
Instance("focusCursorBlock", focusCursorBlock),
Instance("focusCursorBlockBlinking", focusCursorBlockBlinking),
Instance("focusCursorBar", focusCursorBar),
Instance("focusCursorBarBlinking", focusCursorBarBlinking),
Instance("focusCursorUnderline", focusCursorUnderline),
Instance("focusCursorUnderlineBlinking", focusCursorUnderlineBlinking),
}));
return 0;
}

View file

@ -0,0 +1,133 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <functional> // for function
#include <memory> // for shared_ptr, allocator, __shared_ptr_access
#include <string> // for string, basic_string
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Slider, Checkbox, Vertical, Renderer, Button, Input, Menu, Radiobox, Toggle
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
#include "ftxui/dom/elements.hpp" // for separator, operator|, Element, size, xflex, text, WIDTH, hbox, vbox, EQUAL, border, GREATER_THAN
using namespace ftxui;
// Display a component nicely with a title on the left.
Component Wrap(std::string name, Component component) {
return Renderer(component, [name, component] {
return hbox({
text(name) | size(WIDTH, EQUAL, 8),
separator(),
component->Render() | xflex,
}) |
xflex;
});
}
int main() {
auto screen = ScreenInteractive::FitComponent();
// -- Menu
// ----------------------------------------------------------------------
const std::vector<std::string> menu_entries = {
"Menu 1",
"Menu 2",
"Menu 3",
"Menu 4",
};
int menu_selected = 0;
auto menu = Menu(&menu_entries, &menu_selected);
menu = Wrap("Menu", menu);
// -- Toggle------------------------------------------------------------------
int toggle_selected = 0;
std::vector<std::string> toggle_entries = {
"Toggle_1",
"Toggle_2",
};
auto toggle = Toggle(&toggle_entries, &toggle_selected);
toggle = Wrap("Toggle", toggle);
// -- Checkbox ---------------------------------------------------------------
bool checkbox_1_selected = false;
bool checkbox_2_selected = false;
bool checkbox_3_selected = false;
bool checkbox_4_selected = false;
auto checkboxes = Container::Vertical({
Checkbox("checkbox1", &checkbox_1_selected),
Checkbox("checkbox2", &checkbox_2_selected),
Checkbox("checkbox3", &checkbox_3_selected),
Checkbox("checkbox4", &checkbox_4_selected),
});
checkboxes = Wrap("Checkbox", checkboxes);
// -- Radiobox ---------------------------------------------------------------
int radiobox_selected = 0;
std::vector<std::string> radiobox_entries = {
"Radiobox 1",
"Radiobox 2",
"Radiobox 3",
"Radiobox 4",
};
auto radiobox = Radiobox(&radiobox_entries, &radiobox_selected);
radiobox = Wrap("Radiobox", radiobox);
// -- Input ------------------------------------------------------------------
std::string input_label;
auto input = Input(&input_label, "placeholder");
input = Wrap("Input", input);
// -- Button -----------------------------------------------------------------
std::string button_label = "Quit";
std::function<void()> on_button_clicked_;
auto button = Button(&button_label, screen.ExitLoopClosure());
button = Wrap("Button", button);
// -- Slider -----------------------------------------------------------------
int slider_value_1 = 12;
int slider_value_2 = 56;
int slider_value_3 = 128;
auto sliders = Container::Vertical({
Slider("R:", &slider_value_1, 0, 256, 1),
Slider("G:", &slider_value_2, 0, 256, 1),
Slider("B:", &slider_value_3, 0, 256, 1),
});
sliders = Wrap("Slider", sliders);
// -- Layout -----------------------------------------------------------------
auto layout = Container::Vertical({
menu,
toggle,
checkboxes,
radiobox,
input,
sliders,
button,
});
auto component = Renderer(layout, [&] {
return vbox({
menu->Render(),
separator(),
toggle->Render(),
separator(),
checkboxes->Render(),
separator(),
radiobox->Render(),
separator(),
input->Render(),
separator(),
sliders->Render(),
separator(),
button->Render(),
}) |
xflex | size(WIDTH, GREATER_THAN, 40) | border;
});
screen.Loop(component);
return 0;
}

View file

@ -0,0 +1,526 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <stddef.h> // for size_t
#include <array> // for array
#include <atomic> // for atomic
#include <chrono> // for operator""s, chrono_literals
#include <cmath> // for sin
#include <functional> // for ref, reference_wrapper, function
#include <memory> // for allocator, shared_ptr, __shared_ptr_access
#include <string> // for string, basic_string, char_traits, operator+, to_string
#include <thread> // for sleep_for, thread
#include <utility> // for move
#include <vector> // for vector
#include "../dom/color_info_sorted_2d.ipp" // for ColorInfoSorted2D
#include "ftxui/component/component.hpp" // for Checkbox, Renderer, Horizontal, Vertical, Input, Menu, Radiobox, ResizableSplitLeft, Tab
#include "ftxui/component/component_base.hpp" // for ComponentBase, Component
#include "ftxui/component/component_options.hpp" // for MenuOption, InputOption
#include "ftxui/component/event.hpp" // for Event, Event::Custom
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
#include "ftxui/dom/elements.hpp" // for text, color, operator|, bgcolor, filler, Element, vbox, size, hbox, separator, flex, window, graph, EQUAL, paragraph, WIDTH, hcenter, Elements, bold, vscroll_indicator, HEIGHT, flexbox, hflow, border, frame, flex_grow, gauge, paragraphAlignCenter, paragraphAlignJustify, paragraphAlignLeft, paragraphAlignRight, dim, spinner, LESS_THAN, center, yframe, GREATER_THAN
#include "ftxui/dom/flexbox_config.hpp" // for FlexboxConfig
#include "ftxui/screen/color.hpp" // for Color, Color::BlueLight, Color::RedLight, Color::Black, Color::Blue, Color::Cyan, Color::CyanLight, Color::GrayDark, Color::GrayLight, Color::Green, Color::GreenLight, Color::Magenta, Color::MagentaLight, Color::Red, Color::White, Color::Yellow, Color::YellowLight, Color::Default, Color::Palette256, ftxui
#include "ftxui/screen/color_info.hpp" // for ColorInfo
#include "ftxui/screen/terminal.hpp" // for Size, Dimensions
using namespace ftxui;
int main() {
auto screen = ScreenInteractive::Fullscreen();
// ---------------------------------------------------------------------------
// HTOP
// ---------------------------------------------------------------------------
int shift = 0;
auto my_graph = [&shift](int width, int height) {
std::vector<int> output(width);
for (int i = 0; i < width; ++i) {
float v = 0.5f;
v += 0.1f * sin((i + shift) * 0.1f);
v += 0.2f * sin((i + shift + 10) * 0.15f);
v += 0.1f * sin((i + shift) * 0.03f);
v *= height;
output[i] = (int)v;
}
return output;
};
auto htop = Renderer([&] {
auto frequency = vbox({
text("Frequency [Mhz]") | hcenter,
hbox({
vbox({
text("2400 "),
filler(),
text("1200 "),
filler(),
text("0 "),
}),
graph(std::ref(my_graph)) | flex,
}) | flex,
});
auto utilization = vbox({
text("Utilization [%]") | hcenter,
hbox({
vbox({
text("100 "),
filler(),
text("50 "),
filler(),
text("0 "),
}),
graph(std::ref(my_graph)) | color(Color::RedLight),
}) | flex,
});
auto ram = vbox({
text("Ram [Mo]") | hcenter,
hbox({
vbox({
text("8192"),
filler(),
text("4096 "),
filler(),
text("0 "),
}),
graph(std::ref(my_graph)) | color(Color::BlueLight),
}) | flex,
});
return hbox({
vbox({
frequency | flex,
separator(),
utilization | flex,
}) | flex,
separator(),
ram | flex,
}) |
flex;
});
// ---------------------------------------------------------------------------
// Compiler
// ---------------------------------------------------------------------------
const std::vector<std::string> compiler_entries = {
"gcc",
"clang",
"emcc",
"game_maker",
"Ada compilers",
"ALGOL 60 compilers",
"ALGOL 68 compilers",
"Assemblers (Intel *86)",
"Assemblers (Motorola 68*)",
"Assemblers (Zilog Z80)",
"Assemblers (other)",
"BASIC Compilers",
"BASIC interpreters",
"Batch compilers",
"C compilers",
"Source-to-source compilers",
"C++ compilers",
"C# compilers",
"COBOL compilers",
"Common Lisp compilers",
"D compilers",
"DIBOL/DBL compilers",
"ECMAScript interpreters",
"Eiffel compilers",
"Fortran compilers",
"Go compilers",
"Haskell compilers",
"Java compilers",
"Pascal compilers",
"Perl Interpreters",
"PHP compilers",
"PL/I compilers",
"Python compilers",
"Scheme compilers and interpreters",
"Smalltalk compilers",
"Tcl Interpreters",
"VMS Interpreters",
"Rexx Interpreters",
"CLI compilers",
};
int compiler_selected = 0;
Component compiler = Radiobox(&compiler_entries, &compiler_selected);
std::array<std::string, 8> options_label = {
"-Wall",
"-Werror",
"-lpthread",
"-O3",
"-Wabi-tag",
"-Wno-class-conversion",
"-Wcomma-subscript",
"-Wno-conversion-null",
};
std::array<bool, 8> options_state = {
false, false, false, false, false, false, false, false,
};
std::vector<std::string> input_entries;
int input_selected = 0;
Component input = Menu(&input_entries, &input_selected);
auto input_option = InputOption();
std::string input_add_content;
input_option.on_enter = [&] {
input_entries.push_back(input_add_content);
input_add_content = "";
};
Component input_add = Input(&input_add_content, "input files", input_option);
std::string executable_content_ = "";
Component executable_ = Input(&executable_content_, "executable");
Component flags = Container::Vertical({
Checkbox(&options_label[0], &options_state[0]),
Checkbox(&options_label[1], &options_state[1]),
Checkbox(&options_label[2], &options_state[2]),
Checkbox(&options_label[3], &options_state[3]),
Checkbox(&options_label[4], &options_state[4]),
Checkbox(&options_label[5], &options_state[5]),
Checkbox(&options_label[6], &options_state[6]),
Checkbox(&options_label[7], &options_state[7]),
});
auto compiler_component = Container::Horizontal({
compiler,
flags,
Container::Vertical({
executable_,
Container::Horizontal({
input_add,
input,
}),
}),
});
auto render_command = [&] {
Elements line;
// Compiler
line.push_back(text(compiler_entries[compiler_selected]) | bold);
// flags
for (int i = 0; i < 8; ++i) {
if (options_state[i]) {
line.push_back(text(" "));
line.push_back(text(options_label[i]) | dim);
}
}
// Executable
if (!executable_content_.empty()) {
line.push_back(text(" -o ") | bold);
line.push_back(text(executable_content_) | color(Color::BlueLight) |
bold);
}
// Input
for (auto& it : input_entries) {
line.push_back(text(" " + it) | color(Color::RedLight));
}
return line;
};
auto compiler_renderer = Renderer(compiler_component, [&] {
auto compiler_win = window(text("Compiler"),
compiler->Render() | vscroll_indicator | frame);
auto flags_win =
window(text("Flags"), flags->Render() | vscroll_indicator | frame);
auto executable_win = window(text("Executable:"), executable_->Render());
auto input_win =
window(text("Input"), hbox({
vbox({
hbox({
text("Add: "),
input_add->Render(),
}) | size(WIDTH, EQUAL, 20) |
size(HEIGHT, EQUAL, 1),
filler(),
}),
separator(),
input->Render() | vscroll_indicator | frame |
size(HEIGHT, EQUAL, 3) | flex,
}));
return vbox({
hbox({
compiler_win,
flags_win,
vbox({
executable_win | size(WIDTH, EQUAL, 20),
input_win | size(WIDTH, EQUAL, 60),
}),
filler(),
}) | size(HEIGHT, LESS_THAN, 8),
hflow(render_command()) | flex_grow,
}) |
flex_grow;
});
// ---------------------------------------------------------------------------
// Spiner
// ---------------------------------------------------------------------------
auto spinner_tab_renderer = Renderer([&] {
Elements entries;
for (int i = 0; i < 22; ++i) {
entries.push_back(spinner(i, shift / 2) | bold |
size(WIDTH, GREATER_THAN, 2) | border);
}
return hflow(std::move(entries));
});
// ---------------------------------------------------------------------------
// Colors
// ---------------------------------------------------------------------------
auto color_tab_renderer = Renderer([] {
auto basic_color_display =
vbox({
text("16 color palette:"),
separator(),
hbox({
vbox({
color(Color::Default, text("Default")),
color(Color::Black, text("Black")),
color(Color::GrayDark, text("GrayDark")),
color(Color::GrayLight, text("GrayLight")),
color(Color::White, text("White")),
color(Color::Blue, text("Blue")),
color(Color::BlueLight, text("BlueLight")),
color(Color::Cyan, text("Cyan")),
color(Color::CyanLight, text("CyanLight")),
color(Color::Green, text("Green")),
color(Color::GreenLight, text("GreenLight")),
color(Color::Magenta, text("Magenta")),
color(Color::MagentaLight, text("MagentaLight")),
color(Color::Red, text("Red")),
color(Color::RedLight, text("RedLight")),
color(Color::Yellow, text("Yellow")),
color(Color::YellowLight, text("YellowLight")),
}),
vbox({
bgcolor(Color::Default, text("Default")),
bgcolor(Color::Black, text("Black")),
bgcolor(Color::GrayDark, text("GrayDark")),
bgcolor(Color::GrayLight, text("GrayLight")),
bgcolor(Color::White, text("White")),
bgcolor(Color::Blue, text("Blue")),
bgcolor(Color::BlueLight, text("BlueLight")),
bgcolor(Color::Cyan, text("Cyan")),
bgcolor(Color::CyanLight, text("CyanLight")),
bgcolor(Color::Green, text("Green")),
bgcolor(Color::GreenLight, text("GreenLight")),
bgcolor(Color::Magenta, text("Magenta")),
bgcolor(Color::MagentaLight, text("MagentaLight")),
bgcolor(Color::Red, text("Red")),
bgcolor(Color::RedLight, text("RedLight")),
bgcolor(Color::Yellow, text("Yellow")),
bgcolor(Color::YellowLight, text("YellowLight")),
}),
}),
}) |
border;
auto palette_256_color_display = text("256 colors palette:");
{
std::vector<std::vector<ColorInfo>> info_columns = ColorInfoSorted2D();
Elements columns;
for (auto& column : info_columns) {
Elements column_elements;
for (auto& it : column) {
column_elements.push_back(
text(" ") | bgcolor(Color(Color::Palette256(it.index_256))));
}
columns.push_back(hbox(std::move(column_elements)));
}
palette_256_color_display = vbox({
palette_256_color_display,
separator(),
vbox(columns),
}) |
border;
}
// True color display.
auto true_color_display = text("TrueColors: 24bits:");
{
int saturation = 255;
Elements array;
for (int value = 0; value < 255; value += 16) {
Elements line;
for (int hue = 0; hue < 255; hue += 6) {
line.push_back(text("") //
| color(Color::HSV(hue, saturation, value)) //
| bgcolor(Color::HSV(hue, saturation, value + 8)));
}
array.push_back(hbox(std::move(line)));
}
true_color_display = vbox({
true_color_display,
separator(),
vbox(std::move(array)),
}) |
border;
}
return flexbox(
{
basic_color_display,
palette_256_color_display,
true_color_display,
},
FlexboxConfig().SetGap(1, 1));
});
// ---------------------------------------------------------------------------
// Gauges
// ---------------------------------------------------------------------------
auto render_gauge = [&shift](int delta) {
float progress = (shift + delta) % 500 / 500.f;
return hbox({
text(std::to_string(int(progress * 100)) + "% ") |
size(WIDTH, EQUAL, 5),
gauge(progress),
});
};
auto gauge_component = Renderer([render_gauge] {
return vbox({
render_gauge(0) | color(Color::Black),
render_gauge(100) | color(Color::GrayDark),
render_gauge(50) | color(Color::GrayLight),
render_gauge(6894) | color(Color::White),
separator(),
render_gauge(6841) | color(Color::Blue),
render_gauge(9813) | color(Color::BlueLight),
render_gauge(98765) | color(Color::Cyan),
render_gauge(98) | color(Color::CyanLight),
render_gauge(9846) | color(Color::Green),
render_gauge(1122) | color(Color::GreenLight),
render_gauge(84) | color(Color::Magenta),
render_gauge(645) | color(Color::MagentaLight),
render_gauge(568) | color(Color::Red),
render_gauge(2222) | color(Color::RedLight),
render_gauge(220) | color(Color::Yellow),
render_gauge(348) | color(Color::YellowLight),
});
});
// ---------------------------------------------------------------------------
// Paragraph
// ---------------------------------------------------------------------------
auto make_box = [](size_t dimx, size_t dimy) {
std::string title = std::to_string(dimx) + "x" + std::to_string(dimy);
return window(text(title) | hcenter | bold,
text("content") | hcenter | dim) |
size(WIDTH, EQUAL, dimx) | size(HEIGHT, EQUAL, dimy);
};
auto paragraph_renderer_left = Renderer([&] {
std::string str =
"Lorem Ipsum is simply dummy text of the printing and typesetting "
"industry. Lorem Ipsum has been the industry's standard dummy text "
"ever since the 1500s, when an unknown printer took a galley of type "
"and scrambled it to make a type specimen book.";
return vbox({
window(text("Align left:"), paragraphAlignLeft(str)),
window(text("Align center:"), paragraphAlignCenter(str)),
window(text("Align right:"), paragraphAlignRight(str)),
window(text("Align justify:"), paragraphAlignJustify(str)),
window(text("Side by side"), hbox({
paragraph(str),
separator(),
paragraph(str),
})),
window(text("Elements with different size:"),
flexbox({
make_box(10, 5),
make_box(9, 4),
make_box(8, 4),
make_box(6, 3),
make_box(10, 5),
make_box(9, 4),
make_box(8, 4),
make_box(6, 3),
make_box(10, 5),
make_box(9, 4),
make_box(8, 4),
make_box(6, 3),
})),
}) |
vscroll_indicator | yframe | flex;
});
auto paragraph_renderer_right = Renderer([] {
return paragraph("<--- This vertical bar is resizable using the mouse") |
center;
});
int paragraph_renderer_split_position = Terminal::Size().dimx / 2;
auto paragraph_renderer_group =
ResizableSplitLeft(paragraph_renderer_left, paragraph_renderer_right,
&paragraph_renderer_split_position);
auto paragraph_renderer_group_renderer =
Renderer(paragraph_renderer_group,
[&] { return paragraph_renderer_group->Render(); });
// ---------------------------------------------------------------------------
// Tabs
// ---------------------------------------------------------------------------
int tab_index = 0;
std::vector<std::string> tab_entries = {
"htop", "color", "spinner", "gauge", "compiler", "paragraph",
};
auto tab_selection =
Menu(&tab_entries, &tab_index, MenuOption::HorizontalAnimated());
auto tab_content = Container::Tab(
{
htop,
color_tab_renderer,
spinner_tab_renderer,
gauge_component,
compiler_renderer,
paragraph_renderer_group_renderer,
},
&tab_index);
auto main_container = Container::Vertical({
tab_selection,
tab_content,
});
auto main_renderer = Renderer(main_container, [&] {
return vbox({
text("FTXUI Demo") | bold | hcenter,
tab_selection->Render(),
tab_content->Render() | flex,
});
});
std::atomic<bool> refresh_ui_continue = true;
std::thread refresh_ui([&] {
while (refresh_ui_continue) {
using namespace std::chrono_literals;
std::this_thread::sleep_for(0.05s);
// The |shift| variable belong to the main thread. `screen.Post(task)`
// will execute the update on the thread where |screen| lives (e.g. the
// main thread). Using `screen.Post(task)` is threadsafe.
screen.Post([&] { shift++; });
// After updating the state, request a new frame to be drawn. This is done
// by simulating a new "custom" event to be handled.
screen.Post(Event::Custom);
}
});
screen.Loop(main_renderer);
refresh_ui_continue = false;
refresh_ui.join();
return 0;
}

View file

@ -0,0 +1,48 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for allocator, __shared_ptr_access
#include <string> // for char_traits, operator+, string, basic_string
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Input, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/component_options.hpp" // for InputOption
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
#include "ftxui/dom/elements.hpp" // for text, hbox, separator, Element, operator|, vbox, border
#include "ftxui/util/ref.hpp" // for Ref
int main() {
using namespace ftxui;
std::string first_name;
std::string last_name;
std::string password;
Component input_first_name = Input(&first_name, "first name");
Component input_last_name = Input(&last_name, "last name");
InputOption password_option;
password_option.password = true;
Component input_password = Input(&password, "password", password_option);
auto component = Container::Vertical({
input_first_name,
input_last_name,
input_password,
});
auto renderer = Renderer(component, [&] {
return vbox({
text("Hello " + first_name + " " + last_name),
separator(),
hbox(text(" First name : "), input_first_name->Render()),
hbox(text(" Last name : "), input_last_name->Render()),
hbox(text(" Password : "), input_password->Render()),
}) |
border;
});
auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(renderer);
}

View file

@ -0,0 +1,97 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <ftxui/dom/linear_gradient.hpp> // for LinearGradient
#include <ftxui/screen/color.hpp> // for Color, Color::White, Color::Red, Color::Blue, Color::Black, Color::GrayDark, ftxui
#include <functional> // for function
#include <string> // for allocator, string
#include <utility> // for move
#include "ftxui/component/component.hpp" // for Input, Horizontal, Vertical, operator|
#include "ftxui/component/component_base.hpp" // for Component
#include "ftxui/component/component_options.hpp" // for InputState, InputOption
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for operator|=, Element, bgcolor, operator|, separatorEmpty, color, borderEmpty, separator, text, center, dim, hbox, vbox, border, borderDouble, borderRounded
int main() {
using namespace ftxui;
InputOption style_1 = InputOption::Default();
InputOption style_2 = InputOption::Spacious();
InputOption style_3 = InputOption::Spacious();
style_3.transform = [](InputState state) {
state.element |= borderEmpty;
if (state.is_placeholder) {
state.element |= dim;
}
if (state.focused) {
state.element |= borderDouble;
state.element |= bgcolor(Color::White);
state.element |= color(Color::Black);
} else if (state.hovered) {
state.element |= borderRounded;
state.element |= bgcolor(LinearGradient(90, Color::Blue, Color::Red));
state.element |= color(Color::White);
} else {
state.element |= border;
state.element |= bgcolor(LinearGradient(0, Color::Blue, Color::Red));
state.element |= color(Color::White);
}
return state.element;
};
InputOption style_4 = InputOption::Spacious();
style_4.transform = [](InputState state) {
state.element = hbox({
text("Theorem") | center | borderEmpty | bgcolor(Color::Red),
separatorEmpty(),
separator() | color(Color::White),
separatorEmpty(),
std::move(state.element),
});
state.element |= borderEmpty;
if (state.is_placeholder) {
state.element |= dim;
}
if (state.focused) {
state.element |= bgcolor(Color::Black);
} else {
state.element |= bgcolor(Color::Blue);
}
if (state.hovered) {
state.element |= bgcolor(Color::GrayDark);
}
return vbox({state.element, separatorEmpty()});
};
auto generateUiFromStyle = [&](InputOption style) {
auto first_name = new std::string(); // Leaked
auto middle_name = new std::string(); // Leaked
auto last_name = new std::string(); // Leaked
return Container::Vertical({
Input(first_name, "first name", style),
Input(middle_name, "middle name", style),
Input(last_name, "last name", style),
}) |
borderEmpty;
};
auto ui = Container::Horizontal({
generateUiFromStyle(style_1),
generateUiFromStyle(style_2),
generateUiFromStyle(style_3),
generateUiFromStyle(style_4),
});
auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(ui);
}

View file

@ -0,0 +1,55 @@
// Copyright 2023 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <ftxui/component/component_base.hpp> // for ComponentBase, Component
#include <ftxui/dom/elements.hpp> // for operator|, Element, flex, bgcolor, text, vbox, center
#include <ftxui/dom/linear_gradient.hpp> // for LinearGradient
#include <ftxui/screen/color.hpp> // for Color, Color::Blue, Color::Red
#include <memory> // for __shared_ptr_access, shared_ptr
#include <string> // for allocator, operator+, char_traits, string, to_string
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Slider, Renderer, Vertical
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
int main() {
using namespace ftxui;
auto screen = ScreenInteractive::Fullscreen();
int angle = 180.f;
float start = 0.f;
float end = 1.f;
std::string slider_angle_text;
std::string slider_start_text;
std::string slider_end_text;
auto slider_angle = Slider(&slider_angle_text, &angle, 0, 360);
auto slider_start = Slider(&slider_start_text, &start, 0.f, 1.f, 0.05f);
auto slider_end = Slider(&slider_end_text, &end, 0.f, 1.f, 0.05f);
auto layout = Container::Vertical({
slider_angle,
slider_start,
slider_end,
});
auto renderer = Renderer(layout, [&] {
slider_angle_text = "angle = " + std::to_string(angle) + "°";
slider_start_text = "start = " + std::to_string(int(start * 100)) + "%";
slider_end_text = "end = " + std::to_string(int(end * 100)) + "%";
auto background = text("Gradient") | center |
bgcolor(LinearGradient()
.Angle(angle)
.Stop(Color::Blue, start)
.Stop(Color::Red, end));
return vbox({
background | flex,
layout->Render(),
}) |
flex;
});
screen.Loop(renderer);
}

View file

@ -0,0 +1,41 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <string> // for string, allocator, basic_string
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for operator|, Maybe, Checkbox, Radiobox, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for Component
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for Element, border, color, operator|, text
#include "ftxui/screen/color.hpp" // for Color, Color::Red
using namespace ftxui;
int main() {
std::vector<std::string> entries = {
"entry 1",
"entry 2",
"entry 3",
};
int menu_1_selected = 0;
int menu_2_selected = 0;
bool menu_1_show = false;
bool menu_2_show = false;
auto layout = Container::Vertical({
Checkbox("Show menu_1", &menu_1_show),
Radiobox(&entries, &menu_1_selected) | border | Maybe(&menu_1_show),
Checkbox("Show menu_2", &menu_2_show),
Radiobox(&entries, &menu_2_selected) | border | Maybe(&menu_2_show),
Renderer([] {
return text("You found the secret combinaison!") | color(Color::Red);
}) | Maybe([&] { return menu_1_selected == 1 && menu_2_selected == 2; }),
});
auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(layout);
}

View file

@ -0,0 +1,32 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <functional> // for function
#include <iostream> // for basic_ostream::operator<<, operator<<, endl, basic_ostream, basic_ostream<>::__ostream_type, cout, ostream
#include <string> // for string, basic_string, allocator
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Menu
#include "ftxui/component/component_options.hpp" // for MenuOption
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
int main() {
using namespace ftxui;
auto screen = ScreenInteractive::TerminalOutput();
std::vector<std::string> entries = {
"entry 1",
"entry 2",
"entry 3",
};
int selected = 0;
MenuOption option;
option.on_enter = screen.ExitLoopClosure();
auto menu = Menu(&entries, &selected, option);
screen.Loop(menu);
std::cout << "Selected element = " << selected << std::endl;
}

View file

@ -0,0 +1,79 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <functional> // for function
#include <memory> // for allocator, __shared_ptr_access
#include <string> // for string, basic_string, operator+, to_string
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Menu, Horizontal, Renderer
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/component_options.hpp" // for MenuOption
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
#include "ftxui/dom/elements.hpp" // for text, separator, bold, hcenter, vbox, hbox, gauge, Element, operator|, border
int main() {
using namespace ftxui;
auto screen = ScreenInteractive::TerminalOutput();
std::vector<std::string> left_menu_entries = {
"0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%",
};
std::vector<std::string> right_menu_entries = {
"0%", "1%", "2%", "3%", "4%", "5%", "6%", "7%", "8%", "9%", "10%",
};
auto menu_option = MenuOption();
menu_option.on_enter = screen.ExitLoopClosure();
int left_menu_selected = 0;
int right_menu_selected = 0;
Component left_menu_ =
Menu(&left_menu_entries, &left_menu_selected, menu_option);
Component right_menu_ =
Menu(&right_menu_entries, &right_menu_selected, menu_option);
Component container = Container::Horizontal({
left_menu_,
right_menu_,
});
auto renderer = Renderer(container, [&] {
int sum = left_menu_selected * 10 + right_menu_selected;
return vbox({
// -------- Top panel --------------
hbox({
// -------- Left Menu --------------
vbox({
hcenter(bold(text("Percentage by 10%"))),
separator(),
left_menu_->Render(),
}),
separator(),
// -------- Right Menu --------------
vbox({
hcenter(bold(text("Percentage by 1%"))),
separator(),
right_menu_->Render(),
}),
separator(),
}),
separator(),
// -------- Bottom panel --------------
vbox({
hbox({
text(" gauge : "),
gauge(sum / 100.0),
}),
hbox({
text(" text : "),
text(std::to_string(sum) + " %"),
}),
}),
}) |
border;
});
screen.Loop(renderer);
}

View file

@ -0,0 +1,81 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <functional> // for function
#include <iostream> // for basic_ostream::operator<<, operator<<, endl, basic_ostream, basic_ostream<>::__ostream_type, cout, ostream
#include <memory> // for allocator, shared_ptr, __shared_ptr_access
#include <string> // for char_traits, to_string, operator+, string, basic_string
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for MenuEntry, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/component_options.hpp" // for MenuEntryOption
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for operator|, Element, separator, text, hbox, size, frame, color, vbox, HEIGHT, LESS_THAN, bold, border, inverted
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::Cyan, Color::Green, Color::Red, Color::Yellow
using namespace ftxui;
// Define a special style for some menu entry.
MenuEntryOption Colored(ftxui::Color c) {
MenuEntryOption option;
option.transform = [c](EntryState state) {
state.label = (state.active ? "> " : " ") + state.label;
Element e = text(state.label) | color(c);
if (state.focused)
e = e | inverted;
if (state.active)
e = e | bold;
return e;
};
return option;
}
int main() {
auto screen = ScreenInteractive::TerminalOutput();
int selected = 0;
auto menu = Container::Vertical(
{
MenuEntry(" 1. improve"),
MenuEntry(" 2. tolerant"),
MenuEntry(" 3. career"),
MenuEntry(" 4. cast"),
MenuEntry(" 5. question"),
Renderer([] { return separator(); }),
MenuEntry(" 6. rear", Colored(Color::Red)),
MenuEntry(" 7. drown", Colored(Color::Yellow)),
MenuEntry(" 8. nail", Colored(Color::Green)),
MenuEntry(" 9. quit", Colored(Color::Cyan)),
MenuEntry("10. decorative", Colored(Color::Blue)),
Renderer([] { return separator(); }),
MenuEntry("11. costume"),
MenuEntry("12. pick"),
MenuEntry("13. oral"),
MenuEntry("14. minister"),
MenuEntry("15. football"),
MenuEntry("16. welcome"),
MenuEntry("17. copper"),
MenuEntry("18. inhabitant"),
MenuEntry("19. fortune"),
},
&selected);
// Display together the menu with a border
auto renderer = Renderer(menu, [&] {
return vbox({
hbox(text("selected = "), text(std::to_string(selected))),
separator(),
menu->Render() | frame | size(HEIGHT, LESS_THAN, 10),
}) |
border;
});
screen.Loop(renderer);
std::cout << "Selected element = " << selected << std::endl;
}

View file

@ -0,0 +1,65 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <iostream> // for basic_ostream::operator<<, operator<<, endl, basic_ostream, basic_ostream<>::__ostream_type, cout, ostream
#include <memory> // for shared_ptr, __shared_ptr_access
#include <string> // for to_string, allocator
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for MenuEntryAnimated, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/component_options.hpp" // for MenuEntryAnimated
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for operator|, separator, Element, Decorator, color, text, hbox, size, bold, frame, inverted, vbox, HEIGHT, LESS_THAN, border
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::Cyan, Color::Green, Color::Red, Color::Yellow
using namespace ftxui;
// Define a special style for some menu entry.
MenuEntryOption Colored(ftxui::Color c) {
MenuEntryOption option;
option.animated_colors.foreground.enabled = true;
option.animated_colors.background.enabled = true;
option.animated_colors.background.active = c;
option.animated_colors.background.inactive = Color::Black;
option.animated_colors.foreground.active = Color::White;
option.animated_colors.foreground.inactive = c;
return option;
}
int main() {
auto screen = ScreenInteractive::TerminalOutput();
int selected = 0;
auto menu = Container::Vertical(
{
MenuEntry(" 1. rear", Colored(Color::Red)),
MenuEntry(" 2. drown", Colored(Color::Yellow)),
MenuEntry(" 3. nail", Colored(Color::Green)),
MenuEntry(" 4. quit", Colored(Color::Cyan)),
MenuEntry(" 5. decorative", Colored(Color::Blue)),
MenuEntry(" 7. costume"),
MenuEntry(" 8. pick"),
MenuEntry(" 9. oral"),
MenuEntry("11. minister"),
MenuEntry("12. football"),
MenuEntry("13. welcome"),
MenuEntry("14. copper"),
MenuEntry("15. inhabitant"),
},
&selected);
// Display together the menu with a border
auto renderer = Renderer(menu, [&] {
return vbox({
hbox(text("selected = "), text(std::to_string(selected))),
separator(),
menu->Render() | frame,
}) |
border | bgcolor(Color::Black);
});
screen.Loop(renderer);
std::cout << "Selected element = " << selected << std::endl;
}

View file

@ -0,0 +1,32 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for shared_ptr, __shared_ptr_access
#include <string> // for string, basic_string, operator+, to_string
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Radiobox, Renderer
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for operator|, Element, size, border, frame, HEIGHT, LESS_THAN
using namespace ftxui;
int main() {
std::vector<std::string> entries;
int selected = 0;
for (int i = 0; i < 30; ++i)
entries.push_back("Entry " + std::to_string(i));
auto radiobox = Menu(&entries, &selected);
auto renderer = Renderer(radiobox, [&] {
return radiobox->Render() | vscroll_indicator | frame |
size(HEIGHT, LESS_THAN, 10) | border;
});
auto screen = ScreenInteractive::FitComponent();
screen.Loop(renderer);
return 0;
}

View file

@ -0,0 +1,77 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <stdlib.h> // for EXIT_SUCCESS
#include <memory> // for allocator, __shared_ptr_access
#include <string> // for string, operator+, basic_string, to_string, char_traits
#include <vector> // for vector, __alloc_traits<>::value_type
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Menu, Renderer, Horizontal, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
#include "ftxui/dom/elements.hpp" // for text, Element, operator|, window, flex, vbox
using namespace ftxui;
Component Window(std::string title, Component component) {
return Renderer(component, [component, title] { //
return window(text(title), component->Render()) | flex;
});
}
int main() {
int menu_selected[] = {0, 0, 0};
std::vector<std::vector<std::string>> menu_entries = {
{
"Ananas",
"Raspberry",
"Citrus",
},
{
"Potatoes",
"Weat",
"Rise",
},
{
"Carrot",
"Lettuce",
"Tomato",
},
};
int menu_selected_global = 0;
auto menu_global = Container::Vertical(
{
Window("Menu 1", Menu(&menu_entries[0], &menu_selected[0])),
Window("Menu 2", Menu(&menu_entries[1], &menu_selected[1])),
Window("Menu 3", Menu(&menu_entries[2], &menu_selected[2])),
},
&menu_selected_global);
auto info = Renderer([&] {
int g = menu_selected_global;
std::string value = menu_entries[g][menu_selected[g]];
return window(text("Content"), //
vbox({
text("menu_selected_global = " + std::to_string(g)),
text("menu_selected[0] = " +
std::to_string(menu_selected[0])),
text("menu_selected[1] = " +
std::to_string(menu_selected[1])),
text("menu_selected[2] = " +
std::to_string(menu_selected[2])),
text("Value = " + value),
})) |
flex;
});
auto global = Container::Horizontal({
menu_global,
info,
});
auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(global);
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,257 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <array> // for array
#include <chrono> // for milliseconds
#include <functional> // for function
#include <memory> // for __shared_ptr_access, shared_ptr, allocator
#include <string> // for string, char_traits, operator+, basic_string
#include <vector> // for vector
#include "ftxui/component/animation.hpp" // for ElasticOut, Linear
#include "ftxui/component/component.hpp" // for Menu, Horizontal, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/component_options.hpp" // for MenuOption, EntryState, MenuEntryOption, AnimatedColorOption, AnimatedColorsOption, UnderlineOption
#include "ftxui/component/mouse.hpp" // for ftxui
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
#include "ftxui/dom/elements.hpp" // for separator, operator|, Element, text, bgcolor, hbox, bold, color, filler, border, vbox, borderDouble, dim, flex, hcenter
#include "ftxui/screen/color.hpp" // for Color, Color::Red, Color::Black, Color::Yellow, Color::Blue, Color::Default, Color::White
using namespace ftxui;
Component VMenu1(std::vector<std::string>* entries, int* selected);
Component VMenu2(std::vector<std::string>* entries, int* selected);
Component VMenu3(std::vector<std::string>* entries, int* selected);
Component VMenu4(std::vector<std::string>* entries, int* selected);
Component VMenu5(std::vector<std::string>* entries, int* selected);
Component VMenu6(std::vector<std::string>* entries, int* selected);
Component VMenu7(std::vector<std::string>* entries, int* selected);
Component VMenu8(std::vector<std::string>* entries, int* selected);
Component HMenu1(std::vector<std::string>* entries, int* selected);
Component HMenu2(std::vector<std::string>* entries, int* selected);
Component HMenu3(std::vector<std::string>* entries, int* selected);
Component HMenu4(std::vector<std::string>* entries, int* selected);
Component HMenu5(std::vector<std::string>* entries, int* selected);
int main() {
auto screen = ScreenInteractive::TerminalOutput();
std::vector<std::string> entries{
"Monkey", "Dog", "Cat", "Bird", "Elephant", "Cat",
};
std::array<int, 12> selected = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
auto vmenu_1_ = VMenu1(&entries, &selected[0]);
auto vmenu_2_ = VMenu2(&entries, &selected[1]);
auto vmenu_3_ = VMenu3(&entries, &selected[2]);
auto vmenu_4_ = VMenu4(&entries, &selected[3]);
auto vmenu_5_ = VMenu5(&entries, &selected[4]);
auto vmenu_6_ = VMenu6(&entries, &selected[5]);
auto vmenu_7_ = VMenu7(&entries, &selected[6]);
auto vmenu_8_ = VMenu8(&entries, &selected[7]);
auto hmenu_1_ = HMenu1(&entries, &selected[8]);
auto hmenu_2_ = HMenu2(&entries, &selected[9]);
auto hmenu_3_ = HMenu3(&entries, &selected[10]);
auto hmenu_4_ = HMenu4(&entries, &selected[11]);
auto hmenu_5_ = HMenu5(&entries, &selected[12]);
auto container = Container::Vertical({
Container::Horizontal({
vmenu_1_,
vmenu_2_,
vmenu_3_,
vmenu_4_,
vmenu_5_,
vmenu_6_,
vmenu_7_,
vmenu_8_,
}),
hmenu_1_,
hmenu_2_,
hmenu_3_,
hmenu_4_,
hmenu_5_,
});
auto renderer = Renderer(container, [&] {
return //
hbox({
vbox({
hbox({
vmenu_1_->Render(),
separator(),
vmenu_2_->Render(),
separator(),
vmenu_3_->Render(),
separator(),
vmenu_4_->Render(),
separator(),
vmenu_5_->Render(),
vmenu_6_->Render(),
separator(),
vmenu_7_->Render(),
separator(),
vmenu_8_->Render(),
}),
separator(),
hmenu_1_->Render(),
separator(),
hmenu_2_->Render(),
separator(),
hmenu_3_->Render(),
separator(),
hmenu_4_->Render(),
hmenu_5_->Render(),
}) | border,
filler(),
});
});
screen.Loop(renderer);
}
Component VMenu1(std::vector<std::string>* entries, int* selected) {
auto option = MenuOption::Vertical();
option.entries_option.transform = [](EntryState state) {
state.label = (state.active ? "> " : " ") + state.label;
Element e = text(state.label);
if (state.focused)
e = e | bgcolor(Color::Blue);
if (state.active)
e = e | bold;
return e;
};
return Menu(entries, selected, option);
}
Component VMenu2(std::vector<std::string>* entries, int* selected) {
auto option = MenuOption::Vertical();
option.entries_option.transform = [](EntryState state) {
state.label += (state.active ? " <" : " ");
Element e = hbox(filler(), text(state.label));
if (state.focused)
e = e | bgcolor(Color::Red);
if (state.active)
e = e | bold;
return e;
};
return Menu(entries, selected, option);
}
Component VMenu3(std::vector<std::string>* entries, int* selected) {
auto option = MenuOption::Vertical();
option.entries_option.transform = [](EntryState state) {
Element e = state.active ? text("[" + state.label + "]")
: text(" " + state.label + " ");
if (state.focused)
e = e | bold;
if (state.focused)
e = e | color(Color::Blue);
if (state.active)
e = e | bold;
return e;
};
return Menu(entries, selected, option);
}
Component VMenu4(std::vector<std::string>* entries, int* selected) {
auto option = MenuOption::Vertical();
option.entries_option.transform = [](EntryState state) {
if (state.active && state.focused) {
return text(state.label) | color(Color::Yellow) | bgcolor(Color::Black) |
bold;
}
if (state.active) {
return text(state.label) | color(Color::Yellow) | bgcolor(Color::Black);
}
if (state.focused) {
return text(state.label) | color(Color::Black) | bgcolor(Color::Yellow) |
bold;
}
return text(state.label) | color(Color::Black) | bgcolor(Color::Yellow);
};
return Menu(entries, selected, option);
}
Component VMenu5(std::vector<std::string>* entries, int* selected) {
auto option = MenuOption::Vertical();
option.entries_option.transform = [](EntryState state) {
auto element = text(state.label);
if (state.active && state.focused) {
return element | borderDouble;
}
if (state.active) {
return element | border;
}
if (state.focused) {
return element | bold;
}
return element;
};
return Menu(entries, selected, option);
}
Component VMenu6(std::vector<std::string>* entries, int* selected) {
auto option = MenuOption::VerticalAnimated();
option.underline.color_inactive = Color::Default;
option.underline.color_active = Color::Red;
option.underline.SetAnimationFunction(animation::easing::Linear);
return Menu(entries, selected, option);
}
Component VMenu7(std::vector<std::string>* entries, int* selected) {
auto option = MenuOption::Vertical();
option.entries_option.animated_colors.foreground.enabled = true;
option.entries_option.animated_colors.background.enabled = true;
option.entries_option.animated_colors.background.active = Color::Red;
option.entries_option.animated_colors.background.inactive = Color::Black;
option.entries_option.animated_colors.foreground.active = Color::White;
option.entries_option.animated_colors.foreground.inactive = Color::Red;
return Menu(entries, selected, option);
}
Component VMenu8(std::vector<std::string>* entries, int* selected) {
auto option = MenuOption::Vertical();
option.entries_option.animated_colors.foreground.Set(
Color::Red, Color::White, std::chrono::milliseconds(500));
return Menu(entries, selected, option);
}
Component HMenu1(std::vector<std::string>* entries, int* selected) {
return Menu(entries, selected, MenuOption::Horizontal());
}
Component HMenu2(std::vector<std::string>* entries, int* selected) {
return Menu(entries, selected, MenuOption::Toggle());
}
Component HMenu3(std::vector<std::string>* entries, int* selected) {
auto option = MenuOption::Toggle();
option.elements_infix = [] { return text(" 🮣🮠 "); };
return Menu(entries, selected, option);
}
Component HMenu4(std::vector<std::string>* entries, int* selected) {
return Menu(entries, selected, MenuOption::HorizontalAnimated());
}
Component HMenu5(std::vector<std::string>* entries, int* selected) {
auto option = MenuOption::HorizontalAnimated();
option.underline.SetAnimation(std::chrono::milliseconds(1500),
animation::easing::ElasticOut);
option.entries_option.transform = [](EntryState state) {
Element e = text(state.label) | hcenter | flex;
if (state.active && state.focused)
e = e | bold;
if (!state.focused && !state.active)
e = e | dim;
return e;
};
option.underline.color_inactive = Color::Default;
option.underline.color_active = Color::Red;
return Menu(entries, selected, option);
}

View file

@ -0,0 +1,93 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <chrono> // for operator""ms, literals
#include <memory> // for allocator, shared_ptr, __shared_ptr_access
#include <string> // for string, operator+, to_string, basic_string
#include <vector> // for vector
#include "ftxui/component/animation.hpp" // for BackOut, Duration
#include "ftxui/component/component.hpp" // for Menu, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/component_options.hpp" // for MenuOption, UnderlineOption
#include "ftxui/component/mouse.hpp" // for ftxui
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
#include "ftxui/dom/elements.hpp" // for text, Element, operator|, borderEmpty, inverted
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::Red
using namespace ftxui;
Component DummyComponent(int id) {
return Renderer([id](bool focused) {
auto t = text("component " + std::to_string(id));
if (focused)
t = t | inverted;
return t;
});
}
Component Text(const std::string& t) {
return Renderer([t] { return text(t) | borderEmpty; });
}
int main() {
using namespace std::literals;
std::vector<std::string> tab_values{
"Tab 1", "Tab 2", "Tab 3", "A very very long tab", "",
};
int tab_selected = 0;
auto container = Container::Vertical({});
int frame_count = 0;
container->Add(Renderer(
[&] { return text("Frame count: " + std::to_string(frame_count++)); }));
{
auto option = MenuOption::HorizontalAnimated();
container->Add(Text("This demonstrate the Menu component"));
container->Add(Menu(&tab_values, &tab_selected, option));
}
{
container->Add(Text("Set underline color to blue"));
auto option = MenuOption::HorizontalAnimated();
option.underline.color_inactive = Color::Blue;
container->Add(Menu(&tab_values, &tab_selected, option));
}
{
container->Add(Text("Set underline active color to red"));
auto option = MenuOption::HorizontalAnimated();
option.underline.color_active = Color::Red;
container->Add(Menu(&tab_values, &tab_selected, option));
}
{
container->Add(Text("Set animation duration to 0ms"));
auto option = MenuOption::HorizontalAnimated();
option.underline.SetAnimationDuration(0ms);
container->Add(Menu(&tab_values, &tab_selected, option));
}
{
container->Add(Text("Set animation easing function to back-out"));
auto option = MenuOption::HorizontalAnimated();
option.underline.SetAnimationFunction(animation::easing::BackOut);
option.underline.SetAnimationDuration(350ms);
container->Add(Menu(&tab_values, &tab_selected, option));
}
// option.underline_animation_follower_delay = 250ms
{
container->Add(Text("Add delay to desynchronize animation"));
auto option = MenuOption::HorizontalAnimated();
option.underline.follower_delay = 250ms;
container->Add(Menu(&tab_values, &tab_selected, option));
}
container->SetActiveChild(container->ChildAt(2));
auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(container);
}

View file

@ -0,0 +1,82 @@
// Copyright 2022 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <ftxui/component/component_options.hpp> // for ButtonOption
#include <ftxui/component/mouse.hpp> // for ftxui
#include <functional> // for function
#include <memory> // for allocator, shared_ptr
#include "ftxui/component/component.hpp" // for Button, operator|=, Renderer, Vertical, Modal
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive, Component
#include "ftxui/dom/elements.hpp" // for operator|, separator, text, size, Element, vbox, border, GREATER_THAN, WIDTH, center, HEIGHT
using namespace ftxui;
auto button_style = ButtonOption::Animated();
// Definition of the main component. The details are not important.
Component MainComponent(std::function<void()> show_modal,
std::function<void()> exit) {
auto component = Container::Vertical({
Button("Show modal", show_modal, button_style),
Button("Quit", exit, button_style),
});
// Polish how the two buttons are rendered:
component |= Renderer([&](Element inner) {
return vbox({
text("Main component"),
separator(),
inner,
}) //
| size(WIDTH, GREATER_THAN, 15) //
| size(HEIGHT, GREATER_THAN, 15) //
| border //
| center; //
});
return component;
}
// Definition of the modal component. The details are not important.
Component ModalComponent(std::function<void()> do_nothing,
std::function<void()> hide_modal) {
auto component = Container::Vertical({
Button("Do nothing", do_nothing, button_style),
Button("Quit modal", hide_modal, button_style),
});
// Polish how the two buttons are rendered:
component |= Renderer([&](Element inner) {
return vbox({
text("Modal component "),
separator(),
inner,
}) //
| size(WIDTH, GREATER_THAN, 30) //
| border; //
});
return component;
}
int main(int argc, const char* argv[]) {
auto screen = ScreenInteractive::TerminalOutput();
// State of the application:
bool modal_shown = false;
// Some actions modifying the state:
auto show_modal = [&] { modal_shown = true; };
auto hide_modal = [&] { modal_shown = false; };
auto exit = screen.ExitLoopClosure();
auto do_nothing = [&] {};
// Instanciate the main and modal components:
auto main_component = MainComponent(show_modal, exit);
auto modal_component = ModalComponent(do_nothing, hide_modal);
// Use the `Modal` function to use together the main component and its modal
// window. The |modal_shown| boolean controls whether the modal is shown or
// not.
main_component |= Modal(modal_component, &modal_shown);
screen.Loop(main_component);
return 0;
}

View file

@ -0,0 +1,93 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for allocator, shared_ptr, __shared_ptr_access
#include <string> // for string, basic_string, char_traits, operator+
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Button, Renderer, Horizontal, Tab
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for operator|, Element, filler, text, hbox, separator, center, vbox, bold, border, clear_under, dbox, size, GREATER_THAN, HEIGHT
int main() {
using namespace ftxui;
auto screen = ScreenInteractive::TerminalOutput();
// There are two layers. One at depth = 0 and the modal window at depth = 1;
int depth = 0;
// The current rating of FTXUI.
std::string rating = "3/5 stars";
// At depth=0, two buttons. One for rating FTXUI and one for quitting.
auto button_rate_ftxui = Button("Rate FTXUI", [&] { depth = 1; });
auto button_quit = Button("Quit", screen.ExitLoopClosure());
auto depth_0_container = Container::Horizontal({
button_rate_ftxui,
button_quit,
});
auto depth_0_renderer = Renderer(depth_0_container, [&] {
return vbox({
text("Modal dialog example"),
separator(),
text("☆☆☆ FTXUI:" + rating + " ☆☆☆") | bold,
filler(),
hbox({
button_rate_ftxui->Render(),
filler(),
button_quit->Render(),
}),
}) |
border | size(HEIGHT, GREATER_THAN, 18) | center;
});
// At depth=1, The "modal" window.
std::vector<std::string> rating_labels = {
"1/5 stars", "2/5 stars", "3/5 stars", "4/5 stars", "5/5 stars",
};
auto on_rating = [&](std::string new_rating) {
rating = new_rating;
depth = 0;
};
auto depth_1_container = Container::Horizontal({
Button(&rating_labels[0], [&] { on_rating(rating_labels[0]); }),
Button(&rating_labels[1], [&] { on_rating(rating_labels[1]); }),
Button(&rating_labels[2], [&] { on_rating(rating_labels[2]); }),
Button(&rating_labels[3], [&] { on_rating(rating_labels[3]); }),
Button(&rating_labels[4], [&] { on_rating(rating_labels[4]); }),
});
auto depth_1_renderer = Renderer(depth_1_container, [&] {
return vbox({
text("Do you like FTXUI?"),
separator(),
hbox(depth_1_container->Render()),
}) |
border;
});
auto main_container = Container::Tab(
{
depth_0_renderer,
depth_1_renderer,
},
&depth);
auto main_renderer = Renderer(main_container, [&] {
Element document = depth_0_renderer->Render();
if (depth == 1) {
document = dbox({
document,
depth_1_renderer->Render() | clear_under | center,
});
}
return document;
});
screen.Loop(main_renderer);
return 0;
}

View file

@ -0,0 +1,50 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for allocator, shared_ptr, __shared_ptr_access
#include <string> // for operator+, string, char_traits, basic_string
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Button, Vertical, Renderer
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for separator, text, Element, operator|, vbox, border
using namespace ftxui;
void Nested(std::string path) {
auto screen = ScreenInteractive::FitComponent();
auto back_button = Button("Back", screen.ExitLoopClosure());
auto goto_1 = Button("Goto /1", [path] { Nested(path + "/1"); });
auto goto_2 = Button("Goto /2", [path] { Nested(path + "/2"); });
auto goto_3 = Button("Goto /3", [path] { Nested(path + "/3"); });
auto layout = Container::Vertical({
back_button,
goto_1,
goto_2,
goto_3,
});
auto renderer = Renderer(layout, [&] {
return vbox({
text("path: " + path),
separator(),
back_button->Render(),
goto_1->Render(),
goto_2->Render(),
goto_3->Render(),
}) |
border;
});
screen.Loop(renderer);
}
int main() {
auto screen = ScreenInteractive::FitComponent();
auto button_quit = Button("Quit", screen.ExitLoopClosure());
auto button_nested = Button("Nested", [] { Nested(""); });
screen.Loop(Container::Vertical({
button_quit,
button_nested,
}));
return 0;
}

View file

@ -0,0 +1,155 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <stddef.h> // for size_t
#include <algorithm> // for max
#include <memory> // for allocator, shared_ptr
#include <string> // for char_traits, operator+, string, basic_string, to_string
#include <utility> // for move
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for CatchEvent, Renderer
#include "ftxui/component/event.hpp" // for Event
#include "ftxui/component/mouse.hpp" // for Mouse, Mouse::Left, Mouse::Middle, Mouse::None, Mouse::Pressed, Mouse::Released, Mouse::Right, Mouse::WheelDown, Mouse::WheelUp
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for text, vbox, window, Element, Elements
using namespace ftxui;
std::string Stringify(Event event) {
std::string out;
for (auto& it : event.input())
out += " " + std::to_string((unsigned int)it);
out = "(" + out + " ) -> ";
if (event.is_character()) {
out += "Event::Character(\"" + event.character() + "\")";
} else if (event.is_mouse()) {
out += "mouse";
switch (event.mouse().button) {
case Mouse::Left:
out += "_left";
break;
case Mouse::Middle:
out += "_middle";
break;
case Mouse::Right:
out += "_right";
break;
case Mouse::None:
out += "_none";
break;
case Mouse::WheelUp:
out += "_wheel_up";
break;
case Mouse::WheelDown:
out += "_wheel_down";
break;
}
switch (event.mouse().motion) {
case Mouse::Pressed:
out += "_pressed";
break;
case Mouse::Released:
out += "_released";
break;
}
if (event.mouse().control)
out += "_control";
if (event.mouse().shift)
out += "_shift";
if (event.mouse().meta)
out += "_meta";
out += "(" + //
std::to_string(event.mouse().x) + "," +
std::to_string(event.mouse().y) + ")";
} else if (event == Event::ArrowLeft) {
out += "Event::ArrowLeft";
} else if (event == Event::ArrowRight) {
out += "Event::ArrowRight";
} else if (event == Event::ArrowUp) {
out += "Event::ArrowUp";
} else if (event == Event::ArrowDown) {
out += "Event::ArrowDown";
} else if (event == Event::ArrowLeftCtrl) {
out += "Event::ArrowLeftCtrl";
} else if (event == Event ::ArrowRightCtrl) {
out += "Event::ArrowRightCtrl";
} else if (event == Event::ArrowUpCtrl) {
out += "Event::ArrowUpCtrl";
} else if (event == Event::ArrowDownCtrl) {
out += "Event::ArrowDownCtrl";
} else if (event == Event::Backspace) {
out += "Event::Backspace";
} else if (event == Event::Delete) {
out += "Event::Delete";
} else if (event == Event::Escape) {
out += "Event::Escape";
} else if (event == Event::Return) {
out += "Event::Return";
} else if (event == Event::Tab) {
out += "Event::Tab";
} else if (event == Event::TabReverse) {
out += "Event::TabReverse";
} else if (event == Event::F1) {
out += "Event::F1";
} else if (event == Event::F2) {
out += "Event::F2";
} else if (event == Event::F3) {
out += "Event::F3";
} else if (event == Event::F4) {
out += "Event::F4";
} else if (event == Event::F5) {
out += "Event::F5";
} else if (event == Event::F6) {
out += "Event::F6";
} else if (event == Event::F7) {
out += "Event::F7";
} else if (event == Event::F8) {
out += "Event::F8";
} else if (event == Event::F9) {
out += "Event::F9";
} else if (event == Event::F10) {
out += "Event::F10";
} else if (event == Event::F11) {
out += "Event::F11";
} else if (event == Event::F12) {
out += "Event::F12";
} else if (event == Event::Home) {
out += "Event::Home";
} else if (event == Event::End) {
out += "Event::End";
} else if (event == Event::PageUp) {
out += "Event::PageUp";
} else if (event == Event::PageDown) {
out += "Event::PageDown";
} else if (event == Event::Custom) {
out += "Custom";
} else {
out += "(special)";
}
return out;
}
int main() {
auto screen = ScreenInteractive::TerminalOutput();
std::vector<Event> keys;
auto component = Renderer([&] {
Elements children;
for (size_t i = std::max(0, (int)keys.size() - 20); i < keys.size(); ++i)
children.push_back(text(Stringify(keys[i])));
return window(text("keys"), vbox(std::move(children)));
});
component |= CatchEvent([&](Event event) {
keys.push_back(event);
return true;
});
screen.Loop(component);
}

View file

@ -0,0 +1,25 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <string> // for string, allocator, basic_string
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Radiobox
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
using namespace ftxui;
int main() {
std::vector<std::string> radiobox_list = {
"Use gcc",
"Use clang",
"Use emscripten",
"Use tcc",
};
int selected = 0;
auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(Radiobox(&radiobox_list, &selected));
return 0;
}

View file

@ -0,0 +1,32 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for shared_ptr, __shared_ptr_access
#include <string> // for string, basic_string, operator+, to_string
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Radiobox, Renderer
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for operator|, Element, size, border, frame, HEIGHT, LESS_THAN
using namespace ftxui;
int main() {
std::vector<std::string> entries;
int selected = 0;
for (int i = 0; i < 30; ++i)
entries.push_back("RadioBox " + std::to_string(i));
auto radiobox = Radiobox(&entries, &selected);
auto renderer = Renderer(radiobox, [&] {
return radiobox->Render() | vscroll_indicator | frame |
size(HEIGHT, LESS_THAN, 10) | border;
});
auto screen = ScreenInteractive::FitComponent();
screen.Loop(renderer);
return 0;
}

View file

@ -0,0 +1,48 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for shared_ptr, allocator, __shared_ptr_access
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Renderer, Button, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for operator|, Element, text, bold, border, center, color
#include "ftxui/screen/color.hpp" // for Color, Color::Red
int main() {
using namespace ftxui;
auto screen = ScreenInteractive::FitComponent();
// A Renderer() is a component using a lambda function as a parameter to
// render itself.
// 1. Example of focusable renderer:
auto renderer_focusable = Renderer([](bool focused) {
if (focused)
return text("FOCUSABLE RENDERER()") | center | bold | border;
else
return text(" Focusable renderer() ") | center | border;
});
// 2. Examples of a non focusable renderer.
auto renderer_non_focusable = Renderer([&] {
return text("~~~~~ Non Focusable renderer() ~~~~~"); //
});
// 3. Renderer can wrap other components to redefine their Render() function.
auto button = Button("Wrapped quit button", screen.ExitLoopClosure());
auto renderer_wrap = Renderer(button, [&] {
if (button->Focused())
return button->Render() | bold | color(Color::Red);
else
return button->Render();
});
// Let's renderer everyone:
screen.Loop(Container::Vertical({
renderer_focusable,
renderer_non_focusable,
renderer_wrap,
}));
}

View file

@ -0,0 +1,38 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for shared_ptr, allocator, __shared_ptr_access
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Renderer, ResizableSplitBottom, ResizableSplitLeft, ResizableSplitRight, ResizableSplitTop
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for Element, operator|, text, center, border
using namespace ftxui;
int main() {
auto screen = ScreenInteractive::Fullscreen();
auto middle = Renderer([] { return text("middle") | center; });
auto left = Renderer([] { return text("Left") | center; });
auto right = Renderer([] { return text("right") | center; });
auto top = Renderer([] { return text("top") | center; });
auto bottom = Renderer([] { return text("bottom") | center; });
int left_size = 20;
int right_size = 20;
int top_size = 10;
int bottom_size = 10;
auto container = middle;
container = ResizableSplitLeft(left, container, &left_size);
container = ResizableSplitRight(right, container, &right_size);
container = ResizableSplitTop(top, container, &top_size);
container = ResizableSplitBottom(bottom, container, &bottom_size);
auto renderer =
Renderer(container, [&] { return container->Render() | border; });
screen.Loop(renderer);
}

View file

@ -0,0 +1,16 @@
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Slider
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
using namespace ftxui;
int main() {
auto screen = ScreenInteractive::TerminalOutput();
int value = 50;
auto slider = Slider("Value:", &value, 0, 100, 1);
screen.Loop(slider);
}
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.

View file

@ -0,0 +1,49 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <array> // for array
#include <cmath> // for sin
#include <ftxui/component/component_base.hpp> // for ComponentBase
#include <ftxui/component/component_options.hpp> // for SliderOption
#include <ftxui/dom/direction.hpp> // for Direction, Direction::Up
#include <ftxui/dom/elements.hpp> // for size, GREATER_THAN, HEIGHT
#include <ftxui/util/ref.hpp> // for ConstRef, Ref
#include <memory> // for shared_ptr, __shared_ptr_access
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Horizontal, Slider, operator|=
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
using namespace ftxui;
int main() {
auto screen = ScreenInteractive::TerminalOutput();
std::array<int, 30> values;
for (int i = 0; i < values.size(); ++i) {
values[i] = 50 + 20 * std::sin(i * 0.3);
}
auto layout_horizontal = Container::Horizontal({});
for (auto& value : values) {
// In C++17:
SliderOption<int> option;
option.value = &value;
option.max = 100;
option.increment = 5;
option.direction = Direction::Up;
layout_horizontal->Add(Slider<int>(option));
/* In C++20:
layout_horizontal->Add(Slider<int>({
.value = &values[i],
.max = 100,
.increment = 5,
.direction = Direction::Up,
}));
*/
}
layout_horizontal |= size(HEIGHT, GREATER_THAN, 20);
screen.Loop(layout_horizontal);
}

View file

@ -0,0 +1,61 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for allocator, shared_ptr, __shared_ptr_access
#include <string> // for char_traits, operator+, to_string
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Slider, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for separator, operator|, Element, size, text, vbox, xflex, bgcolor, hbox, GREATER_THAN, WIDTH, border, HEIGHT, LESS_THAN
#include "ftxui/screen/color.hpp" // for Color
using namespace ftxui;
Element ColorTile(int red, int green, int blue) {
return text("") | size(WIDTH, GREATER_THAN, 14) |
size(HEIGHT, GREATER_THAN, 7) | bgcolor(Color::RGB(red, green, blue));
}
Element ColorString(int red, int green, int blue) {
return text("RGB = (" + //
std::to_string(red) + "," + //
std::to_string(green) + "," + //
std::to_string(blue) + ")" //
);
}
int main() {
int red = 128;
int green = 25;
int blue = 100;
auto slider_red = Slider("Red :", &red, 0, 255, 1);
auto slider_green = Slider("Green:", &green, 0, 255, 1);
auto slider_blue = Slider("Blue :", &blue, 0, 255, 1);
auto container = Container::Vertical({
slider_red,
slider_green,
slider_blue,
});
auto renderer = Renderer(container, [&] {
return hbox({
ColorTile(red, green, blue),
separator(),
vbox({
slider_red->Render(),
separator(),
slider_green->Render(),
separator(),
slider_blue->Render(),
separator(),
ColorString(red, green, blue),
}) | xflex,
}) |
border | size(WIDTH, LESS_THAN, 80);
});
auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(renderer);
}

View file

@ -0,0 +1,70 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for allocator, __shared_ptr_access, shared_ptr
#include <string> // for string, basic_string
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Radiobox, Renderer, Tab, Toggle, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for Element, separator, operator|, vbox, border
using namespace ftxui;
int main() {
std::vector<std::string> tab_values{
"tab_1",
"tab_2",
"tab_3",
};
int tab_selected = 0;
auto tab_toggle = Toggle(&tab_values, &tab_selected);
std::vector<std::string> tab_1_entries{
"Forest",
"Water",
"I don't know",
};
int tab_1_selected = 0;
std::vector<std::string> tab_2_entries{
"Hello",
"Hi",
"Hay",
};
int tab_2_selected = 0;
std::vector<std::string> tab_3_entries{
"Table",
"Nothing",
"Is",
"Empty",
};
int tab_3_selected = 0;
auto tab_container = Container::Tab(
{
Radiobox(&tab_1_entries, &tab_1_selected),
Radiobox(&tab_2_entries, &tab_2_selected),
Radiobox(&tab_3_entries, &tab_3_selected),
},
&tab_selected);
auto container = Container::Vertical({
tab_toggle,
tab_container,
});
auto renderer = Renderer(container, [&] {
return vbox({
tab_toggle->Render(),
separator(),
tab_container->Render(),
}) |
border;
});
auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(renderer);
}

View file

@ -0,0 +1,70 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for allocator, __shared_ptr_access, shared_ptr
#include <string> // for string, basic_string
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Radiobox, Horizontal, Menu, Renderer, Tab
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for Element, separator, hbox, operator|, border
using namespace ftxui;
int main() {
std::vector<std::string> tab_values{
"tab_1",
"tab_2",
"tab_3",
};
int tab_selected = 0;
auto tab_menu = Menu(&tab_values, &tab_selected);
std::vector<std::string> tab_1_entries{
"Forest",
"Water",
"I don't know",
};
int tab_1_selected = 0;
std::vector<std::string> tab_2_entries{
"Hello",
"Hi",
"Hay",
};
int tab_2_selected = 0;
std::vector<std::string> tab_3_entries{
"Table",
"Nothing",
"Is",
"Empty",
};
int tab_3_selected = 0;
auto tab_container = Container::Tab(
{
Radiobox(&tab_1_entries, &tab_1_selected),
Radiobox(&tab_2_entries, &tab_2_selected),
Radiobox(&tab_3_entries, &tab_3_selected),
},
&tab_selected);
auto container = Container::Horizontal({
tab_menu,
tab_container,
});
auto renderer = Renderer(container, [&] {
return hbox({
tab_menu->Render(),
separator(),
tab_container->Render(),
}) |
border;
});
auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(renderer);
}

View file

@ -0,0 +1,34 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for allocator, __shared_ptr_access, shared_ptr
#include <string> // for string
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Input, Renderer, ResizableSplitLeft
#include "ftxui/component/component_base.hpp" // for ComponentBase, Component
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for operator|, separator, text, Element, flex, vbox, border
int main() {
using namespace ftxui;
std::string content_1;
std::string content_2;
auto textarea_1 = Input(&content_1);
auto textarea_2 = Input(&content_2);
int size = 50;
auto layout = ResizableSplitLeft(textarea_1, textarea_2, &size);
auto component = Renderer(layout, [&] {
return vbox({
text("Input:"),
separator(),
layout->Render() | flex,
}) |
border;
});
auto screen = ScreenInteractive::Fullscreen();
screen.Loop(component);
}

View file

@ -0,0 +1,64 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for allocator, __shared_ptr_access
#include <string> // for string, basic_string
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Toggle, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
#include "ftxui/dom/elements.hpp" // for text, hbox, vbox, Element
using namespace ftxui;
int main() {
std::vector<std::string> toggle_1_entries = {
"On",
"Off",
};
std::vector<std::string> toggle_2_entries = {
"Enabled",
"Disabled",
};
std::vector<std::string> toggle_3_entries = {
"10€",
"0€",
};
std::vector<std::string> toggle_4_entries = {
"Nothing",
"One element",
"Several elements",
};
int toggle_1_selected = 0;
int toggle_2_selected = 0;
int toggle_3_selected = 0;
int toggle_4_selected = 0;
Component toggle_1 = Toggle(&toggle_1_entries, &toggle_1_selected);
Component toggle_2 = Toggle(&toggle_2_entries, &toggle_2_selected);
Component toggle_3 = Toggle(&toggle_3_entries, &toggle_3_selected);
Component toggle_4 = Toggle(&toggle_4_entries, &toggle_4_selected);
auto container = Container::Vertical({
toggle_1,
toggle_2,
toggle_3,
toggle_4,
});
auto renderer = Renderer(container, [&] {
return vbox({
text("Choose your options:"),
text(""),
hbox(text(" * Poweroff on startup : "), toggle_1->Render()),
hbox(text(" * Out of process : "), toggle_2->Render()),
hbox(text(" * Price of the information : "), toggle_3->Render()),
hbox(text(" * Number of elements : "), toggle_4->Render()),
});
});
auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(renderer);
}

View file

@ -0,0 +1,88 @@
// Copyright 2023 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <ftxui/component/component.hpp>
#include <ftxui/component/screen_interactive.hpp>
using namespace ftxui;
Component DummyWindowContent() {
class Impl : public ComponentBase {
private:
bool checked[3] = {false, false, false};
float slider = 50;
public:
Impl() {
Add(Container::Vertical({
Checkbox("Check me", &checked[0]),
Checkbox("Check me", &checked[1]),
Checkbox("Check me", &checked[2]),
Slider("Slider", &slider, 0.f, 100.f),
}));
}
};
return Make<Impl>();
}
int main() {
int window_1_left = 20;
int window_1_top = 10;
int window_1_width = 40;
int window_1_height = 20;
auto window_1 = Window({
.inner = DummyWindowContent(),
.title = "First window",
.left = &window_1_left,
.top = &window_1_top,
.width = &window_1_width,
.height = &window_1_height,
});
auto window_2 = Window({
.inner = DummyWindowContent(),
.title = "My window",
.left = 40,
.top = 20,
});
auto window_3 = Window({
.inner = DummyWindowContent(),
.title = "My window",
.left = 60,
.top = 30,
});
auto window_4 = Window({
.inner = DummyWindowContent(),
});
auto window_5 = Window({});
auto window_container = Container::Stacked({
window_1,
window_2,
window_3,
window_4,
window_5,
});
auto display_win_1 = Renderer([&] {
return text("window_1: " + //
std::to_string(window_1_width) + "x" +
std::to_string(window_1_height) + " + " +
std::to_string(window_1_left) + "," +
std::to_string(window_1_top));
});
auto layout = Container::Vertical({
display_win_1,
window_container,
});
auto screen = ScreenInteractive::Fullscreen();
screen.Loop(layout);
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,60 @@
// Copyright 2022 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <cstdlib> // for system, EXIT_SUCCESS
#include <iostream> // for operator<<, basic_ostream, basic_ostream::operator<<, cout, endl, flush, ostream, basic_ostream<>::__ostream_type, cin
#include <memory> // for shared_ptr, __shared_ptr_access, allocator
#include <string> // for getline, string
#include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Button, Horizontal, Renderer
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for operator|, filler, Element, borderEmpty, hbox, size, paragraph, vbox, LESS_THAN, border, center, HEIGHT, WIDTH
int main() {
using namespace ftxui;
auto screen = ScreenInteractive::Fullscreen();
// When pressing this button, "screen.WithRestoredIO" will execute the
// temporarily uninstall the terminal hook and execute the provided callback
// function. This allow running the application in a non-interactive mode.
auto btn_run = Button("Execute with restored IO", screen.WithRestoredIO([] {
std::cout << "This is a child program using stdin/stdout." << std::endl;
for (int i = 0; i < 10; ++i) {
std::cout << "Please enter 10 strings (" << i << "/10)" << std::flush;
std::string input;
std::getline(std::cin, input);
}
}));
auto btn_quit = Button("Quit", screen.ExitLoopClosure());
auto layout = Container::Horizontal({
btn_run,
btn_quit,
});
auto renderer = Renderer(layout, [&] {
auto explanation = paragraph(
"After clicking this button, the ScreenInteractive will be "
"suspended and access to stdin/stdout will temporarilly be "
"restore for running a function.");
auto element = vbox({
explanation | borderEmpty,
hbox({
btn_run->Render(),
filler(),
btn_quit->Render(),
}),
});
element = element | borderEmpty | border | size(WIDTH, LESS_THAN, 80) |
size(HEIGHT, LESS_THAN, 20) | center;
return element;
});
screen.Loop(renderer);
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,37 @@
set(DIRECTORY_LIB dom)
example(border)
example(border_colored)
example(border_style)
example(canvas)
example(color_gallery)
example(color_info_palette256)
example(color_truecolor_HSV)
example(color_truecolor_RGB)
example(dbox)
example(gauge)
example(gauge_direction)
example(graph)
example(gridbox)
example(hflow)
example(html_like)
example(linear_gradient)
example(package_manager)
example(paragraph)
example(separator)
example(separator_style)
example(size)
example(spinner)
example(style_blink)
example(style_bold)
example(style_color)
example(style_dim)
example(style_gallery)
example(style_hyperlink)
example(style_inverted)
example(style_strikethrough)
example(style_underlined)
example(style_underlined_double)
example(table)
example(vbox_hbox)
example(vflow)

View file

@ -0,0 +1,38 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <stdlib.h> // for EXIT_SUCCESS
#include <ftxui/dom/elements.hpp> // for text, operator|, vbox, border, Element, Fit, hbox
#include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for ftxui
int main() {
using namespace ftxui;
auto document = //
hbox({
vbox({
text("Line 1"),
text("Line 2"),
text("Line 3"),
}) | border,
vbox({
text("Line 4"),
text("Line 5"),
text("Line 6"),
}) | border,
vbox({
text("Line 7"),
text("Line 8"),
text("Line 9"),
}) | border,
});
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
screen.Print();
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,39 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <ftxui/dom/elements.hpp> // for operator|, text, Element, Fit, borderDouble, borderHeavy, borderLight, borderRounded, vbox
#include <ftxui/screen/screen.hpp> // for Screen
#include <iostream> // for endl, cout, ostream
#include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for ftxui
int main() {
using namespace ftxui;
auto make_boxed = [] {
return vbox({
text("borderLight") | borderStyled(LIGHT, Color::Red),
text("borderDashed") | borderStyled(DASHED, Color::Green),
text("borderHeavy") | borderStyled(HEAVY, Color::Blue),
text("borderDouble") | borderStyled(DOUBLE, Color::Yellow),
text("borderRounded") | borderStyled(ROUNDED, Color::Cyan),
});
};
auto document = hbox({
make_boxed(),
separator() | color(Color::Red),
make_boxed(),
separator() | color(Color::Red),
make_boxed(),
}) |
borderStyled(ROUNDED, Color::Red);
auto screen =
Screen::Create(Dimension::Fit(document), Dimension::Fit(document));
Render(screen, document);
screen.Print();
std::cout << std::endl;
}

View file

@ -0,0 +1,28 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <ftxui/dom/elements.hpp> // for operator|, text, Element, Fit, borderDouble, borderHeavy, borderLight, borderRounded, vbox
#include <ftxui/screen/screen.hpp> // for Screen
#include <iostream> // for endl, cout, ostream
#include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for ftxui
int main() {
using namespace ftxui;
auto document = vbox({
text("borderLight") | borderLight,
text("borderDashed") | borderDashed,
text("borderHeavy") | borderHeavy,
text("borderDouble") | borderDouble,
text("borderRounded") | borderRounded,
});
auto screen =
Screen::Create(Dimension::Fit(document), Dimension::Fit(document));
Render(screen, document);
screen.Print();
std::cout << std::endl;
}

View file

@ -0,0 +1,48 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <stdio.h> // for getchar
#include <cmath> // for cos
#include <ftxui/dom/elements.hpp> // for Fit, canvas, operator|, border, Element
#include <ftxui/screen/screen.hpp> // for Pixel, Screen
#include <vector> // for vector, allocator
#include "ftxui/dom/canvas.hpp" // for Canvas
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for Color, Color::Red, Color::Blue, Color::Green, ftxui
int main() {
using namespace ftxui;
auto c = Canvas(100, 100);
c.DrawText(0, 0, "This is a canvas", [](Pixel& p) {
p.foreground_color = Color::Red;
p.underlined = true;
});
// Triangle:
c.DrawPointLine(10, 10, 80, 10, Color::Red);
c.DrawPointLine(80, 10, 80, 40, Color::Blue);
c.DrawPointLine(80, 40, 10, 10, Color::Green);
// Circle, not filled and filled:
c.DrawPointCircle(30, 50, 20);
c.DrawPointCircleFilled(40, 40, 10);
// Plot a function:
std::vector<int> ys(100);
for (int x = 0; x < 100; x++)
ys[x] = int(80 + 20 * cos(x * 0.2));
for (int x = 0; x < 99; x++)
c.DrawPointLine(x, ys[x], x + 1, ys[x + 1], Color::Red);
auto document = canvas(&c) | border;
auto screen = Screen::Create(Dimension::Fit(document));
Render(screen, document);
screen.Print();
getchar();
return 0;
}

View file

@ -0,0 +1,141 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <ftxui/screen/color_info.hpp> // for ColorInfo
#include <ftxui/screen/screen.hpp> // for Full, Screen
#include <ftxui/screen/terminal.hpp> // for ColorSupport, Color, Palette16, Palette256, TrueColor
#include <memory> // for allocator, shared_ptr
#include <utility> // for move
#include <vector> // for vector
#include "ftxui/dom/elements.hpp" // for text, bgcolor, color, vbox, hbox, separator, operator|, Elements, Element, Fit, border
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for Color, Color::Black, Color::Blue, Color::BlueLight, Color::Cyan, Color::CyanLight, Color::Default, Color::GrayDark, Color::GrayLight, Color::Green, Color::GreenLight, Color::Magenta, Color::MagentaLight, Color::Red, Color::RedLight, Color::White, Color::Yellow, Color::YellowLight, Color::Palette256, ftxui
using namespace ftxui;
#include "./color_info_sorted_2d.ipp" // for ColorInfoSorted2D
int main() {
// clang-format off
auto basic_color_display =
vbox(
text("16 color palette:"),
separator(),
hbox(
vbox(
color(Color::Default, text("Default")),
color(Color::Black, text("Black")),
color(Color::GrayDark, text("GrayDark")),
color(Color::GrayLight, text("GrayLight")),
color(Color::White, text("White")),
color(Color::Blue, text("Blue")),
color(Color::BlueLight, text("BlueLight")),
color(Color::Cyan, text("Cyan")),
color(Color::CyanLight, text("CyanLight")),
color(Color::Green, text("Green")),
color(Color::GreenLight, text("GreenLight")),
color(Color::Magenta, text("Magenta")),
color(Color::MagentaLight, text("MagentaLight")),
color(Color::Red, text("Red")),
color(Color::RedLight, text("RedLight")),
color(Color::Yellow, text("Yellow")),
color(Color::YellowLight, text("YellowLight"))
),
vbox(
bgcolor(Color::Default, text("Default")),
bgcolor(Color::Black, text("Black")),
bgcolor(Color::GrayDark, text("GrayDark")),
bgcolor(Color::GrayLight, text("GrayLight")),
bgcolor(Color::White, text("White")),
bgcolor(Color::Blue, text("Blue")),
bgcolor(Color::BlueLight, text("BlueLight")),
bgcolor(Color::Cyan, text("Cyan")),
bgcolor(Color::CyanLight, text("CyanLight")),
bgcolor(Color::Green, text("Green")),
bgcolor(Color::GreenLight, text("GreenLight")),
bgcolor(Color::Magenta, text("Magenta")),
bgcolor(Color::MagentaLight, text("MagentaLight")),
bgcolor(Color::Red, text("Red")),
bgcolor(Color::RedLight, text("RedLight")),
bgcolor(Color::Yellow, text("Yellow")),
bgcolor(Color::YellowLight, text("YellowLight"))
)
)
);
// clang-format on
auto palette_256_color_display = text("256 colors palette:");
{
std::vector<std::vector<ColorInfo>> info_columns = ColorInfoSorted2D();
Elements columns;
for (auto& column : info_columns) {
Elements column_elements;
for (auto& it : column) {
column_elements.push_back(
text(" ") | bgcolor(Color(Color::Palette256(it.index_256))));
}
columns.push_back(hbox(std::move(column_elements)));
}
palette_256_color_display = vbox({
palette_256_color_display,
separator(),
vbox(columns),
});
}
// True color display.
auto true_color_display = text("TrueColors: 24bits:");
{
const int max_value = 255;
const int value_increment = 8;
const int hue_increment = 6;
int saturation = max_value;
Elements array;
for (int value = 0; value < max_value; value += 2 * value_increment) {
Elements line;
for (int hue = 0; hue < max_value; hue += hue_increment) {
line.push_back(
text("") //
| color(Color::HSV(hue, saturation, value)) //
| bgcolor(Color::HSV(hue, saturation, value + value_increment)));
}
array.push_back(hbox(std::move(line)));
}
true_color_display = vbox({
true_color_display,
separator(),
vbox(std::move(array)),
});
}
auto terminal_info =
vbox({
Terminal::ColorSupport() >= Terminal::Color::Palette16
? text(" 16 color palette support : Yes")
: text(" 16 color palette support : No"),
Terminal::ColorSupport() >= Terminal::Color::Palette256
? text("256 color palette support : Yes")
: text("256 color palette support : No"),
Terminal::ColorSupport() >= Terminal::Color::TrueColor
? text(" True color support : Yes")
: text(" True color support : No"),
}) |
border;
auto document = vbox({hbox({
basic_color_display,
text(" "),
palette_256_color_display,
text(" "),
true_color_display,
}),
terminal_info});
// clang-format on
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
screen.Print();
return 0;
}

View file

@ -0,0 +1,39 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <ftxui/dom/elements.hpp> // for text, bgcolor, hbox, operator|, Elements, Fit, vbox, Element
#include <ftxui/screen/color_info.hpp> // for ColorInfo
#include <ftxui/screen/screen.hpp> // for Full, Screen
#include <utility> // for move
#include <vector> // for vector, allocator
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for Color, Color::Palette256, ftxui
using namespace ftxui;
#include "./color_info_sorted_2d.ipp" // for ColorInfoSorted2D
int main() {
std::vector<std::vector<ColorInfo>> info_columns = ColorInfoSorted2D();
// Draw every columns
Elements columns_elements;
for (auto& column : info_columns) {
Elements column_elements;
for (auto& it : column) {
column_elements.push_back(hbox({
text(" ") | bgcolor(Color(Color::Palette256(it.index_256))),
text(it.name),
}));
}
columns_elements.push_back(vbox(std::move(column_elements)));
}
auto document = hbox(std::move(columns_elements));
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
screen.Print();
return 0;
}

View file

@ -0,0 +1,53 @@
#include <algorithm>
#include <cmath>
#include <ftxui/screen/color_info.hpp> // for ftxui::ColorInfo
std::vector<std::vector<ftxui::ColorInfo>> ColorInfoSorted2D() {
// Acquire the color information for the palette256.
std::vector<ftxui::ColorInfo> info_gray;
std::vector<ftxui::ColorInfo> info_color;
for (int i = 16; i < 256; ++i) {
ftxui::ColorInfo info = GetColorInfo(ftxui::Color::Palette256(i));
if (info.saturation == 0)
info_gray.push_back(info);
else
info_color.push_back(info);
}
// Sort info_color by hue.
std::sort(
info_color.begin(), info_color.end(),
[](const ftxui::ColorInfo& A, const ftxui::ColorInfo& B) { return A.hue < B.hue; });
// Make 8 colums, one gray and seven colored.
std::vector<std::vector<ftxui::ColorInfo>> info_columns(8);
info_columns[0] = info_gray;
for (size_t i = 0; i < info_color.size(); ++i) {
info_columns[1 + 7 * i / info_color.size()].push_back(info_color[i]);
}
// Minimize discontinuities for every columns.
for (auto& column : info_columns) {
std::sort(column.begin(), column.end(),
[](const ftxui::ColorInfo& A, const ftxui::ColorInfo& B) {
return A.value < B.value;
});
for (int i = 0; i < int(column.size()) - 1; ++i) {
int best_index = i + 1;
int best_distance = 255 * 255 * 3;
for (int j = i + 1; j < column.size(); ++j) {
int dx = column[i].red - column[j].red;
int dy = column[i].green - column[j].green;
int dz = column[i].blue - column[j].blue;
int distance = dx * dx + dy * dy + dz * dz;
if (best_distance > distance) {
best_distance = distance;
best_index = j;
}
}
std::swap(column[i + 1], column[best_index]);
}
}
return std::move(info_columns);
}

View file

@ -0,0 +1,35 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <ftxui/dom/elements.hpp> // for operator|, Elements, Fit, bgcolor, color, hbox, text, vbox, Element
#include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator
#include <utility> // for move
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for Color, ftxui
int main() {
using namespace ftxui;
int saturation = 255;
Elements array;
for (int value = 0; value < 255; value += 20) {
Elements line;
for (int hue = 0; hue < 255; hue += 2) {
line.push_back(text("") //
| color(Color::HSV(hue, saturation, value)) //
| bgcolor(Color::HSV(hue, saturation, value + 10)));
}
array.push_back(hbox(std::move(line)));
}
auto document = vbox(std::move(array));
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
screen.Print();
return 0;
}

View file

@ -0,0 +1,54 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <ftxui/dom/elements.hpp> // for hbox, text, bgcolor, operator|, vbox, Elements, window, Element, Fit
#include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator
#include <utility> // for move
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for Color, ftxui
int main() {
using namespace ftxui;
int saturation = 255;
Elements red_line;
Elements green_line;
Elements blue_line;
Elements cyan_line;
Elements magenta_line;
Elements yellow_line;
for (int value = 0; value < 255; value += 3) {
int v = value * value / 255;
red_line.push_back(text(" ") | bgcolor(Color::RGB(v, 0, 0)));
green_line.push_back(text(" ") | bgcolor(Color::RGB(0, v, 0)));
blue_line.push_back(text(" ") | bgcolor(Color::RGB(0, 0, v)));
cyan_line.push_back(text(" ") | bgcolor(Color::RGB(0, v, v)));
magenta_line.push_back(text(" ") | bgcolor(Color::RGB(v, 0, v)));
yellow_line.push_back(text(" ") | bgcolor(Color::RGB(v, v, 0)));
}
auto document = vbox({
window(text("Primary colors"),
vbox({
hbox({text("Red line :"), hbox(std::move(red_line))}),
hbox({text("Green line :"), hbox(std::move(green_line))}),
hbox({text("Blue line :"), hbox(std::move(blue_line))}),
})),
window(text("Secondary colors"),
vbox({
hbox({text("cyan line :"), hbox(std::move(cyan_line))}),
hbox({text("magenta line:"), hbox(std::move(magenta_line))}),
hbox({text("Yellow line :"), hbox(std::move(yellow_line))}),
})),
});
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
screen.Print();
return 0;
}

View file

@ -0,0 +1,29 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <ftxui/dom/elements.hpp> // for text, operator|, border, Element, vbox, center, Fit, dbox
#include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for ftxui
int main() {
using namespace ftxui;
auto document = dbox({
vbox({
text("line_1"),
text("line_2"),
text("line_3"),
text("line_4"),
text("line_5"),
}) | border,
text("overlay") | border | center,
});
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
screen.Print();
return 0;
}

View file

@ -0,0 +1,36 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <chrono> // for operator""s, chrono_literals
#include <ftxui/dom/elements.hpp> // for text, gauge, operator|, flex, hbox, Element
#include <ftxui/screen/screen.hpp> // for Screen
#include <iostream> // for cout, endl, ostream
#include <string> // for allocator, char_traits, operator+, operator<<, string, to_string, basic_string
#include <thread> // for sleep_for
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for ftxui
int main() {
using namespace ftxui;
using namespace std::chrono_literals;
std::string reset_position;
for (float percentage = 0.0f; percentage <= 1.0f; percentage += 0.002f) {
std::string data_downloaded =
std::to_string(int(percentage * 5000)) + "/5000";
auto document = hbox({
text("downloading:"),
gauge(percentage) | flex,
text(" " + data_downloaded),
});
auto screen = Screen(100, 1);
Render(screen, document);
std::cout << reset_position;
screen.Print();
reset_position = screen.ResetPosition();
std::this_thread::sleep_for(0.01s);
}
std::cout << std::endl;
}

View file

@ -0,0 +1,78 @@
// Copyright 2022 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <chrono> // for operator""s, chrono_literals
#include <ftxui/dom/elements.hpp> // for filler, operator|, separator, text, border, Element, vbox, vtext, hbox, center, gaugeDown, gaugeLeft, gaugeRight, gaugeUp
#include <ftxui/screen/screen.hpp> // for Screen
#include <iostream> // for cout, endl, ostream
#include <string> // for allocator, operator+, operator<<, string, to_string
#include <thread> // for sleep_for
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for ftxui
int main() {
using namespace ftxui;
using namespace std::chrono_literals;
std::string reset_position;
for (float percentage = 0.0f; percentage <= 1.0f; percentage += 0.002f) {
std::string data_downloaded =
std::to_string(int(percentage * 5000)) + "/5000";
auto gauge_up = //
hbox({
vtext("gauge vertical"),
separator(),
gaugeUp(percentage),
}) |
border;
auto gauge_down = //
hbox({
vtext("gauge vertical"),
separator(),
gaugeDown(percentage),
}) |
border;
auto gauge_right = //
vbox({
text("gauge horizontal"),
separator(),
gaugeRight(percentage),
}) |
border;
auto gauge_left = //
vbox({
text("gauge horizontal"),
separator(),
gaugeLeft(percentage),
}) |
border;
auto document = hbox({
gauge_up,
filler(),
vbox({
gauge_right,
filler(),
text(data_downloaded) | border | center,
filler(),
gauge_left,
}),
filler(),
gauge_down,
});
auto screen = Screen(32, 16);
Render(screen, document);
std::cout << reset_position;
screen.Print();
reset_position = screen.ResetPosition();
std::this_thread::sleep_for(0.01s);
}
std::cout << std::endl;
}

View file

@ -0,0 +1,85 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <chrono> // for operator""s, chrono_literals
#include <cmath> // for sin
#include <ftxui/dom/elements.hpp> // for graph, operator|, separator, color, Element, vbox, flex, inverted, operator|=, Fit, hbox, size, border, GREATER_THAN, HEIGHT
#include <ftxui/screen/screen.hpp> // for Full, Screen
#include <functional> // for ref, reference_wrapper
#include <iostream> // for cout, ostream
#include <memory> // for shared_ptr
#include <string> // for operator<<, string
#include <thread> // for sleep_for
#include <vector> // for vector
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for Color, Color::BlueLight, Color::RedLight, Color::YellowLight, ftxui
class Graph {
public:
std::vector<int> operator()(int width, int height) const {
std::vector<int> output(width);
for (int i = 0; i < width; ++i) {
float v = 0;
v += 0.1f * sin((i + shift) * 0.1f); // NOLINT
v += 0.2f * sin((i + shift + 10) * 0.15f); // NOLINT
v += 0.1f * sin((i + shift) * 0.03f); // NOLINT
v *= height; // NOLINT
v += 0.5f * height; // NOLINT
output[i] = static_cast<int>(v);
}
return output;
}
int shift = 0;
};
std::vector<int> triangle(int width, int height) {
std::vector<int> output(width);
for (int i = 0; i < width; ++i) {
output[i] = i % (height - 4) + 2;
}
return output;
}
int main() {
using namespace ftxui;
using namespace std::chrono_literals;
Graph my_graph;
std::string reset_position;
for (int i = 0;; ++i) {
auto document = hbox({
vbox({
graph(std::ref(my_graph)),
separator(),
graph(triangle) | inverted,
}) | flex,
separator(),
vbox({
graph(std::ref(my_graph)) | color(Color::BlueLight),
separator(),
graph(std::ref(my_graph)) | color(Color::RedLight),
separator(),
graph(std::ref(my_graph)) | color(Color::YellowLight),
}) | flex,
});
document |= border;
const int min_width = 40;
document |= size(HEIGHT, GREATER_THAN, min_width);
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
std::cout << reset_position;
screen.Print();
reset_position = screen.ResetPosition();
const auto sleep_time = 0.03s;
std::this_thread::sleep_for(sleep_time);
my_graph.shift++;
}
return 0;
}

View file

@ -0,0 +1,48 @@
// Copyright 2021 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <stdio.h> // for getchar
#include <ftxui/dom/elements.hpp> // for Elements, gridbox, Fit, operator|, text, border, Element
#include <ftxui/screen/screen.hpp> // for Screen
#include <memory> // for allocator, shared_ptr
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for ftxui
int main() {
using namespace ftxui;
auto cell = [](const char* t) { return text(t) | border; };
auto document = //
gridbox({
{
cell("north-west"),
cell("north"),
cell("north-east"),
},
{
cell("center-west"),
gridbox({
{
cell("center-north-west"),
cell("center-north-east"),
},
{
cell("center-south-west"),
cell("center-south-east"),
},
}),
cell("center-east"),
},
{
cell("south-west"),
cell("south"),
cell("south-east"),
},
});
auto screen = Screen::Create(Dimension::Fit(document));
Render(screen, document);
screen.Print();
getchar();
return 0;
}

View file

@ -0,0 +1,52 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <stdio.h> // for getchar
#include <ftxui/dom/elements.hpp> // for operator|, size, Element, text, hcenter, Decorator, Fit, WIDTH, hflow, window, EQUAL, GREATER_THAN, HEIGHT, bold, border, dim, LESS_THAN
#include <ftxui/screen/screen.hpp> // for Full, Screen
#include <string> // for allocator, char_traits, operator+, to_string, string
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for ftxui
int main() {
using namespace ftxui;
auto make_box = [](int dimx, int dimy) {
std::string title = std::to_string(dimx) + "x" + std::to_string(dimy);
return window(text(title) | hcenter | bold,
text("content") | hcenter | dim) |
size(WIDTH, EQUAL, dimx) | size(HEIGHT, EQUAL, dimy);
};
auto style = size(WIDTH, GREATER_THAN, 20) | border |
size(HEIGHT, GREATER_THAN, 30) | size(WIDTH, LESS_THAN, 50);
auto document = hflow({
make_box(7, 7),
make_box(7, 5),
make_box(5, 7),
make_box(10, 4),
make_box(10, 4),
make_box(10, 4),
make_box(10, 4),
make_box(11, 4),
make_box(11, 4),
make_box(11, 4),
make_box(11, 4),
make_box(12, 4),
make_box(12, 5),
make_box(12, 4),
make_box(13, 4),
make_box(13, 3),
make_box(13, 3),
make_box(10, 3),
}) |
style;
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
screen.Print();
getchar();
return 0;
}

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