mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2025-09-28 16:29:34 +08:00
Compare commits
144 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
513ec6c5e1 | ||
![]() |
234b3c8a5d | ||
![]() |
6ce88c25e5 | ||
![]() |
f74c5322bd | ||
![]() |
1e86587b68 | ||
![]() |
41c3d4dd52 | ||
![]() |
2fb0b77f02 | ||
![]() |
e2aff66b98 | ||
![]() |
22ebc823c9 | ||
![]() |
49f0277103 | ||
![]() |
ac10603fdb | ||
![]() |
a3f51ecf22 | ||
![]() |
78897ef1f4 | ||
![]() |
debcbc668c | ||
![]() |
1a7a550bfe | ||
![]() |
4ce8f6d250 | ||
![]() |
7b08dae6d0 | ||
![]() |
521d1125d9 | ||
![]() |
0903ad1608 | ||
![]() |
399549d180 | ||
![]() |
7bdca3ee68 | ||
![]() |
eb313e0f2d | ||
![]() |
d3ee655a90 | ||
![]() |
d301fab1f4 | ||
![]() |
3e35f45830 | ||
![]() |
a4e70dfb93 | ||
![]() |
b2853c8f14 | ||
![]() |
6fe8310321 | ||
![]() |
350dcac032 | ||
![]() |
65848d1e5f | ||
![]() |
1561293140 | ||
![]() |
90dfceefcb | ||
![]() |
5410329ac6 | ||
![]() |
9f9571190a | ||
![]() |
b56afce48c | ||
![]() |
abd5b2a503 | ||
![]() |
60b9e491db | ||
![]() |
6cea410eaa | ||
![]() |
a52b959f66 | ||
![]() |
0542227ba7 | ||
![]() |
4dc1a9fff9 | ||
![]() |
b9f51844c3 | ||
![]() |
0d54285e19 | ||
![]() |
f21ca3aa14 | ||
![]() |
05f29ff3b3 | ||
![]() |
55b9706cfd | ||
![]() |
121bd0d046 | ||
![]() |
2c5681ee20 | ||
![]() |
1689802349 | ||
![]() |
9babfea36b | ||
![]() |
dfdbe1eecf | ||
![]() |
aeaf39b8ea | ||
![]() |
0acfd8f255 | ||
![]() |
26d63bc56f | ||
![]() |
f692a50195 | ||
![]() |
e04ea27dcd | ||
![]() |
f4b47333be | ||
![]() |
ccfe22bc24 | ||
![]() |
5ba29a9539 | ||
![]() |
c61fadd8ec | ||
![]() |
b3aad183da | ||
![]() |
fab74f745d | ||
![]() |
c8ec151154 | ||
![]() |
1d76a2321c | ||
![]() |
1661a5e83d | ||
![]() |
b3ba747d82 | ||
![]() |
8226c5aea7 | ||
![]() |
1e381fcad6 | ||
![]() |
d04e04adc6 | ||
![]() |
ec994a4e65 | ||
![]() |
3ec765e1f0 | ||
![]() |
251306a4bb | ||
![]() |
7cc68cfbd0 | ||
![]() |
36460fea2a | ||
![]() |
d755356481 | ||
![]() |
f461050759 | ||
![]() |
e42ab7b2e6 | ||
![]() |
d9241435ce | ||
![]() |
d5044bdaaf | ||
![]() |
f91677e79f | ||
![]() |
d6da30a518 | ||
![]() |
d5b1899290 | ||
![]() |
d545fb6f19 | ||
![]() |
f80e20c4aa | ||
![]() |
d805eb0648 | ||
![]() |
940f805b8f | ||
![]() |
57da24dfdb | ||
![]() |
0abaab6268 | ||
![]() |
ef0f1da147 | ||
![]() |
137f1fbf67 | ||
![]() |
094d8d9d0a | ||
![]() |
81e086788d | ||
![]() |
925a7578d4 | ||
![]() |
bb3231695f | ||
![]() |
0a522488a7 | ||
![]() |
b63aa9e375 | ||
![]() |
ed5b4cec49 | ||
![]() |
219daf46ff | ||
![]() |
11519ef1c6 | ||
![]() |
f9256fa132 | ||
![]() |
c033ca61ae | ||
![]() |
a6e04b4346 | ||
![]() |
09a2c077eb | ||
![]() |
bc206f85da | ||
![]() |
e9772a0116 | ||
![]() |
e4c5c7b43b | ||
![]() |
c2e1920449 | ||
![]() |
3d56146447 | ||
![]() |
c33e805a76 | ||
![]() |
d0890f94d1 | ||
![]() |
84d6e6b3dd | ||
![]() |
001dd0a8c3 | ||
![]() |
114cbfcffd | ||
![]() |
5ba301d316 | ||
![]() |
06ed8567b8 | ||
![]() |
04b36df567 | ||
![]() |
764c24ef40 | ||
![]() |
b2896aba49 | ||
![]() |
9f610a0110 | ||
![]() |
aebde94352 | ||
![]() |
62fb6298be | ||
![]() |
548fa51b71 | ||
![]() |
1a3fcc1bd8 | ||
![]() |
0137d2a9ac | ||
![]() |
c76612a3c8 | ||
![]() |
4da63b9260 | ||
![]() |
95c766e9e4 | ||
![]() |
3e28fd6520 | ||
![]() |
a254e36632 | ||
![]() |
9dbc23a7d4 | ||
![]() |
3fe12b8a2f | ||
![]() |
43dd70979d | ||
![]() |
779c2d5b1a | ||
![]() |
20f16b3984 | ||
![]() |
f95ed885bb | ||
![]() |
63e8dadad9 | ||
![]() |
9b83205b3e | ||
![]() |
5da7b8a59a | ||
![]() |
9c4218c2a8 | ||
![]() |
62747a49b6 | ||
![]() |
8ba3698437 | ||
![]() |
7c3ca1beb5 | ||
![]() |
689d5dd299 | ||
![]() |
372d0ace4a |
24
.clang-tidy
Normal file
24
.clang-tidy
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
Checks: "*,
|
||||
-abseil-*,
|
||||
-altera-*,
|
||||
-android-*,
|
||||
-fuchsia-*,
|
||||
-google-*,
|
||||
-llvm*,
|
||||
-modernize-use-trailing-return-type,
|
||||
-zircon-*,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-cppcoreguidelines-non-private-member-variables-in-classes,
|
||||
-misc-no-recursion,
|
||||
-misc-non-private-member-variables-in-classes,
|
||||
-modernize-use-nodiscard,
|
||||
-readability-avoid-const-params-in-decls,
|
||||
-readability-else-after-return,
|
||||
-readability-identifier-length,
|
||||
-readability-implicit-bool-conversion,
|
||||
-readability-static-accessed-through-instance,
|
||||
"
|
||||
WarningsAsErrors: ''
|
||||
HeaderFilterRegex: ''
|
||||
FormatStyle: none
|
127
.github/workflows/build.yaml
vendored
127
.github/workflows/build.yaml
vendored
@@ -15,58 +15,103 @@ jobs:
|
||||
test:
|
||||
name: "Tests"
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: Linux GCC
|
||||
os: ubuntu-latest
|
||||
compiler: g++-9
|
||||
test: true
|
||||
compiler: gcc
|
||||
gcov_executable: gcov
|
||||
|
||||
- name: Linux Clang
|
||||
os: ubuntu-latest
|
||||
compiler: clang++
|
||||
test: true
|
||||
compiler: llvm
|
||||
gcov_executable: "llvm-cov gcov"
|
||||
|
||||
- name: MacOS clang
|
||||
os: macos-latest
|
||||
compiler: clang++
|
||||
test: true
|
||||
compiler: llvm
|
||||
gcov_executable: "llvm-cov gcov"
|
||||
|
||||
- name: Windows MSVC
|
||||
os: windows-latest
|
||||
compiler: cl
|
||||
test: false
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: "Checkout repository"
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: "Enable MSVC command prompt"
|
||||
if: matrix.os == 'windows-latest'
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
- name: "Setup Cpp"
|
||||
uses: aminya/setup-cpp@v1
|
||||
with:
|
||||
compiler: ${{ matrix.compiler }}
|
||||
vcvarsall: ${{ contains(matrix.os, 'windows' )}}
|
||||
cmake: true
|
||||
ninja: true
|
||||
clangtidy: true
|
||||
cppcheck: false
|
||||
gcovr: "5.0"
|
||||
opencppcoverage: true
|
||||
|
||||
- name: "Install cmake"
|
||||
uses: lukka/get-cmake@latest
|
||||
|
||||
- name: "Build debug mode"
|
||||
# make sure coverage is only enabled for Debug builds, since it sets -O0
|
||||
# to make sure coverage has meaningful results
|
||||
- name: "Configure CMake"
|
||||
run: >
|
||||
mkdir build;
|
||||
cd build;
|
||||
cmake ..
|
||||
-DCMAKE_CXX_COMPILER=${{ matrix.compiler }}
|
||||
-DFTXUI_BUILD_DOCS=OFF
|
||||
-DFTXUI_BUILD_EXAMPLES=ON
|
||||
-DFTXUI_BUILD_TESTS=ON
|
||||
-DFTXUI_BUILD_TESTS_FUZZER=OFF
|
||||
-DFTXUI_ENABLE_INSTALL=ON ;
|
||||
cmake --build . --config Debug;
|
||||
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
|
||||
-DFTXUI_DEV_WARNINGS:BOOL=ON ;
|
||||
|
||||
- name: "Run tests"
|
||||
if: matrix.test
|
||||
- name: "Build"
|
||||
run: >
|
||||
cd build;
|
||||
./tests
|
||||
cmake
|
||||
--build ./build
|
||||
|
||||
- name: Unix - Test and coverage
|
||||
if: runner.os != 'Windows'
|
||||
working-directory: ./build
|
||||
run: >
|
||||
ctest -C Debug --rerun-failed --output-on-failure;
|
||||
gcovr
|
||||
-j ${{env.nproc}}
|
||||
--delete
|
||||
--root ../
|
||||
--exclude "../examples"
|
||||
--exclude ".*google.*"
|
||||
--exclude ".*test.*"
|
||||
--exclude-unreachable-branches
|
||||
--exclude-throw-branches
|
||||
--sort-uncovered
|
||||
--print-summary
|
||||
--xml-pretty
|
||||
--xml
|
||||
coverage.xml
|
||||
.
|
||||
--gcov-executable '${{ matrix.gcov_executable }}';
|
||||
|
||||
- name: Windows - Test and coverage
|
||||
if: runner.os == 'Windows'
|
||||
working-directory: ./build
|
||||
run: >
|
||||
OpenCppCoverage.exe
|
||||
--export_type cobertura:coverage.xml
|
||||
--cover_children
|
||||
--
|
||||
ctest -C Debug --rerun-failed --output-on-failure;
|
||||
|
||||
- name: Publish to codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
flags: ${{ runner.os }}
|
||||
name: ${{ runner.os }}-coverage
|
||||
files: ./build/coverage.xml
|
||||
|
||||
# Create a release on new v* tags
|
||||
release:
|
||||
@@ -116,8 +161,9 @@ jobs:
|
||||
-DFTXUI_BUILD_EXAMPLES=OFF
|
||||
-DFTXUI_BUILD_TESTS=OFF
|
||||
-DFTXUI_BUILD_TESTS_FUZZER=OFF
|
||||
-DFTXUI_ENABLE_INSTALL=ON;
|
||||
cmake --build . --config Release --target package;
|
||||
-DFTXUI_ENABLE_INSTALL=ON
|
||||
-DFTXUI_DEV_WARNINGS=ON ;
|
||||
cmake --build . --target package;
|
||||
- uses: shogo82148/actions-upload-release-asset@v1
|
||||
with:
|
||||
upload_url: ${{ needs.release.outputs.upload_url }}
|
||||
@@ -125,7 +171,7 @@ jobs:
|
||||
overwrite: true
|
||||
|
||||
documentation:
|
||||
needs: package
|
||||
if: github.ref == 'refs/heads/master'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "Checkout repository"
|
||||
@@ -146,9 +192,24 @@ jobs:
|
||||
run: >
|
||||
mkdir build;
|
||||
cd build;
|
||||
emcmake cmake ..;
|
||||
emcmake cmake ..
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DFTXUI_BUILD_DOCS=ON
|
||||
-DFTXUI_BUILD_EXAMPLES=ON
|
||||
-DFTXUI_BUILD_TESTS=OFF
|
||||
-DFTXUI_BUILD_TESTS_FUZZER=OFF
|
||||
-DFTXUI_ENABLE_INSTALL=OFF
|
||||
-DFTXUI_DEV_WARNINGS=ON ;
|
||||
cmake --build . --target doc;
|
||||
rsync -amv --include='*/' --include='*.html' --include='*.js' --include='*.wasm' --exclude='*' examples doc/doxygen/html;
|
||||
cmake --build . ;
|
||||
rsync -amv
|
||||
--include='*/'
|
||||
--include='*.html'
|
||||
--include='*.js'
|
||||
--include='*.wasm'
|
||||
--exclude='*'
|
||||
examples
|
||||
doc/doxygen/html;
|
||||
|
||||
- name: "Deploy"
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
|
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"platform": [
|
||||
"GTest::+gtest"
|
||||
]
|
||||
}
|
141
CHANGELOG.md
141
CHANGELOG.md
@@ -1,8 +1,145 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
current (development)
|
||||
---------------------
|
||||
4.1.1
|
||||
-----
|
||||
|
||||
### Component
|
||||
- Revert Feature: Support `ResizableSplit` with customizable separator.
|
||||
|
||||
### Build
|
||||
- Check version compatibility when using cmake find_package()
|
||||
|
||||
4.1.0 (abandonned)
|
||||
-----
|
||||
|
||||
### Component
|
||||
- Feature: Support `ResizableSplit` with customizable separator.
|
||||
- Fix: Support arrow keys in application mode
|
||||
- Fix: Remove useless new line when using an alternative screen.
|
||||
|
||||
### Dom
|
||||
- Feature: Add the dashed style for border and separator.
|
||||
- Feature: Add colored borders.
|
||||
- Feature: Add `LinearGradient`!
|
||||
- Improvement: Color::Interpolate() uses gamma correction.
|
||||
- Fix: Check the `graph` area is positive.
|
||||
|
||||
### Build/Install
|
||||
- Use globally set CMAKE_CXX_STANDARD if it is set.
|
||||
- Expose the pkg-config file.
|
||||
|
||||
4.0.0
|
||||
-----
|
||||
|
||||
### DOM
|
||||
- Feature: more styles:
|
||||
- `strikethrough`
|
||||
- `underlinedDouble`
|
||||
- Feature: Customize the cursor. Add the following decorators:
|
||||
- `focusCursorBlock`
|
||||
- `focusCursorBlockBlinking`
|
||||
- `focusCursorBar`
|
||||
- `focusCursorBarBlinking`
|
||||
- `focusCursorUnderline`
|
||||
- `focusCursorUnderlineBlinking`
|
||||
- Bugfix: Fix `focus`/`select` when the `vbox`/`hbox`/`dbox` contains a
|
||||
`flexbox`
|
||||
- Bugfix: Fix the selected/focused area. It used to be 1 cell larger/longer than
|
||||
requested
|
||||
- Bugfix: Forward the selected/focused area from the child in gridbox.
|
||||
- Bugfix: Fix incorrect Canvas computed dimensions.
|
||||
- Bugfix: Support `vscroll_indicator` with a zero inner size.
|
||||
- Bugfix: Fix `vscroll_indicator` hidding the last column.
|
||||
|
||||
### Component:
|
||||
- Feature: Add the `Modal` component.
|
||||
- Feature: `Slider` supports taking references for all its arguments.
|
||||
- Feature: `Slider` supports `SliderOption`. It supports:
|
||||
- multiple directions.
|
||||
- multiple colors.
|
||||
- various values (value, min, max, increment).
|
||||
- Feature: Define `ScreenInteractive::Exit()`.
|
||||
- Feature: Add `Loop` to give developers a better control on the main loop. This
|
||||
can be used to integrate FTXUI into another main loop, without taking the full
|
||||
control.
|
||||
- Feature: `Input` supports CTRL+Left and CTRL+Right
|
||||
- Feature: Use a blinking bar in the `Input` component.
|
||||
- Improvement: The `Menu` keeps the focus when an entry is selected with the
|
||||
mouse.
|
||||
- Bugfix: Add implementation of `ButtonOption::Border()`. It was missing.
|
||||
- Bugfix: Provide the correct key for F1-F4 and F11.
|
||||
- Feature: Add the `Hoverable` component decorators.
|
||||
|
||||
### Screen
|
||||
- Feature: add `Box::Union(a,b) -> Box`
|
||||
- Bugfix: Fix resetting `dim` clashing with resetting of `bold`.
|
||||
- Feature: Add emscripten screen resize support.
|
||||
- Bugfix: Add unicode 13 support for full width characters.
|
||||
- Bugfix: Fix MSVC treating codecvt C++17 deprecated function as an error.
|
||||
|
||||
### Build
|
||||
- Support using the google test version provided by the package manager.
|
||||
|
||||
3.0.0
|
||||
-----
|
||||
|
||||
### Build
|
||||
- **breaking**: The library prefix is now back to "lib" (the default). This
|
||||
means non-cmake users should not link against "libftxui-dom" for instance.
|
||||
|
||||
### Component
|
||||
- **Animations** module! Components can implement the `OnAnimation` method and
|
||||
the animation::Animator to define some animated properties.
|
||||
- `Menu` now support animations.
|
||||
- `Button` now supports animations.
|
||||
- Support SIGTSTP. (ctrl+z).
|
||||
- Support task posting. `ScreenInteractive::Post(Task)`.
|
||||
- `Menu` can now be used in the 4 directions, using `MenuOption.direction`.
|
||||
- `Menu` can display an animated underline, using
|
||||
`MenuOption.underline.enabled`.
|
||||
- `Button` is now taking the focus in frame.
|
||||
- **breaking** All the options are now using a transform function.
|
||||
- **breaking** The `Toggle` component is now implemented using `Menu`.
|
||||
- **bugfix** Container::Tab implements `Focusable()`.
|
||||
- **bugfix** Improved default implementations of ComponentBase `Focusable()` and
|
||||
`ActiveChild()` methods.
|
||||
- **bugfix** Automatically convert '\r' keys into '\n' for Linux programs that
|
||||
do not send the correct code for the return key, like the 'bind'.
|
||||
https://github.com/ArthurSonzogni/FTXUI/issues/337
|
||||
- Add decorator for components:
|
||||
- `operator|(Component, ComponentDecorator)`
|
||||
- `operator|(Component, ElementDecorator)`
|
||||
- `operator|=(Component, ComponentDecorator)`
|
||||
- `operator|=(Component, ElementDecorator)`
|
||||
- Add the `Maybe` decorator.
|
||||
- Add the `CatchEvent` decorator.
|
||||
- Add the `Renderer` decorator.
|
||||
- **breaking** remove the "deprectated.hpp" header and Input support for wide
|
||||
string.
|
||||
|
||||
### DOM:
|
||||
- **breaking**: The `inverted` decorator now toggle in the inverted attribute.
|
||||
- Add `gauge` for the 4 directions. Expose the following API:
|
||||
```cpp
|
||||
Element gauge(float ratio);
|
||||
Element gaugeLeft(float ratio);
|
||||
Element gaugeRight(float ratio);
|
||||
Element gaugeUp(float ratio);
|
||||
Element gaugeDown(float ratio);
|
||||
Element gaugeDirection(float ratio, GaugeDirection);
|
||||
```
|
||||
- Add `separatorHSelector` and `separatorVSelector` elements. This can be used
|
||||
to highlight an area.
|
||||
- Add the `automerge` decorator. This makes separator characters to be merged
|
||||
with others nearby.
|
||||
- Fix the `Table` rendering function, to allow automerging characters.
|
||||
- **Bugfix**: The `vscroll_indicator` now computes its offset and size
|
||||
correctly.
|
||||
- Add the `operator|=(Element, Decorator)`
|
||||
|
||||
### Screen:
|
||||
- Add: `Color::Interpolate(lambda, color_a, color_b)`.
|
||||
|
||||
2.0.0
|
||||
-----
|
||||
|
@@ -2,7 +2,8 @@ cmake_minimum_required(VERSION 3.11)
|
||||
|
||||
project(ftxui
|
||||
LANGUAGES CXX
|
||||
VERSION 2.0.0
|
||||
VERSION 4.1.1
|
||||
DESCRIPTION "C++ Functional Terminal User Interface."
|
||||
)
|
||||
|
||||
option(FTXUI_BUILD_DOCS "Set to ON to build docs" ON)
|
||||
@@ -10,6 +11,9 @@ option(FTXUI_BUILD_EXAMPLES "Set to ON to build examples" ON)
|
||||
option(FTXUI_BUILD_TESTS "Set to ON to build tests" OFF)
|
||||
option(FTXUI_BUILD_TESTS_FUZZER "Set to ON to enable fuzzing" OFF)
|
||||
option(FTXUI_ENABLE_INSTALL "Generate the install target" ON)
|
||||
option(FTXUI_CLANG_TIDY "Execute clang-tidy" OFF)
|
||||
option(FTXUI_ENABLE_COVERAGE "Execute code coverage" OFF)
|
||||
option(FTXUI_DEV_WARNINGS "Enable more compiler warnings and warnings as errors" OFF)
|
||||
|
||||
set(FTXUI_MICROSOFT_TERMINAL_FALLBACK_HELP_TEXT "On windows, assume the \
|
||||
terminal used will be one of Microsoft and use a set of reasonnable fallback \
|
||||
@@ -22,6 +26,7 @@ else()
|
||||
${FTXUI_MICROSOFT_TERMINAL_FALLBACK_HELP_TEXT} OFF)
|
||||
endif()
|
||||
|
||||
|
||||
add_library(screen
|
||||
include/ftxui/screen/box.hpp
|
||||
include/ftxui/screen/color.hpp
|
||||
@@ -44,6 +49,7 @@ add_library(dom
|
||||
include/ftxui/dom/node.hpp
|
||||
include/ftxui/dom/requirement.hpp
|
||||
include/ftxui/dom/take_any_args.hpp
|
||||
src/ftxui/dom/automerge.cpp
|
||||
src/ftxui/dom/blink.cpp
|
||||
src/ftxui/dom/bold.cpp
|
||||
src/ftxui/dom/border.cpp
|
||||
@@ -67,6 +73,7 @@ add_library(dom
|
||||
src/ftxui/dom/gridbox.cpp
|
||||
src/ftxui/dom/hbox.cpp
|
||||
src/ftxui/dom/inverted.cpp
|
||||
src/ftxui/dom/linear_gradient.cpp
|
||||
src/ftxui/dom/node.cpp
|
||||
src/ftxui/dom/node_decorator.cpp
|
||||
src/ftxui/dom/paragraph.cpp
|
||||
@@ -75,32 +82,43 @@ add_library(dom
|
||||
src/ftxui/dom/separator.cpp
|
||||
src/ftxui/dom/size.cpp
|
||||
src/ftxui/dom/spinner.cpp
|
||||
src/ftxui/dom/strikethrough.cpp
|
||||
src/ftxui/dom/table.cpp
|
||||
src/ftxui/dom/text.cpp
|
||||
src/ftxui/dom/underlined.cpp
|
||||
src/ftxui/dom/underlined_double.cpp
|
||||
src/ftxui/dom/util.cpp
|
||||
src/ftxui/dom/vbox.cpp
|
||||
)
|
||||
|
||||
add_library(component
|
||||
include/ftxui/component/animation.hpp
|
||||
include/ftxui/component/captured_mouse.hpp
|
||||
include/ftxui/component/component.hpp
|
||||
include/ftxui/component/component_base.hpp
|
||||
include/ftxui/component/component_options.hpp
|
||||
include/ftxui/component/event.hpp
|
||||
include/ftxui/component/loop.hpp
|
||||
include/ftxui/component/mouse.hpp
|
||||
include/ftxui/component/receiver.hpp
|
||||
include/ftxui/component/screen_interactive.hpp
|
||||
include/ftxui/component/task.hpp
|
||||
src/ftxui/component/animation.cpp
|
||||
src/ftxui/component/button.cpp
|
||||
src/ftxui/component/catch_event.cpp
|
||||
src/ftxui/component/checkbox.cpp
|
||||
src/ftxui/component/collapsible.cpp
|
||||
src/ftxui/component/component.cpp
|
||||
src/ftxui/component/component_options.cpp
|
||||
src/ftxui/component/container.cpp
|
||||
src/ftxui/component/dropdown.cpp
|
||||
src/ftxui/component/event.cpp
|
||||
src/ftxui/component/hoverable.cpp
|
||||
src/ftxui/component/input.cpp
|
||||
src/ftxui/component/loop.cpp
|
||||
src/ftxui/component/maybe.cpp
|
||||
src/ftxui/component/menu.cpp
|
||||
src/ftxui/component/modal.cpp
|
||||
src/ftxui/component/radiobox.cpp
|
||||
src/ftxui/component/radiobox.cpp
|
||||
src/ftxui/component/renderer.cpp
|
||||
@@ -109,44 +127,41 @@ add_library(component
|
||||
src/ftxui/component/slider.cpp
|
||||
src/ftxui/component/terminal_input_parser.cpp
|
||||
src/ftxui/component/terminal_input_parser.hpp
|
||||
src/ftxui/component/toggle.cpp
|
||||
src/ftxui/component/util.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(dom
|
||||
PUBLIC screen
|
||||
)
|
||||
|
||||
find_package(Threads)
|
||||
target_link_libraries(component
|
||||
PUBLIC dom
|
||||
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})
|
||||
if (NOT EMSCRIPTEN)
|
||||
find_package(Threads)
|
||||
target_link_libraries(component
|
||||
PUBLIC Threads::Threads
|
||||
)
|
||||
endif()
|
||||
|
||||
include(cmake/ftxui_set_options.cmake)
|
||||
ftxui_set_options(screen)
|
||||
ftxui_set_options(dom)
|
||||
ftxui_set_options(component)
|
||||
|
||||
if (FTXUI_BUILD_TESTS AND ${CMAKE_VERSION} VERSION_GREATER "3.11.4")
|
||||
include(cmake/ftxui_test.cmake)
|
||||
endif()
|
||||
|
||||
if(FTXUI_BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
||||
if(FTXUI_BUILD_DOCS)
|
||||
add_subdirectory(doc)
|
||||
endif()
|
||||
include(cmake/ftxui_coverage.cmake)
|
||||
ftxui_check_coverage(screen)
|
||||
ftxui_check_coverage(dom)
|
||||
ftxui_check_coverage(component)
|
||||
|
||||
include(cmake/ftxui_test.cmake)
|
||||
include(cmake/ftxui_benchmark.cmake)
|
||||
include(cmake/ftxui_fuzzer.cmake)
|
||||
include(cmake/iwyu.cmake)
|
||||
include(cmake/ftxui_export.cmake)
|
||||
include(cmake/ftxui_install.cmake)
|
||||
include(cmake/ftxui_package.cmake)
|
||||
|
||||
if(FTXUI_ENABLE_INSTALL)
|
||||
include(cmake/ftxui_install.cmake)
|
||||
include(cmake/ftxui_package.cmake)
|
||||
endif()
|
||||
add_subdirectory(examples)
|
||||
add_subdirectory(doc)
|
||||
|
102
README.md
102
README.md
@@ -8,10 +8,14 @@
|
||||
<a href="#"><img src="https://img.shields.io/github/repo-size/ArthurSonzogni/FTXUI"></img></a>
|
||||
<a href="https://github.com/ArthurSonzogni/FTXUI/issues"><img src="https://img.shields.io/github/issues/ArthurSonzogni/FTXUI"></img></a>
|
||||
<a href="https://github.com/ArthurSonzogni/FTXUI/graphs/contributors"><img src="https://img.shields.io/github/contributors/arthursonzogni/FTXUI?color=blue"></img></a>
|
||||
<a href="https://codecov.io/gh/ArthurSonzogni/FTXUI">
|
||||
<img src="https://codecov.io/gh/ArthurSonzogni/FTXUI/branch/master/graph/badge.svg?token=C41FdRpNVA"/>
|
||||
</a>
|
||||
|
||||
|
||||
<br/>
|
||||
<a href="https://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://github.com/ArthurSonzogni/FTXUI/issues">Request Feature</a> ·
|
||||
<a href="https://github.com/ArthurSonzogni/FTXUI/pulls">Send a Pull Request</a>
|
||||
@@ -22,21 +26,34 @@
|
||||
|
||||
<i>Functional Terminal (X) User interface</i>
|
||||
|
||||
A simple C++ library for terminal based user interface.
|
||||
A simple C++ library for terminal based user interfaces!
|
||||
|
||||
## Feature
|
||||
* Functional style. Inspired by
|
||||
[[1]](https://hackernoon.com/building-reactive-terminal-interfaces-in-c-d392ce34e649?gi=d9fb9ce35901)
|
||||
and [React](https://reactjs.org/)
|
||||
* Simple and elegant syntax (in my opinion).
|
||||
* Support for [UTF8](https://en.wikipedia.org/wiki/UTF-8) and [fullwidth chars](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms) (→ 测试).
|
||||
* No dependencies.
|
||||
* Cross platform. Linux/mac (main target), Windows (experimental thanks to contributors), WebAssembly.
|
||||
* Simple and elegant syntax (in my opinion)
|
||||
* Keyboard & mouse navigation.
|
||||
* Support for [UTF8](https://en.wikipedia.org/wiki/UTF-8) and [fullwidth chars](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms) (→ 测试)
|
||||
* Support for animations. [Demo 1](https://arthursonzogni.github.io/FTXUI/examples/?file=component/menu_underline_animated_gallery), [Demo 2](https://arthursonzogni.github.io/FTXUI/examples/?file=component/button_style)
|
||||
* Support for drawing. [Demo](https://arthursonzogni.github.io/FTXUI/examples/?file=component/canvas_animated)
|
||||
* No dependencies
|
||||
* Cross platform: Linux/MacOS (main target), WebAssembly, Windows (Thanks to contributors!).
|
||||
* Learn by [examples](#documentation), and [tutorials](#documentation)
|
||||
* Multiple packages: CMake [FetchContent](https://bewagner.net/programming/2020/05/02/cmake-fetchcontent/) (preferred), vcpkg, pkgbuild, conan.
|
||||
* Good practises: documentation, tests, fuzzers, performance tests, automated CI, automated packaging, etc...
|
||||
|
||||
## Documentation
|
||||
|
||||
- [Starter example project](https://github.com/ArthurSonzogni/ftxui-starter)
|
||||
- [Documentation](https://arthursonzogni.github.io/FTXUI/)
|
||||
- [Examples (WebAssembly)](https://arthursonzogni.github.io/FTXUI/examples/)
|
||||
- [Build using CMake](https://arthursonzogni.github.io/FTXUI/#build-cmake)
|
||||
|
||||
## Operating systems
|
||||
|
||||
- Webassembly
|
||||
This is expected to be cross platform. This supports / tests:
|
||||
- WebAssembly
|
||||
- Linux
|
||||
- MacOS
|
||||
- Windows
|
||||
@@ -62,13 +79,6 @@ A simple C++ library for terminal based user interface.
|
||||
└────────────────────────────────────────────────────────────────────────────┘
|
||||
~~~
|
||||
|
||||
## 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)
|
||||
|
||||
## Short gallery
|
||||
|
||||
#### DOM
|
||||
@@ -101,7 +111,7 @@ Element can become flexible using the the `flex` decorator.
|
||||
|
||||

|
||||
|
||||
[See](https://arthursonzogni.github.io/FTXUI/examples_2dom_2hflow_8cpp-example.html) also this [demo](https://arthursonzogni.com/FTXUI/examples/?file=component/flexbox).
|
||||
[See](https://arthursonzogni.github.io/FTXUI/examples_2dom_2hflow_8cpp-example.html) also this [demo](https://arthursonzogni.github.io/FTXUI/examples/?file=component/flexbox).
|
||||
|
||||
</details>
|
||||
|
||||
@@ -112,7 +122,9 @@ An element can be decorated using the functions:
|
||||
- `dim`
|
||||
- `inverted`
|
||||
- `underlined`
|
||||
- `underlinedDouble`
|
||||
- `blink`
|
||||
- `strikethrough`
|
||||
- `color`
|
||||
- `bgcolor`
|
||||
|
||||
@@ -120,13 +132,13 @@ An element can be decorated using the functions:
|
||||
|
||||

|
||||
|
||||
FTXUI support the pipe operator. It means: `decorator1(decorator2(element))` and `element | decorator1 | decorator2` can be used.
|
||||
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 palettes:
|
||||
FTXUI support every color palette:
|
||||
|
||||
Color [gallery](https://arthursonzogni.github.io/FTXUI/examples_2dom_2color_gallery_8cpp-example.html):
|
||||

|
||||
@@ -156,7 +168,7 @@ auto document = vbox({
|
||||
|
||||
A simple piece of text is represented using `text("content")`.
|
||||
|
||||
To support text wrapping following spaces the following function are provided:
|
||||
To support text wrapping following spaces the following functions are provided:
|
||||
```cpp
|
||||
Element paragraph(std::string text);
|
||||
Element paragraphAlignLeft(std::string text);
|
||||
@@ -165,7 +177,7 @@ Element paragraphAlignCenter(std::string text);
|
||||
Element paragraphAlignJustify(std::string text);
|
||||
```
|
||||
|
||||
[Paragraph example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2table_8cpp-example.html):
|
||||
[Paragraph example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2paragraph_8cpp-example.html)
|
||||
|
||||

|
||||
|
||||
@@ -202,7 +214,7 @@ Prebuilt components are declared in [<ftxui/component/component.hpp>](https://ar
|
||||
|
||||
<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))
|
||||
[Gallery](https://arthursonzogni.github.io/FTXUI/examples_2component_2gallery_8cpp-example.html) of multiple components. ([demo](https://arthursonzogni.github.io/FTXUI/examples/?file=component/gallery))
|
||||
|
||||

|
||||
|
||||
@@ -312,16 +324,54 @@ Feel free to add your projects here:
|
||||
- [TimeAccumulator](https://github.com/asari555/TimeAccumulator)
|
||||
- [vantage](https://github.com/gokulmaxi/vantage)
|
||||
- [tabdeeli](https://github.com/typon/tabdeeli)
|
||||
- [tiles](https://github.com/tusharpm/tiles)
|
||||
- [cachyos-cli-installer](https://github.com/cachyos/new-cli-installer)
|
||||
- [beagle-config](https://github.com/SAtacker/beagle-config)
|
||||
- [turing_cmd](https://github.com/DanArmor/turing_cmd)
|
||||
- [StartUp](https://github.com/StubbornVegeta/StartUp)
|
||||
- [eCAL monitor](https://github.com/eclipse-ecal/ecal)
|
||||
|
||||
## Hosted on
|
||||
* [github](https://github.com/ArthurSonzogni/ftxui)
|
||||
* [gitlab](https://gitlab.com/ArthurSonzogni/ftxui)
|
||||
## [cpp-best-practices/game_jam](https://github.com/cpp-best-practices/game_jam)
|
||||
|
||||
Several games using the FTXUI have been made during the Game Jam:
|
||||
- [TermBreaker](https://github.com/ArthurSonzogni/termBreaker) [**[Play web version]**](https://arthursonzogni.com/TermBreaker/)
|
||||
- [Minesweeper Marathon](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/minesweeper_marathon.md) [**[Play web version]**](https://barlasgarden.com/minesweeper/index.html)
|
||||
- [Grand Rounds](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/grandrounds.md)
|
||||
- [LightsRound](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/LightsRound.v.0.1.0.md)
|
||||
- [DanteO](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/danteo.md)
|
||||
- [Sumo](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/sumo.md)
|
||||
- [Drag Me aROUND](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/drag_me_around.md)
|
||||
- [DisarmSelfDestruct](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/DisarmSelfDestruct.md)
|
||||
- [TheWorld](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/TheWorld.md)
|
||||
- [smoothlife](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/smoothlife.md)
|
||||
- [Consu](https://github.com/cpp-best-practices/game_jam/blob/main/Jam1_April_2022/consu.md)
|
||||
|
||||
## External package
|
||||
|
||||
It is **highly** recommanded to use cmake FetchContent to depends on FTXUI. This
|
||||
way you can specify which commit you would like to depends on.
|
||||
It is **highly** recommended to use CMake FetchContent to depend on FTXUI. This
|
||||
way you can specify which commit you would like to depend on.
|
||||
```cmake
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(ftxui
|
||||
GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui
|
||||
GIT_TAG v3.0.0
|
||||
)
|
||||
|
||||
FetchContent_GetProperties(ftxui)
|
||||
if(NOT ftxui_POPULATED)
|
||||
FetchContent_Populate(ftxui)
|
||||
add_subdirectory(${ftxui_SOURCE_DIR} ${ftxui_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
```
|
||||
|
||||
If you don't, the following packages have been created:
|
||||
- vcpkg ([soon](https://github.com/ArthurSonzogni/FTXUI/issues/112))
|
||||
- [vcpkg](https://vcpkgx.com/details.html?package=ftxui)
|
||||
- [Arch Linux PKGBUILD](https://aur.archlinux.org/packages/ftxui-git/).
|
||||
- [conan.io](https://conan.io/center/ftxui)
|
||||
|
||||
## Contributors
|
||||
|
||||
<a href="https://github.com/ArthurSonzogni/FTXUI/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=ArthurSonzogni/FTXUI" />
|
||||
</a>
|
||||
|
@@ -2,3 +2,5 @@
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
find_dependency(Threads)
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/ftxui-targets.cmake")
|
@@ -1,24 +1,21 @@
|
||||
if (NOT WIN32)
|
||||
FetchContent_Declare(googlebenchmark
|
||||
GIT_REPOSITORY "https://github.com/google/benchmark"
|
||||
GIT_TAG 62937f91b5c763a8e119d0c20c67b87bde8eff1c
|
||||
)
|
||||
|
||||
FetchContent_GetProperties(googlebenchmark)
|
||||
if(NOT googlebenchmark_POPULATED)
|
||||
FetchContent_Populate(googlebenchmark)
|
||||
add_subdirectory(${googlebenchmark_SOURCE_DIR} ${googlebenchmark_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
add_executable(ftxui_benchmark
|
||||
src/ftxui/dom/benchmark_test.cpp
|
||||
)
|
||||
target_link_libraries(ftxui_benchmark
|
||||
PRIVATE dom
|
||||
PRIVATE benchmark::benchmark
|
||||
PRIVATE benchmark::benchmark_main
|
||||
)
|
||||
target_include_directories(ftxui_benchmark
|
||||
PRIVATE src
|
||||
)
|
||||
if (NOT FTXUI_BUILD_TESTS OR
|
||||
NOT ${CMAKE_VERSION} VERSION_GREATER "3.11.4" OR
|
||||
WIN32
|
||||
)
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(cmake/ftxui_find_google_benchmark.cmake)
|
||||
|
||||
add_executable(ftxui-benchmark
|
||||
src/ftxui/dom/benchmark_test.cpp
|
||||
)
|
||||
ftxui_set_options(ftxui-benchmark)
|
||||
target_link_libraries(ftxui-benchmark
|
||||
PRIVATE dom
|
||||
PRIVATE benchmark::benchmark
|
||||
PRIVATE benchmark::benchmark_main
|
||||
)
|
||||
target_include_directories(ftxui-benchmark
|
||||
PRIVATE src
|
||||
)
|
||||
|
8
cmake/ftxui_coverage.cmake
Normal file
8
cmake/ftxui_coverage.cmake
Normal file
@@ -0,0 +1,8 @@
|
||||
function(ftxui_check_coverage library)
|
||||
if (FTXUI_ENABLE_COVERAGE)
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
|
||||
target_compile_options(${library} INTERFACE --coverage -O0 -g)
|
||||
target_link_libraries(${library} INTERFACE --coverage)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
32
cmake/ftxui_find_google_benchmark.cmake
Normal file
32
cmake/ftxui_find_google_benchmark.cmake
Normal file
@@ -0,0 +1,32 @@
|
||||
# Some developers would be happier with the google benchmark version provided
|
||||
# from their package manager. Use it if it is installed the package provide
|
||||
# cmake support.
|
||||
# https://github.com/ArthurSonzogni/FTXUI/issues/551
|
||||
find_package(benchmark QUIET)
|
||||
if (benchmark_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
option(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)
|
||||
option(FETCHCONTENT_QUIET FALSE)
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(googlebenchmark
|
||||
GIT_REPOSITORY "https://github.com/google/benchmark"
|
||||
GIT_TAG 62937f91b5c763a8e119d0c20c67b87bde8eff1c
|
||||
GIT_PROGRESS TRUE
|
||||
)
|
||||
|
||||
FetchContent_GetProperties(googlebenchmark)
|
||||
set (BENCHMARK_ENABLE_GTEST_TESTS OFF CACHE INTERNAL "")
|
||||
set (BENCHMARK_ENABLE_TESTING OFF CACHE INTERNAL "")
|
||||
if(googlebenchmark_POPULATED)
|
||||
return()
|
||||
endif()
|
||||
|
||||
FetchContent_Populate(googlebenchmark)
|
||||
add_subdirectory(
|
||||
${googlebenchmark_SOURCE_DIR}
|
||||
${googlebenchmark_BINARY_DIR}
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
33
cmake/ftxui_find_google_test.cmake
Normal file
33
cmake/ftxui_find_google_test.cmake
Normal file
@@ -0,0 +1,33 @@
|
||||
# Some developers would be happier with the gtest version provided from their
|
||||
# package manager. Use it if it is installed the package provide cmake support.
|
||||
# https://github.com/ArthurSonzogni/FTXUI/issues/551
|
||||
find_package(GTest QUIET)
|
||||
|
||||
if (GTest_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
option(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)
|
||||
option(FETCHCONTENT_QUIET FALSE)
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(googletest
|
||||
GIT_REPOSITORY "https://github.com/google/googletest"
|
||||
GIT_TAG 23ef29555ef4789f555f1ba8c51b4c52975f0907
|
||||
GIT_PROGRESS TRUE
|
||||
)
|
||||
|
||||
FetchContent_GetProperties(googletest)
|
||||
if(googletest_POPULATED)
|
||||
return()
|
||||
endif()
|
||||
|
||||
FetchContent_Populate(googletest)
|
||||
set(BUILD_GMOCK OFF CACHE INTERNAL "")
|
||||
set(INSTALL_GTEST OFF CACHE INTERNAL "")
|
||||
set(gtest_force_shared_crt ON CACHE INTERNAL "")
|
||||
add_subdirectory(
|
||||
${googletest_SOURCE_DIR}
|
||||
${googletest_BINARY_DIR}
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
@@ -1,22 +1,20 @@
|
||||
if (NOT FTXUI_BUILD_TESTS_FUZZER)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_COMPILER clang)
|
||||
set(CMAKE_CXX_COMPILER clang++)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
function(fuzz name)
|
||||
add_executable(${name}
|
||||
src/ftxui/component/${name}.cpp
|
||||
)
|
||||
target_include_directories(${name}
|
||||
PRIVATE src
|
||||
)
|
||||
target_link_libraries(${name}
|
||||
PRIVATE component
|
||||
)
|
||||
target_compile_options(${name}
|
||||
PRIVATE -fsanitize=fuzzer,address
|
||||
)
|
||||
target_link_libraries(${name}
|
||||
PRIVATE -fsanitize=fuzzer,address
|
||||
)
|
||||
target_include_directories(${name} PRIVATE src)
|
||||
target_link_libraries(${name} PRIVATE component)
|
||||
target_compile_options(${name} PRIVATE -fsanitize=fuzzer,address)
|
||||
target_link_libraries(${name} PRIVATE -fsanitize=fuzzer,address)
|
||||
target_compile_features(${name} PRIVATE cxx_std_17)
|
||||
endfunction(fuzz)
|
||||
|
||||
fuzz(terminal_input_parser_test_fuzzer)
|
||||
|
@@ -1,29 +1,62 @@
|
||||
if(NOT FTXUI_ENABLE_INSTALL)
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS screen dom component
|
||||
EXPORT ftxui-export
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
install(DIRECTORY include/ftxui DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
configure_package_config_file(ftxui-config.cmake.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ftxui-config.cmake
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/ftxui/cmake
|
||||
PATH_VARS CMAKE_INSTALL_INCLUDEDIR
|
||||
)
|
||||
write_basic_package_version_file(
|
||||
ftxui-config-version.cmake
|
||||
VERSION ${PACKAGE_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ftxui-config.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ftxui
|
||||
)
|
||||
install(EXPORT ftxui-export
|
||||
FILE ftxui-config-version.cmake
|
||||
# ------------------------------------------------------------------------------
|
||||
# Install the library and its public headers into the standard subdirectories
|
||||
# ------------------------------------------------------------------------------
|
||||
install(
|
||||
TARGETS screen dom component
|
||||
EXPORT ftxui-targets
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY include/ftxui
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Install the exported cmake targets for use in other CMake projects.
|
||||
# ------------------------------------------------------------------------------
|
||||
install(
|
||||
EXPORT ftxui-targets
|
||||
NAMESPACE ftxui::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ftxui
|
||||
)
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Create and install the ftuxi-config.cmake and ftuxi-config-version.cmake files
|
||||
# needed to support users of find_package()
|
||||
# ------------------------------------------------------------------------------
|
||||
configure_package_config_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/ftxui-config.cmake.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/cmake/ftxui-config.cmake
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/ftxui/cmake
|
||||
PATH_VARS CMAKE_INSTALL_INCLUDEDIR
|
||||
)
|
||||
write_basic_package_version_file(
|
||||
${CMAKE_CURRENT_BINARY_DIR}/cmake/ftxui-config-version.cmake
|
||||
VERSION ${PACKAGE_VERSION}
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/cmake/ftxui-config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/cmake/ftxui-config-version.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ftxui
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Create and install pkg-config file for easy use of library in build systems
|
||||
# other than CMake:
|
||||
# ------------------------------------------------------------------------------
|
||||
configure_file(ftxui.pc.in ${CMAKE_CURRENT_BINARY_DIR}/ftxui.pc @ONLY)
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/ftxui.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
|
@@ -1,3 +1,7 @@
|
||||
if(NOT FTXUI_ENABLE_INSTALL)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
set(CPACK_GENERATOR "DEB;External;RPM;STGZ;TBZ2;TGZ;TXZ;TZ;TZST;ZIP")
|
||||
elseif (UNIX AND APPLE)
|
||||
|
@@ -1,16 +1,48 @@
|
||||
find_program(CLANG_TIDY_EXE NAMES "clang-tidy" DOC "Path to clang-tidy executable" )
|
||||
if(NOT CLANG_TIDY_EXE)
|
||||
message(STATUS "clang-tidy not found.")
|
||||
else()
|
||||
message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}")
|
||||
endif()
|
||||
|
||||
function(ftxui_set_options library)
|
||||
set_target_properties(${library} PROPERTIES PREFIX "ftxui-")
|
||||
message(STATUS "ftxui_set_options " ${library})
|
||||
set_target_properties(${library} PROPERTIES VERSION ${PROJECT_VERSION})
|
||||
if (NOT ${library} MATCHES "ftxui-*")
|
||||
set_target_properties(${library} PROPERTIES OUTPUT_NAME "ftxui-${library}")
|
||||
endif()
|
||||
|
||||
if(CLANG_TIDY_EXE AND FTXUI_CLANG_TIDY)
|
||||
set_target_properties(${library}
|
||||
PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_EXE};-warnings-as-errors=*"
|
||||
)
|
||||
|
||||
target_include_directories(${library}
|
||||
PUBLIC
|
||||
# By using "PUBLIC" as opposed to "SYSTEM INTERFACE", the compiler warning
|
||||
# are enforced on the headers. This is behind "FTXUI_CLANG_TIDY", so that it
|
||||
# applies only when developing FTXUI and on the CI. User's of the library
|
||||
# get only the SYSTEM INTERFACE instead.
|
||||
target_include_directories(${library}
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
)
|
||||
else()
|
||||
target_include_directories(${library} SYSTEM
|
||||
INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories(${library} SYSTEM
|
||||
INTERFACE
|
||||
$<INSTALL_INTERFACE:include>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
PRIVATE
|
||||
src
|
||||
)
|
||||
|
||||
# C++17 is used. We require fold expression at least.
|
||||
target_include_directories(${library}
|
||||
PRIVATE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
)
|
||||
|
||||
target_compile_features(${library} PUBLIC cxx_std_17)
|
||||
|
||||
# Force Microsoft Visual Studio to decode sources files in UTF-8. This applies
|
||||
@@ -22,8 +54,10 @@ function(ftxui_set_options library)
|
||||
# Add as many warning as possible:
|
||||
if (WIN32)
|
||||
if (MSVC)
|
||||
target_compile_options(${library} PRIVATE "/W3")
|
||||
target_compile_options(${library} PRIVATE "/WX")
|
||||
if(FTXUI_DEV_WARNINGS)
|
||||
target_compile_options(${library} PRIVATE "/W3")
|
||||
target_compile_options(${library} PRIVATE "/WX")
|
||||
endif()
|
||||
target_compile_options(${library} PRIVATE "/wd4244")
|
||||
target_compile_options(${library} PRIVATE "/wd4267")
|
||||
target_compile_options(${library} PRIVATE "/D_CRT_SECURE_NO_WARNINGS")
|
||||
@@ -31,13 +65,21 @@ function(ftxui_set_options library)
|
||||
# Force Win32 to UNICODE
|
||||
target_compile_definitions(${library} PRIVATE UNICODE _UNICODE)
|
||||
else()
|
||||
target_compile_options(${library} PRIVATE "-Wall")
|
||||
target_compile_options(${library} PRIVATE "-Wextra")
|
||||
target_compile_options(${library} PRIVATE "-pedantic")
|
||||
target_compile_options(${library} PRIVATE "-Werror")
|
||||
target_compile_options(${library} PRIVATE "-Wmissing-declarations")
|
||||
target_compile_options(${library} PRIVATE "-Wdeprecated")
|
||||
target_compile_options(${library} PRIVATE "-Wshadow")
|
||||
if(FTXUI_DEV_WARNINGS)
|
||||
target_compile_options(${library} PRIVATE "-Wall")
|
||||
target_compile_options(${library} PRIVATE "-Werror")
|
||||
target_compile_options(${library} PRIVATE "-Wextra")
|
||||
|
||||
target_compile_options(${library} PRIVATE "-Wcast-align")
|
||||
target_compile_options(${library} PRIVATE "-Wdeprecated")
|
||||
target_compile_options(${library} PRIVATE "-Wmissing-declarations")
|
||||
target_compile_options(${library} PRIVATE "-Wnon-virtual-dtor")
|
||||
target_compile_options(${library} PRIVATE "-Wnull-dereference")
|
||||
target_compile_options(${library} PRIVATE "-Woverloaded-virtual")
|
||||
target_compile_options(${library} PRIVATE "-Wpedantic")
|
||||
target_compile_options(${library} PRIVATE "-Wshadow")
|
||||
target_compile_options(${library} PRIVATE "-Wunused")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (FTXUI_MICROSOFT_TERMINAL_FALLBACK)
|
||||
@@ -47,9 +89,7 @@ function(ftxui_set_options library)
|
||||
endfunction()
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
#string(APPEND CMAKE_CXX_FLAGS " -s ASSERTIONS=1")
|
||||
string(APPEND CMAKE_CXX_FLAGS " -s USE_PTHREADS")
|
||||
string(APPEND CMAKE_EXE_LINKER_FLAGS " -s ASYNCIFY")
|
||||
string(APPEND CMAKE_EXE_LINKER_FLAGS " -s PROXY_TO_PTHREAD")
|
||||
endif()
|
||||
|
||||
|
@@ -1,56 +1,70 @@
|
||||
enable_testing()
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
|
||||
set(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(googletest
|
||||
GIT_REPOSITORY "https://github.com/google/googletest"
|
||||
GIT_TAG 23ef29555ef4789f555f1ba8c51b4c52975f0907
|
||||
)
|
||||
FetchContent_GetProperties(googletest)
|
||||
if(NOT googletest_POPULATED)
|
||||
FetchContent_Populate(googletest)
|
||||
add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
if (NOT FTXUI_BUILD_TESTS OR
|
||||
NOT ${CMAKE_VERSION} VERSION_GREATER "3.11.4")
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_executable(tests
|
||||
enable_testing()
|
||||
|
||||
include(cmake/ftxui_find_google_test.cmake)
|
||||
|
||||
add_executable(ftxui-tests
|
||||
src/ftxui/component/animation_test.cpp
|
||||
src/ftxui/component/button_test.cpp
|
||||
src/ftxui/component/collapsible_test.cpp
|
||||
src/ftxui/component/component_test.cpp
|
||||
src/ftxui/component/component_test.cpp
|
||||
src/ftxui/component/container_test.cpp
|
||||
src/ftxui/component/hoverable_test.cpp
|
||||
src/ftxui/component/input_test.cpp
|
||||
src/ftxui/component/menu_test.cpp
|
||||
src/ftxui/component/modal_test.cpp
|
||||
src/ftxui/component/radiobox_test.cpp
|
||||
src/ftxui/component/receiver_test.cpp
|
||||
src/ftxui/component/resizable_split_test.cpp
|
||||
src/ftxui/component/screen_interactive_test.cpp
|
||||
src/ftxui/component/slider_test.cpp
|
||||
src/ftxui/component/terminal_input_parser_test.cpp
|
||||
src/ftxui/component/toggle_test.cpp
|
||||
src/ftxui/dom/blink_test.cpp
|
||||
src/ftxui/dom/bold_test.cpp
|
||||
src/ftxui/dom/border_test.cpp
|
||||
src/ftxui/dom/canvas_test.cpp
|
||||
src/ftxui/dom/color_test.cpp
|
||||
src/ftxui/dom/dbox_test.cpp
|
||||
src/ftxui/dom/dim_test.cpp
|
||||
src/ftxui/dom/flexbox_helper_test.cpp
|
||||
src/ftxui/dom/flexbox_test.cpp
|
||||
src/ftxui/dom/gauge_test.cpp
|
||||
src/ftxui/dom/gridbox_test.cpp
|
||||
src/ftxui/dom/hbox_test.cpp
|
||||
src/ftxui/dom/linear_gradient_test.cpp
|
||||
src/ftxui/dom/scroll_indicator_test.cpp
|
||||
src/ftxui/dom/separator_test.cpp
|
||||
src/ftxui/dom/spinner_test.cpp
|
||||
src/ftxui/dom/table_test.cpp
|
||||
src/ftxui/dom/text_test.cpp
|
||||
src/ftxui/dom/underlined_test.cpp
|
||||
src/ftxui/dom/vbox_test.cpp
|
||||
src/ftxui/screen/color_test.cpp
|
||||
src/ftxui/screen/string_test.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(tests
|
||||
target_link_libraries(ftxui-tests
|
||||
PRIVATE component
|
||||
PRIVATE gtest
|
||||
PRIVATE gmock
|
||||
PRIVATE gtest_main
|
||||
PRIVATE GTest::gtest
|
||||
PRIVATE GTest::gtest_main
|
||||
)
|
||||
target_include_directories(tests
|
||||
target_include_directories(ftxui-tests
|
||||
PRIVATE src
|
||||
)
|
||||
target_compile_options(tests PRIVATE -fsanitize=address)
|
||||
target_link_libraries(tests PRIVATE -fsanitize=address)
|
||||
target_compile_features(ftxui-tests PRIVATE cxx_std_20)
|
||||
|
||||
if (NOT MSVC)
|
||||
include(cmake/ftxui_benchmark.cmake)
|
||||
if (FTXUI_MICROSOFT_TERMINAL_FALLBACK)
|
||||
target_compile_definitions(ftxui-tests
|
||||
PRIVATE "FTXUI_MICROSOFT_TERMINAL_FALLBACK")
|
||||
endif()
|
||||
|
||||
if (FTXUI_BUILD_TESTS_FUZZER)
|
||||
include(cmake/ftxui_fuzzer.cmake)
|
||||
endif()
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(ftxui-tests
|
||||
DISCOVERY_TIMEOUT 600
|
||||
)
|
||||
|
@@ -2,6 +2,6 @@ find_program(iwyu_path NAMES include-what-you-use iwyu)
|
||||
if(iwyu_path)
|
||||
set_property(TARGET ${lib}
|
||||
PROPERTY ${iwyu_path} -Xiwyu
|
||||
--mapping_file ${CMAKE_CURRENT_SOURCE_DIR}/iwyu.impl
|
||||
--mapping_file ${CMAKE_CURRENT_SOURCE_DIR}/iwyu.imp
|
||||
)
|
||||
endif()
|
||||
|
12
codecov.yml
Normal file
12
codecov.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
codecov:
|
||||
require_ci_to_pass: no
|
||||
notify:
|
||||
after_n_builds: 4
|
||||
wait_for_ci: yes
|
||||
|
||||
coverage:
|
||||
precision: 2
|
||||
round: down
|
||||
range: "50...100"
|
||||
|
||||
comment: false
|
@@ -1,22 +1,27 @@
|
||||
if(NOT FTXUI_BUILD_DOCS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(Doxygen)
|
||||
if (DOXYGEN_FOUND)
|
||||
# Generate example list for documentation
|
||||
set(EXAMPLE_LIST "${CMAKE_CURRENT_BINARY_DIR}/example_list.md")
|
||||
file(WRITE ${EXAMPLE_LIST} "# Examples")
|
||||
get_property(EXAMPLES GLOBAL PROPERTY FTXUI::EXAMPLES)
|
||||
foreach(EXAMPLE IN LISTS EXAMPLES)
|
||||
file(APPEND ${EXAMPLE_LIST} "\n@example examples/${EXAMPLE}.cpp")
|
||||
endforeach(EXAMPLE IN LISTS EXAMPLES)
|
||||
|
||||
configure_file(Doxyfile.in Doxyfile @ONLY)
|
||||
|
||||
# note the option ALL which allows to build the docs together with the application
|
||||
add_custom_target(doc
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Generating API documentation with Doxygen"
|
||||
VERBATIM
|
||||
)
|
||||
else (DOXYGEN_FOUND)
|
||||
if (NOT DOXYGEN_FOUND)
|
||||
message("Doxygen need to be installed to generate the doxygen documentation")
|
||||
endif (DOXYGEN_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Generate example list for documentation
|
||||
set(EXAMPLE_LIST "${CMAKE_CURRENT_BINARY_DIR}/example_list.md")
|
||||
file(WRITE ${EXAMPLE_LIST} "# Examples")
|
||||
get_property(EXAMPLES GLOBAL PROPERTY FTXUI::EXAMPLES)
|
||||
foreach(EXAMPLE IN LISTS EXAMPLES)
|
||||
file(APPEND ${EXAMPLE_LIST} "\n@example examples/${EXAMPLE}.cpp")
|
||||
endforeach(EXAMPLE IN LISTS EXAMPLES)
|
||||
|
||||
configure_file(Doxyfile.in Doxyfile @ONLY)
|
||||
|
||||
# note the option ALL which allows to build the docs together with the application
|
||||
add_custom_target(doc
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Generating API documentation with Doxygen"
|
||||
VERBATIM
|
||||
)
|
||||
|
@@ -178,11 +178,12 @@ div.headertitle {
|
||||
}
|
||||
|
||||
div.fragment {
|
||||
padding: 16px;
|
||||
background-color: #f3f3f3;
|
||||
border: 0 solid;
|
||||
transition: all 0.5s ease-in-out;
|
||||
border-radius:5px;
|
||||
border: 0 solid;
|
||||
border: none;
|
||||
padding:16px;
|
||||
transition: all 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
div.fragment:hover {
|
||||
@@ -192,8 +193,9 @@ div.fragment:hover {
|
||||
|
||||
div.line {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 85%;
|
||||
line-height: 1.45;
|
||||
font-size: 90%;
|
||||
font-variant-numeric: tabular-nums lining-nums;
|
||||
font-kerning: none;
|
||||
-webkit-transition-duration: 0;
|
||||
-moz-transition-duration: 0;
|
||||
-ms-transition-duration: 0;
|
||||
@@ -206,15 +208,6 @@ div.line.glow {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
pre.fragment {
|
||||
border: 0 solid #C4CFE5;
|
||||
padding: 16px;
|
||||
background-color: #f3f3f3;
|
||||
font-size: 85%;
|
||||
line-height: 1.45;
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
}
|
||||
|
||||
/* @group Code Colorization */
|
||||
span.keyword {
|
||||
color: #808000
|
||||
|
690
doc/mainpage.md
690
doc/mainpage.md
@@ -1,14 +1,19 @@
|
||||
\mainpage
|
||||
|
||||
# Introduction
|
||||
# Introduction {#introduction}
|
||||
|
||||
Welcome to the FTXUI documentation. Here, you will find the detail of every
|
||||
functions and classes.
|
||||
Welcome to the FTXUI documentation!
|
||||
|
||||
This is a brief tutorial. You are also encouraged to self-learn by reading the
|
||||
[examples](./examples.html).
|
||||
|
||||
@tableofcontents
|
||||
|
||||
**Short example**
|
||||
|
||||
To build a single frame, you need create an `ftxui::Element`, and display it on
|
||||
a `ftxui::Screen`.
|
||||
|
||||
**main.cpp**
|
||||
```cpp
|
||||
#include <ftxui/dom/elements.hpp>
|
||||
@@ -37,19 +42,22 @@ int main(void) {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
**output**
|
||||
```bash
|
||||
┌────┐┌─────────────────────────────────────────────────────────────────┐┌─────┐
|
||||
│left││middle ││right│
|
||||
└────┘└─────────────────────────────────────────────────────────────────┘└─────┘
|
||||
┌────┐┌────────────────────────────────────┐┌─────┐
|
||||
│left││middle ││right│
|
||||
└────┘└────────────────────────────────────┘└─────┘
|
||||
```
|
||||
|
||||
# Build
|
||||
# Build {#build}
|
||||
|
||||
## Using CMake
|
||||
## Using CMake {#build-cmake}
|
||||
|
||||
This is an example configuration for your **CMakeLists.txt**
|
||||
|
||||
CMakeLists.txt
|
||||
~~~cmake
|
||||
```cmake
|
||||
cmake_minimum_required (VERSION 3.11)
|
||||
|
||||
# --- Fetch FTXUI --------------------------------------------------------------
|
||||
@@ -58,7 +66,7 @@ include(FetchContent)
|
||||
set(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)
|
||||
FetchContent_Declare(ftxui
|
||||
GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui
|
||||
# Specify a GIT_TAG here.
|
||||
# Important: Specify a GIT_TAG XXXXX here.
|
||||
)
|
||||
|
||||
FetchContent_GetProperties(ftxui)
|
||||
@@ -83,38 +91,43 @@ target_link_libraries(ftxui-starter
|
||||
PRIVATE ftxui::component # Not needed for this example.
|
||||
)
|
||||
|
||||
~~~
|
||||
```
|
||||
|
||||
Build
|
||||
~~~
|
||||
Subsequently, you build the project in the standard fashion as follows:
|
||||
```bash
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
make
|
||||
./main
|
||||
~~~
|
||||
```
|
||||
|
||||
# List of modules.
|
||||
# List of modules. {#modules}
|
||||
|
||||
The project is split into 3 modules:
|
||||
The project is comprised of 3 modules:
|
||||
|
||||
1. **ftxui/screen** defines a `ftxui::Screen`, this is a grid of `ftxui::Pixel`.
|
||||
1. **ftxui/screen** defines a `ftxui::Screen`, a grid of `ftxui::Pixel`.
|
||||
|
||||
2. **ftxui/dom** is the main module. It defines a hierarchical set of
|
||||
`ftxui::Element`. An element draws something on the `ftxui::Screen`. It is
|
||||
responsive to the size of its container.
|
||||
|
||||
3. **ftxui/component** The part is only needed if you need to respond to the
|
||||
User input. It defines a set of `ftxui::Component`. The use can navigates
|
||||
3. **ftxui/component** The module is required if your program needs to respond
|
||||
to user input. It defines a set of `ftxui::Component`. These components can
|
||||
be utilized to navigate the program by using the arrow keys and interacting
|
||||
with widgets such as the checkbox. You can also make you own components.
|
||||
The use can navigates
|
||||
using the arrow keys and interact with widgets like checkbox/inputbox/... You
|
||||
can make you own components.
|
||||
|
||||
# screen
|
||||
# screen {#module-screen}
|
||||
|
||||
It defines a `ftxui::Screen`. This is a grid of `ftxui::Pixel`. A Pixel
|
||||
represent a Unicode character and its associated style (bold, colors, etc...).
|
||||
The screen can be printed as a string using `ftxui::Screen::ToString()`.
|
||||
This is the visual element of the program. It defines a `ftxui::Screen`, which
|
||||
is a grid of `ftxui::Pixel`. A Pixel represents a Unicode character and its
|
||||
associated style (bold, colors, etc.). The screen can be printed as a string
|
||||
using `ftxui::Screen::ToString()`. The following example highlights this
|
||||
process:
|
||||
|
||||
~~~cpp
|
||||
```cpp
|
||||
#include <ftxui/screen/screen.hpp>
|
||||
#include <iostream>
|
||||
|
||||
@@ -130,75 +143,154 @@ The screen can be printed as a string using `ftxui::Screen::ToString()`.
|
||||
std::cout << screen.ToString();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
~~~
|
||||
```
|
||||
|
||||
# dom
|
||||
# dom {#module-dom}
|
||||
|
||||
This module defines a hierarchical set of Element. An element manages layout and
|
||||
can be responsive to the terminal dimensions.
|
||||
This module defines a hierarchical set of `ftxui::Element`. An element manages
|
||||
the layout and can be responsive to the terminal dimension changes. Note the
|
||||
following example where this module is used to create a simple layout with a
|
||||
number of operators:
|
||||
|
||||
**Example:**
|
||||
```cpp
|
||||
// Define the document
|
||||
Element document = vbox({
|
||||
text("The window") | bold | color(Color::Blue),
|
||||
gauge(0.5)
|
||||
text("The footer")
|
||||
});
|
||||
text("The window") | bold | color(Color::Blue),
|
||||
gauge(0.5)
|
||||
text("The footer")
|
||||
});
|
||||
|
||||
// Add a border.
|
||||
// Add a border, by calling the `ftxui::border` decorator function.
|
||||
document = border(document);
|
||||
|
||||
// Add another border, using the pipe operator.
|
||||
document = document | border.
|
||||
|
||||
// Add another border, using the |= operator.
|
||||
document |= border
|
||||
|
||||
```
|
||||
|
||||
**List of elements**
|
||||
|
||||
You only need one header: ftxui/dom/elements.hpp
|
||||
The list of all elements are included and can be accessed by including the
|
||||
corresponding header file:
|
||||
```cpp
|
||||
#include <ftxui/dom/elements.hpp>
|
||||
```
|
||||
|
||||
\include ftxui/dom/elements.hpp
|
||||
|
||||
## text
|
||||
## text ## {#dom-text}
|
||||
|
||||
The most simple widget. It displays a text.
|
||||
~~~cpp
|
||||
```cpp
|
||||
text("I am a piece of text");
|
||||
~~~
|
||||
~~~bash
|
||||
```
|
||||
```bash
|
||||
I am a piece of text.
|
||||
~~~
|
||||
```
|
||||
|
||||
## border
|
||||
## vtext {#dom-vtext}
|
||||
|
||||
Add a border around an element
|
||||
~~~cpp
|
||||
Identical to `ftxui::text`, but displayed vertically.
|
||||
|
||||
Code:
|
||||
```cpp
|
||||
vtext("HELLO");
|
||||
```
|
||||
|
||||
Terminal output:
|
||||
```bash
|
||||
H
|
||||
E
|
||||
L
|
||||
L
|
||||
O
|
||||
```
|
||||
|
||||
## paragraph {#dom-paragraph}
|
||||
|
||||
Similar to `ftxui::text`, but the individual word are wrapped along multiple
|
||||
lines, depending on the width of its container.
|
||||
|
||||
Sample Code:
|
||||
```cpp
|
||||
paragraph("A very long text")
|
||||
```
|
||||
|
||||

|
||||
|
||||
For a more detailed example refer to [detailed example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2paragraph_8cpp-example.html). Paragraph also includes a number of other variants as shown below:
|
||||
```cpp
|
||||
Element paragraph(std::string text);
|
||||
Element paragraphAlignLeft(std::string text);
|
||||
Element paragraphAlignRight(std::string text);
|
||||
Element paragraphAlignCenter(std::string text);
|
||||
Element paragraphAlignJustify(std::string text);
|
||||
```
|
||||
|
||||
|
||||
## border {#dom-border}
|
||||
|
||||
Adds a border around an element.
|
||||
|
||||
Code:
|
||||
```cpp
|
||||
border(text("The element"))
|
||||
~~~
|
||||
```
|
||||
|
||||
~~~bash
|
||||
Terminal output:
|
||||
```bash
|
||||
┌───────────┐
|
||||
│The element│
|
||||
└───────────┘
|
||||
~~~
|
||||
```
|
||||
|
||||
## window
|
||||
You can achieve the same behavior by using the pipe operator.
|
||||
|
||||
A `ftxui::window` is a `ftxui::border`, but with some text on top of the border.
|
||||
Add a border around an element
|
||||
~~~cpp
|
||||
Code:
|
||||
```cpp
|
||||
text("The element") | border
|
||||
```
|
||||
|
||||
Border also comes in a variety of styles as shown below:
|
||||
```cpp
|
||||
Element border(Element);
|
||||
Element borderLight(Element);
|
||||
Element borderHeavy(Element);
|
||||
Element borderDouble(Element);
|
||||
Element borderRounded(Element);
|
||||
Element borderEmpty(Element);
|
||||
Decorator borderStyled(BorderStyle);
|
||||
Decorator borderWith(Pixel);
|
||||
```
|
||||
|
||||
|
||||
## window ## {#dom-window}
|
||||
|
||||
A `ftxui::window` is a `ftxui::border`, but with an additional header. To add a
|
||||
window around an element, wrap it and specify a string as the header.
|
||||
Code:
|
||||
```cpp
|
||||
window("The window", text("The element"))
|
||||
~~~
|
||||
```
|
||||
|
||||
~~~bash
|
||||
Terminal output:
|
||||
```bash
|
||||
┌The window─┐
|
||||
│The element│
|
||||
└───────────┘
|
||||
~~~
|
||||
```
|
||||
|
||||
## separator
|
||||
## separator {#dom-separator}
|
||||
|
||||
Display a vertical or horizontal line to visually split the content of a
|
||||
Displays a vertical/horizontal line to visually split the content of a
|
||||
container in two.
|
||||
|
||||
~~~cpp
|
||||
Code:
|
||||
```cpp
|
||||
border(
|
||||
hbox({
|
||||
text("Left"),
|
||||
@@ -206,44 +298,89 @@ border(
|
||||
text("Right")
|
||||
})
|
||||
)
|
||||
~~~
|
||||
```
|
||||
|
||||
~~~bash
|
||||
Terminal output:
|
||||
```bash
|
||||
┌────┬─────┐
|
||||
│left│right│
|
||||
└────┴─────┘
|
||||
~~~
|
||||
```
|
||||
|
||||
## gauge
|
||||
|
||||
A gauge. It can be used to represent a progress bar.
|
||||
~~~cpp
|
||||
Separators come in a variety of flavors as shown below:
|
||||
```cpp
|
||||
Element separator(void);
|
||||
Element separatorLight();
|
||||
Element separatorHeavy();
|
||||
Element separatorDouble();
|
||||
Element separatorEmpty();
|
||||
Element separatorStyled(BorderStyle);
|
||||
Element separator(Pixel);
|
||||
Element separatorCharacter(std::string);
|
||||
Element separatorHSelector(float left,
|
||||
float right,
|
||||
Color background,
|
||||
Color foreground);
|
||||
Element separatorVSelector(float up,
|
||||
float down,
|
||||
Color background,
|
||||
Color foreground);
|
||||
```
|
||||
|
||||
## gauge {#dom-gauge}
|
||||
|
||||
It constitutes a gauge. It can be used to represent a progress bar.
|
||||
|
||||
Code:
|
||||
```cpp
|
||||
border(gauge(0.5))
|
||||
~~~
|
||||
```
|
||||
|
||||
~~~bash
|
||||
Teminal output:
|
||||
```bash
|
||||
┌────────────────────────────────────────────────────────────────────────────┐
|
||||
│██████████████████████████████████████ │
|
||||
└────────────────────────────────────────────────────────────────────────────┘
|
||||
~~~
|
||||
```
|
||||
|
||||
## graph
|
||||
Gauges can be displayed in many orientations as shown below:
|
||||
```cpp
|
||||
Element gauge(float ratio);
|
||||
Element gaugeLeft(float ratio);
|
||||
Element gaugeRight(float ratio);
|
||||
Element gaugeUp(float ratio);
|
||||
Element gaugeDown(float ratio);
|
||||
Element gaugeDirection(float ratio, GaugeDirection);
|
||||
```
|
||||
|
||||
## graph {#dom-graph}
|
||||
|
||||
@htmlonly
|
||||
<script id="asciicast-223726" src="https://asciinema.org/a/223726.js" async></script>
|
||||
@endhtmlonly
|
||||
|
||||
## Colors
|
||||
A terminal console can usually display colored text and colored background.
|
||||
See:
|
||||
```cpp
|
||||
Element graph(GraphFunction);
|
||||
```
|
||||
|
||||
~~~cpp
|
||||
## Colors {#dom-colors}
|
||||
|
||||
Most terminal consoles can display colored text and colored backgrounds. FTXUI
|
||||
supports every color palette:
|
||||
```cpp
|
||||
Decorator color(Color);
|
||||
Decorator bgcolor(Color);
|
||||
~~~
|
||||
```
|
||||
|
||||
### Palette16
|
||||
|
||||
On most terminal the following colors are supported:
|
||||
Color [gallery](https://arthursonzogni.github.io/FTXUI/examples_2dom_2color_gallery_8cpp-example.html):
|
||||

|
||||
|
||||
### Palette16 #{#dom-colors-palette-16}
|
||||
|
||||
On most terminals the following colors are supported:
|
||||
- Default
|
||||
|
||||
- Black
|
||||
@@ -270,14 +407,14 @@ On most terminal the following colors are supported:
|
||||
- Yellow
|
||||
- YellowLight
|
||||
|
||||
Example:
|
||||
Example use of the above colors using the pipe operator:
|
||||
```cpp
|
||||
text("Blue foreground") | color(Color::Blue);
|
||||
text("Blue background") | bgcolor(Color::Blue);
|
||||
text("Black on white") | color(Color::Black) | bgcolor(Color::White);
|
||||
```
|
||||
|
||||
### Palette256
|
||||
### Palette256 #{#dom-colors-palette-256}
|
||||
|
||||
On terminal supporting 256 colors.
|
||||
@htmlonly
|
||||
@@ -288,9 +425,13 @@ On terminal supporting 256 colors.
|
||||
text("HotPink") | color(Color::HotPink);
|
||||
```
|
||||
|
||||
### TrueColor
|
||||
### TrueColor #{#dom-colors-true-color}
|
||||
|
||||
On terminal supporting trueColor, you can directly chose the 24bit RGB color:
|
||||
On terminal supporting trueColor, you can directly use the 24bit RGB color
|
||||
space:
|
||||
|
||||
Use the constructors below to specify the **RGB** or **HSV** values for your
|
||||
color:
|
||||
|
||||
There are two constructors:
|
||||
```cpp
|
||||
@@ -303,100 +444,190 @@ ftxui::Color::HSV(uint8_t hue, uint8_t saturation, uint8_t value);
|
||||
<script id="asciicast-xwzzghmqcqzIuyLwCpQFEqbEu" src="https://asciinema.org/a/xwzzghmqcqzIuyLwCpQFEqbEu.js" async></script>
|
||||
@endhtmlonly
|
||||
|
||||
## Style
|
||||
A terminal console can usually display colored text and colored background.
|
||||
The text can also have different effects: bold, dim, underlined, inverted,
|
||||
blink.
|
||||
## LinearGradient #{#dom-linear-gradient}
|
||||
|
||||
~~~cpp
|
||||
FTXUI supports linear gradient. Either on the foreground or the background.
|
||||
|
||||
```cpp
|
||||
Decorator color(const LinearGradient&);
|
||||
Decorator bgcolor(const LinearGradient&);
|
||||
```
|
||||
|
||||
A `ftxui::LinearGradient` is defined by an angle in degree, and a list of color
|
||||
stops.
|
||||
```cpp
|
||||
auto gradient = LinearGradient()
|
||||
.Angle(45)
|
||||
.AddStop(0.0, Color::Red)
|
||||
.AddStop(0.5, Color::Green)
|
||||
.AddStop(1.0, Color::Blue);
|
||||
```
|
||||
|
||||
You can also use simplified constructors:
|
||||
```cpp
|
||||
LinearGradient(Color::Red, Color::Blue);
|
||||
```
|
||||
```cpp
|
||||
LinearGradient(45, Color::Red, Color::Blue);
|
||||
```
|
||||
|
||||
See [demo](https://arthursonzogni.github.io/FTXUI/examples/?file=component/linear_gradient_gallery).
|
||||
|
||||
|
||||
## Style {#dom-style}
|
||||
In addition to colored text and colored backgrounds. Many terminals support text
|
||||
effects such as: `bold`, `dim`, `underlined`, `inverted`, `blink`.
|
||||
|
||||
```cpp
|
||||
Element bold(Element);
|
||||
Element dim(Element);
|
||||
Element inverted(Element);
|
||||
Element underlined(Element);
|
||||
Element underlinedDouble(Element);
|
||||
Element strikethrough(Element);
|
||||
Element blink(Element);
|
||||
Decorator color(Color);
|
||||
Decorator bgcolor(Color);
|
||||
~~~
|
||||
Decorator colorgrad(LinearGradient);
|
||||
Decorator bgcolorgrad(LinearGradient);
|
||||
```
|
||||
|
||||
Example:
|
||||
~~~cpp
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2style_gallery_8cpp-example.html)
|
||||
|
||||

|
||||
|
||||
To use these effects, simply wrap your elements with your desired effect:
|
||||
```cpp
|
||||
underlined(bold(text("This text is bold and underlined")))
|
||||
~~~
|
||||
```
|
||||
|
||||
Tips: The pipe operator can be used to chain Decorator:
|
||||
~~~cpp
|
||||
text("This text is bold")) | bold | underlined
|
||||
~~~
|
||||
Alternatively, use the pipe operator to chain it on your element:
|
||||
```cpp
|
||||
text("This text is bold") | bold | underlined
|
||||
```
|
||||
|
||||
## Layout
|
||||
## Layout {#dom-layout}
|
||||
|
||||
These layout are similar to the HTML flexbox:
|
||||
* vbox (Vertical-box)
|
||||
* hbox (Horizontal-box)
|
||||
* dbox (Z-axis-box)
|
||||
They are used to compose all the elements together. Each
|
||||
children are put side by side. If the container is flexible, the extra space
|
||||
available will be shared among the remaining flexible children.
|
||||
Enables elements to be arranged in the following ways:
|
||||
- **Horizontally** with `ftxui::hbox`
|
||||
- **Vertically** with `ftxui::vbox`
|
||||
- **Inside a grid** with `ftxui::gridbox`
|
||||
- **Wrapped along one direction** using the `ftxui::flexbox`.
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2vbox_hbox_8cpp-example.html) using `ftxui::hbox`, `ftxui::vbox` and `ftxui::filler`.
|
||||
|
||||
`flex(element)` can be used to make a non-flexible element flexible. `filler()`
|
||||
is a flexible empty element. You can use it align children on one side of the
|
||||
container.
|
||||

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

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

|
||||
|
||||
Checkout this
|
||||
[example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2hflow_8cpp-example.html)
|
||||
and the associated
|
||||
[demo](https://arthursonzogni.github.io/FTXUI/examples/?file=component/flexbox).
|
||||
|
||||
Element can also become flexible using the the `ftxui::flex` decorator.
|
||||
|
||||
Code:
|
||||
```cpp
|
||||
hbox({
|
||||
text("left") | border ,
|
||||
text("middle") | border | flex,
|
||||
text("right") | border,
|
||||
});
|
||||
~~~
|
||||
~~~bash
|
||||
┌────┐┌─────────────────────────────────────────────────────────────────┐┌─────┐
|
||||
│left││middle ││right│
|
||||
└────┘└─────────────────────────────────────────────────────────────────┘└─────┘
|
||||
~~~
|
||||
```
|
||||
Terminal output:
|
||||
```bash
|
||||
┌────┐┌─────────────────────────────────────────────────────┐┌─────┐
|
||||
│left││middle ││right│
|
||||
└────┘└─────────────────────────────────────────────────────┘└─────┘
|
||||
```
|
||||
|
||||
~~~cpp
|
||||
Code:
|
||||
```cpp
|
||||
hbox({
|
||||
text("left") | border ,
|
||||
text("middle") | border | flex,
|
||||
text("right") | border | flex,
|
||||
});
|
||||
~~~
|
||||
~~~bash
|
||||
┌────┐┌───────────────────────────────────┐┌───────────────────────────────────┐
|
||||
│left││middle ││right │
|
||||
└────┘└───────────────────────────────────┘└───────────────────────────────────┘
|
||||
~~~
|
||||
```
|
||||
|
||||
Terminal output:
|
||||
```bash
|
||||
┌────┐┌───────────────────────────────┐┌───────────────────────────────┐
|
||||
│left││middle ││right │
|
||||
└────┘└───────────────────────────────┘└───────────────────────────────┘
|
||||
```
|
||||
|
||||
# component
|
||||
## Table {#dom-table}
|
||||
|
||||
The `ftxui/component` directory defines the logic to get produce
|
||||
interactive component responding to user's events (keyboard, mouse, etc...)
|
||||
Enables easy formatting of data into a neat table like visual form.
|
||||
|
||||
A `ftxui::ScreenInteractive` defines a main loop to render a component.
|
||||
[Code example](https://arthursonzogni.github.io/FTXUI/examples_2dom_2table_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
A `ftxui::Component` is a shared pointer to a `ftxui::ComponentBase`. The later
|
||||
defines
|
||||
## Canvas {#dom-canvas}
|
||||
|
||||
See the API [<ftxui/dom/canvas.hpp>](./canvas_8hpp_source.html)
|
||||
|
||||
```cpp
|
||||
auto c = Canvas(100, 100);
|
||||
c.DrawPointLine(10, 10, 80, 10, Color::Red);
|
||||
auto element = canvas(c);
|
||||
```
|
||||
|
||||
Drawing can be performed on a `ftxui::Canvas`, using braille, block, or simple
|
||||
characters:
|
||||
|
||||
Simple [example](https://github.com/ArthurSonzogni/FTXUI/blob/master/examples/dom/canvas.cpp):
|
||||
|
||||

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

|
||||
# component {#module-component}
|
||||
|
||||
The `ftxui::component` module defines the logic that produces interactive
|
||||
components that respond to user events (keyboard, mouse, etc.).
|
||||
|
||||
A `ftxui::ScreenInteractive` defines a main loop that renders a component.
|
||||
|
||||
A `ftxui::Component` is a shared pointer to a `ftxui::ComponentBase`. The latter defines:
|
||||
- `ftxui::ComponentBase::Render()`: How to render the interface.
|
||||
- `ftxui::ComponentBase::OnEvent()`: How to react to events.
|
||||
- `ftxui::ComponentBase::Add()`: Give a parent/child relation ship in between
|
||||
two component. This defines a tree a components, which help properly define
|
||||
how keyboard navigation works.
|
||||
- `ftxui::ComponentBase::Add()`: Construct a parent/child relationship
|
||||
between two components. The tree of component is used to define how to
|
||||
navigate using the keyboard.
|
||||
|
||||
Predefined components are available in `ftxui/dom/component.hpp`:
|
||||
`ftxui::Element` are used to render a single frame.
|
||||
|
||||
`ftxui::Component` are used to render dynamic user interface, producing multiple
|
||||
frame, and updating its state on events.
|
||||
|
||||
[Gallery](https://arthursonzogni.github.io/FTXUI/examples_2component_2gallery_8cpp-example.html) of multiple components. ([demo](https://arthursonzogni.github.io/FTXUI/examples/?file=component/gallery))
|
||||
|
||||

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

|
||||
|
||||
Produced by: `ftxui::Input()` from "ftxui/component/component.hpp"
|
||||
|
||||
@@ -404,7 +635,14 @@ Produced by: `ftxui::Input()` from "ftxui/component/component.hpp"
|
||||
<script id="asciicast-223719" src="https://asciinema.org/a/223719.js" async></script>
|
||||
@endhtmlonly
|
||||
|
||||
## Menu
|
||||
## Menu {#component-menu}
|
||||
|
||||
Defines a menu object. It contains a list of entries, one of them is selected.
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2menu_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
|
||||
Produced by: `ftxui::Menu()` from "ftxui/component/component.hpp"
|
||||
|
||||
@@ -412,7 +650,13 @@ Produced by: `ftxui::Menu()` from "ftxui/component/component.hpp"
|
||||
<script id="asciicast-223720" src="https://asciinema.org/a/223720.js" async></script>
|
||||
@endhtmlonly
|
||||
|
||||
## Toggle.
|
||||
## Toggle {#component-toggle}
|
||||
|
||||
A special kind of menu. The entries are displayed horizontally.
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2toggle_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
Produced by: `ftxui::Toggle()` from "ftxui/component/component.hpp"
|
||||
|
||||
@@ -420,7 +664,14 @@ Produced by: `ftxui::Toggle()` from "ftxui/component/component.hpp"
|
||||
<script id="asciicast-223722" src="https://asciinema.org/a/223722.js" async></script>
|
||||
@endhtmlonly
|
||||
|
||||
## CheckBox
|
||||
## CheckBox {#component-checkbox}
|
||||
|
||||
This component defines a checkbox. It is a single entry that can be turned
|
||||
on/off.
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2checkbox_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
Produced by: `ftxui::Checkbox()` from "ftxui/component/component.hpp"
|
||||
|
||||
@@ -428,7 +679,13 @@ Produced by: `ftxui::Checkbox()` from "ftxui/component/component.hpp"
|
||||
<script id="asciicast-223724" src="https://asciinema.org/a/223724.js" async></script>
|
||||
@endhtmlonly
|
||||
|
||||
## RadioBox
|
||||
## RadioBox {#component-radiobox}
|
||||
|
||||
A radiobutton component. This is a list of entries, where one can be turned on.
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2radiobox_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
Produced by: `ftxui::Radiobox()` from "ftxui/component/component.hpp"
|
||||
|
||||
@@ -436,65 +693,182 @@ Produced by: `ftxui::Radiobox()` from "ftxui/component/component.hpp"
|
||||
<script id="asciicast-223725" src="https://asciinema.org/a/223725.js" async></script>
|
||||
@endhtmlonly
|
||||
|
||||
## Renderer
|
||||
## Dropdown {#component-dropdown}
|
||||
|
||||
Produced by: `ftxui::Renderer()` from \ref "ftxui/component/component.hpp". This
|
||||
A drop down menu is a component that when checked display a list of element for
|
||||
the user to select one.
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2dropdown_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
Produced by: `ftxui::Dropdown()` from "ftxui/component/component.hpp"
|
||||
|
||||
## Slider {#component-slider}
|
||||
|
||||
Represents a slider object that consists of a range with binned intermediate
|
||||
intervals. It can be created by `ftxui::Slider()`.
|
||||
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2slider_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
Produced by: `ftxui::Slider()` from "ftxui/component/component.hpp"
|
||||
|
||||
## Renderer {#component-renderer}
|
||||
|
||||
Produced by: `ftxui::Renderer()` from \ref ftxui/component/component.hpp. This
|
||||
component decorate another one by using a different function to render an
|
||||
interface.
|
||||
|
||||
## CatchEvent
|
||||
Example:
|
||||
```cpp
|
||||
auto inner = [...]
|
||||
|
||||
Produced by: `ftxui::CatchEvent()` from \ref "ftxui/component/component.hpp".
|
||||
This component decorate another one and catch the events before the underlying
|
||||
component.
|
||||
auto renderer = Renderer(inner, [&] {
|
||||
return inner->Render() | border
|
||||
});
|
||||
```
|
||||
|
||||
## Container::Horizontal
|
||||
`ftxui::Renderer` also supports the component decorator pattern:
|
||||
```cpp
|
||||
auto component = [...]
|
||||
component = component
|
||||
| Renderer([](Element e) { return e | border))
|
||||
| Renderer(bold)
|
||||
```
|
||||
|
||||
As a short hand, you can also compose a component with an element decorator:
|
||||
```cpp
|
||||
auto component = [...]
|
||||
component = component | border | bold;
|
||||
```
|
||||
|
||||
## CatchEvent {#component-catchevent}
|
||||
|
||||
Produced by: `ftxui::CatchEvent()` from \ref ftxui/component/component.hpp.
|
||||
This component decorate others, catching events before the underlying component.
|
||||
|
||||
Examples:
|
||||
```cpp
|
||||
auto screen = ScreenInteractive::TerminalOutput();
|
||||
auto renderer = Renderer([] {
|
||||
return text("My interface");
|
||||
});
|
||||
auto component = CatchEvent(renderer, [&](Event event) {
|
||||
if (event == Event::Character('q')) {
|
||||
screen.ExitLoopClosure()();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
screen.Loop(component);
|
||||
```
|
||||
|
||||
The `ftxui::CatchEvent` can also be used as a decorator:
|
||||
```cpp
|
||||
component = component
|
||||
| CatchEvent(handler_1)
|
||||
| CatchEvent(handler_2)
|
||||
| CatchEvent(handler_3)
|
||||
;
|
||||
```
|
||||
|
||||
## Collapsible {#component-collapsible}
|
||||
|
||||
Useful for visual elements whose visibility can be toggle on/off by the user.
|
||||
Essentially, this the combination of the `ftxui::Checkbox()` and
|
||||
`ftxui::Maybe()` components.
|
||||
|
||||
```cpp
|
||||
auto collabsible = Collapsible("Show more", inner_element);
|
||||
```
|
||||
|
||||
## Maybe {#component-maybe}
|
||||
|
||||
Produced by: `ftxui::Maybe()` from \ref ftxui/component/component.hpp.
|
||||
This component can be utilized to show/hide any other component via a boolean or
|
||||
a predicate.
|
||||
|
||||
Example with a boolean:
|
||||
```cpp
|
||||
bool show = true;
|
||||
auto component = Renderer([]{ return "Hello World!"; });
|
||||
auto maybe_component = Maybe(component, &show)
|
||||
```
|
||||
|
||||
Example with a predicate:
|
||||
```cpp
|
||||
auto component = Renderer([]{ return "Hello World!"; });
|
||||
auto maybe_component = Maybe(component, [&] { return time > 10; })
|
||||
```
|
||||
|
||||
As usual, `ftxui::Maybe` can also be used as a decorator:
|
||||
```cpp
|
||||
component = component
|
||||
| Maybe(&a_boolean)
|
||||
| Maybe([&] { return time > 10; })
|
||||
;
|
||||
```
|
||||
|
||||
## Container {#component-container}
|
||||
|
||||
### Horizontal {#component-horizontal}
|
||||
|
||||
Produced by: `ftxui::Container::Horizontal()` from
|
||||
"ftxui/component/component.hpp". It displays a list of components horizontally
|
||||
and handle keyboard/mouse navigation.
|
||||
|
||||
## Container::Vertial
|
||||
### Vertical {#component-vertical}
|
||||
|
||||
Produced by: `ftxui::Container::Vertical()` from
|
||||
"ftxui/component/component.hpp". It displays a list of components vertically
|
||||
and handles keyboard/mouse navigation.
|
||||
|
||||
## Container::Tab
|
||||
### Tab {#component-tab}
|
||||
|
||||
Produced by: `ftxui::Container::Tab()` from
|
||||
"ftxui/component/component.hpp". It take a list of component and display only
|
||||
one of them. This is useful for implementing a tab bar.
|
||||
|
||||
## ResizableSplit::{Left, Right, Top, Bottom}
|
||||
[Vertical](https://arthursonzogni.github.io/FTXUI/examples_2component_2tab_vertical_8cpp-example.html):
|
||||
|
||||

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

|
||||
|
||||
|
||||
## ResizableSplit {#component-resizable-split}
|
||||
|
||||
It defines a horizontal or vertical separation between two children components.
|
||||
The position of the split is variable and controllable using the mouse.
|
||||
There are four possible splits:
|
||||
- `ftxui::ResizableSplitLeft()`
|
||||
- `ftxui::ResizableSplitRight()`
|
||||
- `ftxui::ResizableSplitTop()`
|
||||
- `ftxui::ResizableSplitBottom()`
|
||||
from "ftxui/component/component.hpp"
|
||||
|
||||
It defines an horizontal or vertical separation in between two children
|
||||
component. The position of the split is variable and controllable using the
|
||||
mouse.
|
||||
[Example](https://arthursonzogni.github.io/FTXUI/examples_2component_2resizable_split_8cpp-example.html):
|
||||
|
||||

|
||||
|
||||
@htmlonly
|
||||
<script id="asciicast-tprMH2EdkUoMb7D2YxgMGgpzx" src="https://asciinema.org/a/tprMH2EdkUoMb7D2YxgMGgpzx.js" async></script>
|
||||
@endhtmlonly
|
||||
|
||||
## Force a frame redraw.
|
||||
## Force a frame redraw. {#component-force-redraw}
|
||||
|
||||
Whenever a new group of events have been processed: keyboard, mouse, window
|
||||
resize, etc..., the `ftxui::ScreenInteractive::Loop()` is responsible for
|
||||
drawing a new frame.
|
||||
|
||||
You might want to react to arbitrary events that are unknown to FTXUI. This can
|
||||
be achieve by posting events via `ftxui::ScreenInteractive::PostEvent`, via a
|
||||
thread. You can post the event`ftxui::Event::Custom`.
|
||||
Typically, `ftxui::ScreenInteractive::Loop()` is responsible for drawing a new
|
||||
frame whenever a new group of events (e.g keyboard, mouse, window resize, etc.)
|
||||
has been processed. However, you might want to react to arbitrary events that
|
||||
are unknown to FTXUI. To accomplish this, you must post events using
|
||||
`ftxui::ScreenInteractive::PostEvent` (**this is thread safe**) via a thread.
|
||||
You will have to post the event `ftxui::Event::Custom`.
|
||||
|
||||
Example:
|
||||
```cpp
|
||||
screen->PostEvent(Event::Custom);
|
||||
```
|
||||
|
||||
`ftxui::ScreenInteractive::PostEvent` is thread safe.
|
||||
|
@@ -1,18 +1,30 @@
|
||||
if(NOT FTXUI_BUILD_EXAMPLES)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(EXAMPLES_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
function(example name)
|
||||
add_executable(ftxui_example_${name} ${name}.cpp)
|
||||
target_link_libraries(ftxui_example_${name} PUBLIC ${DIRECTORY_LIB})
|
||||
file(RELATIVE_PATH dir ${EXAMPLES_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set_property(GLOBAL APPEND PROPERTY FTXUI::EXAMPLES ${dir}/${name})
|
||||
target_compile_features(ftxui_example_${name} PRIVATE cxx_std_17)
|
||||
endfunction(example)
|
||||
|
||||
add_subdirectory(component)
|
||||
add_subdirectory(dom)
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
# 32MB should be enough to run all the examples, in debug mode.
|
||||
target_link_options(component PUBLIC "SHELL: -s TOTAL_MEMORY=33554432")
|
||||
target_link_options(component PUBLIC "SHELL: -s ASSERTIONS=1")
|
||||
#string(APPEND CMAKE_EXE_LINKER_FLAGS " -s ALLOW_MEMORY_GROWTH=1")
|
||||
#target_link_options(component PUBLIC "SHELL: -s ALLOW_MEMORY_GROWTH=1")
|
||||
|
||||
get_property(EXAMPLES GLOBAL PROPERTY FTXUI::EXAMPLES)
|
||||
foreach(file
|
||||
"index.html"
|
||||
"sw.js"
|
||||
"run_webassembly.py")
|
||||
configure_file(${file} ${file})
|
||||
endforeach(file)
|
||||
|
@@ -1,25 +1,34 @@
|
||||
set(DIRECTORY_LIB component)
|
||||
|
||||
example(button)
|
||||
example(button_animated)
|
||||
example(button_in_frame)
|
||||
example(button_style)
|
||||
example(canvas_animated)
|
||||
example(checkbox)
|
||||
example(checkbox_in_frame)
|
||||
example(collapsible)
|
||||
example(composition)
|
||||
example(custom_loop)
|
||||
example(dropdown)
|
||||
example(flexbox_gallery)
|
||||
example(focus)
|
||||
example(focus_cursor)
|
||||
example(gallery)
|
||||
example(homescreen)
|
||||
example(input)
|
||||
example(linear_gradient_gallery)
|
||||
example(maybe)
|
||||
example(menu)
|
||||
example(menu2)
|
||||
example(menu_entries)
|
||||
example(menu_entries_animated)
|
||||
example(menu_in_frame)
|
||||
example(menu_multiple)
|
||||
example(menu_style)
|
||||
example(menu_underline_animated_gallery)
|
||||
example(modal_dialog)
|
||||
example(modal_dialog_custom)
|
||||
example(nested_screen)
|
||||
example(print_key_press)
|
||||
example(radiobox)
|
||||
@@ -27,6 +36,7 @@ example(radiobox_in_frame)
|
||||
example(renderer)
|
||||
example(resizable_split)
|
||||
example(slider)
|
||||
example(slider_direction)
|
||||
example(slider_rgb)
|
||||
example(tab_horizontal)
|
||||
example(tab_vertical)
|
||||
|
@@ -1,12 +1,11 @@
|
||||
#include <memory> // for shared_ptr, __shared_ptr_access
|
||||
#include <string> // for operator+, to_wstring
|
||||
#include <string> // for operator+, to_string
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Button, Horizontal, Renderer
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/component_options.hpp" // for ButtonOption
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for separator, gauge, Element, operator|, vbox, border
|
||||
#include "ftxui/dom/elements.hpp" // for separator, gauge, text, Element, operator|, vbox, border
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
@@ -14,13 +13,9 @@ int main(int argc, const char* argv[]) {
|
||||
int value = 50;
|
||||
|
||||
// The tree of components. This defines how to navigate using the keyboard.
|
||||
auto button_option = ButtonOption();
|
||||
button_option.border = false;
|
||||
auto buttons = Container::Horizontal({
|
||||
Button(
|
||||
"[Decrease]", [&] { value--; }, &button_option),
|
||||
Button(
|
||||
"[Increase]", [&] { value++; }, &button_option),
|
||||
Button("Decrease", [&] { value--; }),
|
||||
Button("Increase", [&] { value++; }),
|
||||
});
|
||||
|
||||
// Modify the way to render them on screen:
|
||||
|
46
examples/component/button_animated.cpp
Normal file
46
examples/component/button_animated.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <memory> // for shared_ptr, __shared_ptr_access
|
||||
#include <string> // for operator+, to_string
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Button, Horizontal, Renderer
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/component_options.hpp" // for ButtonOption
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for gauge, separator, text, vbox, operator|, Element, border
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::Green, Color::Red
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int value = 50;
|
||||
|
||||
// The tree of components. This defines how to navigate using the keyboard.
|
||||
auto buttons = Container::Horizontal({
|
||||
Button(
|
||||
"Decrease", [&] { value--; }, ButtonOption::Animated(Color::Red)),
|
||||
Button(
|
||||
"Reset", [&] { value = 50; }, ButtonOption::Animated(Color::Green)),
|
||||
Button(
|
||||
"Increase", [&] { value++; }, ButtonOption::Animated(Color::Blue)),
|
||||
});
|
||||
|
||||
// Modify the way to render them on screen:
|
||||
auto component = Renderer(buttons, [&] {
|
||||
return vbox({
|
||||
vbox({
|
||||
text("value = " + std::to_string(value)),
|
||||
separator(),
|
||||
gauge(value * 0.01f),
|
||||
}) | border,
|
||||
buttons->Render(),
|
||||
});
|
||||
});
|
||||
|
||||
auto screen = ScreenInteractive::FitComponent();
|
||||
screen.Loop(component);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
49
examples/component/button_in_frame.cpp
Normal file
49
examples/component/button_in_frame.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <memory> // for allocator, __shared_ptr_access, shared_ptr
|
||||
#include <string> // for to_string, operator+
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Button, Renderer, Vertical
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/component_options.hpp" // for ButtonOption
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for operator|, text, Element, hbox, separator, size, vbox, border, frame, vscroll_indicator, HEIGHT, LESS_THAN
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Default, Color::GrayDark, Color::White
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int counter = 0;
|
||||
auto on_click = [&] { counter++; };
|
||||
|
||||
auto button_style = ButtonOption::Animated(Color::Default, Color::GrayDark,
|
||||
Color::Default, Color::White);
|
||||
|
||||
auto container = Container::Vertical({});
|
||||
for (int i = 0; i < 30; ++i) {
|
||||
auto button =
|
||||
Button("Button " + std::to_string(i), on_click, &button_style);
|
||||
container->Add(button);
|
||||
}
|
||||
|
||||
auto renderer = Renderer(container, [&] {
|
||||
return vbox({
|
||||
hbox({
|
||||
text("Counter:"),
|
||||
text(std::to_string(counter)),
|
||||
}),
|
||||
separator(),
|
||||
container->Render() | vscroll_indicator | frame |
|
||||
size(HEIGHT, LESS_THAN, 20),
|
||||
}) |
|
||||
border;
|
||||
});
|
||||
|
||||
auto screen = ScreenInteractive::FitComponent();
|
||||
screen.Loop(renderer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copyright 2022 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
61
examples/component/button_style.cpp
Normal file
61
examples/component/button_style.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include <string> // for operator+, to_string
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Button, Vertical, Renderer, Horizontal, operator|
|
||||
#include "ftxui/component/component_base.hpp" // for Component
|
||||
#include "ftxui/component/component_options.hpp" // for ButtonOption
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for Element, separator, text, border
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::Green, Color::Red
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int value = 0;
|
||||
auto action = [&] { value++; };
|
||||
auto action_renderer =
|
||||
Renderer([&] { return text("count = " + std::to_string(value)); });
|
||||
|
||||
auto buttons =
|
||||
Container::Vertical({
|
||||
action_renderer,
|
||||
Renderer([] { return separator(); }),
|
||||
Container::Horizontal({
|
||||
Container::Vertical({
|
||||
Button("Ascii 1", action, ButtonOption::Ascii()),
|
||||
Button("Ascii 2", action, ButtonOption::Ascii()),
|
||||
Button("Ascii 3", action, ButtonOption::Ascii()),
|
||||
}),
|
||||
Renderer([] { return separator(); }),
|
||||
Container::Vertical({
|
||||
Button("Simple 1", action, ButtonOption::Simple()),
|
||||
Button("Simple 2", action, ButtonOption::Simple()),
|
||||
Button("Simple 3", action, ButtonOption::Simple()),
|
||||
}),
|
||||
Renderer([] { return separator(); }),
|
||||
Container::Vertical({
|
||||
Button("Animated 1", action, ButtonOption::Animated()),
|
||||
Button("Animated 2", action, ButtonOption::Animated()),
|
||||
Button("Animated 3", action, ButtonOption::Animated()),
|
||||
}),
|
||||
Renderer([] { return separator(); }),
|
||||
Container::Vertical({
|
||||
Button("Animated 4", action,
|
||||
ButtonOption::Animated(Color::Red)),
|
||||
Button("Animated 5", action,
|
||||
ButtonOption::Animated(Color::Green)),
|
||||
Button("Animated 6", action,
|
||||
ButtonOption::Animated(Color::Blue)),
|
||||
}),
|
||||
}),
|
||||
}) |
|
||||
border;
|
||||
|
||||
auto screen = ScreenInteractive::FitComponent();
|
||||
screen.Loop(buttons);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -126,9 +126,9 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
std::vector<int> ys(100);
|
||||
for (int x = 0; x < 100; x++) {
|
||||
float dx = x - mouse_x;
|
||||
float dy = 50;
|
||||
ys[x] = dy + 20 * cos(dx * 0.14) + 10 * sin(dx * 0.42);
|
||||
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]);
|
||||
@@ -141,10 +141,10 @@ int main(int argc, const char* argv[]) {
|
||||
c.DrawText(0, 0, "A symmetrical graph filled");
|
||||
std::vector<int> ys(100);
|
||||
for (int x = 0; x < 100; x++) {
|
||||
ys[x] = 30 + //
|
||||
10 * cos(x * 0.2 - mouse_x * 0.05) + //
|
||||
5 * sin(x * 0.4) + //
|
||||
5 * sin(x * 0.3 - mouse_y * 0.05); //
|
||||
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);
|
||||
|
@@ -1,26 +1,22 @@
|
||||
#include <memory> // for shared_ptr, __shared_ptr_access, allocator_traits<>::value_type
|
||||
#include <array> // for array
|
||||
#include <memory> // for shared_ptr, __shared_ptr_access
|
||||
#include <string> // for operator+, to_string
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Checkbox, Renderer, Vertical
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for operator|, Element, size, border, frame, HEIGHT, LESS_THAN
|
||||
#include "ftxui/dom/elements.hpp" // for operator|, Element, size, border, frame, vscroll_indicator, HEIGHT, LESS_THAN
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
struct CheckboxState {
|
||||
bool checked;
|
||||
};
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
std::vector<CheckboxState> states(30);
|
||||
std::array<bool, 30> states;
|
||||
|
||||
auto container = Container::Vertical({});
|
||||
for (int i = 0; i < 30; ++i) {
|
||||
states[i].checked = false;
|
||||
container->Add(
|
||||
Checkbox("Checkbox" + std::to_string(i), &states[i].checked));
|
||||
states[i] = false;
|
||||
container->Add(Checkbox("Checkbox" + std::to_string(i), &states[i]));
|
||||
}
|
||||
|
||||
auto renderer = Renderer(container, [&] {
|
||||
|
@@ -4,7 +4,6 @@
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Button, Horizontal, Renderer
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/component_options.hpp" // for ButtonOption
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for text, separator, Element, operator|, vbox, border
|
||||
|
||||
@@ -13,24 +12,17 @@ using namespace ftxui;
|
||||
// An example of how to compose multiple components into one and maintain their
|
||||
// interactiveness.
|
||||
int main(int argc, const char* argv[]) {
|
||||
auto button_option = ButtonOption();
|
||||
button_option.border = false;
|
||||
|
||||
auto left_count = 0;
|
||||
auto right_count = 0;
|
||||
|
||||
auto left_buttons = Container::Horizontal({
|
||||
Button(
|
||||
"[Decrease]", [&] { left_count--; }, &button_option),
|
||||
Button(
|
||||
"[Increase]", [&] { left_count++; }, &button_option),
|
||||
Button("Decrease", [&] { left_count--; }),
|
||||
Button("Increase", [&] { left_count++; }),
|
||||
});
|
||||
|
||||
auto right_buttons = Container::Horizontal({
|
||||
Button(
|
||||
"[Decrease]", [&] { right_count--; }, &button_option),
|
||||
Button(
|
||||
"[Increase]", [&] { right_count++; }, &button_option),
|
||||
Button("Decrease", [&] { right_count--; }),
|
||||
Button("Increase", [&] { right_count++; }),
|
||||
});
|
||||
|
||||
// Renderer decorates its child with a new rendering function. The way the
|
||||
|
55
examples/component/custom_loop.cpp
Normal file
55
examples/component/custom_loop.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <stdlib.h> // for EXIT_SUCCESS
|
||||
#include <chrono> // for milliseconds
|
||||
#include <ftxui/component/event.hpp> // for Event
|
||||
#include <ftxui/component/mouse.hpp> // for ftxui
|
||||
#include <ftxui/dom/elements.hpp> // for text, separator, Element, operator|, vbox, border
|
||||
#include <memory> // for allocator, shared_ptr
|
||||
#include <string> // for operator+, to_string
|
||||
#include <thread> // for sleep_for
|
||||
|
||||
#include "ftxui/component/component.hpp" // for CatchEvent, Renderer, operator|=
|
||||
#include "ftxui/component/loop.hpp" // for Loop
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
auto screen = ScreenInteractive::FitComponent();
|
||||
|
||||
// Create a component counting the number of frames drawn and event handled.
|
||||
int custom_loop_count = 0;
|
||||
int frame_count = 0;
|
||||
int event_count = 0;
|
||||
auto component = Renderer([&] {
|
||||
frame_count++;
|
||||
return vbox({
|
||||
text("This demonstrates using a custom ftxui::Loop. It "),
|
||||
text("runs at 100 iterations per seconds. The FTXUI events "),
|
||||
text("are all processed once per iteration and a new frame "),
|
||||
text("is rendered as needed"),
|
||||
separator(),
|
||||
text("ftxui event count: " + std::to_string(event_count)),
|
||||
text("ftxui frame count: " + std::to_string(frame_count)),
|
||||
text("Custom loop count: " + std::to_string(custom_loop_count)),
|
||||
}) |
|
||||
border;
|
||||
});
|
||||
|
||||
component |= CatchEvent([&](Event) -> bool {
|
||||
event_count++;
|
||||
return false;
|
||||
});
|
||||
|
||||
Loop loop(&screen, component);
|
||||
|
||||
while (!loop.HasQuitted()) {
|
||||
custom_loop_count++;
|
||||
loop.RunOnce();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -32,8 +32,8 @@ Element make_grid() {
|
||||
};
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
float focus_x = 0.0f;
|
||||
float focus_y = 0.0f;
|
||||
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);
|
||||
|
38
examples/component/focus_cursor.cpp
Normal file
38
examples/component/focus_cursor.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include <ftxui/component/captured_mouse.hpp> // for ftxui
|
||||
#include <string> // for allocator, operator+, char_traits, string
|
||||
|
||||
#include "ftxui/component/component.hpp" // for Renderer, Vertical
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive, Component
|
||||
#include "ftxui/dom/elements.hpp" // for text, Decorator, focus, focusCursorBar, focusCursorBarBlinking, focusCursorBlock, focusCursorBlockBlinking, focusCursorUnderline, focusCursorUnderlineBlinking, hbox, Element
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
Component Instance(std::string label, Decorator focusCursor) {
|
||||
return Renderer([=](bool focused) {
|
||||
if (focused) {
|
||||
return hbox({
|
||||
text("> " + label + " "),
|
||||
focusCursor(text(" ")),
|
||||
});
|
||||
}
|
||||
return text(" " + label + " ");
|
||||
});
|
||||
};
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
auto screen = ScreenInteractive::Fullscreen();
|
||||
screen.Loop(Container::Vertical({
|
||||
Instance("focus", focus),
|
||||
Instance("focusCursorBlock", focusCursorBlock),
|
||||
Instance("focusCursorBlockBlinking", focusCursorBlockBlinking),
|
||||
Instance("focusCursorBar", focusCursorBar),
|
||||
Instance("focusCursorBarBlinking", focusCursorBarBlinking),
|
||||
Instance("focusCursorUnderline", focusCursorUnderline),
|
||||
Instance("focusCursorUnderlineBlinking", focusCursorUnderlineBlinking),
|
||||
}));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -1,23 +1,26 @@
|
||||
#include <stddef.h> // for size_t
|
||||
#include <array> // for array
|
||||
#include <atomic> // for atomic
|
||||
#include <chrono> // for operator""s, chrono_literals
|
||||
#include <cmath> // for sin
|
||||
#include <functional> // for ref, reference_wrapper, function
|
||||
#include <memory> // for allocator, shared_ptr, __shared_ptr_access
|
||||
#include <string> // for string, basic_string, operator+, to_string, char_traits
|
||||
#include <string> // for string, basic_string, char_traits, operator+, to_string
|
||||
#include <thread> // for sleep_for, thread
|
||||
#include <utility> // for move
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Checkbox, Renderer, Horizontal, Vertical, Input, Menu, Radiobox, ResizableSplitLeft, Tab, Toggle
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/component_options.hpp" // for InputOption
|
||||
#include "../dom/color_info_sorted_2d.ipp" // for ColorInfoSorted2D
|
||||
#include "ftxui/component/component.hpp" // for Checkbox, Renderer, Horizontal, Vertical, Input, Menu, Radiobox, ResizableSplitLeft, Tab
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase, Component
|
||||
#include "ftxui/component/component_options.hpp" // for MenuOption, InputOption
|
||||
#include "ftxui/component/event.hpp" // for Event, Event::Custom
|
||||
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for text, operator|, color, bgcolor, filler, Element, size, vbox, flex, hbox, separator, graph, EQUAL, paragraph, hcenter, WIDTH, bold, window, border, vscroll_indicator, Elements, HEIGHT, hflow, frame, flex_grow, flexbox, gauge, paragraphAlignCenter, paragraphAlignJustify, paragraphAlignLeft, paragraphAlignRight, dim, spinner, Decorator, LESS_THAN, center, yflex, GREATER_THAN
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::BlueLight, Color::RedLight, Color::Black, 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/screen/terminal.hpp" // for Size, Dimensions
|
||||
#include "ftxui/dom/elements.hpp" // for text, color, operator|, bgcolor, filler, Element, vbox, size, hbox, separator, flex, window, graph, EQUAL, paragraph, WIDTH, hcenter, Elements, bold, vscroll_indicator, HEIGHT, flexbox, hflow, border, frame, flex_grow, gauge, paragraphAlignCenter, paragraphAlignJustify, paragraphAlignLeft, paragraphAlignRight, dim, spinner, LESS_THAN, center, yframe, GREATER_THAN
|
||||
#include "ftxui/dom/flexbox_config.hpp" // for FlexboxConfig
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::BlueLight, Color::RedLight, Color::Black, Color::Blue, Color::Cyan, Color::CyanLight, Color::GrayDark, Color::GrayLight, Color::Green, Color::GreenLight, Color::Magenta, Color::MagentaLight, Color::Red, Color::White, Color::Yellow, Color::YellowLight, Color::Default, Color::Palette256, ftxui
|
||||
#include "ftxui/screen/color_info.hpp" // for ColorInfo
|
||||
#include "ftxui/screen/terminal.hpp" // for Size, Dimensions
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
@@ -27,7 +30,6 @@ int main(int argc, const char* argv[]) {
|
||||
// ---------------------------------------------------------------------------
|
||||
// HTOP
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
int shift = 0;
|
||||
|
||||
auto my_graph = [&shift](int width, int height) {
|
||||
@@ -95,7 +97,7 @@ int main(int argc, const char* argv[]) {
|
||||
separator(),
|
||||
ram | flex,
|
||||
}) |
|
||||
flex | border;
|
||||
flex;
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -255,7 +257,7 @@ int main(int argc, const char* argv[]) {
|
||||
}) | size(HEIGHT, LESS_THAN, 8),
|
||||
hflow(render_command()) | flex_grow,
|
||||
}) |
|
||||
flex_grow | border;
|
||||
flex_grow;
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -267,61 +269,116 @@ int main(int argc, const char* argv[]) {
|
||||
entries.push_back(spinner(i, shift / 2) | bold |
|
||||
size(WIDTH, GREATER_THAN, 2) | border);
|
||||
}
|
||||
return hflow(std::move(entries)) | border;
|
||||
return hflow(std::move(entries));
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Colors
|
||||
// ---------------------------------------------------------------------------
|
||||
auto color_tab_renderer = Renderer([] {
|
||||
return hbox({
|
||||
vbox({
|
||||
color(Color::Default, text("Default")),
|
||||
color(Color::Black, text("Black")),
|
||||
color(Color::GrayDark, text("GrayDark")),
|
||||
color(Color::GrayLight, text("GrayLight")),
|
||||
color(Color::White, text("White")),
|
||||
color(Color::Blue, text("Blue")),
|
||||
color(Color::BlueLight, text("BlueLight")),
|
||||
color(Color::Cyan, text("Cyan")),
|
||||
color(Color::CyanLight, text("CyanLight")),
|
||||
color(Color::Green, text("Green")),
|
||||
color(Color::GreenLight, text("GreenLight")),
|
||||
color(Color::Magenta, text("Magenta")),
|
||||
color(Color::MagentaLight, text("MagentaLight")),
|
||||
color(Color::Red, text("Red")),
|
||||
color(Color::RedLight, text("RedLight")),
|
||||
color(Color::Yellow, text("Yellow")),
|
||||
color(Color::YellowLight, text("YellowLight")),
|
||||
}),
|
||||
vbox({
|
||||
bgcolor(Color::Default, text("Default")),
|
||||
bgcolor(Color::Black, text("Black")),
|
||||
bgcolor(Color::GrayDark, text("GrayDark")),
|
||||
bgcolor(Color::GrayLight, text("GrayLight")),
|
||||
bgcolor(Color::White, text("White")),
|
||||
bgcolor(Color::Blue, text("Blue")),
|
||||
bgcolor(Color::BlueLight, text("BlueLight")),
|
||||
bgcolor(Color::Cyan, text("Cyan")),
|
||||
bgcolor(Color::CyanLight, text("CyanLight")),
|
||||
bgcolor(Color::Green, text("Green")),
|
||||
bgcolor(Color::GreenLight, text("GreenLight")),
|
||||
bgcolor(Color::Magenta, text("Magenta")),
|
||||
bgcolor(Color::MagentaLight, text("MagentaLight")),
|
||||
bgcolor(Color::Red, text("Red")),
|
||||
bgcolor(Color::RedLight, text("RedLight")),
|
||||
bgcolor(Color::Yellow, text("Yellow")),
|
||||
bgcolor(Color::YellowLight, text("YellowLight")),
|
||||
}),
|
||||
}) |
|
||||
hcenter | border;
|
||||
auto basic_color_display =
|
||||
vbox({
|
||||
text("16 color palette:"),
|
||||
separator(),
|
||||
hbox({
|
||||
vbox({
|
||||
color(Color::Default, text("Default")),
|
||||
color(Color::Black, text("Black")),
|
||||
color(Color::GrayDark, text("GrayDark")),
|
||||
color(Color::GrayLight, text("GrayLight")),
|
||||
color(Color::White, text("White")),
|
||||
color(Color::Blue, text("Blue")),
|
||||
color(Color::BlueLight, text("BlueLight")),
|
||||
color(Color::Cyan, text("Cyan")),
|
||||
color(Color::CyanLight, text("CyanLight")),
|
||||
color(Color::Green, text("Green")),
|
||||
color(Color::GreenLight, text("GreenLight")),
|
||||
color(Color::Magenta, text("Magenta")),
|
||||
color(Color::MagentaLight, text("MagentaLight")),
|
||||
color(Color::Red, text("Red")),
|
||||
color(Color::RedLight, text("RedLight")),
|
||||
color(Color::Yellow, text("Yellow")),
|
||||
color(Color::YellowLight, text("YellowLight")),
|
||||
}),
|
||||
vbox({
|
||||
bgcolor(Color::Default, text("Default")),
|
||||
bgcolor(Color::Black, text("Black")),
|
||||
bgcolor(Color::GrayDark, text("GrayDark")),
|
||||
bgcolor(Color::GrayLight, text("GrayLight")),
|
||||
bgcolor(Color::White, text("White")),
|
||||
bgcolor(Color::Blue, text("Blue")),
|
||||
bgcolor(Color::BlueLight, text("BlueLight")),
|
||||
bgcolor(Color::Cyan, text("Cyan")),
|
||||
bgcolor(Color::CyanLight, text("CyanLight")),
|
||||
bgcolor(Color::Green, text("Green")),
|
||||
bgcolor(Color::GreenLight, text("GreenLight")),
|
||||
bgcolor(Color::Magenta, text("Magenta")),
|
||||
bgcolor(Color::MagentaLight, text("MagentaLight")),
|
||||
bgcolor(Color::Red, text("Red")),
|
||||
bgcolor(Color::RedLight, text("RedLight")),
|
||||
bgcolor(Color::Yellow, text("Yellow")),
|
||||
bgcolor(Color::YellowLight, text("YellowLight")),
|
||||
}),
|
||||
}),
|
||||
}) |
|
||||
border;
|
||||
|
||||
auto palette_256_color_display = text("256 colors palette:");
|
||||
{
|
||||
std::vector<std::vector<ColorInfo>> info_columns = ColorInfoSorted2D();
|
||||
Elements columns;
|
||||
for (auto& column : info_columns) {
|
||||
Elements column_elements;
|
||||
for (auto& it : column) {
|
||||
column_elements.push_back(
|
||||
text(" ") | bgcolor(Color(Color::Palette256(it.index_256))));
|
||||
}
|
||||
columns.push_back(hbox(std::move(column_elements)));
|
||||
}
|
||||
palette_256_color_display = vbox({
|
||||
palette_256_color_display,
|
||||
separator(),
|
||||
vbox(columns),
|
||||
}) |
|
||||
border;
|
||||
}
|
||||
|
||||
// True color display.
|
||||
auto true_color_display = text("TrueColors: 24bits:");
|
||||
{
|
||||
int saturation = 255;
|
||||
Elements array;
|
||||
for (int value = 0; value < 255; value += 16) {
|
||||
Elements line;
|
||||
for (int hue = 0; hue < 255; hue += 6) {
|
||||
line.push_back(text("▀") //
|
||||
| color(Color::HSV(hue, saturation, value)) //
|
||||
| bgcolor(Color::HSV(hue, saturation, value + 8)));
|
||||
}
|
||||
array.push_back(hbox(std::move(line)));
|
||||
}
|
||||
true_color_display = vbox({
|
||||
true_color_display,
|
||||
separator(),
|
||||
vbox(std::move(array)),
|
||||
}) |
|
||||
border;
|
||||
}
|
||||
|
||||
return flexbox(
|
||||
{
|
||||
basic_color_display,
|
||||
palette_256_color_display,
|
||||
true_color_display,
|
||||
},
|
||||
FlexboxConfig().SetGap(1, 1));
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Gauges
|
||||
// ---------------------------------------------------------------------------
|
||||
auto render_gauge = [&shift](int delta) {
|
||||
float progress = (shift + delta) % 1000 / 1000.f;
|
||||
float progress = (shift + delta) % 500 / 500.f;
|
||||
return hbox({
|
||||
text(std::to_string(int(progress * 100)) + "% ") |
|
||||
size(WIDTH, EQUAL, 5),
|
||||
@@ -331,25 +388,24 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
auto gauge_component = Renderer([render_gauge] {
|
||||
return vbox({
|
||||
render_gauge(0) | color(Color::Black),
|
||||
render_gauge(100) | color(Color::GrayDark),
|
||||
render_gauge(50) | color(Color::GrayLight),
|
||||
render_gauge(6894) | color(Color::White),
|
||||
separator(),
|
||||
render_gauge(6841) | color(Color::Blue),
|
||||
render_gauge(9813) | color(Color::BlueLight),
|
||||
render_gauge(98765) | color(Color::Cyan),
|
||||
render_gauge(98) | color(Color::CyanLight),
|
||||
render_gauge(9846) | color(Color::Green),
|
||||
render_gauge(1122) | color(Color::GreenLight),
|
||||
render_gauge(84) | color(Color::Magenta),
|
||||
render_gauge(645) | color(Color::MagentaLight),
|
||||
render_gauge(568) | color(Color::Red),
|
||||
render_gauge(2222) | color(Color::RedLight),
|
||||
render_gauge(220) | color(Color::Yellow),
|
||||
render_gauge(348) | color(Color::YellowLight),
|
||||
}) |
|
||||
border;
|
||||
render_gauge(0) | color(Color::Black),
|
||||
render_gauge(100) | color(Color::GrayDark),
|
||||
render_gauge(50) | color(Color::GrayLight),
|
||||
render_gauge(6894) | color(Color::White),
|
||||
separator(),
|
||||
render_gauge(6841) | color(Color::Blue),
|
||||
render_gauge(9813) | color(Color::BlueLight),
|
||||
render_gauge(98765) | color(Color::Cyan),
|
||||
render_gauge(98) | color(Color::CyanLight),
|
||||
render_gauge(9846) | color(Color::Green),
|
||||
render_gauge(1122) | color(Color::GreenLight),
|
||||
render_gauge(84) | color(Color::Magenta),
|
||||
render_gauge(645) | color(Color::MagentaLight),
|
||||
render_gauge(568) | color(Color::Red),
|
||||
render_gauge(2222) | color(Color::RedLight),
|
||||
render_gauge(220) | color(Color::Yellow),
|
||||
render_gauge(348) | color(Color::YellowLight),
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -363,48 +419,36 @@ int main(int argc, const char* argv[]) {
|
||||
};
|
||||
|
||||
auto paragraph_renderer_left = Renderer([&] {
|
||||
auto title_style = bold | bgcolor(Color::Blue) | color(Color::Black);
|
||||
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({
|
||||
// [ Left ]
|
||||
text("Align left:") | title_style,
|
||||
paragraphAlignLeft(str),
|
||||
// [ Center ]
|
||||
text("Align center:") | title_style,
|
||||
paragraphAlignCenter(str),
|
||||
// [ Right ]
|
||||
text("Align right:") | title_style,
|
||||
paragraphAlignRight(str),
|
||||
// [ Justify]
|
||||
text("Align justify:") | title_style,
|
||||
paragraphAlignJustify(str),
|
||||
// [ Side by side ]
|
||||
text("Side by side:") | title_style,
|
||||
hbox({
|
||||
paragraph(str),
|
||||
separator() | color(Color::Blue),
|
||||
paragraph(str),
|
||||
}),
|
||||
// [ Misc ]
|
||||
text("Elements with different size:") | title_style,
|
||||
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),
|
||||
}),
|
||||
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;
|
||||
});
|
||||
@@ -420,7 +464,7 @@ int main(int argc, const char* argv[]) {
|
||||
¶graph_renderer_split_position);
|
||||
auto paragraph_renderer_group_renderer =
|
||||
Renderer(paragraph_renderer_group,
|
||||
[&] { return paragraph_renderer_group->Render() | border; });
|
||||
[&] { return paragraph_renderer_group->Render(); });
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Tabs
|
||||
@@ -430,7 +474,8 @@ int main(int argc, const char* argv[]) {
|
||||
std::vector<std::string> tab_entries = {
|
||||
"htop", "color", "spinner", "gauge", "compiler", "paragraph",
|
||||
};
|
||||
auto tab_selection = Toggle(&tab_entries, &tab_index);
|
||||
auto tab_selection =
|
||||
Menu(&tab_entries, &tab_index, MenuOption::HorizontalAnimated());
|
||||
auto tab_content = Container::Tab(
|
||||
{
|
||||
htop,
|
||||
@@ -450,18 +495,23 @@ int main(int argc, const char* argv[]) {
|
||||
auto main_renderer = Renderer(main_container, [&] {
|
||||
return vbox({
|
||||
text("FTXUI Demo") | bold | hcenter,
|
||||
tab_selection->Render() | hcenter,
|
||||
tab_selection->Render(),
|
||||
tab_content->Render() | flex,
|
||||
});
|
||||
});
|
||||
|
||||
bool refresh_ui_continue = true;
|
||||
std::atomic<bool> refresh_ui_continue = true;
|
||||
std::thread refresh_ui([&] {
|
||||
while (refresh_ui_continue) {
|
||||
using namespace std::chrono_literals;
|
||||
std::this_thread::sleep_for(0.05s);
|
||||
shift++;
|
||||
screen.PostEvent(Event::Custom);
|
||||
// The |shift| variable belong to the main thread. `screen.Post(task)`
|
||||
// will execute the update on the thread where |screen| lives (e.g. the
|
||||
// main thread). Using `screen.Post(task)` is threadsafe.
|
||||
screen.Post([&] { shift++; });
|
||||
// After updating the state, request a new frame to be drawn. This is done
|
||||
// by simulating a new "custom" event to be handled.
|
||||
screen.Post(Event::Custom);
|
||||
}
|
||||
});
|
||||
|
||||
|
56
examples/component/linear_gradient_gallery.cpp
Normal file
56
examples/component/linear_gradient_gallery.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include <ftxui/component/component_base.hpp> // for ComponentBase, Component
|
||||
#include <ftxui/dom/elements.hpp> // for operator|, Element, flex, bgcolor, text, vbox, center
|
||||
#include <ftxui/dom/linear_gradient.hpp> // for LinearGradient
|
||||
#include <ftxui/screen/color.hpp> // for Color, Color::Blue, Color::Red
|
||||
#include <memory> // for __shared_ptr_access, shared_ptr
|
||||
#include <string> // for allocator, operator+, char_traits, string, to_string
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Slider, Renderer, Vertical
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
auto screen = ScreenInteractive::Fullscreen();
|
||||
|
||||
int angle = 180.f;
|
||||
float start = 0.f;
|
||||
float end = 1.f;
|
||||
|
||||
std::string slider_angle_text;
|
||||
std::string slider_start_text;
|
||||
std::string slider_end_text;
|
||||
|
||||
auto slider_angle = Slider(&slider_angle_text, &angle, 0, 360);
|
||||
auto slider_start = Slider(&slider_start_text, &start, 0.f, 1.f);
|
||||
auto slider_end = Slider(&slider_end_text, &end, 0.f, 1.f);
|
||||
|
||||
auto layout = Container::Vertical({
|
||||
slider_angle,
|
||||
slider_start,
|
||||
slider_end,
|
||||
});
|
||||
|
||||
auto renderer = Renderer(layout, [&] {
|
||||
slider_angle_text = "angle = " + std::to_string(angle) + "°";
|
||||
slider_start_text = "start = " + std::to_string(int(start * 100)) + "%";
|
||||
slider_end_text = "end = " + std::to_string(int(end * 100)) + "%";
|
||||
|
||||
auto background = text("Gradient") | center |
|
||||
bgcolor(LinearGradient()
|
||||
.Angle(angle)
|
||||
.Stop(Color::Blue, start)
|
||||
.Stop(Color::Red, end));
|
||||
return vbox({
|
||||
background | flex,
|
||||
layout->Render(),
|
||||
}) |
|
||||
flex;
|
||||
});
|
||||
|
||||
screen.Loop(renderer);
|
||||
}
|
||||
|
||||
// Copyright 2023 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -1,17 +1,14 @@
|
||||
#include <memory> // for shared_ptr, __shared_ptr_access
|
||||
#include <string> // for string, basic_string, allocator
|
||||
#include <string> // for string, allocator, basic_string
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Checkbox, Maybe, Radiobox, 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 Element, operator|, border
|
||||
#include "ftxui/component/component.hpp" // for operator|, Maybe, Checkbox, Radiobox, Renderer, Vertical
|
||||
#include "ftxui/component/component_base.hpp" // for Component
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for Element, border, color, operator|, text
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Red
|
||||
|
||||
using namespace ftxui;
|
||||
Component Border(Component child) {
|
||||
return Renderer(child, [child] { return child->Render() | border; });
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
std::vector<std::string> entries = {
|
||||
@@ -21,20 +18,19 @@ int main(int argc, const char* argv[]) {
|
||||
};
|
||||
int menu_1_selected = 0;
|
||||
int menu_2_selected = 0;
|
||||
auto menu_1 = Radiobox(&entries, &menu_1_selected);
|
||||
auto menu_2 = Radiobox(&entries, &menu_2_selected);
|
||||
|
||||
menu_1 = Border(menu_1);
|
||||
menu_2 = Border(menu_2);
|
||||
|
||||
bool menu_1_show = false;
|
||||
bool menu_2_show = false;
|
||||
|
||||
auto layout = Container::Vertical({
|
||||
Checkbox("Show menu_1", &menu_1_show),
|
||||
Maybe(menu_1, &menu_1_show),
|
||||
Radiobox(&entries, &menu_1_selected) | border | Maybe(&menu_1_show),
|
||||
Checkbox("Show menu_2", &menu_2_show),
|
||||
Maybe(menu_2, &menu_2_show),
|
||||
Radiobox(&entries, &menu_2_selected) | border | Maybe(&menu_2_show),
|
||||
|
||||
Renderer([] {
|
||||
return text("You found the secret combinaison!") | color(Color::Red);
|
||||
}) | Maybe([&] { return menu_1_selected == 1 && menu_2_selected == 2; }),
|
||||
});
|
||||
|
||||
auto screen = ScreenInteractive::TerminalOutput();
|
||||
|
@@ -1,25 +1,31 @@
|
||||
#include <functional> // for function
|
||||
#include <iostream> // for basic_ostream::operator<<, operator<<, endl, basic_ostream, basic_ostream<>::__ostream_type, cout, ostream
|
||||
#include <memory> // for shared_ptr, __shared_ptr_access
|
||||
#include <string> // for to_string, allocator
|
||||
#include <memory> // for allocator, shared_ptr, __shared_ptr_access
|
||||
#include <string> // for char_traits, to_string, operator+, string, basic_string
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for MenuEntry, Renderer, Vertical
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/component_options.hpp" // for MenuEntryOption
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for operator|, separator, Element, Decorator, color, text, hbox, size, bold, frame, inverted, vbox, HEIGHT, LESS_THAN, border
|
||||
#include "ftxui/dom/elements.hpp" // for operator|, Element, separator, text, hbox, size, frame, color, vbox, HEIGHT, LESS_THAN, bold, border, inverted
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::Cyan, Color::Green, Color::Red, Color::Yellow
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
// Define a special style for some menu entry.
|
||||
MenuEntryOption Colored(ftxui::Color c) {
|
||||
MenuEntryOption special_style;
|
||||
special_style.style_normal = Decorator(color(c));
|
||||
special_style.style_focused = Decorator(color(c)) | inverted;
|
||||
special_style.style_selected = Decorator(color(c)) | bold;
|
||||
special_style.style_selected_focused = Decorator(color(c)) | inverted | bold;
|
||||
return special_style;
|
||||
MenuEntryOption option;
|
||||
option.transform = [c](EntryState state) {
|
||||
state.label = (state.active ? "> " : " ") + state.label;
|
||||
Element e = text(state.label) | color(c);
|
||||
if (state.focused)
|
||||
e = e | inverted;
|
||||
if (state.active)
|
||||
e = e | bold;
|
||||
return e;
|
||||
};
|
||||
return option;
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
|
66
examples/component/menu_entries_animated.cpp
Normal file
66
examples/component/menu_entries_animated.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#include <iostream> // for basic_ostream::operator<<, operator<<, endl, basic_ostream, basic_ostream<>::__ostream_type, cout, ostream
|
||||
#include <memory> // for shared_ptr, __shared_ptr_access
|
||||
#include <string> // for to_string, allocator
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for MenuEntryAnimated, Renderer, Vertical
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/component_options.hpp" // for MenuEntryAnimated
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for operator|, separator, Element, Decorator, color, text, hbox, size, bold, frame, inverted, vbox, HEIGHT, LESS_THAN, border
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::Cyan, Color::Green, Color::Red, Color::Yellow
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
// Define a special style for some menu entry.
|
||||
MenuEntryOption Colored(ftxui::Color c) {
|
||||
MenuEntryOption option;
|
||||
option.animated_colors.foreground.enabled = true;
|
||||
option.animated_colors.background.enabled = true;
|
||||
option.animated_colors.background.active = c;
|
||||
option.animated_colors.background.inactive = Color::Black;
|
||||
option.animated_colors.foreground.active = Color::White;
|
||||
option.animated_colors.foreground.inactive = c;
|
||||
return option;
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
auto screen = ScreenInteractive::TerminalOutput();
|
||||
|
||||
int selected = 0;
|
||||
auto menu = Container::Vertical(
|
||||
{
|
||||
MenuEntry(" 1. rear", Colored(Color::Red)),
|
||||
MenuEntry(" 2. drown", Colored(Color::Yellow)),
|
||||
MenuEntry(" 3. nail", Colored(Color::Green)),
|
||||
MenuEntry(" 4. quit", Colored(Color::Cyan)),
|
||||
MenuEntry(" 5. decorative", Colored(Color::Blue)),
|
||||
MenuEntry(" 7. costume"),
|
||||
MenuEntry(" 8. pick"),
|
||||
MenuEntry(" 9. oral"),
|
||||
MenuEntry("11. minister"),
|
||||
MenuEntry("12. football"),
|
||||
MenuEntry("13. welcome"),
|
||||
MenuEntry("14. copper"),
|
||||
MenuEntry("15. inhabitant"),
|
||||
},
|
||||
&selected);
|
||||
|
||||
// Display together the menu with a border
|
||||
auto renderer = Renderer(menu, [&] {
|
||||
return vbox({
|
||||
hbox(text("selected = "), text(std::to_string(selected))),
|
||||
separator(),
|
||||
menu->Render() | frame,
|
||||
}) |
|
||||
border | bgcolor(Color::Black);
|
||||
});
|
||||
|
||||
screen.Loop(renderer);
|
||||
|
||||
std::cout << "Selected element = " << selected << std::endl;
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -1,100 +1,258 @@
|
||||
#include <array> // for array
|
||||
#include <chrono> // for milliseconds
|
||||
#include <functional> // for function
|
||||
#include <memory> // for shared_ptr, __shared_ptr_access, allocator
|
||||
#include <string> // for string, basic_string
|
||||
#include <memory> // for __shared_ptr_access, shared_ptr, allocator
|
||||
#include <string> // for string, char_traits, operator+, basic_string
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Menu, Horizontal, Renderer
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/component_options.hpp" // for MenuOption
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for operator|, color, separator, Decorator, bgcolor, flex, Element, bold, hbox, border, dim
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::BlueLight, Color::Red, Color::Yellow
|
||||
#include "ftxui/component/animation.hpp" // for ElasticOut, Linear
|
||||
#include "ftxui/component/component.hpp" // for Menu, Horizontal, Renderer, Vertical
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/component_options.hpp" // for MenuOption, EntryState, MenuEntryOption, AnimatedColorOption, AnimatedColorsOption, UnderlineOption
|
||||
#include "ftxui/component/mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for separator, operator|, Element, text, bgcolor, hbox, bold, color, filler, border, vbox, borderDouble, dim, flex, hcenter
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Red, Color::Black, Color::Yellow, Color::Blue, Color::Default, Color::White
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
Component VMenu1(std::vector<std::string>* entries, int* selected);
|
||||
Component VMenu2(std::vector<std::string>* entries, int* selected);
|
||||
Component VMenu3(std::vector<std::string>* entries, int* selected);
|
||||
Component VMenu4(std::vector<std::string>* entries, int* selected);
|
||||
Component VMenu5(std::vector<std::string>* entries, int* selected);
|
||||
Component VMenu6(std::vector<std::string>* entries, int* selected);
|
||||
Component VMenu7(std::vector<std::string>* entries, int* selected);
|
||||
Component VMenu8(std::vector<std::string>* entries, int* selected);
|
||||
Component HMenu1(std::vector<std::string>* entries, int* selected);
|
||||
Component HMenu2(std::vector<std::string>* entries, int* selected);
|
||||
Component HMenu3(std::vector<std::string>* entries, int* selected);
|
||||
Component HMenu4(std::vector<std::string>* entries, int* selected);
|
||||
Component HMenu5(std::vector<std::string>* entries, int* selected);
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
auto screen = ScreenInteractive::TerminalOutput();
|
||||
|
||||
std::vector<std::string> entries = {
|
||||
"Monkey", "Dog", "Cat", "Bird", "Elephant",
|
||||
std::vector<std::string> entries{
|
||||
"Monkey", "Dog", "Cat", "Bird", "Elephant", "Cat",
|
||||
};
|
||||
int menu_1_selected_ = 0;
|
||||
int menu_2_selected_ = 0;
|
||||
int menu_3_selected_ = 0;
|
||||
int menu_4_selected_ = 0;
|
||||
int menu_5_selected_ = 0;
|
||||
int menu_6_selected_ = 0;
|
||||
std::array<int, 12> selected = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
MenuOption option_1;
|
||||
option_1.style_focused = bold | color(Color::Blue);
|
||||
option_1.style_selected = color(Color::Blue);
|
||||
option_1.style_selected_focused = bold | color(Color::Blue);
|
||||
option_1.on_enter = screen.ExitLoopClosure();
|
||||
auto menu_1_ = Menu(&entries, &menu_1_selected_, &option_1);
|
||||
auto vmenu_1_ = VMenu1(&entries, &selected[0]);
|
||||
auto vmenu_2_ = VMenu2(&entries, &selected[1]);
|
||||
auto vmenu_3_ = VMenu3(&entries, &selected[2]);
|
||||
auto vmenu_4_ = VMenu4(&entries, &selected[3]);
|
||||
auto vmenu_5_ = VMenu5(&entries, &selected[4]);
|
||||
auto vmenu_6_ = VMenu6(&entries, &selected[5]);
|
||||
auto vmenu_7_ = VMenu7(&entries, &selected[6]);
|
||||
auto vmenu_8_ = VMenu8(&entries, &selected[7]);
|
||||
|
||||
MenuOption option_2;
|
||||
option_2.style_focused = bold | color(Color::Blue);
|
||||
option_2.style_selected = color(Color::Blue);
|
||||
option_2.style_selected_focused = bold | color(Color::Blue);
|
||||
option_2.on_enter = screen.ExitLoopClosure();
|
||||
auto menu_2_ = Menu(&entries, &menu_2_selected_, &option_2);
|
||||
auto hmenu_1_ = HMenu1(&entries, &selected[8]);
|
||||
auto hmenu_2_ = HMenu2(&entries, &selected[9]);
|
||||
auto hmenu_3_ = HMenu3(&entries, &selected[10]);
|
||||
auto hmenu_4_ = HMenu4(&entries, &selected[11]);
|
||||
auto hmenu_5_ = HMenu5(&entries, &selected[12]);
|
||||
|
||||
MenuOption option_3;
|
||||
option_3.style_selected = color(Color::Blue);
|
||||
option_3.style_focused = bgcolor(Color::Blue);
|
||||
option_3.style_selected_focused = bgcolor(Color::Blue);
|
||||
option_3.on_enter = screen.ExitLoopClosure();
|
||||
auto menu_3_ = Menu(&entries, &menu_3_selected_, &option_3);
|
||||
|
||||
MenuOption option_4;
|
||||
option_4.style_selected = bgcolor(Color::Blue);
|
||||
option_4.style_focused = bgcolor(Color::BlueLight);
|
||||
option_4.style_selected_focused = bgcolor(Color::BlueLight);
|
||||
option_4.on_enter = screen.ExitLoopClosure();
|
||||
auto menu_4_ = Menu(&entries, &menu_4_selected_, &option_4);
|
||||
|
||||
MenuOption option_5;
|
||||
option_5.style_normal = bgcolor(Color::Blue);
|
||||
option_5.style_selected = bgcolor(Color::Yellow);
|
||||
option_5.style_focused = bgcolor(Color::Red);
|
||||
option_5.style_selected_focused = bgcolor(Color::Red);
|
||||
option_5.on_enter = screen.ExitLoopClosure();
|
||||
auto menu_5_ = Menu(&entries, &menu_5_selected_, &option_5);
|
||||
|
||||
MenuOption option_6;
|
||||
option_6.style_normal = dim | color(Color::Blue);
|
||||
option_6.style_selected = color(Color::Blue);
|
||||
option_6.style_focused = bold | color(Color::Blue);
|
||||
option_6.style_selected_focused = bold | color(Color::Blue);
|
||||
option_6.on_enter = screen.ExitLoopClosure();
|
||||
auto menu_6_ = Menu(&entries, &menu_6_selected_, &option_6);
|
||||
|
||||
auto container = Container::Horizontal({
|
||||
menu_1_,
|
||||
menu_2_,
|
||||
menu_3_,
|
||||
menu_4_,
|
||||
menu_5_,
|
||||
menu_6_,
|
||||
auto container = Container::Vertical({
|
||||
Container::Horizontal({
|
||||
vmenu_1_,
|
||||
vmenu_2_,
|
||||
vmenu_3_,
|
||||
vmenu_4_,
|
||||
vmenu_5_,
|
||||
vmenu_6_,
|
||||
vmenu_7_,
|
||||
vmenu_8_,
|
||||
}),
|
||||
hmenu_1_,
|
||||
hmenu_2_,
|
||||
hmenu_3_,
|
||||
hmenu_4_,
|
||||
hmenu_5_,
|
||||
});
|
||||
|
||||
// clang-format off
|
||||
auto renderer = Renderer(container, [&] {
|
||||
return
|
||||
hbox({
|
||||
menu_1_->Render() | flex, separator(),
|
||||
menu_2_->Render() | flex, separator(),
|
||||
menu_3_->Render() | flex, separator(),
|
||||
menu_4_->Render() | flex, separator(),
|
||||
menu_5_->Render() | flex, separator(),
|
||||
menu_6_->Render() | flex,
|
||||
}) | border;
|
||||
return //
|
||||
hbox({
|
||||
vbox({
|
||||
hbox({
|
||||
vmenu_1_->Render(),
|
||||
separator(),
|
||||
vmenu_2_->Render(),
|
||||
separator(),
|
||||
vmenu_3_->Render(),
|
||||
separator(),
|
||||
vmenu_4_->Render(),
|
||||
separator(),
|
||||
vmenu_5_->Render(),
|
||||
vmenu_6_->Render(),
|
||||
separator(),
|
||||
vmenu_7_->Render(),
|
||||
separator(),
|
||||
vmenu_8_->Render(),
|
||||
}),
|
||||
separator(),
|
||||
hmenu_1_->Render(),
|
||||
separator(),
|
||||
hmenu_2_->Render(),
|
||||
separator(),
|
||||
hmenu_3_->Render(),
|
||||
separator(),
|
||||
hmenu_4_->Render(),
|
||||
hmenu_5_->Render(),
|
||||
}) | border,
|
||||
filler(),
|
||||
});
|
||||
});
|
||||
// clang-format on
|
||||
|
||||
screen.Loop(renderer);
|
||||
}
|
||||
|
||||
Component VMenu1(std::vector<std::string>* entries, int* selected) {
|
||||
auto option = MenuOption::Vertical();
|
||||
option.entries.transform = [](EntryState state) {
|
||||
state.label = (state.active ? "> " : " ") + state.label;
|
||||
Element e = text(state.label);
|
||||
if (state.focused)
|
||||
e = e | bgcolor(Color::Blue);
|
||||
if (state.active)
|
||||
e = e | bold;
|
||||
return e;
|
||||
};
|
||||
return Menu(entries, selected, option);
|
||||
}
|
||||
|
||||
Component VMenu2(std::vector<std::string>* entries, int* selected) {
|
||||
auto option = MenuOption::Vertical();
|
||||
option.entries.transform = [](EntryState state) {
|
||||
state.label += (state.active ? " <" : " ");
|
||||
Element e = hbox(filler(), text(state.label));
|
||||
if (state.focused)
|
||||
e = e | bgcolor(Color::Red);
|
||||
if (state.active)
|
||||
e = e | bold;
|
||||
return e;
|
||||
};
|
||||
return Menu(entries, selected, option);
|
||||
}
|
||||
|
||||
Component VMenu3(std::vector<std::string>* entries, int* selected) {
|
||||
auto option = MenuOption::Vertical();
|
||||
option.entries.transform = [](EntryState state) {
|
||||
Element e = state.active ? text("[" + state.label + "]")
|
||||
: text(" " + state.label + " ");
|
||||
if (state.focused)
|
||||
e = e | bold;
|
||||
|
||||
if (state.focused)
|
||||
e = e | color(Color::Blue);
|
||||
if (state.active)
|
||||
e = e | bold;
|
||||
return e;
|
||||
};
|
||||
return Menu(entries, selected, option);
|
||||
}
|
||||
|
||||
Component VMenu4(std::vector<std::string>* entries, int* selected) {
|
||||
auto option = MenuOption::Vertical();
|
||||
option.entries.transform = [](EntryState state) {
|
||||
if (state.active && state.focused) {
|
||||
return text(state.label) | color(Color::Yellow) | bgcolor(Color::Black) |
|
||||
bold;
|
||||
}
|
||||
|
||||
if (state.active) {
|
||||
return text(state.label) | color(Color::Yellow) | bgcolor(Color::Black);
|
||||
}
|
||||
if (state.focused) {
|
||||
return text(state.label) | color(Color::Black) | bgcolor(Color::Yellow) |
|
||||
bold;
|
||||
}
|
||||
return text(state.label) | color(Color::Black) | bgcolor(Color::Yellow);
|
||||
};
|
||||
return Menu(entries, selected, option);
|
||||
}
|
||||
|
||||
Component VMenu5(std::vector<std::string>* entries, int* selected) {
|
||||
auto option = MenuOption::Vertical();
|
||||
option.entries.transform = [](EntryState state) {
|
||||
auto element = text(state.label);
|
||||
if (state.active && state.focused) {
|
||||
return element | borderDouble;
|
||||
}
|
||||
if (state.active) {
|
||||
return element | border;
|
||||
}
|
||||
if (state.focused) {
|
||||
return element | bold;
|
||||
}
|
||||
return element;
|
||||
};
|
||||
return Menu(entries, selected, option);
|
||||
}
|
||||
|
||||
Component VMenu6(std::vector<std::string>* entries, int* selected) {
|
||||
auto option = MenuOption::VerticalAnimated();
|
||||
option.underline.color_inactive = Color::Default;
|
||||
option.underline.color_active = Color::Red;
|
||||
option.underline.SetAnimationFunction(animation::easing::Linear);
|
||||
return Menu(entries, selected, option);
|
||||
}
|
||||
|
||||
Component VMenu7(std::vector<std::string>* entries, int* selected) {
|
||||
auto option = MenuOption::Vertical();
|
||||
option.entries.animated_colors.foreground.enabled = true;
|
||||
option.entries.animated_colors.background.enabled = true;
|
||||
option.entries.animated_colors.background.active = Color::Red;
|
||||
option.entries.animated_colors.background.inactive = Color::Black;
|
||||
option.entries.animated_colors.foreground.active = Color::White;
|
||||
option.entries.animated_colors.foreground.inactive = Color::Red;
|
||||
return Menu(entries, selected, option);
|
||||
}
|
||||
|
||||
Component VMenu8(std::vector<std::string>* entries, int* selected) {
|
||||
auto option = MenuOption::Vertical();
|
||||
option.entries.animated_colors.foreground.Set(Color::Red, Color::White,
|
||||
std::chrono::milliseconds(500));
|
||||
return Menu(entries, selected, option);
|
||||
}
|
||||
|
||||
Component HMenu1(std::vector<std::string>* entries, int* selected) {
|
||||
return Menu(entries, selected, MenuOption::Horizontal());
|
||||
}
|
||||
|
||||
Component HMenu2(std::vector<std::string>* entries, int* selected) {
|
||||
return Menu(entries, selected, MenuOption::Toggle());
|
||||
}
|
||||
|
||||
Component HMenu3(std::vector<std::string>* entries, int* selected) {
|
||||
auto option = MenuOption::Toggle();
|
||||
option.elements_infix = [] { return text(" 🮣🮠 "); };
|
||||
|
||||
return Menu(entries, selected, option);
|
||||
}
|
||||
|
||||
Component HMenu4(std::vector<std::string>* entries, int* selected) {
|
||||
return Menu(entries, selected, MenuOption::HorizontalAnimated());
|
||||
}
|
||||
|
||||
Component HMenu5(std::vector<std::string>* entries, int* selected) {
|
||||
auto option = MenuOption::HorizontalAnimated();
|
||||
option.underline.SetAnimation(std::chrono::milliseconds(1500),
|
||||
animation::easing::ElasticOut);
|
||||
option.entries.transform = [](EntryState state) {
|
||||
Element e = text(state.label) | hcenter | flex;
|
||||
if (state.active && state.focused)
|
||||
e = e | bold;
|
||||
if (!state.focused && !state.active)
|
||||
e = e | dim;
|
||||
return e;
|
||||
};
|
||||
option.underline.color_inactive = Color::Default;
|
||||
option.underline.color_active = Color::Red;
|
||||
return Menu(entries, selected, option);
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
||||
|
94
examples/component/menu_underline_animated_gallery.cpp
Normal file
94
examples/component/menu_underline_animated_gallery.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include <chrono> // for operator""ms, literals
|
||||
#include <memory> // for allocator, shared_ptr, __shared_ptr_access
|
||||
#include <string> // for string, operator+, to_string, basic_string
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/component/animation.hpp" // for BackOut, Duration
|
||||
#include "ftxui/component/component.hpp" // for Menu, Renderer, Vertical
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/component_options.hpp" // for MenuOption, UnderlineOption
|
||||
#include "ftxui/component/mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for text, Element, operator|, borderEmpty, inverted
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Blue, Color::Red
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
Component DummyComponent(int id) {
|
||||
return Renderer([id](bool focused) {
|
||||
auto t = text("component " + std::to_string(id));
|
||||
if (focused)
|
||||
t = t | inverted;
|
||||
return t;
|
||||
});
|
||||
}
|
||||
|
||||
Component Text(const std::string& t) {
|
||||
return Renderer([t] { return text(t) | borderEmpty; });
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace std::literals;
|
||||
std::vector<std::string> tab_values{
|
||||
"Tab 1", "Tab 2", "Tab 3", "A very very long tab", "탭",
|
||||
};
|
||||
int tab_selected = 0;
|
||||
|
||||
auto container = Container::Vertical({});
|
||||
|
||||
int frame_count = 0;
|
||||
container->Add(Renderer(
|
||||
[&] { return text("Frame count: " + std::to_string(frame_count++)); }));
|
||||
|
||||
{
|
||||
auto option = MenuOption::HorizontalAnimated();
|
||||
container->Add(Text("This demonstrate the Menu component"));
|
||||
container->Add(Menu(&tab_values, &tab_selected, option));
|
||||
}
|
||||
|
||||
{
|
||||
container->Add(Text("Set underline color to blue"));
|
||||
auto option = MenuOption::HorizontalAnimated();
|
||||
option.underline.color_inactive = Color::Blue;
|
||||
container->Add(Menu(&tab_values, &tab_selected, option));
|
||||
}
|
||||
|
||||
{
|
||||
container->Add(Text("Set underline active color to red"));
|
||||
auto option = MenuOption::HorizontalAnimated();
|
||||
option.underline.color_active = Color::Red;
|
||||
container->Add(Menu(&tab_values, &tab_selected, option));
|
||||
}
|
||||
|
||||
{
|
||||
container->Add(Text("Set animation duration to 0ms"));
|
||||
auto option = MenuOption::HorizontalAnimated();
|
||||
option.underline.SetAnimationDuration(0ms);
|
||||
container->Add(Menu(&tab_values, &tab_selected, option));
|
||||
}
|
||||
|
||||
{
|
||||
container->Add(Text("Set animation easing function to back-out"));
|
||||
auto option = MenuOption::HorizontalAnimated();
|
||||
option.underline.SetAnimationFunction(animation::easing::BackOut);
|
||||
option.underline.SetAnimationDuration(350ms);
|
||||
container->Add(Menu(&tab_values, &tab_selected, option));
|
||||
}
|
||||
|
||||
// option.underline_animation_follower_delay = 250ms
|
||||
{
|
||||
container->Add(Text("Add delay to desynchronize animation"));
|
||||
auto option = MenuOption::HorizontalAnimated();
|
||||
option.underline.follower_delay = 250ms;
|
||||
container->Add(Menu(&tab_values, &tab_selected, option));
|
||||
}
|
||||
|
||||
container->SetActiveChild(container->ChildAt(2));
|
||||
|
||||
auto screen = ScreenInteractive::TerminalOutput();
|
||||
screen.Loop(container);
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -1,94 +1,83 @@
|
||||
#include <memory> // for allocator, shared_ptr, __shared_ptr_access
|
||||
#include <string> // for string, basic_string, char_traits, operator+
|
||||
#include <vector> // for vector
|
||||
#include <ftxui/component/component_options.hpp> // for ButtonOption
|
||||
#include <ftxui/component/mouse.hpp> // for ftxui
|
||||
#include <functional> // for function
|
||||
#include <memory> // for allocator, shared_ptr
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Button, Renderer, Horizontal, Tab
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for operator|, Element, filler, text, hbox, separator, center, vbox, bold, border, clear_under, dbox, size, GREATER_THAN, HEIGHT
|
||||
#include "ftxui/component/component.hpp" // for Button, operator|=, Renderer, Vertical, Modal
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive, Component
|
||||
#include "ftxui/dom/elements.hpp" // for operator|, separator, text, size, Element, vbox, border, GREATER_THAN, WIDTH, center, HEIGHT
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
auto button_style = ButtonOption::Animated();
|
||||
|
||||
// Definition of the main component. The details are not important.
|
||||
Component MainComponent(std::function<void()> show_modal,
|
||||
std::function<void()> exit) {
|
||||
auto component = Container::Vertical({
|
||||
Button("Show modal", show_modal, button_style),
|
||||
Button("Quit", exit, button_style),
|
||||
});
|
||||
// Polish how the two buttons are rendered:
|
||||
component |= Renderer([&](Element inner) {
|
||||
return vbox({
|
||||
text("Main component"),
|
||||
separator(),
|
||||
inner,
|
||||
}) //
|
||||
| size(WIDTH, GREATER_THAN, 15) //
|
||||
| size(HEIGHT, GREATER_THAN, 15) //
|
||||
| border //
|
||||
| center; //
|
||||
});
|
||||
return component;
|
||||
}
|
||||
|
||||
// Definition of the modal component. The details are not important.
|
||||
Component ModalComponent(std::function<void()> do_nothing,
|
||||
std::function<void()> hide_modal) {
|
||||
auto component = Container::Vertical({
|
||||
Button("Do nothing", do_nothing, button_style),
|
||||
Button("Quit modal", hide_modal, button_style),
|
||||
});
|
||||
// Polish how the two buttons are rendered:
|
||||
component |= Renderer([&](Element inner) {
|
||||
return vbox({
|
||||
text("Modal component "),
|
||||
separator(),
|
||||
inner,
|
||||
}) //
|
||||
| size(WIDTH, GREATER_THAN, 30) //
|
||||
| border; //
|
||||
});
|
||||
return component;
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
auto screen = ScreenInteractive::TerminalOutput();
|
||||
|
||||
// There are two layers. One at depth = 0 and the modal window at depth = 1;
|
||||
int depth = 0;
|
||||
// State of the application:
|
||||
bool modal_shown = false;
|
||||
|
||||
// The current rating of FTXUI.
|
||||
std::string rating = "3/5 stars";
|
||||
// Some actions modifying the state:
|
||||
auto show_modal = [&] { modal_shown = true; };
|
||||
auto hide_modal = [&] { modal_shown = false; };
|
||||
auto exit = screen.ExitLoopClosure();
|
||||
auto do_nothing = [&] {};
|
||||
|
||||
// At depth=0, two buttons. One for rating FTXUI and one for quitting.
|
||||
auto button_rate_ftxui = Button("Rate FTXUI", [&] { depth = 1; });
|
||||
auto button_quit = Button("Quit", screen.ExitLoopClosure());
|
||||
// Instanciate the main and modal components:
|
||||
auto main_component = MainComponent(show_modal, exit);
|
||||
auto modal_component = ModalComponent(do_nothing, hide_modal);
|
||||
|
||||
auto depth_0_container = Container::Horizontal({
|
||||
button_rate_ftxui,
|
||||
button_quit,
|
||||
});
|
||||
auto depth_0_renderer = Renderer(depth_0_container, [&] {
|
||||
return vbox({
|
||||
text("Modal dialog example"),
|
||||
separator(),
|
||||
text("☆☆☆ FTXUI:" + rating + " ☆☆☆") | bold,
|
||||
filler(),
|
||||
hbox({
|
||||
button_rate_ftxui->Render(),
|
||||
filler(),
|
||||
button_quit->Render(),
|
||||
}),
|
||||
}) |
|
||||
border | size(HEIGHT, GREATER_THAN, 18) | center;
|
||||
});
|
||||
// Use the `Modal` function to use together the main component and its modal
|
||||
// window. The |modal_shown| boolean controls whether the modal is shown or
|
||||
// not.
|
||||
main_component |= Modal(modal_component, &modal_shown);
|
||||
|
||||
// At depth=1, The "modal" window.
|
||||
std::vector<std::string> rating_labels = {
|
||||
"1/5 stars", "2/5 stars", "3/5 stars", "4/5 stars", "5/5 stars",
|
||||
};
|
||||
auto on_rating = [&](std::string new_rating) {
|
||||
rating = new_rating;
|
||||
depth = 0;
|
||||
};
|
||||
auto depth_1_container = Container::Horizontal({
|
||||
Button(&rating_labels[0], [&] { on_rating(rating_labels[0]); }),
|
||||
Button(&rating_labels[1], [&] { on_rating(rating_labels[1]); }),
|
||||
Button(&rating_labels[2], [&] { on_rating(rating_labels[2]); }),
|
||||
Button(&rating_labels[3], [&] { on_rating(rating_labels[3]); }),
|
||||
Button(&rating_labels[4], [&] { on_rating(rating_labels[4]); }),
|
||||
});
|
||||
|
||||
auto depth_1_renderer = Renderer(depth_1_container, [&] {
|
||||
return vbox({
|
||||
text("Do you like FTXUI?"),
|
||||
separator(),
|
||||
hbox(depth_1_container->Render()),
|
||||
}) |
|
||||
border;
|
||||
});
|
||||
|
||||
auto main_container = Container::Tab(
|
||||
{
|
||||
depth_0_renderer,
|
||||
depth_1_renderer,
|
||||
},
|
||||
&depth);
|
||||
|
||||
auto main_renderer = Renderer(main_container, [&] {
|
||||
Element document = depth_0_renderer->Render();
|
||||
|
||||
if (depth == 1) {
|
||||
document = dbox({
|
||||
document,
|
||||
depth_1_renderer->Render() | clear_under | center,
|
||||
});
|
||||
}
|
||||
return document;
|
||||
});
|
||||
|
||||
screen.Loop(main_renderer);
|
||||
screen.Loop(main_component);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Copyright 2022 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
||||
|
94
examples/component/modal_dialog_custom.cpp
Normal file
94
examples/component/modal_dialog_custom.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include <memory> // for allocator, shared_ptr, __shared_ptr_access
|
||||
#include <string> // for string, basic_string, char_traits, operator+
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Button, Renderer, Horizontal, Tab
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
#include "ftxui/dom/elements.hpp" // for operator|, Element, filler, text, hbox, separator, center, vbox, bold, border, clear_under, dbox, size, GREATER_THAN, HEIGHT
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
auto screen = ScreenInteractive::TerminalOutput();
|
||||
|
||||
// There are two layers. One at depth = 0 and the modal window at depth = 1;
|
||||
int depth = 0;
|
||||
|
||||
// The current rating of FTXUI.
|
||||
std::string rating = "3/5 stars";
|
||||
|
||||
// At depth=0, two buttons. One for rating FTXUI and one for quitting.
|
||||
auto button_rate_ftxui = Button("Rate FTXUI", [&] { depth = 1; });
|
||||
auto button_quit = Button("Quit", screen.ExitLoopClosure());
|
||||
|
||||
auto depth_0_container = Container::Horizontal({
|
||||
button_rate_ftxui,
|
||||
button_quit,
|
||||
});
|
||||
auto depth_0_renderer = Renderer(depth_0_container, [&] {
|
||||
return vbox({
|
||||
text("Modal dialog example"),
|
||||
separator(),
|
||||
text("☆☆☆ FTXUI:" + rating + " ☆☆☆") | bold,
|
||||
filler(),
|
||||
hbox({
|
||||
button_rate_ftxui->Render(),
|
||||
filler(),
|
||||
button_quit->Render(),
|
||||
}),
|
||||
}) |
|
||||
border | size(HEIGHT, GREATER_THAN, 18) | center;
|
||||
});
|
||||
|
||||
// At depth=1, The "modal" window.
|
||||
std::vector<std::string> rating_labels = {
|
||||
"1/5 stars", "2/5 stars", "3/5 stars", "4/5 stars", "5/5 stars",
|
||||
};
|
||||
auto on_rating = [&](std::string new_rating) {
|
||||
rating = new_rating;
|
||||
depth = 0;
|
||||
};
|
||||
auto depth_1_container = Container::Horizontal({
|
||||
Button(&rating_labels[0], [&] { on_rating(rating_labels[0]); }),
|
||||
Button(&rating_labels[1], [&] { on_rating(rating_labels[1]); }),
|
||||
Button(&rating_labels[2], [&] { on_rating(rating_labels[2]); }),
|
||||
Button(&rating_labels[3], [&] { on_rating(rating_labels[3]); }),
|
||||
Button(&rating_labels[4], [&] { on_rating(rating_labels[4]); }),
|
||||
});
|
||||
|
||||
auto depth_1_renderer = Renderer(depth_1_container, [&] {
|
||||
return vbox({
|
||||
text("Do you like FTXUI?"),
|
||||
separator(),
|
||||
hbox(depth_1_container->Render()),
|
||||
}) |
|
||||
border;
|
||||
});
|
||||
|
||||
auto main_container = Container::Tab(
|
||||
{
|
||||
depth_0_renderer,
|
||||
depth_1_renderer,
|
||||
},
|
||||
&depth);
|
||||
|
||||
auto main_renderer = Renderer(main_container, [&] {
|
||||
Element document = depth_0_renderer->Render();
|
||||
|
||||
if (depth == 1) {
|
||||
document = dbox({
|
||||
document,
|
||||
depth_1_renderer->Render() | clear_under | center,
|
||||
});
|
||||
}
|
||||
return document;
|
||||
});
|
||||
|
||||
screen.Loop(main_renderer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -25,7 +25,7 @@ std::string Stringify(Event event) {
|
||||
|
||||
out = "(" + out + " ) -> ";
|
||||
if (event.is_character()) {
|
||||
out += "character(" + event.character() + ")";
|
||||
out += "Event::Character(\"" + event.character() + "\")";
|
||||
} else if (event.is_mouse()) {
|
||||
out += "mouse";
|
||||
switch (event.mouse().button) {
|
||||
@@ -66,6 +66,68 @@ std::string Stringify(Event event) {
|
||||
out += "(" + //
|
||||
std::to_string(event.mouse().x) + "," +
|
||||
std::to_string(event.mouse().y) + ")";
|
||||
} else if (event == Event::ArrowLeft) {
|
||||
out += "Event::ArrowLeft";
|
||||
} else if (event == Event::ArrowRight) {
|
||||
out += "Event::ArrowRight";
|
||||
} else if (event == Event::ArrowUp) {
|
||||
out += "Event::ArrowUp";
|
||||
} else if (event == Event::ArrowDown) {
|
||||
out += "Event::ArrowDown";
|
||||
} else if (event == Event::ArrowLeftCtrl) {
|
||||
out += "Event::ArrowLeftCtrl";
|
||||
} else if (event == Event ::ArrowRightCtrl) {
|
||||
out += "Event::ArrowRightCtrl";
|
||||
} else if (event == Event::ArrowUpCtrl) {
|
||||
out += "Event::ArrowUpCtrl";
|
||||
} else if (event == Event::ArrowDownCtrl) {
|
||||
out += "Event::ArrowDownCtrl";
|
||||
} else if (event == Event::Backspace) {
|
||||
out += "Event::Backspace";
|
||||
} else if (event == Event::Delete) {
|
||||
out += "Event::Delete";
|
||||
} else if (event == Event::Escape) {
|
||||
out += "Event::Escape";
|
||||
} else if (event == Event::Return) {
|
||||
out += "Event::Return";
|
||||
} else if (event == Event::Tab) {
|
||||
out += "Event::Tab";
|
||||
} else if (event == Event::TabReverse) {
|
||||
out += "Event::TabReverse";
|
||||
} else if (event == Event::F1) {
|
||||
out += "Event::F1";
|
||||
} else if (event == Event::F2) {
|
||||
out += "Event::F2";
|
||||
} else if (event == Event::F3) {
|
||||
out += "Event::F3";
|
||||
} else if (event == Event::F4) {
|
||||
out += "Event::F4";
|
||||
} else if (event == Event::F5) {
|
||||
out += "Event::F5";
|
||||
} else if (event == Event::F6) {
|
||||
out += "Event::F6";
|
||||
} else if (event == Event::F7) {
|
||||
out += "Event::F7";
|
||||
} else if (event == Event::F8) {
|
||||
out += "Event::F8";
|
||||
} else if (event == Event::F9) {
|
||||
out += "Event::F9";
|
||||
} else if (event == Event::F10) {
|
||||
out += "Event::F10";
|
||||
} else if (event == Event::F11) {
|
||||
out += "Event::F11";
|
||||
} else if (event == Event::F12) {
|
||||
out += "Event::F12";
|
||||
} else if (event == Event::Home) {
|
||||
out += "Event::Home";
|
||||
} else if (event == Event::End) {
|
||||
out += "Event::End";
|
||||
} else if (event == Event::PageUp) {
|
||||
out += "Event::PageUp";
|
||||
} else if (event == Event::PageDown) {
|
||||
out += "Event::PageDown";
|
||||
} else if (event == Event::Custom) {
|
||||
out += "Custom";
|
||||
} else {
|
||||
out += "(special)";
|
||||
}
|
||||
@@ -84,7 +146,7 @@ int main(int argc, const char* argv[]) {
|
||||
return window(text("keys"), vbox(std::move(children)));
|
||||
});
|
||||
|
||||
component = CatchEvent(component, [&](Event event) {
|
||||
component |= CatchEvent([&](Event event) {
|
||||
keys.push_back(event);
|
||||
return true;
|
||||
});
|
||||
|
49
examples/component/slider_direction.cpp
Normal file
49
examples/component/slider_direction.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <array> // for array
|
||||
#include <cmath> // for sin
|
||||
#include <ftxui/component/component_base.hpp> // for ComponentBase
|
||||
#include <ftxui/component/component_options.hpp> // for SliderOption
|
||||
#include <ftxui/dom/elements.hpp> // for size, GREATER_THAN, GaugeDirection, GaugeDirection::Up, HEIGHT
|
||||
#include <ftxui/util/ref.hpp> // for ConstRef, Ref
|
||||
#include <memory> // for shared_ptr, __shared_ptr_access
|
||||
|
||||
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||
#include "ftxui/component/component.hpp" // for Horizontal, Slider, operator|=
|
||||
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||
|
||||
using namespace ftxui;
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
auto screen = ScreenInteractive::TerminalOutput();
|
||||
std::array<int, 30> values;
|
||||
for (int i = 0; i < values.size(); ++i) {
|
||||
values[i] = 50 + 20 * std::sin(i * 0.3);
|
||||
}
|
||||
|
||||
auto layout_horizontal = Container::Horizontal({});
|
||||
for (int i = 0; i < values.size(); ++i) {
|
||||
// In C++17:
|
||||
SliderOption<int> option;
|
||||
option.value = &values[i];
|
||||
option.max = 100;
|
||||
option.increment = 5;
|
||||
option.direction = GaugeDirection::Up;
|
||||
layout_horizontal->Add(Slider<int>(option));
|
||||
|
||||
/* In C++20:
|
||||
layout_horizontal->Add(Slider<int>({
|
||||
.value = &values[i],
|
||||
.max = 100,
|
||||
.increment = 5,
|
||||
.direction = GaugeDirection::Up,
|
||||
}));
|
||||
*/
|
||||
}
|
||||
|
||||
layout_horizontal |= size(HEIGHT, GREATER_THAN, 20);
|
||||
|
||||
screen.Loop(layout_horizontal);
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -1,5 +1,13 @@
|
||||
#include "ftxui/component/component.hpp" // for Menu
|
||||
#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;
|
||||
@@ -10,14 +18,12 @@ int main() {
|
||||
// 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::system("bash");
|
||||
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);
|
||||
}
|
||||
std::system("bash");
|
||||
}));
|
||||
|
||||
auto btn_quit = Button("Quit", screen.ExitLoopClosure());
|
||||
|
@@ -1,18 +1,21 @@
|
||||
set(DIRECTORY_LIB dom)
|
||||
|
||||
example(border)
|
||||
example(border_colored)
|
||||
example(border_style)
|
||||
example(canvas)
|
||||
example(color_gallery)
|
||||
example(color_info_palette256)
|
||||
example(color_truecolor_HSV)
|
||||
example(color_truecolor_RGB)
|
||||
example(dbox)
|
||||
example(canvas)
|
||||
example(gauge)
|
||||
example(gauge_direction)
|
||||
example(graph)
|
||||
example(gridbox)
|
||||
example(hflow)
|
||||
example(html_like)
|
||||
example(linear_gradient)
|
||||
example(package_manager)
|
||||
example(paragraph)
|
||||
example(separator)
|
||||
@@ -25,7 +28,9 @@ example(style_color)
|
||||
example(style_dim)
|
||||
example(style_gallery)
|
||||
example(style_inverted)
|
||||
example(style_strikethrough)
|
||||
example(style_underlined)
|
||||
example(style_underlined_double)
|
||||
example(table)
|
||||
example(vbox_hbox)
|
||||
example(vflow)
|
||||
|
@@ -1,3 +1,4 @@
|
||||
#include <stdlib.h> // for EXIT_SUCCESS
|
||||
#include <ftxui/dom/elements.hpp> // for text, operator|, vbox, border, Element, Fit, hbox
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator
|
||||
@@ -5,7 +6,7 @@
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int main() {
|
||||
using namespace ftxui;
|
||||
auto document = //
|
||||
hbox({
|
||||
@@ -30,6 +31,7 @@ int main(int argc, const char* argv[]) {
|
||||
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
|
||||
Render(screen, document);
|
||||
screen.Print();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
|
40
examples/dom/border_colored.cpp
Normal file
40
examples/dom/border_colored.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include <ftxui/dom/elements.hpp> // for operator|, text, Element, Fit, borderDouble, borderHeavy, borderLight, borderRounded, vbox
|
||||
#include <ftxui/screen/screen.hpp> // for Screen
|
||||
#include <iostream> // for endl, cout, ostream
|
||||
#include <memory> // for allocator
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
|
||||
auto make_boxed = [] {
|
||||
return vbox({
|
||||
text("borderLight") | borderStyled(LIGHT, Color::Red),
|
||||
text("borderDashed") | borderStyled(DASHED, Color::Green),
|
||||
text("borderHeavy") | borderStyled(HEAVY, Color::Blue),
|
||||
text("borderDouble") | borderStyled(DOUBLE, Color::Yellow),
|
||||
text("borderRounded") | borderStyled(ROUNDED, Color::Cyan),
|
||||
});
|
||||
};
|
||||
|
||||
auto document = hbox({
|
||||
make_boxed(),
|
||||
separator() | color(Color::Red),
|
||||
make_boxed(),
|
||||
separator() | color(Color::Red),
|
||||
make_boxed(),
|
||||
}) |
|
||||
borderStyled(ROUNDED, Color::Red);
|
||||
|
||||
auto screen =
|
||||
Screen::Create(Dimension::Fit(document), Dimension::Fit(document));
|
||||
Render(screen, document);
|
||||
screen.Print();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
// 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.
|
@@ -11,6 +11,7 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
auto document = vbox({
|
||||
text("borderLight") | borderLight,
|
||||
text("borderDashed") | borderDashed,
|
||||
text("borderHeavy") | borderHeavy,
|
||||
text("borderDouble") | borderDouble,
|
||||
text("borderRounded") | borderRounded,
|
||||
|
@@ -30,7 +30,7 @@ int main(int argc, const char* argv[]) {
|
||||
// Plot a function:
|
||||
std::vector<int> ys(100);
|
||||
for (int x = 0; x < 100; x++)
|
||||
ys[x] = 80 + 20 * cos(x * 0.2);
|
||||
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);
|
||||
|
||||
|
@@ -5,13 +5,14 @@
|
||||
#include <utility> // for move
|
||||
#include <vector> // for vector
|
||||
|
||||
using namespace ftxui;
|
||||
#include "./color_info_sorted_2d.ipp" // for ColorInfoSorted2D
|
||||
#include "ftxui/dom/elements.hpp" // for text, bgcolor, color, vbox, hbox, separator, operator|, Elements, Element, Fit, border
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Black, Color::Blue, Color::BlueLight, Color::Cyan, Color::CyanLight, Color::Default, Color::GrayDark, Color::GrayLight, Color::Green, Color::GreenLight, Color::Magenta, Color::MagentaLight, Color::Red, Color::RedLight, Color::White, Color::Yellow, Color::YellowLight, Color::Palette256, ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
#include "./color_info_sorted_2d.ipp" // for ColorInfoSorted2D
|
||||
|
||||
int main() {
|
||||
// clang-format off
|
||||
auto basic_color_display =
|
||||
vbox(
|
||||
@@ -82,14 +83,18 @@ int main(int argc, const char* argv[]) {
|
||||
// True color display.
|
||||
auto true_color_display = text("TrueColors: 24bits:");
|
||||
{
|
||||
int saturation = 255;
|
||||
const int max_value = 255;
|
||||
const int value_increment = 8;
|
||||
const int hue_increment = 6;
|
||||
int saturation = max_value;
|
||||
Elements array;
|
||||
for (int value = 0; value < 255; value += 16) {
|
||||
for (int value = 0; value < max_value; value += 2 * value_increment) {
|
||||
Elements line;
|
||||
for (int hue = 0; hue < 255; hue += 6) {
|
||||
line.push_back(text("▀") //
|
||||
| color(Color::HSV(hue, saturation, value)) //
|
||||
| bgcolor(Color::HSV(hue, saturation, value + 8)));
|
||||
for (int hue = 0; hue < max_value; hue += hue_increment) {
|
||||
line.push_back(
|
||||
text("▀") //
|
||||
| color(Color::HSV(hue, saturation, value)) //
|
||||
| bgcolor(Color::HSV(hue, saturation, value + value_increment)));
|
||||
}
|
||||
array.push_back(hbox(std::move(line)));
|
||||
}
|
||||
|
@@ -1,12 +1,13 @@
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <ftxui/screen/color_info.hpp> // for ftxui::ColorInfo
|
||||
|
||||
std::vector<std::vector<ColorInfo>> ColorInfoSorted2D() {
|
||||
std::vector<std::vector<ftxui::ColorInfo>> ColorInfoSorted2D() {
|
||||
// Acquire the color information for the palette256.
|
||||
std::vector<ColorInfo> info_gray;
|
||||
std::vector<ColorInfo> info_color;
|
||||
std::vector<ftxui::ColorInfo> info_gray;
|
||||
std::vector<ftxui::ColorInfo> info_color;
|
||||
for (int i = 16; i < 256; ++i) {
|
||||
ColorInfo info = GetColorInfo(Color::Palette256(i));
|
||||
ftxui::ColorInfo info = GetColorInfo(ftxui::Color::Palette256(i));
|
||||
if (info.saturation == 0)
|
||||
info_gray.push_back(info);
|
||||
else
|
||||
@@ -16,10 +17,10 @@ std::vector<std::vector<ColorInfo>> ColorInfoSorted2D() {
|
||||
// Sort info_color by hue.
|
||||
std::sort(
|
||||
info_color.begin(), info_color.end(),
|
||||
[](const ColorInfo& A, const ColorInfo& B) { return A.hue < B.hue; });
|
||||
[](const ftxui::ColorInfo& A, const ftxui::ColorInfo& B) { return A.hue < B.hue; });
|
||||
|
||||
// Make 8 colums, one gray and seven colored.
|
||||
std::vector<std::vector<ColorInfo>> info_columns(8);
|
||||
std::vector<std::vector<ftxui::ColorInfo>> info_columns(8);
|
||||
info_columns[0] = info_gray;
|
||||
for (size_t i = 0; i < info_color.size(); ++i) {
|
||||
info_columns[1 + 7 * i / info_color.size()].push_back(info_color[i]);
|
||||
@@ -28,13 +29,13 @@ std::vector<std::vector<ColorInfo>> ColorInfoSorted2D() {
|
||||
// Minimize discontinuities for every columns.
|
||||
for (auto& column : info_columns) {
|
||||
std::sort(column.begin(), column.end(),
|
||||
[](const ColorInfo& A, const ColorInfo& B) {
|
||||
[](const ftxui::ColorInfo& A, const ftxui::ColorInfo& B) {
|
||||
return A.value < B.value;
|
||||
});
|
||||
for (size_t i = 0; i < column.size() - 1; ++i) {
|
||||
for (int i = 0; i < int(column.size()) - 1; ++i) {
|
||||
int best_index = i + 1;
|
||||
int best_distance = 255 * 255 * 3;
|
||||
for (size_t j = i + 1; j < column.size(); ++j) {
|
||||
for (int j = i + 1; j < column.size(); ++j) {
|
||||
int dx = column[i].red - column[j].red;
|
||||
int dy = column[i].green - column[j].green;
|
||||
int dz = column[i].blue - column[j].blue;
|
||||
|
@@ -2,7 +2,7 @@
|
||||
#include <ftxui/dom/elements.hpp> // for text, gauge, operator|, flex, hbox, Element
|
||||
#include <ftxui/screen/screen.hpp> // for Screen
|
||||
#include <iostream> // for cout, endl, ostream
|
||||
#include <string> // for allocator, operator+, char_traits, operator<<, string, to_string, basic_string
|
||||
#include <string> // for allocator, char_traits, operator+, operator<<, string, to_string, basic_string
|
||||
#include <thread> // for sleep_for
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
|
79
examples/dom/gauge_direction.cpp
Normal file
79
examples/dom/gauge_direction.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#include <chrono> // for operator""s, chrono_literals
|
||||
#include <ftxui/dom/elements.hpp> // for filler, operator|, separator, text, border, Element, vbox, vtext, hbox, center, gaugeDown, gaugeLeft, gaugeRight, gaugeUp
|
||||
#include <ftxui/screen/screen.hpp> // for Screen
|
||||
#include <iostream> // for cout, endl, ostream
|
||||
#include <string> // for allocator, operator+, operator<<, string, to_string
|
||||
#include <thread> // for sleep_for
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
std::string reset_position;
|
||||
for (float percentage = 0.0f; percentage <= 1.0f; percentage += 0.002f) {
|
||||
std::string data_downloaded =
|
||||
std::to_string(int(percentage * 5000)) + "/5000";
|
||||
|
||||
auto gauge_up = //
|
||||
hbox({
|
||||
vtext("gauge vertical"),
|
||||
separator(),
|
||||
gaugeUp(percentage),
|
||||
}) |
|
||||
border;
|
||||
|
||||
auto gauge_down = //
|
||||
hbox({
|
||||
vtext("gauge vertical"),
|
||||
separator(),
|
||||
gaugeDown(percentage),
|
||||
}) |
|
||||
border;
|
||||
|
||||
auto gauge_right = //
|
||||
vbox({
|
||||
text("gauge horizontal"),
|
||||
separator(),
|
||||
gaugeRight(percentage),
|
||||
}) |
|
||||
border;
|
||||
|
||||
auto gauge_left = //
|
||||
vbox({
|
||||
text("gauge horizontal"),
|
||||
separator(),
|
||||
gaugeLeft(percentage),
|
||||
}) |
|
||||
border;
|
||||
|
||||
auto document = hbox({
|
||||
gauge_up,
|
||||
filler(),
|
||||
vbox({
|
||||
gauge_right,
|
||||
filler(),
|
||||
text(data_downloaded) | border | center,
|
||||
filler(),
|
||||
gauge_left,
|
||||
}),
|
||||
filler(),
|
||||
gauge_down,
|
||||
});
|
||||
|
||||
auto screen = Screen(32, 16);
|
||||
Render(screen, document);
|
||||
std::cout << reset_position;
|
||||
screen.Print();
|
||||
reset_position = screen.ResetPosition();
|
||||
|
||||
std::this_thread::sleep_for(0.01s);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
// Copyright 2022 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -1,9 +1,10 @@
|
||||
#include <chrono> // for operator""s, chrono_literals
|
||||
#include <cmath> // for sin
|
||||
#include <ftxui/dom/elements.hpp> // for operator|, graph, separator, color, Element, vbox, flex, inverted, Fit, hbox, size, border, GREATER_THAN, HEIGHT
|
||||
#include <ftxui/dom/elements.hpp> // for graph, operator|, separator, color, Element, vbox, flex, inverted, operator|=, Fit, hbox, size, border, GREATER_THAN, HEIGHT
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <functional> // for ref, reference_wrapper
|
||||
#include <iostream> // for cout, ostream
|
||||
#include <memory> // for shared_ptr
|
||||
#include <string> // for operator<<, string
|
||||
#include <thread> // for sleep_for
|
||||
#include <vector> // for vector
|
||||
@@ -13,15 +14,15 @@
|
||||
|
||||
class Graph {
|
||||
public:
|
||||
std::vector<int> operator()(int width, int height) {
|
||||
std::vector<int> operator()(int width, int height) const {
|
||||
std::vector<int> output(width);
|
||||
for (int i = 0; i < width; ++i) {
|
||||
float v = 0;
|
||||
v += 0.1f * sin((i + shift) * 0.1f);
|
||||
v += 0.2f * sin((i + shift + 10) * 0.15f);
|
||||
v += 0.1f * sin((i + shift) * 0.03f);
|
||||
v *= height;
|
||||
v += 0.5f * height;
|
||||
v += 0.1f * sin((i + shift) * 0.1f); // NOLINT
|
||||
v += 0.2f * sin((i + shift + 10) * 0.15f); // NOLINT
|
||||
v += 0.1f * sin((i + shift) * 0.03f); // NOLINT
|
||||
v *= height; // NOLINT
|
||||
v += 0.5f * height; // NOLINT
|
||||
output[i] = static_cast<int>(v);
|
||||
}
|
||||
return output;
|
||||
@@ -37,7 +38,7 @@ std::vector<int> triangle(int width, int height) {
|
||||
return output;
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int main() {
|
||||
using namespace ftxui;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
@@ -45,23 +46,26 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
std::string reset_position;
|
||||
for (int i = 0;; ++i) {
|
||||
auto document =
|
||||
hbox({
|
||||
vbox({
|
||||
graph(std::ref(my_graph)),
|
||||
separator(),
|
||||
graph(triangle) | inverted,
|
||||
}) | flex,
|
||||
auto document = hbox({
|
||||
vbox({
|
||||
graph(std::ref(my_graph)),
|
||||
separator(),
|
||||
vbox({
|
||||
graph(std::ref(my_graph)) | color(Color::BlueLight),
|
||||
separator(),
|
||||
graph(std::ref(my_graph)) | color(Color::RedLight),
|
||||
separator(),
|
||||
graph(std::ref(my_graph)) | color(Color::YellowLight),
|
||||
}) | flex,
|
||||
}) |
|
||||
border | size(HEIGHT, GREATER_THAN, 40);
|
||||
graph(triangle) | inverted,
|
||||
}) | flex,
|
||||
separator(),
|
||||
vbox({
|
||||
graph(std::ref(my_graph)) | color(Color::BlueLight),
|
||||
separator(),
|
||||
graph(std::ref(my_graph)) | color(Color::RedLight),
|
||||
separator(),
|
||||
graph(std::ref(my_graph)) | color(Color::YellowLight),
|
||||
}) | flex,
|
||||
});
|
||||
|
||||
document |= border;
|
||||
|
||||
const int min_width = 40;
|
||||
document |= size(HEIGHT, GREATER_THAN, min_width);
|
||||
|
||||
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
|
||||
Render(screen, document);
|
||||
@@ -69,7 +73,8 @@ int main(int argc, const char* argv[]) {
|
||||
screen.Print();
|
||||
reset_position = screen.ResetPosition();
|
||||
|
||||
std::this_thread::sleep_for(0.03s);
|
||||
const auto sleep_time = 0.03s;
|
||||
std::this_thread::sleep_for(sleep_time);
|
||||
my_graph.shift++;
|
||||
}
|
||||
|
||||
|
@@ -1,16 +1,14 @@
|
||||
#include <stddef.h> // for size_t
|
||||
#include <stdio.h> // for getchar
|
||||
#include <ftxui/dom/elements.hpp> // for operator|, size, Element, text, hcenter, Decorator, Fit, WIDTH, hflow, window, EQUAL, GREATER_THAN, HEIGHT, bold, border, dim, LESS_THAN
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator, shared_ptr
|
||||
#include <string> // for operator+, to_string, char_traits, string
|
||||
#include <string> // for allocator, char_traits, operator+, to_string, string
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
auto make_box = [](size_t dimx, size_t dimy) {
|
||||
auto make_box = [](int dimx, int dimy) {
|
||||
std::string title = std::to_string(dimx) + "x" + std::to_string(dimy);
|
||||
return window(text(title) | hcenter | bold,
|
||||
text("content") | hcenter | dim) |
|
||||
|
@@ -1,11 +1,10 @@
|
||||
#include <chrono> // for operator""s, chrono_literals
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <ftxui/screen/screen.hpp> // for Screen
|
||||
#include <iostream> // for cout, ostream
|
||||
#include <memory> // for allocator, shared_ptr
|
||||
#include <string> // for operator<<, string
|
||||
#include <string> // for allocator, operator<<, string
|
||||
#include <thread> // for sleep_for
|
||||
|
||||
#include "ftxui/dom/elements.hpp" // for paragraph, text, operator|, Element, border, color, hflow, spinner, vbox, bold, dim, underlined
|
||||
#include "ftxui/dom/elements.hpp" // for paragraph, text, operator|, Element, border, Fit, color, hflow, spinner, vbox, bold, dim, underlined
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for ftxui
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::Red
|
||||
|
26
examples/dom/linear_gradient.cpp
Normal file
26
examples/dom/linear_gradient.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <ftxui/dom/elements.hpp> // for bgcolor, operator|, operator|=, text, center, Element
|
||||
#include <ftxui/dom/linear_gradient.hpp> // for LinearGradient::Stop, LinearGradient
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator, shared_ptr
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::DeepPink1, Color::DeepSkyBlue1, Color::Yellow, ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
auto document = text("gradient") | center;
|
||||
|
||||
document |= bgcolor(LinearGradient()
|
||||
.Angle(45)
|
||||
.Stop(Color::DeepPink1)
|
||||
.Stop(Color::DeepSkyBlue1));
|
||||
auto screen = Screen::Create(Dimension::Full(), Dimension::Full());
|
||||
Render(screen, document);
|
||||
screen.Print();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copyright 2023 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -2,7 +2,7 @@
|
||||
#include <ftxui/dom/elements.hpp> // for operator|, text, Element, hbox, bold, color, filler, separator, vbox, window, gauge, Fit, size, dim, EQUAL, WIDTH
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <iostream> // for cout, endl, ostream
|
||||
#include <list> // for list, operator!=, _List_iterator, _List_iterator<>::_Self
|
||||
#include <list> // for list, operator==, _List_iterator, _List_iterator<>::_Self
|
||||
#include <memory> // for allocator, shared_ptr, allocator_traits<>::value_type
|
||||
#include <string> // for string, operator<<, to_string
|
||||
#include <thread> // for sleep_for
|
||||
@@ -41,7 +41,7 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
int remaining_threads = 12;
|
||||
|
||||
int nb_queued = remaining_tasks.size();
|
||||
int nb_queued = (int)remaining_tasks.size();
|
||||
int nb_active = 0;
|
||||
int nb_done = 0;
|
||||
|
||||
|
@@ -16,6 +16,12 @@ int main(int argc, const char* argv[]) {
|
||||
hbox(text("left"), separatorLight(), text("right")),
|
||||
}) | borderLight,
|
||||
|
||||
vbox({
|
||||
text("separatorDashed"),
|
||||
separatorDashed(),
|
||||
hbox(text("left"), separatorDashed(), text("right")),
|
||||
}) | borderDashed,
|
||||
|
||||
vbox({
|
||||
text("separatorHeavy"),
|
||||
separatorHeavy(),
|
||||
|
@@ -17,7 +17,7 @@ int main(int argc, const char* argv[]) {
|
||||
std::string reset_position;
|
||||
for (int index = 0; index < 200; ++index) {
|
||||
std::vector<Element> entries;
|
||||
for (int i = 0; i < 22; ++i) {
|
||||
for (int i = 0; i < 23; ++i) {
|
||||
if (i != 0)
|
||||
entries.push_back(separator());
|
||||
entries.push_back( //
|
||||
|
@@ -1,59 +1,60 @@
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator
|
||||
#include <ftxui/dom/linear_gradient.hpp> // for LinearGradient
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator
|
||||
|
||||
#include "ftxui/dom/elements.hpp" // for text, bgcolor, color, vbox, Fit, filler, hbox
|
||||
#include "ftxui/dom/elements.hpp" // for text, bgcolor, color, vbox, filler, Fit, hbox
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/box.hpp" // for 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
|
||||
#include "ftxui/screen/color.hpp" // for Color, operator""_rgb, Color::Black, Color::Blue, Color::BlueLight, Color::Cyan, Color::CyanLight, Color::DeepSkyBlue4, Color::Default, Color::GrayDark, Color::GrayLight, Color::Green, Color::GreenLight, Color::Magenta, Color::MagentaLight, Color::Red, Color::RedLight, Color::SkyBlue1, Color::White, Color::Yellow, Color::YellowLight, ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
// clang-format off
|
||||
auto document =
|
||||
hbox(
|
||||
vbox(
|
||||
color(Color::Default, text("Default")),
|
||||
color(Color::Black, text("Black")),
|
||||
color(Color::GrayDark, text("GrayDark")),
|
||||
color(Color::GrayLight, text("GrayLight")),
|
||||
color(Color::White, text("White")),
|
||||
color(Color::Blue, text("Blue")),
|
||||
color(Color::BlueLight, text("BlueLight")),
|
||||
color(Color::Cyan, text("Cyan")),
|
||||
color(Color::CyanLight, text("CyanLight")),
|
||||
color(Color::Green, text("Green")),
|
||||
color(Color::GreenLight, text("GreenLight")),
|
||||
color(Color::Magenta, text("Magenta")),
|
||||
color(Color::MagentaLight, text("MagentaLight")),
|
||||
color(Color::Red, text("Red")),
|
||||
color(Color::RedLight, text("RedLight")),
|
||||
color(Color::Yellow, text("Yellow")),
|
||||
color(Color::YellowLight, text("YellowLight")),
|
||||
color(0x66ff66_rgb, text("Phosphor"))
|
||||
),
|
||||
vbox(
|
||||
bgcolor(Color::Default, text("Default")),
|
||||
bgcolor(Color::Black, text("Black")),
|
||||
bgcolor(Color::GrayDark, text("GrayDark")),
|
||||
bgcolor(Color::GrayLight, text("GrayLight")),
|
||||
bgcolor(Color::White, text("White")),
|
||||
bgcolor(Color::Blue, text("Blue")),
|
||||
bgcolor(Color::BlueLight, text("BlueLight")),
|
||||
bgcolor(Color::Cyan, text("Cyan")),
|
||||
bgcolor(Color::CyanLight, text("CyanLight")),
|
||||
bgcolor(Color::Green, text("Green")),
|
||||
bgcolor(Color::GreenLight, text("GreenLight")),
|
||||
bgcolor(Color::Magenta, text("Magenta")),
|
||||
bgcolor(Color::MagentaLight, text("MagentaLight")),
|
||||
bgcolor(Color::Red, text("Red")),
|
||||
bgcolor(Color::RedLight, text("RedLight")),
|
||||
bgcolor(Color::Yellow, text("Yellow")),
|
||||
bgcolor(Color::YellowLight, text("YellowLight")),
|
||||
bgcolor(0x66ff66_rgb, text("Phosphor"))
|
||||
),
|
||||
filler()
|
||||
);
|
||||
// clang-format on
|
||||
auto document = hbox({
|
||||
vbox({
|
||||
color(Color::Default, text("Default")),
|
||||
color(Color::Black, text("Black")),
|
||||
color(Color::GrayDark, text("GrayDark")),
|
||||
color(Color::GrayLight, text("GrayLight")),
|
||||
color(Color::White, text("White")),
|
||||
color(Color::Blue, text("Blue")),
|
||||
color(Color::BlueLight, text("BlueLight")),
|
||||
color(Color::Cyan, text("Cyan")),
|
||||
color(Color::CyanLight, text("CyanLight")),
|
||||
color(Color::Green, text("Green")),
|
||||
color(Color::GreenLight, text("GreenLight")),
|
||||
color(Color::Magenta, text("Magenta")),
|
||||
color(Color::MagentaLight, text("MagentaLight")),
|
||||
color(Color::Red, text("Red")),
|
||||
color(Color::RedLight, text("RedLight")),
|
||||
color(Color::Yellow, text("Yellow")),
|
||||
color(Color::YellowLight, text("YellowLight")),
|
||||
color(0x66ff66_rgb, text("Phosphor")),
|
||||
color(LinearGradient(Color::SkyBlue1, Color::DeepSkyBlue4),
|
||||
text("Skyblue to DeepSkyBlue")),
|
||||
}),
|
||||
vbox({
|
||||
bgcolor(Color::Default, text("Default")),
|
||||
bgcolor(Color::Black, text("Black")),
|
||||
bgcolor(Color::GrayDark, text("GrayDark")),
|
||||
bgcolor(Color::GrayLight, text("GrayLight")),
|
||||
bgcolor(Color::White, text("White")),
|
||||
bgcolor(Color::Blue, text("Blue")),
|
||||
bgcolor(Color::BlueLight, text("BlueLight")),
|
||||
bgcolor(Color::Cyan, text("Cyan")),
|
||||
bgcolor(Color::CyanLight, text("CyanLight")),
|
||||
bgcolor(Color::Green, text("Green")),
|
||||
bgcolor(Color::GreenLight, text("GreenLight")),
|
||||
bgcolor(Color::Magenta, text("Magenta")),
|
||||
bgcolor(Color::MagentaLight, text("MagentaLight")),
|
||||
bgcolor(Color::Red, text("Red")),
|
||||
bgcolor(Color::RedLight, text("RedLight")),
|
||||
bgcolor(Color::Yellow, text("Yellow")),
|
||||
bgcolor(Color::YellowLight, text("YellowLight")),
|
||||
bgcolor(0x66ff66_rgb, text("Phosphor")),
|
||||
bgcolor(LinearGradient(Color::SkyBlue1, Color::DeepSkyBlue4),
|
||||
text("Skyblue to DeepSkyBlue")),
|
||||
}),
|
||||
filler(),
|
||||
});
|
||||
|
||||
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
|
||||
Render(screen, document);
|
||||
|
@@ -10,14 +10,16 @@ int main(int argc, const char* argv[]) {
|
||||
// clang-format off
|
||||
auto document =
|
||||
hbox({
|
||||
text("normal") , text(" ") ,
|
||||
text("bold") | bold , text(" ") ,
|
||||
text("dim") | dim , text(" ") ,
|
||||
text("inverted") | inverted , text(" ") ,
|
||||
text("underlined")| underlined , text(" ") ,
|
||||
text("blink") | blink , text(" ") ,
|
||||
text("color") | color(Color::Blue) , text(" ") ,
|
||||
text("bgcolor") | bgcolor(Color::Blue),
|
||||
text("normal") , text(" ") ,
|
||||
text("bold") | bold , text(" ") ,
|
||||
text("dim") | dim , text(" ") ,
|
||||
text("inverted") | inverted , text(" ") ,
|
||||
text("underlined") | underlined , text(" ") ,
|
||||
text("underlinedDouble") | underlinedDouble , text(" ") ,
|
||||
text("blink") | blink , text(" ") ,
|
||||
text("strikethrough") | strikethrough , text(" ") ,
|
||||
text("color") | color(Color::Blue) , text(" ") ,
|
||||
text("bgcolor") | bgcolor(Color::Blue) ,
|
||||
});
|
||||
// clang-format on
|
||||
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
|
||||
|
25
examples/dom/style_strikethrough.cpp
Normal file
25
examples/dom/style_strikethrough.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <ftxui/dom/elements.hpp> // for text, operator|, strikethrough, Fit, hbox, Element
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
auto document = //
|
||||
hbox({
|
||||
text("This text is "),
|
||||
text("strikethrough") | strikethrough,
|
||||
text(". Do you like it?"),
|
||||
});
|
||||
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
|
||||
Render(screen, document);
|
||||
screen.Print();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
25
examples/dom/style_underlined_double.cpp
Normal file
25
examples/dom/style_underlined_double.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <ftxui/dom/elements.hpp> // for text, operator|, underlinedDouble, Fit, hbox, Element
|
||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
||||
#include <memory> // for allocator
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
auto document = //
|
||||
hbox({
|
||||
text("This text is "),
|
||||
text("underlinedDouble") | underlinedDouble,
|
||||
text(". Do you like it?"),
|
||||
});
|
||||
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
|
||||
Render(screen, document);
|
||||
screen.Print();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -1,16 +1,14 @@
|
||||
#include <stddef.h> // for size_t
|
||||
#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 allocator, shared_ptr
|
||||
#include <string> // for operator+, to_string, char_traits, string
|
||||
#include <string> // for allocator, char_traits, operator+, to_string, string
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for ftxui
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
using namespace ftxui;
|
||||
auto make_box = [](size_t dimx, size_t dimy) {
|
||||
auto make_box = [](int dimx, int dimy) {
|
||||
std::string title = std::to_string(dimx) + "x" + std::to_string(dimy);
|
||||
return window(text(title) | hcenter | bold,
|
||||
text("content") | hcenter | dim) |
|
||||
|
@@ -1,25 +1,32 @@
|
||||
#include <ftxui/dom/elements.hpp> // for operator|, color, Element, bgcolor, graph, border
|
||||
#include <stdlib.h> // for EXIT_SUCCESS
|
||||
#include <ftxui/dom/elements.hpp> // for operator|=, Element, bgcolor, color, graph, border
|
||||
#include <ftxui/screen/screen.hpp> // for Fixed, Screen
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::DarkBlue, Color::Green, Color::Red, ftxui
|
||||
#include "ftxui/dom/node.hpp" // for Render
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::DarkBlue, Color::Red, ftxui
|
||||
|
||||
int main(void) {
|
||||
int main() {
|
||||
using namespace ftxui;
|
||||
Element document = graph([](int x, int y) {
|
||||
std::vector<int> result(x, 0);
|
||||
for (int i{0}; i < x; ++i) {
|
||||
result[i] = ((3 * i) / 2) % y;
|
||||
}
|
||||
return result;
|
||||
}) |
|
||||
color(Color::Red) | border | color(Color::Green) |
|
||||
bgcolor(Color::DarkBlue);
|
||||
std::vector<int> result(x, 0);
|
||||
for (int i{0}; i < x; ++i) {
|
||||
result[i] = ((3 * i) / 2) % y;
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
auto screen = Screen::Create(Dimension::Fixed(80), Dimension::Fixed(10));
|
||||
document |= color(Color::Red);
|
||||
document |= bgcolor(Color::DarkBlue);
|
||||
document |= border;
|
||||
|
||||
const int width = 80;
|
||||
const int height = 10;
|
||||
auto screen =
|
||||
Screen::Create(Dimension::Fixed(width), Dimension::Fixed(height));
|
||||
Render(screen, document);
|
||||
screen.Print();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
|
@@ -2,8 +2,22 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>FTXUI examples WebAssembly</title>
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm@4.11.0/lib/xterm.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm@4.18.0/lib/xterm.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-webgl@0.11.4/lib/xterm-addon-webgl.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.5.0/lib/xterm-addon-fit.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@4.11.0/css/xterm.css"></link>
|
||||
<!--Add COOP/COEP via a ServiceWorker to use SharedArrayBuffer-->
|
||||
<script>
|
||||
if ("serviceWorker" in navigator && !window.crossOriginIsolated) {
|
||||
navigator.serviceWorker.register(new URL("./sw.js", location.href)).then(
|
||||
registration => {
|
||||
if (registration.active && !navigator.serviceWorker.controller) {
|
||||
window.location.reload();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script id="example_script"></script>
|
||||
@@ -43,12 +57,12 @@
|
||||
});
|
||||
|
||||
let stdin_buffer = [];
|
||||
let stdin = () => {
|
||||
const stdin = () => {
|
||||
return stdin_buffer.shift() || 0;
|
||||
}
|
||||
|
||||
stdout_buffer = [];
|
||||
let stdout = code => {
|
||||
let stdout_buffer = [];
|
||||
const stdout = code => {
|
||||
if (code == 0) {
|
||||
term.write(new Uint8Array(stdout_buffer));
|
||||
stdout_buffer = [];
|
||||
@@ -56,20 +70,53 @@
|
||||
stdout_buffer.push(code)
|
||||
}
|
||||
}
|
||||
let stderr = code => console.log(code);
|
||||
var term = new Terminal();
|
||||
term.open(document.querySelector('#terminal'));
|
||||
term.resize(140,43);
|
||||
let stderrbuffer = [];
|
||||
const stderr = code => {
|
||||
if (code == 0 || code == 10) {
|
||||
console.error(String.fromCodePoint(...stderrbuffer));
|
||||
stderrbuffer = [];
|
||||
} else {
|
||||
stderrbuffer.push(code)
|
||||
}
|
||||
}
|
||||
const term = new Terminal();
|
||||
const term_element = document.querySelector('#terminal');
|
||||
term.open(term_element);
|
||||
|
||||
const webgl_addon = new (WebglAddon.WebglAddon)();
|
||||
term.loadAddon(webgl_addon);
|
||||
|
||||
const onBinary = e => {
|
||||
for(c of e)
|
||||
stdin_buffer.push(c.charCodeAt(0));
|
||||
}
|
||||
term.onBinary(onBinary);
|
||||
term.onData(onBinary)
|
||||
term.resize(140,43);
|
||||
window.Module = {
|
||||
preRun: () => { FS.init(stdin, stdout, stderr); },
|
||||
preRun: () => {
|
||||
FS.init(stdin, stdout, stderr);
|
||||
},
|
||||
postRun: [],
|
||||
onRuntimeInitialized: () => {},
|
||||
onRuntimeInitialized: () => {
|
||||
if (window.Module._ftxui_on_resize == undefined)
|
||||
return;
|
||||
|
||||
const fit_addon = new (FitAddon.FitAddon)();
|
||||
term.loadAddon(fit_addon);
|
||||
fit_addon.fit();
|
||||
const resize_handler = () => {
|
||||
const {cols, rows} = fit_addon.proposeDimensions();
|
||||
term.resize(cols, rows);
|
||||
window.Module._ftxui_on_resize(cols, rows);
|
||||
};
|
||||
const resize_observer = new ResizeObserver(resize_handler);
|
||||
resize_observer.observe(term_element);
|
||||
resize_handler();
|
||||
|
||||
// Disable scrollbar
|
||||
term.write('\x1b[?47h')
|
||||
},
|
||||
};
|
||||
|
||||
const words = example.split('/')
|
||||
@@ -78,6 +125,7 @@
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
body {
|
||||
background-color:#EEE;
|
||||
padding:20px;
|
||||
@@ -112,9 +160,11 @@
|
||||
}
|
||||
|
||||
#terminal {
|
||||
padding:10px;
|
||||
width:100%;
|
||||
height: 500px;
|
||||
height: calc(clamp(200px, 100vh - 300px, 900px));
|
||||
overflow: hidden;
|
||||
border:none;
|
||||
background-color:black;
|
||||
padding:auto;
|
||||
}
|
||||
|
||||
|
25
examples/sw.js
Normal file
25
examples/sw.js
Normal file
@@ -0,0 +1,25 @@
|
||||
// sw.js
|
||||
self.addEventListener("install", () => self.skipWaiting());
|
||||
self.addEventListener("activate", e => e.waitUntil(self.clients.claim()));
|
||||
self.addEventListener("fetch", e => {
|
||||
if (e.request.mode != 'navigate' &&
|
||||
!e.request.url.includes(".worker.js")) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.respondWith((async () => {
|
||||
const response = await fetch(e.request);
|
||||
|
||||
const newHeaders = new Headers(response.headers);
|
||||
newHeaders.set("Cross-Origin-Embedder-Policy", "require-corp");
|
||||
newHeaders.set("Cross-Origin-Opener-Policy", "same-origin");
|
||||
|
||||
const moddedResponse = new Response(response.body, {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: newHeaders,
|
||||
});
|
||||
|
||||
return moddedResponse;
|
||||
})());
|
||||
});
|
43
flake.lock
generated
Normal file
43
flake.lock
generated
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1678901627,
|
||||
"narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1679734080,
|
||||
"narHash": "sha256-z846xfGLlon6t9lqUzlNtBOmsgQLQIZvR6Lt2dImk1M=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "dbf5322e93bcc6cfc52268367a8ad21c09d76fea",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
61
flake.nix
Normal file
61
flake.nix
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
description = "C++ Functional Terminal User Interface library";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = {self, nixpkgs, flake-utils}:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let pkgs = import nixpkgs { inherit system; }; in
|
||||
{
|
||||
packages.ftxui = pkgs.stdenv.mkDerivation rec {
|
||||
pname = "ftxui";
|
||||
version = "v4.0.0";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "ArthurSonzogni";
|
||||
repo = "FTXUI";
|
||||
rev = version;
|
||||
sha256 = "sha256-3kAhHDUwzwdvHc8JZAcA14tGqa6w69qrN1JXhSxNBQY=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
pkgs.cmake
|
||||
];
|
||||
|
||||
cmakeFlags = [
|
||||
"-DFTXUI_ENABLE_INSTALL=ON"
|
||||
"-DFTXUI_BUILD_EXAMPLES=OFF"
|
||||
"-DFTXUI_BUILD_TESTS=OFF"
|
||||
"-DFTXUI_BUILD_DOCS=OFF"
|
||||
"-DCMAKE_BUILD_TYPE=Release"
|
||||
];
|
||||
|
||||
meta = {
|
||||
homepage = "https://arthursonzogni.github.io/FTXUI/";
|
||||
description = "C++ Functional Terminal User Interface.";
|
||||
longDescription = ''
|
||||
Functional Terminal (X) User interface
|
||||
|
||||
A simple C++ library for terminal based user interfaces!
|
||||
Feature
|
||||
- Functional style. Inspired by [1] and React
|
||||
- Simple and elegant syntax (in my opinion)
|
||||
- Keyboard & mouse navigation.
|
||||
- Support for UTF8 and fullwidth chars (→ 测试)
|
||||
- Support for animations. Demo 1, Demo 2
|
||||
- Support for drawing. Demo
|
||||
- No dependencies
|
||||
- Cross platform: Linux/MacOS (main target), WebAssembly, Windows (Thanks to contributors!).
|
||||
- Learn by examples, and tutorials
|
||||
- Multiple packages: CMake FetchContent (preferred), vcpkg, pkgbuild, conan, nix, etc...
|
||||
- Good practises: documentation, tests, fuzzers, performance tests, automated CI, automated packaging, etc...
|
||||
'';
|
||||
license = pkgs.lib.licenses.mit;
|
||||
platforms = pkgs.lib.platforms.all;
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
9
ftxui.pc.in
Normal file
9
ftxui.pc.in
Normal file
@@ -0,0 +1,9 @@
|
||||
prefix="@CMAKE_INSTALL_PREFIX@"
|
||||
libdir="@CMAKE_INSTALL_FULL_LIBDIR@"
|
||||
includedir="@CMAKE_INSTALL_FULL_INCLUDEDIR@"
|
||||
|
||||
Name: @PROJECT_NAME@
|
||||
Description: @CMAKE_PROJECT_DESCRIPTION@
|
||||
Version: @PROJECT_VERSION@
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -lftxui-component -lftxui-dom -lftxui-screen
|
119
include/ftxui/component/animation.hpp
Normal file
119
include/ftxui/component/animation.hpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#ifndef FTXUI_ANIMATION_HPP
|
||||
#define FTXUI_ANIMATION_HPP
|
||||
|
||||
#include <chrono> // for milliseconds, duration, steady_clock, time_point
|
||||
#include <functional> // for function
|
||||
|
||||
#include "ftxui/component/event.hpp"
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
namespace animation {
|
||||
// Components who haven't completed their animation can call this function to
|
||||
// request a new frame to be drawn later.
|
||||
//
|
||||
// When there is no new events and no animations to complete, no new frame is
|
||||
// drawn.
|
||||
void RequestAnimationFrame();
|
||||
|
||||
using Clock = std::chrono::steady_clock;
|
||||
using TimePoint = std::chrono::time_point<Clock>;
|
||||
using Duration = std::chrono::duration<double>;
|
||||
|
||||
// Parameter of Component::OnAnimation(param).
|
||||
class Params {
|
||||
public:
|
||||
Params(Duration duration) : duration_(duration) {}
|
||||
|
||||
/// The duration this animation step represents.
|
||||
Duration duration() const { return duration_; }
|
||||
|
||||
private:
|
||||
Duration duration_;
|
||||
};
|
||||
|
||||
namespace easing {
|
||||
using Function = std::function<float(float)>;
|
||||
// Linear interpolation (no easing)
|
||||
float Linear(float p);
|
||||
|
||||
// Quadratic easing; p^2
|
||||
float QuadraticIn(float p);
|
||||
float QuadraticOut(float p);
|
||||
float QuadraticInOut(float p);
|
||||
|
||||
// Cubic easing; p^3
|
||||
float CubicIn(float p);
|
||||
float CubicOut(float p);
|
||||
float CubicInOut(float p);
|
||||
|
||||
// Quartic easing; p^4
|
||||
float QuarticIn(float p);
|
||||
float QuarticOut(float p);
|
||||
float QuarticInOut(float p);
|
||||
|
||||
// Quintic easing; p^5
|
||||
float QuinticIn(float p);
|
||||
float QuinticOut(float p);
|
||||
float QuinticInOut(float p);
|
||||
|
||||
// Sine wave easing; sin(p * PI/2)
|
||||
float SineIn(float p);
|
||||
float SineOut(float p);
|
||||
float SineInOut(float p);
|
||||
|
||||
// Circular easing; sqrt(1 - p^2)
|
||||
float CircularIn(float p);
|
||||
float CircularOut(float p);
|
||||
float CircularInOut(float p);
|
||||
|
||||
// Exponential easing, base 2
|
||||
float ExponentialIn(float p);
|
||||
float ExponentialOut(float p);
|
||||
float ExponentialInOut(float p);
|
||||
|
||||
// Exponentially-damped sine wave easing
|
||||
float ElasticIn(float p);
|
||||
float ElasticOut(float p);
|
||||
float ElasticInOut(float p);
|
||||
|
||||
// Overshooting cubic easing;
|
||||
float BackIn(float p);
|
||||
float BackOut(float p);
|
||||
float BackInOut(float p);
|
||||
|
||||
// Exponentially-decaying bounce easing
|
||||
float BounceIn(float p);
|
||||
float BounceOut(float p);
|
||||
float BounceInOut(float p);
|
||||
} // namespace easing
|
||||
|
||||
class Animator {
|
||||
public:
|
||||
Animator(float* from,
|
||||
float to = 0.f,
|
||||
Duration duration = std::chrono::milliseconds(250),
|
||||
easing::Function easing_function = easing::Linear,
|
||||
Duration delay = std::chrono::milliseconds(0));
|
||||
|
||||
void OnAnimation(Params&);
|
||||
|
||||
float to() const { return to_; }
|
||||
|
||||
private:
|
||||
float* value_;
|
||||
float from_;
|
||||
float to_;
|
||||
Duration duration_;
|
||||
easing::Function easing_function_;
|
||||
Duration current_;
|
||||
};
|
||||
|
||||
} // namespace animation
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* end of include guard: FTXUI_ANIMATION_HPP */
|
||||
|
||||
// Copyright 2022 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -4,12 +4,13 @@
|
||||
#include <functional> // for function
|
||||
#include <memory> // for make_shared, shared_ptr
|
||||
#include <string> // for wstring
|
||||
#include <utility> // for forward
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/component/component_base.hpp" // for Component, Components
|
||||
#include "ftxui/component/component_options.hpp" // for ButtonOption, CheckboxOption, InputOption, MenuOption, RadioboxOption, ToggleOption
|
||||
#include "ftxui/dom/elements.hpp" // for Element
|
||||
#include "ftxui/util/ref.hpp" // for Ref, ConstStringRef, ConstStringListRef, StringRef
|
||||
#include "ftxui/component/component_base.hpp" // for Component, Components
|
||||
#include "ftxui/component/component_options.hpp" // for ButtonOption, CheckboxOption, MenuOption
|
||||
#include "ftxui/dom/elements.hpp" // for Element
|
||||
#include "ftxui/util/ref.hpp" // for ConstRef, Ref, ConstStringRef, ConstStringListRef, StringRef
|
||||
|
||||
namespace ftxui {
|
||||
struct ButtonOption;
|
||||
@@ -18,14 +19,21 @@ struct Event;
|
||||
struct InputOption;
|
||||
struct MenuOption;
|
||||
struct RadioboxOption;
|
||||
struct ToggleOption;
|
||||
struct MenuEntryOption;
|
||||
|
||||
template <class T, class... Args>
|
||||
std::shared_ptr<T> Make(Args&&... args) {
|
||||
return std::make_shared<T>(args...);
|
||||
return std::make_shared<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// Pipe operator to decorate components.
|
||||
using ComponentDecorator = std::function<Component(Component)>;
|
||||
using ElementDecorator = std::function<Element(Element)>;
|
||||
Component operator|(Component component, ComponentDecorator decorator);
|
||||
Component operator|(Component component, ElementDecorator decorator);
|
||||
Component& operator|=(Component& component, ComponentDecorator decorator);
|
||||
Component& operator|=(Component& component, ElementDecorator decorator);
|
||||
|
||||
namespace Container {
|
||||
Component Vertical(Components children);
|
||||
Component Vertical(Components children, int* selector);
|
||||
@@ -37,43 +45,86 @@ Component Tab(Components children, int* selector);
|
||||
|
||||
Component Button(ConstStringRef label,
|
||||
std::function<void()> on_click,
|
||||
Ref<ButtonOption> = {});
|
||||
Ref<ButtonOption> = ButtonOption::Simple());
|
||||
|
||||
Component Checkbox(ConstStringRef label,
|
||||
bool* checked,
|
||||
Ref<CheckboxOption> option = {});
|
||||
Ref<CheckboxOption> option = CheckboxOption::Simple());
|
||||
|
||||
Component Input(StringRef content,
|
||||
ConstStringRef placeholder,
|
||||
Ref<InputOption> option = {});
|
||||
|
||||
Component Menu(ConstStringListRef entries,
|
||||
int* selected_,
|
||||
Ref<MenuOption> = {});
|
||||
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,
|
||||
Ref<ToggleOption> option = {});
|
||||
template <class T> // T = {int, float, long}
|
||||
Component Slider(ConstStringRef label, T* value, T min, T max, T increment);
|
||||
Component Toggle(ConstStringListRef entries, int* selected);
|
||||
|
||||
// General slider constructor:
|
||||
template <typename T>
|
||||
Component Slider(SliderOption<T> options = {});
|
||||
|
||||
// Shorthand without the `SliderOption` constructor:
|
||||
Component Slider(ConstStringRef label,
|
||||
Ref<int> value,
|
||||
ConstRef<int> min = 0,
|
||||
ConstRef<int> max = 100,
|
||||
ConstRef<int> increment = 5);
|
||||
Component Slider(ConstStringRef label,
|
||||
Ref<float> value,
|
||||
ConstRef<float> min = 0.f,
|
||||
ConstRef<float> max = 100.f,
|
||||
ConstRef<float> increment = 5.f);
|
||||
Component Slider(ConstStringRef label,
|
||||
Ref<long> value,
|
||||
ConstRef<long> min = 0l,
|
||||
ConstRef<long> max = 100l,
|
||||
ConstRef<long> increment = 5l);
|
||||
|
||||
Component ResizableSplitLeft(Component main, Component back, int* main_size);
|
||||
Component ResizableSplitRight(Component main, Component back, int* main_size);
|
||||
Component ResizableSplitTop(Component main, Component back, int* main_size);
|
||||
Component ResizableSplitBottom(Component main, Component back, int* main_size);
|
||||
|
||||
Component Renderer(Component child, std::function<Element()>);
|
||||
Component Renderer(std::function<Element()>);
|
||||
Component Renderer(std::function<Element(bool /* focused */)>);
|
||||
ComponentDecorator Renderer(ElementDecorator);
|
||||
|
||||
Component CatchEvent(Component child, std::function<bool(Event)>);
|
||||
ComponentDecorator CatchEvent(std::function<bool(Event)> on_event);
|
||||
|
||||
Component Maybe(Component, const bool* show);
|
||||
Component Maybe(Component, std::function<bool()>);
|
||||
ComponentDecorator Maybe(const bool* show);
|
||||
ComponentDecorator Maybe(std::function<bool()>);
|
||||
|
||||
Component Modal(Component main, Component modal, const bool* show_modal);
|
||||
ComponentDecorator Modal(Component modal, const bool* show_modal);
|
||||
|
||||
Component Collapsible(ConstStringRef label,
|
||||
Component child,
|
||||
Ref<bool> show = false);
|
||||
|
||||
} // namespace ftxui
|
||||
Component Hoverable(Component component, bool* hover);
|
||||
Component Hoverable(Component component,
|
||||
std::function<void()> on_enter,
|
||||
std::function<void()> on_leave);
|
||||
Component Hoverable(Component component, //
|
||||
std::function<void(bool)> on_change);
|
||||
ComponentDecorator Hoverable(bool* hover);
|
||||
ComponentDecorator Hoverable(std::function<void()> on_enter,
|
||||
std::function<void()> on_leave);
|
||||
ComponentDecorator Hoverable(std::function<void(bool)> on_change);
|
||||
|
||||
// Include component using the old deprecated wstring.
|
||||
#include "ftxui/component/deprecated.hpp"
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* end of include guard: FTXUI_COMPONENT_HPP */
|
||||
|
||||
|
@@ -13,6 +13,10 @@ class Delegate;
|
||||
class Focus;
|
||||
struct Event;
|
||||
|
||||
namespace animation {
|
||||
class Params;
|
||||
} // namespace animation
|
||||
|
||||
class ComponentBase;
|
||||
using Component = std::shared_ptr<ComponentBase>;
|
||||
using Components = std::vector<Component>;
|
||||
@@ -42,6 +46,9 @@ class ComponentBase {
|
||||
// Returns whether the event was handled or not.
|
||||
virtual bool OnEvent(Event);
|
||||
|
||||
// Handle an animation step.
|
||||
virtual void OnAnimation(animation::Params& params);
|
||||
|
||||
// Focus management ----------------------------------------------------------
|
||||
//
|
||||
// If this component contains children, this indicates which one is active,
|
||||
|
@@ -1,58 +1,136 @@
|
||||
#ifndef FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP
|
||||
#define FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP
|
||||
|
||||
#include <ftxui/dom/elements.hpp>
|
||||
#include <ftxui/util/ref.hpp>
|
||||
#include <chrono> // for milliseconds
|
||||
#include <ftxui/component/animation.hpp> // for Duration, QuadraticInOut, Function
|
||||
#include <ftxui/dom/elements.hpp> // for Element, GaugeDirection, GaugeDirection::Right
|
||||
#include <ftxui/util/ref.hpp> // for Ref, ConstRef
|
||||
#include <functional> // for function
|
||||
#include <optional> // for optional
|
||||
#include <string> // for string
|
||||
|
||||
#include "ftxui/screen/color.hpp" // for Color, Color::GrayDark, Color::White
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
/// @brief Option for the Menu component.
|
||||
/// @brief arguments for |ButtonOption::transform|, |CheckboxOption::transform|,
|
||||
/// |Radiobox::transform|, |MenuEntryOption::transform|,
|
||||
/// |MenuOption::transform|.
|
||||
struct EntryState {
|
||||
std::string label; /// < The label to display.
|
||||
bool state; /// < The state of the button/checkbox/radiobox
|
||||
bool active; /// < Whether the entry is the active one.
|
||||
bool focused; /// < Whether the entry is one focused by the user.
|
||||
};
|
||||
|
||||
struct UnderlineOption {
|
||||
bool enabled = false;
|
||||
|
||||
Color color_active = Color::White;
|
||||
Color color_inactive = Color::GrayDark;
|
||||
|
||||
animation::easing::Function leader_function =
|
||||
animation::easing::QuadraticInOut;
|
||||
animation::easing::Function follower_function =
|
||||
animation::easing::QuadraticInOut;
|
||||
|
||||
animation::Duration leader_duration = std::chrono::milliseconds(250);
|
||||
animation::Duration leader_delay = std::chrono::milliseconds(0);
|
||||
animation::Duration follower_duration = std::chrono::milliseconds(250);
|
||||
animation::Duration follower_delay = std::chrono::milliseconds(0);
|
||||
|
||||
void SetAnimation(animation::Duration d, animation::easing::Function f);
|
||||
void SetAnimationDuration(animation::Duration d);
|
||||
void SetAnimationFunction(animation::easing::Function f);
|
||||
void SetAnimationFunction(animation::easing::Function f_leader,
|
||||
animation::easing::Function f_follower);
|
||||
};
|
||||
|
||||
/// @brief Option about a potentially animated color.
|
||||
/// @ingroup component
|
||||
struct MenuOption {
|
||||
Decorator style_normal = nothing; ///< style.
|
||||
Decorator style_focused = inverted; ///< Style when focused.
|
||||
Decorator style_selected = bold; ///< Style when selected.
|
||||
Decorator style_selected_focused =
|
||||
Decorator(inverted) | bold; ///< Style when selected and focused.
|
||||
struct AnimatedColorOption {
|
||||
void Set(
|
||||
Color inactive,
|
||||
Color active,
|
||||
animation::Duration duration = std::chrono::milliseconds(250),
|
||||
animation::easing::Function function = animation::easing::QuadraticInOut);
|
||||
|
||||
/// Called when the selected entry changes.
|
||||
std::function<void()> on_change = [] {};
|
||||
/// Called when the user presses enter.
|
||||
std::function<void()> on_enter = [] {};
|
||||
bool enabled = false;
|
||||
Color inactive;
|
||||
Color active;
|
||||
animation::Duration duration = std::chrono::milliseconds(250);
|
||||
animation::easing::Function function = animation::easing::QuadraticInOut;
|
||||
};
|
||||
|
||||
Ref<int> focused_entry = 0;
|
||||
struct AnimatedColorsOption {
|
||||
AnimatedColorOption background;
|
||||
AnimatedColorOption foreground;
|
||||
};
|
||||
|
||||
/// @brief Option for the MenuEntry component.
|
||||
/// @ingroup component
|
||||
struct MenuEntryOption {
|
||||
Decorator style_normal = nothing; ///< style.
|
||||
Decorator style_focused = inverted; ///< Style when focused.
|
||||
Decorator style_selected = bold; ///< Style when selected.
|
||||
Decorator style_selected_focused =
|
||||
Decorator(inverted) | bold; ///< Style when selected and focused.
|
||||
std::function<Element(const EntryState& state)> transform;
|
||||
AnimatedColorsOption animated_colors;
|
||||
};
|
||||
|
||||
/// @brief Option for the Button component.
|
||||
/// @brief Option for the Menu component.
|
||||
/// @ingroup component
|
||||
struct MenuOption {
|
||||
// Standard constructors:
|
||||
static MenuOption Horizontal();
|
||||
static MenuOption HorizontalAnimated();
|
||||
static MenuOption Vertical();
|
||||
static MenuOption VerticalAnimated();
|
||||
static MenuOption Toggle();
|
||||
|
||||
// Style:
|
||||
UnderlineOption underline;
|
||||
MenuEntryOption entries;
|
||||
enum Direction { Up, Down, Left, Right };
|
||||
Direction direction = Down;
|
||||
std::function<Element()> elements_prefix;
|
||||
std::function<Element()> elements_infix;
|
||||
std::function<Element()> elements_postfix;
|
||||
|
||||
// Observers:
|
||||
std::function<void()> on_change; ///> Called when the selected entry changes.
|
||||
std::function<void()> on_enter; ///> Called when the user presses enter.
|
||||
Ref<int> focused_entry = 0;
|
||||
};
|
||||
|
||||
/// @brief Option for the AnimatedButton component.
|
||||
/// @ingroup component
|
||||
struct ButtonOption {
|
||||
/// Whether to show a border around the button.
|
||||
bool border = true;
|
||||
// Standard constructors:
|
||||
static ButtonOption Ascii();
|
||||
static ButtonOption Simple();
|
||||
static ButtonOption Border();
|
||||
static ButtonOption Animated();
|
||||
static ButtonOption Animated(Color color);
|
||||
static ButtonOption Animated(Color background, Color foreground);
|
||||
static ButtonOption Animated(Color background,
|
||||
Color foreground,
|
||||
Color background_active,
|
||||
Color foreground_active);
|
||||
|
||||
// Style:
|
||||
std::function<Element(const EntryState&)> transform;
|
||||
AnimatedColorsOption animated_colors;
|
||||
};
|
||||
|
||||
/// @brief Option for the Checkbox component.
|
||||
/// @ingroup component
|
||||
struct CheckboxOption {
|
||||
std::string style_checked = "▣ "; ///< Prefix for a "checked" state.
|
||||
std::string style_unchecked = "☐ "; ///< Prefix for a "unchecked" state.
|
||||
Decorator style_normal = nothing; ///< style.
|
||||
Decorator style_focused = inverted; ///< Style when focused.
|
||||
Decorator style_selected = bold; ///< Style when selected.
|
||||
Decorator style_selected_focused =
|
||||
Decorator(inverted) | bold; ///< Style when selected and focused.
|
||||
// Standard constructors:
|
||||
static CheckboxOption Simple();
|
||||
|
||||
// Style:
|
||||
std::function<Element(const EntryState&)> transform;
|
||||
|
||||
// Observer:
|
||||
/// Called when the user change the state.
|
||||
std::function<void()> on_change = []() {};
|
||||
std::function<void()> on_change = [] {};
|
||||
};
|
||||
|
||||
/// @brief Option for the Input component.
|
||||
@@ -74,35 +152,29 @@ struct InputOption {
|
||||
/// @brief Option for the Radiobox component.
|
||||
/// @ingroup component
|
||||
struct RadioboxOption {
|
||||
std::string style_checked = "◉ "; ///< Prefix for a "checked" state.
|
||||
std::string style_unchecked = "○ "; ///< Prefix for a "unchecked" state.
|
||||
Decorator style_normal = nothing; ///< style.
|
||||
Decorator style_focused = inverted; ///< Style when focused.
|
||||
Decorator style_selected = bold; ///< Style when selected.
|
||||
Decorator style_selected_focused =
|
||||
Decorator(inverted) | bold; ///< Style when selected and focused.
|
||||
// Standard constructors:
|
||||
static RadioboxOption Simple();
|
||||
|
||||
// Style:
|
||||
std::function<Element(const EntryState&)> transform;
|
||||
|
||||
// Observers:
|
||||
/// Called when the selected entry changes.
|
||||
std::function<void()> on_change = []() {};
|
||||
|
||||
std::function<void()> on_change = [] {};
|
||||
Ref<int> focused_entry = 0;
|
||||
};
|
||||
|
||||
/// @brief Option for the Toggle component.
|
||||
/// @ingroup component
|
||||
struct ToggleOption {
|
||||
Decorator style_normal = nothing; ///< style.
|
||||
Decorator style_focused = inverted; ///< Style when focused.
|
||||
Decorator style_selected = bold; ///< Style when selected.
|
||||
Decorator style_selected_focused =
|
||||
Decorator(inverted) | bold; ///< Style when selected and focused.
|
||||
|
||||
/// Called when the selected entry changes.
|
||||
std::function<void()> on_change = [] {};
|
||||
/// Called when the user presses enter.
|
||||
std::function<void()> on_enter = [] {};
|
||||
|
||||
Ref<int> focused_entry = 0;
|
||||
// @brief Option for the `Slider` component.
|
||||
// @ingroup component
|
||||
template <typename T>
|
||||
struct SliderOption {
|
||||
Ref<T> value;
|
||||
ConstRef<T> min = T(0);
|
||||
ConstRef<T> max = T(100);
|
||||
ConstRef<T> increment = (max() - min()) / 20;
|
||||
GaugeDirection direction = GaugeDirection::Right;
|
||||
Color color_active = Color::White;
|
||||
Color color_inactive = Color::GrayDark;
|
||||
};
|
||||
|
||||
} // namespace ftxui
|
||||
|
@@ -1,17 +0,0 @@
|
||||
#ifndef FTXUI_COMPONENT_DEPRECATED_HPP
|
||||
#define FTXUI_COMPONENT_DEPRECATED_HPP
|
||||
|
||||
#include "ftxui/component/component.hpp"
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
Component Input(WideStringRef content,
|
||||
ConstStringRef placeholder,
|
||||
Ref<InputOption> option = {});
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* FTXUI_COMPONENT_DEPRECATED_HPP */
|
||||
|
||||
// Copyright 2021 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -2,7 +2,8 @@
|
||||
#define FTXUI_COMPONENT_EVENT_HPP
|
||||
|
||||
#include <ftxui/component/mouse.hpp> // for Mouse
|
||||
#include <string> // for string, operator==
|
||||
#include <functional>
|
||||
#include <string> // for string, operator==
|
||||
#include <vector>
|
||||
|
||||
namespace ftxui {
|
||||
@@ -37,6 +38,11 @@ struct Event {
|
||||
static const Event ArrowUp;
|
||||
static const Event ArrowDown;
|
||||
|
||||
static const Event ArrowLeftCtrl;
|
||||
static const Event ArrowRightCtrl;
|
||||
static const Event ArrowUpCtrl;
|
||||
static const Event ArrowDownCtrl;
|
||||
|
||||
// --- Other ---
|
||||
static const Event Backspace;
|
||||
static const Event Delete;
|
||||
@@ -53,16 +59,14 @@ struct Event {
|
||||
static const Event PageDown;
|
||||
|
||||
// --- Custom ---
|
||||
static Event Custom;
|
||||
static const Event Custom;
|
||||
|
||||
//--- Method section ---------------------------------------------------------
|
||||
bool is_character() const { return type_ == Type::Character; }
|
||||
std::string character() const { return input_; }
|
||||
|
||||
bool is_mouse() const { return type_ == Type::Mouse; }
|
||||
struct Mouse& mouse() {
|
||||
return mouse_;
|
||||
}
|
||||
struct Mouse& mouse() { return mouse_; }
|
||||
|
||||
bool is_cursor_reporting() const { return type_ == Type::CursorReporting; }
|
||||
int cursor_x() const { return cursor_.x; }
|
||||
|
39
include/ftxui/component/loop.hpp
Normal file
39
include/ftxui/component/loop.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef FTXUI_COMPONENT_LOOP_HPP
|
||||
#define FTXUI_COMPONENT_LOOP_HPP
|
||||
|
||||
#include <memory> // for shared_ptr
|
||||
|
||||
#include "ftxui/component/component_base.hpp" // for ComponentBase
|
||||
|
||||
namespace ftxui {
|
||||
class ComponentBase;
|
||||
|
||||
using Component = std::shared_ptr<ComponentBase>;
|
||||
class ScreenInteractive;
|
||||
|
||||
class Loop {
|
||||
public:
|
||||
Loop(ScreenInteractive* screen, Component component);
|
||||
~Loop();
|
||||
|
||||
bool HasQuitted();
|
||||
void RunOnce();
|
||||
void RunOnceBlocking();
|
||||
void Run();
|
||||
|
||||
private:
|
||||
// This class is non copyable.
|
||||
Loop(const ScreenInteractive&) = delete;
|
||||
Loop& operator=(const Loop&) = delete;
|
||||
|
||||
ScreenInteractive* screen_;
|
||||
Component component_;
|
||||
};
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
#endif // FTXUI_COMPONENT_LOOP_HPP
|
||||
|
||||
// Copyright 2022 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -86,11 +86,25 @@ class ReceiverImpl {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReceiveNonBlocking(T* t) {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
if (queue_.empty())
|
||||
return false;
|
||||
*t = queue_.front();
|
||||
queue_.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HasPending() {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
return !queue_.empty();
|
||||
}
|
||||
|
||||
bool HasQuitted() {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
return queue_.empty() && !senders_;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class SenderImpl<T>;
|
||||
|
||||
|
@@ -7,47 +7,70 @@
|
||||
#include <memory> // for shared_ptr
|
||||
#include <string> // for string
|
||||
#include <thread> // for thread
|
||||
#include <variant> // for variant
|
||||
|
||||
#include "ftxui/component/animation.hpp" // for TimePoint
|
||||
#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse
|
||||
#include "ftxui/component/event.hpp" // for Event
|
||||
#include "ftxui/component/task.hpp" // for Task, Closure
|
||||
#include "ftxui/screen/screen.hpp" // for Screen
|
||||
|
||||
namespace ftxui {
|
||||
class ComponentBase;
|
||||
class Loop;
|
||||
struct Event;
|
||||
|
||||
using Component = std::shared_ptr<ComponentBase>;
|
||||
class ScreenInteractivePrivate;
|
||||
|
||||
class ScreenInteractive : public Screen {
|
||||
public:
|
||||
using Callback = std::function<void()>;
|
||||
|
||||
// Constructors:
|
||||
static ScreenInteractive FixedSize(int dimx, int dimy);
|
||||
static ScreenInteractive Fullscreen();
|
||||
static ScreenInteractive FitComponent();
|
||||
static ScreenInteractive TerminalOutput();
|
||||
|
||||
void Loop(Component);
|
||||
Callback ExitLoopClosure();
|
||||
// Return the currently active screen, nullptr if none.
|
||||
static ScreenInteractive* Active();
|
||||
|
||||
// Start/Stop the main loop.
|
||||
void Loop(Component);
|
||||
void Exit();
|
||||
Closure ExitLoopClosure();
|
||||
|
||||
// Post tasks to be executed by the loop.
|
||||
void Post(Task task);
|
||||
void PostEvent(Event event);
|
||||
void RequestAnimationFrame();
|
||||
|
||||
CapturedMouse CaptureMouse();
|
||||
|
||||
// Decorate a function. The outputted one will execute similarly to the
|
||||
// inputted one, but with the currently active screen terminal hooks
|
||||
// temporarily uninstalled.
|
||||
Callback WithRestoredIO(Callback);
|
||||
Closure WithRestoredIO(Closure);
|
||||
|
||||
private:
|
||||
void ExitNow();
|
||||
|
||||
void Install();
|
||||
void Uninstall();
|
||||
|
||||
void Main(Component component);
|
||||
ScreenInteractive* suspended_screen_ = nullptr;
|
||||
void PreMain();
|
||||
void PostMain();
|
||||
|
||||
bool HasQuitted();
|
||||
void RunOnce(Component component);
|
||||
void RunOnceBlocking(Component component);
|
||||
|
||||
void HandleTask(Component component, Task& task);
|
||||
void Draw(Component component);
|
||||
void EventLoop(Component component);
|
||||
void ResetCursorPosition();
|
||||
|
||||
void Signal(int signal);
|
||||
|
||||
ScreenInteractive* suspended_screen_ = nullptr;
|
||||
enum class Dimension {
|
||||
FitComponent,
|
||||
Fixed,
|
||||
@@ -61,20 +84,34 @@ class ScreenInteractive : public Screen {
|
||||
Dimension dimension,
|
||||
bool use_alternative_screen);
|
||||
|
||||
Sender<Event> event_sender_;
|
||||
Receiver<Event> event_receiver_;
|
||||
Sender<Task> task_sender_;
|
||||
Receiver<Task> task_receiver_;
|
||||
|
||||
std::string set_cursor_position;
|
||||
std::string reset_cursor_position;
|
||||
|
||||
std::atomic<bool> quit_ = false;
|
||||
std::thread event_listener_;
|
||||
std::thread animation_listener_;
|
||||
bool animation_requested_ = false;
|
||||
animation::TimePoint previous_animation_time_;
|
||||
|
||||
int cursor_x_ = 1;
|
||||
int cursor_y_ = 1;
|
||||
|
||||
bool mouse_captured = false;
|
||||
bool previous_frame_resized_ = false;
|
||||
|
||||
bool frame_valid_ = false;
|
||||
|
||||
friend class Loop;
|
||||
|
||||
public:
|
||||
class Private {
|
||||
public:
|
||||
static void Signal(ScreenInteractive& s, int signal) { s.Signal(signal); }
|
||||
};
|
||||
friend Private;
|
||||
};
|
||||
|
||||
} // namespace ftxui
|
||||
|
18
include/ftxui/component/task.hpp
Normal file
18
include/ftxui/component/task.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef FTXUI_COMPONENT_ANIMATION_HPP
|
||||
#define FTXUI_COMPONENT_ANIMATION_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <variant>
|
||||
#include "ftxui/component/event.hpp"
|
||||
|
||||
namespace ftxui {
|
||||
class AnimationTask {};
|
||||
using Closure = std::function<void()>;
|
||||
using Task = std::variant<Event, Closure, AnimationTask>;
|
||||
} // namespace ftxui
|
||||
|
||||
#endif // FTXUI_COMPONENT_ANIMATION_HPP
|
||||
|
||||
// Copyright 2022 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -1,7 +1,7 @@
|
||||
#ifndef FTXUI_DOM_CANVAS_HPP
|
||||
#define FTXUI_DOM_CANVAS_HPP
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
#include <cstddef> // for size_t
|
||||
#include <functional> // for function
|
||||
#include <string> // for string
|
||||
#include <unordered_map> // for unordered_map
|
||||
@@ -9,11 +9,17 @@
|
||||
#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() {}
|
||||
Canvas() = default;
|
||||
Canvas(int width, int height);
|
||||
|
||||
// Getters:
|
||||
@@ -114,7 +120,8 @@ struct Canvas {
|
||||
|
||||
struct XYHash {
|
||||
size_t operator()(const XY& xy) const {
|
||||
return static_cast<size_t>(xy.x * 1024 + xy.y);
|
||||
constexpr size_t shift = 1024;
|
||||
return size_t(xy.x) * shift + size_t(xy.y);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#ifndef FTXUI_DOM_DEPRECRATED_HPP
|
||||
#define FTXUI_DOM_DEPRECRATED_HPP
|
||||
#ifndef FTXUI_DOM_DEPRECATED_HPP
|
||||
#define FTXUI_DOM_DEPRECATED_HPP
|
||||
|
||||
#include "ftxui/dom/elements.hpp"
|
||||
|
||||
@@ -9,7 +9,7 @@ Element vtext(std::wstring text);
|
||||
Elements paragraph(std::wstring text);
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* end of include guard: FTXUI_DOM_DEPRECRATED_HPP */
|
||||
#endif // FTXUI_DOM_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
|
||||
|
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "ftxui/dom/canvas.hpp"
|
||||
#include "ftxui/dom/flexbox_config.hpp"
|
||||
#include "ftxui/dom/linear_gradient.hpp"
|
||||
#include "ftxui/dom/node.hpp"
|
||||
#include "ftxui/screen/box.hpp"
|
||||
#include "ftxui/screen/color.hpp"
|
||||
@@ -20,43 +21,70 @@ using Elements = std::vector<Element>;
|
||||
using Decorator = std::function<Element(Element)>;
|
||||
using GraphFunction = std::function<std::vector<int>(int, int)>;
|
||||
|
||||
enum BorderStyle { LIGHT, HEAVY, DOUBLE, ROUNDED, EMPTY };
|
||||
enum BorderStyle {
|
||||
LIGHT,
|
||||
DASHED,
|
||||
HEAVY,
|
||||
DOUBLE,
|
||||
ROUNDED,
|
||||
EMPTY,
|
||||
};
|
||||
|
||||
enum class GaugeDirection { Left, Up, Right, Down };
|
||||
|
||||
// Pipe elements into decorator togethers.
|
||||
// For instance the next lines are equivalents:
|
||||
// -> text("ftxui") | bold | underlined
|
||||
// -> underlined(bold(text("FTXUI")))
|
||||
Element operator|(Element, Decorator);
|
||||
Element& operator|=(Element&, Decorator);
|
||||
Elements operator|(Elements, Decorator);
|
||||
Decorator operator|(Decorator, Decorator);
|
||||
|
||||
// --- Widget ---
|
||||
Element text(std::string text);
|
||||
Element vtext(std::string text);
|
||||
Element separator(void);
|
||||
Element separator();
|
||||
Element separatorLight();
|
||||
Element separatorDashed();
|
||||
Element separatorHeavy();
|
||||
Element separatorDouble();
|
||||
Element separatorEmpty();
|
||||
Element separatorStyled(BorderStyle);
|
||||
Element separator(Pixel);
|
||||
Element separatorCharacter(std::string);
|
||||
Element gauge(float ratio);
|
||||
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 borderLight(Element);
|
||||
Element borderDashed(Element);
|
||||
Element borderHeavy(Element);
|
||||
Element borderDouble(Element);
|
||||
Element borderRounded(Element);
|
||||
Element borderEmpty(Element);
|
||||
Decorator borderStyled(BorderStyle);
|
||||
Decorator borderWith(Pixel);
|
||||
Decorator borderStyled(BorderStyle, Color);
|
||||
Decorator borderStyled(Color);
|
||||
Decorator borderWith(const Pixel&);
|
||||
Element window(Element title, Element content);
|
||||
Element spinner(int charset_index, size_t image_index);
|
||||
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);
|
||||
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 emptyElement();
|
||||
Element canvas(ConstRef<Canvas>);
|
||||
@@ -68,13 +96,20 @@ Element bold(Element);
|
||||
Element dim(Element);
|
||||
Element inverted(Element);
|
||||
Element underlined(Element);
|
||||
Element underlinedDouble(Element);
|
||||
Element blink(Element);
|
||||
Element strikethrough(Element);
|
||||
Decorator color(Color);
|
||||
Decorator bgcolor(Color);
|
||||
Decorator color(const LinearGradient&);
|
||||
Decorator bgcolor(const LinearGradient&);
|
||||
Element color(Color, Element);
|
||||
Element bgcolor(Color, Element);
|
||||
Element color(const LinearGradient&, Element);
|
||||
Element bgcolor(const LinearGradient&, Element);
|
||||
Decorator focusPosition(int x, int y);
|
||||
Decorator focusPositionRelative(float x, float y);
|
||||
Element automerge(Element child);
|
||||
|
||||
// --- Layout is
|
||||
// Horizontal, Vertical or stacked set of elements.
|
||||
@@ -110,9 +145,6 @@ enum Direction { WIDTH, HEIGHT };
|
||||
enum Constraint { LESS_THAN, EQUAL, GREATER_THAN };
|
||||
Decorator size(Direction, Constraint, int value);
|
||||
|
||||
// --
|
||||
Decorator reflect(Box& box);
|
||||
|
||||
// --- Frame ---
|
||||
// A frame is a scrollable area. The internal area is potentially larger than
|
||||
// the external one. The internal area is scrolled in order to make visible the
|
||||
@@ -123,7 +155,21 @@ Element yframe(Element);
|
||||
Element focus(Element);
|
||||
Element select(Element);
|
||||
|
||||
// --- Cursor ---
|
||||
// Those are similar to `focus`, but also change the shape of the cursor.
|
||||
Element focusCursorBlock(Element);
|
||||
Element focusCursorBlockBlinking(Element);
|
||||
Element focusCursorBar(Element);
|
||||
Element focusCursorBarBlinking(Element);
|
||||
Element focusCursorUnderline(Element);
|
||||
Element focusCursorUnderlineBlinking(Element);
|
||||
|
||||
// --- Misc ---
|
||||
Element vscroll_indicator(Element);
|
||||
Decorator reflect(Box& box);
|
||||
// Before drawing the |element| clear the pixel below. This is useful in
|
||||
// combinaison with dbox.
|
||||
Element clear_under(Element element);
|
||||
|
||||
// --- Util --------------------------------------------------------------------
|
||||
Element hcenter(Element);
|
||||
@@ -132,10 +178,6 @@ Element center(Element);
|
||||
Element align_right(Element);
|
||||
Element nothing(Element element);
|
||||
|
||||
// Before drawing the |element| clear the pixel below. This is useful in
|
||||
// combinaison with dbox.
|
||||
Element clear_under(Element element);
|
||||
|
||||
namespace Dimension {
|
||||
Dimensions Fit(Element&);
|
||||
} // namespace Dimension
|
||||
@@ -147,7 +189,7 @@ Dimensions Fit(Element&);
|
||||
|
||||
// Include old definitions using wstring.
|
||||
#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.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
|
@@ -108,7 +108,7 @@ struct FlexboxConfig {
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* end of include guard: FTXUI_DOM_FLEXBOX_CONFIG_HPP */
|
||||
#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
|
||||
|
52
include/ftxui/dom/linear_gradient.hpp
Normal file
52
include/ftxui/dom/linear_gradient.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef FTXUI_DOM_LINEAR_GRADIENT_HPP
|
||||
#define FTXUI_DOM_LINEAR_GRADIENT_HPP
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "ftxui/screen/color.hpp" // for Colors
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
/// @brief A class representing the settings for linear-gradient color effect.
|
||||
///
|
||||
/// Example:
|
||||
/// ```cpp
|
||||
/// LinearGradient()
|
||||
/// .Angle(45)
|
||||
/// .Stop(Color::Red, 0.0)
|
||||
/// .Stop(Color::Green, 0.5)
|
||||
/// .Stop(Color::Blue, 1.0);
|
||||
/// ```
|
||||
///
|
||||
/// There are also shorthand constructors:
|
||||
/// ```cpp
|
||||
/// LinearGradient(Color::Red, Color::Blue);
|
||||
/// LinearGradient(45, Color::Red, Color::Blue);
|
||||
/// ```
|
||||
struct LinearGradient {
|
||||
float angle = 0.f;
|
||||
struct Stop {
|
||||
Color color = Color::Default;
|
||||
std::optional<float> position;
|
||||
};
|
||||
std::vector<Stop> stops;
|
||||
|
||||
// Simple constructor
|
||||
LinearGradient();
|
||||
LinearGradient(Color begin, Color end);
|
||||
LinearGradient(float angle, Color begin, Color end);
|
||||
|
||||
// Modifier using the builder pattern.
|
||||
LinearGradient& Angle(float angle);
|
||||
LinearGradient& Stop(Color color, float position);
|
||||
LinearGradient& Stop(Color color);
|
||||
};
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
#endif // FTXUI_DOM_LINEAR_GRADIENT_HPP
|
||||
|
||||
// Copyright 2023 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
@@ -20,6 +20,11 @@ class Node {
|
||||
public:
|
||||
Node();
|
||||
Node(Elements children);
|
||||
Node(const Node&) = delete;
|
||||
Node(const Node&&) = delete;
|
||||
Node& operator=(const Node&) = delete;
|
||||
Node& operator=(const Node&&) = delete;
|
||||
|
||||
virtual ~Node();
|
||||
|
||||
// Step 1: Compute layout requirement. Tell parent what dimensions this
|
||||
@@ -50,12 +55,12 @@ class Node {
|
||||
Box box_;
|
||||
};
|
||||
|
||||
void Render(Screen& screen, const Element& node);
|
||||
void Render(Screen& screen, const Element& element);
|
||||
void Render(Screen& screen, Node* node);
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* end of include guard: FTXUI_DOM_NODE_HPP */
|
||||
#endif // FTXUI_DOM_NODE_HPP
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
|
@@ -28,7 +28,7 @@ struct Requirement {
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* end of include guard: FTXUI_DOM_REQUIREMENT_HPP */
|
||||
#endif // FTXUI_DOM_REQUIREMENT_HPP
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include <string> // for string
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/dom/elements.hpp" // for BorderStyle, LIGHT, Element, Decorator
|
||||
#include "ftxui/dom/elements.hpp" // for Element, BorderStyle, LIGHT, Decorator
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
@@ -52,10 +52,10 @@ class Table {
|
||||
void Initialize(std::vector<std::vector<Element>>);
|
||||
friend TableSelection;
|
||||
std::vector<std::vector<Element>> elements_;
|
||||
int input_dim_x_;
|
||||
int input_dim_y_;
|
||||
int dim_x_;
|
||||
int dim_y_;
|
||||
int input_dim_x_ = 0;
|
||||
int input_dim_y_ = 0;
|
||||
int dim_x_ = 0;
|
||||
int dim_y_ = 0;
|
||||
};
|
||||
|
||||
class TableSelection {
|
||||
|
@@ -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"
|
||||
#include <type_traits>
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
template <class T>
|
||||
void Merge(Elements&, T) {}
|
||||
void Merge(Elements& /*container*/, T /*element*/) {}
|
||||
|
||||
template <>
|
||||
inline void Merge(Elements& container, Element element) {
|
||||
@@ -38,6 +41,8 @@ TAKE_ANY_ARGS(dbox)
|
||||
TAKE_ANY_ARGS(hflow)
|
||||
} // namespace ftxui
|
||||
|
||||
#endif // FTXUI_DOM_TAKE_ANY_ARGS_HPP
|
||||
|
||||
// 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.
|
||||
|
@@ -9,15 +9,16 @@ struct Box {
|
||||
int y_min = 0;
|
||||
int y_max = 0;
|
||||
|
||||
static Box Intersection(Box a, Box b);
|
||||
bool Contain(int x, int y);
|
||||
static auto Intersection(Box a, Box b) -> Box;
|
||||
static auto Union(Box a, Box b) -> Box;
|
||||
bool Contain(int x, int y) const;
|
||||
bool operator==(const Box& other) const;
|
||||
bool operator!=(const Box& other) const;
|
||||
};
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* end of include guard: FTXUI_SCREEN_BOX_HPP */
|
||||
#endif // FTXUI_SCREEN_BOX_HPP
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
|
@@ -1,8 +1,9 @@
|
||||
#ifndef FTXUI_SCREEN_COLOR
|
||||
#define FTXUI_SCREEN_COLOR
|
||||
#ifndef FTXUI_SCREEN_COLOR_HPP
|
||||
#define FTXUI_SCREEN_COLOR_HPP
|
||||
|
||||
#include <stdint.h> // for uint8_t
|
||||
#include <string> // for wstring
|
||||
#include <cstdint> // for uint8_t
|
||||
#include <string> // for string
|
||||
#include <vector> // for vector
|
||||
|
||||
#ifdef RGB
|
||||
// Workaround for wingdi.h (via Windows.h) defining macros that break things.
|
||||
@@ -27,6 +28,7 @@ class Color {
|
||||
Color(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 Interpolate(float t, const Color& a, const Color& b);
|
||||
|
||||
//---------------------------
|
||||
// List of colors:
|
||||
@@ -312,12 +314,8 @@ class Color {
|
||||
Palette256,
|
||||
TrueColor,
|
||||
};
|
||||
|
||||
ColorType type_;
|
||||
union {
|
||||
uint8_t index_ = 0;
|
||||
uint8_t red_;
|
||||
};
|
||||
ColorType type_ = ColorType::Palette1;
|
||||
uint8_t red_ = 0;
|
||||
uint8_t green_ = 0;
|
||||
uint8_t blue_ = 0;
|
||||
};
|
||||
@@ -332,7 +330,7 @@ Color operator""_rgb(unsigned long long int combined);
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* end of include guard: FTXUI_COLOR_H_ */
|
||||
#endif // FTXUI_SCREEN_COLOR_HPP
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#ifndef FTXUI_SCREEN_COLOR_INFO_HPP
|
||||
#define FTXUI_SCREEN_COLOR_INFO_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstdint>
|
||||
#include <ftxui/screen/color.hpp>
|
||||
|
||||
namespace ftxui {
|
||||
@@ -23,7 +23,7 @@ ColorInfo GetColorInfo(Color::Palette16 index);
|
||||
|
||||
} // 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.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
|
@@ -8,7 +8,7 @@ int wchar_width(wchar_t);
|
||||
int wstring_width(const std::wstring&);
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* end of include guard: FTXUI_SCREEN_DEPRECATED_HPP */
|
||||
#endif // FTXUI_SCREEN_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
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#ifndef FTXUI_SCREEN_SCREEN
|
||||
#define FTXUI_SCREEN_SCREEN
|
||||
#ifndef FTXUI_SCREEN_SCREEN_HPP
|
||||
#define FTXUI_SCREEN_SCREEN_HPP
|
||||
|
||||
#include <memory>
|
||||
#include <string> // for string, allocator, basic_string
|
||||
@@ -14,6 +14,8 @@ namespace ftxui {
|
||||
/// @brief A unicode character and its associated style.
|
||||
/// @ingroup screen
|
||||
struct Pixel {
|
||||
bool operator==(const Pixel& other) const;
|
||||
|
||||
// The graphemes stored into the pixel. To support combining characters,
|
||||
// like: a⃦, this can potentially contains multiple codepoitns.
|
||||
std::string character = " ";
|
||||
@@ -28,6 +30,8 @@ struct Pixel {
|
||||
bool dim : 1;
|
||||
bool inverted : 1;
|
||||
bool underlined : 1;
|
||||
bool underlined_double : 1;
|
||||
bool strikethrough : 1;
|
||||
bool automerge : 1;
|
||||
|
||||
Pixel()
|
||||
@@ -36,6 +40,8 @@ struct Pixel {
|
||||
dim(false),
|
||||
inverted(false),
|
||||
underlined(false),
|
||||
underlined_double(false),
|
||||
strikethrough(false),
|
||||
automerge(false) {}
|
||||
};
|
||||
|
||||
@@ -68,21 +74,33 @@ class Screen {
|
||||
int dimy() const { return 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.
|
||||
void Clear();
|
||||
|
||||
void ApplyShader();
|
||||
Box stencil;
|
||||
|
||||
struct Cursor {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
enum Shape {
|
||||
Hidden = 0,
|
||||
BlockBlinking = 1,
|
||||
Block = 2,
|
||||
UnderlineBlinking = 3,
|
||||
Underline = 4,
|
||||
BarBlinking = 5,
|
||||
Bar = 6,
|
||||
};
|
||||
Shape shape;
|
||||
};
|
||||
Cursor cursor() const { return cursor_; }
|
||||
void SetCursor(Cursor cursor) { cursor_ = cursor; }
|
||||
|
||||
Box stencil;
|
||||
|
||||
protected:
|
||||
int dimx_;
|
||||
int dimy_;
|
||||
@@ -92,7 +110,7 @@ class Screen {
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* end of include guard: FTXUI_SCREEN_SCREEN */
|
||||
#endif // FTXUI_SCREEN_SCREEN_HPP
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
|
@@ -26,6 +26,33 @@ int GlyphPosition(const std::string& input,
|
||||
// Returns the number of glyphs in |input|.
|
||||
int GlyphCount(const std::string& input);
|
||||
|
||||
// Properties from:
|
||||
// https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/WordBreakProperty.txt
|
||||
enum class WordBreakProperty {
|
||||
ALetter,
|
||||
CR,
|
||||
Double_Quote,
|
||||
Extend,
|
||||
ExtendNumLet,
|
||||
Format,
|
||||
Hebrew_Letter,
|
||||
Katakana,
|
||||
LF,
|
||||
MidLetter,
|
||||
MidNum,
|
||||
MidNumLet,
|
||||
Newline,
|
||||
Numeric,
|
||||
Regional_Indicator,
|
||||
Single_Quote,
|
||||
WSegSpace,
|
||||
ZWJ,
|
||||
};
|
||||
std::vector<WordBreakProperty> Utf8ToWordBreakProperty(
|
||||
const std::string& input);
|
||||
|
||||
bool IsWordBreakingCharacter(const std::string& input, size_t glyph_index);
|
||||
|
||||
// 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);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#ifndef FTXUI_CORE_TERMINAL_HPP
|
||||
#define FTXUI_CORE_TERMINAL_HPP
|
||||
#ifndef FTXUI_SCREEN_TERMINAL_HPP
|
||||
#define FTXUI_SCREEN_TERMINAL_HPP
|
||||
|
||||
namespace ftxui {
|
||||
struct Dimensions {
|
||||
@@ -18,11 +18,13 @@ enum Color {
|
||||
TrueColor,
|
||||
};
|
||||
Color ColorSupport();
|
||||
void SetColorSupport(Color color);
|
||||
|
||||
} // namespace Terminal
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* end of include guard: FTXUI_CORE_TERMINAL_HPP */
|
||||
#endif // FTXUI_SCREEN_TERMINAL_HPP
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
|
@@ -27,7 +27,8 @@ template <typename T>
|
||||
class Ref {
|
||||
public:
|
||||
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) {}
|
||||
T& operator*() { return address_ ? *address_ : owned_; }
|
||||
T& operator()() { return address_ ? *address_ : owned_; }
|
||||
@@ -54,23 +55,6 @@ class StringRef {
|
||||
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
|
||||
/// class convert multiple immutable string toward a shared representation.
|
||||
class ConstStringRef {
|
||||
@@ -82,6 +66,9 @@ class ConstStringRef {
|
||||
ConstStringRef(const wchar_t* ref) : ConstStringRef(std::wstring(ref)) {}
|
||||
ConstStringRef(const char* ref)
|
||||
: ConstStringRef(to_wstring(std::string(ref))) {}
|
||||
const std::string& operator()() const {
|
||||
return address_ ? *address_ : owned_;
|
||||
}
|
||||
const std::string& operator*() const { return address_ ? *address_ : owned_; }
|
||||
const std::string* operator->() const {
|
||||
return address_ ? address_ : &owned_;
|
||||
|
30
iwyu.imp
30
iwyu.imp
@@ -1,17 +1,27 @@
|
||||
[
|
||||
{ include: ["<bits/chrono.h>", "private", "<chrono>", "public"]},
|
||||
{ include: ["<bits/std_abs.h>", "private", "<cmath>", "public"]},
|
||||
{ include: ["<bits/termios-c_cc.h>", "private", "<termios.h>", "public"]},
|
||||
{ include: ["<bits/termios-c_lflag.h>", "private", "<termios.h>", "public"]},
|
||||
{ include: ["<bits/termios-struct.h>", "private", "<termios.h>", "public"]},
|
||||
{ include: ["<bits/termios-tcflow.h>", "private", "<termios.h>", "public"]},
|
||||
{ include: ["<ext/alloc_traits.h>", "private", "<vector>", "public"] },
|
||||
{ symbol: [ "ftxui", "private", "", "public" ] },
|
||||
{ symbol: [ "char_traits", "private", "<string>", "public" ] },
|
||||
{ symbol: [ "ECHO", "private", "<termios.h>", "public" ] },
|
||||
{ symbol: [ "ICANON", "private", "<termios.h>", "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" ] },
|
||||
{ include: ["<gtest/internal/gtest-internal.h>", "private", "<gtest/gtest.h>", "public" ] },
|
||||
{ include: ["<gtest/internal/gtest-string.h>", "private", "<gtest/gtest.h>", "public" ] },
|
||||
{ include: ["<gtest/gtest-death-test.h>", "private", "<gtest/gtest.h>", "public" ] },
|
||||
{ include: ["<gtest/gtest-message.h>", "private", "<gtest/gtest.h>", "public" ] },
|
||||
{ include: ["<gtest/gtest-param-test.h>", "private", "<gtest/gtest.h>", "public" ] },
|
||||
{ include: ["<gtest/gtest-printers.h>", "private", "<gtest/gtest.h>", "public" ] },
|
||||
{ include: ["<gtest/gtest-test-part.h>", "private", "<gtest/gtest.h>", "public" ] },
|
||||
{ include: ["<gtest/gtest-typed-test.h>", "private", "<gtest/gtest.h>", "public" ] },
|
||||
{ symbol: ["ftxui", "private", "", "public" ] },
|
||||
{ symbol: ["char_traits", "private", "<string>", "public" ] },
|
||||
{ symbol: ["ECHO", "private", "<termios.h>", "public" ] },
|
||||
{ symbol: ["ICANON", "private", "<termios.h>", "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" ] }
|
||||
]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user