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 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src/subway_map.cpp') 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}; +} -- cgit 1.4.1