mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2025-09-04 14:24:35 +08:00
Compare commits
166 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d301fab1f4 | ||
![]() |
3e35f45830 | ||
![]() |
a4e70dfb93 | ||
![]() |
b2853c8f14 | ||
![]() |
6fe8310321 | ||
![]() |
350dcac032 | ||
![]() |
65848d1e5f | ||
![]() |
1561293140 | ||
![]() |
90dfceefcb | ||
![]() |
5410329ac6 | ||
![]() |
9f9571190a | ||
![]() |
b56afce48c | ||
![]() |
abd5b2a503 | ||
![]() |
60b9e491db | ||
![]() |
6cea410eaa | ||
![]() |
a52b959f66 | ||
![]() |
0542227ba7 | ||
![]() |
4dc1a9fff9 | ||
![]() |
b9f51844c3 | ||
![]() |
0d54285e19 | ||
![]() |
f21ca3aa14 | ||
![]() |
05f29ff3b3 | ||
![]() |
55b9706cfd | ||
![]() |
121bd0d046 | ||
![]() |
2c5681ee20 | ||
![]() |
1689802349 | ||
![]() |
9babfea36b | ||
![]() |
dfdbe1eecf | ||
![]() |
aeaf39b8ea | ||
![]() |
0acfd8f255 | ||
![]() |
26d63bc56f | ||
![]() |
f692a50195 | ||
![]() |
e04ea27dcd | ||
![]() |
f4b47333be | ||
![]() |
ccfe22bc24 | ||
![]() |
5ba29a9539 | ||
![]() |
c61fadd8ec | ||
![]() |
b3aad183da | ||
![]() |
fab74f745d | ||
![]() |
c8ec151154 | ||
![]() |
1d76a2321c | ||
![]() |
1661a5e83d | ||
![]() |
b3ba747d82 | ||
![]() |
8226c5aea7 | ||
![]() |
1e381fcad6 | ||
![]() |
d04e04adc6 | ||
![]() |
ec994a4e65 | ||
![]() |
3ec765e1f0 | ||
![]() |
251306a4bb | ||
![]() |
7cc68cfbd0 | ||
![]() |
36460fea2a | ||
![]() |
d755356481 | ||
![]() |
f461050759 | ||
![]() |
e42ab7b2e6 | ||
![]() |
d9241435ce | ||
![]() |
d5044bdaaf | ||
![]() |
f91677e79f | ||
![]() |
d6da30a518 | ||
![]() |
d5b1899290 | ||
![]() |
d545fb6f19 | ||
![]() |
f80e20c4aa | ||
![]() |
d805eb0648 | ||
![]() |
940f805b8f | ||
![]() |
57da24dfdb | ||
![]() |
0abaab6268 | ||
![]() |
ef0f1da147 | ||
![]() |
137f1fbf67 | ||
![]() |
094d8d9d0a | ||
![]() |
81e086788d | ||
![]() |
925a7578d4 | ||
![]() |
bb3231695f | ||
![]() |
0a522488a7 | ||
![]() |
b63aa9e375 | ||
![]() |
ed5b4cec49 | ||
![]() |
219daf46ff | ||
![]() |
11519ef1c6 | ||
![]() |
f9256fa132 | ||
![]() |
c033ca61ae | ||
![]() |
a6e04b4346 | ||
![]() |
09a2c077eb | ||
![]() |
bc206f85da | ||
![]() |
e9772a0116 | ||
![]() |
e4c5c7b43b | ||
![]() |
c2e1920449 | ||
![]() |
3d56146447 | ||
![]() |
c33e805a76 | ||
![]() |
d0890f94d1 | ||
![]() |
84d6e6b3dd | ||
![]() |
001dd0a8c3 | ||
![]() |
114cbfcffd | ||
![]() |
5ba301d316 | ||
![]() |
06ed8567b8 | ||
![]() |
04b36df567 | ||
![]() |
764c24ef40 | ||
![]() |
b2896aba49 | ||
![]() |
9f610a0110 | ||
![]() |
aebde94352 | ||
![]() |
62fb6298be | ||
![]() |
548fa51b71 | ||
![]() |
1a3fcc1bd8 | ||
![]() |
0137d2a9ac | ||
![]() |
c76612a3c8 | ||
![]() |
4da63b9260 | ||
![]() |
95c766e9e4 | ||
![]() |
3e28fd6520 | ||
![]() |
a254e36632 | ||
![]() |
9dbc23a7d4 | ||
![]() |
3fe12b8a2f | ||
![]() |
43dd70979d | ||
![]() |
779c2d5b1a | ||
![]() |
20f16b3984 | ||
![]() |
f95ed885bb | ||
![]() |
63e8dadad9 | ||
![]() |
9b83205b3e | ||
![]() |
5da7b8a59a | ||
![]() |
9c4218c2a8 | ||
![]() |
62747a49b6 | ||
![]() |
8ba3698437 | ||
![]() |
7c3ca1beb5 | ||
![]() |
689d5dd299 | ||
![]() |
372d0ace4a | ||
![]() |
81b7207121 | ||
![]() |
6039474a26 | ||
![]() |
4267b40a68 | ||
![]() |
3829734fa9 | ||
![]() |
b4a655ec65 | ||
![]() |
cd82fccde7 | ||
![]() |
382205c057 | ||
![]() |
feb24b9498 | ||
![]() |
3dc215e6c0 | ||
![]() |
1888631bec | ||
![]() |
84299de2e1 | ||
![]() |
cdd6339849 | ||
![]() |
358f886fab | ||
![]() |
728976bdeb | ||
![]() |
fc92f52b4c | ||
![]() |
071d2bc92b | ||
![]() |
d549cdabb0 | ||
![]() |
aea67743d4 | ||
![]() |
7614bf04a6 | ||
![]() |
188cffc5f6 | ||
![]() |
0d47dd19ab | ||
![]() |
7e5cd23b4c | ||
![]() |
52276c8a2b | ||
![]() |
602392c43d | ||
![]() |
f7c6bf91a7 | ||
![]() |
cecd54df42 | ||
![]() |
0186f8a463 | ||
![]() |
ebfb5ef3a1 | ||
![]() |
8f405f5054 | ||
![]() |
8652280c85 | ||
![]() |
aa6b78b8ad | ||
![]() |
c0e47aecb2 | ||
![]() |
cba11151b5 | ||
![]() |
f80d9b5cfd | ||
![]() |
313ce9c35f | ||
![]() |
4188ee2c04 | ||
![]() |
026a005753 | ||
![]() |
7298636e7c | ||
![]() |
5e199fcd85 | ||
![]() |
57a5512a22 | ||
![]() |
75482d82d4 | ||
![]() |
31c26c6956 | ||
![]() |
6dd626a79a | ||
![]() |
05fc866d74 | ||
![]() |
46f481ded7 |
24
.clang-tidy
Normal file
24
.clang-tidy
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
Checks: "*,
|
||||
-abseil-*,
|
||||
-altera-*,
|
||||
-android-*,
|
||||
-fuchsia-*,
|
||||
-google-*,
|
||||
-llvm*,
|
||||
-modernize-use-trailing-return-type,
|
||||
-zircon-*,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-cppcoreguidelines-non-private-member-variables-in-classes,
|
||||
-misc-no-recursion,
|
||||
-misc-non-private-member-variables-in-classes,
|
||||
-modernize-use-nodiscard,
|
||||
-readability-avoid-const-params-in-decls,
|
||||
-readability-else-after-return,
|
||||
-readability-identifier-length,
|
||||
-readability-implicit-bool-conversion,
|
||||
-readability-static-accessed-through-instance,
|
||||
"
|
||||
WarningsAsErrors: ''
|
||||
HeaderFilterRegex: ''
|
||||
FormatStyle: none
|
219
.github/workflows/build.yaml
vendored
Normal file
219
.github/workflows/build.yaml
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
create:
|
||||
tags:
|
||||
-v*
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
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: "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: true
|
||||
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
|
||||
-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 ;
|
||||
|
||||
- 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: "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
|
||||
-DFTXUI_BUILD_DOCS=OFF
|
||||
-DFTXUI_BUILD_EXAMPLES=OFF
|
||||
-DFTXUI_BUILD_TESTS=OFF
|
||||
-DFTXUI_BUILD_TESTS_FUZZER=OFF
|
||||
-DFTXUI_ENABLE_INSTALL=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/master'
|
||||
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;
|
||||
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
|
71
.github/workflows/codeql-analysis.yml
vendored
71
.github/workflows/codeql-analysis.yml
vendored
@@ -1,71 +0,0 @@
|
||||
# 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: [ master ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '38 7 * * 4'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: 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' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
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.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, 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@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
27
.github/workflows/linux-clang.yaml
vendored
27
.github/workflows/linux-clang.yaml
vendored
@@ -1,27 +0,0 @@
|
||||
name: Linux Clang
|
||||
|
||||
on:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Linux Clang
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: seanmiddleditch/gha-setup-ninja@master
|
||||
- name: Build
|
||||
run: >
|
||||
mkdir build;
|
||||
cd build;
|
||||
cmake ..
|
||||
-DCMAKE_CXX_COMPILER=clang++
|
||||
-DFTXUI_BUILD_TESTS=ON;
|
||||
cmake --build . --config Release;
|
||||
|
||||
- name: Tests
|
||||
if: ${{ matrix.config.test }}
|
||||
run: >
|
||||
cd build;
|
||||
./tests
|
47
.github/workflows/linux-emscripten.yaml
vendored
47
.github/workflows/linux-emscripten.yaml
vendored
@@ -1,47 +0,0 @@
|
||||
name: Linux Emscripten
|
||||
|
||||
on:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Linux Emscripten
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DOCUMENTATION: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: seanmiddleditch/gha-setup-ninja@master
|
||||
- uses: mymindstorm/setup-emsdk@v7
|
||||
|
||||
- name: Install Doxygen/Graphviz
|
||||
if: fromJSON(env.DOCUMENTATION)
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install doxygen graphviz
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
emcmake cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -S . -B build
|
||||
cmake --build build
|
||||
|
||||
- name: Build documentation
|
||||
if: fromJSON(env.DOCUMENTATION)
|
||||
run: |
|
||||
cd build
|
||||
cmake --build . --target doc
|
||||
# Copy emscripten built examples to the doxygen output directory for deployment
|
||||
rsync -amv --include='*/' --include='*.html' --include='*.js' --include='*.wasm' --exclude='*' examples doc/doxygen/html
|
||||
|
||||
# Deploy the HTML documentation to GitHub Pages
|
||||
- name: GH Pages Deployment
|
||||
if: fromJSON(env.DOCUMENTATION)
|
||||
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
|
26
.github/workflows/linux-gcc.yaml
vendored
26
.github/workflows/linux-gcc.yaml
vendored
@@ -1,26 +0,0 @@
|
||||
name: Linux GCC
|
||||
|
||||
on:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Linux GCC
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: seanmiddleditch/gha-setup-ninja@master
|
||||
- name: Build
|
||||
run: >
|
||||
mkdir build;
|
||||
cd build;
|
||||
cmake ..
|
||||
-DCMAKE_CXX_COMPILER=g++-9
|
||||
-DFTXUI_BUILD_TESTS=ON;
|
||||
cmake --build . --config Release;
|
||||
|
||||
- name: Tests
|
||||
run: >
|
||||
cd build;
|
||||
./tests
|
27
.github/workflows/mac-clang.yaml
vendored
27
.github/workflows/mac-clang.yaml
vendored
@@ -1,27 +0,0 @@
|
||||
name: MacOS Clang
|
||||
|
||||
on:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: MacOS Clang
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: seanmiddleditch/gha-setup-ninja@master
|
||||
- name: Build
|
||||
run: >
|
||||
mkdir build;
|
||||
cd build;
|
||||
cmake ..
|
||||
-DCMAKE_CXX_COMPILER=clang++
|
||||
-DFTXUI_BUILD_TESTS=ON;
|
||||
cmake --build . --config Release;
|
||||
|
||||
- name: Tests
|
||||
if: ${{ matrix.config.test }}
|
||||
run: >
|
||||
cd build;
|
||||
./tests
|
39
.github/workflows/release.yaml
vendored
39
.github/workflows/release.yaml
vendored
@@ -1,39 +0,0 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
create:
|
||||
tags:
|
||||
-v*
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: seanmiddleditch/gha-setup-ninja@master
|
||||
|
||||
- name: Build
|
||||
run: >
|
||||
mkdir build;
|
||||
cd build;
|
||||
cmake ..
|
||||
-DCMAKE_CXX_COMPILER=clang++
|
||||
-DFTXUI_BUILD_DOCS=OFF
|
||||
-DFTXUI_BUILD_EXAMPLES=OFF
|
||||
-DFTXUI_BUILD_TESTS=OFF
|
||||
-DFTXUI_BUILD_TESTS_FUZZER=OFF
|
||||
-DFTXUI_ENABLE_INSTALL=ON;
|
||||
cmake --build . --config Release;
|
||||
make package;
|
||||
|
||||
- name: Upload
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: build/ftxui-*
|
||||
draft: false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
28
.github/workflows/windows-msvc.yaml
vendored
28
.github/workflows/windows-msvc.yaml
vendored
@@ -1,28 +0,0 @@
|
||||
name: Windows MSVC
|
||||
|
||||
on:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Windows MSVC
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: seanmiddleditch/gha-setup-ninja@master
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
- name: Build
|
||||
run: >
|
||||
mkdir build;
|
||||
cd build;
|
||||
cmake ..
|
||||
-DCMAKE_CXX_COMPILER="cl"
|
||||
-DFTXUI_BUILD_TESTS=ON;
|
||||
cmake --build . --config Release;
|
||||
|
||||
- name: Tests
|
||||
if: ${{ matrix.config.test }}
|
||||
run: >
|
||||
cd build;
|
||||
./tests.exe
|
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"platform": [
|
||||
"GTest::+gtest"
|
||||
]
|
||||
}
|
202
CHANGELOG.md
202
CHANGELOG.md
@@ -1,20 +1,208 @@
|
||||
# Changelog
|
||||
Changelog
|
||||
=========
|
||||
|
||||
## Current
|
||||
current (development)
|
||||
---------------------
|
||||
|
||||
## 0.10 (2021-09-30)
|
||||
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
|
||||
- `vscroll_indicator`. Show a scrollbar indicator on the right.
|
||||
- `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.
|
||||
- `Maybe`: Display an component conditionnally based on a boolean.
|
||||
- `Dropdown`: A dropdown select list.
|
||||
|
||||
## 0.9 (2021-09-26)
|
||||
0.9 (2021-09-26)
|
||||
----------------
|
||||
|
||||
The initial release where changelog where written.
|
||||
|
||||
|
@@ -1,17 +1,17 @@
|
||||
cmake_minimum_required(VERSION 3.11)
|
||||
|
||||
include(cmake/ftxui_git_version.cmake)
|
||||
|
||||
project(ftxui
|
||||
LANGUAGES CXX
|
||||
VERSION 0.10.${git_version}
|
||||
VERSION 4.0.0
|
||||
)
|
||||
|
||||
option(FTXUI_BUILD_DOCS "Set to ON to build tests" ON)
|
||||
option(FTXUI_BUILD_DOCS "Set to ON to build docs" ON)
|
||||
option(FTXUI_BUILD_EXAMPLES "Set to ON to build examples" ON)
|
||||
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)
|
||||
|
||||
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 \
|
||||
@@ -24,42 +24,52 @@ else()
|
||||
${FTXUI_MICROSOFT_TERMINAL_FALLBACK_HELP_TEXT} OFF)
|
||||
endif()
|
||||
|
||||
add_library(screen STATIC
|
||||
|
||||
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
|
||||
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/util.hpp
|
||||
)
|
||||
|
||||
add_library(dom STATIC
|
||||
add_library(dom
|
||||
include/ftxui/dom/canvas.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/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/hflow.cpp
|
||||
src/ftxui/dom/inverted.cpp
|
||||
src/ftxui/dom/node.cpp
|
||||
src/ftxui/dom/node_decorator.cpp
|
||||
@@ -69,30 +79,43 @@ add_library(dom STATIC
|
||||
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 STATIC
|
||||
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
|
||||
@@ -101,41 +124,41 @@ add_library(component STATIC
|
||||
src/ftxui/component/slider.cpp
|
||||
src/ftxui/component/terminal_input_parser.cpp
|
||||
src/ftxui/component/terminal_input_parser.hpp
|
||||
src/ftxui/component/toggle.cpp
|
||||
src/ftxui/component/util.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(dom
|
||||
PUBLIC screen
|
||||
)
|
||||
|
||||
find_package(Threads)
|
||||
target_link_libraries(component
|
||||
PUBLIC dom
|
||||
PRIVATE Threads::Threads
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
if (FTXUI_BUILD_TESTS AND ${CMAKE_VERSION} VERSION_GREATER "3.11.4")
|
||||
include(cmake/ftxui_test.cmake)
|
||||
endif()
|
||||
|
||||
if(FTXUI_BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
||||
if(FTXUI_BUILD_DOCS)
|
||||
add_subdirectory(doc)
|
||||
endif()
|
||||
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)
|
||||
|
||||
if(FTXUI_ENABLE_INSTALL)
|
||||
include(cmake/ftxui_install.cmake)
|
||||
include(cmake/ftxui_package.cmake)
|
||||
endif()
|
||||
|
||||
add_subdirectory(examples)
|
||||
add_subdirectory(doc)
|
||||
|
334
README.md
334
README.md
@@ -8,10 +8,14 @@
|
||||
<a href="#"><img src="https://img.shields.io/github/repo-size/ArthurSonzogni/FTXUI"></img></a>
|
||||
<a href="https://github.com/ArthurSonzogni/FTXUI/issues"><img src="https://img.shields.io/github/issues/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>
|
||||
<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://github.com/ArthurSonzogni/FTXUI/wiki">Documentation</a> ·
|
||||
<a href="https://github.com/ArthurSonzogni/FTXUI/issues">Report Bug</a> ·
|
||||
<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>
|
||||
@@ -22,36 +26,37 @@
|
||||
|
||||
<i>Functional Terminal (X) User interface</i>
|
||||
|
||||
A simple C++ library for terminal based user interface.
|
||||
A simple 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).
|
||||
* Support for [UTF8](https://en.wikipedia.org/wiki/UTF-8) and [fullwidth chars](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms) (→ 测试).
|
||||
* No dependencies.
|
||||
* Cross platform. Linux/mac (main target), Windows (experimental thanks to contributors), WebAssembly.
|
||||
* 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/) (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)
|
||||
|
||||
## Operating systems
|
||||
- [![linux-emscripten][badge.linux-emscripten]][link.linux-emscripten]
|
||||
- [![linux-gcc][badge.linux-gcc]][link.linux-gcc]
|
||||
[![linux-clang][badge.linux-clang]][link.linux-clang]
|
||||
- [![windows-msvc][badge.windows-msvc]][link.windows-msvc]
|
||||
- [![mac-clang][badge.mac-clang]][link.mac-clang]
|
||||
|
||||
[badge.linux-gcc]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/linux-gcc.yaml/badge.svg?branch=master
|
||||
[badge.linux-clang]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/linux-clang.yaml/badge.svg?branch=master
|
||||
[badge.linux-emscripten]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/linux-emscripten.yaml/badge.svg?branch=master
|
||||
[badge.windows-msvc]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/windows-msvc.yaml/badge.svg?branch=master
|
||||
[badge.mac-clang]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/mac-clang.yaml/badge.svg?branch=master
|
||||
|
||||
[link.linux-gcc]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/linux-gcc.yaml
|
||||
[link.linux-clang]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/linux-clang.yaml
|
||||
[link.linux-emscripten]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/linux-emscripten.yaml
|
||||
[link.windows-msvc]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/windows-msvc.yaml
|
||||
[link.mac-clang]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/mac-clang.yaml
|
||||
This is expected to be cross platform. This supports / tests:
|
||||
- WebAssembly
|
||||
- Linux
|
||||
- MacOS
|
||||
- Windows
|
||||
|
||||
## Example
|
||||
~~~cpp
|
||||
@@ -74,17 +79,236 @@ A simple C++ library for terminal based user interface.
|
||||
└────────────────────────────────────────────────────────────────────────────┘
|
||||
~~~
|
||||
|
||||
# Documentation
|
||||
## 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`.
|
||||
|
||||

