From e3fbcc9f29a1b1c83b23a4cef3819631fd3117d0 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Sun, 12 May 2024 18:45:21 -0400 Subject: Subway map hover detection with a quadtree --- src/subway_map.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/subway_map.h | 10 ++++++++++ 2 files changed, 47 insertions(+) (limited to 'src') diff --git a/src/subway_map.cpp b/src/subway_map.cpp index 0aa7df3..230a256 100644 --- a/src/subway_map.cpp +++ b/src/subway_map.cpp @@ -25,6 +25,13 @@ SubwayMap::SubwayMap(wxWindow *parent) : wxPanel(parent, wxID_ANY) { return; } + tree_ = std::make_unique>( + quadtree::Box{0, 0, static_cast(map_image_.GetWidth()), + static_cast(map_image_.GetHeight())}); + for (const SubwayItem &subway_item : GD_GetSubwayItems()) { + tree_->add(subway_item.id); + } + Redraw(); Bind(wxEVT_PAINT, &SubwayMap::OnPaint, this); @@ -47,6 +54,30 @@ void SubwayMap::OnPaint(wxPaintEvent &event) { } void SubwayMap::OnMouseMove(wxMouseEvent &event) { + int mouse_x = std::clamp( + (event.GetX() - render_x_) * map_image_.GetWidth() / render_width_, + 0, map_image_.GetWidth() - 1); + int mouse_y = std::clamp( + (event.GetY() - render_y_) * map_image_.GetWidth() / render_width_, + 0, map_image_.GetHeight() - 1); + + std::vector hovered = tree_->query( + {static_cast(mouse_x), static_cast(mouse_y), 2, 2}); + std::optional new_hovered_item; + if (!hovered.empty()) { + new_hovered_item = hovered[0]; + } + + if (new_hovered_item != hovered_item_) { + if (new_hovered_item) { + wxLogVerbose("Hovered: %d", *new_hovered_item); + } else { + wxLogVerbose("Un-hovered: %d", *hovered_item_); + } + + hovered_item_ = new_hovered_item; + } + event.Skip(); } @@ -121,3 +152,9 @@ void SubwayMap::Redraw() { } } } + +quadtree::Box SubwayMap::GetItemBox::operator()(const int& id) const { + const SubwayItem &subway_item = GD_GetSubwayItem(id); + return {static_cast(subway_item.x), static_cast(subway_item.y), + AREA_ACTUAL_SIZE, AREA_ACTUAL_SIZE}; +} diff --git a/src/subway_map.h b/src/subway_map.h index e375750..6cb5c63 100644 --- a/src/subway_map.h +++ b/src/subway_map.h @@ -7,8 +7,12 @@ #include #endif +#include +#include #include +#include + class SubwayMap : public wxPanel { public: SubwayMap(wxWindow *parent); @@ -29,7 +33,13 @@ class SubwayMap : public wxPanel { int render_y_ = 0; int render_width_ = 0; int render_height_ = 0; + + struct GetItemBox { + quadtree::Box operator()(const int &id) const; + }; + std::unique_ptr> tree_; + std::optional hovered_item_; }; #endif /* end of include guard: SUBWAY_MAP_H_BD2D843E */ -- cgit 1.4.1