diff --git a/examples/component/gallery.cpp b/examples/component/gallery.cpp index ca73f6b..a9b497d 100644 --- a/examples/component/gallery.cpp +++ b/examples/component/gallery.cpp @@ -22,18 +22,16 @@ class MyComponent : public Component { MyComponent() { Add(&container); menu.entries = { - L"Browse the web", - L"Meditate", - L"Sleep", - L"Eat", + L"Menu 1", + L"Menu 2", + L"Menu 3", + L"Menu 4", }; container.Add(&menu); toggle.entries = { - L"Browse the web", - L"Meditate", - L"Sleep", - L"Eat", + L"Toggle_1", + L"Toggle_2", }; container.Add(&toggle); @@ -44,10 +42,10 @@ class MyComponent : public Component { checkbox_container.Add(&checkbox2); radiobox.entries = { - L"Browse the web", - L"Meditate", - L"Sleep", - L"Eat", + L"Radiobox 1", + L"Radiobox 2", + L"Radiobox 3", + L"Radiobox 4", }; container.Add(&radiobox); @@ -56,7 +54,7 @@ class MyComponent : public Component { } Element Render(std::wstring name, Component& component) { - return hbox(text(name) | size(10,1), separator(), component.Render()); + return hbox(text(name) | size(8,1), separator(), component.Render()); } Element Render() override { @@ -76,7 +74,7 @@ class MyComponent : public Component { }; int main(int argc, const char* argv[]) { - auto screen = ScreenInteractive::TerminalOutput(); + auto screen = ScreenInteractive::FitComponent(); MyComponent component; screen.Loop(&component); diff --git a/ftxui/include/ftxui/component/checkbox.hpp b/ftxui/include/ftxui/component/checkbox.hpp index 9a2c325..6e880cf 100644 --- a/ftxui/include/ftxui/component/checkbox.hpp +++ b/ftxui/include/ftxui/component/checkbox.hpp @@ -20,6 +20,9 @@ class CheckBox : public Component { std::wstring checked = L"☑ "; std::wstring unchecked = L"☐ "; + Decorator focused_style = inverted; + Decorator unfocused_style = nothing; + // State update callback. std::function on_change = [](){}; diff --git a/ftxui/include/ftxui/component/screen_interactive.hpp b/ftxui/include/ftxui/component/screen_interactive.hpp index b69e313..5553a1b 100644 --- a/ftxui/include/ftxui/component/screen_interactive.hpp +++ b/ftxui/include/ftxui/component/screen_interactive.hpp @@ -12,6 +12,7 @@ class ScreenInteractive : public Screen { public: static ScreenInteractive FixedSize(size_t dimx, size_t dimy); static ScreenInteractive Fullscreen(); + static ScreenInteractive FitComponent(); static ScreenInteractive TerminalOutput(); ~ScreenInteractive(); @@ -23,9 +24,10 @@ class ScreenInteractive : public Screen { bool quit_ = false; enum class Dimension { + FitComponent, Fixed, - TerminalOutput, Fullscreen, + TerminalOutput, }; Dimension dimension_ = Dimension::Fixed; ScreenInteractive(size_t dimx, size_t dimy, Dimension dimension); diff --git a/ftxui/include/ftxui/screen/screen.hpp b/ftxui/include/ftxui/screen/screen.hpp index 28fb51b..d491d9d 100644 --- a/ftxui/include/ftxui/screen/screen.hpp +++ b/ftxui/include/ftxui/screen/screen.hpp @@ -50,6 +50,8 @@ class Screen { // Fill with space. void Clear(); + void ApplyShader(); + protected: size_t dimx_; size_t dimy_; diff --git a/ftxui/src/ftxui/component/checkbox.cpp b/ftxui/src/ftxui/component/checkbox.cpp index a879a06..b6b6a49 100644 --- a/ftxui/src/ftxui/component/checkbox.cpp +++ b/ftxui/src/ftxui/component/checkbox.cpp @@ -4,8 +4,8 @@ namespace ftxui { Element CheckBox::Render() { - auto style = Focused() ? bold : nothing; - return text((state ? checked : unchecked) + label) | style; + auto style = Focused() ? focused_style : unfocused_style; + return hbox(text(state ? checked : unchecked), text(label) | style); } bool CheckBox::OnEvent(Event event) { diff --git a/ftxui/src/ftxui/component/screen_interactive.cpp b/ftxui/src/ftxui/component/screen_interactive.cpp index 7f49b15..6407a04 100644 --- a/ftxui/src/ftxui/component/screen_interactive.cpp +++ b/ftxui/src/ftxui/component/screen_interactive.cpp @@ -65,6 +65,11 @@ ScreenInteractive ScreenInteractive::TerminalOutput() { return ScreenInteractive(0, 0, Dimension::TerminalOutput); } +// static +ScreenInteractive ScreenInteractive::FitComponent() { + return ScreenInteractive(0, 0, Dimension::FitComponent); +} + void ScreenInteractive::Loop(Component* component) { //std::cout << "\033[?9h"; [> Send Mouse Row & Column on Button Press <] //std::cout << "\033[?1000h"; [> Send Mouse X & Y on button press and release <] @@ -114,10 +119,14 @@ void ScreenInteractive::Draw(Component* component) { dimy = document->requirement().min.y; break; case Dimension::Fullscreen: - document->ComputeRequirement(); dimx = Terminal::Size().dimx; dimy = Terminal::Size().dimy; break; + case Dimension::FitComponent: + document->ComputeRequirement(); + dimx = document->requirement().min.x; + dimy = document->requirement().min.y; + break; } if (dimx != dimx_ || dimy != dimy_) { diff --git a/ftxui/src/ftxui/dom/frame.cpp b/ftxui/src/ftxui/dom/frame.cpp index 7879470..c6282fb 100644 --- a/ftxui/src/ftxui/dom/frame.cpp +++ b/ftxui/src/ftxui/dom/frame.cpp @@ -61,20 +61,6 @@ class Frame : public Node { screen.at(box_.right,y) = charset[5]; } - // Try to merge with separator. - for(float x = box_.left + 1; xRender(screen); diff --git a/ftxui/src/ftxui/dom/node.cpp b/ftxui/src/ftxui/dom/node.cpp index 1a7245f..cc2e5da 100644 --- a/ftxui/src/ftxui/dom/node.cpp +++ b/ftxui/src/ftxui/dom/node.cpp @@ -38,6 +38,9 @@ void Render(Screen& screen, Node* node) { // Step 3: Draw the element. node->Render(screen); + + // Step 4: Apply shaders + screen.ApplyShader(); } }; // namespace ftxui diff --git a/ftxui/src/ftxui/screen/screen.cpp b/ftxui/src/ftxui/screen/screen.cpp index 5d2ff01..33c8fb2 100644 --- a/ftxui/src/ftxui/screen/screen.cpp +++ b/ftxui/src/ftxui/screen/screen.cpp @@ -22,6 +22,10 @@ static const wchar_t* BLINK_RESET = L"\e[25m"; static const wchar_t* INVERTED_SET = L"\e[7m"; static const wchar_t* INVERTED_RESET = L"\e[27m"; +static const char* MOVE_LEFT = "\r"; +static const char* MOVE_UP = "\e[1A"; +static const char* CLEAR_LINE = "\e[2K"; + Screen::Screen(size_t dimx, size_t dimy) : dimx_(dimx), dimy_(dimy), pixels_(dimy, std::vector(dimx)) {} @@ -94,9 +98,9 @@ Screen Screen::TerminalOutput(std::unique_ptr& element) { std::string Screen::ResetPosition() { std::stringstream ss; - ss << '\r'; + ss << MOVE_LEFT << CLEAR_LINE; for (size_t y = 1; y < dimy_; ++y) { - ss << "\e[2K\r\e[1A"; + ss << MOVE_UP << CLEAR_LINE; } return ss.str(); } @@ -106,4 +110,37 @@ void Screen::Clear() { std::vector(dimx_, Pixel())); } +void Screen::ApplyShader() { + + // Merge box characters togethers. + for(size_t y = 1; y