From 1325256aa96045bd61079844c5a87219f3142914 Mon Sep 17 00:00:00 2001 From: Clement Roblot Date: Tue, 27 Aug 2024 17:35:21 +0700 Subject: [PATCH] We can catch mouse events --- examples/component/selectable_input.cpp | 2 +- .../ftxui/component/screen_interactive.hpp | 13 +++++ include/ftxui/dom/elements.hpp | 3 ++ include/ftxui/screen/pixel.hpp | 2 + src/ftxui/component/screen_interactive.cpp | 51 ++++++++++++++++++- src/ftxui/dom/selectable.cpp | 4 +- 6 files changed, 71 insertions(+), 4 deletions(-) diff --git a/examples/component/selectable_input.cpp b/examples/component/selectable_input.cpp index e2fc15ec..fd16b2d8 100644 --- a/examples/component/selectable_input.cpp +++ b/examples/component/selectable_input.cpp @@ -59,7 +59,7 @@ int main() { hbox(text(" First name : "), input_first_name->Render()), hbox(text(" Last name : ") | selectable(), input_last_name->Render()), hbox(text(" Password : "), input_password->Render()), - hbox(text(" Phone num : "), input_phone_number->Render()), + hbox(text(" Phone num : "), input_phone_number->Render()) | selectable(), separator(), text("Hello " + first_name + " " + last_name), text("Your password is " + password), diff --git a/include/ftxui/component/screen_interactive.hpp b/include/ftxui/component/screen_interactive.hpp index 6c799136..a01fa95d 100644 --- a/include/ftxui/component/screen_interactive.hpp +++ b/include/ftxui/component/screen_interactive.hpp @@ -26,6 +26,15 @@ struct Event; using Component = std::shared_ptr; class ScreenInteractivePrivate; +typedef struct { + + uint16_t startx = 0; + uint16_t endx = 0; + uint16_t starty = 0; + uint16_t endy = 0; + bool changed = false; +} Region; + class ScreenInteractive : public Screen { public: // Constructors: @@ -82,6 +91,8 @@ class ScreenInteractive : public Screen { void RunOnceBlocking(Component component); void HandleTask(Component component, Task& task); + bool selectableCatchEvent(Event event); + std::string getSelection(void); void Draw(Component component); void ResetCursorPosition(); @@ -126,6 +137,8 @@ class ScreenInteractive : public Screen { bool force_handle_ctrl_c_ = true; bool force_handle_ctrl_z_ = true; + Region selectedRegion; + // The style of the cursor to restore on exit. int cursor_reset_shape_ = 1; diff --git a/include/ftxui/dom/elements.hpp b/include/ftxui/dom/elements.hpp index 61cd3243..eb0faf18 100644 --- a/include/ftxui/dom/elements.hpp +++ b/include/ftxui/dom/elements.hpp @@ -116,6 +116,9 @@ Element hyperlink(std::string link, Element child); Element selectable(Element child); Decorator selectable(void); +// -- Selection -- +std::string getSelection(void); + // --- Layout is // Horizontal, Vertical or stacked set of elements. Element hbox(Elements); diff --git a/include/ftxui/screen/pixel.hpp b/include/ftxui/screen/pixel.hpp index cbc7cc23..817778b0 100644 --- a/include/ftxui/screen/pixel.hpp +++ b/include/ftxui/screen/pixel.hpp @@ -21,6 +21,7 @@ struct Pixel { underlined(false), underlined_double(false), strikethrough(false), + selectable(false), automerge(false) {} // A bit field representing the style: @@ -30,6 +31,7 @@ struct Pixel { bool inverted : 1; bool underlined : 1; bool underlined_double : 1; + bool selectable : 1; bool strikethrough : 1; bool automerge : 1; diff --git a/src/ftxui/component/screen_interactive.cpp b/src/ftxui/component/screen_interactive.cpp index 45a4fff9..af5a82e1 100644 --- a/src/ftxui/component/screen_interactive.cpp +++ b/src/ftxui/component/screen_interactive.cpp @@ -35,6 +35,12 @@ #include "ftxui/screen/pixel.hpp" // for Pixel #include "ftxui/screen/terminal.hpp" // for Dimensions, Size + + +#include +#include + + #if defined(_WIN32) #define DEFINE_CONSOLEV2_PROPERTIES #define WIN32_LEAN_AND_MEAN @@ -781,7 +787,15 @@ void ScreenInteractive::HandleTask(Component component, Task& task) { arg.screen_ = this; - const bool handled = component->OnEvent(arg); + bool handled = component->OnEvent(arg); + + if(handled == false) + { + if(selectableCatchEvent(arg)) + { + handled = true; + } + } if (arg == Event::CtrlC && (!handled || force_handle_ctrl_c_)) { RecordSignal(SIGABRT); @@ -824,6 +838,41 @@ void ScreenInteractive::HandleTask(Component component, Task& task) { // clang-format on } +bool ScreenInteractive::selectableCatchEvent(Event event) { + + // std::ofstream MyFile("debug.log", std::ios_base::app); + // MyFile << "Top dog!" << std::endl; + // MyFile.close(); + + if (event.is_mouse()) { + auto& mouse = event.mouse(); + if (mouse.button == Mouse::Left) { + + if (mouse.motion == Mouse::Pressed) { + selectedRegion.startx = mouse.x; + selectedRegion.starty = mouse.y; + selectedRegion.endx = mouse.x; + selectedRegion.endy = mouse.y; + selectedRegion.changed = true; + } else if (mouse.motion == Mouse::Released) { + selectedRegion.endx = mouse.x; + selectedRegion.endy = mouse.y; + selectedRegion.changed = true; + } else if (mouse.motion == Mouse::Moved) { + selectedRegion.endx = mouse.x; + selectedRegion.endy = mouse.y; + selectedRegion.changed = true; + } + } + } + + return false; +} + +std::string ScreenInteractive::getSelection(void) { + return "Selection"; +} + // private // NOLINTNEXTLINE void ScreenInteractive::Draw(Component component) { diff --git a/src/ftxui/dom/selectable.cpp b/src/ftxui/dom/selectable.cpp index 9f6f8683..191c5f4a 100644 --- a/src/ftxui/dom/selectable.cpp +++ b/src/ftxui/dom/selectable.cpp @@ -1,6 +1,6 @@ #include "ftxui/dom/elements.hpp" // for Element, Decorator #include "ftxui/dom/node_decorator.hpp" // for NodeDecorator - +#include "ftxui/component/event.hpp" // for Event namespace ftxui { @@ -16,7 +16,7 @@ class Selectable : public NodeDecorator { for (int y = box_.y_min; y <= box_.y_max; ++y) { for (int x = box_.x_min; x <= box_.x_max; ++x) { - screen.PixelAt(x, y).inverted = true; + screen.PixelAt(x, y).selectable = true; } }