diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2025-03-10 12:45:14 -0400 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2025-03-10 12:45:14 -0400 |
commit | 79424e86dd7aa28c1b25868d86fa8ebffc801593 (patch) | |
tree | ebbc23fb998f14d69e638ce8b973b5a7da0b46c6 /src/area_popup.cpp | |
parent | d3457700075fab2dac25bcff2775b7ae5a436a28 (diff) | |
download | lingo-ap-tracker-79424e86dd7aa28c1b25868d86fa8ebffc801593.tar.gz lingo-ap-tracker-79424e86dd7aa28c1b25868d86fa8ebffc801593.tar.bz2 lingo-ap-tracker-79424e86dd7aa28c1b25868d86fa8ebffc801593.zip |
Optimized AreaPopup indicators
The list of indicators and the size of the window are calculated only when necessary (new connection, DPI changed, or hunt panel settings changed) and otherwise all we do is redraw the image.
Diffstat (limited to 'src/area_popup.cpp')
-rw-r--r-- | src/area_popup.cpp | 147 |
1 files changed, 77 insertions, 70 deletions
diff --git a/src/area_popup.cpp b/src/area_popup.cpp index d7f45b6..a8e6004 100644 --- a/src/area_popup.cpp +++ b/src/area_popup.cpp | |||
@@ -27,28 +27,26 @@ AreaPopup::AreaPopup(wxWindow* parent, int area_id) | |||
27 | Bind(wxEVT_PAINT, &AreaPopup::OnPaint, this); | 27 | Bind(wxEVT_PAINT, &AreaPopup::OnPaint, this); |
28 | Bind(wxEVT_DPI_CHANGED, &AreaPopup::OnDPIChanged, this); | 28 | Bind(wxEVT_DPI_CHANGED, &AreaPopup::OnDPIChanged, this); |
29 | 29 | ||
30 | UpdateIndicators(); | 30 | ResetIndicators(); |
31 | } | 31 | } |
32 | 32 | ||
33 | void AreaPopup::UpdateIndicators() { | 33 | void AreaPopup::ResetIndicators() { |
34 | const MapArea& map_area = GD_GetMapArea(area_id_); | 34 | indicators_.clear(); |
35 | 35 | ||
36 | const MapArea& map_area = GD_GetMapArea(area_id_); | ||
36 | wxFont the_font = GetFont().Scale(GetDPIScaleFactor()); | 37 | wxFont the_font = GetFont().Scale(GetDPIScaleFactor()); |
38 | TrackerPanel* tracker_panel = dynamic_cast<TrackerPanel*>(GetParent()); | ||
37 | 39 | ||
38 | // Start calculating extents. | 40 | // Start calculating extents. |
39 | wxMemoryDC mem_dc; | 41 | wxMemoryDC mem_dc; |
40 | mem_dc.SetFont(the_font.Bold()); | 42 | mem_dc.SetFont(the_font.Bold()); |
41 | wxSize header_extent = mem_dc.GetTextExtent(map_area.name); | 43 | header_extent_ = mem_dc.GetTextExtent(map_area.name); |
42 | 44 | ||
43 | int acc_height = header_extent.GetHeight() + FromDIP(20); | 45 | int acc_height = header_extent_.GetHeight() + FromDIP(20); |
44 | int col_width = 0; | 46 | int col_width = 0; |
45 | 47 | ||
46 | mem_dc.SetFont(the_font); | 48 | mem_dc.SetFont(the_font); |
47 | 49 | ||
48 | TrackerPanel* tracker_panel = dynamic_cast<TrackerPanel*>(GetParent()); | ||
49 | |||
50 | std::vector<int> real_locations; | ||
51 | |||
52 | for (int section_id = 0; section_id < map_area.locations.size(); | 50 | for (int section_id = 0; section_id < map_area.locations.size(); |
53 | section_id++) { | 51 | section_id++) { |
54 | const Location& location = map_area.locations.at(section_id); | 52 | const Location& location = map_area.locations.at(section_id); |
@@ -67,7 +65,7 @@ void AreaPopup::UpdateIndicators() { | |||
67 | } | 65 | } |
68 | } | 66 | } |
69 | 67 | ||
70 | real_locations.push_back(section_id); | 68 | indicators_.emplace_back(section_id, kLOCATION, acc_height); |
71 | 69 | ||
72 | wxSize item_extent = mem_dc.GetTextExtent(location.name); | 70 | wxSize item_extent = mem_dc.GetTextExtent(location.name); |
73 | int item_height = | 71 | int item_height = |
@@ -85,6 +83,8 @@ void AreaPopup::UpdateIndicators() { | |||
85 | continue; | 83 | continue; |
86 | } | 84 | } |
87 | 85 | ||
86 | indicators_.emplace_back(painting_id, kPAINTING, acc_height); | ||
87 | |||
88 | const PaintingExit& painting = GD_GetPaintingExit(painting_id); | 88 | const PaintingExit& painting = GD_GetPaintingExit(painting_id); |
89 | wxSize item_extent = mem_dc.GetTextExtent(painting.display_name); | 89 | wxSize item_extent = mem_dc.GetTextExtent(painting.display_name); |
90 | int item_height = | 90 | int item_height = |
@@ -98,84 +98,91 @@ void AreaPopup::UpdateIndicators() { | |||
98 | } | 98 | } |
99 | 99 | ||
100 | int item_width = col_width + FromDIP(10 + 32); | 100 | int item_width = col_width + FromDIP(10 + 32); |
101 | int full_width = std::max(header_extent.GetWidth(), item_width) + FromDIP(20); | 101 | full_width_ = std::max(header_extent_.GetWidth(), item_width) + FromDIP(20); |
102 | full_height_ = acc_height; | ||
102 | 103 | ||
103 | Fit(); | 104 | Fit(); |
104 | SetVirtualSize(full_width, acc_height); | 105 | SetVirtualSize(full_width_, full_height_); |
106 | |||
107 | UpdateIndicators(); | ||
108 | } | ||
109 | |||
110 | void AreaPopup::UpdateIndicators() { | ||
111 | const MapArea& map_area = GD_GetMapArea(area_id_); | ||
112 | wxFont the_font = GetFont().Scale(GetDPIScaleFactor()); | ||
113 | TrackerPanel* tracker_panel = dynamic_cast<TrackerPanel*>(GetParent()); | ||
114 | |||
115 | rendered_ = wxBitmap(full_width_, full_height_); | ||
105 | 116 | ||
106 | rendered_ = wxBitmap(full_width, acc_height); | 117 | wxMemoryDC mem_dc; |
107 | mem_dc.SelectObject(rendered_); | 118 | mem_dc.SelectObject(rendered_); |
108 | mem_dc.SetPen(*wxTRANSPARENT_PEN); | 119 | mem_dc.SetPen(*wxTRANSPARENT_PEN); |
109 | mem_dc.SetBrush(*wxBLACK_BRUSH); | 120 | mem_dc.SetBrush(*wxBLACK_BRUSH); |
110 | mem_dc.DrawRectangle({0, 0}, {full_width, acc_height}); | 121 | mem_dc.DrawRectangle({0, 0}, {full_width_, full_height_}); |
111 | 122 | ||
112 | mem_dc.SetFont(the_font.Bold()); | 123 | mem_dc.SetFont(the_font.Bold()); |
113 | mem_dc.SetTextForeground(*wxWHITE); | 124 | mem_dc.SetTextForeground(*wxWHITE); |
114 | mem_dc.DrawText(map_area.name, | 125 | mem_dc.DrawText(map_area.name, |
115 | {(full_width - header_extent.GetWidth()) / 2, FromDIP(10)}); | 126 | {(full_width_ - header_extent_.GetWidth()) / 2, FromDIP(10)}); |
116 | |||
117 | int cur_height = header_extent.GetHeight() + FromDIP(20); | ||
118 | 127 | ||
119 | mem_dc.SetFont(the_font); | 128 | mem_dc.SetFont(the_font); |
120 | 129 | ||
121 | for (int section_id : real_locations) { | 130 | for (const IndicatorInfo& indicator : indicators_) { |
122 | const Location& location = map_area.locations.at(section_id); | 131 | switch (indicator.type) { |
123 | 132 | case kLOCATION: { | |
124 | bool checked = false; | 133 | const Location& location = map_area.locations.at(indicator.id); |
125 | if (IsLocationWinCondition(location)) { | 134 | |
126 | checked = AP_HasReachedGoal(); | 135 | bool checked = false; |
127 | } else if (tracker_panel->IsPanelsMode()) { | 136 | if (IsLocationWinCondition(location)) { |
128 | const Panel& panel = GD_GetPanel(*location.single_panel); | 137 | checked = AP_HasReachedGoal(); |
129 | if (panel.non_counting) { | 138 | } else if (tracker_panel->IsPanelsMode()) { |
130 | checked = AP_HasCheckedGameLocation(location.ap_location_id); | 139 | const Panel& panel = GD_GetPanel(*location.single_panel); |
131 | } else { | 140 | if (panel.non_counting) { |
132 | checked = tracker_panel->GetSolvedPanels().contains(panel.nodepath); | 141 | checked = AP_HasCheckedGameLocation(location.ap_location_id); |
142 | } else { | ||
143 | checked = tracker_panel->GetSolvedPanels().contains(panel.nodepath); | ||
144 | } | ||
145 | } else { | ||
146 | checked = AP_HasCheckedGameLocation(location.ap_location_id) || | ||
147 | (location.hunt && | ||
148 | AP_HasCheckedHuntPanel(location.ap_location_id)); | ||
149 | } | ||
150 | |||
151 | const wxBitmap* eye_ptr = checked ? checked_eye_ : unchecked_eye_; | ||
152 | |||
153 | mem_dc.DrawBitmap(*eye_ptr, {FromDIP(10), indicator.y}); | ||
154 | |||
155 | bool reachable = IsLocationReachable(location.ap_location_id); | ||
156 | const wxColour* text_color = reachable ? wxWHITE : wxRED; | ||
157 | mem_dc.SetTextForeground(*text_color); | ||
158 | |||
159 | wxSize item_extent = mem_dc.GetTextExtent(location.name); | ||
160 | mem_dc.DrawText( | ||
161 | location.name, | ||
162 | {FromDIP(10 + 32 + 10), | ||
163 | indicator.y + (FromDIP(32) - mem_dc.GetFontMetrics().height) / 2}); | ||
164 | |||
165 | break; | ||
133 | } | 166 | } |
134 | } else { | 167 | case kPAINTING: { |
135 | checked = | 168 | const PaintingExit& painting = GD_GetPaintingExit(indicator.id); |
136 | AP_HasCheckedGameLocation(location.ap_location_id) || | ||
137 | (location.hunt && AP_HasCheckedHuntPanel(location.ap_location_id)); | ||
138 | } | ||
139 | |||
140 | const wxBitmap* eye_ptr = checked ? checked_eye_ : unchecked_eye_; | ||
141 | 169 | ||
142 | mem_dc.DrawBitmap(*eye_ptr, {FromDIP(10), cur_height}); | 170 | bool reachable = IsPaintingReachable(indicator.id); |
171 | const wxColour* text_color = reachable ? wxWHITE : wxRED; | ||
172 | mem_dc.SetTextForeground(*text_color); | ||
143 | 173 | ||
144 | bool reachable = IsLocationReachable(location.ap_location_id); | 174 | bool checked = reachable && AP_IsPaintingChecked(painting.internal_id); |
145 | const wxColour* text_color = reachable ? wxWHITE : wxRED; | 175 | const wxBitmap* eye_ptr = checked ? checked_owl_ : unchecked_owl_; |
146 | mem_dc.SetTextForeground(*text_color); | 176 | mem_dc.DrawBitmap(*eye_ptr, {FromDIP(10), indicator.y}); |
147 | 177 | ||
148 | wxSize item_extent = mem_dc.GetTextExtent(location.name); | 178 | wxSize item_extent = mem_dc.GetTextExtent(painting.display_name); |
149 | mem_dc.DrawText( | 179 | mem_dc.DrawText( |
150 | location.name, | 180 | painting.display_name, |
151 | {FromDIP(10 + 32 + 10), | 181 | {FromDIP(10 + 32 + 10), |
152 | cur_height + (FromDIP(32) - mem_dc.GetFontMetrics().height) / 2}); | 182 | indicator.y + (FromDIP(32) - mem_dc.GetFontMetrics().height) / 2}); |
153 | |||
154 | cur_height += FromDIP(10 + 32); | ||
155 | } | ||
156 | 183 | ||
157 | if (AP_IsPaintingShuffle() && !tracker_panel->IsPanelsMode()) { | 184 | break; |
158 | for (int painting_id : map_area.paintings) { | ||
159 | if (IsPaintingPostgame(painting_id)) { | ||
160 | continue; | ||
161 | } | 185 | } |
162 | |||
163 | const PaintingExit& painting = GD_GetPaintingExit(painting_id); | ||
164 | |||
165 | bool reachable = IsPaintingReachable(painting_id); | ||
166 | const wxColour* text_color = reachable ? wxWHITE : wxRED; | ||
167 | mem_dc.SetTextForeground(*text_color); | ||
168 | |||
169 | bool checked = reachable && AP_IsPaintingChecked(painting.internal_id); | ||
170 | const wxBitmap* eye_ptr = checked ? checked_owl_ : unchecked_owl_; | ||
171 | mem_dc.DrawBitmap(*eye_ptr, {FromDIP(10), cur_height}); | ||
172 | |||
173 | wxSize item_extent = mem_dc.GetTextExtent(painting.display_name); | ||
174 | mem_dc.DrawText(painting.display_name, | ||
175 | {FromDIP(10 + 32 + 10), | ||
176 | cur_height + (FromDIP(32) - mem_dc.GetFontMetrics().height) / 2}); | ||
177 | |||
178 | cur_height += FromDIP(10 + 32); | ||
179 | } | 186 | } |
180 | } | 187 | } |
181 | } | 188 | } |
@@ -190,7 +197,7 @@ void AreaPopup::OnPaint(wxPaintEvent& event) { | |||
190 | 197 | ||
191 | void AreaPopup::OnDPIChanged(wxDPIChangedEvent& event) { | 198 | void AreaPopup::OnDPIChanged(wxDPIChangedEvent& event) { |
192 | LoadIcons(); | 199 | LoadIcons(); |
193 | UpdateIndicators(); | 200 | ResetIndicators(); |
194 | 201 | ||
195 | event.Skip(); | 202 | event.Skip(); |
196 | } | 203 | } |