diff --git a/CMakeLists.txt b/CMakeLists.txt index bf4a9da..350278e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,6 +82,7 @@ add_library(dom src/ftxui/dom/gridbox.cpp src/ftxui/dom/hbox.cpp src/ftxui/dom/inverted.cpp + src/ftxui/dom/selected.cpp src/ftxui/dom/linear_gradient.cpp src/ftxui/dom/node.cpp src/ftxui/dom/node_decorator.cpp diff --git a/examples/component/input.cpp b/examples/component/input.cpp index 9768359..67ef0bc 100644 --- a/examples/component/input.cpp +++ b/examples/component/input.cpp @@ -12,6 +12,7 @@ #include "ftxui/dom/elements.hpp" // for text, hbox, separator, Element, operator|, vbox, border #include "ftxui/util/ref.hpp" // for Ref + int main() { using namespace ftxui; @@ -21,6 +22,14 @@ int main() { std::string password; std::string phoneNumber; + int select_startx = -1; + int select_starty = -1; + int select_endx = -1; + int select_endy = -1; + std::string textToCopy; + + auto screen = ScreenInteractive::TerminalOutput(); + // The basic input components: Component input_first_name = Input(&first_name, "first name"); Component input_last_name = Input(&last_name, "last name"); @@ -59,10 +68,48 @@ int main() { text("Hello " + first_name + " " + last_name), text("Your password is " + password), text("Your phone number is " + phoneNumber), + text("select_start " + std::to_string(select_startx) + ";" + std::to_string(select_starty)), + text("select_end " + std::to_string(select_endx) + ";" + std::to_string(select_endy)), + text("textToCopy " + textToCopy) }) | - border; + border | selected(select_startx, select_endx); + }); + + + renderer |= CatchEvent([&](Event event) { + if (event.is_mouse()) { + auto& mouse = event.mouse(); + if (mouse.button == Mouse::Left) { + if (mouse.motion == Mouse::Pressed) { + select_startx = mouse.x; + select_starty = mouse.y; + select_endx = mouse.x; + select_endy = mouse.y; + } else if (mouse.motion == Mouse::Released) { + select_endx = mouse.x; + select_endy = mouse.y; + } + else if (mouse.motion == Mouse::Moved) { + select_endx = mouse.x; + select_endy = mouse.y; + } + + screen.PostEvent(Event::Custom); + return true; + } + } + + // if (event == Event::SpecialKey("Ctrl+Shift+C")) { + // textToCopy = "Kikoo!"; + // //clip::set_text(text_to_copy); // Set the clipboard content + + // screen.PostEvent(Event::Custom); + + // return true; + // } + + return false; }); - auto screen = ScreenInteractive::TerminalOutput(); screen.Loop(renderer); } diff --git a/include/ftxui/dom/elements.hpp b/include/ftxui/dom/elements.hpp index b17a711..1b74f0c 100644 --- a/include/ftxui/dom/elements.hpp +++ b/include/ftxui/dom/elements.hpp @@ -96,6 +96,8 @@ Element canvas(std::function); Element bold(Element); Element dim(Element); Element inverted(Element); +Element selected(int &start, int &end, Element); +Decorator selected(int &start, int &end); Element underlined(Element); Element underlinedDouble(Element); Element blink(Element); diff --git a/src/ftxui/dom/selected.cpp b/src/ftxui/dom/selected.cpp new file mode 100644 index 0000000..f97b9bb --- /dev/null +++ b/src/ftxui/dom/selected.cpp @@ -0,0 +1,49 @@ +// 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. +#include // for make_shared +#include // for move + +#include "ftxui/dom/elements.hpp" // for Element, inverted +#include "ftxui/dom/node.hpp" // for Node +#include "ftxui/dom/node_decorator.hpp" // for NodeDecorator +#include "ftxui/screen/box.hpp" // for Box +#include "ftxui/screen/screen.hpp" // for Pixel, Screen + +namespace ftxui { + +namespace { +class Selected : public NodeDecorator { + public: + using NodeDecorator::NodeDecorator; + Selected(Element child, int &start, int &end) + : NodeDecorator(std::move(child)), startx_(start), endx_(end) {} + + void Render(Screen& screen) override { + Node::Render(screen); + for (int y = box_.y_min; y <= box_.y_max; ++y) { + for (int x = startx_; x <= endx_; ++x) { + screen.PixelAt(x, y).inverted ^= true; + } + } + } + +private: + int &startx_; + int &endx_; +}; +} // namespace + +/// @brief Add a filter that will invert the foreground and the background +/// colors. +/// @ingroup dom + +Element selected(int &start, int &end, Element child) { + return std::make_shared(std::move(child), start, end); +} + +Decorator selected(int &start, int &end) { + return [&start, &end](Element child) { return selected(start, end, std::move(child)); }; +} + +} // namespace ftxui