From 08b4b10113496b9644cf3c71b6332cd191d5a99d Mon Sep 17 00:00:00 2001 From: Jan Mrna Date: Fri, 10 Oct 2025 19:32:58 +0200 Subject: [PATCH] Selection rectangle --- cpp/src/pathfindingdemo.cpp | 30 ++++++++++++++++++++++++++++++ cpp/src/pathfindingdemo.hpp | 8 ++++++++ cpp/src/user_input.cpp | 14 +++++++++++++- cpp/src/user_input.hpp | 13 ++++++++++++- 4 files changed, 63 insertions(+), 2 deletions(-) diff --git a/cpp/src/pathfindingdemo.cpp b/cpp/src/pathfindingdemo.cpp index 46ccd2b..7a1064c 100644 --- a/cpp/src/pathfindingdemo.cpp +++ b/cpp/src/pathfindingdemo.cpp @@ -203,5 +203,35 @@ void PathFindingDemo::HandleActions(const std::vector &actions) m_Camera.Zoom(action.Argument.float_number); LOG_INFO("Camera zoom: ", action.Argument.float_number); } + else if (action.type == UserAction::Type::SELECTION_START) + { + m_SelectionBox.active = true; + m_SelectionBox.start = action.Argument.position; + } + else if (action.type == UserAction::Type::SELECTION_END) + { + m_SelectionBox.end = action.Argument.position; + m_SelectionBox.active = false; + SelectEntitiesInRectangle(m_SelectionBox.start, m_SelectionBox.end); + } }; } + +void PathFindingDemo::SelectEntitiesInRectangle(WindowPos A, WindowPos B) +{ + // TODO use colliders for this + m_SelectedEntities.clear(); + auto [x_min, x_max] = std::minmax(A.x(), B.x()); + auto [y_min, y_max] = std::minmax(A.y(), B.y()); + for (const auto& entity : m_Entities) + { + const auto& pos = entity->GetPosition(); + bool x_in_range = x_min < pos.x() && pos.x() < x_max; + bool y_in_range = y_min < pos.y() && pos.y() < y_max; + if (x_in_range && y_in_range) + { + m_SelectedEntities.push_back(std::weak_ptr(entity)); + } + } +} + diff --git a/cpp/src/pathfindingdemo.hpp b/cpp/src/pathfindingdemo.hpp index ea34769..442716c 100644 --- a/cpp/src/pathfindingdemo.hpp +++ b/cpp/src/pathfindingdemo.hpp @@ -14,6 +14,12 @@ using Collision = std::pair, std::weak_ptr>; +struct SelectionBox +{ + WindowPos start, end; + bool active; +}; + class PathFindingDemo { public: PathFindingDemo(int width, int height); @@ -35,6 +41,7 @@ public: void HandleActions(const std::vector &actions); WorldPos GetRandomPosition() const; + void SelectEntitiesInRectangle(WindowPos A, WindowPos B); private: const std::vector& GetEntityCollisions(); @@ -45,4 +52,5 @@ private: std::vector> m_Entities; std::unique_ptr m_PathFinder; std::vector> m_SelectedEntities; + SelectionBox m_SelectionBox; }; diff --git a/cpp/src/user_input.cpp b/cpp/src/user_input.cpp index 1604f94..590924e 100644 --- a/cpp/src/user_input.cpp +++ b/cpp/src/user_input.cpp @@ -31,7 +31,13 @@ void UserInput::GetActions_mouse(const SDL_Event& event) { if (button == MouseButton::LEFT) { - LOG_DEBUG("Mouse down: ", mouse_event.x, ", ", mouse_event.y); + LOG_DEBUG("Selection start at ", mouse_event.x, ", ", mouse_event.y); + m_Actions.emplace_back(UserAction::Type::SELECTION_START, + WindowPos{mouse_event.x, mouse_event.y}); + } + else if (button == MouseButton::RIGHT) + { + LOG_DEBUG("Set move target to: ", mouse_event.x, ", ", mouse_event.y); m_Actions.emplace_back(UserAction::Type::SET_MOVE_TARGET, WindowPos{mouse_event.x, mouse_event.y}); } @@ -42,6 +48,12 @@ void UserInput::GetActions_mouse(const SDL_Event& event) } else if (event.type == SDL_EVENT_MOUSE_BUTTON_UP) { + if (button == MouseButton::LEFT) + { + LOG_DEBUG("Selection end at ", mouse_event.x, ", ", mouse_event.y); + m_Actions.emplace_back(UserAction::Type::SELECTION_END, + WindowPos{mouse_event.x, mouse_event.y}); + } if (button == MouseButton::MIDDLE) { mouse_pan = false; diff --git a/cpp/src/user_input.hpp b/cpp/src/user_input.hpp index c32b071..de2c9f1 100644 --- a/cpp/src/user_input.hpp +++ b/cpp/src/user_input.hpp @@ -12,7 +12,18 @@ enum class MouseButton { LEFT = 1, MIDDLE, RIGHT }; class UserAction { public: - enum class Type { NONE, EXIT, SET_MOVE_TARGET, SELECT_PATHFINDER, CAMERA_PAN, CAMERA_ZOOM }; + + enum class Type + { + NONE, + EXIT, + SET_MOVE_TARGET, + SELECT_PATHFINDER, + CAMERA_PAN, + CAMERA_ZOOM, + SELECTION_START, + SELECTION_END + }; UserAction() : type(Type::NONE), Argument{.number = 0} {} UserAction(Type t) : type(t), Argument{.number = 0} {}