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