From 0121ce8e79a17336e42ccd14afd9a9c5dbfb29df Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Mon, 10 Mar 2025 13:35:48 -0400 Subject: Optimized TrackerPanel refresh Scaling the map image, determining which map areas are active, placing each area indicator, and positioning the area popups now only happen when necessary (the panel is resized / DPI changed, new connection, hunt settings changed). Notably, this means that updating indicators in a regular way such as from clearing locations will not have to resize the image or reposition windows. It will just redraw all of the indicators on the map image. --- src/tracker_panel.cpp | 116 +++++++++++++++++++++++++++++--------------------- src/tracker_panel.h | 3 ++ 2 files changed, 70 insertions(+), 49 deletions(-) diff --git a/src/tracker_panel.cpp b/src/tracker_panel.cpp index 64e6ab3..37e3265 100644 --- a/src/tracker_panel.cpp +++ b/src/tracker_panel.cpp @@ -44,6 +44,7 @@ TrackerPanel::TrackerPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY) { areas_.push_back(area); } + Resize(); Redraw(); Bind(wxEVT_PAINT, &TrackerPanel::OnPaint, this); @@ -57,8 +58,24 @@ void TrackerPanel::UpdateIndicators(bool reset) { if (reset) { for (AreaIndicator &area : areas_) { + const MapArea &map_area = GD_GetMapArea(area.area_id); + + if (IsAreaPostgame(area.area_id)) { + area.active = false; + } else if (panels_mode_) { + area.active = map_area.has_single_panel; + } else if (!AP_IsLocationVisible(map_area.classification) && + !(map_area.hunt && GetTrackerConfig().show_hunt_panels) && + !(AP_IsPaintingShuffle() && !map_area.paintings.empty())) { + area.active = false; + } else { + area.active = true; + } + area.popup->ResetIndicators(); } + + Resize(); } else { for (AreaIndicator &area : areas_) { area.popup->UpdateIndicators(); @@ -103,6 +120,7 @@ void TrackerPanel::RefreshSavedata() { void TrackerPanel::OnPaint(wxPaintEvent &event) { if (GetSize() != rendered_.GetSize()) { + Resize(); Redraw(); if (refresh_button_ != nullptr) { @@ -160,7 +178,7 @@ void TrackerPanel::OnRefreshSavedata(wxCommandEvent &event) { RefreshSavedata(); } -void TrackerPanel::Redraw() { +void TrackerPanel::Resize() { wxSize panel_size = GetSize(); wxSize image_size = map_image_.GetSize(); @@ -180,7 +198,7 @@ void TrackerPanel::Redraw() { final_x = (panel_size.GetWidth() - final_width) / 2; } - rendered_ = wxBitmap( + scaled_map_ = wxBitmap( map_image_.Scale(final_width, final_height, wxIMAGE_QUALITY_NORMAL) .Size(panel_size, {final_x, final_y}, 0, 0, 0)); @@ -195,32 +213,57 @@ void TrackerPanel::Redraw() { wxBitmap(player_image_.Scale(player_width > 0 ? player_width : 1, player_height > 0 ? player_height : 1)); + real_area_size_ = final_width * AREA_EFFECTIVE_SIZE / image_size.GetWidth(); + + for (AreaIndicator &area : areas_) { + const MapArea &map_area = GD_GetMapArea(area.area_id); + + int real_area_x = final_x + (map_area.map_x - (AREA_EFFECTIVE_SIZE / 2)) * + final_width / image_size.GetWidth(); + int real_area_y = final_y + (map_area.map_y - (AREA_EFFECTIVE_SIZE / 2)) * + final_width / image_size.GetWidth(); + + area.real_x1 = real_area_x; + area.real_x2 = real_area_x + real_area_size_; + area.real_y1 = real_area_y; + area.real_y2 = real_area_y + real_area_size_; + + int popup_x = + final_x + map_area.map_x * final_width / image_size.GetWidth(); + int popup_y = + final_y + map_area.map_y * final_width / image_size.GetWidth(); + + area.popup->SetClientSize( + area.popup->GetVirtualSize().GetWidth(), + std::min(panel_size.GetHeight(), + area.popup->GetVirtualSize().GetHeight())); + + if (popup_x + area.popup->GetSize().GetWidth() > panel_size.GetWidth()) { + popup_x = panel_size.GetWidth() - area.popup->GetSize().GetWidth(); + } + if (popup_y + area.popup->GetSize().GetHeight() > panel_size.GetHeight()) { + popup_y = panel_size.GetHeight() - area.popup->GetSize().GetHeight(); + } + area.popup->SetPosition({popup_x, popup_y}); + } +} + +void TrackerPanel::Redraw() { + rendered_ = scaled_map_; + wxMemoryDC dc; dc.SelectObject(rendered_); - int real_area_size = - final_width * AREA_EFFECTIVE_SIZE / image_size.GetWidth(); int actual_border_size = - real_area_size * AREA_BORDER_SIZE / AREA_EFFECTIVE_SIZE; + real_area_size_ * AREA_BORDER_SIZE / AREA_EFFECTIVE_SIZE; const wxPoint upper_left_triangle[] = { - {0, 0}, {0, real_area_size}, {real_area_size, 0}}; - const wxPoint lower_right_triangle[] = {{0, real_area_size - 1}, - {real_area_size - 1, 0}, - {real_area_size, real_area_size}}; + {0, 0}, {0, real_area_size_}, {real_area_size_, 0}}; + const wxPoint lower_right_triangle[] = {{0, real_area_size_ - 1}, + {real_area_size_ - 1, 0}, + {real_area_size_, real_area_size_}}; for (AreaIndicator &area : areas_) { const MapArea &map_area = GD_GetMapArea(area.area_id); - if (IsAreaPostgame(area.area_id)) { - area.active = false; - } else if (panels_mode_) { - area.active = map_area.has_single_panel; - } else if (!AP_IsLocationVisible(map_area.classification) && - !(map_area.hunt && GetTrackerConfig().show_hunt_panels) && - !(AP_IsPaintingShuffle() && !map_area.paintings.empty())) { - area.active = false; - } else { - area.active = true; - } if (!area.active) { continue; @@ -276,10 +319,8 @@ void TrackerPanel::Redraw() { } } - int real_area_x = final_x + (map_area.map_x - (AREA_EFFECTIVE_SIZE / 2)) * - final_width / image_size.GetWidth(); - int real_area_y = final_y + (map_area.map_y - (AREA_EFFECTIVE_SIZE / 2)) * - final_width / image_size.GetWidth(); + int real_area_x = area.real_x1; + int real_area_y = area.real_y1; if (has_reachable_unchecked && has_unreachable_unchecked && GetTrackerConfig().hybrid_areas) { @@ -293,7 +334,7 @@ void TrackerPanel::Redraw() { dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, actual_border_size)); dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.DrawRectangle({real_area_x, real_area_y}, - {real_area_size, real_area_size}); + {real_area_size_, real_area_size_}); } else { const wxBrush *brush_color = wxGREY_BRUSH; @@ -308,31 +349,8 @@ void TrackerPanel::Redraw() { dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, actual_border_size)); dc.SetBrush(*brush_color); dc.DrawRectangle({real_area_x, real_area_y}, - {real_area_size, real_area_size}); + {real_area_size_, real_area_size_}); } - - area.real_x1 = real_area_x; - area.real_x2 = real_area_x + real_area_size; - area.real_y1 = real_area_y; - area.real_y2 = real_area_y + real_area_size; - - int popup_x = - final_x + map_area.map_x * final_width / image_size.GetWidth(); - int popup_y = - final_y + map_area.map_y * final_width / image_size.GetWidth(); - - area.popup->SetClientSize( - area.popup->GetVirtualSize().GetWidth(), - std::min(panel_size.GetHeight(), - area.popup->GetVirtualSize().GetHeight())); - - if (popup_x + area.popup->GetSize().GetWidth() > panel_size.GetWidth()) { - popup_x = panel_size.GetWidth() - area.popup->GetSize().GetWidth(); - } - if (popup_y + area.popup->GetSize().GetHeight() > panel_size.GetHeight()) { - popup_y = panel_size.GetHeight() - area.popup->GetSize().GetHeight(); - } - area.popup->SetPosition({popup_x, popup_y}); } } diff --git a/src/tracker_panel.h b/src/tracker_panel.h index ae89a35..abab1bf 100644 --- a/src/tracker_panel.h +++ b/src/tracker_panel.h @@ -44,6 +44,7 @@ class TrackerPanel : public wxPanel { void OnMouseMove(wxMouseEvent &event); void OnRefreshSavedata(wxCommandEvent &event); + void Resize(); void Redraw(); void RefreshSavedata(); @@ -52,6 +53,7 @@ class TrackerPanel : public wxPanel { wxImage map_image_; wxImage player_image_; + wxBitmap scaled_map_; wxBitmap rendered_; wxBitmap scaled_player_; @@ -61,6 +63,7 @@ class TrackerPanel : public wxPanel { int offset_y_ = 0; double scale_x_ = 0; double scale_y_ = 0; + int real_area_size_ = 0; std::vector areas_; -- cgit 1.4.1