diff options
-rw-r--r-- | src/area_popup.cpp | 147 | ||||
-rw-r--r-- | src/area_popup.h | 25 | ||||
-rw-r--r-- | src/tracker_frame.cpp | 16 | ||||
-rw-r--r-- | src/tracker_frame.h | 1 | ||||
-rw-r--r-- | src/tracker_panel.cpp | 15 | ||||
-rw-r--r-- | src/tracker_panel.h | 2 |
6 files changed, 125 insertions, 81 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 | } |
diff --git a/src/area_popup.h b/src/area_popup.h index 2401e4e..50e10e8 100644 --- a/src/area_popup.h +++ b/src/area_popup.h | |||
@@ -7,13 +7,32 @@ | |||
7 | #include <wx/wx.h> | 7 | #include <wx/wx.h> |
8 | #endif | 8 | #endif |
9 | 9 | ||
10 | #include <vector> | ||
11 | |||
10 | class AreaPopup : public wxScrolledCanvas { | 12 | class AreaPopup : public wxScrolledCanvas { |
11 | public: | 13 | public: |
12 | AreaPopup(wxWindow* parent, int area_id); | 14 | AreaPopup(wxWindow* parent, int area_id); |
13 | 15 | ||
16 | void ResetIndicators(); | ||
14 | void UpdateIndicators(); | 17 | void UpdateIndicators(); |
15 | 18 | ||
16 | private: | 19 | private: |
20 | enum IndicatorType { | ||
21 | kLOCATION, | ||
22 | kPAINTING, | ||
23 | }; | ||
24 | |||
25 | struct IndicatorInfo { | ||
26 | // For locations, the id is an index into the map area's locations list. | ||
27 | // For paintings, it is a real painting id. | ||
28 | int id; | ||
29 | IndicatorType type; | ||
30 | int y; | ||
31 | |||
32 | IndicatorInfo(int id, IndicatorType type, int y) | ||
33 | : id(id), type(type), y(y) {} | ||
34 | }; | ||
35 | |||
17 | void OnPaint(wxPaintEvent& event); | 36 | void OnPaint(wxPaintEvent& event); |
18 | void OnDPIChanged(wxDPIChangedEvent& event); | 37 | void OnDPIChanged(wxDPIChangedEvent& event); |
19 | 38 | ||
@@ -26,6 +45,12 @@ class AreaPopup : public wxScrolledCanvas { | |||
26 | const wxBitmap* unchecked_owl_; | 45 | const wxBitmap* unchecked_owl_; |
27 | const wxBitmap* checked_owl_; | 46 | const wxBitmap* checked_owl_; |
28 | 47 | ||
48 | int full_width_ = 0; | ||
49 | int full_height_ = 0; | ||
50 | wxSize header_extent_; | ||
51 | |||
52 | std::vector<IndicatorInfo> indicators_; | ||
53 | |||
29 | wxBitmap rendered_; | 54 | wxBitmap rendered_; |
30 | }; | 55 | }; |
31 | 56 | ||
diff --git a/src/tracker_frame.cpp b/src/tracker_frame.cpp index 6a4ab2e..fa68582 100644 --- a/src/tracker_frame.cpp +++ b/src/tracker_frame.cpp | |||
@@ -255,8 +255,9 @@ void TrackerFrame::OnSettings(wxCommandEvent &event) { | |||
255 | GetTrackerConfig().track_position = dlg.GetTrackPosition(); | 255 | GetTrackerConfig().track_position = dlg.GetTrackPosition(); |
256 | GetTrackerConfig().Save(); | 256 | GetTrackerConfig().Save(); |
257 | 257 | ||
258 | UpdateIndicators( | 258 | UpdateIndicators(StateUpdate{.cleared_locations = true, |
259 | StateUpdate{.cleared_locations = true, .player_position = true}); | 259 | .player_position = true, |
260 | .changed_settings = true}); | ||
260 | } | 261 | } |
261 | } | 262 | } |
262 | 263 | ||
@@ -328,7 +329,7 @@ void TrackerFrame::OnSashPositionChanged(wxSplitterEvent& event) { | |||
328 | } | 329 | } |
329 | 330 | ||
330 | void TrackerFrame::OnStateReset(wxCommandEvent &event) { | 331 | void TrackerFrame::OnStateReset(wxCommandEvent &event) { |
331 | tracker_panel_->UpdateIndicators(); | 332 | tracker_panel_->UpdateIndicators(/*reset=*/true); |
332 | achievements_pane_->UpdateIndicators(); | 333 | achievements_pane_->UpdateIndicators(); |
333 | items_pane_->ResetIndicators(); | 334 | items_pane_->ResetIndicators(); |
334 | options_pane_->OnConnect(); | 335 | options_pane_->OnConnect(); |
@@ -350,7 +351,7 @@ void TrackerFrame::OnStateChanged(StateChangedEvent &event) { | |||
350 | panels_panel_->SetPanelsMode(); | 351 | panels_panel_->SetPanelsMode(); |
351 | notebook_->AddPage(panels_panel_, "Panels"); | 352 | notebook_->AddPage(panels_panel_, "Panels"); |
352 | } | 353 | } |
353 | panels_panel_->UpdateIndicators(); | 354 | panels_panel_->UpdateIndicators(/*reset=*/false); |
354 | if (notebook_->GetSelection() == 2) { | 355 | if (notebook_->GetSelection() == 2) { |
355 | Refresh(); | 356 | Refresh(); |
356 | } | 357 | } |
@@ -361,10 +362,13 @@ void TrackerFrame::OnStateChanged(StateChangedEvent &event) { | |||
361 | if (!state.items.empty() || !state.paintings.empty() || | 362 | if (!state.items.empty() || !state.paintings.empty() || |
362 | state.cleared_locations || | 363 | state.cleared_locations || |
363 | (state.hunt_panels && GetTrackerConfig().show_hunt_panels)) { | 364 | (state.hunt_panels && GetTrackerConfig().show_hunt_panels)) { |
364 | tracker_panel_->UpdateIndicators(); | 365 | // TODO: The only real reason to reset tracker_panel during an active |
366 | // connection is if the hunt panels setting changes. If we remove hunt | ||
367 | // panels later, we can get rid of this. | ||
368 | tracker_panel_->UpdateIndicators(/*reset=*/state.changed_settings); | ||
365 | subway_map_->UpdateIndicators(); | 369 | subway_map_->UpdateIndicators(); |
366 | if (panels_panel_ != nullptr) { | 370 | if (panels_panel_ != nullptr) { |
367 | panels_panel_->UpdateIndicators(); | 371 | panels_panel_->UpdateIndicators(/*reset=*/false); |
368 | } | 372 | } |
369 | Refresh(); | 373 | Refresh(); |
370 | } else if (state.player_position && GetTrackerConfig().track_position) { | 374 | } else if (state.player_position && GetTrackerConfig().track_position) { |
diff --git a/src/tracker_frame.h b/src/tracker_frame.h index 7704208..131c7b8 100644 --- a/src/tracker_frame.h +++ b/src/tracker_frame.h | |||
@@ -57,6 +57,7 @@ struct StateUpdate { | |||
57 | bool cleared_locations = false; | 57 | bool cleared_locations = false; |
58 | bool hunt_panels = false; | 58 | bool hunt_panels = false; |
59 | bool player_position = false; | 59 | bool player_position = false; |
60 | bool changed_settings = false; | ||
60 | }; | 61 | }; |
61 | 62 | ||
62 | class StateChangedEvent : public wxEvent { | 63 | class StateChangedEvent : public wxEvent { |
diff --git a/src/tracker_panel.cpp b/src/tracker_panel.cpp index b4e6697..64e6ab3 100644 --- a/src/tracker_panel.cpp +++ b/src/tracker_panel.cpp | |||
@@ -50,13 +50,19 @@ TrackerPanel::TrackerPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY) { | |||
50 | Bind(wxEVT_MOTION, &TrackerPanel::OnMouseMove, this); | 50 | Bind(wxEVT_MOTION, &TrackerPanel::OnMouseMove, this); |
51 | } | 51 | } |
52 | 52 | ||
53 | void TrackerPanel::UpdateIndicators() { | 53 | void TrackerPanel::UpdateIndicators(bool reset) { |
54 | if (panels_mode_ && !savedata_path_) { | 54 | if (panels_mode_ && !savedata_path_) { |
55 | solved_panels_ = IPC_GetSolvedPanels(); | 55 | solved_panels_ = IPC_GetSolvedPanels(); |
56 | } | 56 | } |
57 | 57 | ||
58 | for (AreaIndicator &area : areas_) { | 58 | if (reset) { |
59 | area.popup->UpdateIndicators(); | 59 | for (AreaIndicator &area : areas_) { |
60 | area.popup->ResetIndicators(); | ||
61 | } | ||
62 | } else { | ||
63 | for (AreaIndicator &area : areas_) { | ||
64 | area.popup->UpdateIndicators(); | ||
65 | } | ||
60 | } | 66 | } |
61 | 67 | ||
62 | Redraw(); | 68 | Redraw(); |
@@ -74,6 +80,7 @@ void TrackerPanel::SetSavedataPath(std::string savedata_path) { | |||
74 | savedata_path_ = savedata_path; | 80 | savedata_path_ = savedata_path; |
75 | panels_mode_ = true; | 81 | panels_mode_ = true; |
76 | 82 | ||
83 | UpdateIndicators(/*reset=*/true); | ||
77 | RefreshSavedata(); | 84 | RefreshSavedata(); |
78 | } | 85 | } |
79 | 86 | ||
@@ -90,7 +97,7 @@ void TrackerPanel::RefreshSavedata() { | |||
90 | } | 97 | } |
91 | } | 98 | } |
92 | 99 | ||
93 | UpdateIndicators(); | 100 | UpdateIndicators(/*reset=*/false); |
94 | Refresh(); | 101 | Refresh(); |
95 | } | 102 | } |
96 | 103 | ||
diff --git a/src/tracker_panel.h b/src/tracker_panel.h index b7067f5..ae89a35 100644 --- a/src/tracker_panel.h +++ b/src/tracker_panel.h | |||
@@ -17,7 +17,7 @@ class TrackerPanel : public wxPanel { | |||
17 | public: | 17 | public: |
18 | TrackerPanel(wxWindow *parent); | 18 | TrackerPanel(wxWindow *parent); |
19 | 19 | ||
20 | void UpdateIndicators(); | 20 | void UpdateIndicators(bool reset); |
21 | 21 | ||
22 | void SetPanelsMode(); | 22 | void SetPanelsMode(); |
23 | 23 | ||