|
||||
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2gridbox_8cpp-example.htmlp) using gridbox:
|
||||
|
||||

|
||||
|
||||
[Example](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/dom/hflow.cpp) using flexbox:
|
||||
|
||||

|
||||
|
||||
[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`
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2style_gallery_8cpp-example.html)
|
||||
|
||||

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

|
||||
|
||||
</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):
|
||||
|
||||

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

|
||||
|
||||
</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):
|
||||
|
||||

|
||||
|
||||
</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):
|
||||
|
||||

|
||||
|
||||
Complex [examples](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/component/canvas_animated.cpp):
|
||||
|
||||

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

|
||||
|
||||
</details>
|
||||
|
||||
<details><summary>Radiobox</summary>
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2radiobox_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
<details><summary>Checkbox</summary>
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2checkbox_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
<details><summary>Input</summary>
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2input_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
<details><summary>Toggle</summary>
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2toggle_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
|
||||
<details><summary>Slider</summary>
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2slider_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
|
||||
<details><summary>Menu</summary>
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2menu_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
|
||||
<details><summary>ResizableSplit</summary>
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2resizable_split_8cpp-example.html):
|
||||
|
||||

|
||||
</details>
|
||||
|
||||
|
||||
<details><summary>Dropdown</summary>
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2dropdown_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
<details><summary>Tab</summary>
|
||||
|
||||
[Vertical](https://arthursonzogni.github.io/FTXUI/examples_2component_2tab_vertical_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
[Horizontal](https://arthursonzogni.github.io/FTXUI/examples_2component_2tab_horizontal_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
|
||||
|
||||
- [Starter example project](https://github.com/ArthurSonzogni/ftxui-starter)
|
||||
- [Documentation](https://arthursonzogni.github.io/FTXUI/)
|
||||
- [Examples (WebAssembly)](https://arthursonzogni.com/FTXUI/examples/)
|
||||
- [Build using CMake](https://arthursonzogni.com/FTXUI/doc/#build-using-cmake)
|
||||
- [Build using nxxm](https://arthursonzogni.com/FTXUI/doc/#build-using-cmake)
|
||||
|
||||
## 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)
|
||||
@@ -98,16 +322,56 @@ Feel free to add your projects here:
|
||||
- [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)
|
||||
|
||||
## Hosted on
|
||||
* [github](https://github.com/ArthurSonzogni/ftxui)
|
||||
* [gitlab](https://gitlab.com/ArthurSonzogni/ftxui)
|
||||
## [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** recommanded to use cmake FetchContent to depends on FTXUI. This
|
||||
way you can specify which commit you would like to depends on.
|
||||
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 ([soon](https://github.com/ArthurSonzogni/FTXUI/issues/112))
|
||||
- [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)
|
||||
|
||||
## Contributors
|
||||
|
||||
<a href="https://github.com/ArthurSonzogni/FTXUI/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=ArthurSonzogni/FTXUI" />
|
||||
</a>
|
||||
|
@@ -1,19 +1,21 @@
|
||||
if (NOT WIN32)
|
||||
FetchContent_Declare(googlebenchmark
|
||||
GIT_REPOSITORY "https://github.com/google/benchmark"
|
||||
GIT_TAG 62937f91b5c763a8e119d0c20c67b87bde8eff1c
|
||||
)
|
||||
FetchContent_MakeAvailable(googlebenchmark)
|
||||
|
||||
add_executable(ftxui_benchmark
|
||||
src/ftxui/dom/benchmark_test.cpp
|
||||
)
|
||||
target_link_libraries(ftxui_benchmark
|
||||
PRIVATE dom
|
||||
PRIVATE benchmark::benchmark
|
||||
PRIVATE benchmark::benchmark_main
|
||||
)
|
||||
target_include_directories(ftxui_benchmark
|
||||
PRIVATE src
|
||||
)
|
||||
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
|
||||
)
|
||||
|
8
cmake/ftxui_coverage.cmake
Normal file
8
cmake/ftxui_coverage.cmake
Normal 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()
|
32
cmake/ftxui_find_google_benchmark.cmake
Normal file
32
cmake/ftxui_find_google_benchmark.cmake
Normal 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 62937f91b5c763a8e119d0c20c67b87bde8eff1c
|
||||
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
|
||||
)
|
33
cmake/ftxui_find_google_test.cmake
Normal file
33
cmake/ftxui_find_google_test.cmake
Normal 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
|
||||
)
|
@@ -1,3 +1,7 @@
|
||||
if (NOT FTXUI_BUILD_TESTS_FUZZER)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_COMPILER clang)
|
||||
set(CMAKE_CXX_COMPILER clang++)
|
||||
|
||||
|
@@ -1,13 +0,0 @@
|
||||
find_package(Git QUIET)
|
||||
if (Git_FOUND AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git")
|
||||
message("git found")
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} rev-list --count HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE git_version
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
else()
|
||||
set(git_version 0)
|
||||
endif()
|
||||
|
@@ -1,3 +1,7 @@
|
||||
if(NOT FTXUI_ENABLE_INSTALL)
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS screen dom component
|
||||
EXPORT ftxui-export
|
||||
|
@@ -1,4 +1,16 @@
|
||||
set(CPACK_GENERATOR "DEB;External;RPM;STGZ;TBZ2;TGZ;TXZ;TZ;TZST;ZIP")
|
||||
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")
|
||||
|
@@ -1,17 +1,53 @@
|
||||
function(ftxui_set_options library)
|
||||
set_target_properties(${library} PROPERTIES PREFIX "ftxui-")
|
||||
find_program(CLANG_TIDY_EXE NAMES "clang-tidy" DOC "Path to clang-tidy executable" )
|
||||
if(NOT CLANG_TIDY_EXE)
|
||||
message(STATUS "clang-tidy not found.")
|
||||
else()
|
||||
message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}")
|
||||
endif()
|
||||
|
||||
function(ftxui_set_options library)
|
||||
message(STATUS "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(CLANG_TIDY_EXE AND FTXUI_CLANG_TIDY)
|
||||
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}
|
||||
PUBLIC
|
||||
$<INSTALL_INTERFACE:include>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
PRIVATE
|
||||
src
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
)
|
||||
|
||||
# C++17 is used. We require fold expression at least.
|
||||
target_compile_features(${library} PUBLIC cxx_std_17)
|
||||
set_target_properties(${library} PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_EXTENSIONS OFF
|
||||
)
|
||||
|
||||
# Force Microsoft Visual Studio to decode sources files in UTF-8. This applies
|
||||
# to the library and the library users.
|
||||
@@ -47,9 +83,7 @@ function(ftxui_set_options library)
|
||||
endfunction()
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
#string(APPEND CMAKE_CXX_FLAGS " -s ASSERTIONS=1")
|
||||
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()
|
||||
|
||||
|
@@ -1,48 +1,65 @@
|
||||
if (NOT FTXUI_BUILD_TESTS OR
|
||||
NOT ${CMAKE_VERSION} VERSION_GREATER "3.11.4")
|
||||
return()
|
||||
endif()
|
||||
|
||||
enable_testing()
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
|
||||
set(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)
|
||||
include(FetchContent)
|
||||
include(cmake/ftxui_find_google_test.cmake)
|
||||
|
||||
FetchContent_Declare( googletest
|
||||
GIT_REPOSITORY "https://github.com/google/googletest"
|
||||
GIT_TAG 23ef29555ef4789f555f1ba8c51b4c52975f0907
|
||||
)
|
||||
FetchContent_MakeAvailable(googletest)
|
||||
|
||||
add_executable(tests
|
||||
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/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(tests
|
||||
target_link_libraries(ftxui-tests
|
||||
PRIVATE component
|
||||
PRIVATE gtest
|
||||
PRIVATE gmock
|
||||
PRIVATE gtest_main
|
||||
PRIVATE GTest::gtest
|
||||
PRIVATE GTest::gtest_main
|
||||
)
|
||||
target_include_directories(tests
|
||||
target_include_directories(ftxui-tests
|
||||
PRIVATE src
|
||||
)
|
||||
target_compile_options(tests PRIVATE -fsanitize=address)
|
||||
target_link_libraries(tests PRIVATE -fsanitize=address)
|
||||
ftxui_set_options(ftxui-tests)
|
||||
target_compile_features(ftxui-tests PUBLIC cxx_std_20)
|
||||
|
||||
if (NOT MSVC)
|
||||
include(cmake/ftxui_benchmark.cmake)
|
||||
endif()
|
||||
|
||||
if (FTXUI_BUILD_TESTS_FUZZER)
|
||||
include(cmake/ftxui_fuzzer.cmake)
|
||||
endif()
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(ftxui-tests
|
||||
DISCOVERY_TIMEOUT 600
|
||||
)
|
||||
|
@@ -2,6 +2,6 @@ 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.impl
|
||||
--mapping_file ${CMAKE_CURRENT_SOURCE_DIR}/iwyu.imp
|
||||
)
|
||||
endif()
|
||||
|
12
codecov.yml
Normal file
12
codecov.yml
Normal 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
|
@@ -1,22 +1,27 @@
|
||||
if(NOT FTXUI_BUILD_DOCS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(Doxygen)
|
||||
if (DOXYGEN_FOUND)
|
||||
# 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
|
||||
)
|
||||
else (DOXYGEN_FOUND)
|
||||
if (NOT DOXYGEN_FOUND)
|
||||
message("Doxygen need to be installed to generate the doxygen documentation")
|
||||
endif (DOXYGEN_FOUND)
|
||||
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
|
||||
)
|
||||
|
@@ -178,11 +178,12 @@ div.headertitle {
|
||||
}
|
||||
|
||||
div.fragment {
|
||||
padding: 16px;
|
||||
background-color: #f3f3f3;
|
||||
border: 0 solid;
|
||||
transition: all 0.5s ease-in-out;
|
||||
border-radius:5px;
|
||||
border: 0 solid;
|
||||
border: none;
|
||||
padding:16px;
|
||||
transition: all 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
div.fragment:hover {
|
||||
@@ -192,8 +193,9 @@ div.fragment:hover {
|
||||
|
||||
div.line {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 85%;
|
||||
line-height: 1.45;
|
||||
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;
|
||||
@@ -206,15 +208,6 @@ div.line.glow {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
pre.fragment {
|
||||
border: 0 solid #C4CFE5;
|
||||
padding: 16px;
|
||||
background-color: #f3f3f3;
|
||||
font-size: 85%;
|
||||
line-height: 1.45;
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
}
|
||||
|
||||
/* @group Code Colorization */
|
||||
span.keyword {
|
||||
color: #808000
|
||||
|
659
doc/mainpage.md
659
doc/mainpage.md
@@ -1,14 +1,19 @@
|
||||
\mainpage
|
||||
|
||||
# Introduction
|
||||
# Introduction {#introduction}
|
||||
|
||||
Welcome to the FTXUI documentation. Here, you will find the detail of every
|
||||
functions and classes.
|
||||
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>
|
||||
@@ -37,19 +42,22 @@ int main(void) {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
**output**
|
||||
```bash
|
||||
┌────┐┌─────────────────────────────────────────────────────────────────┐┌─────┐
|
||||
│left││middle ││right│
|
||||
└────┘└─────────────────────────────────────────────────────────────────┘└─────┘
|
||||
┌────┐┌────────────────────────────────────┐┌─────┐
|
||||
│left││middle ││right│
|
||||
└────┘└────────────────────────────────────┘└─────┘
|
||||
```
|
||||
|
||||
# Build
|
||||
# Build {#build}
|
||||
|
||||
## Using CMake
|
||||
## Using CMake {#build-cmake}
|
||||
|
||||
This is an example configuration for your **CMakeLists.txt**
|
||||
|
||||
CMakeLists.txt
|
||||
~~~cmake
|
||||
```cmake
|
||||
cmake_minimum_required (VERSION 3.11)
|
||||
|
||||
# --- Fetch FTXUI --------------------------------------------------------------
|
||||
@@ -58,7 +66,7 @@ include(FetchContent)
|
||||
set(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)
|
||||
FetchContent_Declare(ftxui
|
||||
GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui
|
||||
# Specify a GIT_TAG here.
|
||||
# Important: Specify a GIT_TAG XXXXX here.
|
||||
)
|
||||
|
||||
FetchContent_GetProperties(ftxui)
|
||||
@@ -83,38 +91,43 @@ target_link_libraries(ftxui-starter
|
||||
PRIVATE ftxui::component # Not needed for this example.
|
||||
)
|
||||
|
||||
~~~
|
||||
```
|
||||
|
||||
Build
|
||||
~~~
|
||||
Subsequently, you build the project in the standard fashion as follows:
|
||||
```bash
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
make
|
||||
./main
|
||||
~~~
|
||||
```
|
||||
|
||||
# List of modules.
|
||||
# List of modules. {#modules}
|
||||
|
||||
The project is split into 3 modules:
|
||||
The project is comprised of 3 modules:
|
||||
|
||||
1. **ftxui/screen** defines a `ftxui::Screen`, this is a grid of `ftxui::Pixel`.
|
||||
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 part is only needed if you need to respond to the
|
||||
User input. It defines a set of `ftxui::Component`. The use can navigates
|
||||
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 the program by using the arrow keys and interacting
|
||||
with widgets such as the checkbox. You can also make you own components.
|
||||
The use can navigates
|
||||
using the arrow keys and interact with widgets like checkbox/inputbox/... You
|
||||
can make you own components.
|
||||
|
||||
# screen
|
||||
# screen {#module-screen}
|
||||
|
||||
It defines a `ftxui::Screen`. This is a grid of `ftxui::Pixel`. A Pixel
|
||||
represent a Unicode character and its associated style (bold, colors, etc...).
|
||||
The screen can be printed as a string using `ftxui::Screen::ToString()`.
|
||||
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
|
||||
```cpp
|
||||
#include <ftxui/screen/screen.hpp>
|
||||
#include <iostream>
|
||||
|
||||
@@ -130,75 +143,154 @@ The screen can be printed as a string using `ftxui::Screen::ToString()`.
|
||||
std::cout << screen.ToString();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
~~~
|
||||
```
|
||||
|
||||
# dom
|
||||
# dom {#module-dom}
|
||||
|
||||
This module defines a hierarchical set of Element. An element manages layout and
|
||||
can be responsive to the terminal dimensions.
|
||||
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")
|
||||
});
|
||||
text("The window") | bold | color(Color::Blue),
|
||||
gauge(0.5)
|
||||
text("The footer")
|
||||
});
|
||||
|
||||
// Add a border.
|
||||
// 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**
|
||||
|
||||
You only need one header: ftxui/dom/elements.hpp
|
||||
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
|
||||
## text ## {#dom-text}
|
||||
|
||||
The most simple widget. It displays a text.
|
||||
~~~cpp
|
||||
```cpp
|
||||
text("I am a piece of text");
|
||||
~~~
|
||||
~~~bash
|
||||
```
|
||||
```bash
|
||||
I am a piece of text.
|
||||
~~~
|
||||
```
|
||||
|
||||
## border
|
||||
## vtext {#dom-vtext}
|
||||
|
||||
Add a border around an element
|
||||
~~~cpp
|
||||
Identical to `ftxui::text`, but displayed vertically.
|
||||
|
||||
Code:
|
||||
```cpp
|
||||
vtext("HELLO");
|
||||
```
|
||||
|
||||
Terminal output:
|
||||
```bash
|
||||
H
|
||||
E
|
||||
L
|
||||
L
|
||||
O
|
||||
```
|
||||
|
||||
## paragraph {#dom-paragraph}
|
||||
|
||||
Similar to `ftxui::text`, but the individual word are wrapped along multiple
|
||||
lines, depending on the width of its container.
|
||||
|
||||
Sample Code:
|
||||
```cpp
|
||||
paragraph("A very long text")
|
||||
```
|
||||
|
||||

|
||||
|
||||
For a more detailed example refer to [detailed example](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"))
|
||||
~~~
|
||||
```
|
||||
|
||||
~~~bash
|
||||
Terminal output:
|
||||
```bash
|
||||
┌───────────┐
|
||||
│The element│
|
||||
└───────────┘
|
||||
~~~
|
||||
```
|
||||
|
||||
## window
|
||||
You can achieve the same behavior by using the pipe operator.
|
||||
|
||||
A `ftxui::window` is a `ftxui::border`, but with some text on top of the border.
|
||||
Add a border around an element
|
||||
~~~cpp
|
||||
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"))
|
||||
~~~
|
||||
```
|
||||
|
||||
~~~bash
|
||||
Terminal output:
|
||||
```bash
|
||||
┌The window─┐
|
||||
│The element│
|
||||
└───────────┘
|
||||
~~~
|
||||
```
|
||||
|
||||
## separator
|
||||
## separator {#dom-separator}
|
||||
|
||||
Display a vertical or horizontal line to visually split the content of a
|
||||
Displays a vertical/horizontal line to visually split the content of a
|
||||
container in two.
|
||||
|
||||
~~~cpp
|
||||
Code:
|
||||
```cpp
|
||||
border(
|
||||
hbox({
|
||||
text("Left"),
|
||||
@@ -206,44 +298,89 @@ border(
|
||||
text("Right")
|
||||
})
|
||||
)
|
||||
~~~
|
||||
```
|
||||
|
||||
~~~bash
|
||||
Terminal output:
|
||||
```bash
|
||||
┌────┬─────┐
|
||||
│left│right│
|
||||
└────┴─────┘
|
||||
~~~
|
||||
```
|
||||
|
||||
## gauge
|
||||
|
||||
A gauge. It can be used to represent a progress bar.
|
||||
~~~cpp
|
||||
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))
|
||||
~~~
|
||||
```
|
||||
|
||||
~~~bash
|
||||
Teminal output:
|
||||
```bash
|
||||
┌────────────────────────────────────────────────────────────────────────────┐
|
||||
│██████████████████████████████████████ │
|
||||
└────────────────────────────────────────────────────────────────────────────┘
|
||||
~~~
|
||||
```
|
||||
|
||||
## graph
|
||||
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
|
||||
|
||||
## Colors
|
||||
A terminal console can usually display colored text and colored background.
|
||||
See:
|
||||
```cpp
|
||||
Element graph(GraphFunction);
|
||||
```
|
||||
|
||||
~~~cpp
|
||||
## 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);
|
||||
~~~
|
||||
```
|
||||
|
||||
### Palette16
|
||||
|
||||
On most terminal the following colors are supported:
|
||||
Color [gallery](https://arthursonzogni.github.io/FTXUI/examples_2dom_2color_gallery_8cpp-example.html):
|
||||

|
||||
|
||||
### Palette16 #{#dom-colors-palette-16}
|
||||
|
||||
On most terminals the following colors are supported:
|
||||
- Default
|
||||
|
||||
- Black
|
||||
@@ -270,14 +407,14 @@ On most terminal the following colors are supported:
|
||||
- Yellow
|
||||
- YellowLight
|
||||
|
||||
Example:
|
||||
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
|
||||
### Palette256 #{#dom-colors-palette-256}
|
||||
|
||||
On terminal supporting 256 colors.
|
||||
@htmlonly
|
||||
@@ -288,9 +425,13 @@ On terminal supporting 256 colors.
|
||||
text("HotPink") | color(Color::HotPink);
|
||||
```
|
||||
|
||||
### TrueColor
|
||||
### TrueColor #{#dom-colors-true-color}
|
||||
|
||||
On terminal supporting trueColor, you can directly chose the 24bit RGB 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
|
||||
@@ -303,100 +444,159 @@ ftxui::Color::HSV(uint8_t hue, uint8_t saturation, uint8_t value);
|
||||
<script id="asciicast-xwzzghmqcqzIuyLwCpQFEqbEu" src="https://asciinema.org/a/xwzzghmqcqzIuyLwCpQFEqbEu.js" async></script>
|
||||
@endhtmlonly
|
||||
|
||||
## Style
|
||||
A terminal console can usually display colored text and colored background.
|
||||
The text can also have different effects: bold, dim, underlined, inverted,
|
||||
blink.
|
||||
## Style {#dom-style}
|
||||
In addition to colored text and colored backgrounds. Many terminals support text
|
||||
effects such as: `bold`, `dim`, `underlined`, `inverted`, `blink`.
|
||||
|
||||
~~~cpp
|
||||
```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);
|
||||
~~~
|
||||
```
|
||||
|
||||
Example:
|
||||
~~~cpp
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2style_gallery_8cpp-example.html)
|
||||
|
||||

|
||||
|
||||
To use these effects, simply wrap your elements with your desired effect:
|
||||
```cpp
|
||||
underlined(bold(text("This text is bold and underlined")))
|
||||
~~~
|
||||
```
|
||||
|
||||
Tips: The pipe operator can be used to chain Decorator:
|
||||
~~~cpp
|
||||
text("This text is bold")) | bold | underlined
|
||||
~~~
|
||||
Alternatively, use the pipe operator to chain it on your element:
|
||||
```cpp
|
||||
text("This text is bold") | bold | underlined
|
||||
```
|
||||
|
||||
## Layout
|
||||
## Layout {#dom-layout}
|
||||
|
||||
These layout are similar to the HTML flexbox:
|
||||
* vbox (Vertical-box)
|
||||
* hbox (Horizontal-box)
|
||||
* dbox (Z-axis-box)
|
||||
They are used to compose all the elements together. Each
|
||||
children are put side by side. If the container is flexible, the extra space
|
||||
available will be shared among the remaining flexible children.
|
||||
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`.
|
||||
|
||||
`flex(element)` can be used to make a non-flexible element flexible. `filler()`
|
||||
is a flexible empty element. You can use it align children on one side of the
|
||||
container.
|
||||

|
||||
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2gridbox_8cpp-example.htmlp)
|
||||
using `ftxui::gridbox`:
|
||||
|
||||
An horizontal flow layout is implemented by:
|
||||
* hflow (Horizontal flow)
|
||||

|
||||
|
||||
**Examples**
|
||||
~~~cpp
|
||||
[Example](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/dom/hflow.cpp)
|
||||
using flexbox:
|
||||
|
||||

|
||||
|
||||
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,
|
||||
});
|
||||
~~~
|
||||
~~~bash
|
||||
┌────┐┌─────────────────────────────────────────────────────────────────┐┌─────┐
|
||||
│left││middle ││right│
|
||||
└────┘└─────────────────────────────────────────────────────────────────┘└─────┘
|
||||
~~~
|
||||
```
|
||||
Terminal output:
|
||||
```bash
|
||||
┌────┐┌─────────────────────────────────────────────────────┐┌─────┐
|
||||
│left││middle ││right│
|
||||
└────┘└─────────────────────────────────────────────────────┘└─────┘
|
||||
```
|
||||
|
||||
~~~cpp
|
||||
Code:
|
||||
```cpp
|
||||
hbox({
|
||||
text("left") | border ,
|
||||
text("middle") | border | flex,
|
||||
text("right") | border | flex,
|
||||
});
|
||||
~~~
|
||||
~~~bash
|
||||
┌────┐┌───────────────────────────────────┐┌───────────────────────────────────┐
|
||||
│left││middle ││right │
|
||||
└────┘└───────────────────────────────────┘└───────────────────────────────────┘
|
||||
~~~
|
||||
```
|
||||
|
||||
Terminal output:
|
||||
```bash
|
||||
┌────┐┌───────────────────────────────┐┌───────────────────────────────┐
|
||||
│left││middle ││right │
|
||||
└────┘└───────────────────────────────┘└───────────────────────────────┘
|
||||
```
|
||||
|
||||
# component
|
||||
## Table {#dom-table}
|
||||
|
||||
The `ftxui/component` directory defines the logic to get produce
|
||||
interactive component responding to user's events (keyboard, mouse, etc...)
|
||||
Enables easy formatting of data into a neat table like visual form.
|
||||
|
||||
A `ftxui::ScreenInteractive` defines a main loop to render a component.
|
||||
[Code example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2table_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
A `ftxui::Component` is a shared pointer to a `ftxui::ComponentBase`. The later
|
||||
defines
|
||||
## 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):
|
||||
|
||||

|
||||
|
||||
Complex [example](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/component/canvas_animated.cpp):
|
||||
|
||||

|
||||
|
||||
# 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()`: Give a parent/child relation ship in between
|
||||
two component. This defines a tree a components, which help properly define
|
||||
how keyboard navigation works.
|
||||
- `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.
|
||||
|
||||
Predefined components are available in `ftxui/dom/component.hpp`:
|
||||
`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))
|
||||
|
||||

