89 Commits

Author SHA1 Message Date
Arthur Sonzogni
c033ca61ae Remove NXXM. Execute IWYU. (#397) 2022-05-08 08:44:38 +02:00
Arthur Sonzogni
a6e04b4346 Table: reset dimensions. (#396)
The table is not meant to be used to render more than once. Reset the
dimensions so that, even if it is used wrongly, this is not memory
unsafe.

This was raised by:
https://github.com/ArthurSonzogni/FTXUI/issues/381
2022-05-08 08:34:51 +02:00
SColibri
09a2c077eb windows.h defines DrawText and shadows the function Canvas.DrawText, fix based on the solution #70 (#394)
Co-authored-by: Sebastian Carrion Ständer <sebastian.carrion@tum.de>
2022-05-04 23:39:03 +02:00
ArthurSonzogni
bc206f85da Fix compilation error on Windows for Color::Print 2022-05-02 20:50:15 +02:00
ArthurSonzogni
e9772a0116 Update gcov options. 2022-04-28 11:32:30 +02:00
ArthurSonzogni
e4c5c7b43b Fix ButtonTest.Animate 2022-04-28 11:03:39 +02:00
ArthurSonzogni
c2e1920449 Execute IWYU. 2022-04-28 10:43:31 +02:00
ArthurSonzogni
3d56146447 Add test coverage for button, collapsible and menu. 2022-04-28 10:08:33 +02:00
ArthurSonzogni
c33e805a76 Add coverage for menu and resizable_split. 2022-04-27 23:00:29 +02:00
ArthurSonzogni
d0890f94d1 execute IWYU and add some coverage tests. 2022-04-27 18:57:48 +02:00
ArthurSonzogni
84d6e6b3dd Add additional coverage tests. 2022-04-27 14:00:46 +02:00
ArthurSonzogni
001dd0a8c3 Exclude tests from coverage. 2022-04-27 13:25:43 +02:00
ArthurSonzogni
114cbfcffd Add coverage and remove deprecated WideInput. 2022-04-27 11:33:42 +02:00
ArthurSonzogni
5ba301d316 Add coverage for terminal_input_parser. 2022-04-27 11:11:32 +02:00
Arthur Sonzogni
06ed8567b8 Add coverage for colors (extended) (#385) 2022-04-27 09:28:48 +02:00
Arthur Sonzogni
04b36df567 Coverage decorator (#384)
Add code coverage for colors and decorators.
2022-04-26 17:04:34 +02:00
Arthur Sonzogni
764c24ef40 Add code coverage support. (#378) 2022-04-17 15:47:20 +02:00
Arthur Sonzogni
b2896aba49 Add games from the gamejam 2022-04-12 23:52:35 +02:00
Arthur Sonzogni
9f610a0110 Make the focused button to take the focus inside frame. (#371)
This resolves:
https://github.com/ArthurSonzogni/FTXUI/issues/370
2022-04-03 15:04:33 +02:00
Arthur Sonzogni
aebde94352 Add clang-tidy. (#368) 2022-03-31 02:17:43 +02:00
Arthur Sonzogni
62fb6298be Bug fixes. (#367)
- Do not draw more frames than what is needed.
- Fix MenuEntry transform state.
- Fix Canvas animated example.
2022-03-26 07:55:52 +01:00
Arthur Sonzogni
548fa51b71 Upgrade version (#363) 2022-03-20 21:14:17 +01:00
Arthur Sonzogni
1a3fcc1bd8 Improvement documentation. (#361) 2022-03-20 18:13:11 +01:00
Kefu Chai
0137d2a9ac component/collapsible: drop unused member variable (#360)
Signed-off-by: Kefu Chai <tchaikov@gmail.com>
2022-03-20 16:04:42 +01:00
Arthur Sonzogni
c76612a3c8 Fix error with invalid float in the gauge component. (#356) 2022-03-13 22:30:05 +01:00
Arthur Sonzogni
4da63b9260 Animation (#355) 2022-03-13 18:51:46 +01:00
Kefu Chai
95c766e9e4 Component decorators (#354)
Add decorator variants for decorator components

Add the "pipe" operator for components, similar to what was done for Elements.
We are able to put something like:
```
Button(...) | Maybe(&show_button)
```

Add decorators for:
- `Maybe`
- `CatchEvent`
- `Renderer`

Signed-off-by: Kefu Chai <tchaikov@gmail.com>
Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
2022-03-12 15:18:36 +01:00
Arthur Sonzogni
3e28fd6520 Convert \r into \n (#350)
This resolves:
https://github.com/ArthurSonzogni/FTXUI/issues/337
2022-03-04 13:23:45 +01:00
Kefu Chai
a254e36632 component/catch_event: improve the example for CatchEvent() (#351)
before this change, the example in the doxygen document for CatchEvent()
does not use the documented function. hence the example is not that
useful for developers interested in a typical usage of this function.

after this change, the example is improved to added the call to
CatchEvent(), which allows the application to the Loop() function at
user input.

Signed-off-by: Kefu Chai <tchaikov@gmail.com>
2022-03-04 13:23:31 +01:00
IsakTheHacker
9dbc23a7d4 Fix typos in README (#349) 2022-03-01 19:07:50 +01:00
Vladislav Nepogodin
3fe12b8a2f Add cachyos-cli-installer in README (#347) 2022-02-24 14:38:28 +01:00
Arthur Sonzogni
43dd70979d Update README.md 2022-02-21 10:27:53 +01:00
Elazar Leibovich
779c2d5b1a Add conan as a possible packaging system. (#342) 2022-02-21 10:25:05 +01:00
Arthur Sonzogni
20f16b3984 Improve ComponentBase and Container::Tab Focusable implementations (#341)
- Provide better defaults for ComponentBase `Focusable()` and
  `ActiveChild()` methods. This resolves:
  https://github.com/ArthurSonzogni/FTXUI/issues/335

- Implement `Container::Tab` 's  `Focusable()` methods. This prevents
  the users to navigate into a tab with no interactivity.
2022-02-19 11:49:12 +01:00
ericLemanissier
f95ed885bb Don't override PREFIX target property (#340)
PREFIX is by default "lib", which most of the libraries use.
this changes makes the library files libftxui-foo.a
as ArthurSonzogni/FTXUI#140 intended originally
2022-02-19 10:48:07 +01:00
Kefu Chai
63e8dadad9 allow passing move-only parameter to Make() (#338)
ftxui::Ref<> is used for passing Options, for instance, MenuOption,
to the corresponding component which is supposed to hold a strong
reference of it. and we can observe the events sent to the component
by setting callback(s) in the option instance passed to the owner
component.

but the callback function is not always copyable, despite that it
might be moveable.

in this change,

* Make<>() is updated to use the perfect forwarding to avoid
  enforcing its parameters to be copyable.
* Ref<> is also updated to take a rvalue reference, so we can
  move away from the contructor parameter when creating an
  instance of Ref<>() from it.

Signed-off-by: Kefu Chai <tchaikov@gmail.com>
2022-02-16 14:09:08 +01:00
Arthur Sonzogni
9b83205b3e Fix vscroll-indicator size and offset. (#334) 2022-02-14 02:44:57 +01:00
Arthur Sonzogni
5da7b8a59a Fix automerge in tables. (#333) 2022-02-13 11:41:31 +01:00
Arthur Sonzogni
9c4218c2a8 Support SIGTSTP and task posting. (#331)
- Add support for SIGTSTP:
https://github.com/ArthurSonzogni/FTXUI/issues/330
This

- Add support for task posting.
This allows folks to defer function execution, and execute it directly
below the main loop. The task are executed in a FIFO order.
2022-02-13 11:11:34 +01:00
Arthur Sonzogni
62747a49b6 Fix windows warning. (#332) 2022-02-13 10:51:47 +01:00
Arthur Sonzogni
8ba3698437 Gauge direction (#326)
Add `gauge` with all the different directions.

Co-authored-by: Aleksandar Brakmic <13668697+brakmic-aleksandar@users.noreply.github.com>
2022-02-06 19:17:21 +01:00
Arthur Sonzogni
7c3ca1beb5 Update README.md 2022-02-05 15:06:23 +01:00
Nikola Dućak
689d5dd299 Replace std::clamp with util::clamp and reformat the code (#321)
* Replace std::clamp with util::clamp
* Apply clang-format
* Execute ./tools/iwyu.sh

Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
2022-02-05 15:03:45 +01:00
Tushar Maheshwari
372d0ace4a Add tusharpm/tiles in README (#324) 2022-02-04 13:18:34 +01:00
Arthur Sonzogni
81b7207121 Move to v2.0.0 (#315) 2022-01-22 17:58:33 +01:00
Arthur Sonzogni
6039474a26 Automerge feature. (#313)
Add the `automerge` attribute to the Pixel bit field. It controls
whether two pixels must be automerged. Defining this allows two
mergeable characters not to be merged.

This was requested by:
https://github.com/ArthurSonzogni/FTXUI/issues/285
2022-01-22 15:38:01 +01:00
Arthur Sonzogni
4267b40a68 Add collapsible into fuzzer. (#312) 2022-01-22 11:44:52 +01:00
Arthur Sonzogni
3829734fa9 Fix table separator (#311) 2022-01-21 23:02:29 +01:00
Vladislav Nepogodin
b4a655ec65 Introduce WithRestoredIO (#307)
This function allow running a callback with the terminal hooks
temporarily uninstalled.

Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
2022-01-19 13:38:39 +01:00
Vladislav Nepogodin
cd82fccde7 Add missing const. (#297)
Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
2022-01-18 19:48:58 +01:00
Arthur Sonzogni
382205c057 Add Table constructor from Elements. (#310) 2022-01-16 16:46:32 +01:00
pezy
feb24b9498 Fix Clamp crash when entries_ size is zero (#306)
Run ftxui_example_homescreen on Windows, then select compiler tab, crash on origin code.

Co-authored-by: chenpeizhe <peizhe.chen@horizon.ai>
2022-01-13 01:46:09 +01:00
pezy
3dc215e6c0 Fix README link (#308)
- [Build using nxxm] is same with [Build using CMake], just remove
- fix [Build using CMake] link

Co-authored-by: chenpeizhe <peizhe.chen@horizon.ai>
2022-01-12 15:31:44 +01:00
Arthur Sonzogni
1888631bec Main (#303)
* Refresh cursor reporting on resize.

* Fix invalid size write.

This resolves:
https://github.com/ArthurSonzogni/FTXUI/issues/302
2022-01-11 23:06:36 +01:00
Arthur Sonzogni
84299de2e1 Add json-tui as using FTXUI. 2022-01-09 22:00:45 +01:00
Arthur Sonzogni
cdd6339849 Execute IWYU (#299) 2022-01-07 11:03:54 +01:00
Andrey Zimin
358f886fab Clamp selected_ on list resize for Radiobox/Menu/Toggle (#298)
fix: https://github.com/ArthurSonzogni/FTXUI/issues/296#issue-1092343846

When the list in Radiobox/Menu/Toggle is resized, clamp the |selected_| values so that it stays within bounds.
Clamping is executed in Render() and in OnEvent()

Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
2022-01-06 22:38:32 +01:00
Arthur Sonzogni
728976bdeb Fix vscroll indicator (#295)
* Clear vscroll_indicator content before drawing it.
2022-01-05 12:04:03 +01:00
Arthur Sonzogni
fc92f52b4c The collapsible element. (#294) 2022-01-02 15:48:56 +01:00
Man, Jianting (Meco)
071d2bc92b improve the window size handle method (#292)
1. the default window size should be 80x24 rather than 80x25 in VT100.
2. the ioctl return value result should be checked. Some operating systems don't support TIOCGWINSZ this command.
2022-01-01 19:24:37 +01:00
Vladislav Nepogodin
d549cdabb0 Reduce amount of warnings with pedantic compiler (#291) 2022-01-01 11:40:18 +01:00
Arthur Sonzogni
aea67743d4 Canvas bug fix and documentation. (#289) 2021-12-29 16:31:27 +01:00
Arthur Sonzogni
7614bf04a6 Address felixjulianheitmann suggestions. (#288)
- Remove unused examples/dom/flexbox.cpp
- Add canvas(width, height, void(Canvas&)) method
2021-12-24 17:29:39 +01:00
Arthur Sonzogni
188cffc5f6 Add example in the README.md 2021-12-23 15:12:22 +01:00
Arthur Sonzogni
0d47dd19ab Feature: Canvas (#287)
Draw using braille and block characters on a grid.
2021-12-23 14:17:33 +01:00
Arthur Sonzogni
7e5cd23b4c Add focusPosition[relative](x,y) (#280)
It allows when using inside a frame, to scroll the view toward a
particular position.

This resolves:
https://github.com/ArthurSonzogni/FTXUI/issues/125
2021-12-13 11:38:31 +01:00
Arthur Sonzogni
52276c8a2b Bugfix Input use std::string (#279)
Use std::string by default for the implementation of FTXUI's input
component.

Along the way:
- Give a correct implementation for fullwidth characters.
- Add tests
- Modify the way the cursor is drawn.
2021-12-12 21:31:54 +01:00
Arthur Sonzogni
602392c43d Implement flexbox (#277)
This implement the flexbox elements, following the HTML one.

Built from them, there is also the following elements:
- `paragraph`
- `paragraphAlignLeft`
- `paragraphAlignRight`
- `paragraphAlignCenter`
- `paragraphAlignJustify`

This is a breaking change.
2021-12-11 17:58:25 +01:00
Hassan Farooq
f7c6bf91a7 adding to projects using FTXUI list (#274)
Co-authored-by: hfarooq <hfarooq@tenstorrent.com>
2021-12-06 20:18:09 +01:00
Nikola Dućak
cecd54df42 Fix gridbox segfault (#260)
The problem was about
2021-11-17 10:16:09 +01:00
Gokulakrishnan D P
0186f8a463 added vantage in project section (#258) 2021-11-10 13:06:15 +01:00
Arthur Sonzogni
ebfb5ef3a1 Input shouldn't take focus. (#257)
This fixes:
https://github.com/ArthurSonzogni/FTXUI/issues/252
2021-11-09 20:30:27 +01:00
bogdasar1985
8f405f5054 Fix a typo (#256) 2021-11-09 12:11:45 +01:00
Arthur Sonzogni
8652280c85 Input shouldn't take focus. (#253)
This fixes:
https://github.com/ArthurSonzogni/FTXUI/issues/252
2021-11-07 12:01:17 +01:00
Arthur Sonzogni
aa6b78b8ad Upgrade version to 0.11.1 (#246)
A minor new version. Mostly for packaging the library in Release mode.
2021-10-23 21:13:23 +02:00
Arthur Sonzogni
c0e47aecb2 Remove unused file. (#244)
It was added mistakenly in:
https://github.com/ArthurSonzogni/FTXUI/pull/214#pullrequestreview-786773967
but @robinlinden found it.
2021-10-22 18:10:11 +02:00
Kevin Brennan
cba11151b5 Fix Windows builds not being in Release mode (#245) 2021-10-22 18:06:19 +02:00
Arthur Sonzogni
f80d9b5cfd Fix dropdown fuzzer. (#243) 2021-10-22 14:04:07 +02:00
Arthur Sonzogni
313ce9c35f Add support for PageUp/PageDown/Home/End buttons. (#242)
See:
https://github.com/ArthurSonzogni/FTXUI/issues/241
2021-10-20 21:15:40 +02:00
Arthur Sonzogni
4188ee2c04 Merge workflows. (#234)
- Merge all the workflows into one file.
- Produce Windows and MacOS artifact.
2021-10-17 20:10:07 +02:00
Arthur Sonzogni
026a005753 Table (#229)
This class allows rendering stylized table.
2021-10-15 23:04:11 +02:00
Jarosław Pelczar
7298636e7c Add API to set terminal fallback size (#230)
In case of embedded systems, the terminal size may not
always be detectable (e.g. in case of serial output).
Allow application to set up the default size in case
autodetection fails. On platform such as Emscripten,
there is only "fallback" size.

Signed-off-by: Jarosław Pelczar <jarek@jpelczar.com>
2021-10-13 13:44:30 +02:00
tomvg
5e199fcd85 Include <algorithm> for std::max for msvc 2017, (#226)
Msvc defined its own (lowercase) macros for min/max. Because of this, the std::min and std::max functions need to be explicitly included or otherwise are not availible.
In the msvc 2019 compiler this issue seems fixed. However, on msvc 2017 not including <algorithm> causes compilation errors. Adding the include is a simple fix that does not hurt the other platforms and enables compilation on msvc 2017.
2021-10-12 11:36:19 +02:00
Arthur Sonzogni
57a5512a22 Support dynamic library. (#225)
- Let the global `BUILD_SHARED_LIBS` dictates whether the library should
  be built statically or dynamically. The cmake's default is statically.
- Add library version and symlink.

This lead to the following install tree.
.
├── include
│   └── ftxui
│       ├── component [...]
│       ├── dom [...]
│       ├── screen [...]
│       └── util [...]
└── lib
    ├── cmake
    │   └── ftxui
    │       ├── ftxui-config.cmake
    │       ├── ftxui-config-version.cmake
    │       └── ftxui-config-version-noconfig.cmake
    ├── ftxui-component.so -> ftxui-component.so.0.10.369
    ├── ftxui-component.so.0.10.369
    ├── ftxui-dom.so -> ftxui-dom.so.0.10.369
    ├── ftxui-dom.so.0.10.369
    ├── ftxui-screen.so -> ftxui-screen.so.0.10.369
    └── ftxui-screen.so.0.10.369

Fixed: https://github.com/ArthurSonzogni/FTXUI/issues/223
2021-10-10 12:52:34 +02:00
Jarosław Pelczar
75482d82d4 Use sensible defaults in case TIOCGWINSZ fails (#224)
This can happen for example in embedded linux, in case
the application is started via serial terminal.

Signed-off-by: Jarosław Pelczar <jarek@jpelczar.com>
Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
2021-10-09 11:51:00 +02:00
Arthur Sonzogni
31c26c6956 Update README.md 2021-10-08 14:12:27 +02:00
ArthurSonzogni
6dd626a79a Fix: Add separator(Pixel) back.
It was removed by mistacke previously.
Take the opportunity to create new documentation.
2021-10-03 10:45:47 +02:00
ArthurSonzogni
05fc866d74 Do not trigger the CQ twice on pull request. 2021-09-30 21:44:29 +02:00
ArthurSonzogni
46f481ded7 Submit release as draft.
This will let me time to add a description.
2021-09-30 21:42:52 +02:00
199 changed files with 13544 additions and 2550 deletions

22
.clang-tidy Normal file
View File

@@ -0,0 +1,22 @@
---
Checks: "*,
-abseil-*,
-altera-*,
-android-*,
-fuchsia-*,
-google-*,
-llvm*,
-modernize-use-trailing-return-type,
-zircon-*,
-readability-else-after-return,
-readability-static-accessed-through-instance,
-readability-avoid-const-params-in-decls,
-cppcoreguidelines-non-private-member-variables-in-classes,
-misc-non-private-member-variables-in-classes,
-modernize-use-nodiscard,
-misc-no-recursion,
-readability-implicit-bool-conversion,
"
WarningsAsErrors: ''
HeaderFilterRegex: ''
FormatStyle: none

205
.github/workflows/build.yaml vendored Normal file
View File

@@ -0,0 +1,205 @@
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: true
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@v2
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:
needs: package
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 ..;
cmake --build . --target doc;
rsync -amv --include='*/' --include='*.html' --include='*.js' --include='*.wasm' --exclude='*' examples doc/doxygen/html;
- name: "Deploy"
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: build/doc/doxygen/html/
enable_jekyll: false
allow_empty_commit: false
force_orphan: true
publish_branch: gh-pages

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

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

View File

@@ -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

View File

@@ -1,5 +0,0 @@
{
"platform": [
"GTest::+gtest"
]
}

View File

@@ -1,20 +1,156 @@
# Changelog Changelog
=========
## Current current (development)
---------------------
## 0.10 (2021-09-30) 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 ## Bug
- Fix the automated merge of borders. - Fix the automated merge of borders.
### Dom ### 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 ### Component
- `Maybe`: Display an component conditionnally based on a boolean. - `Maybe`: Display an component conditionnally based on a boolean.
- `Dropdown`: A dropdown select list. - `Dropdown`: A dropdown select list.
## 0.9 (2021-09-26) 0.9 (2021-09-26)
----------------
The initial release where changelog where written. The initial release where changelog where written.

View File

@@ -1,17 +1,17 @@
cmake_minimum_required(VERSION 3.11) cmake_minimum_required(VERSION 3.11)
include(cmake/ftxui_git_version.cmake)
project(ftxui project(ftxui
LANGUAGES CXX LANGUAGES CXX
VERSION 0.10.${git_version} VERSION 3.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_EXAMPLES "Set to ON to build examples" ON)
option(FTXUI_BUILD_TESTS "Set to ON to build tests" OFF) option(FTXUI_BUILD_TESTS "Set to ON to build tests" OFF)
option(FTXUI_BUILD_TESTS_FUZZER "Set to ON to enable fuzzing" OFF) option(FTXUI_BUILD_TESTS_FUZZER "Set to ON to enable fuzzing" OFF)
option(FTXUI_ENABLE_INSTALL "Generate the install target" ON) 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 \ 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 \ 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) ${FTXUI_MICROSOFT_TERMINAL_FALLBACK_HELP_TEXT} OFF)
endif() 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/box.cpp
src/ftxui/screen/color.cpp src/ftxui/screen/color.cpp
src/ftxui/screen/color_info.cpp src/ftxui/screen/color_info.cpp
src/ftxui/screen/screen.cpp src/ftxui/screen/screen.cpp
src/ftxui/screen/string.cpp src/ftxui/screen/string.cpp
src/ftxui/screen/terminal.cpp src/ftxui/screen/terminal.cpp
include/ftxui/screen/box.hpp src/ftxui/screen/util.hpp
include/ftxui/screen/color.hpp
include/ftxui/screen/color_info.hpp
include/ftxui/screen/screen.hpp
include/ftxui/screen/string.hpp
) )
add_library(dom STATIC add_library(dom
include/ftxui/dom/canvas.hpp
include/ftxui/dom/elements.hpp include/ftxui/dom/elements.hpp
include/ftxui/dom/flexbox_config.hpp
include/ftxui/dom/node.hpp include/ftxui/dom/node.hpp
include/ftxui/dom/requirement.hpp include/ftxui/dom/requirement.hpp
include/ftxui/dom/take_any_args.hpp include/ftxui/dom/take_any_args.hpp
src/ftxui/dom/automerge.cpp
src/ftxui/dom/blink.cpp src/ftxui/dom/blink.cpp
src/ftxui/dom/bold.cpp src/ftxui/dom/bold.cpp
src/ftxui/dom/border.cpp src/ftxui/dom/border.cpp
src/ftxui/dom/box_helper.cpp src/ftxui/dom/box_helper.cpp
src/ftxui/dom/box_helper.hpp src/ftxui/dom/box_helper.hpp
src/ftxui/dom/canvas.cpp
src/ftxui/dom/clear_under.cpp src/ftxui/dom/clear_under.cpp
src/ftxui/dom/color.cpp src/ftxui/dom/color.cpp
src/ftxui/dom/composite_decorator.cpp src/ftxui/dom/composite_decorator.cpp
src/ftxui/dom/dbox.cpp src/ftxui/dom/dbox.cpp
src/ftxui/dom/dim.cpp src/ftxui/dom/dim.cpp
src/ftxui/dom/flex.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/frame.cpp
src/ftxui/dom/gauge.cpp src/ftxui/dom/gauge.cpp
src/ftxui/dom/graph.cpp src/ftxui/dom/graph.cpp
src/ftxui/dom/gridbox.cpp src/ftxui/dom/gridbox.cpp
src/ftxui/dom/hbox.cpp src/ftxui/dom/hbox.cpp
src/ftxui/dom/hflow.cpp
src/ftxui/dom/inverted.cpp src/ftxui/dom/inverted.cpp
src/ftxui/dom/node.cpp src/ftxui/dom/node.cpp
src/ftxui/dom/node_decorator.cpp src/ftxui/dom/node_decorator.cpp
@@ -69,24 +79,31 @@ add_library(dom STATIC
src/ftxui/dom/separator.cpp src/ftxui/dom/separator.cpp
src/ftxui/dom/size.cpp src/ftxui/dom/size.cpp
src/ftxui/dom/spinner.cpp src/ftxui/dom/spinner.cpp
src/ftxui/dom/table.cpp
src/ftxui/dom/text.cpp src/ftxui/dom/text.cpp
src/ftxui/dom/underlined.cpp src/ftxui/dom/underlined.cpp
src/ftxui/dom/util.cpp src/ftxui/dom/util.cpp
src/ftxui/dom/vbox.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/captured_mouse.hpp
include/ftxui/component/component.hpp include/ftxui/component/component.hpp
include/ftxui/component/component_base.hpp include/ftxui/component/component_base.hpp
include/ftxui/component/component_options.hpp
include/ftxui/component/event.hpp include/ftxui/component/event.hpp
include/ftxui/component/mouse.hpp include/ftxui/component/mouse.hpp
include/ftxui/component/receiver.hpp include/ftxui/component/receiver.hpp
include/ftxui/component/screen_interactive.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/button.cpp
src/ftxui/component/catch_event.cpp src/ftxui/component/catch_event.cpp
src/ftxui/component/checkbox.cpp src/ftxui/component/checkbox.cpp
src/ftxui/component/collapsible.cpp
src/ftxui/component/component.cpp src/ftxui/component/component.cpp
src/ftxui/component/component_options.cpp
src/ftxui/component/container.cpp src/ftxui/component/container.cpp
src/ftxui/component/dropdown.cpp src/ftxui/component/dropdown.cpp
src/ftxui/component/event.cpp src/ftxui/component/event.cpp
@@ -101,7 +118,7 @@ add_library(component STATIC
src/ftxui/component/slider.cpp src/ftxui/component/slider.cpp
src/ftxui/component/terminal_input_parser.cpp src/ftxui/component/terminal_input_parser.cpp
src/ftxui/component/terminal_input_parser.hpp src/ftxui/component/terminal_input_parser.hpp
src/ftxui/component/toggle.cpp src/ftxui/component/util.cpp
) )
target_link_libraries(dom target_link_libraries(dom
@@ -111,14 +128,23 @@ target_link_libraries(dom
find_package(Threads) find_package(Threads)
target_link_libraries(component target_link_libraries(component
PUBLIC dom PUBLIC dom
PRIVATE Threads::Threads PUBLIC Threads::Threads
) )
set_target_properties(screen PROPERTIES VERSION ${PROJECT_VERSION})
set_target_properties(dom PROPERTIES VERSION ${PROJECT_VERSION})
set_target_properties(component PROPERTIES VERSION ${PROJECT_VERSION})
include(cmake/ftxui_set_options.cmake) include(cmake/ftxui_set_options.cmake)
ftxui_set_options(screen) ftxui_set_options(screen)
ftxui_set_options(dom) ftxui_set_options(dom)
ftxui_set_options(component) ftxui_set_options(component)
include(cmake/ftxui_coverage.cmake)
ftxui_check_coverage(screen)
ftxui_check_coverage(dom)
ftxui_check_coverage(component)
if (FTXUI_BUILD_TESTS AND ${CMAKE_VERSION} VERSION_GREATER "3.11.4") if (FTXUI_BUILD_TESTS AND ${CMAKE_VERSION} VERSION_GREATER "3.11.4")
include(cmake/ftxui_test.cmake) include(cmake/ftxui_test.cmake)
endif() endif()
@@ -138,4 +164,3 @@ if(FTXUI_ENABLE_INSTALL)
include(cmake/ftxui_install.cmake) include(cmake/ftxui_install.cmake)
include(cmake/ftxui_package.cmake) include(cmake/ftxui_package.cmake)
endif() endif()

328
README.md
View File

@@ -8,10 +8,14 @@
<a href="#"><img src="https://img.shields.io/github/repo-size/ArthurSonzogni/FTXUI"></img></a> <a href="#"><img src="https://img.shields.io/github/repo-size/ArthurSonzogni/FTXUI"></img></a>
<a href="https://github.com/ArthurSonzogni/FTXUI/issues"><img src="https://img.shields.io/github/issues/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://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/> <br/>
<a href="https://github.com/ArthurSonzogni/FTXUI/wiki">Documentation</a> · <a href="https://arthursonzogni.github.io/FTXUI/">Documentation</a> ·
<a href="https://github.com/ArthurSonzogni/FTXUI/issues">Report Bug</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://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/issues">Request Feature</a> ·
<a href="https://github.com/ArthurSonzogni/FTXUI/pulls">Send a Pull Request</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> <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 ## Feature
* Functional style. Inspired by * Functional style. Inspired by
[[1]](https://hackernoon.com/building-reactive-terminal-interfaces-in-c-d392ce34e649?gi=d9fb9ce35901) [[1]](https://hackernoon.com/building-reactive-terminal-interfaces-in-c-d392ce34e649?gi=d9fb9ce35901)
and [React](https://reactjs.org/) and [React](https://reactjs.org/)
* Simple and elegant syntax (in my opinion). * 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.
* Keyboard & mouse navigation. * 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.com/FTXUI/examples/?file=component/menu_underline_animated_gallery), [Demo 2](https://arthursonzogni.com/FTXUI/examples/?file=component/button_style)
* Support for drawing. [Demo](https://arthursonzogni.com/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.com/FTXUI/examples/)
- [Build using CMake](https://github.com/ArthurSonzogni/FTXUI/blob/master/doc/mainpage.md#using-cmake)
## Operating systems ## 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 This is expected to be cross platform. This supports / tests:
[badge.linux-clang]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/linux-clang.yaml/badge.svg?branch=master - WebAssembly
[badge.linux-emscripten]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/linux-emscripten.yaml/badge.svg?branch=master - Linux
[badge.windows-msvc]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/windows-msvc.yaml/badge.svg?branch=master - MacOS
[badge.mac-clang]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/mac-clang.yaml/badge.svg?branch=master - Windows
[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
## Example ## Example
~~~cpp ~~~cpp
@@ -74,17 +79,234 @@ 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`.
![image](https://user-images.githubusercontent.com/4759106/147242524-7103b5d9-1a92-4e2d-ac70-b3d6740061e3.png)
[Example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2gridbox_8cpp-example.htmlp) using gridbox:
![image](https://user-images.githubusercontent.com/4759106/147242972-0db1f2e9-0790-496f-86e6-ed2c604f7a73.png)
[Example](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/dom/hflow.cpp) using flexbox:
![image](https://user-images.githubusercontent.com/4759106/147243064-780ac7cc-605b-475f-94b8-cf7c4aed03a5.png)
[See](https://arthursonzogni.github.io/FTXUI/examples_2dom_2hflow_8cpp-example.html) also this [demo](https://arthursonzogni.com/FTXUI/examples/?file=component/flexbox).
</details>
<details><summary>Style</summary>
An element can be decorated using the functions:
- `bold`
- `dim`
- `inverted`
- `underlined`
- `blink`
- `color`
- `bgcolor`
[Example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2style_gallery_8cpp-example.html)
![image](https://user-images.githubusercontent.com/4759106/147244118-380bf834-9e33-40df-9ff0-07c10f2598ef.png)
FTXUI supports the pipe operator. It means: `decorator1(decorator2(element))` and `element | decorator1 | decorator2` can be used.
</details>
<details><summary>Colors</summary>
FTXUI support every color palette:
Color [gallery](https://arthursonzogni.github.io/FTXUI/examples_2dom_2color_gallery_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147248595-04c7245a-5b85-4544-809d-a5984fc6f9e7.png)
</details>
<details><summary>Border and separator</summary>
Use decorator border and element separator() to subdivide your UI:
```cpp
auto document = vbox({
text("top"),
separator(),
text("bottom"),
}) | border;
```
[Demo](https://arthursonzogni.github.io/FTXUI/examples_2dom_2separator_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147244514-4135f24b-fb8e-4067-8896-bc53545583f7.png)
</details>
<details><summary>Text and paragraph</summary>
A simple piece of text is represented using `text("content")`.
To support text wrapping following spaces the following functions are provided:
```cpp
Element paragraph(std::string text);
Element paragraphAlignLeft(std::string text);
Element paragraphAlignRight(std::string text);
Element paragraphAlignCenter(std::string text);
Element paragraphAlignJustify(std::string text);
```
[Paragraph example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2paragraph_8cpp-example.html)
![ezgif com-gif-maker (4)](https://user-images.githubusercontent.com/4759106/147251370-983a06e7-6f41-4113-92b8-942f43d34d06.gif)
</details>
<details><summary>Table</summary>
A class to easily style a table of data.
[Example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2table_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147250766-77d8ec9e-cf2b-486d-9866-1fd9f1bd2e6b.png)
</details>
<details><summary>Canvas</summary>
Drawing can be made on a Canvas, using braille, block, or simple characters:
Simple [example](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/dom/canvas.cpp):
![image](https://user-images.githubusercontent.com/4759106/147245843-76cc62fb-ccb4-421b-aacf-939f9afb42fe.png)
Complex [examples](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/component/canvas_animated.cpp):
![ezgif com-gif-maker (3)](https://user-images.githubusercontent.com/4759106/147250538-783a8246-98e0-4a25-b032-3bd3710549d1.gif)
</details>
#### Component
The ftxui/component is needed when you want to produce dynamic UI, reactive to the user's input. It defines a set of ftxui::Component. A component reacts to Events (keyboard, mouse, resize, ...) and Render Element (see previous section).
Prebuilt components are declared in [<ftxui/component/component.hpp>](https://arthursonzogni.github.io/FTXUI/component_8hpp_source.html)
<details><summary>Gallery</summary>
[Gallery](https://arthursonzogni.github.io/FTXUI/examples_2component_2gallery_8cpp-example.html) of multiple components. ([demo](https://arthursonzogni.com/FTXUI/examples/?file=component/gallery))
![image](https://user-images.githubusercontent.com/4759106/147247330-b60beb9f-e665-48b4-81c0-4b01ee95bc66.png)
</details>
<details><summary>Radiobox</summary>
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2radiobox_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147246401-809d14a5-6621-4e36-8dd9-a2d75ef2a94e.png)
</details>
<details><summary>Checkbox</summary>
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2checkbox_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147246646-b86926a9-1ef9-4efb-af98-48a9b62acd81.png)
</details>
<details><summary>Input</summary>
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2input_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147247671-f1d6f606-1845-4e94-a4a0-d4273e9ae6bd.png)
</details>
<details><summary>Toggle</summary>
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2toggle_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147249383-e2201cf1-b7b8-4a5a-916f-d761e3e7ae40.png)
</details>
<details><summary>Slider</summary>
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2slider_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147249265-7e2cad75-082c-436e-affe-44a550c480ab.png)
</details>
<details><summary>Menu</summary>
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2menu_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147247822-0035fd6f-bb13-4b3a-b057-77eb9291582f.png)
</details>
<details><summary>ResizableSplit</summary>
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2resizable_split_8cpp-example.html):
![ezgif com-gif-maker](https://user-images.githubusercontent.com/4759106/147248372-c55512fe-9b96-4b08-a1df-d05cf2cae431.gif)
</details>
<details><summary>Dropdown</summary>
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2dropdown_8cpp-example.html):
![youtube-video-gif (3)](https://user-images.githubusercontent.com/4759106/147246982-1e821751-531c-4e1f-bc37-2fa290e143cd.gif)
</details>
<details><summary>Tab</summary>
[Vertical](https://arthursonzogni.github.io/FTXUI/examples_2component_2tab_vertical_8cpp-example.html):
![ezgif com-gif-maker (1)](https://user-images.githubusercontent.com/4759106/147250144-22ff044a-4773-4ff7-a49c-12ba4034acb4.gif)
[Horizontal](https://arthursonzogni.github.io/FTXUI/examples_2component_2tab_horizontal_8cpp-example.html):
![ezgif com-gif-maker (2)](https://user-images.githubusercontent.com/4759106/147250217-fe447e0f-7a99-4e08-948a-995087d9b40e.gif)
</details>
- [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 ## Project using FTXUI
Feel free to add your projects here: Feel free to add your projects here:
- [json-tui](https://github.com/ArthurSonzogni/json-tui)
- [git-tui](https://github.com/ArthurSonzogni/git-tui) - [git-tui](https://github.com/ArthurSonzogni/git-tui)
- [rgb-tui](https://github.com/ArthurSonzogni/rgb-tui) - [rgb-tui](https://github.com/ArthurSonzogni/rgb-tui)
- [chrome-log-beautifier](https://github.com/ArthurSonzogni/chrome-log-beautifier) - [chrome-log-beautifier](https://github.com/ArthurSonzogni/chrome-log-beautifier)
@@ -98,16 +320,52 @@ Feel free to add your projects here:
- [CryptoCalculator](https://github.com/brevis/CryptoCalculator) - [CryptoCalculator](https://github.com/brevis/CryptoCalculator)
- [todoman](https://github.com/aaleino/todoman) - [todoman](https://github.com/aaleino/todoman)
- [TimeAccumulator](https://github.com/asari555/TimeAccumulator) - [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)
## Hosted on ## [cpp-best-practices/game_jam](https://github.com/cpp-best-practices/game_jam)
* [github](https://github.com/ArthurSonzogni/ftxui)
* [gitlab](https://gitlab.com/ArthurSonzogni/ftxui) 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/LightsRound.v.0.1.0.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 ## External package
It is **highly** recommanded to use cmake FetchContent to depends on FTXUI. This It is **highly** recommended to use CMake FetchContent to depend on FTXUI. This
way you can specify which commit you would like to depends on. 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 v2.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: If you don't, the following packages have been created:
- vcpkg ([soon](https://github.com/ArthurSonzogni/FTXUI/issues/112)) - [vcpkg](https://vcpkg.info/port/ftxui)
- [Arch Linux PKGBUILD](https://aur.archlinux.org/packages/ftxui-git/). - [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>

View File

@@ -2,8 +2,20 @@ if (NOT WIN32)
FetchContent_Declare(googlebenchmark FetchContent_Declare(googlebenchmark
GIT_REPOSITORY "https://github.com/google/benchmark" GIT_REPOSITORY "https://github.com/google/benchmark"
GIT_TAG 62937f91b5c763a8e119d0c20c67b87bde8eff1c GIT_TAG 62937f91b5c763a8e119d0c20c67b87bde8eff1c
GIT_PROGRESS TRUE
) )
FetchContent_MakeAvailable(googlebenchmark)
FetchContent_GetProperties(googlebenchmark)
set (BENCHMARK_ENABLE_GTEST_TESTS OFF CACHE INTERNAL "")
set (BENCHMARK_ENABLE_TESTING OFF CACHE INTERNAL "")
if(NOT googlebenchmark_POPULATED)
FetchContent_Populate(googlebenchmark)
add_subdirectory(
${googlebenchmark_SOURCE_DIR}
${googlebenchmark_BINARY_DIR}
EXCLUDE_FROM_ALL
)
endif()
add_executable(ftxui_benchmark add_executable(ftxui_benchmark
src/ftxui/dom/benchmark_test.cpp src/ftxui/dom/benchmark_test.cpp

View File

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

View File

@@ -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()

View File

@@ -1,4 +1,12 @@
set(CPACK_GENERATOR "DEB;External;RPM;STGZ;TBZ2;TGZ;TXZ;TZ;TZST;ZIP") 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_DEPENDS " ")
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE_URL "https://github.com/ArthurSonzogni/FTXUI/") set(CPACK_DEBIAN_PACKAGE_HOMEPAGE_URL "https://github.com/ArthurSonzogni/FTXUI/")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Arthur Sonzogni") set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Arthur Sonzogni")

View File

@@ -1,7 +1,20 @@
function(ftxui_set_options library) find_program( CLANG_TIDY_EXE NAMES "clang-tidy" DOC "Path to clang-tidy executable" )
set_target_properties(${library} PROPERTIES PREFIX "ftxui-") 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)
set_target_properties(${library} PROPERTIES OUTPUT_NAME "ftxui-${library}")
if(CLANG_TIDY_EXE AND FTXUI_CLANG_TIDY)
set_target_properties(${library}
PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_EXE};-warnings-as-errors=*"
)
endif()
target_include_directories(${library} target_include_directories(${library}
PUBLIC PUBLIC
$<INSTALL_INTERFACE:include> $<INSTALL_INTERFACE:include>

View File

@@ -1,47 +1,82 @@
enable_testing() enable_testing()
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
set(FETCHCONTENT_UPDATES_DISCONNECTED TRUE) option(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)
option(FETCHCONTENT_QUIET FALSE)
include(FetchContent) include(FetchContent)
FetchContent_Declare( googletest FetchContent_Declare(googletest
GIT_REPOSITORY "https://github.com/google/googletest" GIT_REPOSITORY "https://github.com/google/googletest"
GIT_TAG 23ef29555ef4789f555f1ba8c51b4c52975f0907 GIT_TAG 23ef29555ef4789f555f1ba8c51b4c52975f0907
GIT_PROGRESS TRUE
) )
FetchContent_MakeAvailable(googletest) FetchContent_GetProperties(googletest)
if(NOT googletest_POPULATED)
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
)
endif()
add_executable(tests add_executable(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/component_test.cpp
src/ftxui/component/container_test.cpp src/ftxui/component/container_test.cpp
src/ftxui/component/input_test.cpp src/ftxui/component/input_test.cpp
src/ftxui/component/menu_test.cpp
src/ftxui/component/radiobox_test.cpp src/ftxui/component/radiobox_test.cpp
src/ftxui/component/receiver_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/screen_interactive_test.cpp
src/ftxui/component/terminal_input_parser_test.cpp src/ftxui/component/terminal_input_parser_test.cpp
src/ftxui/component/toggle_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/gauge_test.cpp
src/ftxui/dom/gridbox_test.cpp src/ftxui/dom/gridbox_test.cpp
src/ftxui/dom/hbox_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/text_test.cpp
src/ftxui/dom/underlined_test.cpp
src/ftxui/dom/vbox_test.cpp src/ftxui/dom/vbox_test.cpp
src/ftxui/screen/color_test.cpp
src/ftxui/screen/string_test.cpp src/ftxui/screen/string_test.cpp
) )
target_link_libraries(tests target_link_libraries(tests
PRIVATE component PRIVATE component
PRIVATE gtest PRIVATE gtest
PRIVATE gmock
PRIVATE gtest_main PRIVATE gtest_main
) )
target_include_directories(tests target_include_directories(tests
PRIVATE src PRIVATE src
) )
target_compile_options(tests PRIVATE -fsanitize=address) ftxui_set_options(tests)
target_link_libraries(tests PRIVATE -fsanitize=address)
if (NOT MSVC) include(GoogleTest)
include(cmake/ftxui_benchmark.cmake) gtest_discover_tests(tests
endif() DISCOVERY_TIMEOUT 600
)
include(cmake/ftxui_benchmark.cmake)
if (FTXUI_BUILD_TESTS_FUZZER) if (FTXUI_BUILD_TESTS_FUZZER)
include(cmake/ftxui_fuzzer.cmake) include(cmake/ftxui_fuzzer.cmake)

View File

@@ -1,14 +1,19 @@
\mainpage \mainpage
# Introduction # Introduction {#introduction}
Welcome to the FTXUI documentation. Here, you will find the detail of every Welcome to the FTXUI documentation!
functions and classes.
This is a brief tutorial. You are also encouraged to learn, by reading the
[examples](./examples.html)
@tableofcontents @tableofcontents
**Short example** **Short example**
To build a single frame, you need create an `ftxui::Element`, and display it on
a `ftxui::Screen`.
**main.cpp** **main.cpp**
```cpp ```cpp
#include <ftxui/dom/elements.hpp> #include <ftxui/dom/elements.hpp>
@@ -37,6 +42,7 @@ int main(void) {
} }
``` ```
**output** **output**
```bash ```bash
┌────┐┌─────────────────────────────────────────────────────────────────┐┌─────┐ ┌────┐┌─────────────────────────────────────────────────────────────────┐┌─────┐
@@ -44,9 +50,9 @@ int main(void) {
└────┘└─────────────────────────────────────────────────────────────────┘└─────┘ └────┘└─────────────────────────────────────────────────────────────────┘└─────┘
``` ```
# Build # Build {#build}
## Using CMake ## Using CMake {#build-cmake}
CMakeLists.txt CMakeLists.txt
~~~cmake ~~~cmake
@@ -58,7 +64,7 @@ include(FetchContent)
set(FETCHCONTENT_UPDATES_DISCONNECTED TRUE) set(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)
FetchContent_Declare(ftxui FetchContent_Declare(ftxui
GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui
# Specify a GIT_TAG here. # Important: Specify a GIT_TAG XXXXX here.
) )
FetchContent_GetProperties(ftxui) FetchContent_GetProperties(ftxui)
@@ -86,16 +92,16 @@ target_link_libraries(ftxui-starter
~~~ ~~~
Build Build
~~~ ~~~sh
mkdir build && cd build mkdir build && cd build
cmake .. cmake ..
make make
./main ./main
~~~ ~~~
# List of modules. # List of modules. {#modules}
The project is split into 3 modules: The project is made from into 3 modules:
1. **ftxui/screen** defines a `ftxui::Screen`, this is a grid of `ftxui::Pixel`. 1. **ftxui/screen** defines a `ftxui::Screen`, this is a grid of `ftxui::Pixel`.
@@ -108,7 +114,7 @@ The project is split into 3 modules:
using the arrow keys and interact with widgets like checkbox/inputbox/... You using the arrow keys and interact with widgets like checkbox/inputbox/... You
can make you own components. can make you own components.
# screen # screen {#module-screen}
It defines a `ftxui::Screen`. This is a grid of `ftxui::Pixel`. A Pixel 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...). represent a Unicode character and its associated style (bold, colors, etc...).
@@ -132,31 +138,41 @@ The screen can be printed as a string using `ftxui::Screen::ToString()`.
} }
~~~ ~~~
# dom # dom {#module-dom}
This module defines a hierarchical set of Element. An element manages layout and This module defines a hierarchical set of `ftxui::Element`. An element manages
can be responsive to the terminal dimensions. layout and can be responsive to the terminal dimensions.
**Example:** **Example:**
```cpp ```cpp
// Define the document // Define the document
Element document = vbox({ Element document = vbox({
text("The window") | bold | color(Color::Blue), text("The window") | bold | color(Color::Blue),
gauge(0.5) gauge(0.5)
text("The footer") text("The footer")
}); });
// Add a border. // Add a border, by calling the `ftxui::border` decorator function.
document = border(document); document = border(document);
// Add another border, using the pipe operator.
document = document | border.
// Add another border, using the |= operator.
document |= border
``` ```
**List of elements** **List of elements**
You only need one header: ftxui/dom/elements.hpp They are all defined inside:
```cpp
#include <ftxui/dom/elements.hpp>
```
\include ftxui/dom/elements.hpp \include ftxui/dom/elements.hpp
## text ## text ## {#dom-text}
The most simple widget. It displays a text. The most simple widget. It displays a text.
~~~cpp ~~~cpp
@@ -166,7 +182,44 @@ text("I am a piece of text");
I am a piece of text. I am a piece of text.
~~~ ~~~
## border ## vtext {#dom-vtext}
Same as `ftxui::text`, but vertical.
~~~cpp
vtext("HELLO");
~~~
~~~bash
H
E
L
L
O
~~~
## paragraph {#dom-paragraph}
```cpp
paragraph("A very long text")
```
Similar to `ftxui::text`, but this support line wrapping and alignments. The
words are split by spaces
[Paragraph example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2paragraph_8cpp-example.html)
![ezgif com-gif-maker (4)](https://user-images.githubusercontent.com/4759106/147251370-983a06e7-6f41-4113-92b8-942f43d34d06.gif)
See:
```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}
Add a border around an element Add a border around an element
~~~cpp ~~~cpp
@@ -179,7 +232,27 @@ border(text("The element"))
└───────────┘ └───────────┘
~~~ ~~~
## window Same, with the pipe operator:
```cpp
text("The element") | border
```
Border come with different styles.
See:
```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 some text on top of the border. A `ftxui::window` is a `ftxui::border`, but with some text on top of the border.
Add a border around an element Add a border around an element
@@ -193,7 +266,7 @@ window("The window", text("The element"))
└───────────┘ └───────────┘
~~~ ~~~
## separator ## separator {#dom-separator}
Display a vertical or horizontal line to visually split the content of a Display a vertical or horizontal line to visually split the content of a
container in two. container in two.
@@ -214,7 +287,29 @@ border(
└────┴─────┘ └────┴─────┘
~~~ ~~~
## gauge
Separators come with different styles:
See:
```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}
A gauge. It can be used to represent a progress bar. A gauge. It can be used to represent a progress bar.
~~~cpp ~~~cpp
@@ -227,13 +322,28 @@ border(gauge(0.5))
└────────────────────────────────────────────────────────────────────────────┘ └────────────────────────────────────────────────────────────────────────────┘
~~~ ~~~
## graph A gauge can be displayed into several directions. See:
```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 @htmlonly
<script id="asciicast-223726" src="https://asciinema.org/a/223726.js" async></script> <script id="asciicast-223726" src="https://asciinema.org/a/223726.js" async></script>
@endhtmlonly @endhtmlonly
## Colors See:
```cpp
Element graph(GraphFunction);
```
## Colors {#dom-colors}
A terminal console can usually display colored text and colored background. A terminal console can usually display colored text and colored background.
~~~cpp ~~~cpp
@@ -241,7 +351,12 @@ Decorator color(Color);
Decorator bgcolor(Color); Decorator bgcolor(Color);
~~~ ~~~
### Palette16 FTXUI support every color palette:
Color [gallery](https://arthursonzogni.github.io/FTXUI/examples_2dom_2color_gallery_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147248595-04c7245a-5b85-4544-809d-a5984fc6f9e7.png)
### Palette16 #{#dom-colors-palette-16}
On most terminal the following colors are supported: On most terminal the following colors are supported:
- Default - Default
@@ -277,7 +392,7 @@ text("Blue background") | bgcolor(Color::Blue);
text("Black on white") | color(Color::Black) | bgcolor(Color::White); text("Black on white") | color(Color::Black) | bgcolor(Color::White);
``` ```
### Palette256 ### Palette256 #{#dom-colors-palette-256}
On terminal supporting 256 colors. On terminal supporting 256 colors.
@htmlonly @htmlonly
@@ -288,7 +403,7 @@ On terminal supporting 256 colors.
text("HotPink") | color(Color::HotPink); 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 chose the 24bit RGB color:
@@ -303,7 +418,7 @@ 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> <script id="asciicast-xwzzghmqcqzIuyLwCpQFEqbEu" src="https://asciinema.org/a/xwzzghmqcqzIuyLwCpQFEqbEu.js" async></script>
@endhtmlonly @endhtmlonly
## Style ## Style {#dom-style}
A terminal console can usually display colored text and colored background. A terminal console can usually display colored text and colored background.
The text can also have different effects: bold, dim, underlined, inverted, The text can also have different effects: bold, dim, underlined, inverted,
blink. blink.
@@ -318,6 +433,10 @@ Decorator color(Color);
Decorator bgcolor(Color); Decorator bgcolor(Color);
~~~ ~~~
[Example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2style_gallery_8cpp-example.html)
![image](https://user-images.githubusercontent.com/4759106/147244118-380bf834-9e33-40df-9ff0-07c10f2598ef.png)
Example: Example:
~~~cpp ~~~cpp
underlined(bold(text("This text is bold and underlined"))) underlined(bold(text("This text is bold and underlined")))
@@ -328,22 +447,30 @@ Tips: The pipe operator can be used to chain Decorator:
text("This text is bold")) | bold | underlined text("This text is bold")) | bold | underlined
~~~ ~~~
## Layout ## Layout {#dom-layout}
These layout are similar to the HTML flexbox: Element can be arranged together:
* vbox (Vertical-box) - horizontally with `ftxui::hbox`
* hbox (Horizontal-box) - vertically with `ftxui::vbox`
* dbox (Z-axis-box) - inside a grid with `ftxui::gridbox`
They are used to compose all the elements together. Each - wrap along one direction using the `ftxui::flexbox`.
children are put side by side. If the container is flexible, the extra space
available will be shared among the remaining flexible children. [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()` ![image](https://user-images.githubusercontent.com/4759106/147242524-7103b5d9-1a92-4e2d-ac70-b3d6740061e3.png)
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: ![image](https://user-images.githubusercontent.com/4759106/147242972-0db1f2e9-0790-496f-86e6-ed2c604f7a73.png)
* hflow (Horizontal flow)
[Example](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/dom/hflow.cpp) using flexbox:
![image](https://user-images.githubusercontent.com/4759106/147243064-780ac7cc-605b-475f-94b8-cf7c4aed03a5.png)
[See](https://arthursonzogni.github.io/FTXUI/examples_2dom_2hflow_8cpp-example.html) also this [demo](https://arthursonzogni.com/FTXUI/examples/?file=component/flexbox).
Element can become flexible using the the `ftxui::flex` decorator.
**Examples** **Examples**
~~~cpp ~~~cpp
@@ -372,11 +499,39 @@ An horizontal flow layout is implemented by:
└────┘└───────────────────────────────────┘└───────────────────────────────────┘ └────┘└───────────────────────────────────┘└───────────────────────────────────┘
~~~ ~~~
## Table {#dom-table}
# component A class to easily style a table of data.
The `ftxui/component` directory defines the logic to get produce [Example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2table_8cpp-example.html):
interactive component responding to user's events (keyboard, mouse, etc...)
![image](https://user-images.githubusercontent.com/4759106/147250766-77d8ec9e-cf2b-486d-9866-1fd9f1bd2e6b.png)
## Canvas {#dom-canvas}
See [<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 made on a `ftxui::Canvas`, using braille, block, or simple
characters:
Simple [example](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/dom/canvas.cpp):
![image](https://user-images.githubusercontent.com/4759106/147245843-76cc62fb-ccb4-421b-aacf-939f9afb42fe.png)
Complex [examples](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/component/canvas_animated.cpp):
![ezgif com-gif-maker (3)](https://user-images.githubusercontent.com/4759106/147250538-783a8246-98e0-4a25-b032-3bd3710549d1.gif)
# component {#module-component}
The `ftxui::component`module defines the logic to produce interactive component
responding to user's events (keyboard, mouse, etc...)
A `ftxui::ScreenInteractive` defines a main loop to render a component. A `ftxui::ScreenInteractive` defines a main loop to render a component.
@@ -388,15 +543,23 @@ defines
two component. This defines a tree a components, which help properly define two component. This defines a tree a components, which help properly define
how keyboard navigation works. how keyboard navigation works.
Predefined components are available in `ftxui/dom/component.hpp`: `ftxui::Element` are used to render a single frame. On the other side
`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.com/FTXUI/examples/?file=component/gallery))
![image](https://user-images.githubusercontent.com/4759106/147247330-b60beb9f-e665-48b4-81c0-4b01ee95bc66.png)
Predefined components are available in ["ftxui/dom/component.hpp"](./component_8hpp.html)
\include ftxui/component/component.hpp \include ftxui/component/component.hpp
Element are stateless object. On the other side, components are used when an ## Input {#component-input}
internal state is needed. Components are used to interact with the user with
its keyboard. They handle keyboard navigation, including component focus.
## Input [Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2input_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147247671-f1d6f606-1845-4e94-a4a0-d4273e9ae6bd.png)
Produced by: `ftxui::Input()` from "ftxui/component/component.hpp" Produced by: `ftxui::Input()` from "ftxui/component/component.hpp"
@@ -404,7 +567,12 @@ Produced by: `ftxui::Input()` from "ftxui/component/component.hpp"
<script id="asciicast-223719" src="https://asciinema.org/a/223719.js" async></script> <script id="asciicast-223719" src="https://asciinema.org/a/223719.js" async></script>
@endhtmlonly @endhtmlonly
## Menu ## Menu {#component-menu}
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2menu_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147247822-0035fd6f-bb13-4b3a-b057-77eb9291582f.png)
Produced by: `ftxui::Menu()` from "ftxui/component/component.hpp" Produced by: `ftxui::Menu()` from "ftxui/component/component.hpp"
@@ -412,7 +580,11 @@ Produced by: `ftxui::Menu()` from "ftxui/component/component.hpp"
<script id="asciicast-223720" src="https://asciinema.org/a/223720.js" async></script> <script id="asciicast-223720" src="https://asciinema.org/a/223720.js" async></script>
@endhtmlonly @endhtmlonly
## Toggle. ## Toggle {#component-toggle}
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2toggle_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147249383-e2201cf1-b7b8-4a5a-916f-d761e3e7ae40.png)
Produced by: `ftxui::Toggle()` from "ftxui/component/component.hpp" Produced by: `ftxui::Toggle()` from "ftxui/component/component.hpp"
@@ -420,7 +592,11 @@ Produced by: `ftxui::Toggle()` from "ftxui/component/component.hpp"
<script id="asciicast-223722" src="https://asciinema.org/a/223722.js" async></script> <script id="asciicast-223722" src="https://asciinema.org/a/223722.js" async></script>
@endhtmlonly @endhtmlonly
## CheckBox ## CheckBox {#component-checkbox}
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2checkbox_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147246646-b86926a9-1ef9-4efb-af98-48a9b62acd81.png)
Produced by: `ftxui::Checkbox()` from "ftxui/component/component.hpp" Produced by: `ftxui::Checkbox()` from "ftxui/component/component.hpp"
@@ -428,7 +604,11 @@ Produced by: `ftxui::Checkbox()` from "ftxui/component/component.hpp"
<script id="asciicast-223724" src="https://asciinema.org/a/223724.js" async></script> <script id="asciicast-223724" src="https://asciinema.org/a/223724.js" async></script>
@endhtmlonly @endhtmlonly
## RadioBox ## RadioBox {#component-radiobox}
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2radiobox_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147246401-809d14a5-6621-4e36-8dd9-a2d75ef2a94e.png)
Produced by: `ftxui::Radiobox()` from "ftxui/component/component.hpp" Produced by: `ftxui::Radiobox()` from "ftxui/component/component.hpp"
@@ -436,37 +616,154 @@ Produced by: `ftxui::Radiobox()` from "ftxui/component/component.hpp"
<script id="asciicast-223725" src="https://asciinema.org/a/223725.js" async></script> <script id="asciicast-223725" src="https://asciinema.org/a/223725.js" async></script>
@endhtmlonly @endhtmlonly
## Renderer ## Dropdown {#component-dropdown}
Produced by: `ftxui::Renderer()` from \ref "ftxui/component/component.hpp". This [Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2dropdown_8cpp-example.html):
![youtube-video-gif (3)](https://user-images.githubusercontent.com/4759106/147246982-1e821751-531c-4e1f-bc37-2fa290e143cd.gif)
Produced by: `ftxui::Dropdown()` from "ftxui/component/component.hpp"
## Slider {#component-slider}
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2slider_8cpp-example.html):
![image](https://user-images.githubusercontent.com/4759106/147249265-7e2cad75-082c-436e-affe-44a550c480ab.png)
Produced by: `ftxui::Slider()` from "ftxui/component/component.hpp"
## Renderer {#component-renderer}
Produced by: `ftxui::Renderer()` from \ref 'ftxui/component/component.hpp'. This
component decorate another one by using a different function to render an component decorate another one by using a different function to render an
interface. interface.
## CatchEvent Example:
```cpp
auto inner = [...]
Produced by: `ftxui::CatchEvent()` from \ref "ftxui/component/component.hpp". auto renderer = Renderer(inner, [&] {
return inner->Render() | border
});
```
`ftxui::Renderer` also support 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 another one and catch the events before the underlying This component decorate another one and catch the events before the underlying
component. component.
## Container::Horizontal 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 section whose visibility can be toggle on/off by the user.
This is basically, a combinaison of a `ftxui::Checkbox` and a `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 decorate another one, by showing/hiding it depending on 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; })
```
`ftxui::Maybe` can be used as a decorator.
```
component = component
| Maybe(&a_boolean)
| Maybe([&] { return time > 10; })
;
```
## Container {#component-container}
### Horizontal {#component-horizontal}
Produced by: `ftxui::Container::Horizontal()` from Produced by: `ftxui::Container::Horizontal()` from
"ftxui/component/component.hpp". It displays a list of components horizontally "ftxui/component/component.hpp". It displays a list of components horizontally
and handle keyboard/mouse navigation. and handle keyboard/mouse navigation.
## Container::Vertial ### Vertical {#component-vertical}
Produced by: `ftxui::Container::Vertical()` from Produced by: `ftxui::Container::Vertical()` from
"ftxui/component/component.hpp". It displays a list of components vertically "ftxui/component/component.hpp". It displays a list of components vertically
and handles keyboard/mouse navigation. and handles keyboard/mouse navigation.
## Container::Tab ### Tab {#component-tab}
Produced by: `ftxui::Container::Tab()` from Produced by: `ftxui::Container::Tab()` from
"ftxui/component/component.hpp". It take a list of component and display only "ftxui/component/component.hpp". It take a list of component and display only
one of them. This is useful for implementing a tab bar. 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):
![ezgif com-gif-maker (1)](https://user-images.githubusercontent.com/4759106/147250144-22ff044a-4773-4ff7-a49c-12ba4034acb4.gif)
[Horizontal](https://arthursonzogni.github.io/FTXUI/examples_2component_2tab_horizontal_8cpp-example.html):
![ezgif com-gif-maker (2)](https://user-images.githubusercontent.com/4759106/147250217-fe447e0f-7a99-4e08-948a-995087d9b40e.gif)
## ResizableSplit::{Left, Right, Top, Bottom} {#component-resizable-split}
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2resizable_split_8cpp-example.html):
![ezgif com-gif-maker](https://user-images.githubusercontent.com/4759106/147248372-c55512fe-9b96-4b08-a1df-d05cf2cae431.gif)
Produced by: Produced by:
- `ftxui::ResizableSplitLeft()` - `ftxui::ResizableSplitLeft()`
@@ -483,7 +780,7 @@ mouse.
<script id="asciicast-tprMH2EdkUoMb7D2YxgMGgpzx" src="https://asciinema.org/a/tprMH2EdkUoMb7D2YxgMGgpzx.js" async></script> <script id="asciicast-tprMH2EdkUoMb7D2YxgMGgpzx" src="https://asciinema.org/a/tprMH2EdkUoMb7D2YxgMGgpzx.js" async></script>
@endhtmlonly @endhtmlonly
## Force a frame redraw. ## Force a frame redraw. {#component-force-redraw}
Whenever a new group of events have been processed: keyboard, mouse, window Whenever a new group of events have been processed: keyboard, mouse, window
resize, etc..., the `ftxui::ScreenInteractive::Loop()` is responsible for resize, etc..., the `ftxui::ScreenInteractive::Loop()` is responsible for

View File

@@ -1,7 +1,7 @@
set(EXAMPLES_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(EXAMPLES_DIR ${CMAKE_CURRENT_SOURCE_DIR})
function(example name) function(example name)
add_executable(${name} ${name}.cpp) add_executable(ftxui_example_${name} ${name}.cpp)
target_link_libraries(${name} PUBLIC ${DIRECTORY_LIB}) target_link_libraries(ftxui_example_${name} PUBLIC ${DIRECTORY_LIB})
file(RELATIVE_PATH dir ${EXAMPLES_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) file(RELATIVE_PATH dir ${EXAMPLES_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
set_property(GLOBAL APPEND PROPERTY FTXUI::EXAMPLES ${dir}/${name}) set_property(GLOBAL APPEND PROPERTY FTXUI::EXAMPLES ${dir}/${name})
endfunction(example) endfunction(example)
@@ -10,6 +10,12 @@ add_subdirectory(component)
add_subdirectory(dom) add_subdirectory(dom)
if (EMSCRIPTEN) 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) get_property(EXAMPLES GLOBAL PROPERTY FTXUI::EXAMPLES)
foreach(file foreach(file
"index.html" "index.html"

View File

@@ -1,10 +1,17 @@
set(DIRECTORY_LIB component) set(DIRECTORY_LIB component)
example(button) example(button)
example(button_animated)
example(button_in_frame)
example(button_style)
example(canvas_animated)
example(checkbox) example(checkbox)
example(checkbox_in_frame) example(checkbox_in_frame)
example(collapsible)
example(composition) example(composition)
example(dropdown) example(dropdown)
example(flexbox_gallery)
example(focus)
example(gallery) example(gallery)
example(homescreen) example(homescreen)
example(input) example(input)
@@ -12,9 +19,11 @@ example(maybe)
example(menu) example(menu)
example(menu2) example(menu2)
example(menu_entries) example(menu_entries)
example(menu_entries_animated)
example(menu_in_frame) example(menu_in_frame)
example(menu_multiple) example(menu_multiple)
example(menu_style) example(menu_style)
example(menu_underline_animated_gallery)
example(modal_dialog) example(modal_dialog)
example(nested_screen) example(nested_screen)
example(print_key_press) example(print_key_press)
@@ -27,3 +36,4 @@ example(slider_rgb)
example(tab_horizontal) example(tab_horizontal)
example(tab_vertical) example(tab_vertical)
example(toggle) example(toggle)
example(with_restored_io)

View File

@@ -1,12 +1,11 @@
#include <memory> // for shared_ptr, __shared_ptr_access #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/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Button, Horizontal, Renderer #include "ftxui/component/component.hpp" // for Button, Horizontal, Renderer
#include "ftxui/component/component_base.hpp" // for ComponentBase #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/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; using namespace ftxui;
@@ -14,13 +13,9 @@ int main(int argc, const char* argv[]) {
int value = 50; int value = 50;
// The tree of components. This defines how to navigate using the keyboard. // The tree of components. This defines how to navigate using the keyboard.
auto button_option = ButtonOption();
button_option.border = false;
auto buttons = Container::Horizontal({ auto buttons = Container::Horizontal({
Button( Button("Decrease", [&] { value--; }),
"[Decrease]", [&] { value--; }, &button_option), Button("Increase", [&] { value++; }),
Button(
"[Increase]", [&] { value++; }, &button_option),
}); });
// Modify the way to render them on screen: // Modify the way to render them on screen:

View 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.

View 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.

View File

@@ -0,0 +1,62 @@
#include <memory> // for shared_ptr
#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 separator, Element, 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.

View 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.

View File

@@ -1,25 +1,31 @@
#include "ftxui/component/captured_mouse.hpp" // for ftxui #include <memory> // for allocator, __shared_ptr_access
#include "ftxui/component/component.hpp" // for Checkbox, Vertical #include <string> // for string, basic_string, operator+, to_string
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive #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[]) { int main(int argc, const char* argv[]) {
bool build_examples_state = false; using namespace ftxui;
bool build_tests_state = false;
bool use_webassembly_state = true;
auto component = Container::Vertical({ Component input_list = Container::Vertical({});
Checkbox("Build examples", &build_examples_state), std::vector<std::string> items(100, "");
Checkbox("Build tests", &build_tests_state), for (int i = 0; i < items.size(); ++i) {
Checkbox("Use WebAssembly", &use_webassembly_state), 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(); auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(component); screen.Loop(renderer);
return 0;
} }
// 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 // Use of this source code is governed by the MIT license that can be found in
// the LICENSE file. // the LICENSE file.

View 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 <string> // for operator+, to_string
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui #include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Checkbox, Renderer, Vertical #include "ftxui/component/component.hpp" // for Checkbox, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase #include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive #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; using namespace ftxui;
struct CheckboxState {
bool checked;
};
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
std::vector<CheckboxState> states(30); std::array<bool, 30> states;
auto container = Container::Vertical({}); auto container = Container::Vertical({});
for (int i = 0; i < 30; ++i) { for (int i = 0; i < 30; ++i) {
states[i].checked = false; states[i] = false;
container->Add( container->Add(Checkbox("Checkbox" + std::to_string(i), &states[i]));
Checkbox("Checkbox" + std::to_string(i), &states[i].checked));
} }
auto renderer = Renderer(container, [&] { auto renderer = Renderer(container, [&] {

View 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.

View File

@@ -4,7 +4,6 @@
#include "ftxui/component/captured_mouse.hpp" // for ftxui #include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Button, Horizontal, Renderer #include "ftxui/component/component.hpp" // for Button, Horizontal, Renderer
#include "ftxui/component/component_base.hpp" // for ComponentBase #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/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for text, separator, Element, operator|, vbox, border #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 // An example of how to compose multiple components into one and maintain their
// interactiveness. // interactiveness.
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
auto button_option = ButtonOption();
button_option.border = false;
auto left_count = 0; auto left_count = 0;
auto right_count = 0; auto right_count = 0;
auto left_buttons = Container::Horizontal({ auto left_buttons = Container::Horizontal({
Button( Button("Decrease", [&] { left_count--; }),
"[Decrease]", [&] { left_count--; }, &button_option), Button("Increase", [&] { left_count++; }),
Button(
"[Increase]", [&] { left_count++; }, &button_option),
}); });
auto right_buttons = Container::Horizontal({ auto right_buttons = Container::Horizontal({
Button( Button("Decrease", [&] { right_count--; }),
"[Decrease]", [&] { right_count--; }, &button_option), Button("Increase", [&] { right_count++; }),
Button(
"[Increase]", [&] { right_count++; }, &button_option),
}); });
// Renderer decorates its child with a new rendering function. The way the // Renderer decorates its child with a new rendering function. The way the

View File

@@ -1,26 +1,23 @@
#include <functional> // for function #include <string> // for basic_string, string, allocator
#include <iostream> // for basic_ostream::operator<<, operator<<, endl, basic_ostream, basic_ostream<>::__ostream_type, cout, ostream #include <vector> // for vector
#include <string> // for string, basic_string, allocator
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui #include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Menu #include "ftxui/component/component.hpp" // for Dropdown, Horizontal, Vertical
#include "ftxui/component/component_options.hpp" // for MenuOption
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive #include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;
std::vector<std::string> entries = { std::vector<std::string> entries = {
"tribute", "clearance", "ally", "bend", "electronics", "tribute", "clearance", "ally", "bend", "electronics",
"module", "era", "cultural", "sniff", "nationalism", "module", "era", "cultural", "sniff", "nationalism",
"negotiation", "deliver", "figure", "east", "negotiation", "deliver", "figure", "east", "tribute",
"tribute", "clearance", "ally", "bend", "electronics", "clearance", "ally", "bend", "electronics", "module",
"module", "era", "cultural", "sniff", "nationalism", "era", "cultural", "sniff", "nationalism", "negotiation",
"negotiation", "deliver", "figure", "east", "deliver", "figure", "east", "tribute", "clearance",
"tribute", "clearance", "ally", "bend", "electronics", "ally", "bend", "electronics", "module", "era",
"module", "era", "cultural", "sniff", "nationalism", "cultural", "sniff", "nationalism", "negotiation", "deliver",
"negotiation", "deliver", "figure", "east", "figure", "east",
}; };
int selected_1 = 0; int selected_1 = 0;

View 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.

View 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.

View File

@@ -1,27 +1,34 @@
#include <stddef.h> // for size_t
#include <array> // for array #include <array> // for array
#include <chrono> // for operator""s, chrono_literals #include <chrono> // for operator""s, chrono_literals
#include <cmath> // for sin #include <cmath> // for sin
#include <functional> // for ref, reference_wrapper, function #include <functional> // for ref, reference_wrapper, function
#include <memory> // for allocator, shared_ptr, __shared_ptr_access #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, operator+, to_string, char_traits
#include <thread> // for sleep_for, thread #include <thread> // for sleep_for, thread
#include <utility> // for move #include <utility> // for move
#include <vector> // for vector #include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui #include "../dom/color_info_sorted_2d.ipp" // for ColorInfoSorted2D
#include "ftxui/component/component.hpp" // for Checkbox, Renderer, Horizontal, Vertical, Menu, Radiobox, Tab, Toggle #include "ftxui/component/component.hpp" // for Checkbox, Renderer, Horizontal, Vertical, Input, Menu, Radiobox, ResizableSplitLeft, Tab
#include "ftxui/component/component_base.hpp" // for ComponentBase #include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/component_options.hpp" // for InputOption #include "ftxui/component/component_options.hpp" // for MenuOption, InputOption
#include "ftxui/component/event.hpp" // for Event, Event::Custom #include "ftxui/component/event.hpp" // for Event, Event::Custom
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive #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/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/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/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; using namespace ftxui;
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
auto screen = ScreenInteractive::Fullscreen(); auto screen = ScreenInteractive::Fullscreen();
// ---------------------------------------------------------------------------
// HTOP
// ---------------------------------------------------------------------------
int shift = 0; int shift = 0;
auto my_graph = [&shift](int width, int height) { auto my_graph = [&shift](int width, int height) {
@@ -89,9 +96,13 @@ int main(int argc, const char* argv[]) {
separator(), separator(),
ram | flex, ram | flex,
}) | }) |
flex | border; flex;
}); });
// ---------------------------------------------------------------------------
// Compiler
// ---------------------------------------------------------------------------
const std::vector<std::string> compiler_entries = { const std::vector<std::string> compiler_entries = {
"gcc", "gcc",
"clang", "clang",
@@ -245,64 +256,128 @@ int main(int argc, const char* argv[]) {
}) | size(HEIGHT, LESS_THAN, 8), }) | size(HEIGHT, LESS_THAN, 8),
hflow(render_command()) | flex_grow, hflow(render_command()) | flex_grow,
}) | }) |
flex_grow | border; flex_grow;
}); });
// ---------------------------------------------------------------------------
// Spiner
// ---------------------------------------------------------------------------
auto spinner_tab_renderer = Renderer([&] { auto spinner_tab_renderer = Renderer([&] {
Elements entries; Elements entries;
for (int i = 0; i < 22; ++i) { for (int i = 0; i < 22; ++i) {
entries.push_back(spinner(i, shift / 2) | bold | entries.push_back(spinner(i, shift / 2) | bold |
size(WIDTH, GREATER_THAN, 2) | border); size(WIDTH, GREATER_THAN, 2) | border);
} }
return hflow(std::move(entries)) | border; return hflow(std::move(entries));
}); });
// ---------------------------------------------------------------------------
// Colors
// ---------------------------------------------------------------------------
auto color_tab_renderer = Renderer([] { auto color_tab_renderer = Renderer([] {
return hbox({ auto basic_color_display =
vbox({ vbox({
color(Color::Default, text("Default")), text("16 color palette:"),
color(Color::Black, text("Black")), separator(),
color(Color::GrayDark, text("GrayDark")), hbox({
color(Color::GrayLight, text("GrayLight")), vbox({
color(Color::White, text("White")), color(Color::Default, text("Default")),
color(Color::Blue, text("Blue")), color(Color::Black, text("Black")),
color(Color::BlueLight, text("BlueLight")), color(Color::GrayDark, text("GrayDark")),
color(Color::Cyan, text("Cyan")), color(Color::GrayLight, text("GrayLight")),
color(Color::CyanLight, text("CyanLight")), color(Color::White, text("White")),
color(Color::Green, text("Green")), color(Color::Blue, text("Blue")),
color(Color::GreenLight, text("GreenLight")), color(Color::BlueLight, text("BlueLight")),
color(Color::Magenta, text("Magenta")), color(Color::Cyan, text("Cyan")),
color(Color::MagentaLight, text("MagentaLight")), color(Color::CyanLight, text("CyanLight")),
color(Color::Red, text("Red")), color(Color::Green, text("Green")),
color(Color::RedLight, text("RedLight")), color(Color::GreenLight, text("GreenLight")),
color(Color::Yellow, text("Yellow")), color(Color::Magenta, text("Magenta")),
color(Color::YellowLight, text("YellowLight")), color(Color::MagentaLight, text("MagentaLight")),
}), color(Color::Red, text("Red")),
vbox({ color(Color::RedLight, text("RedLight")),
bgcolor(Color::Default, text("Default")), color(Color::Yellow, text("Yellow")),
bgcolor(Color::Black, text("Black")), color(Color::YellowLight, text("YellowLight")),
bgcolor(Color::GrayDark, text("GrayDark")), }),
bgcolor(Color::GrayLight, text("GrayLight")), vbox({
bgcolor(Color::White, text("White")), bgcolor(Color::Default, text("Default")),
bgcolor(Color::Blue, text("Blue")), bgcolor(Color::Black, text("Black")),
bgcolor(Color::BlueLight, text("BlueLight")), bgcolor(Color::GrayDark, text("GrayDark")),
bgcolor(Color::Cyan, text("Cyan")), bgcolor(Color::GrayLight, text("GrayLight")),
bgcolor(Color::CyanLight, text("CyanLight")), bgcolor(Color::White, text("White")),
bgcolor(Color::Green, text("Green")), bgcolor(Color::Blue, text("Blue")),
bgcolor(Color::GreenLight, text("GreenLight")), bgcolor(Color::BlueLight, text("BlueLight")),
bgcolor(Color::Magenta, text("Magenta")), bgcolor(Color::Cyan, text("Cyan")),
bgcolor(Color::MagentaLight, text("MagentaLight")), bgcolor(Color::CyanLight, text("CyanLight")),
bgcolor(Color::Red, text("Red")), bgcolor(Color::Green, text("Green")),
bgcolor(Color::RedLight, text("RedLight")), bgcolor(Color::GreenLight, text("GreenLight")),
bgcolor(Color::Yellow, text("Yellow")), bgcolor(Color::Magenta, text("Magenta")),
bgcolor(Color::YellowLight, text("YellowLight")), bgcolor(Color::MagentaLight, text("MagentaLight")),
}), bgcolor(Color::Red, text("Red")),
}) | bgcolor(Color::RedLight, text("RedLight")),
hcenter | border; 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) { auto render_gauge = [&shift](int delta) {
float progress = (shift + delta) % 1000 / 1000.f; float progress = (shift + delta) % 500 / 500.f;
return hbox({ return hbox({
text(std::to_string(int(progress * 100)) + "% ") | text(std::to_string(int(progress * 100)) + "% ") |
size(WIDTH, EQUAL, 5), size(WIDTH, EQUAL, 5),
@@ -312,32 +387,94 @@ int main(int argc, const char* argv[]) {
auto gauge_component = Renderer([render_gauge] { auto gauge_component = Renderer([render_gauge] {
return vbox({ return vbox({
render_gauge(0) | color(Color::Black), render_gauge(0) | color(Color::Black),
render_gauge(100) | color(Color::GrayDark), render_gauge(100) | color(Color::GrayDark),
render_gauge(50) | color(Color::GrayLight), render_gauge(50) | color(Color::GrayLight),
render_gauge(6894) | color(Color::White), render_gauge(6894) | color(Color::White),
separator(), separator(),
render_gauge(6841) | color(Color::Blue), render_gauge(6841) | color(Color::Blue),
render_gauge(9813) | color(Color::BlueLight), render_gauge(9813) | color(Color::BlueLight),
render_gauge(98765) | color(Color::Cyan), render_gauge(98765) | color(Color::Cyan),
render_gauge(98) | color(Color::CyanLight), render_gauge(98) | color(Color::CyanLight),
render_gauge(9846) | color(Color::Green), render_gauge(9846) | color(Color::Green),
render_gauge(1122) | color(Color::GreenLight), render_gauge(1122) | color(Color::GreenLight),
render_gauge(84) | color(Color::Magenta), render_gauge(84) | color(Color::Magenta),
render_gauge(645) | color(Color::MagentaLight), render_gauge(645) | color(Color::MagentaLight),
render_gauge(568) | color(Color::Red), render_gauge(568) | color(Color::Red),
render_gauge(2222) | color(Color::RedLight), render_gauge(2222) | color(Color::RedLight),
render_gauge(220) | color(Color::Yellow), render_gauge(220) | color(Color::Yellow),
render_gauge(348) | color(Color::YellowLight), render_gauge(348) | color(Color::YellowLight),
}) | });
border;
}); });
// ---------------------------------------------------------------------------
// Paragraph
// ---------------------------------------------------------------------------
auto make_box = [](size_t dimx, size_t dimy) {
std::string title = std::to_string(dimx) + "x" + std::to_string(dimy);
return window(text(title) | hcenter | bold,
text("content") | hcenter | dim) |
size(WIDTH, EQUAL, dimx) | size(HEIGHT, EQUAL, dimy);
};
auto paragraph_renderer_left = Renderer([&] {
std::string str =
"Lorem Ipsum is simply dummy text of the printing and typesetting "
"industry. Lorem Ipsum has been the industry's standard dummy text "
"ever since the 1500s, when an unknown printer took a galley of type "
"and scrambled it to make a type specimen book.";
return vbox({
window(text("Align left:"), paragraphAlignLeft(str)),
window(text("Align center:"), paragraphAlignCenter(str)),
window(text("Align right:"), paragraphAlignRight(str)),
window(text("Align justify:"), paragraphAlignJustify(str)),
window(text("Side by side"), hbox({
paragraph(str),
separator(),
paragraph(str),
})),
window(text("Elements with different size:"),
flexbox({
make_box(10, 5),
make_box(9, 4),
make_box(8, 4),
make_box(6, 3),
make_box(10, 5),
make_box(9, 4),
make_box(8, 4),
make_box(6, 3),
make_box(10, 5),
make_box(9, 4),
make_box(8, 4),
make_box(6, 3),
})),
}) |
vscroll_indicator | yframe | flex;
});
auto paragraph_renderer_right = Renderer([] {
return paragraph("<--- This vertical bar is resizable using the mouse") |
center;
});
int paragraph_renderer_split_position = Terminal::Size().dimx / 2;
auto paragraph_renderer_group =
ResizableSplitLeft(paragraph_renderer_left, paragraph_renderer_right,
&paragraph_renderer_split_position);
auto paragraph_renderer_group_renderer =
Renderer(paragraph_renderer_group,
[&] { return paragraph_renderer_group->Render(); });
// ---------------------------------------------------------------------------
// Tabs
// ---------------------------------------------------------------------------
int tab_index = 0; int tab_index = 0;
std::vector<std::string> tab_entries = { 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( auto tab_content = Container::Tab(
{ {
htop, htop,
@@ -345,6 +482,7 @@ int main(int argc, const char* argv[]) {
spinner_tab_renderer, spinner_tab_renderer,
gauge_component, gauge_component,
compiler_renderer, compiler_renderer,
paragraph_renderer_group_renderer,
}, },
&tab_index); &tab_index);
@@ -356,7 +494,7 @@ int main(int argc, const char* argv[]) {
auto main_renderer = Renderer(main_container, [&] { auto main_renderer = Renderer(main_container, [&] {
return vbox({ return vbox({
text("FTXUI Demo") | bold | hcenter, text("FTXUI Demo") | bold | hcenter,
tab_selection->Render() | hcenter, tab_selection->Render(),
tab_content->Render() | flex, tab_content->Render() | flex,
}); });
}); });

View File

@@ -1,20 +1,17 @@
#include <functional> // for function #include <memory> // for shared_ptr
#include <iostream> // for basic_ostream::operator<<, operator<<, endl, basic_ostream, basic_ostream<>::__ostream_type, cout, ostream #include <string> // for string, basic_string, allocator
#include <string> // for string, basic_string, allocator #include <vector> // for vector
#include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui #include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for Menu #include "ftxui/component/component.hpp" // for operator|, Maybe, Checkbox, Radiobox, Renderer, Vertical
#include "ftxui/component/component_options.hpp" // for MenuOption #include "ftxui/component/component_base.hpp" // for Component
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive #include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for border, color, operator|, text, Element
#include "ftxui/screen/color.hpp" // for Color, Color::Red
using namespace ftxui; using namespace ftxui;
Component Border(Component child) {
return Renderer(child, [child] { return child->Render() | border; });
}
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
std::vector<std::string> entries = { std::vector<std::string> entries = {
"entry 1", "entry 1",
"entry 2", "entry 2",
@@ -22,20 +19,19 @@ int main(int argc, const char* argv[]) {
}; };
int menu_1_selected = 0; int menu_1_selected = 0;
int menu_2_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_1_show = false;
bool menu_2_show = false; bool menu_2_show = false;
auto layout = Container::Vertical({ auto layout = Container::Vertical({
Checkbox("Show menu_1", &menu_1_show), 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), 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(); auto screen = ScreenInteractive::TerminalOutput();

View File

@@ -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 <iostream> // for basic_ostream::operator<<, operator<<, endl, basic_ostream, basic_ostream<>::__ostream_type, cout, ostream
#include <memory> // for shared_ptr, __shared_ptr_access #include <memory> // for allocator, shared_ptr, __shared_ptr_access
#include <string> // for to_string, allocator #include <string> // for char_traits, to_string, operator+, string, basic_string
#include "ftxui/component/captured_mouse.hpp" // for ftxui #include "ftxui/component/captured_mouse.hpp" // for ftxui
#include "ftxui/component/component.hpp" // for MenuEntry, Renderer, Vertical #include "ftxui/component/component.hpp" // for MenuEntry, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase #include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/component_options.hpp" // for MenuEntryOption #include "ftxui/component/component_options.hpp" // for MenuEntryOption
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive #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 #include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::Cyan, Color::Green, Color::Red, Color::Yellow
using namespace ftxui; using namespace ftxui;
// Define a special style for some menu entry. // Define a special style for some menu entry.
MenuEntryOption Colored(ftxui::Color c) { MenuEntryOption Colored(ftxui::Color c) {
MenuEntryOption special_style; MenuEntryOption option;
special_style.style_normal = Decorator(color(c)); option.transform = [c](EntryState state) {
special_style.style_focused = Decorator(color(c)) | inverted; state.label = (state.active ? "> " : " ") + state.label;
special_style.style_selected = Decorator(color(c)) | bold; Element e = text(state.label) | color(c);
special_style.style_selected_focused = Decorator(color(c)) | inverted | bold; if (state.focused)
return special_style; e = e | inverted;
if (state.active)
e = e | bold;
return e;
};
return option;
} }
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {

View 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.

View File

@@ -1,100 +1,258 @@
#include <array> // for array
#include <chrono> // for milliseconds
#include <functional> // for function #include <functional> // for function
#include <memory> // for shared_ptr, __shared_ptr_access, allocator #include <memory> // for shared_ptr, __shared_ptr_access, allocator
#include <string> // for string, basic_string #include <string> // for string, char_traits, basic_string, operator+
#include <vector> // for vector #include <vector> // for vector
#include "ftxui/component/captured_mouse.hpp" // for ftxui #include "ftxui/component/animation.hpp" // for ElasticOut, Linear
#include "ftxui/component/component.hpp" // for Menu, Horizontal, Renderer #include "ftxui/component/component.hpp" // for Menu, Horizontal, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase #include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/component_options.hpp" // for MenuOption #include "ftxui/component/component_options.hpp" // for MenuOption, MenuEntryOption, AnimatedColorOption, AnimatedColorsOption, UnderlineOption
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive #include "ftxui/component/mouse.hpp" // for ftxui
#include "ftxui/dom/elements.hpp" // for operator|, color, separator, Decorator, bgcolor, flex, Element, bold, hbox, border, dim #include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::BlueLight, Color::Red, Color::Yellow #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[]) { int main(int argc, const char* argv[]) {
using namespace ftxui;
auto screen = ScreenInteractive::TerminalOutput(); auto screen = ScreenInteractive::TerminalOutput();
std::vector<std::string> entries = { std::vector<std::string> entries{
"Monkey", "Dog", "Cat", "Bird", "Elephant", "Monkey", "Dog", "Cat", "Bird", "Elephant", "Cat",
}; };
int menu_1_selected_ = 0; std::array<int, 12> selected = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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;
MenuOption option_1; auto vmenu_1_ = VMenu1(&entries, &selected[0]);
option_1.style_focused = bold | color(Color::Blue); auto vmenu_2_ = VMenu2(&entries, &selected[1]);
option_1.style_selected = color(Color::Blue); auto vmenu_3_ = VMenu3(&entries, &selected[2]);
option_1.style_selected_focused = bold | color(Color::Blue); auto vmenu_4_ = VMenu4(&entries, &selected[3]);
option_1.on_enter = screen.ExitLoopClosure(); auto vmenu_5_ = VMenu5(&entries, &selected[4]);
auto menu_1_ = Menu(&entries, &menu_1_selected_, &option_1); auto vmenu_6_ = VMenu6(&entries, &selected[5]);
auto vmenu_7_ = VMenu7(&entries, &selected[6]);
auto vmenu_8_ = VMenu8(&entries, &selected[7]);
MenuOption option_2; auto hmenu_1_ = HMenu1(&entries, &selected[8]);
option_2.style_focused = bold | color(Color::Blue); auto hmenu_2_ = HMenu2(&entries, &selected[9]);
option_2.style_selected = color(Color::Blue); auto hmenu_3_ = HMenu3(&entries, &selected[10]);
option_2.style_selected_focused = bold | color(Color::Blue); auto hmenu_4_ = HMenu4(&entries, &selected[11]);
option_2.on_enter = screen.ExitLoopClosure(); auto hmenu_5_ = HMenu5(&entries, &selected[12]);
auto menu_2_ = Menu(&entries, &menu_2_selected_, &option_2);
MenuOption option_3; auto container = Container::Vertical({
option_3.style_selected = color(Color::Blue); Container::Horizontal({
option_3.style_focused = bgcolor(Color::Blue); vmenu_1_,
option_3.style_selected_focused = bgcolor(Color::Blue); vmenu_2_,
option_3.on_enter = screen.ExitLoopClosure(); vmenu_3_,
auto menu_3_ = Menu(&entries, &menu_3_selected_, &option_3); vmenu_4_,
vmenu_5_,
MenuOption option_4; vmenu_6_,
option_4.style_selected = bgcolor(Color::Blue); vmenu_7_,
option_4.style_focused = bgcolor(Color::BlueLight); vmenu_8_,
option_4.style_selected_focused = bgcolor(Color::BlueLight); }),
option_4.on_enter = screen.ExitLoopClosure(); hmenu_1_,
auto menu_4_ = Menu(&entries, &menu_4_selected_, &option_4); hmenu_2_,
hmenu_3_,
MenuOption option_5; hmenu_4_,
option_5.style_normal = bgcolor(Color::Blue); hmenu_5_,
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_,
}); });
// clang-format off
auto renderer = Renderer(container, [&] { auto renderer = Renderer(container, [&] {
return return //
hbox({ hbox({
menu_1_->Render() | flex, separator(), vbox({
menu_2_->Render() | flex, separator(), hbox({
menu_3_->Render() | flex, separator(), vmenu_1_->Render(),
menu_4_->Render() | flex, separator(), separator(),
menu_5_->Render() | flex, separator(), vmenu_2_->Render(),
menu_6_->Render() | flex, separator(),
}) | border; 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); 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. // Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in // Use of this source code is governed by the MIT license that can be found in
// the LICENSE file. // the LICENSE file.

View File

@@ -0,0 +1,94 @@
#include <chrono> // for operator""ms, literals
#include <memory> // for shared_ptr, __shared_ptr_access, allocator
#include <string> // for string, basic_string, operator+, to_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.

View File

@@ -84,7 +84,7 @@ int main(int argc, const char* argv[]) {
return window(text("keys"), vbox(std::move(children))); return window(text("keys"), vbox(std::move(children)));
}); });
component = CatchEvent(component, [&](Event event) { component |= CatchEvent([&](Event event) {
keys.push_back(event); keys.push_back(event);
return true; return true;
}); });

View 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.

View File

@@ -3,9 +3,15 @@ set(DIRECTORY_LIB dom)
example(border) example(border)
example(border_style) example(border_style)
example(color_gallery) example(color_gallery)
example(color_info_palette256)
example(color_truecolor_HSV)
example(color_truecolor_RGB)
example(dbox) example(dbox)
example(canvas)
example(gauge) example(gauge)
example(gauge_direction)
example(graph) example(graph)
example(gridbox)
example(hflow) example(hflow)
example(html_like) example(html_like)
example(package_manager) example(package_manager)
@@ -17,13 +23,11 @@ example(spinner)
example(style_blink) example(style_blink)
example(style_bold) example(style_bold)
example(style_color) example(style_color)
example(color_truecolor_RGB)
example(color_truecolor_HSV)
example(color_info_palette256)
example(style_dim) example(style_dim)
example(gridbox)
example(style_gallery) example(style_gallery)
example(style_inverted) example(style_inverted)
example(style_underlined) example(style_underlined)
example(table)
example(vbox_hbox) example(vbox_hbox)
example(vflow)
example(window) example(window)

View File

@@ -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/dom/elements.hpp> // for text, operator|, vbox, border, Element, Fit, hbox
#include <ftxui/screen/screen.hpp> // for Full, Screen #include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator #include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) { int main() {
using namespace ftxui; using namespace ftxui;
auto document = // auto document = //
hbox({ hbox({
@@ -30,6 +31,7 @@ int main(int argc, const char* argv[]) {
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document); Render(screen, document);
screen.Print(); screen.Print();
return EXIT_SUCCESS;
} }
// Copyright 2020 Arthur Sonzogni. All rights reserved. // Copyright 2020 Arthur Sonzogni. All rights reserved.

View File

@@ -1,10 +1,10 @@
#include <ftxui/dom/elements.hpp> // for text, operator|, vbox, border, Element, Fit, hbox #include <ftxui/dom/elements.hpp> // for operator|, text, Element, Fit, borderDouble, borderHeavy, borderLight, borderRounded, vbox
#include <ftxui/screen/screen.hpp> // for Full, Screen #include <ftxui/screen/screen.hpp> // for Screen
#include <iostream> #include <iostream> // for endl, cout, ostream
#include <memory> // for allocator #include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

49
examples/dom/canvas.cpp Normal file
View 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.

View File

@@ -5,13 +5,14 @@
#include <utility> // for move #include <utility> // for move
#include <vector> // for vector #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/elements.hpp" // for text, bgcolor, color, vbox, hbox, separator, operator|, Elements, Element, Fit, border
#include "ftxui/dom/node.hpp" // for Render #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 #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 // clang-format off
auto basic_color_display = auto basic_color_display =
vbox( vbox(
@@ -82,14 +83,18 @@ int main(int argc, const char* argv[]) {
// True color display. // True color display.
auto true_color_display = text("TrueColors: 24bits:"); 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; Elements array;
for (int value = 0; value < 255; value += 16) { for (int value = 0; value < max_value; value += 2 * value_increment) {
Elements line; Elements line;
for (int hue = 0; hue < 255; hue += 6) { for (int hue = 0; hue < max_value; hue += hue_increment) {
line.push_back(text("") // line.push_back(
| color(Color::HSV(hue, saturation, value)) // text("") //
| bgcolor(Color::HSV(hue, saturation, value + 8))); | color(Color::HSV(hue, saturation, value)) //
| bgcolor(Color::HSV(hue, saturation, value + value_increment)));
} }
array.push_back(hbox(std::move(line))); array.push_back(hbox(std::move(line)));
} }

View File

@@ -5,8 +5,7 @@
#include <vector> // for vector, allocator #include <vector> // for vector, allocator
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for Color, Color::Palette256, ftxui
#include "ftxui/screen/color.hpp" // for Color, Color::Palette256
using namespace ftxui; using namespace ftxui;
#include "./color_info_sorted_2d.ipp" // for ColorInfoSorted2D #include "./color_info_sorted_2d.ipp" // for ColorInfoSorted2D

View File

@@ -1,12 +1,13 @@
#include <cmath>
#include <algorithm> #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. // Acquire the color information for the palette256.
std::vector<ColorInfo> info_gray; std::vector<ftxui::ColorInfo> info_gray;
std::vector<ColorInfo> info_color; std::vector<ftxui::ColorInfo> info_color;
for (int i = 16; i < 256; ++i) { 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) if (info.saturation == 0)
info_gray.push_back(info); info_gray.push_back(info);
else else
@@ -16,10 +17,10 @@ std::vector<std::vector<ColorInfo>> ColorInfoSorted2D() {
// Sort info_color by hue. // Sort info_color by hue.
std::sort( std::sort(
info_color.begin(), info_color.end(), 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. // 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; info_columns[0] = info_gray;
for (size_t i = 0; i < info_color.size(); ++i) { for (size_t i = 0; i < info_color.size(); ++i) {
info_columns[1 + 7 * i / info_color.size()].push_back(info_color[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. // Minimize discontinuities for every columns.
for (auto& column : info_columns) { for (auto& column : info_columns) {
std::sort(column.begin(), column.end(), 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; 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_index = i + 1;
int best_distance = 255 * 255 * 3; 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 dx = column[i].red - column[j].red;
int dy = column[i].green - column[j].green; int dy = column[i].green - column[j].green;
int dz = column[i].blue - column[j].blue; int dz = column[i].blue - column[j].blue;

View File

@@ -4,8 +4,7 @@
#include <utility> // for move #include <utility> // for move
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for Color, ftxui
#include "ftxui/screen/color.hpp" // for Color
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

View File

@@ -4,8 +4,7 @@
#include <utility> // for move #include <utility> // for move
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for Color, ftxui
#include "ftxui/screen/color.hpp" // for Color
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

View File

@@ -2,8 +2,8 @@
#include <ftxui/screen/screen.hpp> // for Full, Screen #include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator #include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

View File

@@ -5,8 +5,8 @@
#include <string> // for allocator, operator+, char_traits, operator<<, string, to_string, basic_string #include <string> // for allocator, operator+, char_traits, operator<<, string, to_string, basic_string
#include <thread> // for sleep_for #include <thread> // for sleep_for
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

View File

@@ -0,0 +1,79 @@
#include <chrono> // for operator""s, chrono_literals
#include <ftxui/dom/elements.hpp> // for text, gauge, operator|, flex, hbox, Element
#include <ftxui/screen/screen.hpp> // for Screen
#include <iostream> // for cout, endl, ostream
#include <string> // for allocator, operator+, char_traits, operator<<, string, to_string, basic_string
#include <thread> // for sleep_for
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for ftxui
int main(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.

View File

@@ -1,28 +1,28 @@
#include <chrono> #include <chrono> // for operator""s, chrono_literals
#include <cmath> #include <cmath> // for sin
#include <ftxui/dom/elements.hpp> #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> #include <ftxui/screen/screen.hpp> // for Full, Screen
#include <functional> #include <functional> // for ref, reference_wrapper
#include <iostream> #include <iostream> // for cout, ostream
#include <string> #include <memory> // for shared_ptr
#include <thread> #include <string> // for operator<<, string
#include <vector> #include <thread> // for sleep_for
#include <vector> // for vector
#include "ftxui/dom/node.hpp" #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" #include "ftxui/screen/color.hpp" // for Color, Color::BlueLight, Color::RedLight, Color::YellowLight, ftxui
#include "ftxui/screen/color.hpp"
class Graph { class Graph {
public: public:
std::vector<int> operator()(int width, int height) { std::vector<int> operator()(int width, int height) const {
std::vector<int> output(width); std::vector<int> output(width);
for (int i = 0; i < width; ++i) { for (int i = 0; i < width; ++i) {
float v = 0; float v = 0;
v += 0.1f * sin((i + shift) * 0.1f); v += 0.1f * sin((i + shift) * 0.1f); // NOLINT
v += 0.2f * sin((i + shift + 10) * 0.15f); v += 0.2f * sin((i + shift + 10) * 0.15f); // NOLINT
v += 0.1f * sin((i + shift) * 0.03f); v += 0.1f * sin((i + shift) * 0.03f); // NOLINT
v *= height; v *= height; // NOLINT
v += 0.5f * height; v += 0.5f * height; // NOLINT
output[i] = static_cast<int>(v); output[i] = static_cast<int>(v);
} }
return output; return output;
@@ -38,7 +38,7 @@ std::vector<int> triangle(int width, int height) {
return output; return output;
} }
int main(int argc, const char* argv[]) { int main() {
using namespace ftxui; using namespace ftxui;
using namespace std::chrono_literals; using namespace std::chrono_literals;
@@ -46,23 +46,26 @@ int main(int argc, const char* argv[]) {
std::string reset_position; std::string reset_position;
for (int i = 0;; ++i) { for (int i = 0;; ++i) {
auto document = auto document = hbox({
hbox({ vbox({
vbox({ graph(std::ref(my_graph)),
graph(std::ref(my_graph)),
separator(),
graph(triangle) | inverted,
}) | flex,
separator(), separator(),
vbox({ graph(triangle) | inverted,
graph(std::ref(my_graph)) | color(Color::BlueLight), }) | flex,
separator(), separator(),
graph(std::ref(my_graph)) | color(Color::RedLight), vbox({
separator(), graph(std::ref(my_graph)) | color(Color::BlueLight),
graph(std::ref(my_graph)) | color(Color::YellowLight), separator(),
}) | flex, graph(std::ref(my_graph)) | color(Color::RedLight),
}) | separator(),
border | size(HEIGHT, GREATER_THAN, 40); 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)); auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document); Render(screen, document);
@@ -70,7 +73,8 @@ int main(int argc, const char* argv[]) {
screen.Print(); screen.Print();
reset_position = screen.ResetPosition(); 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++; my_graph.shift++;
} }

View File

@@ -1,10 +1,10 @@
#include <stdio.h> // for getchar #include <stdio.h> // for getchar
#include <ftxui/dom/elements.hpp> // for filler, text, hbox, vbox #include <ftxui/dom/elements.hpp> // for Elements, gridbox, Fit, operator|, text, border, Element
#include <ftxui/screen/screen.hpp> // for Full, Screen #include <ftxui/screen/screen.hpp> // for Screen
#include <memory> // for allocator #include <memory> // for allocator, shared_ptr
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

View File

@@ -1,15 +1,15 @@
#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/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 <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator, shared_ptr #include <memory> // for shared_ptr
#include <string> // for operator+, to_string, char_traits, string #include <string> // for allocator, operator+, to_string, char_traits, string
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; 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); std::string title = std::to_string(dimx) + "x" + std::to_string(dimy);
return window(text(title) | hcenter | bold, return window(text(title) | hcenter | bold,
text("content") | hcenter | dim) | text("content") | hcenter | dim) |
@@ -44,6 +44,7 @@ int main(int argc, const char* argv[]) {
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document); Render(screen, document);
screen.Print(); screen.Print();
getchar();
return 0; return 0;
} }

View File

@@ -1,11 +1,11 @@
#include <chrono> // for operator""s, chrono_literals #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 <iostream> // for cout, ostream
#include <memory> // for allocator, shared_ptr #include <memory> // for shared_ptr
#include <string> // for operator<<, string #include <string> // for allocator, operator<<, string
#include <thread> // for sleep_for #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/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/box.hpp" // for ftxui
#include "ftxui/screen/color.hpp" // for Color, Color::Red #include "ftxui/screen/color.hpp" // for Color, Color::Red
@@ -44,7 +44,7 @@ int main(int argc, const char* argv[]) {
paragraph(" A spinner "), spinner(6, i / 10)) | paragraph(" A spinner "), spinner(6, i / 10)) |
border; border;
auto screen = Screen::Create(Dimension::Full()); auto screen = Screen::Create(Dimension::Fit(document));
Render(screen, document); Render(screen, document);
std::cout << reset_position; std::cout << reset_position;
screen.Print(); screen.Print();

View File

@@ -9,9 +9,8 @@
#include <utility> // for move #include <utility> // for move
#include <vector> // for vector #include <vector> // for vector
#include "ftxui/dom/node.hpp" // for Render #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, ftxui
#include "ftxui/screen/color.hpp" // for Color, Color::Green, Color::Red, Color::RedLight
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;
@@ -42,7 +41,7 @@ int main(int argc, const char* argv[]) {
int remaining_threads = 12; int remaining_threads = 12;
int nb_queued = remaining_tasks.size(); int nb_queued = (int)remaining_tasks.size();
int nb_active = 0; int nb_active = 0;
int nb_done = 0; int nb_done = 0;

View File

@@ -1,35 +1,50 @@
#include <stdio.h> // for getchar #include <chrono> // for operator""s, chrono_literals
#include <ftxui/dom/elements.hpp> // for operator|, hflow, paragraph, border, Element, hbox, flex, vbox
#include <ftxui/screen/screen.hpp> // for Full, Screen #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/dom/elements.hpp" // for hflow, paragraph, separator, hbox, vbox, filler, operator|, border, Element
#include "ftxui/screen/box.hpp" // for ftxui #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[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;
std::string p = 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.)"; 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({ std::string reset_position;
hbox({ for (int i = 0;; ++i) {
hflow(paragraph(p)) | border, auto document = vbox({
hflow(paragraph(p)) | border, hflow(paragraph(p)),
hflow(paragraph(p)) | border, separator(),
}) | flex, hflow(paragraph(p)),
hbox({ separator(),
hflow(paragraph(p)) | border, hbox({
hflow(paragraph(p)) | border, hflow(paragraph(p)),
}) | flex, separator(),
hbox({ hflow(paragraph(p)),
hflow(paragraph(p)) | border, }),
}) | flex, }) |
}); border;
auto screen = Screen::Create(Dimension::Full(), Dimension::Full()); document = vbox(filler(), document);
Render(screen, document);
screen.Print(); // auto screen = Screen::Create(Dimension::Fit(document));
getchar(); // 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; return 0;
} }

View File

@@ -2,8 +2,8 @@
#include <ftxui/screen/screen.hpp> // for Full, Screen #include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator #include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

View File

@@ -4,8 +4,8 @@
#include <string> // for string, to_string #include <string> // for string, to_string
#include <utility> // for move #include <utility> // for move
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

View File

@@ -7,8 +7,8 @@
#include <utility> // for move #include <utility> // for move
#include <vector> // for vector #include <vector> // for vector
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

View File

@@ -2,8 +2,8 @@
#include <ftxui/screen/screen.hpp> // for Full, Screen #include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator #include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

View File

@@ -2,8 +2,8 @@
#include <ftxui/screen/screen.hpp> // for Full, Screen #include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator #include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

View File

@@ -2,8 +2,8 @@
#include <ftxui/screen/screen.hpp> // for Full, Screen #include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator #include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

View File

@@ -3,8 +3,7 @@
#include <memory> // for allocator #include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for Color, Color::Blue, ftxui
#include "ftxui/screen/color.hpp" // for Color, Color::Blue
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

View File

@@ -2,8 +2,8 @@
#include <ftxui/screen/screen.hpp> // for Full, Screen #include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator #include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

View File

@@ -2,8 +2,8 @@
#include <ftxui/screen/screen.hpp> // for Full, Screen #include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator #include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

65
examples/dom/table.cpp Normal file
View 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.

View File

@@ -3,8 +3,8 @@
#include <ftxui/screen/screen.hpp> // for Full, Screen #include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator #include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" // for ftxui #include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
using namespace ftxui; using namespace ftxui;

51
examples/dom/vflow.cpp Normal file
View File

@@ -0,0 +1,51 @@
#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 <memory> // for shared_ptr
#include <string> // for allocator, operator+, to_string, char_traits, 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.

View File

@@ -1,26 +1,32 @@
#include <ftxui/dom/elements.hpp> #include <stdlib.h> // for EXIT_SUCCESS
#include <ftxui/screen/screen.hpp> #include <ftxui/dom/elements.hpp> // for operator|=, Element, bgcolor, color, graph, border
#include <vector> #include <ftxui/screen/screen.hpp> // for Fixed, Screen
#include <vector> // for vector
#include "ftxui/dom/node.hpp" #include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/box.hpp" #include "ftxui/screen/color.hpp" // for Color, Color::DarkBlue, Color::Red, ftxui
#include "ftxui/screen/color.hpp"
int main(void) { int main() {
using namespace ftxui; using namespace ftxui;
Element document = graph([](int x, int y) { Element document = graph([](int x, int y) {
std::vector<int> result(x, 0); std::vector<int> result(x, 0);
for (int i{0}; i < x; ++i) { for (int i{0}; i < x; ++i) {
result[i] = ((3 * i) / 2) % y; result[i] = ((3 * i) / 2) % y;
} }
return result; return result;
}) | });
color(Color::Red) | border | color(Color::Green) |
bgcolor(Color::DarkBlue);
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); Render(screen, document);
screen.Print(); screen.Print();
return EXIT_SUCCESS;
} }
// Copyright 2020 Arthur Sonzogni. All rights reserved. // Copyright 2020 Arthur Sonzogni. All rights reserved.

View File

@@ -2,7 +2,8 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>FTXUI examples WebAssembly</title> <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>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@4.11.0/css/xterm.css"></link> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@4.11.0/css/xterm.css"></link>
</head> </head>
<body> <body>
@@ -43,12 +44,12 @@
}); });
let stdin_buffer = []; let stdin_buffer = [];
let stdin = () => { const stdin = () => {
return stdin_buffer.shift() || 0; return stdin_buffer.shift() || 0;
} }
stdout_buffer = []; let stdout_buffer = [];
let stdout = code => { const stdout = code => {
if (code == 0) { if (code == 0) {
term.write(new Uint8Array(stdout_buffer)); term.write(new Uint8Array(stdout_buffer));
stdout_buffer = []; stdout_buffer = [];
@@ -56,10 +57,19 @@
stdout_buffer.push(code) stdout_buffer.push(code)
} }
} }
let stderr = code => console.log(code); let stderrbuffer = [];
var term = new Terminal(); const stderr = code => {
if (code == 0 || code == 10) {
console.error(String.fromCodePoint(...stderrbuffer));
stderrbuffer = [];
} else {
stderrbuffer.push(code)
}
}
const term = new Terminal();
term.open(document.querySelector('#terminal')); term.open(document.querySelector('#terminal'));
term.resize(140,43); term.resize(140,43);
term.loadAddon(new (WebglAddon.WebglAddon)());
const onBinary = e => { const onBinary = e => {
for(c of e) for(c of e)
stdin_buffer.push(c.charCodeAt(0)); stdin_buffer.push(c.charCodeAt(0));
@@ -67,14 +77,20 @@
term.onBinary(onBinary); term.onBinary(onBinary);
term.onData(onBinary) term.onData(onBinary)
window.Module = { window.Module = {
preRun: () => { FS.init(stdin, stdout, stderr); }, preRun: () => {
FS.init(stdin, stdout, stderr);
},
postRun: [], postRun: [],
onRuntimeInitialized: () => {}, onRuntimeInitialized: () => {},
}; };
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> </script>
<style> <style>
body { body {
background-color:#EEE; background-color:#EEE;
padding:20px; padding:20px;

View 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.

View File

@@ -4,10 +4,11 @@
#include <functional> // for function #include <functional> // for function
#include <memory> // for make_shared, shared_ptr #include <memory> // for make_shared, shared_ptr
#include <string> // for wstring #include <string> // for wstring
#include <utility> // for forward
#include <vector> // for vector #include <vector> // for vector
#include "ftxui/component/component_base.hpp" // for Component, Components #include "ftxui/component/component_base.hpp" // for Component, Components
#include "ftxui/component/component_options.hpp" // for ButtonOption, CheckboxOption, InputOption, MenuOption, RadioboxOption, ToggleOption #include "ftxui/component/component_options.hpp" // for ButtonOption, CheckboxOption, InputOption (ptr only), MenuEntryOption (ptr only), MenuOption, RadioboxOption (ptr only)
#include "ftxui/dom/elements.hpp" // for Element #include "ftxui/dom/elements.hpp" // for Element
#include "ftxui/util/ref.hpp" // for Ref, ConstStringRef, ConstStringListRef, StringRef #include "ftxui/util/ref.hpp" // for Ref, ConstStringRef, ConstStringListRef, StringRef
@@ -18,45 +19,20 @@ struct Event;
struct InputOption; struct InputOption;
struct MenuOption; struct MenuOption;
struct RadioboxOption; struct RadioboxOption;
struct ToggleOption;
struct MenuEntryOption; struct MenuEntryOption;
template <class T, class... Args> template <class T, class... Args>
std::shared_ptr<T> Make(Args&&... 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, // Pipe operator to decorate components.
std::function<void()> on_click, using ComponentDecorator = std::function<Component(Component)>;
Ref<ButtonOption> = {}); using ElementDecorator = std::function<Element(Element)>;
Component Checkbox(ConstStringRef label, Component operator|(Component component, ComponentDecorator decorator);
bool* checked, Component operator|(Component component, ElementDecorator decorator);
Ref<CheckboxOption> option = {}); Component& operator|=(Component& component, ComponentDecorator decorator);
Component Input(StringRef content, Component& operator|=(Component& component, ElementDecorator decorator);
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);
namespace Container { namespace Container {
Component Vertical(Components children); Component Vertical(Components children);
@@ -67,10 +43,55 @@ Component Tab(Components children, int* selector);
} // namespace Container } // namespace Container
} // namespace ftxui Component Button(ConstStringRef label,
std::function<void()> on_click,
Ref<ButtonOption> = ButtonOption::Simple());
// Include component using the old deprecated wstring. Component Checkbox(ConstStringRef label,
#include "ftxui/component/deprecated.hpp" 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);
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 */)>);
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 Collapsible(ConstStringRef label,
Component child,
Ref<bool> show = false);
} // namespace ftxui
#endif /* end of include guard: FTXUI_COMPONENT_HPP */ #endif /* end of include guard: FTXUI_COMPONENT_HPP */

View File

@@ -13,6 +13,10 @@ class Delegate;
class Focus; class Focus;
struct Event; struct Event;
namespace animation {
class Params;
} // namespace animation
class ComponentBase; class ComponentBase;
using Component = std::shared_ptr<ComponentBase>; using Component = std::shared_ptr<ComponentBase>;
using Components = std::vector<Component>; using Components = std::vector<Component>;
@@ -42,6 +46,9 @@ class ComponentBase {
// Returns whether the event was handled or not. // Returns whether the event was handled or not.
virtual bool OnEvent(Event); virtual bool OnEvent(Event);
// Handle an animation step.
virtual void OnAnimation(animation::Params& params);
// Focus management ---------------------------------------------------------- // Focus management ----------------------------------------------------------
// //
// If this component contains children, this indicates which one is active, // If this component contains children, this indicates which one is active,

View File

@@ -1,58 +1,136 @@
#ifndef FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP #ifndef FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP
#define FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP #define FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP
#include <ftxui/dom/elements.hpp> #include <chrono> // for milliseconds
#include <ftxui/util/ref.hpp> #include <ftxui/component/animation.hpp> // for Duration, QuadraticInOut, Function
#include <ftxui/dom/elements.hpp> // for Element
#include <ftxui/util/ref.hpp> // for Ref
#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 { 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 /// @ingroup component
struct MenuOption { struct AnimatedColorOption {
Decorator style_normal = nothing; ///< style. void Set(
Decorator style_focused = inverted; ///< Style when focused. Color inactive,
Decorator style_selected = bold; ///< Style when selected. Color active,
Decorator style_selected_focused = animation::Duration duration = std::chrono::milliseconds(250),
Decorator(inverted) | bold; ///< Style when selected and focused. animation::easing::Function function = animation::easing::QuadraticInOut);
/// Called when the selected entry changes. bool enabled = false;
std::function<void()> on_change = [] {}; Color inactive;
/// Called when the user presses enter. Color active;
std::function<void()> on_enter = [] {}; 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. /// @brief Option for the MenuEntry component.
/// @ingroup component /// @ingroup component
struct MenuEntryOption { struct MenuEntryOption {
Decorator style_normal = nothing; ///< style. std::function<Element(const EntryState& state)> transform;
Decorator style_focused = inverted; ///< Style when focused. AnimatedColorsOption animated_colors;
Decorator style_selected = bold; ///< Style when selected.
Decorator style_selected_focused =
Decorator(inverted) | bold; ///< Style when selected and focused.
}; };
/// @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 seelcted 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 /// @ingroup component
struct ButtonOption { struct ButtonOption {
/// Whether to show a border around the button. // Standard constructors:
bool border = true; 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. /// @brief Option for the Checkbox component.
/// @ingroup component /// @ingroup component
struct CheckboxOption { struct CheckboxOption {
std::string style_checked = ""; ///< Prefix for a "checked" state. // Standard constructors:
std::string style_unchecked = ""; ///< Prefix for a "unchecked" state. static CheckboxOption Simple();
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.
// Style:
std::function<Element(const EntryState&)> transform;
// Observer:
/// Called when the user change the state. /// Called when the user change the state.
std::function<void()> on_change = []() {}; std::function<void()> on_change = [] {};
}; };
/// @brief Option for the Input component. /// @brief Option for the Input component.
@@ -74,34 +152,15 @@ struct InputOption {
/// @brief Option for the Radiobox component. /// @brief Option for the Radiobox component.
/// @ingroup component /// @ingroup component
struct RadioboxOption { struct RadioboxOption {
std::string style_checked = ""; ///< Prefix for a "checked" state. // Standard constructors:
std::string style_unchecked = ""; ///< Prefix for a "unchecked" state. static RadioboxOption Simple();
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. // Style:
std::function<void()> on_change = []() {}; std::function<Element(const EntryState&)> transform;
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.
// Observers:
/// Called when the selected entry changes. /// Called when the selected entry changes.
std::function<void()> on_change = [] {}; std::function<void()> on_change = [] {};
/// Called when the user presses enter.
std::function<void()> on_enter = [] {};
Ref<int> focused_entry = 0; Ref<int> focused_entry = 0;
}; };

View File

@@ -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.

View File

@@ -2,7 +2,8 @@
#define FTXUI_COMPONENT_EVENT_HPP #define FTXUI_COMPONENT_EVENT_HPP
#include <ftxui/component/mouse.hpp> // for Mouse #include <ftxui/component/mouse.hpp> // for Mouse
#include <string> // for string, operator== #include <functional>
#include <string> // for string, operator==
#include <vector> #include <vector>
namespace ftxui { namespace ftxui {
@@ -53,7 +54,7 @@ struct Event {
static const Event PageDown; static const Event PageDown;
// --- Custom --- // --- Custom ---
static Event Custom; static const Event Custom;
//--- Method section --------------------------------------------------------- //--- Method section ---------------------------------------------------------
bool is_character() const { return type_ == Type::Character; } bool is_character() const { return type_ == Type::Character; }
@@ -75,6 +76,7 @@ struct Event {
//--- State section ---------------------------------------------------------- //--- State section ----------------------------------------------------------
ScreenInteractive* screen_ = nullptr; ScreenInteractive* screen_ = nullptr;
private: private:
friend ComponentBase; friend ComponentBase;
friend ScreenInteractive; friend ScreenInteractive;

View File

@@ -7,9 +7,12 @@
#include <memory> // for shared_ptr #include <memory> // for shared_ptr
#include <string> // for string #include <string> // for string
#include <thread> // for thread #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/captured_mouse.hpp" // for CapturedMouse
#include "ftxui/component/event.hpp" // for Event #include "ftxui/component/event.hpp" // for Event
#include "ftxui/component/task.hpp" // for Closure, Task
#include "ftxui/screen/screen.hpp" // for Screen #include "ftxui/screen/screen.hpp" // for Screen
namespace ftxui { namespace ftxui {
@@ -17,29 +20,43 @@ class ComponentBase;
struct Event; struct Event;
using Component = std::shared_ptr<ComponentBase>; using Component = std::shared_ptr<ComponentBase>;
class ScreenInteractivePrivate;
class ScreenInteractive : public Screen { class ScreenInteractive : public Screen {
public: public:
// Constructors:
static ScreenInteractive FixedSize(int dimx, int dimy); static ScreenInteractive FixedSize(int dimx, int dimy);
static ScreenInteractive Fullscreen(); static ScreenInteractive Fullscreen();
static ScreenInteractive FitComponent(); static ScreenInteractive FitComponent();
static ScreenInteractive TerminalOutput(); static ScreenInteractive TerminalOutput();
void Loop(Component); // Return the currently active screen, nullptr if none.
std::function<void()> ExitLoopClosure(); static ScreenInteractive* Active();
void Loop(Component);
Closure ExitLoopClosure();
void Post(Task task);
void PostEvent(Event event); void PostEvent(Event event);
void RequestAnimationFrame();
CapturedMouse CaptureMouse(); 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: private:
void Install(); void Install();
void Uninstall(); void Uninstall();
void Main(Component component); void Main(Component component);
ScreenInteractive* suspended_screen_ = nullptr;
void Draw(Component component); void Draw(Component component);
void EventLoop(Component component); void SigStop();
ScreenInteractive* suspended_screen_ = nullptr;
enum class Dimension { enum class Dimension {
FitComponent, FitComponent,
Fixed, Fixed,
@@ -53,19 +70,30 @@ class ScreenInteractive : public Screen {
Dimension dimension, Dimension dimension,
bool use_alternative_screen); bool use_alternative_screen);
Sender<Event> event_sender_; Sender<Task> task_sender_;
Receiver<Event> event_receiver_; Receiver<Task> task_receiver_;
std::string set_cursor_position; std::string set_cursor_position;
std::string reset_cursor_position; std::string reset_cursor_position;
std::atomic<bool> quit_ = false; std::atomic<bool> quit_ = false;
std::thread event_listener_; std::thread event_listener_;
std::thread animation_listener_;
bool animation_requested_ = false;
animation::TimePoint previous_animation_time;
int cursor_x_ = 1; int cursor_x_ = 1;
int cursor_y_ = 1; int cursor_y_ = 1;
bool mouse_captured = false; bool mouse_captured = false;
bool previous_frame_resized_ = false;
public:
class Private {
public:
static void SigStop(ScreenInteractive& s) { return s.SigStop(); }
};
friend Private;
}; };
} // namespace ftxui } // namespace ftxui

View 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.

View File

@@ -0,0 +1,139 @@
#ifndef FTXUI_DOM_CANVAS_HPP
#define FTXUI_DOM_CANVAS_HPP
#include <cstddef> // for size_t
#include <functional> // for function
#include <string> // for string
#include <unordered_map> // for unordered_map
#include "ftxui/screen/color.hpp" // for Color
#include "ftxui/screen/screen.hpp" // for Pixel
#ifdef DrawText
// Workaround for WinUsr.h (via Windows.h) defining macros that break things.
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-drawtext
#undef DrawText
#endif
namespace ftxui {
struct Canvas {
public:
Canvas() = default;
Canvas(int width, int height);
// Getters:
int width() const { return width_; }
int height() const { return height_; }
Pixel GetPixel(int x, int y) const;
using Stylizer = std::function<void(Pixel&)>;
// Draws using braille characters --------------------------------------------
void DrawPointOn(int x, int y);
void DrawPointOff(int x, int y);
void DrawPointToggle(int x, int y);
void DrawPoint(int x, int y, bool value);
void DrawPoint(int x, int y, bool value, const Stylizer& s);
void DrawPoint(int x, int y, bool value, const Color& color);
void DrawPointLine(int x1, int y1, int x2, int y2);
void DrawPointLine(int x1, int y1, int x2, int y2, const Stylizer& s);
void DrawPointLine(int x1, int y1, int x2, int y2, const Color& color);
void DrawPointCircle(int x, int y, int radius);
void DrawPointCircle(int x, int y, int radius, const Stylizer& s);
void DrawPointCircle(int x, int y, int radius, const Color& color);
void DrawPointCircleFilled(int x, int y, int radius);
void DrawPointCircleFilled(int x, int y, int radius, const Stylizer& s);
void DrawPointCircleFilled(int x, int y, int radius, const Color& color);
void DrawPointEllipse(int x, int y, int r1, int r2);
void DrawPointEllipse(int x, int y, int r1, int r2, const Color& color);
void DrawPointEllipse(int x, int y, int r1, int r2, const Stylizer& s);
void DrawPointEllipseFilled(int x, int y, int r1, int r2);
void DrawPointEllipseFilled(int x, int y, int r1, int r2, const Color& color);
void DrawPointEllipseFilled(int x, int y, int r1, int r2, const Stylizer& s);
// Draw using box characters -------------------------------------------------
// Block are of size 1x2. y is considered to be a multiple of 2.
void DrawBlockOn(int x, int y);
void DrawBlockOff(int x, int y);
void DrawBlockToggle(int x, int y);
void DrawBlock(int x, int y, bool value);
void DrawBlock(int x, int y, bool value, const Stylizer& s);
void DrawBlock(int x, int y, bool value, const Color& color);
void DrawBlockLine(int x1, int y1, int x2, int y2);
void DrawBlockLine(int x1, int y1, int x2, int y2, const Stylizer& s);
void DrawBlockLine(int x1, int y1, int x2, int y2, const Color& color);
void DrawBlockCircle(int x1, int y1, int radius);
void DrawBlockCircle(int x1, int y1, int radius, const Stylizer& s);
void DrawBlockCircle(int x1, int y1, int radius, const Color& color);
void DrawBlockCircleFilled(int x1, int y1, int radius);
void DrawBlockCircleFilled(int x1, int y1, int radius, const Stylizer& s);
void DrawBlockCircleFilled(int x1, int y1, int radius, const Color& color);
void DrawBlockEllipse(int x1, int y1, int r1, int r2);
void DrawBlockEllipse(int x1, int y1, int r1, int r2, const Stylizer& s);
void DrawBlockEllipse(int x1, int y1, int r1, int r2, const Color& color);
void DrawBlockEllipseFilled(int x1, int y1, int r1, int r2);
void DrawBlockEllipseFilled(int x1,
int y1,
int r1,
int r2,
const Stylizer& s);
void DrawBlockEllipseFilled(int x1,
int y1,
int r1,
int r2,
const Color& color);
// Draw using normal characters ----------------------------------------------
// Draw using character of size 2x4 at position (x,y)
// x is considered to be a multiple of 2.
// y is considered to be a multiple of 4.
void DrawText(int x, int y, const std::string& value);
void DrawText(int x, int y, const std::string& value, const Color& color);
void DrawText(int x, int y, const std::string& value, const Stylizer& style);
// Decorator:
// x is considered to be a multiple of 2.
// y is considered to be a multiple of 4.
void Style(int x, int y, const Stylizer& style);
private:
bool IsIn(int x, int y) const {
return x >= 0 && x < width_ && y >= 0 && y < height_;
}
enum CellType {
kBraille,
kBlock,
kText,
};
struct Cell {
CellType type = kText;
Pixel content;
};
struct XY {
int x;
int y;
bool operator==(const XY& other) const {
return x == other.x && y == other.y;
}
};
struct XYHash {
size_t operator()(const XY& xy) const {
constexpr size_t shift = 1024;
return size_t(xy.x) * shift + size_t(xy.y);
}
};
int width_ = 0;
int height_ = 0;
std::unordered_map<XY, Cell, XYHash> storage_;
};
} // namespace ftxui
#endif // FTXUI_DOM_CANVAS_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.

View File

@@ -1,5 +1,5 @@
#ifndef FTXUI_DOM_DEPRECRATED_HPP #ifndef FTXUI_DOM_DEPRECATED_HPP
#define FTXUI_DOM_DEPRECRATED_HPP #define FTXUI_DOM_DEPRECATED_HPP
#include "ftxui/dom/elements.hpp" #include "ftxui/dom/elements.hpp"
@@ -9,7 +9,7 @@ Element vtext(std::wstring text);
Elements paragraph(std::wstring text); Elements paragraph(std::wstring text);
} // namespace ftxui } // namespace ftxui
#endif /* end of include guard: FTXUI_DOM_DEPRECRATED_HPP */ #endif // FTXUI_DOM_DEPRECATED_HPP
// Copyright 2021 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 // Use of this source code is governed by the MIT license that can be found in

View File

@@ -4,11 +4,14 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include "ftxui/dom/canvas.hpp"
#include "ftxui/dom/flexbox_config.hpp"
#include "ftxui/dom/node.hpp" #include "ftxui/dom/node.hpp"
#include "ftxui/screen/box.hpp" #include "ftxui/screen/box.hpp"
#include "ftxui/screen/color.hpp" #include "ftxui/screen/color.hpp"
#include "ftxui/screen/screen.hpp" #include "ftxui/screen/screen.hpp"
#include "ftxui/screen/terminal.hpp" #include "ftxui/screen/terminal.hpp"
#include "ftxui/util/ref.hpp"
namespace ftxui { namespace ftxui {
class Node; class Node;
@@ -17,37 +20,63 @@ using Elements = std::vector<Element>;
using Decorator = std::function<Element(Element)>; using Decorator = std::function<Element(Element)>;
using GraphFunction = std::function<std::vector<int>(int, int)>; using GraphFunction = std::function<std::vector<int>(int, int)>;
enum BorderStyle { LIGHT, HEAVY, DOUBLE, ROUNDED }; enum BorderStyle { LIGHT, HEAVY, DOUBLE, ROUNDED, EMPTY };
enum class GaugeDirection { Left, Up, Right, Down };
// Pipe elements into decorator togethers. // Pipe elements into decorator togethers.
// For instance the next lines are equivalents: // For instance the next lines are equivalents:
// -> text("ftxui") | bold | underlined // -> text("ftxui") | bold | underlined
// -> underlined(bold(text("FTXUI"))) // -> underlined(bold(text("FTXUI")))
Element operator|(Element, Decorator); Element operator|(Element, Decorator);
Element& operator|=(Element&, Decorator);
Elements operator|(Elements, Decorator); Elements operator|(Elements, Decorator);
Decorator operator|(Decorator, Decorator); Decorator operator|(Decorator, Decorator);
// --- Widget --- // --- Widget ---
Element text(std::string text); Element text(std::string text);
Element vtext(std::string text); Element vtext(std::string text);
Element separator(void); Element separator();
Element separatorLight(); Element separatorLight();
Element separatorHeavy(); Element separatorHeavy();
Element separatorDouble(); Element separatorDouble();
Element separatorEmpty();
Element separatorStyled(BorderStyle); Element separatorStyled(BorderStyle);
Element separator(Pixel); Element separator(Pixel);
Element gauge(float ratio); Element separatorCharacter(std::string);
Element separatorHSelector(float left,
float right,
Color unselected_color,
Color selected_color);
Element separatorVSelector(float up,
float down,
Color unselected_color,
Color selected_color);
Element gauge(float progress);
Element gaugeLeft(float progress);
Element gaugeRight(float progress);
Element gaugeUp(float progress);
Element gaugeDown(float progress);
Element gaugeDirection(float progress, GaugeDirection);
Element border(Element); Element border(Element);
Element borderLight(Element); Element borderLight(Element);
Element borderHeavy(Element); Element borderHeavy(Element);
Element borderDouble(Element); Element borderDouble(Element);
Element borderRounded(Element); Element borderRounded(Element);
Element borderEmpty(Element);
Decorator borderStyled(BorderStyle); Decorator borderStyled(BorderStyle);
Decorator borderWith(Pixel); Decorator borderWith(const Pixel&);
Element window(Element title, Element content); Element window(Element title, Element content);
Element spinner(int charset_index, size_t image_index); Element spinner(int charset_index, size_t image_index);
Elements paragraph(std::string text); // Use inside hflow(). Split by space. Element paragraph(const std::string& text);
Element paragraphAlignLeft(const std::string& text);
Element paragraphAlignRight(const std::string& text);
Element paragraphAlignCenter(const std::string& text);
Element paragraphAlignJustify(const std::string& text);
Element graph(GraphFunction); Element graph(GraphFunction);
Element emptyElement();
Element canvas(ConstRef<Canvas>);
Element canvas(int width, int height, std::function<void(Canvas&)>);
Element canvas(std::function<void(Canvas&)>);
// -- Decorator --- // -- Decorator ---
Element bold(Element); Element bold(Element);
@@ -59,14 +88,20 @@ Decorator color(Color);
Decorator bgcolor(Color); Decorator bgcolor(Color);
Element color(Color, Element); Element color(Color, Element);
Element bgcolor(Color, Element); Element bgcolor(Color, Element);
Decorator focusPosition(int x, int y);
Decorator focusPositionRelative(float x, float y);
Element automerge(Element child);
// --- Layout is // --- Layout is
// Horizontal, Vertical or stacked set of elements. // Horizontal, Vertical or stacked set of elements.
Element hbox(Elements); Element hbox(Elements);
Element vbox(Elements); Element vbox(Elements);
Element dbox(Elements); Element dbox(Elements);
Element flexbox(Elements, FlexboxConfig config = FlexboxConfig());
Element gridbox(std::vector<Elements> lines); Element gridbox(std::vector<Elements> lines);
Element hflow(Elements);
Element hflow(Elements); // Helper: default flexbox with row direction.
Element vflow(Elements); // Helper: default flexbox with column direction.
// -- Flexibility --- // -- Flexibility ---
// Define how to share the remaining space when not all of it is used inside a // Define how to share the remaining space when not all of it is used inside a
@@ -128,7 +163,7 @@ Dimensions Fit(Element&);
// Include old definitions using wstring. // Include old definitions using wstring.
#include "ftxui/dom/deprecated.hpp" #include "ftxui/dom/deprecated.hpp"
#endif /* end of include guard: FTXUI_DOM_ELEMENTS_HPP */ #endif // FTXUI_DOM_ELEMENTS_HPP
// Copyright 2020 Arthur Sonzogni. All rights reserved. // Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in // Use of this source code is governed by the MIT license that can be found in

View File

@@ -0,0 +1,115 @@
#ifndef FTXUI_DOM_FLEXBOX_CONFIG_HPP
#define FTXUI_DOM_FLEXBOX_CONFIG_HPP
/*
This replicate the CSS flexbox model.
See guide for documentation:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
*/
namespace ftxui {
struct FlexboxConfig {
/// This establishes the main-axis, thus defining the direction flex items are
/// placed in the flex container. Flexbox is (aside wrapping) single-direction
/// layout concept. Think of flex items as primarily laying out either in
/// horizontal rows or vertical columns.
enum class Direction {
Row, ///< Flex items are laid out in a row.
RowInversed, ///< Flex items are laid out in a row, but in reverse order.
Column, ///< Flex items are laid out in a column.
ColumnInversed ///< Flex items are laid out in a column, but in reverse
///< order.
};
Direction direction = Direction::Row;
/// By default, flex items will all try to fit onto one line. You can change
/// that and allow the items to wrap as needed with this property.
enum class Wrap {
NoWrap, ///< Flex items will all try to fit onto one line.
Wrap, ///< Flex items will wrap onto multiple lines.
WrapInversed, ///< Flex items will wrap onto multiple lines, but in reverse
///< order.
};
Wrap wrap = Wrap::Wrap;
/// This defines the alignment along the main axis. It helps distribute extra
/// free space leftover when either all the flex items on a line are
/// inflexible, or are flexible but have reached their maximum size. It also
/// exerts some control over the alignment of items when they overflow the
/// line.
enum class JustifyContent {
/// Items are aligned to the start of flexbox's direction.
FlexStart,
/// Items are aligned to the end of flexbox's direction.
FlexEnd,
/// Items are centered along the line.
Center,
/// Items are stretched to fill the line.
Stretch,
/// Items are evenly distributed in the line; first item is on the start
// line, last item on the end line
SpaceBetween,
/// Items are evenly distributed in the line with equal space around them.
/// Note that visually the spaces arent equal, since all the items have
/// equal space on both sides. The first item will have one unit of space
/// against the container edge, but two units of space between the next item
/// because that next item has its own spacing that applies.
SpaceAround,
/// Items are distributed so that the spacing between any two items (and the
/// space to the edges) is equal.
SpaceEvenly,
};
JustifyContent justify_content = JustifyContent::FlexStart;
/// This defines the default behavior for how flex items are laid out along
/// the cross axis on the current line. Think of it as the justify-content
/// version for the cross-axis (perpendicular to the main-axis).
enum class AlignItems {
FlexStart, ///< items are placed at the start of the cross axis.
FlexEnd, ///< items are placed at the end of the cross axis.
Center, ///< items are centered along the cross axis.
Stretch, ///< items are stretched to fill the cross axis.
};
AlignItems align_items = AlignItems::FlexStart;
// This aligns a flex containers lines within when there is extra space in
// the cross-axis, similar to how justify-content aligns individual items
// within the main-axis.
enum class AlignContent {
FlexStart, ///< items are placed at the start of the cross axis.
FlexEnd, ///< items are placed at the end of the cross axis.
Center, ///< items are centered along the cross axis.
Stretch, ///< items are stretched to fill the cross axis.
SpaceBetween, ///< items are evenly distributed in the cross axis.
SpaceAround, ///< tems evenly distributed with equal space around each
///< line.
SpaceEvenly, ///< items are evenly distributed in the cross axis with equal
///< space around them.
};
AlignContent align_content = AlignContent::FlexStart;
int gap_x = 0;
int gap_y = 0;
// Constructor pattern. For chained use like:
// ```
// FlexboxConfig()
// .Set(FlexboxConfig::Direction::Row)
// .Set(FlexboxConfig::Wrap::Wrap);
// ```
FlexboxConfig& Set(FlexboxConfig::Direction);
FlexboxConfig& Set(FlexboxConfig::Wrap);
FlexboxConfig& Set(FlexboxConfig::JustifyContent);
FlexboxConfig& Set(FlexboxConfig::AlignItems);
FlexboxConfig& Set(FlexboxConfig::AlignContent);
FlexboxConfig& SetGap(int gap_x, int gap_y);
};
} // namespace ftxui
#endif // FTXUI_DOM_FLEXBOX_CONFIG_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.

View File

@@ -20,6 +20,11 @@ class Node {
public: public:
Node(); Node();
Node(Elements children); Node(Elements children);
Node(const Node&) = delete;
Node(const Node&&) = delete;
Node& operator=(const Node&) = delete;
Node& operator=(const Node&&) = delete;
virtual ~Node(); virtual ~Node();
// Step 1: Compute layout requirement. Tell parent what dimensions this // Step 1: Compute layout requirement. Tell parent what dimensions this
@@ -35,18 +40,27 @@ class Node {
// Step 3: Draw this element. // Step 3: Draw this element.
virtual void Render(Screen& screen); virtual void Render(Screen& screen);
// Layout may not resolve within a single iteration for some elements. This
// allows them to request additionnal iterations. This signal must be
// forwarded to children at least once.
struct Status {
int iteration = 0;
bool need_iteration = false;
};
virtual void Check(Status* status);
protected: protected:
Elements children_; Elements children_;
Requirement requirement_; Requirement requirement_;
Box box_; Box box_;
}; };
void Render(Screen& screen, const Element& node); void Render(Screen& screen, const Element& element);
void Render(Screen& screen, Node* node); void Render(Screen& screen, Node* node);
} // namespace ftxui } // namespace ftxui
#endif /* end of include guard: FTXUI_DOM_NODE_HPP */ #endif // FTXUI_DOM_NODE_HPP
// Copyright 2020 Arthur Sonzogni. All rights reserved. // Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in // Use of this source code is governed by the MIT license that can be found in

View File

@@ -28,7 +28,7 @@ struct Requirement {
} // namespace ftxui } // namespace ftxui
#endif /* end of include guard: FTXUI_REQUIREMENT_HPP */ #endif // FTXUI_DOM_REQUIREMENT_HPP
// Copyright 2020 Arthur Sonzogni. All rights reserved. // Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in // Use of this source code is governed by the MIT license that can be found in

View File

@@ -0,0 +1,96 @@
#ifndef FTXUI_DOM_TABLE
#define FTXUI_DOM_TABLE
#include <memory>
#include <string> // for string
#include <vector> // for vector
#include "ftxui/dom/elements.hpp" // for Element, BorderStyle, LIGHT, Decorator
namespace ftxui {
// Usage:
//
// Initialization:
// ---------------
//
// auto table = Table({
// {"X", "Y"},
// {"-1", "1"},
// {"+0", "0"},
// {"+1", "1"},
// });
//
// table.SelectAll().Border(LIGHT);
//
// table.SelectRow(1).Border(DOUBLE);
// table.SelectRow(1).SeparatorInternal(Light);
//
// std::move(table).Element();
class Table;
class TableSelection;
class Table {
public:
Table();
Table(std::vector<std::vector<std::string>>);
Table(std::vector<std::vector<Element>>);
TableSelection SelectAll();
TableSelection SelectCell(int column, int row);
TableSelection SelectRow(int row_index);
TableSelection SelectRows(int row_min, int row_max);
TableSelection SelectColumn(int column_index);
TableSelection SelectColumns(int column_min, int column_max);
TableSelection SelectRectangle(int column_min,
int column_max,
int row_min,
int row_max);
Element Render();
private:
void Initialize(std::vector<std::vector<Element>>);
friend TableSelection;
std::vector<std::vector<Element>> elements_;
int input_dim_x_ = 0;
int input_dim_y_ = 0;
int dim_x_ = 0;
int dim_y_ = 0;
};
class TableSelection {
public:
void Decorate(Decorator);
void DecorateAlternateRow(Decorator, int modulo = 2, int shift = 0);
void DecorateAlternateColumn(Decorator, int modulo = 2, int shift = 0);
void DecorateCells(Decorator);
void DecorateCellsAlternateColumn(Decorator, int modulo = 2, int shift = 0);
void DecorateCellsAlternateRow(Decorator, int modulo = 2, int shift = 0);
void Border(BorderStyle border = LIGHT);
void BorderLeft(BorderStyle border = LIGHT);
void BorderRight(BorderStyle border = LIGHT);
void BorderTop(BorderStyle border = LIGHT);
void BorderBottom(BorderStyle border = LIGHT);
void Separator(BorderStyle border = LIGHT);
void SeparatorVertical(BorderStyle border = LIGHT);
void SeparatorHorizontal(BorderStyle border = LIGHT);
private:
friend Table;
Table* table_;
int x_min_;
int x_max_;
int y_min_;
int y_max_;
};
} // namespace ftxui
#endif /* end of include guard: FTXUI_DOM_TABLE */
// 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.

View File

@@ -1,10 +1,13 @@
#ifndef FTXUI_DOM_TAKE_ANY_ARGS_HPP
#define FTXUI_DOM_TAKE_ANY_ARGS_HPP
// IWYU pragma: private, include "ftxui/dom/elements.hpp" // IWYU pragma: private, include "ftxui/dom/elements.hpp"
#include <type_traits> #include <type_traits>
namespace ftxui { namespace ftxui {
template <class T> template <class T>
void Merge(Elements&, T) {} void Merge(Elements& /*container*/, T /*element*/) {}
template <> template <>
inline void Merge(Elements& container, Element element) { inline void Merge(Elements& container, Element element) {
@@ -38,6 +41,8 @@ TAKE_ANY_ARGS(dbox)
TAKE_ANY_ARGS(hflow) TAKE_ANY_ARGS(hflow)
} // namespace ftxui } // namespace ftxui
#endif // FTXUI_DOM_TAKE_ANY_ARGS_HPP
// Copyright 2020 Arthur Sonzogni. All rights reserved. // Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in // Use of this source code is governed by the MIT license that can be found in
// the LICENSE file. // the LICENSE file.

View File

@@ -9,13 +9,15 @@ struct Box {
int y_min = 0; int y_min = 0;
int y_max = 0; int y_max = 0;
static Box Intersection(Box a, Box b); static auto Intersection(Box a, Box b) -> Box;
bool Contain(int x, int y); bool Contain(int x, int y) const;
bool operator==(const Box& other) const;
bool operator!=(const Box& other) const;
}; };
} // namespace ftxui } // namespace ftxui
#endif /* end of include guard: FTXUI_SCREEN_BOX_HPP */ #endif // FTXUI_SCREEN_BOX_HPP
// Copyright 2020 Arthur Sonzogni. All rights reserved. // Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in // Use of this source code is governed by the MIT license that can be found in

View File

@@ -1,8 +1,8 @@
#ifndef FTXUI_SCREEN_COLOR #ifndef FTXUI_SCREEN_COLOR_HPP
#define FTXUI_SCREEN_COLOR #define FTXUI_SCREEN_COLOR_HPP
#include <stdint.h> // for uint8_t #include <cstdint> // for uint8_t
#include <string> // for wstring #include <string> // for wstring
#ifdef RGB #ifdef RGB
// Workaround for wingdi.h (via Windows.h) defining macros that break things. // Workaround for wingdi.h (via Windows.h) defining macros that break things.
@@ -27,6 +27,7 @@ class Color {
Color(uint8_t red, uint8_t green, uint8_t blue); Color(uint8_t red, uint8_t green, uint8_t blue);
static Color RGB(uint8_t red, uint8_t green, uint8_t blue); static Color RGB(uint8_t red, uint8_t green, uint8_t blue);
static Color HSV(uint8_t hue, uint8_t saturation, uint8_t value); static Color HSV(uint8_t hue, uint8_t saturation, uint8_t value);
static Color Interpolate(float t, const Color& a, const Color& b);
//--------------------------- //---------------------------
// List of colors: // List of colors:
@@ -312,12 +313,8 @@ class Color {
Palette256, Palette256,
TrueColor, TrueColor,
}; };
ColorType type_ = ColorType::Palette1;
ColorType type_; uint8_t red_ = 0;
union {
uint8_t index_ = 0;
uint8_t red_;
};
uint8_t green_ = 0; uint8_t green_ = 0;
uint8_t blue_ = 0; uint8_t blue_ = 0;
}; };
@@ -332,7 +329,7 @@ Color operator""_rgb(unsigned long long int combined);
} // namespace ftxui } // namespace ftxui
#endif /* end of include guard: FTXUI_COLOR_H_ */ #endif // FTXUI_SCREEN_COLOR_HPP
// Copyright 2020 Arthur Sonzogni. All rights reserved. // Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in // Use of this source code is governed by the MIT license that can be found in

View File

@@ -1,7 +1,7 @@
#ifndef FTXUI_SCREEN_COLOR_INFO_HPP #ifndef FTXUI_SCREEN_COLOR_INFO_HPP
#define FTXUI_SCREEN_COLOR_INFO_HPP #define FTXUI_SCREEN_COLOR_INFO_HPP
#include <stdint.h> #include <cstdint>
#include <ftxui/screen/color.hpp> #include <ftxui/screen/color.hpp>
namespace ftxui { namespace ftxui {
@@ -23,7 +23,7 @@ ColorInfo GetColorInfo(Color::Palette16 index);
} // namespace ftxui } // namespace ftxui
#endif /* end of include guard: FTXUI_SCREEN_COLOR_INFO_HPP */ #endif // FTXUI_SCREEN_COLOR_INFO_HPP
// Copyright 2020 Arthur Sonzogni. All rights reserved. // Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in // Use of this source code is governed by the MIT license that can be found in

View File

@@ -8,7 +8,7 @@ int wchar_width(wchar_t);
int wstring_width(const std::wstring&); int wstring_width(const std::wstring&);
} // namespace ftxui } // namespace ftxui
#endif /* end of include guard: FTXUI_SCREEN_DEPRECATED_HPP */ #endif // FTXUI_SCREEN_DEPRECATED_HPP
// Copyright 2021 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 // Use of this source code is governed by the MIT license that can be found in

View File

@@ -1,5 +1,5 @@
#ifndef FTXUI_SCREEN_SCREEN #ifndef FTXUI_SCREEN_SCREEN_HPP
#define FTXUI_SCREEN_SCREEN #define FTXUI_SCREEN_SCREEN_HPP
#include <memory> #include <memory>
#include <string> // for string, allocator, basic_string #include <string> // for string, allocator, basic_string
@@ -14,6 +14,8 @@ namespace ftxui {
/// @brief A unicode character and its associated style. /// @brief A unicode character and its associated style.
/// @ingroup screen /// @ingroup screen
struct Pixel { struct Pixel {
bool operator==(const Pixel& other) const;
// The graphemes stored into the pixel. To support combining characters, // The graphemes stored into the pixel. To support combining characters,
// like: a⃦, this can potentially contains multiple codepoitns. // like: a⃦, this can potentially contains multiple codepoitns.
std::string character = " "; std::string character = " ";
@@ -28,13 +30,15 @@ struct Pixel {
bool dim : 1; bool dim : 1;
bool inverted : 1; bool inverted : 1;
bool underlined : 1; bool underlined : 1;
bool automerge : 1;
Pixel() Pixel()
: blink(false), : blink(false),
bold(false), bold(false),
dim(false), dim(false),
inverted(false), inverted(false),
underlined(false) {} underlined(false),
automerge(false) {}
}; };
/// @brief Define how the Screen's dimensions should look like. /// @brief Define how the Screen's dimensions should look like.
@@ -62,17 +66,16 @@ class Screen {
void Print(); void Print();
// Get screen dimensions. // Get screen dimensions.
int dimx() { return dimx_; } int dimx() const { return dimx_; }
int dimy() { return dimy_; } int dimy() const { return dimy_; }
// Move the terminal cursor n-lines up with n = dimy(). // Move the terminal cursor n-lines up with n = dimy().
std::string ResetPosition(bool clear = false); std::string ResetPosition(bool clear = false) const;
// Fill with space. // Fill with space.
void Clear(); void Clear();
void ApplyShader(); void ApplyShader();
Box stencil;
struct Cursor { struct Cursor {
int x = 0; int x = 0;
@@ -81,16 +84,20 @@ class Screen {
Cursor cursor() const { return cursor_; } Cursor cursor() const { return cursor_; }
void SetCursor(Cursor cursor) { cursor_ = cursor; } void SetCursor(Cursor cursor) { cursor_ = cursor; }
Box stencil;
protected: protected:
int dimx_; int dimx_;
int dimy_; int dimy_;
std::vector<std::vector<Pixel>> pixels_; std::vector<std::vector<Pixel>> pixels_;
Cursor cursor_; Cursor cursor_;
private:
}; };
} // namespace ftxui } // namespace ftxui
#endif /* end of include guard: FTXUI_SCREEN_SCREEN */ #endif // FTXUI_SCREEN_SCREEN_HPP
// Copyright 2020 Arthur Sonzogni. All rights reserved. // Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in // Use of this source code is governed by the MIT license that can be found in

View File

@@ -1,8 +1,9 @@
#ifndef FTXUI_SCREEN_STRING_HPP #ifndef FTXUI_SCREEN_STRING_HPP
#define FTXUI_SCREEN_STRING_HPP #define FTXUI_SCREEN_STRING_HPP
#include <string> // for string, wstring, to_string #include <stddef.h> // for size_t
#include <vector> // for vector #include <string> // for string, wstring, to_string
#include <vector> // for vector
namespace ftxui { namespace ftxui {
std::string to_string(const std::wstring& s); std::string to_string(const std::wstring& s);
@@ -14,7 +15,20 @@ std::wstring to_wstring(T s) {
} }
int string_width(const std::string&); int string_width(const std::string&);
// Split the string into a its glyphs. An empty one is inserted ater fullwidth
// ones.
std::vector<std::string> Utf8ToGlyphs(const std::string& input); std::vector<std::string> Utf8ToGlyphs(const std::string& input);
// If |input| was an array of glyphs, this returns the number of char to eat
// before reaching the glyph at index |glyph_index|.
int GlyphPosition(const std::string& input,
size_t glyph_index,
size_t start = 0);
// Returns the number of glyphs in |input|.
int GlyphCount(const std::string& input);
// Map every cells drawn by |input| to their corresponding Glyphs. Half-size
// Glyphs takes one cell, full-size Glyphs take two cells.
std::vector<int> CellToGlyphIndex(const std::string& input);
} // namespace ftxui } // namespace ftxui

View File

@@ -1,5 +1,5 @@
#ifndef FTXUI_CORE_TERMINAL_HPP #ifndef FTXUI_SCREEN_TERMINAL_HPP
#define FTXUI_CORE_TERMINAL_HPP #define FTXUI_SCREEN_TERMINAL_HPP
namespace ftxui { namespace ftxui {
struct Dimensions { struct Dimensions {
@@ -9,6 +9,7 @@ struct Dimensions {
namespace Terminal { namespace Terminal {
Dimensions Size(); Dimensions Size();
void SetFallbackSize(const Dimensions& fallbackSize);
enum Color { enum Color {
Palette1, Palette1,
@@ -17,11 +18,13 @@ enum Color {
TrueColor, TrueColor,
}; };
Color ColorSupport(); Color ColorSupport();
void SetColorSupport(Color color);
} // namespace Terminal } // namespace Terminal
} // namespace ftxui } // namespace ftxui
#endif /* end of include guard: FTXUI_CORE_TERMINAL_HPP */ #endif // FTXUI_SCREEN_TERMINAL_HPP
// Copyright 2020 Arthur Sonzogni. All rights reserved. // Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in // Use of this source code is governed by the MIT license that can be found in

View File

@@ -13,9 +13,9 @@ class ConstRef {
ConstRef() {} ConstRef() {}
ConstRef(T t) : owned_(t) {} ConstRef(T t) : owned_(t) {}
ConstRef(const T* t) : address_(t) {} ConstRef(const T* t) : address_(t) {}
const T& operator*() { return address_ ? *address_ : owned_; } const T& operator*() const { return address_ ? *address_ : owned_; }
const T& operator()() { return address_ ? *address_ : owned_; } const T& operator()() const { return address_ ? *address_ : owned_; }
const T* operator->() { return address_ ? address_ : &owned_; } const T* operator->() const { return address_ ? address_ : &owned_; }
private: private:
T owned_; T owned_;
@@ -27,7 +27,8 @@ template <typename T>
class Ref { class Ref {
public: public:
Ref() {} Ref() {}
Ref(T t) : owned_(t) {} Ref(const T& t) : owned_(t) {}
Ref(T&& t) : owned_(std::forward<T>(t)) {}
Ref(T* t) : address_(t) {} Ref(T* t) : address_(t) {}
T& operator*() { return address_ ? *address_ : owned_; } T& operator*() { return address_ ? *address_ : owned_; }
T& operator()() { return address_ ? *address_ : owned_; } T& operator()() { return address_ ? *address_ : owned_; }
@@ -54,23 +55,6 @@ class StringRef {
std::string* address_ = nullptr; std::string* address_ = nullptr;
}; };
/// @brief An adapter. Own or reference a constant string. For convenience, this
/// class convert multiple mutable string toward a shared representation.
class WideStringRef {
public:
WideStringRef(std::wstring* ref) : address_(ref) {}
WideStringRef(std::wstring ref) : owned_(std::move(ref)) {}
WideStringRef(const wchar_t* ref) : WideStringRef(std::wstring(ref)) {}
WideStringRef(const char* ref)
: WideStringRef(to_wstring(std::string(ref))) {}
std::wstring& operator*() { return address_ ? *address_ : owned_; }
std::wstring* operator->() { return address_ ? address_ : &owned_; }
private:
std::wstring owned_;
std::wstring* address_ = nullptr;
};
/// @brief An adapter. Own or reference a constant string. For convenience, this /// @brief An adapter. Own or reference a constant string. For convenience, this
/// class convert multiple immutable string toward a shared representation. /// class convert multiple immutable string toward a shared representation.
class ConstStringRef { class ConstStringRef {
@@ -82,8 +66,10 @@ class ConstStringRef {
ConstStringRef(const wchar_t* ref) : ConstStringRef(std::wstring(ref)) {} ConstStringRef(const wchar_t* ref) : ConstStringRef(std::wstring(ref)) {}
ConstStringRef(const char* ref) ConstStringRef(const char* ref)
: ConstStringRef(to_wstring(std::string(ref))) {} : ConstStringRef(to_wstring(std::string(ref))) {}
const std::string& operator*() { return address_ ? *address_ : owned_; } const std::string& operator*() const { return address_ ? *address_ : owned_; }
const std::string* operator->() { return address_ ? address_ : &owned_; } const std::string* operator->() const {
return address_ ? address_ : &owned_;
}
private: private:
const std::string owned_; const std::string owned_;

View File

@@ -1,12 +1,17 @@
[ [
{ symbol: [ "char_traits", private, "<string>", public ] }, { include: ["<bits/termios-c_cc.h>", "private", "<termios.h>", "public"]},
{ symbol: [ "ECHO", private, "<termios.h>", public ] }, { include: ["<bits/termios-c_lflag.h>", "private", "<termios.h>", "public"]},
{ symbol: [ "ICANON", private, "<termios.h>", public ] }, { include: ["<bits/termios-struct.h>", "private", "<termios.h>", "public"]},
{ symbol: [ "TCSANOW", private, "<termios.h>", public ] }, { include: ["<bits/termios-tcflow.h>", "private", "<termios.h>", "public"]},
{ symbol: [ "VMIN", private, "<termios.h>", public ] }, { include: ["<ext/alloc_traits.h>", "private", "<vector>", "public"] },
{ symbol: [ "VTIME", private, "<termios.h>", public ] }, { symbol: [ "ftxui", "private", "", "public" ] },
{ symbol: [ "__shared_ptr_access", private, "<memory>", public ] }, { symbol: [ "char_traits", "private", "<string>", "public" ] },
{ symbol: [ "termios", private, "<termios.h>", public ] }, { symbol: [ "ECHO", "private", "<termios.h>", "public" ] },
{ symbol: ["__alloc_traits<>:value_type", private, "<vector>", public ] }, { symbol: [ "ICANON", "private", "<termios.h>", "public" ] },
{ include: ["<ext/alloc_traits.h>", private, "<vector>", public] }, { symbol: [ "TCSANOW", "private", "<termios.h>", "public" ] },
{ symbol: [ "VMIN", "private", "<termios.h>", "public" ] },
{ symbol: [ "VTIME", "private", "<termios.h>", "public" ] },
{ symbol: [ "__shared_ptr_access", "private", "<memory>", "public" ] },
{ symbol: [ "termios", "private", "<termios.h>", "public" ] },
{ symbol: ["__alloc_traits<>:value_type", "private", "<vector>", "public" ] },
] ]

View File

@@ -0,0 +1,293 @@
#include <cmath>
#include <ratio> // for ratio
#include <utility> // for move
#include "ftxui/component/animation.hpp"
namespace ftxui::animation {
namespace easing {
namespace {
constexpr float kPi = 3.14159265358979323846F;
constexpr float kPi2 = kPi / 2.F;
} // namespace
// Easing function have been taken out of:
// https://github.com/warrenm/AHEasing/blob/master/AHEasing/easing.c
//
// Corresponding license:
// Copyright (c) 2011, Auerhaus Development, LLC
//
// This program is free software. It comes without any warranty, to
// the extent permitted by applicable law. You can redistribute it
// and/or modify it under the terms of the Do What The Fuck You Want
// To Public License, Version 2, as published by Sam Hocevar. See
// http://sam.zoy.org/wtfpl/COPYING for more details.
// Modeled after the line y = x
float Linear(float p) {
return p;
}
// Modeled after the parabola y = x^2
float QuadraticIn(float p) {
return p * p;
}
// Modeled after the parabola y = -x^2 + 2x
float QuadraticOut(float p) {
return -(p * (p - 2));
}
// Modeled after the piecewise quadratic
// y = (1/2)((2x)^2) ; [0, 0.5)
// y = -(1/2)((2x-1)*(2x-3) - 1) ; [0.5, 1]
float QuadraticInOut(float p) {
if (p < 0.5F) { // NOLINT
return 2 * p * p;
} else {
return (-2 * p * p) + (4 * p) - 1;
}
}
// Modeled after the cubic y = x^3
float CubicIn(float p) {
return p * p * p;
}
// Modeled after the cubic y = (x - 1)^3 + 1
float CubicOut(float p) {
float f = (p - 1);
return f * f * f + 1;
}
// Modeled after the piecewise cubic
// y = (1/2)((2x)^3) ; [0, 0.5)
// y = (1/2)((2x-2)^3 + 2) ; [0.5, 1]
float CubicInOut(float p) {
if (p < 0.5F) { // NOLINT
return 4 * p * p * p;
} else {
float f = ((2 * p) - 2);
return 0.5F * f * f * f + 1; // NOLINT
}
}
// Modeled after the quartic x^4
float QuarticIn(float p) {
return p * p * p * p;
}
// Modeled after the quartic y = 1 - (x - 1)^4
float QuarticOut(float p) {
float f = (p - 1);
return f * f * f * (1 - p) + 1;
}
// Modeled after the piecewise quartic
// y = (1/2)((2x)^4) ; [0, 0.5)
// y = -(1/2)((2x-2)^4 - 2) ; [0.5, 1]
float QuarticInOut(float p) {
if (p < 0.5F) { // NOLINT
return 8 * p * p * p * p; // NOLINT
} else {
float f = (p - 1);
return -8 * f * f * f * f + 1; // NOLINT
}
}
// Modeled after the quintic y = x^5
float QuinticIn(float p) {
return p * p * p * p * p;
}
// Modeled after the quintic y = (x - 1)^5 + 1
float QuinticOut(float p) {
float f = (p - 1);
return f * f * f * f * f + 1;
}
// Modeled after the piecewise quintic
// y = (1/2)((2x)^5) ; [0, 0.5)
// y = (1/2)((2x-2)^5 + 2) ; [0.5, 1]
float QuinticInOut(float p) {
if (p < 0.5F) { // NOLINT
return 16 * p * p * p * p * p; // NOLINT
} else { // NOLINT
float f = ((2 * p) - 2); // NOLINT
return 0.5 * f * f * f * f * f + 1; // NOLINT
}
}
// Modeled after quarter-cycle of sine wave
float SineIn(float p) {
return std::sin((p - 1) * kPi2) + 1;
}
// Modeled after quarter-cycle of sine wave (different phase)
float SineOut(float p) {
return std::sin(p * kPi2);
}
// Modeled after half sine wave
float SineInOut(float p) {
return 0.5F * (1 - std::cos(p * kPi)); // NOLINT
}
// Modeled after shifted quadrant IV of unit circle
float CircularIn(float p) {
return 1 - std::sqrt(1 - (p * p));
}
// Modeled after shifted quadrant II of unit circle
float CircularOut(float p) {
return std::sqrt((2 - p) * p);
}
// Modeled after the piecewise circular function
// y = (1/2)(1 - sqrt(1 - 4x^2)) ; [0, 0.5)
// y = (1/2)(sqrt(-(2x - 3)*(2x - 1)) + 1) ; [0.5, 1]
float CircularInOut(float p) {
if (p < 0.5F) { // NOLINT
return 0.5F * (1 - std::sqrt(1 - 4 * (p * p))); // NOLINT
} else {
return 0.5F * (std::sqrt(-((2 * p) - 3) * ((2 * p) - 1)) + 1); // NOLINT
}
}
// Modeled after the exponential function y = 2^(10(x - 1))
float ExponentialIn(float p) {
return (p == 0.0) ? p : std::pow(2, 10 * (p - 1)); // NOLINT
}
// Modeled after the exponential function y = -2^(-10x) + 1
float ExponentialOut(float p) {
return (p == 1.0) ? p : 1 - std::pow(2, -10 * p); // NOLINT
}
// Modeled after the piecewise exponential
// y = (1/2)2^(10(2x - 1)) ; [0,0.5)
// y = -(1/2)*2^(-10(2x - 1))) + 1 ; [0.5,1]
float ExponentialInOut(float p) {
if (p == 0.0 || p == 1.F) {
return p;
}
if (p < 0.5F) { // NOLINT
return 0.5 * std::pow(2, (20 * p) - 10); // NOLINT
} else { // NOLINT
return -0.5 * std::pow(2, (-20 * p) + 10) + 1; // NOLINT
}
}
// Modeled after the damped sine wave y = sin(13pi/2*x)*pow(2, 10 * (x - 1))
float ElasticIn(float p) {
return std::sin(13.F * kPi2 * p) * std::pow(2.F, 10.F * (p - 1)); // NOLINT
}
// Modeled after the damped sine wave y = sin(-13pi/2*(x + 1))*pow(2, -10x) +
// 1
float ElasticOut(float p) {
// NOLINTNEXTLINE
return std::sin(-13.F * kPi2 * (p + 1)) * std::pow(2.F, -10.F * p) + 1;
}
// Modeled after the piecewise exponentially-damped sine wave:
// y = (1/2)*sin(13pi/2*(2*x))*pow(2, 10 * ((2*x) - 1)) ; [0,0.5)
// y = (1/2)*(sin(-13pi/2*((2x-1)+1))*pow(2,-10(2*x-1)) + 2) ; [0.5, 1]
float ElasticInOut(float p) {
if (p < 0.5F) { // NOLINT
return 0.5 * std::sin(13.F * kPi2 * (2 * p)) * // NOLINT
std::pow(2, 10 * ((2 * p) - 1)); // NOLINT
} else { // NOLINT
return 0.5 * (std::sin(-13.F * kPi2 * ((2 * p - 1) + 1)) * // NOLINT
std::pow(2, -10 * (2 * p - 1)) + // NOLINT
2); // NOLINT
}
}
// Modeled after the overshooting cubic y = x^3-x*sin(x*pi)
float BackIn(float p) {
return p * p * p - p * std::sin(p * kPi);
}
// Modeled after overshooting cubic y = 1-((1-x)^3-(1-x)*sin((1-x)*pi))
float BackOut(float p) {
float f = (1 - p);
return 1 - (f * f * f - f * std::sin(f * kPi));
}
// Modeled after the piecewise overshooting cubic function:
// y = (1/2)*((2x)^3-(2x)*sin(2*x*pi)) ; [0, 0.5)
// y = (1/2)*(1-((1-x)^3-(1-x)*sin((1-x)*pi))+1) ; [0.5, 1]
float BackInOut(float p) {
if (p < 0.5F) { // NOLINT
float f = 2 * p;
return 0.5F * (f * f * f - f * std::sin(f * kPi)); // NOLINT
} else {
float f = (1 - (2 * p - 1)); // NOLINT
return 0.5F * (1 - (f * f * f - f * std::sin(f * kPi))) + 0.5; // NOLINT
}
}
float BounceIn(float p) {
return 1 - BounceOut(1 - p);
}
float BounceOut(float p) {
if (p < 4 / 11.0) { // NOLINT
return (121 * p * p) / 16.0; // NOLINT
} else if (p < 8 / 11.0) { // NOLINT
return (363 / 40.0 * p * p) - (99 / 10.0 * p) + 17 / 5.0; // NOLINT
} else if (p < 9 / 10.0) { // NOLINT
return (4356 / 361.0 * p * p) - (35442 / 1805.0 * p) + // NOLINT
16061 / 1805.0; // NOLINT
} else { // NOLINT
return (54 / 5.0 * p * p) - (513 / 25.0 * p) + 268 / 25.0; // NOLINT
}
}
float BounceInOut(float p) { // NOLINT
if (p < 0.5F) { // NOLINT
return 0.5F * BounceIn(p * 2); // NOLINT
} else { // NOLINT
return 0.5F * BounceOut(p * 2 - 1) + 0.5F; // NOLINT
}
}
} // namespace easing
Animator::Animator(float* from,
float to,
Duration duration,
easing::Function easing_function,
Duration delay)
: value_(from),
from_(*from),
to_(to),
duration_(duration),
easing_function_(std::move(easing_function)),
current_(-delay) {
RequestAnimationFrame();
}
void Animator::OnAnimation(Params& params) {
current_ += params.duration();
if (current_ >= duration_) {
*value_ = to_;
return;
}
if (current_ <= Duration()) {
*value_ = from_;
} else {
*value_ = from_ +
(to_ - from_) * easing_function_(current_ / duration_); // NOLINT
}
RequestAnimationFrame();
}
} // namespace ftxui::animation

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