diff --git a/include/ftxui/screen/box.hpp b/include/ftxui/screen/box.hpp index 8ad7d1a0..4992bb5d 100644 --- a/include/ftxui/screen/box.hpp +++ b/include/ftxui/screen/box.hpp @@ -11,6 +11,8 @@ struct Box { int x_max = 0; int y_min = 0; int y_max = 0; + bool isXInverted = false; // false means the box box from x_min to x_max (in the case of a selection for example) + bool isYInverted = false; // false means the box box from y_min to y_max (in the case of a selection for example) static auto Intersection(Box a, Box b) -> Box; static auto Union(Box a, Box b) -> Box; diff --git a/src/ftxui/dom/text.cpp b/src/ftxui/dom/text.cpp index 1415191c..e1b2c515 100644 --- a/src/ftxui/dom/text.cpp +++ b/src/ftxui/dom/text.cpp @@ -34,6 +34,17 @@ class Text : public Node { if (y > box_.y_max) { return; } + + // Get the selection start point + int selection_start_x = !screen.selection_region.isXInverted ? screen.selection_region.x_min : screen.selection_region.x_max; + int selection_start_y = !screen.selection_region.isYInverted ? screen.selection_region.y_min : screen.selection_region.y_max; + bool selectedWidget = false; + + if(box_.Contain(selection_start_x, selection_start_y)) + { + selectedWidget = true; + } + for (const auto& cell : Utf8ToGlyphs(text_)) { if (x > box_.x_max) { return; @@ -44,7 +55,7 @@ class Text : public Node { Pixel ¤tPixel = screen.PixelAt(x, y); currentPixel.character = cell; - if(currentPixel.selectable == true) + if((selectedWidget == true) && (currentPixel.selectable == true)) { if(screen.selection_region.Contain(x, y)) { currentPixel.inverted ^= true; @@ -53,12 +64,14 @@ class Text : public Node { else if((x >= screen.selection_region.x_min) && (x >= screen.selection_region.x_max) && (y >= screen.selection_region.y_min) && (y < screen.selection_region.y_max)) { + // Wrap around selection on the right currentPixel.inverted ^= true; screen.selection_text += currentPixel.character; } else if((x <= screen.selection_region.x_min) && (x <= screen.selection_region.x_max) && (y > screen.selection_region.y_min) && (y <= screen.selection_region.y_max)) { + // Wrap around selection on the left currentPixel.inverted ^= true; screen.selection_text += currentPixel.character; } diff --git a/src/ftxui/screen/box.cpp b/src/ftxui/screen/box.cpp index 3e5bc925..e82884a8 100644 --- a/src/ftxui/screen/box.cpp +++ b/src/ftxui/screen/box.cpp @@ -47,11 +47,13 @@ Box Box::Clean() const { if(newBox.x_min > newBox.x_max) { std::swap(newBox.x_min, newBox.x_max); + newBox.isXInverted = true; } if(newBox.y_min > newBox.y_max) { std::swap(newBox.y_min, newBox.y_max); + newBox.isYInverted = true; } return newBox;