From 0a3c0c6882db2976c2b6fdbebbc127747ed63703 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Fri, 19 Jan 2024 18:16:41 -0500 Subject: Area popups are now painted Instead of being a bunch of controls. This fixes the problem with the window being slow to drag around, and with items in lists disappearing. Overall W for me. --- src/area_popup.cpp | 118 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 39 deletions(-) (limited to 'src/area_popup.cpp') diff --git a/src/area_popup.cpp b/src/area_popup.cpp index 6bbc0cf..8f694bb 100644 --- a/src/area_popup.cpp +++ b/src/area_popup.cpp @@ -2,73 +2,113 @@ #include "ap_state.h" #include "game_data.h" +#include "global.h" #include "tracker_config.h" #include "tracker_state.h" AreaPopup::AreaPopup(wxWindow* parent, int area_id) - : wxScrolledWindow(parent, wxID_ANY), area_id_(area_id) { - const MapArea& map_area = GD_GetMapArea(area_id); - - wxFlexGridSizer* section_sizer = new wxFlexGridSizer(2, 10, 10); - - for (const Location& location : map_area.locations) { - EyeIndicator* eye_indicator = new EyeIndicator(this); - section_sizer->Add(eye_indicator, wxSizerFlags().Expand()); - eye_indicators_.push_back(eye_indicator); - - wxStaticText* section_label = new wxStaticText(this, -1, location.name); - section_label->SetForegroundColour(*wxWHITE); - section_sizer->Add( - section_label, - wxSizerFlags().Align(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL)); - section_labels_.push_back(section_label); - } - - wxBoxSizer* top_sizer = new wxBoxSizer(wxVERTICAL); - - wxStaticText* top_label = new wxStaticText(this, -1, map_area.name); - top_label->SetForegroundColour(*wxWHITE); - top_label->SetFont(top_label->GetFont().Bold()); - top_sizer->Add(top_label, - wxSizerFlags().Center().DoubleBorder(wxUP | wxLEFT | wxRIGHT)); - - top_sizer->Add(section_sizer, wxSizerFlags().DoubleBorder(wxALL).Expand()); + : wxScrolledCanvas(parent, wxID_ANY), area_id_(area_id) { + unchecked_eye_ = + wxBitmap(wxImage(GetAbsolutePath("assets/unchecked.png").c_str(), + wxBITMAP_TYPE_PNG) + .Scale(32, 32)); + checked_eye_ = wxBitmap( + wxImage(GetAbsolutePath("assets/checked.png").c_str(), wxBITMAP_TYPE_PNG) + .Scale(32, 32)); - SetSizerAndFit(top_sizer); SetScrollRate(5, 5); SetBackgroundColour(*wxBLACK); Hide(); + + Bind(wxEVT_PAINT, &AreaPopup::OnPaint, this); + + UpdateIndicators(); } void AreaPopup::UpdateIndicators() { const MapArea& map_area = GD_GetMapArea(area_id_); + + // Start calculating extents. + wxMemoryDC mem_dc; + mem_dc.SetFont(GetFont().Bold()); + wxSize header_extent = mem_dc.GetTextExtent(map_area.name); + + int acc_height = header_extent.GetHeight() + 20; + int col_width = 0; + + mem_dc.SetFont(GetFont()); + + std::vector real_locations; + for (int section_id = 0; section_id < map_area.locations.size(); section_id++) { const Location& location = map_area.locations.at(section_id); - wxSizer* container_sizer = - section_labels_[section_id]->GetContainingSizer(); if (!AP_IsLocationVisible(location.classification) && !(location.hunt && GetTrackerConfig().show_hunt_panels)) { - container_sizer->Hide(section_labels_[section_id]); - container_sizer->Hide(eye_indicators_[section_id]); continue; - } else { - container_sizer->Show(section_labels_[section_id]); - container_sizer->Show(eye_indicators_[section_id]); } + real_locations.push_back(section_id); + + wxSize item_extent = mem_dc.GetTextExtent(location.name); + int item_height = std::max(32, item_extent.GetHeight()) + 10; + acc_height += item_height; + + if (item_extent.GetWidth() > col_width) { + col_width = item_extent.GetWidth(); + } + } + + int item_width = col_width + 10 + 32; + int full_width = std::max(header_extent.GetWidth(), item_width) + 20; + + SetVirtualSize(full_width, acc_height); + + rendered_ = wxBitmap(full_width, acc_height); + mem_dc.SelectObject(rendered_); + mem_dc.SetPen(*wxTRANSPARENT_PEN); + mem_dc.SetBrush(*wxBLACK_BRUSH); + mem_dc.DrawRectangle({0, 0}, {full_width, acc_height}); + + mem_dc.SetFont(GetFont().Bold()); + mem_dc.SetTextForeground(*wxWHITE); + mem_dc.DrawText(map_area.name, + {(full_width - header_extent.GetWidth()) / 2, 10}); + + int cur_height = header_extent.GetHeight() + 20; + + mem_dc.SetFont(GetFont()); + + for (int section_id : real_locations) { + const Location& location = map_area.locations.at(section_id); + bool checked = AP_HasCheckedGameLocation(location.ap_location_id) || (location.hunt && AP_HasCheckedHuntPanel(location.ap_location_id)); + + wxBitmap* eye_ptr = checked ? &checked_eye_ : &unchecked_eye_; + + mem_dc.DrawBitmap(*eye_ptr, {10, cur_height}); + bool reachable = IsLocationReachable(location.ap_location_id); const wxColour* text_color = reachable ? wxWHITE : wxRED; + mem_dc.SetTextForeground(*text_color); - section_labels_[section_id]->SetForegroundColour(*text_color); - eye_indicators_[section_id]->SetChecked(checked); + wxSize item_extent = mem_dc.GetTextExtent(location.name); + mem_dc.DrawText( + location.name, + {10 + 32 + 10, cur_height + (32 - mem_dc.GetFontMetrics().height) / 2}); + + cur_height += 10 + 32; } +} + +void AreaPopup::OnPaint(wxPaintEvent& event) { + wxPaintDC dc(this); + PrepareDC(dc); + dc.DrawBitmap(rendered_, 0, 0); - section_labels_[0]->GetContainingSizer()->Layout(); - GetSizer()->Fit(this); + event.Skip(); } -- cgit 1.4.1