14 Commits

Author SHA1 Message Date
Copilot
8249fcb41e Add comprehensive GitHub Copilot instructions for FTXUI development (#1121)
Some checks are pending
Build / Bazel, cl, windows-latest (push) Waiting to run
Build / Bazel, clang++, macos-latest (push) Waiting to run
Build / Bazel, clang++, ubuntu-latest (push) Waiting to run
Build / Bazel, g++, macos-latest (push) Waiting to run
Build / Bazel, g++, ubuntu-latest (push) Waiting to run
Build / CMake, cl, windows-latest (push) Waiting to run
Build / CMake, gcc, ubuntu-latest (push) Waiting to run
Build / CMake, llvm, ubuntu-latest (push) Waiting to run
Build / CMake, llvm, macos-latest (push) Waiting to run
Build / Test modules (llvm, ubuntu-latest) (push) Waiting to run
Documentation / documentation (push) Waiting to run
2025-09-21 10:30:52 +02:00
Benjamin Gwin
f21fcc1995 Fix use of uninitialized cursor variable (#1111)
Some checks failed
Build / Bazel, cl, windows-latest (push) Has been cancelled
Build / Bazel, clang++, macos-latest (push) Has been cancelled
Build / Bazel, clang++, ubuntu-latest (push) Has been cancelled
Build / Bazel, g++, macos-latest (push) Has been cancelled
Build / Bazel, g++, ubuntu-latest (push) Has been cancelled
Build / CMake, cl, windows-latest (push) Has been cancelled
Build / CMake, gcc, ubuntu-latest (push) Has been cancelled
Build / CMake, llvm, ubuntu-latest (push) Has been cancelled
Build / CMake, llvm, macos-latest (push) Has been cancelled
Build / Test modules (llvm, ubuntu-latest) (push) Has been cancelled
Documentation / documentation (push) Has been cancelled
The cursor_ variable was being default initialized, which causes
undefined behaviour when accessing properties in
ScreenInteractive::Draw. This caused a crash when running with UBSAN.

```
ftxui/src/ftxui/component/screen_interactive.cpp:852:17: runtime error:
load of value 4195502944, which is not a valid value for type 'Shape'
```

This change causes the shape variable to be explicitly initialized,
similar to the x and y members.

Co-authored-by: Benjamin Gwin <bgwin@google.com>
2025-09-09 07:34:35 +02:00
birland
f7ac35ed35 Add tic-tac-toe as an example project using FTXUI (#1109)
Some checks failed
Build / Bazel, cl, windows-latest (push) Has been cancelled
Build / Bazel, clang++, macos-latest (push) Has been cancelled
Build / Bazel, clang++, ubuntu-latest (push) Has been cancelled
Build / Bazel, g++, macos-latest (push) Has been cancelled
Build / Bazel, g++, ubuntu-latest (push) Has been cancelled
Build / CMake, cl, windows-latest (push) Has been cancelled
Build / CMake, gcc, ubuntu-latest (push) Has been cancelled
Build / CMake, llvm, ubuntu-latest (push) Has been cancelled
Build / CMake, llvm, macos-latest (push) Has been cancelled
Build / Test modules (llvm, ubuntu-latest) (push) Has been cancelled
Documentation / documentation (push) Has been cancelled
2025-09-07 09:20:11 +02:00
nodeluna
fba510ec02 fixed a typo (#1110) 2025-09-07 09:19:17 +02:00
Xiao Di
775ad9ce5e Improved the installation method via Conan. (#1106)
Some checks failed
Build / Bazel, cl, windows-latest (push) Has been cancelled
Build / Bazel, clang++, macos-latest (push) Has been cancelled
Build / Bazel, clang++, ubuntu-latest (push) Has been cancelled
Build / Bazel, g++, macos-latest (push) Has been cancelled
Build / Bazel, g++, ubuntu-latest (push) Has been cancelled
Build / CMake, cl, windows-latest (push) Has been cancelled
Build / CMake, gcc, ubuntu-latest (push) Has been cancelled
Build / CMake, llvm, ubuntu-latest (push) Has been cancelled
Build / CMake, llvm, macos-latest (push) Has been cancelled
Build / Test modules (llvm, ubuntu-latest) (push) Has been cancelled
Documentation / documentation (push) Has been cancelled
2025-09-01 10:02:57 +02:00
Samuel Bridgham
f5785fd3b4 Fixed bug in component/button example: (#1107)
- The '-1' and '+1' buttons now correctly increment and decrement.
 - Previously it was vice versa.s
2025-09-01 10:02:21 +02:00
Arthur Sonzogni
853d87e917 Fix HTML entities in README.md
Some checks failed
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (cl, cl, windows-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (clang, clang++, macos-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (clang, clang++, ubuntu-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (gcc, g++, macos-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (gcc, g++, ubuntu-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (cl, Windows MSVC, windows-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (gcc, Linux GCC, ubuntu-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (llvm, llvm-cov gcov, Linux Clang, ubuntu-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (llvm, llvm-cov gcov, MacOS clang, macos-latest) (push) Has been cancelled
Build / Test modules (llvm, ubuntu-latest) (push) Has been cancelled
Documentation / documentation (push) Has been cancelled
2025-08-29 07:36:35 +02:00
d06i
11f7132886 Add new project to the list (#1102)
Some checks failed
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (cl, cl, windows-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (clang, clang++, macos-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (clang, clang++, ubuntu-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (gcc, g++, macos-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (gcc, g++, ubuntu-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (cl, Windows MSVC, windows-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (gcc, Linux GCC, ubuntu-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (llvm, llvm-cov gcov, Linux Clang, ubuntu-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (llvm, llvm-cov gcov, MacOS clang, macos-latest) (push) Has been cancelled
Build / Test modules (llvm, ubuntu-latest) (push) Has been cancelled
Documentation / documentation (push) Has been cancelled
Co-authored-by: d06i <llll@DESKTOP-C8VGJLV>
2025-08-26 12:47:10 +02:00
ArthurSonzogni
346f751527 Fix example in docs not being generated.
Some checks failed
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (cl, cl, windows-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (clang, clang++, macos-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (clang, clang++, ubuntu-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (gcc, g++, macos-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (gcc, g++, ubuntu-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (cl, Windows MSVC, windows-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (gcc, Linux GCC, ubuntu-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (llvm, llvm-cov gcov, Linux Clang, ubuntu-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (llvm, llvm-cov gcov, MacOS clang, macos-latest) (push) Has been cancelled
Build / Test modules (llvm, ubuntu-latest) (push) Has been cancelled
Documentation / documentation (push) Has been cancelled
Fixed:https://github.com/ArthurSonzogni/FTXUI/issues/1088
2025-08-21 08:05:23 +02:00
Arthur Sonzogni
e56ff89cf3 Improve example style. (#1101)
Some checks failed
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (cl, cl, windows-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (clang, clang++, macos-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (clang, clang++, ubuntu-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (gcc, g++, macos-latest) (push) Has been cancelled
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (gcc, g++, ubuntu-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (cl, Windows MSVC, windows-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (gcc, Linux GCC, ubuntu-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (llvm, llvm-cov gcov, Linux Clang, ubuntu-latest) (push) Has been cancelled
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (llvm, llvm-cov gcov, MacOS clang, macos-latest) (push) Has been cancelled
Build / Test modules (llvm, ubuntu-latest) (push) Has been cancelled
Documentation / documentation (push) Has been cancelled
Based uppon @yurenchen000 suggestion.

Fixed:https://github.com/ArthurSonzogni/FTXUI/issues/1090
2025-08-20 06:53:42 +02:00
Arthur Sonzogni
21b24a1b78 Fix slider Up key press. (#1099)
Some checks are pending
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (cl, cl, windows-latest) (push) Waiting to run
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (clang, clang++, macos-latest) (push) Waiting to run
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (clang, clang++, ubuntu-latest) (push) Waiting to run
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (gcc, g++, macos-latest) (push) Waiting to run
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (gcc, g++, ubuntu-latest) (push) Waiting to run
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (cl, Windows MSVC, windows-latest) (push) Waiting to run
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (gcc, Linux GCC, ubuntu-latest) (push) Waiting to run
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (llvm, llvm-cov gcov, Linux Clang, ubuntu-latest) (push) Waiting to run
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (llvm, llvm-cov gcov, MacOS clang, macos-latest) (push) Waiting to run
Build / Test modules (llvm, ubuntu-latest) (push) Waiting to run
Documentation / documentation (push) Waiting to run
The direction was inverted. It caused the inability to increase it.

Fixed:https://github.com/ArthurSonzogni/FTXUI/issues/1093
2025-08-19 09:34:30 +02:00
ArthurSonzogni
bfd07ba309 Example. Add missing file.
Some checks are pending
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (cl, cl, windows-latest) (push) Waiting to run
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (clang, clang++, macos-latest) (push) Waiting to run
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (clang, clang++, ubuntu-latest) (push) Waiting to run
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (gcc, g++, macos-latest) (push) Waiting to run
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (gcc, g++, ubuntu-latest) (push) Waiting to run
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (cl, Windows MSVC, windows-latest) (push) Waiting to run
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (gcc, Linux GCC, ubuntu-latest) (push) Waiting to run
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (llvm, llvm-cov gcov, Linux Clang, ubuntu-latest) (push) Waiting to run
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (llvm, llvm-cov gcov, MacOS clang, macos-latest) (push) Waiting to run
Build / Test modules (llvm, ubuntu-latest) (push) Waiting to run
Documentation / documentation (push) Waiting to run
The file "sw.js" was removed mistakenly

Fixed: https://github.com/ArthurSonzogni/FTXUI/issues/1098
2025-08-18 20:50:31 +02:00
ArthurSonzogni
d20b84f720 Fix receiver includes.
Some checks are pending
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (cl, cl, windows-latest) (push) Waiting to run
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (clang, clang++, macos-latest) (push) Waiting to run
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (clang, clang++, ubuntu-latest) (push) Waiting to run
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (gcc, g++, macos-latest) (push) Waiting to run
Build / Bazel, ${{ matrix.cxx }}, ${{ matrix.os }} (gcc, g++, ubuntu-latest) (push) Waiting to run
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (cl, Windows MSVC, windows-latest) (push) Waiting to run
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (gcc, Linux GCC, ubuntu-latest) (push) Waiting to run
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (llvm, llvm-cov gcov, Linux Clang, ubuntu-latest) (push) Waiting to run
Build / CMake, ${{ matrix.compiler }}, ${{ matrix.os }} (llvm, llvm-cov gcov, MacOS clang, macos-latest) (push) Waiting to run
Build / Test modules (llvm, ubuntu-latest) (push) Waiting to run
Documentation / documentation (push) Waiting to run
2025-08-17 21:08:36 +02:00
ArthurSonzogni
0dde21f09e Fix Bazel build. 2025-08-17 19:23:53 +02:00
17 changed files with 518 additions and 104 deletions

212
.github/copilot-instructions.md vendored Normal file
View File

@@ -0,0 +1,212 @@
# FTXUI - Functional Terminal (X) User Interface
FTXUI is a cross-platform C++ library for terminal-based user interfaces with a functional programming approach, inspired by React.
**ALWAYS reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the information here.**
## Working Effectively
### Build System Setup and Commands
- Bootstrap and build the repository:
```bash
# Basic build (library only) - fast
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel $(nproc)
# Build time: ~30 seconds. NEVER CANCEL. Set timeout to 120+ seconds.
# Build with examples
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DFTXUI_BUILD_EXAMPLES=ON
cmake --build build --parallel $(nproc)
# Build time: ~70 seconds. NEVER CANCEL. Set timeout to 180+ seconds.
# Build with examples and tests
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DFTXUI_BUILD_EXAMPLES=ON -DFTXUI_BUILD_TESTS=ON
cmake --build build --parallel $(nproc)
# Build time: ~113 seconds (includes GoogleTest download). NEVER CANCEL. Set timeout to 300+ seconds.
```
- Alternative build with Ninja (faster):
```bash
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DFTXUI_BUILD_EXAMPLES=ON
ninja -C build
# Build time: ~62 seconds. NEVER CANCEL. Set timeout to 180+ seconds.
```
- Run unit tests:
```bash
# Configure with tests enabled first, then:
cd build && ctest --output-on-failure
# Test time: ~4 seconds (302 tests). NEVER CANCEL. Set timeout to 60+ seconds.
```
### Bazel Support
- FTXUI also supports Bazel build system
- **WARNING**: Bazel may fail due to network connectivity issues in sandboxed environments
- If Bazel is available:
```bash
bazel build //... # Build everything
bazel test //... # Run tests
```
## Validation
### Manual Testing After Changes
- **ALWAYS manually validate changes by building and running examples after making code modifications**
- Run example applications to verify functionality:
```bash
# Build an example first
cmake --build build --target ftxui_example_border
# Run examples (they are interactive, use timeout to terminate)
timeout 2s build/examples/dom/ftxui_example_border
timeout 2s build/examples/dom/ftxui_example_color_gallery
timeout 2s build/examples/component/ftxui_example_button
```
- Examples should produce visual terminal output with borders, colors, and UI components
- **CRITICAL**: Always run at least one DOM example and one Component example to verify both modules work
### Code Quality and Formatting
- Always run formatting before committing:
```bash
./tools/format.sh
# Format time: ~7 seconds. NEVER CANCEL. Set timeout to 60+ seconds.
```
- The format script adds license headers and runs clang-format on all source files
- **Required**: Run formatting or the CI (.github/workflows/build.yaml) will fail
### Build Validation Requirements
- ALWAYS build with both `-DFTXUI_BUILD_EXAMPLES=ON` and `-DFTXUI_BUILD_TESTS=ON` when making changes
- Run the complete test suite with `ctest --output-on-failure`
- All 302 tests must pass
- **Scenario Testing**: Run at least these validation scenarios:
1. Build library only (basic validation)
2. Build with examples and run 2-3 different examples
3. Build with tests and run complete test suite
4. Run formatting tool to ensure code style compliance
## Project Structure
### Key Directories
```
/home/runner/work/FTXUI/FTXUI/
├── include/ftxui/ # Public header files
│ ├── component/ # Interactive component headers
│ ├── dom/ # DOM element headers
│ ├── screen/ # Screen and rendering headers
│ └── util/ # Utility headers
├── src/ftxui/ # Implementation files
│ ├── component/ # Interactive components (buttons, menus, etc.)
│ ├── dom/ # DOM elements (layout, styling, text)
│ ├── screen/ # Screen rendering and terminal handling
│ └── util/ # Utilities
├── examples/ # Example applications
│ ├── component/ # Interactive component examples
│ └── dom/ # DOM element examples
├── cmake/ # CMake configuration files
├── tools/ # Development tools (formatting, etc.)
└── .github/workflows/ # CI/CD configuration
```
### Core Library Modules
FTXUI is organized into three main modules that depend on each other:
```
┌component──┐ (Interactive UI components)
│┌dom──────┐│ (Layout and styling elements)
││┌screen─┐││ (Terminal rendering and input)
└┴┴───────┴┴┘
```
1. **screen**: Low-level terminal handling, colors, pixels, input
2. **dom**: Layout elements (hbox, vbox, text, borders, etc.)
3. **component**: Interactive components (buttons, menus, input fields)
### CMake Build Options
| Option | Description | Default |
|-----------------------------------|----------------------------------|---------|
| FTXUI_BUILD_EXAMPLES | Build example applications | OFF |
| FTXUI_BUILD_DOCS | Build documentation | OFF |
| FTXUI_BUILD_TESTS | Build and enable tests | OFF |
| FTXUI_BUILD_MODULES | Build C++20 modules | OFF |
| FTXUI_ENABLE_INSTALL | Generate install targets | ON |
| FTXUI_MICROSOFT_TERMINAL_FALLBACK | Windows terminal compatibility | ON/OFF |
## Common Tasks
### Building Examples
```bash
# Build specific examples
cmake --build build --target ftxui_example_border
cmake --build build --target ftxui_example_button
cmake --build build --target ftxui_example_menu
# List all available examples
find build -name "ftxui_example_*" -type f
```
### Running Tests
```bash
# Run all tests
cd build && ctest
# Run tests with verbose output
cd build && ctest --verbose
# Run specific test pattern
cd build && ctest -R "Button" --verbose
```
### Working with Source Code
- **Component Development**: Modify files in `src/ftxui/component/` for interactive elements
- **DOM Development**: Modify files in `src/ftxui/dom/` for layout and styling
- **Screen Development**: Modify files in `src/ftxui/screen/` for terminal rendering
- **Adding Examples**: Add new `.cpp` files in `examples/component/` or `examples/dom/`
- **Header Files**: Public APIs are in `include/ftxui/[module]/`
### Integration Patterns
When adding FTXUI to a project, use CMake FetchContent (recommended):
```cmake
include(FetchContent)
FetchContent_Declare(ftxui
GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui
GIT_TAG v6.1.9
)
FetchContent_MakeAvailable(ftxui)
target_link_libraries(your_target PRIVATE
ftxui::component # For interactive components
ftxui::dom # For layout elements
ftxui::screen # For basic rendering
)
```
## Troubleshooting
### Build Issues
- If CMake configuration fails, ensure C++20 support: `cmake --version` (need 3.12+)
- If Ninja build fails, fall back to Make: `cmake -S . -B build` (without `-G Ninja`)
- If tests fail to build, GoogleTest download might have failed - check network connectivity
- Build artifacts are in `build/` directory - delete with `rm -rf build` to clean
### Example Issues
- Examples are interactive terminal applications - use `timeout` to terminate them
- If examples don't display correctly, terminal might not support colors/Unicode
- Examples require terminal size of at least 80x24 for proper display
### Formatting Issues
- Format script requires clang-format to be installed
- If format script fails, check that source files are not read-only
- Format script modifies files in-place - commit changes afterwards
## Critical Reminders
- **NEVER CANCEL long-running builds** - they may take 2-3 minutes
- **ALWAYS run the formatting tool** before committing changes
- **ALWAYS build and test examples** when making component/dom changes
- **SET APPROPRIATE TIMEOUTS**: 300+ seconds for builds, 60+ seconds for tests
- **BUILD TIMING EXPECTATIONS**:
- Basic library: ~30 seconds
- With examples: ~70 seconds
- With examples + tests: ~113 seconds (first time, includes GoogleTest download)
- Subsequent builds: ~60-70 seconds
- Tests execution: ~4 seconds
- Formatting: ~7 seconds

2
.gitignore vendored
View File

@@ -28,6 +28,7 @@ out/
# .github directory: # .github directory:
!.github/**/*.yaml !.github/**/*.yaml
!.github/**/*.yml !.github/**/*.yml
!.github/**/*.md
# cmake directory: # cmake directory:
!cmake/**/*.in !cmake/**/*.in
@@ -70,3 +71,4 @@ out/
# tools directory: # tools directory:
!tools/**/*.sh !tools/**/*.sh
!tools/**/*.cpp !tools/**/*.cpp
build/

View File

@@ -169,13 +169,15 @@ ftxui_cc_library(
"src/ftxui/component/util.cpp", "src/ftxui/component/util.cpp",
"src/ftxui/component/window.cpp", "src/ftxui/component/window.cpp",
# Private header from ftxui:dom. # Private header from ftxui:dom.
"src/ftxui/dom/node_decorator.hpp", "src/ftxui/dom/node_decorator.hpp",
# Private header from ftxui:screen. # Private header from ftxui:screen.
"src/ftxui/screen/string_internal.hpp", "src/ftxui/screen/string_internal.hpp",
"src/ftxui/screen/util.hpp", "src/ftxui/screen/util.hpp",
# Private header.
"include/ftxui/util/warn_windows_macro.hpp",
], ],
hdrs = [ hdrs = [
"include/ftxui/component/animation.hpp", "include/ftxui/component/animation.hpp",

View File

@@ -29,6 +29,8 @@ Next
### Component ### Component
- Fix ScreenInteractive::FixedSize screen stomps on the preceding terminal - Fix ScreenInteractive::FixedSize screen stomps on the preceding terminal
output. Thanks @zozowell in #1064. output. Thanks @zozowell in #1064.
- Fix vertical `ftxui::Slider`. The "up" key was previously decreasing the
value. Thanks @its-pablo in #1093 for reporting the issue.
6.1.9 (2025-05-07) 6.1.9 (2025-05-07)

View File

@@ -178,8 +178,8 @@ include(cmake/ftxui_install.cmake)
include(cmake/ftxui_package.cmake) include(cmake/ftxui_package.cmake)
include(cmake/ftxui_modules.cmake) include(cmake/ftxui_modules.cmake)
add_subdirectory(doc)
add_subdirectory(examples) add_subdirectory(examples)
add_subdirectory(doc)
# You can generate ./examples_modules/ by running # You can generate ./examples_modules/ by running
# ./tools/generate_examples_modules.sh # ./tools/generate_examples_modules.sh

View File

@@ -1,3 +1,4 @@
<p align="center"> <p align="center">
<img src="https://github.com/ArthurSonzogni/FTXUI/assets/4759106/6925b6da-0a7e-49d9-883c-c890e1f36007" alt="Demo image"></img> <img src="https://github.com/ArthurSonzogni/FTXUI/assets/4759106/6925b6da-0a7e-49d9-883c-c890e1f36007" alt="Demo image"></img>
<br/> <br/>
@@ -362,6 +363,8 @@ Feel free to add your projects here:
- [FTB - tertminal file browser](https://github.com/Cyxuan0311/FTB) - [FTB - tertminal file browser](https://github.com/Cyxuan0311/FTB)
- [openJuice](https://github.com/mikomikotaishi/openJuice) - [openJuice](https://github.com/mikomikotaishi/openJuice)
- [SHOOT!](https://github.com/ShingZhanho/ENGG1340-Project-25Spring) - [SHOOT!](https://github.com/ShingZhanho/ENGG1340-Project-25Spring)
- [VerifySN (Fast Hash Tool)](https://github.com/d06i/verifySN)
- [tic-tac-toe](https://github.com/birland/tic-tac-toe)
### [cpp-best-practices/game_jam](https://github.com/cpp-best-practices/game_jam) ### [cpp-best-practices/game_jam](https://github.com/cpp-best-practices/game_jam)

View File

@@ -1,24 +1,104 @@
@page installation_conan Conan @page installation_conan Conan
@tableofcontents
Unofficial recipe for FTXUI exists on Conan Center: FTXUI can be easily obtained and integrated into your project using the Conan package manager.
<https://conan.io/center/recipes/ftxui>
## Prerequisites
First, ensure that Conan is installed on your system. If not, you can install it via pip:
```powershell
pip install conan
```
Conan often works in tandem with CMake, so you will need to have CMake installed as well. Once you have confirmed both Conan and CMake are installed, create a project directory, for example, `ftxui-demo`:
```powershell
mkdir C:\ftxui-demo
cd C:\ftxui-demo
```
## Configuration
After ensuring your environment is set up correctly, create a Conan configuration file `conanfile.txt`. This file is used to declare your project's dependencies. The community-maintained package for FTXUI can be found on [Conan Center](https://conan.io/center/recipes/ftxui).
> [!note] > [!note]
> This is an unofficial recipe. That means it is not maintained by the FTXUI > This is an unofficial build script. This means it is not maintained by the FTXUI
> team, but by the community. The package maintainers seems to actively update > team but by the community. The package maintainer appears to actively update it
> the package to the latest version. Thanks to the maintainers for their work! > to the latest releases. Many thanks to the maintainer for their work!
@todo If you are familiar with the process, please consider adding an "official" build script to Conan Center.
This could be a GitHub Action that automatically updates Conan Center upon new releases.
@todo Add instructions on how to use the conan recipe. ```ini
[requires]
ftxui/6.0.2
@todo Please consider adding an "official" recipe to Conan Center if know how. [generators]
It could be a github action that will automatically update the conan center CMakeDeps
when a new release is made. CMakeToolchain
[layout]
cmake_layout
```
## Install Dependencies and Build
Once configured, run the following command to install FTXUI and its dependencies:
```powershell
conan install . --output-folder=build --build=missing
```
This will download and install `ftxui/6.0.2` along with all its dependencies from Conan's remote repositories.
After the installation completes, you can test it by creating a `demo.cpp` file in your project directory:
```cpp
#include <ftxui/screen/screen.hpp>
#include <ftxui/dom/elements.hpp>
#include <iostream>
int main() {
using namespace ftxui;
auto document = hbox({
text(" Hello "),
text("FTXUI ") | bold | color(Color::Red),
text(" world! ")
});
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
std::cout << screen.ToString() << std::endl;
return 0;
}
```
If the test is successful, you can then create a `CMakeLists.txt` file in the project directory:
```cmake
cmake_minimum_required(VERSION 3.20)
project(ftxui-demo)
# Set the C++ standard
set(CMAKE_CXX_STANDARD 20)
# Find the FTXUI package installed via Conan
find_package(ftxui CONFIG REQUIRED)
# Create the executable
add_executable(demo demo.cpp)
# Link the executable to the FTXUI library
target_link_libraries(demo PRIVATE ftxui::component)
```
@todo 考虑到中国多数地区使用Conan很有可能遇到各种网络问题我想做一个定制的版本说明但是我对conan的了解有限再加上没有找到合适的资料因此这个计划短暂的被搁置了如果您知道方法欢迎在[中文版本](xiaoditx.girhub.io/public/docs/ftxui%E4%B8%AD%E6%96%87%E7%BF%BB%E8%AF%91/installation/conan/)的下方留下评论以提醒我
---
<div class="section_buttons"> <div class="section_buttons">
| Previous | | Previous |
|:------------------| |:------------------|
| [Getting Started](getting-started.html) | | [Getting Started](getting-started.html) |
</div> </div>

View File

@@ -17,10 +17,12 @@ add_subdirectory(dom)
if (EMSCRIPTEN) if (EMSCRIPTEN)
get_property(EXAMPLES GLOBAL PROPERTY FTXUI::EXAMPLES) get_property(EXAMPLES GLOBAL PROPERTY FTXUI::EXAMPLES)
foreach(file foreach(file
"index.css"
"index.html" "index.html"
"index.mjs" "index.mjs"
"index.css" "run_webassembly.py"
"run_webassembly.py") "sw.js"
)
configure_file(${file} ${file}) configure_file(${file} ${file})
endforeach(file) endforeach(file)
endif() endif()

View File

@@ -34,8 +34,8 @@ int main() {
int value = 50; int value = 50;
// clang-format off // clang-format off
auto btn_dec_01 = Button("-1", [&] { value += 1; }, Style()); auto btn_dec_01 = Button("-1", [&] { value -= 1; }, Style());
auto btn_inc_01 = Button("+1", [&] { value -= 1; }, Style()); auto btn_inc_01 = Button("+1", [&] { value += 1; }, Style());
auto btn_dec_10 = Button("-10", [&] { value -= 10; }, Style()); auto btn_dec_10 = Button("-10", [&] { value -= 10; }, Style());
auto btn_inc_10 = Button("+10", [&] { value += 10; }, Style()); auto btn_inc_10 = Button("+10", [&] { value += 10; }, Style());
// clang-format on // clang-format on

View File

@@ -1,15 +1,19 @@
@import url(https://fonts.googleapis.com/css?family=Khula:700); @import url(https://fonts.googleapis.com/css?family=Khula:700);
html {
--toc-width: 250px;
}
body { body {
background-color:#EEE; background-color: #EEE;
padding:0px; padding: 0px;
margin:0px; margin: 0px;
font-family: Khula, Helvetica, sans-serif; font-family: Khula, Helvetica, sans-serif;
font-size: 130%; font-size: 130%;
} }
.page { .page {
max-width:1300px; max-width: 1300px;
margin: auto; margin: auto;
padding: 10px; padding: 10px;
} }
@@ -20,7 +24,7 @@ a {
margin: 0 -.25rem; margin: 0 -.25rem;
padding: 0 .25rem; padding: 0 .25rem;
transition: color .3s ease-in-out, transition: color .3s ease-in-out,
box-shadow .3s ease-in-out; box-shadow .3s ease-in-out;
} }
a:hover { a:hover {
@@ -30,45 +34,48 @@ a:hover {
h1 { h1 {
text-decoration: underline; text-decoration: underline;
width:100%; width: 100%;
background-color: rgba(100,100,255,0.5); background-color: rgba(100, 100, 255, 0.5);
padding: 10px; padding: 10px;
margin: 0; margin: 0;
} }
#selectExample { #selectExample {
flex:1; flex: 1;
} }
#selectExample, #selectExample option { #selectExample,
#selectExample option {
font-size: 16px; font-size: 16px;
font-family: sans-serif; font-family: sans-serif;
font-weight: 700; font-weight: 700;
line-height: 1.3; line-height: 1.3;
border:0px; border: 0px;
background-color: #bbb; background-color: #bbb;
color:black; color: black;
} }
#selectExample:focus { #selectExample:focus {
outline:none; outline: none;
} }
#terminal { #terminal {
width:100%; width: 100%;
height 500px; height 500px;
height: calc(clamp(200px, 100vh - 300px, 900px)); height: calc(clamp(200px, 100vh - 300px, 900px));
overflow: hidden; overflow: hidden;
border:none; border: none;
background-color:black; padding: 10px;
margin: 10px;
} }
#terminalContainer { #terminalContainer {
overflow: hidden; overflow: hidden;
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 2px 10px 0px rgba(0,0,0,0.75), box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.75),
0px 2px 80px 0px rgba(0,0,0,0.50); 0px 2px 80px 0px rgba(0, 0, 0, 0.50);
background-color: black;
} }
.fakeButtons { .fakeButtons {
@@ -76,7 +83,7 @@ h1 {
width: 10px; width: 10px;
border-radius: 50%; border-radius: 50%;
border: 1px solid #000; border: 1px solid #000;
margin:6px; margin: 6px;
background-color: #ff3b47; background-color: #ff3b47;
border-color: #9d252b; border-color: #9d252b;
display: inline-block; display: inline-block;
@@ -95,13 +102,79 @@ h1 {
} }
.fakeMenu { .fakeMenu {
display:flex; display: flex;
flex-direction: row; flex-direction: row;
width:100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
height: 25px; height: 25px;
background-color: #bbb; background-color: #bbb;
color:black; color: black;
margin: 0 auto; margin: 0 auto;
overflow: hidden; overflow: hidden;
} }
.toc-container {
position: fixed;
left: 0;
top: 0;
bottom: 0;
width: var(--toc-width);
background: white;
padding: 0;
overflow-y: auto;
overflow-x: hidden;
scrollbar-width: thin;
}
.toc-title {
font-weight: bold;
margin-bottom: 5px;
font-size: 0.9em;
color: #555;
position: sticky;
transition: position 1.0s ease-in-out;
top: 0;
z-index: 1;
padding: 20px;
margin: 0;
border-bottom: 1px solid #ddd;
/* Gradient background for the title */
background-color: #f0f0f0;
}
.toc-item {
padding: 3px 8px;
margin: 0;
cursor: pointer;
font-size: 0.85em;
border-radius: 3px;
transition: background 0.2s;
}
.toc-item:hover {
background: #f0f0f0;
}
.toc-item.selected {
background: #e0e0e0;
font-weight: bold;
}
@media (max-width: 1024px) {
.toc-container {
display: none;
}
.page {
margin-left: 0;
}
}
@media (min-width: 1025px) {
.page {
margin-left: calc(var(--toc-width) + 20px);
}
}

View File

@@ -9,13 +9,18 @@
<script type="module" src="index.mjs"></script> <script type="module" src="index.mjs"></script>
</head> </head>
<body> <body>
<div class="toc-container">
<div class="toc-list"></div>
</div>
<script id="example_script"></script> <script id="example_script"></script>
<div class="page"> <div class="page">
<p> <p>
<a href="https://github.com/ArthurSonzogni/FTXUI">FTXUI</a> is a simple <a href="https://github.com/ArthurSonzogni/FTXUI">FTXUI</a> is a simple
functional C++ library for terminal user interface. <br/> functional C++ library for terminal user interface. <br/>
This showcases the: <a href="https://github.com/ArthurSonzogni/FTXUI/tree/master/examples">./example/</a> folder. <br/> This showcases the: <a
href="https://github.com/ArthurSonzogni/FTXUI/tree/master/examples">./example/</a>
folder. See <a id="source">source</a>.
</p> </p>
<div id="terminalContainer"> <div id="terminalContainer">

View File

@@ -92,6 +92,69 @@ window.Module = {
}, },
}; };
const source = document.querySelector("#source");
source.href = "https://github.com/ArthurSonzogni/FTXUI/blob/main/examples/" + example + ".cpp";
const words = example.split('/') const words = example.split('/')
words[1] = "ftxui_example_" + words[1] + ".js" words[1] = "ftxui_example_" + words[1] + ".js"
document.querySelector("#example_script").src = words.join('/'); document.querySelector("#example_script").src = words.join('/');
// Table of Contents (TOC) for quick navigation.
// Get select element
const selectEl = document.querySelector('select#selectExample');
if (!selectEl) {
console.error('select#selectExample not found');
} else {
// Get TOC container
const tocContainer = document.querySelector('.toc-container');
const tocList = tocContainer.querySelector('.toc-list');
// Group options by directory
const groupedOptions = Array.from(selectEl.options).reduce((acc, option) => {
const [dir, file] = option.text.split('/');
if (!acc[dir]) {
acc[dir] = [];
}
acc[dir].push({ option, file });
return acc;
}, {});
// Generate TOC items
for (const dir in groupedOptions) {
const dirContainer = document.createElement('div');
const dirHeader = document.createElement('div');
dirHeader.textContent = dir;
dirHeader.className = 'toc-title';
dirContainer.appendChild(dirHeader);
groupedOptions[dir].forEach(({ option, file }) => {
const tocItem = document.createElement('div');
tocItem.textContent = file;
tocItem.className = 'toc-item';
if (selectEl.options[selectEl.selectedIndex].value === option.value) {
tocItem.classList.add('selected');
}
// Click handler
tocItem.addEventListener('click', () => {
for(let i=0; i<selectEl.options.length; ++i) {
if (selectEl.options[i].value == option.value) {
selectEl.selectedIndex = i;
break;
}
}
history.pushState({}, "", "?file=" + option.value);
location.reload();
});
dirContainer.appendChild(tocItem);
});
tocList.appendChild(dirContainer);
}
}''

View File

@@ -4,14 +4,14 @@
#ifndef FTXUI_COMPONENT_RECEIVER_HPP_ #ifndef FTXUI_COMPONENT_RECEIVER_HPP_
#define FTXUI_COMPONENT_RECEIVER_HPP_ #define FTXUI_COMPONENT_RECEIVER_HPP_
#include <ftxui/util/warn_windows_macro.h>
#include <algorithm> // for copy, max #include <algorithm> // for copy, max
#include <atomic> // for atomic, __atomic_base #include <atomic> // for atomic, __atomic_base
#include <condition_variable> // for condition_variable #include <condition_variable> // for condition_variable
#include <memory> // for unique_ptr, make_unique #include <ftxui/util/warn_windows_macro.hpp>
#include <mutex> // for mutex, unique_lock #include <memory> // for unique_ptr, make_unique
#include <queue> // for queue #include <mutex> // for mutex, unique_lock
#include <utility> // for move #include <queue> // for queue
#include <utility> // for move
namespace ftxui { namespace ftxui {

View File

@@ -60,7 +60,7 @@ class Screen : public Image {
BarBlinking = 5, BarBlinking = 5,
Bar = 6, Bar = 6,
}; };
Shape shape; Shape shape = Hidden;
}; };
Cursor cursor() const { return cursor_; } Cursor cursor() const { return cursor_; }

View File

@@ -33,6 +33,20 @@ Decorator flexDirection(Direction direction) {
return xflex; // NOT_REACHED() return xflex; // NOT_REACHED()
} }
Direction Opposite(Direction d) {
switch (d) {
case Direction::Up:
return Direction::Down;
case Direction::Down:
return Direction::Up;
case Direction::Left:
return Direction::Right;
case Direction::Right:
return Direction::Left;
}
return d; // NOT_REACHED()
}
template <class T> template <class T>
class SliderBase : public SliderOption<T>, public ComponentBase { class SliderBase : public SliderOption<T>, public ComponentBase {
public: public:
@@ -47,59 +61,15 @@ class SliderBase : public SliderOption<T>, public ComponentBase {
flexDirection(this->direction) | reflect(gauge_box_) | gauge_color; flexDirection(this->direction) | reflect(gauge_box_) | gauge_color;
} }
void OnLeft() { void OnDirection(Direction pressed) {
switch (this->direction) { if (pressed == this->direction) {
case Direction::Right: this->value() += this->increment();
this->value() -= this->increment(); return;
break;
case Direction::Left:
this->value() += this->increment();
break;
case Direction::Up:
case Direction::Down:
break;
} }
}
void OnRight() { if (pressed == Opposite(this->direction)) {
switch (this->direction) { this->value() -= this->increment();
case Direction::Right: return;
this->value() += this->increment();
break;
case Direction::Left:
this->value() -= this->increment();
break;
case Direction::Up:
case Direction::Down:
break;
}
}
void OnUp() {
switch (this->direction) {
case Direction::Up:
this->value() -= this->increment();
break;
case Direction::Down:
this->value() += this->increment();
break;
case Direction::Left:
case Direction::Right:
break;
}
}
void OnDown() {
switch (this->direction) {
case Direction::Down:
this->value() += this->increment();
break;
case Direction::Up:
this->value() -= this->increment();
break;
case Direction::Left:
case Direction::Right:
break;
} }
} }
@@ -110,16 +80,16 @@ class SliderBase : public SliderOption<T>, public ComponentBase {
T old_value = this->value(); T old_value = this->value();
if (event == Event::ArrowLeft || event == Event::Character('h')) { if (event == Event::ArrowLeft || event == Event::Character('h')) {
OnLeft(); OnDirection(Direction::Left);
} }
if (event == Event::ArrowRight || event == Event::Character('l')) { if (event == Event::ArrowRight || event == Event::Character('l')) {
OnRight(); OnDirection(Direction::Right);
} }
if (event == Event::ArrowUp || event == Event::Character('k')) { if (event == Event::ArrowUp || event == Event::Character('k')) {
OnDown(); OnDirection(Direction::Up);
} }
if (event == Event::ArrowDown || event == Event::Character('j')) { if (event == Event::ArrowDown || event == Event::Character('j')) {
OnUp(); OnDirection(Direction::Down);
} }
this->value() = std::max(this->min(), std::min(this->max(), this->value())); this->value() = std::max(this->min(), std::min(this->max(), this->value()));

View File

@@ -21,8 +21,8 @@ class TaskRunner {
auto PostTask(Task task) -> void; auto PostTask(Task task) -> void;
/// Schedules a task to be executed after a certain duration. /// Schedules a task to be executed after a certain duration.
auto PostDelayedTask(Task task, std::chrono::steady_clock::duration duration) auto PostDelayedTask(Task task,
-> void; std::chrono::steady_clock::duration duration) -> void;
/// Runs the tasks in the queue, return the delay until the next delayed task /// Runs the tasks in the queue, return the delay until the next delayed task
/// can be executed. /// can be executed.

View File

@@ -81,7 +81,7 @@ class Size : public Node {
} // namespace } // namespace
/// @brief Apply a constraint on the size of an element. /// @brief Apply a constraint on the size of an element.
/// @param direction Whether the WIDTH of the HEIGHT of the element must be /// @param direction Whether the WIDTH or the HEIGHT of the element must be
/// constrained. /// constrained.
/// @param constraint The type of constaint. /// @param constraint The type of constaint.
/// @param value The value. /// @param value The value.