|
||||
|
||||
All predefined components are available in
|
||||
["ftxui/dom/component.hpp"](./component_8hpp.html)
|
||||
|
||||
\include ftxui/component/component.hpp
|
||||
|
||||
Element are stateless object. On the other side, components are used when an
|
||||
internal state is needed. Components are used to interact with the user with
|
||||
its keyboard. They handle keyboard navigation, including component focus.
|
||||
## Input {#component-input}
|
||||
|
||||
## Input
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2input_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
Produced by: `ftxui::Input()` from "ftxui/component/component.hpp"
|
||||
|
||||
@@ -404,7 +604,14 @@ Produced by: `ftxui::Input()` from "ftxui/component/component.hpp"
|
||||
<script id="asciicast-223719" src="https://asciinema.org/a/223719.js" async></script>
|
||||
@endhtmlonly
|
||||
|
||||
## Menu
|
||||
## 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):
|
||||
|
||||

|
||||
|
||||
|
||||
Produced by: `ftxui::Menu()` from "ftxui/component/component.hpp"
|
||||
|
||||
@@ -412,7 +619,13 @@ Produced by: `ftxui::Menu()` from "ftxui/component/component.hpp"
|
||||
<script id="asciicast-223720" src="https://asciinema.org/a/223720.js" async></script>
|
||||
@endhtmlonly
|
||||
|
||||
## Toggle.
|
||||
## 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):
|
||||
|
||||

|
||||
|
||||
Produced by: `ftxui::Toggle()` from "ftxui/component/component.hpp"
|
||||
|
||||
@@ -420,7 +633,14 @@ Produced by: `ftxui::Toggle()` from "ftxui/component/component.hpp"
|
||||
<script id="asciicast-223722" src="https://asciinema.org/a/223722.js" async></script>
|
||||
@endhtmlonly
|
||||
|
||||
## CheckBox
|
||||
## 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):
|
||||
|
||||

|
||||
|
||||
Produced by: `ftxui::Checkbox()` from "ftxui/component/component.hpp"
|
||||
|
||||
@@ -428,7 +648,13 @@ Produced by: `ftxui::Checkbox()` from "ftxui/component/component.hpp"
|
||||
<script id="asciicast-223724" src="https://asciinema.org/a/223724.js" async></script>
|
||||
@endhtmlonly
|
||||
|
||||
## RadioBox
|
||||
## 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):
|
||||
|
||||

|
||||
|
||||
Produced by: `ftxui::Radiobox()` from "ftxui/component/component.hpp"
|
||||
|
||||
@@ -436,65 +662,182 @@ Produced by: `ftxui::Radiobox()` from "ftxui/component/component.hpp"
|
||||
<script id="asciicast-223725" src="https://asciinema.org/a/223725.js" async></script>
|
||||
@endhtmlonly
|
||||
|
||||
## Renderer
|
||||
## Dropdown {#component-dropdown}
|
||||
|
||||
Produced by: `ftxui::Renderer()` from \ref "ftxui/component/component.hpp". This
|
||||
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):
|
||||
|
||||

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

