diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2024-06-06 11:09:15 -0400 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2024-06-06 11:09:15 -0400 |
commit | f9d209b21596e5aac09a7743385065803749f6a0 (patch) | |
tree | b5465072c5aadeebc4e6b8b0b189e04eea83b9a1 | |
parent | 13d2a129f6972e6e752da9c9cb686a63d5550517 (diff) | |
download | lingo-ap-tracker-f9d209b21596e5aac09a7743385065803749f6a0.tar.gz lingo-ap-tracker-f9d209b21596e5aac09a7743385065803749f6a0.tar.bz2 lingo-ap-tracker-f9d209b21596e5aac09a7743385065803749f6a0.zip |
Subway: Click to activate scroll / sticky popup
-rw-r--r-- | src/subway_map.cpp | 97 | ||||
-rw-r--r-- | src/subway_map.h | 6 |
2 files changed, 74 insertions, 29 deletions
diff --git a/src/subway_map.cpp b/src/subway_map.cpp index 9175514..77f6ae6 100644 --- a/src/subway_map.cpp +++ b/src/subway_map.cpp | |||
@@ -53,6 +53,7 @@ SubwayMap::SubwayMap(wxWindow *parent) : wxPanel(parent, wxID_ANY) { | |||
53 | Bind(wxEVT_MOTION, &SubwayMap::OnMouseMove, this); | 53 | Bind(wxEVT_MOTION, &SubwayMap::OnMouseMove, this); |
54 | Bind(wxEVT_MOUSEWHEEL, &SubwayMap::OnMouseScroll, this); | 54 | Bind(wxEVT_MOUSEWHEEL, &SubwayMap::OnMouseScroll, this); |
55 | Bind(wxEVT_LEAVE_WINDOW, &SubwayMap::OnMouseLeave, this); | 55 | Bind(wxEVT_LEAVE_WINDOW, &SubwayMap::OnMouseLeave, this); |
56 | Bind(wxEVT_LEFT_DOWN, &SubwayMap::OnMouseClick, this); | ||
56 | Bind(wxEVT_TIMER, &SubwayMap::OnTimer, this); | 57 | Bind(wxEVT_TIMER, &SubwayMap::OnTimer, this); |
57 | 58 | ||
58 | zoom_slider_ = new wxSlider(this, wxID_ANY, 0, 0, 8, {15, 15}); | 59 | zoom_slider_ = new wxSlider(this, wxID_ANY, 0, 0, 8, {15, 15}); |
@@ -216,6 +217,8 @@ void SubwayMap::OnPaint(wxPaintEvent &event) { | |||
216 | } | 217 | } |
217 | 218 | ||
218 | if (hovered_item_) { | 219 | if (hovered_item_) { |
220 | // Note that these requirements are duplicated on OnMouseClick so that it | ||
221 | // knows when an item has a hover effect. | ||
219 | const SubwayItem &subway_item = GD_GetSubwayItem(*hovered_item_); | 222 | const SubwayItem &subway_item = GD_GetSubwayItem(*hovered_item_); |
220 | if (subway_item.door && !GetDoorRequirements(*subway_item.door).empty()) { | 223 | if (subway_item.door && !GetDoorRequirements(*subway_item.door).empty()) { |
221 | const std::map<std::string, bool> &report = | 224 | const std::map<std::string, bool> &report = |
@@ -354,44 +357,22 @@ void SubwayMap::OnMouseMove(wxMouseEvent &event) { | |||
354 | 357 | ||
355 | std::vector<int> hovered = tree_->query( | 358 | std::vector<int> hovered = tree_->query( |
356 | {static_cast<float>(mouse_pos.x), static_cast<float>(mouse_pos.y), 2, 2}); | 359 | {static_cast<float>(mouse_pos.x), static_cast<float>(mouse_pos.y), 2, 2}); |
357 | std::optional<int> new_hovered_item; | ||
358 | if (!hovered.empty()) { | 360 | if (!hovered.empty()) { |
359 | new_hovered_item = hovered[0]; | 361 | actual_hover_= hovered[0]; |
362 | } else { | ||
363 | actual_hover_ = std::nullopt; | ||
360 | } | 364 | } |
361 | 365 | ||
362 | if (new_hovered_item != hovered_item_) { | 366 | if (!sticky_hover_ && actual_hover_ != hovered_item_) { |
363 | hovered_item_ = new_hovered_item; | 367 | hovered_item_ = actual_hover_; |
364 | 368 | ||
365 | Refresh(); | 369 | Refresh(); |
366 | } | 370 | } |
367 | 371 | ||
368 | int scroll_x; | 372 | if (scroll_mode_) { |
369 | int scroll_y; | 373 | EvaluateScroll(event.GetPosition()); |
370 | if (event.GetPosition().x < GetSize().GetWidth() / 9) { | ||
371 | scroll_x = 20; | ||
372 | } else if (event.GetPosition().x < GetSize().GetWidth() / 6) { | ||
373 | scroll_x = 5; | ||
374 | } else if (event.GetPosition().x > 8 * GetSize().GetWidth() / 9) { | ||
375 | scroll_x = -20; | ||
376 | } else if (event.GetPosition().x > 5 * GetSize().GetWidth() / 6) { | ||
377 | scroll_x = -5; | ||
378 | } else { | ||
379 | scroll_x = 0; | ||
380 | } | ||
381 | if (event.GetPosition().y < GetSize().GetHeight() / 9) { | ||
382 | scroll_y = 20; | ||
383 | } else if (event.GetPosition().y < GetSize().GetHeight() / 6) { | ||
384 | scroll_y = 5; | ||
385 | } else if (event.GetPosition().y > 8 * GetSize().GetHeight() / 9) { | ||
386 | scroll_y = -20; | ||
387 | } else if (event.GetPosition().y > 5 * GetSize().GetHeight() / 6) { | ||
388 | scroll_y = -5; | ||
389 | } else { | ||
390 | scroll_y = 0; | ||
391 | } | 374 | } |
392 | 375 | ||
393 | SetScrollSpeed(scroll_x, scroll_y); | ||
394 | |||
395 | mouse_position_ = event.GetPosition(); | 376 | mouse_position_ = event.GetPosition(); |
396 | 377 | ||
397 | event.Skip(); | 378 | event.Skip(); |
@@ -417,6 +398,35 @@ void SubwayMap::OnMouseLeave(wxMouseEvent &event) { | |||
417 | mouse_position_ = std::nullopt; | 398 | mouse_position_ = std::nullopt; |
418 | } | 399 | } |
419 | 400 | ||
401 | void SubwayMap::OnMouseClick(wxMouseEvent &event) { | ||
402 | if (sticky_hover_) { | ||
403 | sticky_hover_ = false; | ||
404 | |||
405 | if (actual_hover_ != hovered_item_) { | ||
406 | hovered_item_ = actual_hover_; | ||
407 | |||
408 | Refresh(); | ||
409 | } | ||
410 | } else if (hovered_item_) { | ||
411 | const SubwayItem &subway_item = GD_GetSubwayItem(*hovered_item_); | ||
412 | if ((subway_item.door && !GetDoorRequirements(*subway_item.door).empty()) || | ||
413 | networks_.IsItemInNetwork(*hovered_item_)) { | ||
414 | sticky_hover_ = true; | ||
415 | } | ||
416 | } else if (scroll_mode_) { | ||
417 | scroll_mode_ = false; | ||
418 | |||
419 | SetScrollSpeed(0, 0); | ||
420 | } else if (event.GetPosition().x < GetSize().GetWidth() / 6 || | ||
421 | event.GetPosition().x > 5 * GetSize().GetWidth() / 6 || | ||
422 | event.GetPosition().y < GetSize().GetHeight() / 6 || | ||
423 | event.GetPosition().y > 5 * GetSize().GetHeight() / 6) { | ||
424 | scroll_mode_ = true; | ||
425 | |||
426 | EvaluateScroll(event.GetPosition()); | ||
427 | } | ||
428 | } | ||
429 | |||
420 | void SubwayMap::OnTimer(wxTimerEvent &event) { | 430 | void SubwayMap::OnTimer(wxTimerEvent &event) { |
421 | SetZoomPos({zoom_x_ + scroll_x_, zoom_y_ + scroll_y_}); | 431 | SetZoomPos({zoom_x_ + scroll_x_, zoom_y_ + scroll_y_}); |
422 | Refresh(); | 432 | Refresh(); |
@@ -504,6 +514,35 @@ void SubwayMap::Redraw() { | |||
504 | } | 514 | } |
505 | } | 515 | } |
506 | 516 | ||
517 | void SubwayMap::EvaluateScroll(wxPoint pos) { | ||
518 | int scroll_x; | ||
519 | int scroll_y; | ||
520 | if (pos.x < GetSize().GetWidth() / 9) { | ||
521 | scroll_x = 20; | ||
522 | } else if (pos.x < GetSize().GetWidth() / 6) { | ||
523 | scroll_x = 5; | ||
524 | } else if (pos.x > 8 * GetSize().GetWidth() / 9) { | ||
525 | scroll_x = -20; | ||
526 | } else if (pos.x > 5 * GetSize().GetWidth() / 6) { | ||
527 | scroll_x = -5; | ||
528 | } else { | ||
529 | scroll_x = 0; | ||
530 | } | ||
531 | if (pos.y < GetSize().GetHeight() / 9) { | ||
532 | scroll_y = 20; | ||
533 | } else if (pos.y < GetSize().GetHeight() / 6) { | ||
534 | scroll_y = 5; | ||
535 | } else if (pos.y > 8 * GetSize().GetHeight() / 9) { | ||
536 | scroll_y = -20; | ||
537 | } else if (pos.y > 5 * GetSize().GetHeight() / 6) { | ||
538 | scroll_y = -5; | ||
539 | } else { | ||
540 | scroll_y = 0; | ||
541 | } | ||
542 | |||
543 | SetScrollSpeed(scroll_x, scroll_y); | ||
544 | } | ||
545 | |||
507 | wxPoint SubwayMap::MapPosToRenderPos(wxPoint pos) const { | 546 | wxPoint SubwayMap::MapPosToRenderPos(wxPoint pos) const { |
508 | return {static_cast<int>(pos.x * render_width_ * zoom_ / | 547 | return {static_cast<int>(pos.x * render_width_ * zoom_ / |
509 | map_image_.GetSize().GetWidth() + | 548 | map_image_.GetSize().GetWidth() + |
diff --git a/src/subway_map.h b/src/subway_map.h index 986998a..8b8c6a6 100644 --- a/src/subway_map.h +++ b/src/subway_map.h | |||
@@ -32,6 +32,7 @@ class SubwayMap : public wxPanel { | |||
32 | void OnMouseMove(wxMouseEvent &event); | 32 | void OnMouseMove(wxMouseEvent &event); |
33 | void OnMouseScroll(wxMouseEvent &event); | 33 | void OnMouseScroll(wxMouseEvent &event); |
34 | void OnMouseLeave(wxMouseEvent &event); | 34 | void OnMouseLeave(wxMouseEvent &event); |
35 | void OnMouseClick(wxMouseEvent &event); | ||
35 | void OnTimer(wxTimerEvent &event); | 36 | void OnTimer(wxTimerEvent &event); |
36 | void OnZoomSlide(wxCommandEvent &event); | 37 | void OnZoomSlide(wxCommandEvent &event); |
37 | 38 | ||
@@ -41,6 +42,8 @@ class SubwayMap : public wxPanel { | |||
41 | wxPoint MapPosToVirtualPos(wxPoint pos) const; | 42 | wxPoint MapPosToVirtualPos(wxPoint pos) const; |
42 | wxPoint RenderPosToMapPos(wxPoint pos) const; | 43 | wxPoint RenderPosToMapPos(wxPoint pos) const; |
43 | 44 | ||
45 | void EvaluateScroll(wxPoint pos); | ||
46 | |||
44 | void SetZoomPos(wxPoint pos); | 47 | void SetZoomPos(wxPoint pos); |
45 | void SetScrollSpeed(int scroll_x, int scroll_y); | 48 | void SetScrollSpeed(int scroll_x, int scroll_y); |
46 | void SetZoom(double zoom, wxPoint static_point); | 49 | void SetZoom(double zoom, wxPoint static_point); |
@@ -60,6 +63,7 @@ class SubwayMap : public wxPanel { | |||
60 | int zoom_x_ = 0; // in render space | 63 | int zoom_x_ = 0; // in render space |
61 | int zoom_y_ = 0; | 64 | int zoom_y_ = 0; |
62 | 65 | ||
66 | bool scroll_mode_ = false; | ||
63 | wxTimer* scroll_timer_; | 67 | wxTimer* scroll_timer_; |
64 | int scroll_x_ = 0; | 68 | int scroll_x_ = 0; |
65 | int scroll_y_ = 0; | 69 | int scroll_y_ = 0; |
@@ -74,6 +78,8 @@ class SubwayMap : public wxPanel { | |||
74 | 78 | ||
75 | std::unique_ptr<quadtree::Quadtree<int, GetItemBox>> tree_; | 79 | std::unique_ptr<quadtree::Quadtree<int, GetItemBox>> tree_; |
76 | std::optional<int> hovered_item_; | 80 | std::optional<int> hovered_item_; |
81 | std::optional<int> actual_hover_; | ||
82 | bool sticky_hover_ = false; | ||
77 | 83 | ||
78 | NetworkSet networks_; | 84 | NetworkSet networks_; |
79 | std::set<std::string> checked_paintings_; | 85 | std::set<std::string> checked_paintings_; |