diff --git a/include/ftxui/screen/box.hpp b/include/ftxui/screen/box.hpp index 3770803..8ad7d1a 100644 --- a/include/ftxui/screen/box.hpp +++ b/include/ftxui/screen/box.hpp @@ -15,6 +15,7 @@ struct Box { static auto Intersection(Box a, Box b) -> Box; static auto Union(Box a, Box b) -> Box; bool Contain(int x, int y) const; + Box Clean() const; bool IsEmpty() const; bool operator==(const Box& other) const; bool operator!=(const Box& other) const; diff --git a/include/ftxui/screen/screen.hpp b/include/ftxui/screen/screen.hpp index 211ed59..2f9bf19 100644 --- a/include/ftxui/screen/screen.hpp +++ b/include/ftxui/screen/screen.hpp @@ -65,6 +65,7 @@ class Screen : public Image { bool selection_enabled = false; CapturedMouse selection_pending; + Box mouse_selection_region; Box selection_region; std::string selection_text; diff --git a/src/ftxui/component/screen_interactive.cpp b/src/ftxui/component/screen_interactive.cpp index 49cbee0..ee2591d 100644 --- a/src/ftxui/component/screen_interactive.cpp +++ b/src/ftxui/component/screen_interactive.cpp @@ -843,10 +843,12 @@ bool ScreenInteractive::HandleSelection(Event event) { return false; } selection_enabled = true; - selection_region.x_min = mouse.x; - selection_region.y_min = mouse.y; - selection_region.x_max = mouse.x; - selection_region.y_max = mouse.y; + mouse_selection_region.x_min = mouse.x; + mouse_selection_region.y_min = mouse.y; + mouse_selection_region.x_max = mouse.x; + mouse_selection_region.y_max = mouse.y; + + selection_region = mouse_selection_region.Clean(); return true; } @@ -855,18 +857,22 @@ bool ScreenInteractive::HandleSelection(Event event) { } if (mouse.motion == Mouse::Moved) { - selection_region.x_max = mouse.x; - selection_region.y_max = mouse.y; + mouse_selection_region.x_max = mouse.x; + mouse_selection_region.y_max = mouse.y; + + selection_region = mouse_selection_region.Clean(); return true; } if (mouse.motion == Mouse::Released) { - selection_region.x_max = mouse.x; - selection_region.y_max = mouse.y; + mouse_selection_region.x_max = mouse.x; + mouse_selection_region.y_max = mouse.y; selection_pending = nullptr; - if (selection_region.x_min == selection_region.x_max && - selection_region.y_min == selection_region.y_max) { + selection_region = mouse_selection_region.Clean(); + + if (mouse_selection_region.x_min == mouse_selection_region.x_max && + mouse_selection_region.y_min == mouse_selection_region.y_max) { selection_enabled = false; return true; } diff --git a/src/ftxui/screen/box.cpp b/src/ftxui/screen/box.cpp index e190305..3e5bc92 100644 --- a/src/ftxui/screen/box.cpp +++ b/src/ftxui/screen/box.cpp @@ -39,6 +39,24 @@ bool Box::Contain(int x, int y) const { y_max >= y; } +/// @return a copy of box with the x_min <= x_max and y_min <= y_max. +/// @ingroup screen +Box Box::Clean() const { + Box newBox = *this; + + if(newBox.x_min > newBox.x_max) + { + std::swap(newBox.x_min, newBox.x_max); + } + + if(newBox.y_min > newBox.y_max) + { + std::swap(newBox.y_min, newBox.y_max); + } + + return newBox; +} + /// @return whether the box is empty. /// @ingroup screen bool Box::IsEmpty() const {