about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/subway_map.cpp97
-rw-r--r--src/subway_map.h6
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
401void 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
420void SubwayMap::OnTimer(wxTimerEvent &event) { 430void 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
517void 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
507wxPoint SubwayMap::MapPosToRenderPos(wxPoint pos) const { 546wxPoint 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_;