mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2025-09-29 16:39:34 +08:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
75cd2b0fca | ||
![]() |
0a5e9f2a2f | ||
![]() |
66cdf9b2a5 | ||
![]() |
84287eb217 | ||
![]() |
535974d291 | ||
![]() |
753502998c | ||
![]() |
31b5fac9c5 | ||
![]() |
76b2f17488 | ||
![]() |
c5ef0c7fb5 |
39
.github/workflows/release.yaml
vendored
Normal file
39
.github/workflows/release.yaml
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
create:
|
||||||
|
tags:
|
||||||
|
-v*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- uses: seanmiddleditch/gha-setup-ninja@master
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: >
|
||||||
|
mkdir build;
|
||||||
|
cd build;
|
||||||
|
cmake ..
|
||||||
|
-DCMAKE_CXX_COMPILER=clang++
|
||||||
|
-DFTXUI_BUILD_DOCS=OFF
|
||||||
|
-DFTXUI_BUILD_EXAMPLES=OFF
|
||||||
|
-DFTXUI_BUILD_TESTS=OFF
|
||||||
|
-DFTXUI_BUILD_TESTS_FUZZER=OFF
|
||||||
|
-DFTXUI_ENABLE_INSTALL=ON;
|
||||||
|
cmake --build . --config Release;
|
||||||
|
make package;
|
||||||
|
|
||||||
|
- name: Upload
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
files: build/ftxui-*
|
||||||
|
draft: false
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
14
CHANGELOG.md
14
CHANGELOG.md
@@ -1,5 +1,19 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## Current
|
||||||
|
|
||||||
|
## 0.10 (2021-09-30)
|
||||||
|
|
||||||
|
## Bug
|
||||||
|
- Fix the automated merge of borders.
|
||||||
|
|
||||||
|
### Dom
|
||||||
|
- `vscroll_indicator`. Show a scrollbar indicator on the right.
|
||||||
|
|
||||||
|
### Component
|
||||||
|
- `Maybe`: Display an component conditionnally based on a boolean.
|
||||||
|
- `Dropdown`: A dropdown select list.
|
||||||
|
|
||||||
## 0.9 (2021-09-26)
|
## 0.9 (2021-09-26)
|
||||||
|
|
||||||
The initial release where changelog where written.
|
The initial release where changelog where written.
|
||||||
|
@@ -4,7 +4,7 @@ include(cmake/ftxui_git_version.cmake)
|
|||||||
|
|
||||||
project(ftxui
|
project(ftxui
|
||||||
LANGUAGES CXX
|
LANGUAGES CXX
|
||||||
VERSION 0.9.${git_version}
|
VERSION 0.10.${git_version}
|
||||||
)
|
)
|
||||||
|
|
||||||
option(FTXUI_BUILD_DOCS "Set to ON to build tests" ON)
|
option(FTXUI_BUILD_DOCS "Set to ON to build tests" ON)
|
||||||
@@ -57,14 +57,15 @@ add_library(dom STATIC
|
|||||||
src/ftxui/dom/frame.cpp
|
src/ftxui/dom/frame.cpp
|
||||||
src/ftxui/dom/gauge.cpp
|
src/ftxui/dom/gauge.cpp
|
||||||
src/ftxui/dom/graph.cpp
|
src/ftxui/dom/graph.cpp
|
||||||
src/ftxui/dom/hbox.cpp
|
|
||||||
src/ftxui/dom/gridbox.cpp
|
src/ftxui/dom/gridbox.cpp
|
||||||
|
src/ftxui/dom/hbox.cpp
|
||||||
src/ftxui/dom/hflow.cpp
|
src/ftxui/dom/hflow.cpp
|
||||||
src/ftxui/dom/inverted.cpp
|
src/ftxui/dom/inverted.cpp
|
||||||
src/ftxui/dom/node.cpp
|
src/ftxui/dom/node.cpp
|
||||||
src/ftxui/dom/node_decorator.cpp
|
src/ftxui/dom/node_decorator.cpp
|
||||||
src/ftxui/dom/paragraph.cpp
|
src/ftxui/dom/paragraph.cpp
|
||||||
src/ftxui/dom/reflect.cpp
|
src/ftxui/dom/reflect.cpp
|
||||||
|
src/ftxui/dom/scroll_indicator.cpp
|
||||||
src/ftxui/dom/separator.cpp
|
src/ftxui/dom/separator.cpp
|
||||||
src/ftxui/dom/size.cpp
|
src/ftxui/dom/size.cpp
|
||||||
src/ftxui/dom/spinner.cpp
|
src/ftxui/dom/spinner.cpp
|
||||||
@@ -87,8 +88,10 @@ add_library(component STATIC
|
|||||||
src/ftxui/component/checkbox.cpp
|
src/ftxui/component/checkbox.cpp
|
||||||
src/ftxui/component/component.cpp
|
src/ftxui/component/component.cpp
|
||||||
src/ftxui/component/container.cpp
|
src/ftxui/component/container.cpp
|
||||||
|
src/ftxui/component/dropdown.cpp
|
||||||
src/ftxui/component/event.cpp
|
src/ftxui/component/event.cpp
|
||||||
src/ftxui/component/input.cpp
|
src/ftxui/component/input.cpp
|
||||||
|
src/ftxui/component/maybe.cpp
|
||||||
src/ftxui/component/menu.cpp
|
src/ftxui/component/menu.cpp
|
||||||
src/ftxui/component/radiobox.cpp
|
src/ftxui/component/radiobox.cpp
|
||||||
src/ftxui/component/radiobox.cpp
|
src/ftxui/component/radiobox.cpp
|
||||||
@@ -120,10 +123,6 @@ if (FTXUI_BUILD_TESTS AND ${CMAKE_VERSION} VERSION_GREATER "3.11.4")
|
|||||||
include(cmake/ftxui_test.cmake)
|
include(cmake/ftxui_test.cmake)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FTXUI_ENABLE_INSTALL)
|
|
||||||
include(cmake/ftxui_install.cmake)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(FTXUI_BUILD_EXAMPLES)
|
if(FTXUI_BUILD_EXAMPLES)
|
||||||
add_subdirectory(examples)
|
add_subdirectory(examples)
|
||||||
endif()
|
endif()
|
||||||
@@ -134,3 +133,9 @@ endif()
|
|||||||
|
|
||||||
include(cmake/iwyu.cmake)
|
include(cmake/iwyu.cmake)
|
||||||
include(cmake/ftxui_export.cmake)
|
include(cmake/ftxui_export.cmake)
|
||||||
|
|
||||||
|
if(FTXUI_ENABLE_INSTALL)
|
||||||
|
include(cmake/ftxui_install.cmake)
|
||||||
|
include(cmake/ftxui_package.cmake)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
41
README.md
41
README.md
@@ -1,24 +1,29 @@
|
|||||||
# FTXUI
|
<p align="center">
|
||||||
|
<img src="./examples/component/homescreen.gif" alt="Demo image"></img>
|
||||||
|
<br/>
|
||||||
|
<a href="#"><img src="https://img.shields.io/badge/c++-%2300599C.svg?style=flat&logo=c%2B%2B&logoColor=white"></img></a>
|
||||||
|
<a href="http://opensource.org/licenses/MIT"><img src="https://img.shields.io/github/license/arthursonzogni/FTXUI?color=black"></img></a>
|
||||||
|
<a href="#"><img src="https://img.shields.io/github/stars/ArthurSonzogni/FTXUI"></img></a>
|
||||||
|
<a href="#"><img src="https://img.shields.io/github/forks/ArthurSonzogni/FTXUI"></img></a>
|
||||||
|
<a href="#"><img src="https://img.shields.io/github/repo-size/ArthurSonzogni/FTXUI"></img></a>
|
||||||
|
<a href="https://github.com/ArthurSonzogni/FTXUI/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>
|
||||||
|
|
||||||
[![issues][badge.issues]][issues]
|
<br/>
|
||||||
[![license][badge.license]][license]
|
<a href="https://github.com/ArthurSonzogni/FTXUI/wiki">Documentation</a> ·
|
||||||
[![contributors][badge.contributors]][contributors]
|
<a href="https://github.com/ArthurSonzogni/FTXUI/issues">Report 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>
|
||||||
|
|
||||||
[badge.issues]: https://img.shields.io/github/issues-raw/arthursonzogni/FTXUI
|
</p>
|
||||||
[badge.license]: https://img.shields.io/github/license/arthursonzogni/FTXUI?color=black
|
|
||||||
[badge.contributors]: https://img.shields.io/github/contributors/arthursonzogni/FTXUI?color=blue
|
|
||||||
|
|
||||||
[issues]: https://github.com/ArthurSonzogni/FTXUI/issues
|
## FTXUI
|
||||||
[license]: http://opensource.org/licenses/MIT
|
|
||||||
[contributors]: https://github.com/ArthurSonzogni/FTXUI/graphs/contributors
|
|
||||||
|
|
||||||
**Functional Terminal (X) User interface**
|
<i>Functional Terminal (X) User interface</i>
|
||||||
|
|
||||||
A simple C++ library for terminal based user interface.
|
A simple C++ library for terminal based user interface.
|
||||||
|
|
||||||
## Demo:
|
|
||||||

|
|
||||||
|
|
||||||
## Feature
|
## Feature
|
||||||
* Functional style. Inspired by
|
* Functional style. Inspired by
|
||||||
[[1]](https://hackernoon.com/building-reactive-terminal-interfaces-in-c-d392ce34e649?gi=d9fb9ce35901)
|
[[1]](https://hackernoon.com/building-reactive-terminal-interfaces-in-c-d392ce34e649?gi=d9fb9ce35901)
|
||||||
@@ -48,7 +53,7 @@ A simple C++ library for terminal based user interface.
|
|||||||
[link.windows-msvc]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/windows-msvc.yaml
|
[link.windows-msvc]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/windows-msvc.yaml
|
||||||
[link.mac-clang]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/mac-clang.yaml
|
[link.mac-clang]: https://github.com/ArthurSonzogni/FTXUI/actions/workflows/mac-clang.yaml
|
||||||
|
|
||||||
## Example:
|
## Example
|
||||||
~~~cpp
|
~~~cpp
|
||||||
vbox({
|
vbox({
|
||||||
hbox({
|
hbox({
|
||||||
@@ -69,7 +74,7 @@ A simple C++ library for terminal based user interface.
|
|||||||
└────────────────────────────────────────────────────────────────────────────┘
|
└────────────────────────────────────────────────────────────────────────────┘
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
# Documentation:
|
# Documentation
|
||||||
|
|
||||||
- [Starter example project](https://github.com/ArthurSonzogni/ftxui-starter)
|
- [Starter example project](https://github.com/ArthurSonzogni/ftxui-starter)
|
||||||
- [Documentation](https://arthursonzogni.github.io/FTXUI/)
|
- [Documentation](https://arthursonzogni.github.io/FTXUI/)
|
||||||
@@ -94,11 +99,11 @@ Feel free to add your projects here:
|
|||||||
- [todoman](https://github.com/aaleino/todoman)
|
- [todoman](https://github.com/aaleino/todoman)
|
||||||
- [TimeAccumulator](https://github.com/asari555/TimeAccumulator)
|
- [TimeAccumulator](https://github.com/asari555/TimeAccumulator)
|
||||||
|
|
||||||
## Hosted on:
|
## Hosted on
|
||||||
* [github](https://github.com/ArthurSonzogni/ftxui)
|
* [github](https://github.com/ArthurSonzogni/ftxui)
|
||||||
* [gitlab](https://gitlab.com/ArthurSonzogni/ftxui)
|
* [gitlab](https://gitlab.com/ArthurSonzogni/ftxui)
|
||||||
|
|
||||||
## External package:
|
## External package
|
||||||
|
|
||||||
It is **highly** recommanded to use cmake FetchContent to depends on FTXUI. This
|
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.
|
way you can specify which commit you would like to depends on.
|
||||||
|
16
cmake/ftxui_package.cmake
Normal file
16
cmake/ftxui_package.cmake
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
set(CPACK_GENERATOR "DEB;External;RPM;STGZ;TBZ2;TGZ;TXZ;TZ;TZST;ZIP")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS " ")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE_URL "https://github.com/ArthurSonzogni/FTXUI/")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Arthur Sonzogni")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_VERSION ${PROJECT_VERSION})
|
||||||
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A simple C++ Terminal UI library")
|
||||||
|
set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/ArthurSonzogni/FTXUI/")
|
||||||
|
set(CPACK_PACKAGE_NAME "ftxui")
|
||||||
|
set(CPACK_PACKAGE_VENDOR "Arthur Sonzogni")
|
||||||
|
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
|
||||||
|
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
|
||||||
|
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
|
||||||
|
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
|
||||||
|
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
||||||
|
|
||||||
|
include(CPack)
|
@@ -2,19 +2,21 @@ set(DIRECTORY_LIB component)
|
|||||||
|
|
||||||
example(button)
|
example(button)
|
||||||
example(checkbox)
|
example(checkbox)
|
||||||
example(nested_screen)
|
|
||||||
example(checkbox_in_frame)
|
example(checkbox_in_frame)
|
||||||
example(composition)
|
example(composition)
|
||||||
|
example(dropdown)
|
||||||
example(gallery)
|
example(gallery)
|
||||||
example(homescreen)
|
example(homescreen)
|
||||||
example(input)
|
example(input)
|
||||||
|
example(maybe)
|
||||||
example(menu)
|
example(menu)
|
||||||
example(menu_in_frame)
|
|
||||||
example(menu2)
|
example(menu2)
|
||||||
example(menu_multiple)
|
|
||||||
example(menu_entries)
|
example(menu_entries)
|
||||||
|
example(menu_in_frame)
|
||||||
|
example(menu_multiple)
|
||||||
example(menu_style)
|
example(menu_style)
|
||||||
example(modal_dialog)
|
example(modal_dialog)
|
||||||
|
example(nested_screen)
|
||||||
example(print_key_press)
|
example(print_key_press)
|
||||||
example(radiobox)
|
example(radiobox)
|
||||||
example(radiobox_in_frame)
|
example(radiobox_in_frame)
|
||||||
|
@@ -24,7 +24,8 @@ int main(int argc, const char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto renderer = Renderer(container, [&] {
|
auto renderer = Renderer(container, [&] {
|
||||||
return container->Render() | frame | size(HEIGHT, LESS_THAN, 10) | border;
|
return container->Render() | vscroll_indicator | frame |
|
||||||
|
size(HEIGHT, LESS_THAN, 10) | border;
|
||||||
});
|
});
|
||||||
|
|
||||||
auto screen = ScreenInteractive::FitComponent();
|
auto screen = ScreenInteractive::FitComponent();
|
||||||
|
48
examples/component/dropdown.cpp
Normal file
48
examples/component/dropdown.cpp
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#include <functional> // for function
|
||||||
|
#include <iostream> // for basic_ostream::operator<<, operator<<, endl, basic_ostream, basic_ostream<>::__ostream_type, cout, ostream
|
||||||
|
#include <string> // for string, basic_string, allocator
|
||||||
|
#include <vector> // for vector
|
||||||
|
|
||||||
|
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||||
|
#include "ftxui/component/component.hpp" // for Menu
|
||||||
|
#include "ftxui/component/component_options.hpp" // for MenuOption
|
||||||
|
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||||
|
|
||||||
|
int main(int argc, const char* argv[]) {
|
||||||
|
using namespace ftxui;
|
||||||
|
|
||||||
|
std::vector<std::string> entries = {
|
||||||
|
"tribute", "clearance", "ally", "bend", "electronics",
|
||||||
|
"module", "era", "cultural", "sniff", "nationalism",
|
||||||
|
"negotiation", "deliver", "figure", "east",
|
||||||
|
"tribute", "clearance", "ally", "bend", "electronics",
|
||||||
|
"module", "era", "cultural", "sniff", "nationalism",
|
||||||
|
"negotiation", "deliver", "figure", "east",
|
||||||
|
"tribute", "clearance", "ally", "bend", "electronics",
|
||||||
|
"module", "era", "cultural", "sniff", "nationalism",
|
||||||
|
"negotiation", "deliver", "figure", "east",
|
||||||
|
};
|
||||||
|
|
||||||
|
int selected_1 = 0;
|
||||||
|
int selected_2 = 0;
|
||||||
|
int selected_3 = 0;
|
||||||
|
int selected_4 = 0;
|
||||||
|
|
||||||
|
auto layout = Container::Vertical({
|
||||||
|
Container::Horizontal({
|
||||||
|
Dropdown(&entries, &selected_1),
|
||||||
|
Dropdown(&entries, &selected_2),
|
||||||
|
}),
|
||||||
|
Container::Horizontal({
|
||||||
|
Dropdown(&entries, &selected_3),
|
||||||
|
Dropdown(&entries, &selected_4),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
auto screen = ScreenInteractive::FitComponent();
|
||||||
|
screen.Loop(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
@@ -214,12 +214,13 @@ int main(int argc, const char* argv[]) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto compiler_renderer = Renderer(compiler_component, [&] {
|
auto compiler_renderer = Renderer(compiler_component, [&] {
|
||||||
auto compiler_win = window(text("Compiler"), compiler->Render() | frame);
|
auto compiler_win = window(text("Compiler"),
|
||||||
auto flags_win = window(text("Flags"), flags->Render() | frame);
|
compiler->Render() | vscroll_indicator | frame);
|
||||||
|
auto flags_win =
|
||||||
|
window(text("Flags"), flags->Render() | vscroll_indicator | frame);
|
||||||
auto executable_win = window(text("Executable:"), executable_->Render());
|
auto executable_win = window(text("Executable:"), executable_->Render());
|
||||||
auto input_win =
|
auto input_win =
|
||||||
window(text("Input"),
|
window(text("Input"), hbox({
|
||||||
hbox({
|
|
||||||
vbox({
|
vbox({
|
||||||
hbox({
|
hbox({
|
||||||
text("Add: "),
|
text("Add: "),
|
||||||
@@ -229,7 +230,8 @@ int main(int argc, const char* argv[]) {
|
|||||||
filler(),
|
filler(),
|
||||||
}),
|
}),
|
||||||
separator(),
|
separator(),
|
||||||
input->Render() | frame | size(HEIGHT, EQUAL, 3) | flex,
|
input->Render() | vscroll_indicator | frame |
|
||||||
|
size(HEIGHT, EQUAL, 3) | flex,
|
||||||
}));
|
}));
|
||||||
return vbox({
|
return vbox({
|
||||||
hbox({
|
hbox({
|
||||||
@@ -240,7 +242,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
input_win | size(WIDTH, EQUAL, 60),
|
input_win | size(WIDTH, EQUAL, 60),
|
||||||
}),
|
}),
|
||||||
filler(),
|
filler(),
|
||||||
}) | size(HEIGHT, LESS_THAN, 6),
|
}) | size(HEIGHT, LESS_THAN, 8),
|
||||||
hflow(render_command()) | flex_grow,
|
hflow(render_command()) | flex_grow,
|
||||||
}) |
|
}) |
|
||||||
flex_grow | border;
|
flex_grow | border;
|
||||||
|
47
examples/component/maybe.cpp
Normal file
47
examples/component/maybe.cpp
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include <functional> // for function
|
||||||
|
#include <iostream> // for basic_ostream::operator<<, operator<<, endl, basic_ostream, basic_ostream<>::__ostream_type, cout, ostream
|
||||||
|
#include <string> // for string, basic_string, allocator
|
||||||
|
#include <vector> // for vector
|
||||||
|
|
||||||
|
#include "ftxui/component/captured_mouse.hpp" // for ftxui
|
||||||
|
#include "ftxui/component/component.hpp" // for Menu
|
||||||
|
#include "ftxui/component/component_options.hpp" // for MenuOption
|
||||||
|
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
|
||||||
|
|
||||||
|
using namespace ftxui;
|
||||||
|
Component Border(Component child) {
|
||||||
|
return Renderer(child, [child] { return child->Render() | border; });
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char* argv[]) {
|
||||||
|
|
||||||
|
std::vector<std::string> entries = {
|
||||||
|
"entry 1",
|
||||||
|
"entry 2",
|
||||||
|
"entry 3",
|
||||||
|
};
|
||||||
|
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),
|
||||||
|
Checkbox("Show menu_2", &menu_2_show),
|
||||||
|
Maybe(menu_2, &menu_2_show),
|
||||||
|
});
|
||||||
|
|
||||||
|
auto screen = ScreenInteractive::TerminalOutput();
|
||||||
|
screen.Loop(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
@@ -18,7 +18,8 @@ int main(int argc, const char* argv[]) {
|
|||||||
entries.push_back("Entry " + std::to_string(i));
|
entries.push_back("Entry " + std::to_string(i));
|
||||||
auto radiobox = Menu(&entries, &selected);
|
auto radiobox = Menu(&entries, &selected);
|
||||||
auto renderer = Renderer(radiobox, [&] {
|
auto renderer = Renderer(radiobox, [&] {
|
||||||
return radiobox->Render() | frame | size(HEIGHT, LESS_THAN, 10) | border;
|
return radiobox->Render() | vscroll_indicator | frame |
|
||||||
|
size(HEIGHT, LESS_THAN, 10) | border;
|
||||||
});
|
});
|
||||||
|
|
||||||
auto screen = ScreenInteractive::FitComponent();
|
auto screen = ScreenInteractive::FitComponent();
|
||||||
|
@@ -18,7 +18,8 @@ int main(int argc, const char* argv[]) {
|
|||||||
entries.push_back("RadioBox " + std::to_string(i));
|
entries.push_back("RadioBox " + std::to_string(i));
|
||||||
auto radiobox = Radiobox(&entries, &selected);
|
auto radiobox = Radiobox(&entries, &selected);
|
||||||
auto renderer = Renderer(radiobox, [&] {
|
auto renderer = Renderer(radiobox, [&] {
|
||||||
return radiobox->Render() | frame | size(HEIGHT, LESS_THAN, 10) | border;
|
return radiobox->Render() | vscroll_indicator | frame |
|
||||||
|
size(HEIGHT, LESS_THAN, 10) | border;
|
||||||
});
|
});
|
||||||
|
|
||||||
auto screen = ScreenInteractive::FitComponent();
|
auto screen = ScreenInteractive::FitComponent();
|
||||||
|
@@ -39,6 +39,7 @@ Component Menu(ConstStringListRef entries,
|
|||||||
int* selected_,
|
int* selected_,
|
||||||
Ref<MenuOption> = {});
|
Ref<MenuOption> = {});
|
||||||
Component MenuEntry(ConstStringRef label, Ref<MenuEntryOption> = {});
|
Component MenuEntry(ConstStringRef label, Ref<MenuEntryOption> = {});
|
||||||
|
Component Dropdown(ConstStringListRef entries, int* selected);
|
||||||
Component Radiobox(ConstStringListRef entries,
|
Component Radiobox(ConstStringListRef entries,
|
||||||
int* selected_,
|
int* selected_,
|
||||||
Ref<RadioboxOption> option = {});
|
Ref<RadioboxOption> option = {});
|
||||||
@@ -55,6 +56,7 @@ Component Renderer(Component child, std::function<Element()>);
|
|||||||
Component Renderer(std::function<Element()>);
|
Component Renderer(std::function<Element()>);
|
||||||
Component Renderer(std::function<Element(bool /* focused */)>);
|
Component Renderer(std::function<Element(bool /* focused */)>);
|
||||||
Component CatchEvent(Component child, std::function<bool(Event)>);
|
Component CatchEvent(Component child, std::function<bool(Event)>);
|
||||||
|
Component Maybe(Component, bool* show);
|
||||||
|
|
||||||
namespace Container {
|
namespace Container {
|
||||||
Component Vertical(Components children);
|
Component Vertical(Components children);
|
||||||
|
@@ -74,6 +74,7 @@ struct Event {
|
|||||||
bool operator!=(const Event& other) const { return !operator==(other); }
|
bool operator!=(const Event& other) const { return !operator==(other); }
|
||||||
|
|
||||||
//--- State section ----------------------------------------------------------
|
//--- State section ----------------------------------------------------------
|
||||||
|
ScreenInteractive* screen_ = nullptr;
|
||||||
private:
|
private:
|
||||||
friend ComponentBase;
|
friend ComponentBase;
|
||||||
friend ScreenInteractive;
|
friend ScreenInteractive;
|
||||||
@@ -95,8 +96,6 @@ struct Event {
|
|||||||
struct Cursor cursor_;
|
struct Cursor cursor_;
|
||||||
};
|
};
|
||||||
std::string input_;
|
std::string input_;
|
||||||
|
|
||||||
ScreenInteractive* screen_ = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ftxui
|
} // namespace ftxui
|
||||||
|
@@ -104,6 +104,8 @@ Element yframe(Element);
|
|||||||
Element focus(Element);
|
Element focus(Element);
|
||||||
Element select(Element);
|
Element select(Element);
|
||||||
|
|
||||||
|
Element vscroll_indicator(Element);
|
||||||
|
|
||||||
// --- Util --------------------------------------------------------------------
|
// --- Util --------------------------------------------------------------------
|
||||||
Element hcenter(Element);
|
Element hcenter(Element);
|
||||||
Element vcenter(Element);
|
Element vcenter(Element);
|
||||||
|
@@ -57,7 +57,7 @@ Component GeneratorComponent(const char*& data, size_t& size, int depth) {
|
|||||||
if (depth <= 0)
|
if (depth <= 0)
|
||||||
return Button(GeneratorString(data, size), [] {});
|
return Button(GeneratorString(data, size), [] {});
|
||||||
|
|
||||||
switch (value % 16) {
|
switch (value % 18) {
|
||||||
case 1:
|
case 1:
|
||||||
return Checkbox(GeneratorString(data, size), &g_bool);
|
return Checkbox(GeneratorString(data, size), &g_bool);
|
||||||
case 2:
|
case 2:
|
||||||
@@ -102,6 +102,10 @@ Component GeneratorComponent(const char*& data, size_t& size, int depth) {
|
|||||||
&g_int);
|
&g_int);
|
||||||
case 15:
|
case 15:
|
||||||
return Container::Tab(GeneratorComponents(data, size, depth - 1), &g_int);
|
return Container::Tab(GeneratorComponents(data, size, depth - 1), &g_int);
|
||||||
|
case 16:
|
||||||
|
return Maybe(GeneratorComponent(data, size, depth - 1), &g_bool);
|
||||||
|
case 17:
|
||||||
|
return Dropdown(&g_list, &g_int);
|
||||||
default:
|
default:
|
||||||
return Button(GeneratorString(data, size), [] {});
|
return Button(GeneratorString(data, size), [] {});
|
||||||
}
|
}
|
||||||
|
54
src/ftxui/component/dropdown.cpp
Normal file
54
src/ftxui/component/dropdown.cpp
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#include "ftxui/component/component.hpp"
|
||||||
|
#include "ftxui/component/component_base.hpp"
|
||||||
|
#include "ftxui/component/event.hpp"
|
||||||
|
|
||||||
|
namespace ftxui {
|
||||||
|
|
||||||
|
Component Dropdown(ConstStringListRef entries, int* selected) {
|
||||||
|
class Impl : public ComponentBase {
|
||||||
|
public:
|
||||||
|
Impl(ConstStringListRef entries, int* selected)
|
||||||
|
: entries_(std::move(entries)), selected_(selected) {
|
||||||
|
CheckboxOption option;
|
||||||
|
option.style_checked = "↓│";
|
||||||
|
option.style_unchecked = "→│";
|
||||||
|
checkbox_ = Checkbox(&title_, &show_, option),
|
||||||
|
radiobox_ = Radiobox(entries_, selected_);
|
||||||
|
|
||||||
|
Add(Container::Vertical({
|
||||||
|
checkbox_,
|
||||||
|
Maybe(radiobox_, &show_),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
Element Render() override {
|
||||||
|
title_ = entries_[*selected_];
|
||||||
|
if (show_) {
|
||||||
|
return vbox({
|
||||||
|
checkbox_->Render(),
|
||||||
|
separator(),
|
||||||
|
radiobox_->Render() | vscroll_indicator | frame |
|
||||||
|
size(HEIGHT, LESS_THAN, 12),
|
||||||
|
}) |
|
||||||
|
border;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vbox({
|
||||||
|
checkbox_->Render() | border,
|
||||||
|
filler(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConstStringListRef entries_;
|
||||||
|
bool show_ = false;
|
||||||
|
int* selected_;
|
||||||
|
std::string title_;
|
||||||
|
Component checkbox_;
|
||||||
|
Component radiobox_;
|
||||||
|
};
|
||||||
|
|
||||||
|
return Make<Impl>(std::move(entries), selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ftxui
|
31
src/ftxui/component/maybe.cpp
Normal file
31
src/ftxui/component/maybe.cpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#include "ftxui/component/component.hpp"
|
||||||
|
#include "ftxui/component/component_base.hpp"
|
||||||
|
#include "ftxui/component/event.hpp"
|
||||||
|
|
||||||
|
namespace ftxui {
|
||||||
|
|
||||||
|
Component Maybe(Component child, bool* show) {
|
||||||
|
class Impl : public ComponentBase {
|
||||||
|
public:
|
||||||
|
Impl(bool* show): show_(show) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Element Render() override {
|
||||||
|
return *show_ ? ComponentBase::Render() : std::make_unique<Node>();
|
||||||
|
}
|
||||||
|
bool Focusable() const override {
|
||||||
|
return *show_ && ComponentBase::Focusable();
|
||||||
|
}
|
||||||
|
bool OnEvent(Event event) override {
|
||||||
|
return *show_ && ComponentBase::OnEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool* show_;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto maybe = Make<Impl>(show);
|
||||||
|
maybe->Add(std::move(child));
|
||||||
|
return maybe;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ftxui
|
26
src/ftxui/component/show.cpp
Normal file
26
src/ftxui/component/show.cpp
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#include "ftxui/component/component_base.hpp"
|
||||||
|
|
||||||
|
Component Maybe(Component child, bool* show) {
|
||||||
|
class Impl : public ComponentBase {
|
||||||
|
public:
|
||||||
|
Impl(Component child, bool* show) : ComponentBase(child), show_(show) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Element Render() override {
|
||||||
|
if (*show_)
|
||||||
|
return ComponentBase::Render();
|
||||||
|
else
|
||||||
|
return text("");
|
||||||
|
}
|
||||||
|
bool Focusable() const override {
|
||||||
|
return *show_ && ComponentBase::Focusable();
|
||||||
|
}
|
||||||
|
bool OnEvent(Event event) override {
|
||||||
|
if (*show_)
|
||||||
|
return false return ComponentBase::OnEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool* show_;
|
||||||
|
};
|
||||||
|
return Make<Impl>(std::move(child), show);
|
||||||
|
}
|
58
src/ftxui/dom/scroll_indicator.cpp
Normal file
58
src/ftxui/dom/scroll_indicator.cpp
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include "ftxui/dom/elements.hpp"
|
||||||
|
#include "ftxui/dom/node.hpp"
|
||||||
|
#include "ftxui/dom/node_decorator.hpp" // for NodeDecorator
|
||||||
|
#include "ftxui/screen/box.hpp"
|
||||||
|
#include "ftxui/screen/screen.hpp"
|
||||||
|
|
||||||
|
namespace ftxui {
|
||||||
|
|
||||||
|
/// @brief Add a filter that will invert the foreground and the background
|
||||||
|
/// colors.
|
||||||
|
/// @ingroup dom
|
||||||
|
Element vscroll_indicator(Element child) {
|
||||||
|
class Impl : public NodeDecorator {
|
||||||
|
using NodeDecorator::NodeDecorator;
|
||||||
|
|
||||||
|
void ComputeRequirement() override {
|
||||||
|
Node::ComputeRequirement();
|
||||||
|
requirement_ = children_[0]->requirement();
|
||||||
|
requirement_.min_x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetBox(Box box) override {
|
||||||
|
Node::SetBox(box);
|
||||||
|
if (box_.x_min > box_.x_max)
|
||||||
|
box_.x_max--;
|
||||||
|
children_[0]->SetBox(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Render(Screen& screen) final {
|
||||||
|
Node::Render(screen);
|
||||||
|
|
||||||
|
const Box& stencil = screen.stencil;
|
||||||
|
|
||||||
|
int size_inner = box_.y_max - box_.y_min;
|
||||||
|
int size_outter = stencil.y_max - stencil.y_min;
|
||||||
|
if (size_outter >= size_inner)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int start_y = 2 * stencil.y_min + 2 * float(stencil.y_min - box_.y_min) *
|
||||||
|
(size_outter - 1) / size_inner;
|
||||||
|
int size = 2 * float(size_outter) * (size_outter - 1) / size_inner + 2;
|
||||||
|
size = std::max(size, 1);
|
||||||
|
|
||||||
|
const int x = stencil.x_max;
|
||||||
|
for (int y = stencil.y_min; y <= stencil.y_max; ++y) {
|
||||||
|
bool up = (2 * y + -1 >= start_y) && (2 * y - 1 <= start_y + size);
|
||||||
|
bool down = (2 * y - 0 >= start_y) && (2 * y - 0 <= start_y + size);
|
||||||
|
|
||||||
|
const char* c = up ? (down ? "┃" : "╹") : (down ? "╻" : " ");
|
||||||
|
screen.PixelAt(x, y).character = c;
|
||||||
|
screen.PixelAt(x, y).inverted = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return std::make_shared<Impl>(std::move(child));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ftxui
|
@@ -98,16 +98,21 @@ struct TileEncoding {
|
|||||||
unsigned int down : 2;
|
unsigned int down : 2;
|
||||||
unsigned int round : 1;
|
unsigned int round : 1;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
bool operator<(const TileEncoding& other) const {
|
bool operator<(const TileEncoding& other) const {
|
||||||
union Converter {
|
if (left < other.left) return true;
|
||||||
TileEncoding input;
|
if (left > other.left) return false;
|
||||||
uint16_t output = 0;
|
if (top < other.top) return true;
|
||||||
};
|
if (top > other.top) return false;
|
||||||
Converter a, b;
|
if (right < other.right) return true;
|
||||||
a.input = *this;
|
if (right > other.right) return false;
|
||||||
b.input = other;
|
if (down < other.down) return true;
|
||||||
return a.output < b.output;
|
if (down > other.down) return false;
|
||||||
|
if (round < other.round) return true;
|
||||||
|
if (round > other.round) return false;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
Reference in New Issue
Block a user