|
||||
|
||||
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.
|
||||
|
||||
## CatchEvent
|
||||
Example:
|
||||
```cpp
|
||||
auto inner = [...]
|
||||
|
||||
Produced by: `ftxui::CatchEvent()` from \ref "ftxui/component/component.hpp".
|
||||
This component decorate another one and catch the events before the underlying
|
||||
component.
|
||||
auto renderer = Renderer(inner, [&] {
|
||||
return inner->Render() | border
|
||||
});
|
||||
```
|
||||
|
||||
## Container::Horizontal
|
||||
`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.
|
||||
|
||||
## Container::Vertial
|
||||
### 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.
|
||||
|
||||
## Container::Tab
|
||||
### 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.
|
||||
|
||||
## ResizableSplit::{Left, Right, Top, Bottom}
|
||||
[Vertical](https://arthursonzogni.github.io/FTXUI/examples_2component_2tab_vertical_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
Produced by:
|
||||
[Horizontal](https://arthursonzogni.github.io/FTXUI/examples_2component_2tab_horizontal_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
|
||||
## 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"
|
||||
|
||||
It defines an horizontal or vertical separation in between two children
|
||||
component. The position of the split is variable and controllable using the
|
||||
mouse.
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2resizable_split_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
@htmlonly
|
||||
<script id="asciicast-tprMH2EdkUoMb7D2YxgMGgpzx" src="https://asciinema.org/a/tprMH2EdkUoMb7D2YxgMGgpzx.js" async></script>
|
||||
@endhtmlonly
|
||||
|
||||
## Force a frame redraw.
|
||||
## Force a frame redraw. {#component-force-redraw}
|
||||
|
||||
Whenever a new group of events have been processed: keyboard, mouse, window
|
||||
resize, etc..., the `ftxui::ScreenInteractive::Loop()` is responsible for
|
||||
drawing a new frame.
|
||||
|
||||
You might want to react to arbitrary events that are unknown to FTXUI. This can
|
||||
be achieve by posting events via `ftxui::ScreenInteractive::PostEvent`, via a
|
||||
thread. You can post the event`ftxui::Event::Custom`.
|
||||
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);
|
||||
```
|
||||
|
||||
`ftxui::ScreenInteractive::PostEvent` is thread safe.
|
||||
|
@@ -1,18 +1,32 @@
|
||||
if(NOT FTXUI_BUILD_EXAMPLES)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(EXAMPLES_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
function(example name)
|
||||
add_executable(${name} ${name}.cpp)
|
||||
target_link_libraries(${name} PUBLIC ${DIRECTORY_LIB})
|
||||
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})
|
||||
set_target_properties(ftxui_example_${name} PROPERTIES
|
||||
CXX_STANDARD 20
|
||||
)
|
||||
endfunction(example)
|
||||
|
||||
add_subdirectory(component)
|
||||
add_subdirectory(dom)
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
# 32MB should be enough to run all the examples, in debug mode.
|
||||
target_link_options(component PUBLIC "SHELL: -s TOTAL_MEMORY=33554432")
|
||||
target_link_options(component PUBLIC "SHELL: -s ASSERTIONS=1")
|
||||
#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)
|
||||
|
@@ -1,10 +1,19 @@
|
||||
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)
|
||||
@@ -12,10 +21,13 @@ 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)
|
||||
@@ -23,7 +35,9 @@ example(radiobox_in_frame)
|
||||
example(renderer)
|
||||
example(resizable_split)
|
||||
example(slider)
|
||||
example(slider_direction)
|
||||
example(slider_rgb)
|
||||
example(tab_horizontal)
|
||||
example(tab_vertical)
|
||||
example(toggle)
|
||||
example(with_restored_io)
|
||||
|
@@ -1,12 +1,11 @@
|
||||
#include <memory> // for shared_ptr, __shared_ptr_access
|
||||
#include <string> // for operator+, to_wstring
|
||||
#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 separator, gauge, Element, operator|, vbox, border
|
||||
#include "ftxui/dom/elements.hpp" // for separator, gauge, text, Element, operator|, vbox, border
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
@@ -14,13 +13,9 @@ int main(int argc, const char* argv[]) {
|
||||
int value = 50;
|
||||
|
||||
// The tree of components. This defines how to navigate using the keyboard.
|
||||
auto button_option = ButtonOption();
|
||||
button_option.border = false;
|
||||
auto buttons = Container::Horizontal({
|
||||
Button(
|
||||
"[Decrease]", [&] { value--; }, &button_option),
|
||||
Button(
|
||||
"[Increase]", [&] { value++; }, &button_option),
|
||||
Button("Decrease", [&] { value--; }),
|
||||
Button("Increase", [&] { value++; }),
|
||||
});
|
||||
|
||||
// Modify the way to render them on screen:
|
||||
|
46
examples/component/button_animated.cpp
Normal file
46
examples/component/button_animated.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#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 argc, const char* argv[]) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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.
|
49
examples/component/button_in_frame.cpp
Normal file
49
examples/component/button_in_frame.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#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 argc, const char* argv[]) {
|
||||
int counter = 0;
|
||||
auto on_click = [&] { counter++; };
|
||||
|
||||
auto button_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, &button_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;
|
||||
}
|
||||
|
||||
// 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.
|
61
examples/component/button_style.cpp
Normal file
61
examples/component/button_style.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#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 argc, const char* argv[]) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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.
|
263
examples/component/canvas_animated.cpp
Normal file
263
examples/component/canvas_animated.cpp
Normal file
@@ -0,0 +1,263 @@
|
||||
#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(int argc, const char* argv[]) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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.
|
@@ -1,25 +1,31 @@
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Checkbox, Vertical
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
#include <memory> // for allocator, __shared_ptr_access
|
||||
#include <string> // for string, basic_string, operator+, to_string
|
||||
#include <vector> // for vector
|
||||
|
||||
using namespace ftxui;
|
||||
#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(int argc, const char* argv[]) {
|
||||
bool build_examples_state = false;
|
||||
bool build_tests_state = false;
|
||||
bool use_webassembly_state = true;
|
||||
using namespace ftxui;
|
||||
|
||||
auto component = Container::Vertical({
|
||||
Checkbox("Build examples", &build_examples_state),
|
||||
Checkbox("Build tests", &build_tests_state),
|
||||
Checkbox("Use WebAssembly", &use_webassembly_state),
|
||||
Component input_list = Container::Vertical({});
|
||||
std::vector<std::string> items(100, "");
|
||||
for (int 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(component);
|
||||
return 0;
|
||||
screen.Loop(renderer);
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// 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.
|
||||
|
@@ -1,26 +1,22 @@
|
||||
#include <memory> // for shared_ptr, __shared_ptr_access, allocator_traits<>::value_type
|
||||
#include <array> // for array
|
||||
#include <memory> // for shared_ptr, __shared_ptr_access
|
||||
#include <string> // for operator+, to_string
|
||||
#include <vector> // for vector
|
||||
|
||||
#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, HEIGHT, LESS_THAN
|
||||
#include "ftxui/dom/elements.hpp" // for operator|, Element, size, border, frame, vscroll_indicator, HEIGHT, LESS_THAN
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
struct CheckboxState {
|
||||
bool checked;
|
||||
};
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
std::vector<CheckboxState> states(30);
|
||||
std::array<bool, 30> states;
|
||||
|
||||
auto container = Container::Vertical({});
|
||||
for (int i = 0; i < 30; ++i) {
|
||||
states[i].checked = false;
|
||||
container->Add(
|
||||
Checkbox("Checkbox" + std::to_string(i), &states[i].checked));
|
||||
states[i] = false;
|
||||
container->Add(Checkbox("Checkbox" + std::to_string(i), &states[i]));
|
||||
}
|
||||
|
||||
auto renderer = Renderer(container, [&] {
|
||||
|
58
examples/component/collapsible.cpp
Normal file
58
examples/component/collapsible.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#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(int argc, const char* argv[]) {
|
||||
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);
|
||||
}
|
||||
|
||||
// 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.
|
@@ -4,7 +4,6 @@
|
||||
#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 text, separator, Element, operator|, vbox, border
|
||||
|
||||
@@ -13,24 +12,17 @@ using namespace ftxui;
|
||||
// An example of how to compose multiple components into one and maintain their
|
||||
// interactiveness.
|
||||
int main(int argc, const char* argv[]) {
|
||||
auto button_option = ButtonOption();
|
||||
button_option.border = false;
|
||||
|
||||
auto left_count = 0;
|
||||
auto right_count = 0;
|
||||
|
||||
auto left_buttons = Container::Horizontal({
|
||||
Button(
|
||||
"[Decrease]", [&] { left_count--; }, &button_option),
|
||||
Button(
|
||||
"[Increase]", [&] { left_count++; }, &button_option),
|
||||
Button("Decrease", [&] { left_count--; }),
|
||||
Button("Increase", [&] { left_count++; }),
|
||||
});
|
||||
|
||||
auto right_buttons = Container::Horizontal({
|
||||
Button(
|
||||
"[Decrease]", [&] { right_count--; }, &button_option),
|
||||
Button(
|
||||
"[Increase]", [&] { right_count++; }, &button_option),
|
||||
Button("Decrease", [&] { right_count--; }),
|
||||
Button("Increase", [&] { right_count++; }),
|
||||
});
|
||||
|
||||
// Renderer decorates its child with a new rendering function. The way the
|
||||
|
55
examples/component/custom_loop.cpp
Normal file
55
examples/component/custom_loop.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#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(int argc, const char* argv[]) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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.
|
@@ -1,26 +1,23 @@
|
||||
#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 <string> // for basic_string, 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/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Dropdown, Horizontal, Vertical
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
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",
|
||||
"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;
|
||||
|
192
examples/component/flexbox_gallery.cpp
Normal file
192
examples/component/flexbox_gallery.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
#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(int argc, const char* argv[]) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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.
|
70
examples/component/focus.cpp
Normal file
70
examples/component/focus.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#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(int argc, const char* argv[]) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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.
|
38
examples/component/focus_cursor.cpp
Normal file
38
examples/component/focus_cursor.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#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(int argc, const char* argv[]) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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.
|
@@ -1,27 +1,35 @@
|
||||
#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, operator+, char_traits, to_string
|
||||
#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 "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Checkbox, Renderer, Horizontal, Vertical, Menu, Radiobox, Tab, Toggle
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/component_options.hpp" // for InputOption
|
||||
#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 operator|, color, bgcolor, filler, Element, size, vbox, flex, hbox, graph, separator, EQUAL, WIDTH, hcenter, bold, border, window, HEIGHT, Elements, hflow, flex_grow, frame, gauge, LESS_THAN, spinner, dim, GREATER_THAN
|
||||
#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
|
||||
#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(int argc, const char* argv[]) {
|
||||
auto screen = ScreenInteractive::Fullscreen();
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// HTOP
|
||||
// ---------------------------------------------------------------------------
|
||||
int shift = 0;
|
||||
|
||||
auto my_graph = [&shift](int width, int height) {
|
||||
@@ -89,9 +97,13 @@ int main(int argc, const char* argv[]) {
|
||||
separator(),
|
||||
ram | flex,
|
||||
}) |
|
||||
flex | border;
|
||||
flex;
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Compiler
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const std::vector<std::string> compiler_entries = {
|
||||
"gcc",
|
||||
"clang",
|
||||
@@ -245,64 +257,128 @@ int main(int argc, const char* argv[]) {
|
||||
}) | size(HEIGHT, LESS_THAN, 8),
|
||||
hflow(render_command()) | flex_grow,
|
||||
}) |
|
||||
flex_grow | border;
|
||||
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)) | border;
|
||||
return hflow(std::move(entries));
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Colors
|
||||
// ---------------------------------------------------------------------------
|
||||
auto color_tab_renderer = Renderer([] {
|
||||
return 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")),
|
||||
}),
|
||||
}) |
|
||||
hcenter | border;
|
||||
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) % 1000 / 1000.f;
|
||||
float progress = (shift + delta) % 500 / 500.f;
|
||||
return hbox({
|
||||
text(std::to_string(int(progress * 100)) + "% ") |
|
||||
size(WIDTH, EQUAL, 5),
|
||||
@@ -312,32 +388,94 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
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),
|
||||
}) |
|
||||
border;
|
||||
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,
|
||||
¶graph_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",
|
||||
"htop", "color", "spinner", "gauge", "compiler", "paragraph",
|
||||
};
|
||||
auto tab_selection = Toggle(&tab_entries, &tab_index);
|
||||
auto tab_selection =
|
||||
Menu(&tab_entries, &tab_index, MenuOption::HorizontalAnimated());
|
||||
auto tab_content = Container::Tab(
|
||||
{
|
||||
htop,
|
||||
@@ -345,6 +483,7 @@ int main(int argc, const char* argv[]) {
|
||||
spinner_tab_renderer,
|
||||
gauge_component,
|
||||
compiler_renderer,
|
||||
paragraph_renderer_group_renderer,
|
||||
},
|
||||
&tab_index);
|
||||
|
||||
@@ -356,18 +495,23 @@ int main(int argc, const char* argv[]) {
|
||||
auto main_renderer = Renderer(main_container, [&] {
|
||||
return vbox({
|
||||
text("FTXUI Demo") | bold | hcenter,
|
||||
tab_selection->Render() | hcenter,
|
||||
tab_selection->Render(),
|
||||
tab_content->Render() | flex,
|
||||
});
|
||||
});
|
||||
|
||||
bool refresh_ui_continue = true;
|
||||
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);
|
||||
shift++;
|
||||
screen.PostEvent(Event::Custom);
|
||||
// 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);
|
||||
}
|
||||
});
|
||||
|
||||
|
@@ -1,20 +1,16 @@
|
||||
#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 <string> // for string, allocator, basic_string
|
||||
#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/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;
|
||||
Component Border(Component child) {
|
||||
return Renderer(child, [child] { return child->Render() | border; });
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
|
||||
std::vector<std::string> entries = {
|
||||
"entry 1",
|
||||
"entry 2",
|
||||
@@ -22,20 +18,19 @@ int main(int argc, const char* argv[]) {
|
||||
};
|
||||
int menu_1_selected = 0;
|
||||
int menu_2_selected = 0;
|
||||
auto menu_1 = Radiobox(&entries, &menu_1_selected);
|
||||
auto menu_2 = Radiobox(&entries, &menu_2_selected);
|
||||
|
||||
menu_1 = Border(menu_1);
|
||||
menu_2 = Border(menu_2);
|
||||
|
||||
bool menu_1_show = false;
|
||||
bool menu_2_show = false;
|
||||
|
||||
auto layout = Container::Vertical({
|
||||
Checkbox("Show menu_1", &menu_1_show),
|
||||
Maybe(menu_1, &menu_1_show),
|
||||
Radiobox(&entries, &menu_1_selected) | border | Maybe(&menu_1_show),
|
||||
Checkbox("Show menu_2", &menu_2_show),
|
||||
Maybe(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();
|
||||
|
@@ -1,25 +1,31 @@
|
||||
#include <functional> // for function
|
||||
#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 <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|, separator, Element, Decorator, color, text, hbox, size, bold, frame, inverted, vbox, HEIGHT, LESS_THAN, border
|
||||
#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 special_style;
|
||||
special_style.style_normal = Decorator(color(c));
|
||||
special_style.style_focused = Decorator(color(c)) | inverted;
|
||||
special_style.style_selected = Decorator(color(c)) | bold;
|
||||
special_style.style_selected_focused = Decorator(color(c)) | inverted | bold;
|
||||
return special_style;
|
||||
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(int argc, const char* argv[]) {
|
||||
|
66
examples/component/menu_entries_animated.cpp
Normal file
66
examples/component/menu_entries_animated.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#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(int argc, const char* argv[]) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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.
|
@@ -1,100 +1,258 @@
|
||||
#include <array> // for array
|
||||
#include <chrono> // for milliseconds
|
||||
#include <functional> // for function
|
||||
#include <memory> // for shared_ptr, __shared_ptr_access, allocator
|
||||
#include <string> // for string, basic_string
|
||||
#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/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 ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for operator|, color, separator, Decorator, bgcolor, flex, Element, bold, hbox, border, dim
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::BlueLight, Color::Red, Color::Yellow
|
||||
#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(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
auto screen = ScreenInteractive::TerminalOutput();
|
||||
|
||||
std::vector<std::string> entries = {
|
||||
"Monkey", "Dog", "Cat", "Bird", "Elephant",
|
||||
std::vector<std::string> entries{
|
||||
"Monkey", "Dog", "Cat", "Bird", "Elephant", "Cat",
|
||||
};
|
||||
int menu_1_selected_ = 0;
|
||||
int menu_2_selected_ = 0;
|
||||
int menu_3_selected_ = 0;
|
||||
int menu_4_selected_ = 0;
|
||||
int menu_5_selected_ = 0;
|
||||
int menu_6_selected_ = 0;
|
||||
std::array<int, 12> selected = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
MenuOption option_1;
|
||||
option_1.style_focused = bold | color(Color::Blue);
|
||||
option_1.style_selected = color(Color::Blue);
|
||||
option_1.style_selected_focused = bold | color(Color::Blue);
|
||||
option_1.on_enter = screen.ExitLoopClosure();
|
||||
auto menu_1_ = Menu(&entries, &menu_1_selected_, &option_1);
|
||||
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]);
|
||||
|
||||
MenuOption option_2;
|
||||
option_2.style_focused = bold | color(Color::Blue);
|
||||
option_2.style_selected = color(Color::Blue);
|
||||
option_2.style_selected_focused = bold | color(Color::Blue);
|
||||
option_2.on_enter = screen.ExitLoopClosure();
|
||||
auto menu_2_ = Menu(&entries, &menu_2_selected_, &option_2);
|
||||
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]);
|
||||
|
||||
MenuOption option_3;
|
||||
option_3.style_selected = color(Color::Blue);
|
||||
option_3.style_focused = bgcolor(Color::Blue);
|
||||
option_3.style_selected_focused = bgcolor(Color::Blue);
|
||||
option_3.on_enter = screen.ExitLoopClosure();
|
||||
auto menu_3_ = Menu(&entries, &menu_3_selected_, &option_3);
|
||||
|
||||
MenuOption option_4;
|
||||
option_4.style_selected = bgcolor(Color::Blue);
|
||||
option_4.style_focused = bgcolor(Color::BlueLight);
|
||||
option_4.style_selected_focused = bgcolor(Color::BlueLight);
|
||||
option_4.on_enter = screen.ExitLoopClosure();
|
||||
auto menu_4_ = Menu(&entries, &menu_4_selected_, &option_4);
|
||||
|
||||
MenuOption option_5;
|
||||
option_5.style_normal = bgcolor(Color::Blue);
|
||||
option_5.style_selected = bgcolor(Color::Yellow);
|
||||
option_5.style_focused = bgcolor(Color::Red);
|
||||
option_5.style_selected_focused = bgcolor(Color::Red);
|
||||
option_5.on_enter = screen.ExitLoopClosure();
|
||||
auto menu_5_ = Menu(&entries, &menu_5_selected_, &option_5);
|
||||
|
||||
MenuOption option_6;
|
||||
option_6.style_normal = dim | color(Color::Blue);
|
||||
option_6.style_selected = color(Color::Blue);
|
||||
option_6.style_focused = bold | color(Color::Blue);
|
||||
option_6.style_selected_focused = bold | color(Color::Blue);
|
||||
option_6.on_enter = screen.ExitLoopClosure();
|
||||
auto menu_6_ = Menu(&entries, &menu_6_selected_, &option_6);
|
||||
|
||||
auto container = Container::Horizontal({
|
||||
menu_1_,
|
||||
menu_2_,
|
||||
menu_3_,
|
||||
menu_4_,
|
||||
menu_5_,
|
||||
menu_6_,
|
||||
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_,
|
||||
});
|
||||
|
||||
// clang-format off
|
||||
auto renderer = Renderer(container, [&] {
|
||||
return
|
||||
hbox({
|
||||
menu_1_->Render() | flex, separator(),
|
||||
menu_2_->Render() | flex, separator(),
|
||||
menu_3_->Render() | flex, separator(),
|
||||
menu_4_->Render() | flex, separator(),
|
||||
menu_5_->Render() | flex, separator(),
|
||||
menu_6_->Render() | flex,
|
||||
}) | border;
|
||||
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(),
|
||||
});
|
||||
});
|
||||
// clang-format on
|
||||
|
||||
screen.Loop(renderer);
|
||||
}
|
||||
|
||||
Component VMenu1(std::vector<std::string>* entries, int* selected) {
|
||||
auto option = MenuOption::Vertical();
|
||||
option.entries.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.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.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.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.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.animated_colors.foreground.enabled = true;
|
||||
option.entries.animated_colors.background.enabled = true;
|
||||
option.entries.animated_colors.background.active = Color::Red;
|
||||
option.entries.animated_colors.background.inactive = Color::Black;
|
||||
option.entries.animated_colors.foreground.active = Color::White;
|
||||
option.entries.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.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.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);
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
94
examples/component/menu_underline_animated_gallery.cpp
Normal file
94
examples/component/menu_underline_animated_gallery.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#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(int argc, const char* argv[]) {
|
||||
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);
|
||||
}
|
||||
|
||||
// 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.
|
@@ -1,94 +1,83 @@
|
||||
#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/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/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
|
||||
#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[]) {
|
||||
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;
|
||||
// State of the application:
|
||||
bool modal_shown = false;
|
||||
|
||||
// The current rating of FTXUI.
|
||||
std::string rating = "3/5 stars";
|
||||
// Some actions modifying the state:
|
||||
auto show_modal = [&] { modal_shown = true; };
|
||||
auto hide_modal = [&] { modal_shown = false; };
|
||||
auto exit = screen.ExitLoopClosure();
|
||||
auto do_nothing = [&] {};
|
||||
|
||||
// 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());
|
||||
// Instanciate the main and modal components:
|
||||
auto main_component = MainComponent(show_modal, exit);
|
||||
auto modal_component = ModalComponent(do_nothing, hide_modal);
|
||||
|
||||
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;
|
||||
});
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
screen.Loop(main_component);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// 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.
|
||||
|
94
examples/component/modal_dialog_custom.cpp
Normal file
94
examples/component/modal_dialog_custom.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#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(int argc, const char* argv[]) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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.
|
@@ -25,7 +25,7 @@ std::string Stringify(Event event) {
|
||||
|
||||
out = "(" + out + " ) -> ";
|
||||
if (event.is_character()) {
|
||||
out += "character(" + event.character() + ")";
|
||||
out += "Event::Character(\"" + event.character() + "\")";
|
||||
} else if (event.is_mouse()) {
|
||||
out += "mouse";
|
||||
switch (event.mouse().button) {
|
||||
@@ -66,6 +66,68 @@ std::string Stringify(Event event) {
|
||||
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)";
|
||||
}
|
||||
@@ -84,7 +146,7 @@ int main(int argc, const char* argv[]) {
|
||||
return window(text("keys"), vbox(std::move(children)));
|
||||
});
|
||||
|
||||
component = CatchEvent(component, [&](Event event) {
|
||||
component |= CatchEvent([&](Event event) {
|
||||
keys.push_back(event);
|
||||
return true;
|
||||
});
|
||||
|
49
examples/component/slider_direction.cpp
Normal file
49
examples/component/slider_direction.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#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/elements.hpp> // for size, GREATER_THAN, GaugeDirection, GaugeDirection::Up, 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(int argc, const char* argv[]) {
|
||||
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 (int i = 0; i < values.size(); ++i) {
|
||||
// In C++17:
|
||||
SliderOption<int> option;
|
||||
option.value = &values[i];
|
||||
option.max = 100;
|
||||
option.increment = 5;
|
||||
option.direction = GaugeDirection::Up;
|
||||
layout_horizontal->Add(Slider<int>(option));
|
||||
|
||||
/* In C++20:
|
||||
layout_horizontal->Add(Slider<int>({
|
||||
.value = &values[i],
|
||||
.max = 100,
|
||||
.increment = 5,
|
||||
.direction = GaugeDirection::Up,
|
||||
}));
|
||||
*/
|
||||
}
|
||||
|
||||
layout_horizontal |= size(HEIGHT, GREATER_THAN, 20);
|
||||
|
||||
screen.Loop(layout_horizontal);
|
||||
}
|
||||
|
||||
// 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.
|
61
examples/component/with_restored_io.cpp
Normal file
61
examples/component/with_restored_io.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
// 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.
|
@@ -3,9 +3,15 @@ set(DIRECTORY_LIB dom)
|
||||
example(border)
|
||||
example(border_style)
|
||||
example(color_gallery)
|
||||
example(color_info_palette256)
|
||||
example(color_truecolor_HSV)
|
||||
example(color_truecolor_RGB)
|
||||
example(dbox)
|
||||
example(canvas)
|
||||
example(gauge)
|
||||
example(gauge_direction)
|
||||
example(graph)
|
||||
example(gridbox)
|
||||
example(hflow)
|
||||
example(html_like)
|
||||
example(package_manager)
|
||||
@@ -17,13 +23,13 @@ example(spinner)
|
||||
example(style_blink)
|
||||
example(style_bold)
|
||||
example(style_color)
|
||||
example(color_truecolor_RGB)
|
||||
example(color_truecolor_HSV)
|
||||
example(color_info_palette256)
|
||||
example(style_dim)
|
||||
example(gridbox)
|
||||
example(style_gallery)
|
||||
example(style_inverted)
|
||||
example(style_strikethrough)
|
||||
example(style_underlined)
|
||||
example(style_underlined_double)
|
||||
example(table)
|
||||
example(vbox_hbox)
|
||||
example(vflow)
|
||||
example(window)
|
||||
|
@@ -1,11 +1,12 @@
|
||||
#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/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int main() {
|
||||
using namespace ftxui;
|
||||
auto document = //
|
||||
hbox({
|
||||
@@ -30,6 +31,7 @@ int main(int argc, const char* argv[]) {
|
||||
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
|
||||
Render(screen, document);
|
||||
screen.Print();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
|
@@ -1,10 +1,10 @@
|
||||
#include <ftxui/dom/elements.hpp> // for text, operator|, vbox, border, Element, Fit, hbox
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <iostream>
|
||||
#include <memory> // for allocator
|
||||
#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/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
49
examples/dom/canvas.cpp
Normal file
49
examples/dom/canvas.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#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(int argc, const char* argv[]) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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.
|
@@ -5,13 +5,14 @@
|
||||
#include <utility> // for move
|
||||
#include <vector> // for vector
|
||||
|
||||
using namespace ftxui;
|
||||
#include "./color_info_sorted_2d.ipp" // for ColorInfoSorted2D
|
||||
#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
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
#include "./color_info_sorted_2d.ipp" // for ColorInfoSorted2D
|
||||
|
||||
int main() {
|
||||
// clang-format off
|
||||
auto basic_color_display =
|
||||
vbox(
|
||||
@@ -82,14 +83,18 @@ int main(int argc, const char* argv[]) {
|
||||
// True color display.
|
||||
auto true_color_display = text("TrueColors: 24bits:");
|
||||
{
|
||||
int saturation = 255;
|
||||
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 < 255; value += 16) {
|
||||
for (int value = 0; value < max_value; value += 2 * value_increment) {
|
||||
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)));
|
||||
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)));
|
||||
}
|
||||
|
@@ -5,8 +5,7 @@
|
||||
#include <vector> // for vector, allocator
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Palette256
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Palette256, ftxui
|
||||
|
||||
using namespace ftxui;
|
||||
#include "./color_info_sorted_2d.ipp" // for ColorInfoSorted2D
|
||||
|
@@ -1,12 +1,13 @@
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <ftxui/screen/color_info.hpp> // for ftxui::ColorInfo
|
||||
|
||||
std::vector<std::vector<ColorInfo>> ColorInfoSorted2D() {
|
||||
std::vector<std::vector<ftxui::ColorInfo>> ColorInfoSorted2D() {
|
||||
// Acquire the color information for the palette256.
|
||||
std::vector<ColorInfo> info_gray;
|
||||
std::vector<ColorInfo> info_color;
|
||||
std::vector<ftxui::ColorInfo> info_gray;
|
||||
std::vector<ftxui::ColorInfo> info_color;
|
||||
for (int i = 16; i < 256; ++i) {
|
||||
ColorInfo info = GetColorInfo(Color::Palette256(i));
|
||||
ftxui::ColorInfo info = GetColorInfo(ftxui::Color::Palette256(i));
|
||||
if (info.saturation == 0)
|
||||
info_gray.push_back(info);
|
||||
else
|
||||
@@ -16,10 +17,10 @@ std::vector<std::vector<ColorInfo>> ColorInfoSorted2D() {
|
||||
// Sort info_color by hue.
|
||||
std::sort(
|
||||
info_color.begin(), info_color.end(),
|
||||
[](const ColorInfo& A, const ColorInfo& B) { return A.hue < B.hue; });
|
||||
[](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<ColorInfo>> info_columns(8);
|
||||
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]);
|
||||
@@ -28,13 +29,13 @@ std::vector<std::vector<ColorInfo>> ColorInfoSorted2D() {
|
||||
// Minimize discontinuities for every columns.
|
||||
for (auto& column : info_columns) {
|
||||
std::sort(column.begin(), column.end(),
|
||||
[](const ColorInfo& A, const ColorInfo& B) {
|
||||
[](const ftxui::ColorInfo& A, const ftxui::ColorInfo& B) {
|
||||
return A.value < B.value;
|
||||
});
|
||||
for (size_t i = 0; i < column.size() - 1; ++i) {
|
||||
for (int i = 0; i < int(column.size()) - 1; ++i) {
|
||||
int best_index = i + 1;
|
||||
int best_distance = 255 * 255 * 3;
|
||||
for (size_t j = i + 1; j < column.size(); ++j) {
|
||||
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;
|
||||
|
@@ -4,8 +4,7 @@
|
||||
#include <utility> // for move
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/screen/color.hpp" // for Color
|
||||
#include "ftxui/screen/color.hpp" // for Color, ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
@@ -4,8 +4,7 @@
|
||||
#include <utility> // for move
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/screen/color.hpp" // for Color
|
||||
#include "ftxui/screen/color.hpp" // for Color, ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
@@ -2,8 +2,8 @@
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
@@ -2,11 +2,11 @@
|
||||
#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, operator+, char_traits, operator<<, string, to_string, basic_string
|
||||
#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/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
79
examples/dom/gauge_direction.cpp
Normal file
79
examples/dom/gauge_direction.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#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(int argc, const char* argv[]) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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.
|
@@ -1,28 +1,28 @@
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <ftxui/dom/elements.hpp>
|
||||
#include <ftxui/screen/screen.hpp>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#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"
|
||||
#include "ftxui/screen/box.hpp"
|
||||
#include "ftxui/screen/color.hpp"
|
||||
#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) {
|
||||
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);
|
||||
v += 0.2f * sin((i + shift + 10) * 0.15f);
|
||||
v += 0.1f * sin((i + shift) * 0.03f);
|
||||
v *= height;
|
||||
v += 0.5f * height;
|
||||
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;
|
||||
@@ -38,7 +38,7 @@ std::vector<int> triangle(int width, int height) {
|
||||
return output;
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int main() {
|
||||
using namespace ftxui;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
@@ -46,23 +46,26 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
std::string reset_position;
|
||||
for (int i = 0;; ++i) {
|
||||
auto document =
|
||||
hbox({
|
||||
vbox({
|
||||
graph(std::ref(my_graph)),
|
||||
separator(),
|
||||
graph(triangle) | inverted,
|
||||
}) | flex,
|
||||
auto document = hbox({
|
||||
vbox({
|
||||
graph(std::ref(my_graph)),
|
||||
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,
|
||||
}) |
|
||||
border | size(HEIGHT, GREATER_THAN, 40);
|
||||
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);
|
||||
@@ -70,7 +73,8 @@ int main(int argc, const char* argv[]) {
|
||||
screen.Print();
|
||||
reset_position = screen.ResetPosition();
|
||||
|
||||
std::this_thread::sleep_for(0.03s);
|
||||
const auto sleep_time = 0.03s;
|
||||
std::this_thread::sleep_for(sleep_time);
|
||||
my_graph.shift++;
|
||||
}
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
#include <stdio.h> // for getchar
|
||||
#include <ftxui/dom/elements.hpp> // for filler, text, hbox, vbox
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator
|
||||
#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/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
@@ -1,15 +1,14 @@
|
||||
#include <stddef.h> // for size_t
|
||||
#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 <memory> // for allocator, shared_ptr
|
||||
#include <string> // for operator+, to_string, char_traits, string
|
||||
#include <string> // for allocator, char_traits, operator+, to_string, string
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
auto make_box = [](size_t dimx, size_t dimy) {
|
||||
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) |
|
||||
@@ -44,6 +43,7 @@ int main(int argc, const char* argv[]) {
|
||||
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
|
||||
Render(screen, document);
|
||||
screen.Print();
|
||||
getchar();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,11 +1,10 @@
|
||||
#include <chrono> // for operator""s, chrono_literals
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <ftxui/screen/screen.hpp> // for Screen
|
||||
#include <iostream> // for cout, ostream
|
||||
#include <memory> // for allocator, shared_ptr
|
||||
#include <string> // for operator<<, string
|
||||
#include <string> // for allocator, operator<<, string
|
||||
#include <thread> // for sleep_for
|
||||
|
||||
#include "ftxui/dom/elements.hpp" // for paragraph, text, operator|, Element, border, color, hflow, spinner, vbox, bold, dim, underlined
|
||||
#include "ftxui/dom/elements.hpp" // for paragraph, text, operator|, Element, border, Fit, color, hflow, spinner, vbox, bold, dim, underlined
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Red
|
||||
@@ -44,7 +43,7 @@ int main(int argc, const char* argv[]) {
|
||||
paragraph(" A spinner "), spinner(6, i / 10)) |
|
||||
border;
|
||||
|
||||
auto screen = Screen::Create(Dimension::Full());
|
||||
auto screen = Screen::Create(Dimension::Fit(document));
|
||||
Render(screen, document);
|
||||
std::cout << reset_position;
|
||||
screen.Print();
|
||||
|
@@ -2,16 +2,15 @@
|
||||
#include <ftxui/dom/elements.hpp> // for operator|, text, Element, hbox, bold, color, filler, separator, vbox, window, gauge, Fit, size, dim, EQUAL, WIDTH
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <iostream> // for cout, endl, ostream
|
||||
#include <list> // for list, operator!=, _List_iterator, _List_iterator<>::_Self
|
||||
#include <list> // for list, operator==, _List_iterator, _List_iterator<>::_Self
|
||||
#include <memory> // for allocator, shared_ptr, allocator_traits<>::value_type
|
||||
#include <string> // for string, operator<<, to_string
|
||||
#include <thread> // for sleep_for
|
||||
#include <utility> // for move
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Green, Color::Red, Color::RedLight
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Green, Color::Red, Color::RedLight, ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
@@ -42,7 +41,7 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
int remaining_threads = 12;
|
||||
|
||||
int nb_queued = remaining_tasks.size();
|
||||
int nb_queued = (int)remaining_tasks.size();
|
||||
int nb_active = 0;
|
||||
int nb_done = 0;
|
||||
|
||||
|
@@ -1,35 +1,50 @@
|
||||
#include <stdio.h> // for getchar
|
||||
#include <ftxui/dom/elements.hpp> // for operator|, hflow, paragraph, border, Element, hbox, flex, vbox
|
||||
#include <chrono> // for operator""s, chrono_literals
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <string> // for allocator, string
|
||||
#include <iostream> // for cout, ostream
|
||||
#include <memory> // for allocator, shared_ptr
|
||||
#include <string> // for string, operator<<
|
||||
#include <thread> // for sleep_for
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/elements.hpp" // for hflow, paragraph, separator, hbox, vbox, filler, operator|, border, Element
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
std::string p =
|
||||
R"(In probability theory and statistics, Bayes' theorem (alternatively Bayes' law or Bayes' rule) describes the probability of an event, based on prior knowledge of conditions that might be related to the event. For example, if cancer is related to age, then, using Bayes' theorem, a person's age can be used to more accurately assess the probability that they have cancer, compared to the assessment of the probability of cancer made without knowledge of the person's age. One of the many applications of Bayes' theorem is Bayesian inference, a particular approach to statistical inference. When applied, the probabilities involved in Bayes' theorem may have different probability interpretations. With the Bayesian probability interpretation the theorem expresses how a subjective degree of belief should rationally change to account for availability of related evidence. Bayesian inference is fundamental to Bayesian statistics.)";
|
||||
|
||||
auto document = vbox({
|
||||
hbox({
|
||||
hflow(paragraph(p)) | border,
|
||||
hflow(paragraph(p)) | border,
|
||||
hflow(paragraph(p)) | border,
|
||||
}) | flex,
|
||||
hbox({
|
||||
hflow(paragraph(p)) | border,
|
||||
hflow(paragraph(p)) | border,
|
||||
}) | flex,
|
||||
hbox({
|
||||
hflow(paragraph(p)) | border,
|
||||
}) | flex,
|
||||
});
|
||||
std::string reset_position;
|
||||
for (int i = 0;; ++i) {
|
||||
auto document = vbox({
|
||||
hflow(paragraph(p)),
|
||||
separator(),
|
||||
hflow(paragraph(p)),
|
||||
separator(),
|
||||
hbox({
|
||||
hflow(paragraph(p)),
|
||||
separator(),
|
||||
hflow(paragraph(p)),
|
||||
}),
|
||||
}) |
|
||||
border;
|
||||
|
||||
auto screen = Screen::Create(Dimension::Full(), Dimension::Full());
|
||||
Render(screen, document);
|
||||
screen.Print();
|
||||
getchar();
|
||||
document = vbox(filler(), document);
|
||||
|
||||
// auto screen = Screen::Create(Dimension::Fit(document));
|
||||
// Render(screen, document);
|
||||
// screen.Print();
|
||||
// getchar();
|
||||
|
||||
auto screen = Screen::Create(Dimension::Full());
|
||||
Render(screen, document);
|
||||
std::cout << reset_position;
|
||||
screen.Print();
|
||||
reset_position = screen.ResetPosition();
|
||||
|
||||
std::this_thread::sleep_for(0.01s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -2,8 +2,8 @@
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
@@ -4,8 +4,8 @@
|
||||
#include <string> // for string, to_string
|
||||
#include <utility> // for move
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
@@ -7,8 +7,8 @@
|
||||
#include <utility> // for move
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
@@ -17,7 +17,7 @@ int main(int argc, const char* argv[]) {
|
||||
std::string reset_position;
|
||||
for (int index = 0; index < 200; ++index) {
|
||||
std::vector<Element> entries;
|
||||
for (int i = 0; i < 22; ++i) {
|
||||
for (int i = 0; i < 23; ++i) {
|
||||
if (i != 0)
|
||||
entries.push_back(separator());
|
||||
entries.push_back( //
|
||||
|
@@ -2,8 +2,8 @@
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
@@ -2,8 +2,8 @@
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
@@ -2,8 +2,8 @@
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
@@ -3,22 +3,23 @@
|
||||
#include <memory> // for allocator
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Blue
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
// clang-format off
|
||||
auto document =
|
||||
hbox({
|
||||
text("normal") , text(" ") ,
|
||||
text("bold") | bold , text(" ") ,
|
||||
text("dim") | dim , text(" ") ,
|
||||
text("inverted") | inverted , text(" ") ,
|
||||
text("underlined")| underlined , text(" ") ,
|
||||
text("blink") | blink , text(" ") ,
|
||||
text("color") | color(Color::Blue) , text(" ") ,
|
||||
text("bgcolor") | bgcolor(Color::Blue),
|
||||
text("normal") , text(" ") ,
|
||||
text("bold") | bold , text(" ") ,
|
||||
text("dim") | dim , text(" ") ,
|
||||
text("inverted") | inverted , text(" ") ,
|
||||
text("underlined") | underlined , text(" ") ,
|
||||
text("underlinedDouble") | underlinedDouble , text(" ") ,
|
||||
text("blink") | blink , text(" ") ,
|
||||
text("strikethrough") | strikethrough , text(" ") ,
|
||||
text("color") | color(Color::Blue) , text(" ") ,
|
||||
text("bgcolor") | bgcolor(Color::Blue) ,
|
||||
});
|
||||
// clang-format on
|
||||
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
|
||||
|
@@ -2,8 +2,8 @@
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
25
examples/dom/style_strikethrough.cpp
Normal file
25
examples/dom/style_strikethrough.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <ftxui/dom/elements.hpp> // for text, operator|, strikethrough, Fit, hbox, Element
|
||||
#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(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
auto document = //
|
||||
hbox({
|
||||
text("This text is "),
|
||||
text("strikethrough") | strikethrough,
|
||||
text(". Do you like it?"),
|
||||
});
|
||||
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
|
||||
Render(screen, document);
|
||||
screen.Print();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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.
|
@@ -2,8 +2,8 @@
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
25
examples/dom/style_underlined_double.cpp
Normal file
25
examples/dom/style_underlined_double.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <ftxui/dom/elements.hpp> // for text, operator|, underlinedDouble, Fit, hbox, Element
|
||||
#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(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
auto document = //
|
||||
hbox({
|
||||
text("This text is "),
|
||||
text("underlinedDouble") | underlinedDouble,
|
||||
text(". Do you like it?"),
|
||||
});
|
||||
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
|
||||
Render(screen, document);
|
||||
screen.Print();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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.
|
65
examples/dom/table.cpp
Normal file
65
examples/dom/table.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#include <ftxui/dom/elements.hpp> // for color, Fit, LIGHT, align_right, bold, DOUBLE
|
||||
#include <ftxui/dom/table.hpp> // for Table, TableSelection
|
||||
#include <ftxui/screen/screen.hpp> // for Screen
|
||||
#include <iostream> // for endl, cout, ostream
|
||||
#include <string> // for basic_string, allocator, string
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::Cyan, Color::White, ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
||||
auto table = Table({
|
||||
{"Version", "Marketing name", "Release date", "API level", "Runtime"},
|
||||
{"2.3", "Gingerbread", "February 9 2011", "10", "Dalvik 1.4.0"},
|
||||
{"4.0", "Ice Cream Sandwich", "October 19 2011", "15", "Dalvik"},
|
||||
{"4.1", "Jelly Bean", "July 9 2012", "16", "Dalvik"},
|
||||
{"4.2", "Jelly Bean", "November 13 2012", "17", "Dalvik"},
|
||||
{"4.3", "Jelly Bean", "July 24 2013", "18", "Dalvik"},
|
||||
{"4.4", "KitKat", "October 31 2013", "19", "Dalvik and ART"},
|
||||
{"5.0", "Lollipop", "November 3 2014", "21", "ART"},
|
||||
{"5.1", "Lollipop", "March 9 2015", "22", "ART"},
|
||||
{"6.0", "Marshmallow", "October 5 2015", "23", "ART"},
|
||||
{"7.0", "Nougat", "August 22 2016", "24", "ART"},
|
||||
{"7.1", "Nougat", "October 4 2016", "25", "ART"},
|
||||
{"8.0", "Oreo", "August 21 2017", "26", "ART"},
|
||||
{"8.1", "Oreo", "December 5 2017", "27", "ART"},
|
||||
{"9", "Pie", "August 6 2018", "28", "ART"},
|
||||
{"10", "10", "September 3 2019", "29", "ART"},
|
||||
{"11", "11", "September 8 2020", "30", "ART"},
|
||||
});
|
||||
|
||||
table.SelectAll().Border(LIGHT);
|
||||
|
||||
// Add border around the first column.
|
||||
table.SelectColumn(0).Border(LIGHT);
|
||||
|
||||
// Make first row bold with a double border.
|
||||
table.SelectRow(0).Decorate(bold);
|
||||
table.SelectRow(0).SeparatorVertical(LIGHT);
|
||||
table.SelectRow(0).Border(DOUBLE);
|
||||
|
||||
// Align right the "Release date" column.
|
||||
table.SelectColumn(2).DecorateCells(align_right);
|
||||
|
||||
// Select row from the second to the last.
|
||||
auto content = table.SelectRows(1, -1);
|
||||
// Alternate in between 3 colors.
|
||||
content.DecorateCellsAlternateRow(color(Color::Blue), 3, 0);
|
||||
content.DecorateCellsAlternateRow(color(Color::Cyan), 3, 1);
|
||||
content.DecorateCellsAlternateRow(color(Color::White), 3, 2);
|
||||
|
||||
auto document = table.Render();
|
||||
auto screen = Screen::Create(Dimension::Fit(document));
|
||||
Render(screen, document);
|
||||
screen.Print();
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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.
|
@@ -3,8 +3,8 @@
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
50
examples/dom/vflow.cpp
Normal file
50
examples/dom/vflow.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include <stdio.h> // for getchar
|
||||
#include <ftxui/dom/elements.hpp> // for operator|, Element, size, text, hcenter, Fit, vflow, window, EQUAL, bold, border, dim, HEIGHT, WIDTH
|
||||
#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(int argc, const char* argv[]) {
|
||||
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 document = vflow({
|
||||
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),
|
||||
}) |
|
||||
border;
|
||||
|
||||
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
|
||||
Render(screen, document);
|
||||
screen.Print();
|
||||
getchar();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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.
|
@@ -1,26 +1,32 @@
|
||||
#include <ftxui/dom/elements.hpp>
|
||||
#include <ftxui/screen/screen.hpp>
|
||||
#include <vector>
|
||||
#include <stdlib.h> // for EXIT_SUCCESS
|
||||
#include <ftxui/dom/elements.hpp> // for operator|=, Element, bgcolor, color, graph, border
|
||||
#include <ftxui/screen/screen.hpp> // for Fixed, Screen
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/dom/node.hpp"
|
||||
#include "ftxui/screen/box.hpp"
|
||||
#include "ftxui/screen/color.hpp"
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::DarkBlue, Color::Red, ftxui
|
||||
|
||||
int main(void) {
|
||||
int main() {
|
||||
using namespace ftxui;
|
||||
Element document = graph([](int x, int y) {
|
||||
std::vector<int> result(x, 0);
|
||||
for (int i{0}; i < x; ++i) {
|
||||
result[i] = ((3 * i) / 2) % y;
|
||||
}
|
||||
return result;
|
||||
}) |
|
||||
color(Color::Red) | border | color(Color::Green) |
|
||||
bgcolor(Color::DarkBlue);
|
||||
std::vector<int> result(x, 0);
|
||||
for (int i{0}; i < x; ++i) {
|
||||
result[i] = ((3 * i) / 2) % y;
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
auto screen = Screen::Create(Dimension::Fixed(80), Dimension::Fixed(10));
|
||||
document |= color(Color::Red);
|
||||
document |= bgcolor(Color::DarkBlue);
|
||||
document |= border;
|
||||
|
||||
const int width = 80;
|
||||
const int height = 10;
|
||||
auto screen =
|
||||
Screen::Create(Dimension::Fixed(width), Dimension::Fixed(height));
|
||||
Render(screen, document);
|
||||
screen.Print();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
|
@@ -2,8 +2,22 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>FTXUI examples WebAssembly</title>
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm@4.11.0/lib/xterm.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm@4.18.0/lib/xterm.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-webgl@0.11.4/lib/xterm-addon-webgl.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.5.0/lib/xterm-addon-fit.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@4.11.0/css/xterm.css"></link>
|
||||
<!--Add COOP/COEP via a ServiceWorker to use SharedArrayBuffer-->
|
||||
<script>
|
||||
if ("serviceWorker" in navigator && !window.crossOriginIsolated) {
|
||||
navigator.serviceWorker.register(new URL("./sw.js", location.href)).then(
|
||||
registration => {
|
||||
if (registration.active && !navigator.serviceWorker.controller) {
|
||||
window.location.reload();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script id="example_script"></script>
|
||||
@@ -43,12 +57,12 @@
|
||||
});
|
||||
|
||||
let stdin_buffer = [];
|
||||
let stdin = () => {
|
||||
const stdin = () => {
|
||||
return stdin_buffer.shift() || 0;
|
||||
}
|
||||
|
||||
stdout_buffer = [];
|
||||
let stdout = code => {
|
||||
let stdout_buffer = [];
|
||||
const stdout = code => {
|
||||
if (code == 0) {
|
||||
term.write(new Uint8Array(stdout_buffer));
|
||||
stdout_buffer = [];
|
||||
@@ -56,25 +70,62 @@
|
||||
stdout_buffer.push(code)
|
||||
}
|
||||
}
|
||||
let stderr = code => console.log(code);
|
||||
var term = new Terminal();
|
||||
term.open(document.querySelector('#terminal'));
|
||||
term.resize(140,43);
|
||||
let stderrbuffer = [];
|
||||
const stderr = code => {
|
||||
if (code == 0 || code == 10) {
|
||||
console.error(String.fromCodePoint(...stderrbuffer));
|
||||
stderrbuffer = [];
|
||||
} else {
|
||||
stderrbuffer.push(code)
|
||||
}
|
||||
}
|
||||
const term = new Terminal();
|
||||
const term_element = document.querySelector('#terminal');
|
||||
term.open(term_element);
|
||||
|
||||
const webgl_addon = new (WebglAddon.WebglAddon)();
|
||||
term.loadAddon(webgl_addon);
|
||||
|
||||
const onBinary = e => {
|
||||
for(c of e)
|
||||
stdin_buffer.push(c.charCodeAt(0));
|
||||
}
|
||||
term.onBinary(onBinary);
|
||||
term.onData(onBinary)
|
||||
term.resize(140,43);
|
||||
window.Module = {
|
||||
preRun: () => { FS.init(stdin, stdout, stderr); },
|
||||
preRun: () => {
|
||||
FS.init(stdin, stdout, stderr);
|
||||
},
|
||||
postRun: [],
|
||||
onRuntimeInitialized: () => {},
|
||||
onRuntimeInitialized: () => {
|
||||
if (window.Module._ftxui_on_resize == undefined)
|
||||
return;
|
||||
|
||||
const fit_addon = new (FitAddon.FitAddon)();
|
||||
term.loadAddon(fit_addon);
|
||||
fit_addon.fit();
|
||||
const resize_handler = () => {
|
||||
const {cols, rows} = fit_addon.proposeDimensions();
|
||||
term.resize(cols, rows);
|
||||
window.Module._ftxui_on_resize(cols, rows);
|
||||
};
|
||||
const resize_observer = new ResizeObserver(resize_handler);
|
||||
resize_observer.observe(term_element);
|
||||
resize_handler();
|
||||
|
||||
// Disable scrollbar
|
||||
term.write('\x1b[?47h')
|
||||
},
|
||||
};
|
||||
document.querySelector("#example_script").src = example + '.js';
|
||||
|
||||
const words = example.split('/')
|
||||
words[1] = "ftxui_example_" + words[1] + ".js"
|
||||
document.querySelector("#example_script").src = words.join('/');
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
body {
|
||||
background-color:#EEE;
|
||||
padding:20px;
|
||||
@@ -109,9 +160,11 @@
|
||||
}
|
||||
|
||||
#terminal {
|
||||
padding:10px;
|
||||
width:100%;
|
||||
height: 500px;
|
||||
height: calc(clamp(200px, 100vh - 300px, 900px));
|
||||
overflow: hidden;
|
||||
border:none;
|
||||
background-color:black;
|
||||
padding:auto;
|
||||
}
|
||||
|
||||
|
25
examples/sw.js
Normal file
25
examples/sw.js
Normal file
@@ -0,0 +1,25 @@
|
||||
// sw.js
|
||||
self.addEventListener("install", () => self.skipWaiting());
|
||||
self.addEventListener("activate", e => e.waitUntil(self.clients.claim()));
|
||||
self.addEventListener("fetch", e => {
|
||||
if (e.request.mode != 'navigate' &&
|
||||
!e.request.url.includes(".worker.js")) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.respondWith((async () => {
|
||||
const response = await fetch(e.request);
|
||||
|
||||
const newHeaders = new Headers(response.headers);
|
||||
newHeaders.set("Cross-Origin-Embedder-Policy", "require-corp");
|
||||
newHeaders.set("Cross-Origin-Opener-Policy", "same-origin");
|
||||
|
||||
const moddedResponse = new Response(response.body, {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: newHeaders,
|
||||
});
|
||||
|
||||
return moddedResponse;
|
||||
})());
|
||||
});
|
119
include/ftxui/component/animation.hpp
Normal file
119
include/ftxui/component/animation.hpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#ifndef FTXUI_ANIMATION_HPP
|
||||
#define FTXUI_ANIMATION_HPP
|
||||
|
||||
#include <chrono> // for milliseconds, duration, steady_clock, time_point
|
||||
#include <functional> // for function
|
||||
|
||||
#include "ftxui/component/event.hpp"
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
namespace animation {
|
||||
// Components who haven't completed their animation can call this function to
|
||||
// request a new frame to be drawn later.
|
||||
//
|
||||
// When there is no new events and no animations to complete, no new frame is
|
||||
// drawn.
|
||||
void RequestAnimationFrame();
|
||||
|
||||
using Clock = std::chrono::steady_clock;
|
||||
using TimePoint = std::chrono::time_point<Clock>;
|
||||
using Duration = std::chrono::duration<double>;
|
||||
|
||||
// Parameter of Component::OnAnimation(param).
|
||||
class Params {
|
||||
public:
|
||||
Params(Duration duration) : duration_(duration) {}
|
||||
|
||||
/// The duration this animation step represents.
|
||||
Duration duration() const { return duration_; }
|
||||
|
||||
private:
|
||||
Duration duration_;
|
||||
};
|
||||
|
||||
namespace easing {
|
||||
using Function = std::function<float(float)>;
|
||||
// Linear interpolation (no easing)
|
||||
float Linear(float p);
|
||||
|
||||
// Quadratic easing; p^2
|
||||
float QuadraticIn(float p);
|
||||
float QuadraticOut(float p);
|
||||
float QuadraticInOut(float p);
|
||||
|
||||
// Cubic easing; p^3
|
||||
float CubicIn(float p);
|
||||
float CubicOut(float p);
|
||||
float CubicInOut(float p);
|
||||
|
||||
// Quartic easing; p^4
|
||||
float QuarticIn(float p);
|
||||
float QuarticOut(float p);
|
||||
float QuarticInOut(float p);
|
||||
|
||||
// Quintic easing; p^5
|
||||
float QuinticIn(float p);
|
||||
float QuinticOut(float p);
|
||||
float QuinticInOut(float p);
|
||||
|
||||
// Sine wave easing; sin(p * PI/2)
|
||||
float SineIn(float p);
|
||||
float SineOut(float p);
|
||||
float SineInOut(float p);
|
||||
|
||||
// Circular easing; sqrt(1 - p^2)
|
||||
float CircularIn(float p);
|
||||
float CircularOut(float p);
|
||||
float CircularInOut(float p);
|
||||
|
||||
// Exponential easing, base 2
|
||||
float ExponentialIn(float p);
|
||||
float ExponentialOut(float p);
|
||||
float ExponentialInOut(float p);
|
||||
|
||||
// Exponentially-damped sine wave easing
|
||||
float ElasticIn(float p);
|
||||
float ElasticOut(float p);
|
||||
float ElasticInOut(float p);
|
||||
|
||||
// Overshooting cubic easing;
|
||||
float BackIn(float p);
|
||||
float BackOut(float p);
|
||||
float BackInOut(float p);
|
||||
|
||||
// Exponentially-decaying bounce easing
|
||||
float BounceIn(float p);
|
||||
float BounceOut(float p);
|
||||
float BounceInOut(float p);
|
||||
} // namespace easing
|
||||
|
||||
class Animator {
|
||||
public:
|
||||
Animator(float* from,
|
||||
float to = 0.f,
|
||||
Duration duration = std::chrono::milliseconds(250),
|
||||
easing::Function easing_function = easing::Linear,
|
||||
Duration delay = std::chrono::milliseconds(0));
|
||||
|
||||
void OnAnimation(Params&);
|
||||
|
||||
float to() const { return to_; }
|
||||
|
||||
private:
|
||||
float* value_;
|
||||
float from_;
|
||||
float to_;
|
||||
Duration duration_;
|
||||
easing::Function easing_function_;
|
||||
Duration current_;
|
||||
};
|
||||
|
||||
} // namespace animation
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* end of include guard: FTXUI_ANIMATION_HPP */
|
||||
|
||||
// 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.
|
@@ -4,12 +4,13 @@
|
||||
#include <functional> // for function
|
||||
#include <memory> // for make_shared, shared_ptr
|
||||
#include <string> // for wstring
|
||||
#include <utility> // for forward
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/component/component_base.hpp" // for Component, Components
|
||||
#include "ftxui/component/component_options.hpp" // for ButtonOption, CheckboxOption, InputOption, MenuOption, RadioboxOption, ToggleOption
|
||||
#include "ftxui/dom/elements.hpp" // for Element
|
||||
#include "ftxui/util/ref.hpp" // for Ref, ConstStringRef, ConstStringListRef, StringRef
|
||||
#include "ftxui/component/component_base.hpp" // for Component, Components
|
||||
#include "ftxui/component/component_options.hpp" // for ButtonOption, CheckboxOption, MenuOption
|
||||
#include "ftxui/dom/elements.hpp" // for Element
|
||||
#include "ftxui/util/ref.hpp" // for ConstRef, Ref, ConstStringRef, ConstStringListRef, StringRef
|
||||
|
||||
namespace ftxui {
|
||||
struct ButtonOption;
|
||||
@@ -18,45 +19,20 @@ struct Event;
|
||||
struct InputOption;
|
||||
struct MenuOption;
|
||||
struct RadioboxOption;
|
||||
struct ToggleOption;
|
||||
struct MenuEntryOption;
|
||||
|
||||
template <class T, class... Args>
|
||||
std::shared_ptr<T> Make(Args&&... args) {
|
||||
return std::make_shared<T>(args...);
|
||||
return std::make_shared<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
Component Button(ConstStringRef label,
|
||||
std::function<void()> on_click,
|
||||
Ref<ButtonOption> = {});
|
||||
Component Checkbox(ConstStringRef label,
|
||||
bool* checked,
|
||||
Ref<CheckboxOption> option = {});
|
||||
Component Input(StringRef content,
|
||||
ConstStringRef placeholder,
|
||||
Ref<InputOption> option = {});
|
||||
Component Menu(ConstStringListRef entries,
|
||||
int* selected_,
|
||||
Ref<MenuOption> = {});
|
||||
Component MenuEntry(ConstStringRef label, Ref<MenuEntryOption> = {});
|
||||
Component Dropdown(ConstStringListRef entries, int* selected);
|
||||
Component Radiobox(ConstStringListRef entries,
|
||||
int* selected_,
|
||||
Ref<RadioboxOption> option = {});
|
||||
Component Toggle(ConstStringListRef entries,
|
||||
int* selected,
|
||||
Ref<ToggleOption> option = {});
|
||||
template <class T> // T = {int, float, long}
|
||||
Component Slider(ConstStringRef label, T* value, T min, T max, T increment);
|
||||
Component ResizableSplitLeft(Component main, Component back, int* main_size);
|
||||
Component ResizableSplitRight(Component main, Component back, int* main_size);
|
||||
Component ResizableSplitTop(Component main, Component back, int* main_size);
|
||||
Component ResizableSplitBottom(Component main, Component back, int* main_size);
|
||||
Component Renderer(Component child, std::function<Element()>);
|
||||
Component Renderer(std::function<Element()>);
|
||||
Component Renderer(std::function<Element(bool /* focused */)>);
|
||||
Component CatchEvent(Component child, std::function<bool(Event)>);
|
||||
Component Maybe(Component, bool* show);
|
||||
// Pipe operator to decorate components.
|
||||
using ComponentDecorator = std::function<Component(Component)>;
|
||||
using ElementDecorator = std::function<Element(Element)>;
|
||||
Component operator|(Component component, ComponentDecorator decorator);
|
||||
Component operator|(Component component, ElementDecorator decorator);
|
||||
Component& operator|=(Component& component, ComponentDecorator decorator);
|
||||
Component& operator|=(Component& component, ElementDecorator decorator);
|
||||
|
||||
namespace Container {
|
||||
Component Vertical(Components children);
|
||||
@@ -67,10 +43,88 @@ Component Tab(Components children, int* selector);
|
||||
|
||||
} // namespace Container
|
||||
|
||||
} // namespace ftxui
|
||||
Component Button(ConstStringRef label,
|
||||
std::function<void()> on_click,
|
||||
Ref<ButtonOption> = ButtonOption::Simple());
|
||||
|
||||
// Include component using the old deprecated wstring.
|
||||
#include "ftxui/component/deprecated.hpp"
|
||||
Component Checkbox(ConstStringRef label,
|
||||
bool* checked,
|
||||
Ref<CheckboxOption> option = CheckboxOption::Simple());
|
||||
|
||||
Component Input(StringRef content,
|
||||
ConstStringRef placeholder,
|
||||
Ref<InputOption> option = {});
|
||||
|
||||
Component Menu(ConstStringListRef entries,
|
||||
int* selected_,
|
||||
Ref<MenuOption> = MenuOption::Vertical());
|
||||
Component MenuEntry(ConstStringRef label, Ref<MenuEntryOption> = {});
|
||||
|
||||
Component Dropdown(ConstStringListRef entries, int* selected);
|
||||
|
||||
Component Radiobox(ConstStringListRef entries,
|
||||
int* selected_,
|
||||
Ref<RadioboxOption> option = {});
|
||||
Component Toggle(ConstStringListRef entries, int* selected);
|
||||
|
||||
// General slider constructor:
|
||||
template <typename T>
|
||||
Component Slider(SliderOption<T> options = {});
|
||||
|
||||
// Shorthand without the `SliderOption` constructor:
|
||||
Component Slider(ConstStringRef label,
|
||||
Ref<int> value,
|
||||
ConstRef<int> min = 0,
|
||||
ConstRef<int> max = 100,
|
||||
ConstRef<int> increment = 5);
|
||||
Component Slider(ConstStringRef label,
|
||||
Ref<float> value,
|
||||
ConstRef<float> min = 0.f,
|
||||
ConstRef<float> max = 100.f,
|
||||
ConstRef<float> increment = 5.f);
|
||||
Component Slider(ConstStringRef label,
|
||||
Ref<long> value,
|
||||
ConstRef<long> min = 0l,
|
||||
ConstRef<long> max = 100l,
|
||||
ConstRef<long> increment = 5l);
|
||||
|
||||
Component ResizableSplitLeft(Component main, Component back, int* main_size);
|
||||
Component ResizableSplitRight(Component main, Component back, int* main_size);
|
||||
Component ResizableSplitTop(Component main, Component back, int* main_size);
|
||||
Component ResizableSplitBottom(Component main, Component back, int* main_size);
|
||||
|
||||
Component Renderer(Component child, std::function<Element()>);
|
||||
Component Renderer(std::function<Element()>);
|
||||
Component Renderer(std::function<Element(bool /* focused */)>);
|
||||
ComponentDecorator Renderer(ElementDecorator);
|
||||
|
||||
Component CatchEvent(Component child, std::function<bool(Event)>);
|
||||
ComponentDecorator CatchEvent(std::function<bool(Event)> on_event);
|
||||
|
||||
Component Maybe(Component, const bool* show);
|
||||
Component Maybe(Component, std::function<bool()>);
|
||||
ComponentDecorator Maybe(const bool* show);
|
||||
ComponentDecorator Maybe(std::function<bool()>);
|
||||
|
||||
Component Modal(Component main, Component modal, const bool* show_modal);
|
||||
ComponentDecorator Modal(Component modal, const bool* show_modal);
|
||||
|
||||
Component Collapsible(ConstStringRef label,
|
||||
Component child,
|
||||
Ref<bool> show = false);
|
||||
|
||||
Component Hoverable(Component component, bool* hover);
|
||||
Component Hoverable(Component component,
|
||||
std::function<void()> on_enter,
|
||||
std::function<void()> on_leave);
|
||||
Component Hoverable(Component component, //
|
||||
std::function<void(bool)> on_change);
|
||||
ComponentDecorator Hoverable(bool* hover);
|
||||
ComponentDecorator Hoverable(std::function<void()> on_enter,
|
||||
std::function<void()> on_leave);
|
||||
ComponentDecorator Hoverable(std::function<void(bool)> on_change);
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* end of include guard: FTXUI_COMPONENT_HPP */
|
||||
|
||||
|
@@ -13,6 +13,10 @@ class Delegate;
|
||||
class Focus;
|
||||
struct Event;
|
||||
|
||||
namespace animation {
|
||||
class Params;
|
||||
} // namespace animation
|
||||
|
||||
class ComponentBase;
|
||||
using Component = std::shared_ptr<ComponentBase>;
|
||||
using Components = std::vector<Component>;
|
||||
@@ -42,6 +46,9 @@ class ComponentBase {
|
||||
// Returns whether the event was handled or not.
|
||||
virtual bool OnEvent(Event);
|
||||
|
||||
// Handle an animation step.
|
||||
virtual void OnAnimation(animation::Params& params);
|
||||
|
||||
// Focus management ----------------------------------------------------------
|
||||
//
|
||||
// If this component contains children, this indicates which one is active,
|
||||
|
@@ -1,58 +1,136 @@
|
||||
#ifndef FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP
|
||||
#define FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP
|
||||
|
||||
#include <ftxui/dom/elements.hpp>
|
||||
#include <ftxui/util/ref.hpp>
|
||||
#include <chrono> // for milliseconds
|
||||
#include <ftxui/component/animation.hpp> // for Duration, QuadraticInOut, Function
|
||||
#include <ftxui/dom/elements.hpp> // for Element, GaugeDirection, GaugeDirection::Right
|
||||
#include <ftxui/util/ref.hpp> // for Ref, ConstRef
|
||||
#include <functional> // for function
|
||||
#include <optional> // for optional
|
||||
#include <string> // for string
|
||||
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::GrayDark, Color::White
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
/// @brief Option for the Menu component.
|
||||
/// @brief arguments for |ButtonOption::transform|, |CheckboxOption::transform|,
|
||||
/// |Radiobox::transform|, |MenuEntryOption::transform|,
|
||||
/// |MenuOption::transform|.
|
||||
struct EntryState {
|
||||
std::string label; /// < The label to display.
|
||||
bool state; /// < The state of the button/checkbox/radiobox
|
||||
bool active; /// < Whether the entry is the active one.
|
||||
bool focused; /// < Whether the entry is one focused by the user.
|
||||
};
|
||||
|
||||
struct UnderlineOption {
|
||||
bool enabled = false;
|
||||
|
||||
Color color_active = Color::White;
|
||||
Color color_inactive = Color::GrayDark;
|
||||
|
||||
animation::easing::Function leader_function =
|
||||
animation::easing::QuadraticInOut;
|
||||
animation::easing::Function follower_function =
|
||||
animation::easing::QuadraticInOut;
|
||||
|
||||
animation::Duration leader_duration = std::chrono::milliseconds(250);
|
||||
animation::Duration leader_delay = std::chrono::milliseconds(0);
|
||||
animation::Duration follower_duration = std::chrono::milliseconds(250);
|
||||
animation::Duration follower_delay = std::chrono::milliseconds(0);
|
||||
|
||||
void SetAnimation(animation::Duration d, animation::easing::Function f);
|
||||
void SetAnimationDuration(animation::Duration d);
|
||||
void SetAnimationFunction(animation::easing::Function f);
|
||||
void SetAnimationFunction(animation::easing::Function f_leader,
|
||||
animation::easing::Function f_follower);
|
||||
};
|
||||
|
||||
/// @brief Option about a potentially animated color.
|
||||
/// @ingroup component
|
||||
struct MenuOption {
|
||||
Decorator style_normal = nothing; ///< style.
|
||||
Decorator style_focused = inverted; ///< Style when focused.
|
||||
Decorator style_selected = bold; ///< Style when selected.
|
||||
Decorator style_selected_focused =
|
||||
Decorator(inverted) | bold; ///< Style when selected and focused.
|
||||
struct AnimatedColorOption {
|
||||
void Set(
|
||||
Color inactive,
|
||||
Color active,
|
||||
animation::Duration duration = std::chrono::milliseconds(250),
|
||||
animation::easing::Function function = animation::easing::QuadraticInOut);
|
||||
|
||||
/// Called when the selected entry changes.
|
||||
std::function<void()> on_change = [] {};
|
||||
/// Called when the user presses enter.
|
||||
std::function<void()> on_enter = [] {};
|
||||
bool enabled = false;
|
||||
Color inactive;
|
||||
Color active;
|
||||
animation::Duration duration = std::chrono::milliseconds(250);
|
||||
animation::easing::Function function = animation::easing::QuadraticInOut;
|
||||
};
|
||||
|
||||
Ref<int> focused_entry = 0;
|
||||
struct AnimatedColorsOption {
|
||||
AnimatedColorOption background;
|
||||
AnimatedColorOption foreground;
|
||||
};
|
||||
|
||||
/// @brief Option for the MenuEntry component.
|
||||
/// @ingroup component
|
||||
struct MenuEntryOption {
|
||||
Decorator style_normal = nothing; ///< style.
|
||||
Decorator style_focused = inverted; ///< Style when focused.
|
||||
Decorator style_selected = bold; ///< Style when selected.
|
||||
Decorator style_selected_focused =
|
||||
Decorator(inverted) | bold; ///< Style when selected and focused.
|
||||
std::function<Element(const EntryState& state)> transform;
|
||||
AnimatedColorsOption animated_colors;
|
||||
};
|
||||
|
||||
/// @brief Option for the Button component.
|
||||
/// @brief Option for the Menu component.
|
||||
/// @ingroup component
|
||||
struct MenuOption {
|
||||
// Standard constructors:
|
||||
static MenuOption Horizontal();
|
||||
static MenuOption HorizontalAnimated();
|
||||
static MenuOption Vertical();
|
||||
static MenuOption VerticalAnimated();
|
||||
static MenuOption Toggle();
|
||||
|
||||
// Style:
|
||||
UnderlineOption underline;
|
||||
MenuEntryOption entries;
|
||||
enum Direction { Up, Down, Left, Right };
|
||||
Direction direction = Down;
|
||||
std::function<Element()> elements_prefix;
|
||||
std::function<Element()> elements_infix;
|
||||
std::function<Element()> elements_postfix;
|
||||
|
||||
// Observers:
|
||||
std::function<void()> on_change; ///> Called when the selected entry changes.
|
||||
std::function<void()> on_enter; ///> Called when the user presses enter.
|
||||
Ref<int> focused_entry = 0;
|
||||
};
|
||||
|
||||
/// @brief Option for the AnimatedButton component.
|
||||
/// @ingroup component
|
||||
struct ButtonOption {
|
||||
/// Whether to show a border around the button.
|
||||
bool border = true;
|
||||
// Standard constructors:
|
||||
static ButtonOption Ascii();
|
||||
static ButtonOption Simple();
|
||||
static ButtonOption Border();
|
||||
static ButtonOption Animated();
|
||||
static ButtonOption Animated(Color color);
|
||||
static ButtonOption Animated(Color background, Color foreground);
|
||||
static ButtonOption Animated(Color background,
|
||||
Color foreground,
|
||||
Color background_active,
|
||||
Color foreground_active);
|
||||
|
||||
// Style:
|
||||
std::function<Element(const EntryState&)> transform;
|
||||
AnimatedColorsOption animated_colors;
|
||||
};
|
||||
|
||||
/// @brief Option for the Checkbox component.
|
||||
/// @ingroup component
|
||||
struct CheckboxOption {
|
||||
std::string style_checked = "▣ "; ///< Prefix for a "checked" state.
|
||||
std::string style_unchecked = "☐ "; ///< Prefix for a "unchecked" state.
|
||||
Decorator style_normal = nothing; ///< style.
|
||||
Decorator style_focused = inverted; ///< Style when focused.
|
||||
Decorator style_selected = bold; ///< Style when selected.
|
||||
Decorator style_selected_focused =
|
||||
Decorator(inverted) | bold; ///< Style when selected and focused.
|
||||
// Standard constructors:
|
||||
static CheckboxOption Simple();
|
||||
|
||||
// Style:
|
||||
std::function<Element(const EntryState&)> transform;
|
||||
|
||||
// Observer:
|
||||
/// Called when the user change the state.
|
||||
std::function<void()> on_change = []() {};
|
||||
std::function<void()> on_change = [] {};
|
||||
};
|
||||
|
||||
/// @brief Option for the Input component.
|
||||
@@ -74,35 +152,29 @@ struct InputOption {
|
||||
/// @brief Option for the Radiobox component.
|
||||
/// @ingroup component
|
||||
struct RadioboxOption {
|
||||
std::string style_checked = "◉ "; ///< Prefix for a "checked" state.
|
||||
std::string style_unchecked = "○ "; ///< Prefix for a "unchecked" state.
|
||||
Decorator style_normal = nothing; ///< style.
|
||||
Decorator style_focused = inverted; ///< Style when focused.
|
||||
Decorator style_selected = bold; ///< Style when selected.
|
||||
Decorator style_selected_focused =
|
||||
Decorator(inverted) | bold; ///< Style when selected and focused.
|
||||
// Standard constructors:
|
||||
static RadioboxOption Simple();
|
||||
|
||||
// Style:
|
||||
std::function<Element(const EntryState&)> transform;
|
||||
|
||||
// Observers:
|
||||
/// Called when the selected entry changes.
|
||||
std::function<void()> on_change = []() {};
|
||||
|
||||
std::function<void()> on_change = [] {};
|
||||
Ref<int> focused_entry = 0;
|
||||
};
|
||||
|
||||
/// @brief Option for the Toggle component.
|
||||
/// @ingroup component
|
||||
struct ToggleOption {
|
||||
Decorator style_normal = nothing; ///< style.
|
||||
Decorator style_focused = inverted; ///< Style when focused.
|
||||
Decorator style_selected = bold; ///< Style when selected.
|
||||
Decorator style_selected_focused =
|
||||
Decorator(inverted) | bold; ///< Style when selected and focused.
|
||||
|
||||
/// Called when the selected entry changes.
|
||||
std::function<void()> on_change = [] {};
|
||||
/// Called when the user presses enter.
|
||||
std::function<void()> on_enter = [] {};
|
||||
|
||||
Ref<int> focused_entry = 0;
|
||||
// @brief Option for the `Slider` component.
|
||||
// @ingroup component
|
||||
template <typename T>
|
||||
struct SliderOption {
|
||||
Ref<T> value;
|
||||
ConstRef<T> min = T(0);
|
||||
ConstRef<T> max = T(100);
|
||||
ConstRef<T> increment = (max() - min()) / 20;
|
||||
GaugeDirection direction = GaugeDirection::Right;
|
||||
Color color_active = Color::White;
|
||||
Color color_inactive = Color::GrayDark;
|
||||
};
|
||||
|
||||
} // namespace ftxui
|
||||
|
@@ -1,17 +0,0 @@
|
||||
#ifndef FTXUI_COMPONENT_DEPRECATED_HPP
|
||||
#define FTXUI_COMPONENT_DEPRECATED_HPP
|
||||
|
||||
#include "ftxui/component/component.hpp"
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
Component Input(WideStringRef content,
|
||||
ConstStringRef placeholder,
|
||||
Ref<InputOption> option = {});
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* FTXUI_COMPONENT_DEPRECATED_HPP */
|
||||
|
||||
// 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.
|
@@ -2,7 +2,8 @@
|
||||
#define FTXUI_COMPONENT_EVENT_HPP
|
||||
|
||||
#include <ftxui/component/mouse.hpp> // for Mouse
|
||||
#include <string> // for string, operator==
|
||||
#include <functional>
|
||||
#include <string> // for string, operator==
|
||||
#include <vector>
|
||||
|
||||
namespace ftxui {
|
||||
@@ -37,6 +38,11 @@ struct Event {
|
||||
static const Event ArrowUp;
|
||||
static const Event ArrowDown;
|
||||
|
||||
static const Event ArrowLeftCtrl;
|
||||
static const Event ArrowRightCtrl;
|
||||
static const Event ArrowUpCtrl;
|
||||
static const Event ArrowDownCtrl;
|
||||
|
||||
// --- Other ---
|
||||
static const Event Backspace;
|
||||
static const Event Delete;
|
||||
@@ -53,16 +59,14 @@ struct Event {
|
||||
static const Event PageDown;
|
||||
|
||||
// --- Custom ---
|
||||
static Event Custom;
|
||||
static const Event Custom;
|
||||
|
||||
//--- Method section ---------------------------------------------------------
|
||||
bool is_character() const { return type_ == Type::Character; }
|
||||
std::string character() const { return input_; }
|
||||
|
||||
bool is_mouse() const { return type_ == Type::Mouse; }
|
||||
struct Mouse& mouse() {
|
||||
return mouse_;
|
||||
}
|
||||
struct Mouse& mouse() { return mouse_; }
|
||||
|
||||
bool is_cursor_reporting() const { return type_ == Type::CursorReporting; }
|
||||
int cursor_x() const { return cursor_.x; }
|
||||
@@ -75,6 +79,7 @@ struct Event {
|
||||
|
||||
//--- State section ----------------------------------------------------------
|
||||
ScreenInteractive* screen_ = nullptr;
|
||||
|
||||
private:
|
||||
friend ComponentBase;
|
||||
friend ScreenInteractive;
|
||||
|
39
include/ftxui/component/loop.hpp
Normal file
39
include/ftxui/component/loop.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef FTXUI_COMPONENT_LOOP_HPP
|
||||
#define FTXUI_COMPONENT_LOOP_HPP
|
||||
|
||||
#include <memory> // for shared_ptr
|
||||
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
|
||||
namespace ftxui {
|
||||
class ComponentBase;
|
||||
|
||||
using Component = std::shared_ptr<ComponentBase>;
|
||||
class ScreenInteractive;
|
||||
|
||||
class Loop {
|
||||
public:
|
||||
Loop(ScreenInteractive* screen, Component component);
|
||||
~Loop();
|
||||
|
||||
bool HasQuitted();
|
||||
void RunOnce();
|
||||
void RunOnceBlocking();
|
||||
void Run();
|
||||
|
||||
private:
|
||||
// This class is non copyable.
|
||||
Loop(const ScreenInteractive&) = delete;
|
||||
Loop& operator=(const Loop&) = delete;
|
||||
|
||||
ScreenInteractive* screen_;
|
||||
Component component_;
|
||||
};
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
#endif // FTXUI_COMPONENT_LOOP_HPP
|
||||
|
||||
// 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.
|
@@ -86,11 +86,25 @@ class ReceiverImpl {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReceiveNonBlocking(T* t) {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
if (queue_.empty())
|
||||
return false;
|
||||
*t = queue_.front();
|
||||
queue_.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HasPending() {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
return !queue_.empty();
|
||||
}
|
||||
|
||||
bool HasQuitted() {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
return queue_.empty() && !senders_;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class SenderImpl<T>;
|
||||
|
||||
|
@@ -7,39 +7,70 @@
|
||||
#include <memory> // for shared_ptr
|
||||
#include <string> // for string
|
||||
#include <thread> // for thread
|
||||
#include <variant> // for variant
|
||||
|
||||
#include "ftxui/component/animation.hpp" // for TimePoint
|
||||
#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse
|
||||
#include "ftxui/component/event.hpp" // for Event
|
||||
#include "ftxui/component/task.hpp" // for Task, Closure
|
||||
#include "ftxui/screen/screen.hpp" // for Screen
|
||||
|
||||
namespace ftxui {
|
||||
class ComponentBase;
|
||||
class Loop;
|
||||
struct Event;
|
||||
|
||||
using Component = std::shared_ptr<ComponentBase>;
|
||||
class ScreenInteractivePrivate;
|
||||
|
||||
class ScreenInteractive : public Screen {
|
||||
public:
|
||||
// Constructors:
|
||||
static ScreenInteractive FixedSize(int dimx, int dimy);
|
||||
static ScreenInteractive Fullscreen();
|
||||
static ScreenInteractive FitComponent();
|
||||
static ScreenInteractive TerminalOutput();
|
||||
|
||||
void Loop(Component);
|
||||
std::function<void()> ExitLoopClosure();
|
||||
// Return the currently active screen, nullptr if none.
|
||||
static ScreenInteractive* Active();
|
||||
|
||||
// Start/Stop the main loop.
|
||||
void Loop(Component);
|
||||
void Exit();
|
||||
Closure ExitLoopClosure();
|
||||
|
||||
// Post tasks to be executed by the loop.
|
||||
void Post(Task task);
|
||||
void PostEvent(Event event);
|
||||
void RequestAnimationFrame();
|
||||
|
||||
CapturedMouse CaptureMouse();
|
||||
|
||||
// Decorate a function. The outputted one will execute similarly to the
|
||||
// inputted one, but with the currently active screen terminal hooks
|
||||
// temporarily uninstalled.
|
||||
Closure WithRestoredIO(Closure);
|
||||
|
||||
private:
|
||||
void ExitNow();
|
||||
|
||||
void Install();
|
||||
void Uninstall();
|
||||
void Main(Component component);
|
||||
ScreenInteractive* suspended_screen_ = nullptr;
|
||||
|
||||
void PreMain();
|
||||
void PostMain();
|
||||
|
||||
bool HasQuitted();
|
||||
void RunOnce(Component component);
|
||||
void RunOnceBlocking(Component component);
|
||||
|
||||
void HandleTask(Component component, Task& task);
|
||||
void Draw(Component component);
|
||||
void EventLoop(Component component);
|
||||
void ResetCursorPosition();
|
||||
|
||||
void Signal(int signal);
|
||||
|
||||
ScreenInteractive* suspended_screen_ = nullptr;
|
||||
enum class Dimension {
|
||||
FitComponent,
|
||||
Fixed,
|
||||
@@ -53,19 +84,34 @@ class ScreenInteractive : public Screen {
|
||||
Dimension dimension,
|
||||
bool use_alternative_screen);
|
||||
|
||||
Sender<Event> event_sender_;
|
||||
Receiver<Event> event_receiver_;
|
||||
Sender<Task> task_sender_;
|
||||
Receiver<Task> task_receiver_;
|
||||
|
||||
std::string set_cursor_position;
|
||||
std::string reset_cursor_position;
|
||||
|
||||
std::atomic<bool> quit_ = false;
|
||||
std::thread event_listener_;
|
||||
std::thread animation_listener_;
|
||||
bool animation_requested_ = false;
|
||||
animation::TimePoint previous_animation_time_;
|
||||
|
||||
int cursor_x_ = 1;
|
||||
int cursor_y_ = 1;
|
||||
|
||||
bool mouse_captured = false;
|
||||
bool previous_frame_resized_ = false;
|
||||
|
||||
bool frame_valid_ = false;
|
||||
|
||||
friend class Loop;
|
||||
|
||||
public:
|
||||
class Private {
|
||||
public:
|
||||
static void Signal(ScreenInteractive& s, int signal) { s.Signal(signal); }
|
||||
};
|
||||
friend Private;
|
||||
};
|
||||
|
||||
} // namespace ftxui
|
||||
|
18
include/ftxui/component/task.hpp
Normal file
18
include/ftxui/component/task.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef FTXUI_COMPONENT_ANIMATION_HPP
|
||||
#define FTXUI_COMPONENT_ANIMATION_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <variant>
|
||||
#include "ftxui/component/event.hpp"
|
||||
|
||||
namespace ftxui {
|
||||
class AnimationTask {};
|
||||
using Closure = std::function<void()>;
|
||||
using Task = std::variant<Event, Closure, AnimationTask>;
|
||||
} // namespace ftxui
|
||||
|
||||
#endif // FTXUI_COMPONENT_ANIMATION_HPP
|
||||
|
||||
// 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.
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user