diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 1e2e848..ec4cb1b 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(frame) add_subdirectory(gauge) add_subdirectory(separator) add_subdirectory(vbox_hbox) diff --git a/examples/frame/CMakeLists.txt b/examples/frame/CMakeLists.txt new file mode 100644 index 0000000..cef99a5 --- /dev/null +++ b/examples/frame/CMakeLists.txt @@ -0,0 +1,4 @@ +add_executable(frame_example + main.cpp +) +target_link_libraries(frame_example PRIVATE ftxui) diff --git a/examples/frame/main.cpp b/examples/frame/main.cpp new file mode 100644 index 0000000..7b155cc --- /dev/null +++ b/examples/frame/main.cpp @@ -0,0 +1,35 @@ +#include +#include +#include + +#include "ftxui/core/screen.hpp" +#include "ftxui/core/dom/elements.hpp" + +int main(int argc, const char *argv[]) +{ + using namespace ftxui::dom; + auto document = + hbox( + frame( + vbox( + text(L"Line 1"), + text(L"Line 2"), + text(L"Line 3"), + frame( + vbox( + text(L"Line 4"), + text(L"Line 5"), + text(L"Line 6") + ) + ), + text(L"Line 7"), + text(L"Line 8"), + text(L"Line 9") + ) + ), + flex() + ); + auto screen = ftxui::Screen::TerminalOutput(document); + Render(screen, document.get()); + std::cout << screen.ToString() << std::endl; +} diff --git a/examples/gauge/main.cpp b/examples/gauge/main.cpp index d1bdcd7..ab45ec2 100644 --- a/examples/gauge/main.cpp +++ b/examples/gauge/main.cpp @@ -1,30 +1,22 @@ +#include +#include +#include + #include "ftxui/core/screen.hpp" #include "ftxui/core/dom/elements.hpp" -#include int main(int argc, const char *argv[]) { - using namespace ftxui::dom; - auto document = - hbox( - flex(vbox( - gauge(0.1), - gauge(0.2), - gauge(0.3) - )), - flex(vbox( - gauge(0.1), - gauge(0.8), - gauge(0.3) - )) - ); - //auto screen = ftxui::Screen::WholeTerminal(); - auto screen = ftxui::Screen::TerminalOutput(document); - Render(screen, document.get()); + for(float percentage = 0; percentage <= 1.0; percentage+=0.001) { + using namespace ftxui::dom; + auto document = + hbox(text(L"gauge = -"), flex(gauge(percentage)), text(L"-")); + auto screen = ftxui::Screen(100, 1); + Render(screen, document.get()); + std::cout << '\r' << screen.ToString() << std::flush; - std::cout << screen.ToString(); - - getchar(); - - return 0; + using namespace std::chrono_literals; + std::this_thread::sleep_for(0.01s); + } + std::cout << std::endl; } diff --git a/ftxui/CMakeLists.txt b/ftxui/CMakeLists.txt index 2ff5970..46a91b5 100644 --- a/ftxui/CMakeLists.txt +++ b/ftxui/CMakeLists.txt @@ -3,14 +3,16 @@ project(ftxui) add_library(ftxui src/ftxui/core/component.cpp + src/ftxui/core/dom/frame.cpp + src/ftxui/core/dom/centered.cpp src/ftxui/core/dom/flex.cpp + src/ftxui/core/dom/frame.cpp + src/ftxui/core/dom/gauge.cpp src/ftxui/core/dom/hbox.cpp src/ftxui/core/dom/node.cpp src/ftxui/core/dom/separator.cpp src/ftxui/core/dom/text.cpp - src/ftxui/core/dom/centered.cpp src/ftxui/core/dom/vbox.cpp - src/ftxui/core/dom/gauge.cpp src/ftxui/core/screen.cpp src/ftxui/core/terminal.cpp src/ftxui/util/string.cpp diff --git a/ftxui/include/ftxui/core/dom/elements.hpp b/ftxui/include/ftxui/core/dom/elements.hpp index a1b1116..df2f7cc 100644 --- a/ftxui/include/ftxui/core/dom/elements.hpp +++ b/ftxui/include/ftxui/core/dom/elements.hpp @@ -8,24 +8,27 @@ namespace ftxui { namespace dom { using Element = std::unique_ptr; +using Child = std::unique_ptr; using Children = std::vector>; // --- Layout ---- -std::unique_ptr vbox(Children); -std::unique_ptr hbox(Children); -std::unique_ptr flex(); -std::unique_ptr flex(Element); +Element vbox(Children); +Element hbox(Children); +Element flex(); // --- Widget -- -std::unique_ptr text(std::wstring text); -std::unique_ptr separator(); -std::unique_ptr gauge(float ratio); +Element text(std::wstring text); +Element separator(); +Element gauge(float ratio); +Element frame(Child); +Element frame(std::wstring title, Child); // --- Decorator --- -std::unique_ptr hcenter(Element); -std::unique_ptr vcenter(Element); -std::unique_ptr center(Element); +Element hcenter(Element); +Element vcenter(Element); +Element center(Element); +Element flex(Element); template std::vector unpack(Args... args) { diff --git a/ftxui/src/ftxui/core/dom/frame.cpp b/ftxui/src/ftxui/core/dom/frame.cpp new file mode 100644 index 0000000..4b43f58 --- /dev/null +++ b/ftxui/src/ftxui/core/dom/frame.cpp @@ -0,0 +1,57 @@ +#include "ftxui/core/dom/node.hpp" +#include "ftxui/core/dom/elements.hpp" + +namespace ftxui { +namespace dom { + +static wchar_t charset[] = L"┌┐└┘─│"; + +class Frame : public Node { + public: + Frame(Child child) : Node(unpack(std::move(child))) {} + ~Frame() override {} + + void ComputeRequirement() override { + children[0]->ComputeRequirement(); + requirement_ = children[0]->requirement(); + requirement_.min.x += 2; + requirement_.min.y += 2; + } + + void SetBox(Box box) override { + Node::SetBox(box); + box.left++; + box.right--; + box.top++; + box.bottom--; + children[0]->SetBox(box); + } + + void Render(Screen& screen) override { + if (box_.left >= box_.right || box_.top >= box_.bottom) + return; + + screen.at(box_.left, box_.top) = charset[0]; + screen.at(box_.right, box_.top) = charset[1]; + screen.at(box_.left, box_.bottom) = charset[2]; + screen.at(box_.right, box_.bottom) = charset[3]; + for(float x = box_.left + 1; xRender(screen); + } + private: + float progress_; +}; + +std::unique_ptr frame(Child child) { + return std::make_unique(std::move(child)); +} + +}; // namespace dom +}; // namespace ftxui diff --git a/ftxui/src/ftxui/core/dom/gauge.cpp b/ftxui/src/ftxui/core/dom/gauge.cpp index 0c3f9f6..8b6756f 100644 --- a/ftxui/src/ftxui/core/dom/gauge.cpp +++ b/ftxui/src/ftxui/core/dom/gauge.cpp @@ -4,10 +4,12 @@ namespace ftxui { namespace dom { +static wchar_t charset[] = L" ▏▎▍▌▋▊▉█"; + class Gauge : public Node { public: Gauge(float progress) : progress_(progress) {} - ~Gauge() {} + ~Gauge() override {} void ComputeRequirement() override { requirement_.flex.x = 1; @@ -16,9 +18,14 @@ class Gauge : public Node { void Render(Screen& screen) override { float y = box_.top; - int limit = box_.left + progress_ * (box_.right - box_.left); - for(int i = box_.left; i<=limit; ++i) - screen.at(i, y) = 'X'; + float limit = box_.left + progress_ * (box_.right - box_.left + 1); + int limit_int = limit; + int x = box_.left; + while (x < limit_int) + screen.at(x++, y) = charset[9]; + screen.at(x++, y) = charset[int(9*(limit-limit_int))]; + while (x <= box_.right) + screen.at(x++, y) = charset[0]; } private: float progress_; diff --git a/ftxui/src/ftxui/core/dom/vbox.cpp b/ftxui/src/ftxui/core/dom/vbox.cpp index 386945c..1556621 100644 --- a/ftxui/src/ftxui/core/dom/vbox.cpp +++ b/ftxui/src/ftxui/core/dom/vbox.cpp @@ -37,7 +37,7 @@ class VBox : public Node { int y = box.top; for (auto& child : children) { - if (y > box.right) + if (y > box.bottom) break; Box child_box = box;