about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CMakeLists.txt1
-rw-r--r--ap_state.cpp37
-rw-r--r--ap_state.h17
-rw-r--r--area_popup.cpp48
-rw-r--r--area_popup.h7
-rw-r--r--area_window.cpp20
-rw-r--r--area_window.h2
-rw-r--r--assets/checked.pngbin0 -> 888 bytes
-rw-r--r--assets/unchecked.pngbin0 -> 5001 bytes
-rw-r--r--eye_indicator.cpp47
-rw-r--r--eye_indicator.h30
-rw-r--r--game_data.cpp11
-rw-r--r--game_data.h2
-rw-r--r--tracker_frame.cpp7
-rw-r--r--tracker_frame.h6
-rw-r--r--tracker_panel.cpp13
-rw-r--r--tracker_panel.h3
18 files changed, 220 insertions, 32 deletions
diff --git a/.gitignore b/.gitignore index 4a87eed..3fac228 100644 --- a/.gitignore +++ b/.gitignore
@@ -1,2 +1,3 @@
1build/ 1build/
2assets/LL1.yaml 2assets/LL1.yaml
3.DS_Store
diff --git a/CMakeLists.txt b/CMakeLists.txt index 89f3996..9c346a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -32,6 +32,7 @@ add_executable(lingo_ap_tracker
32 area_popup.cpp 32 area_popup.cpp
33 ap_state.cpp 33 ap_state.cpp
34 connection_dialog.cpp 34 connection_dialog.cpp
35 eye_indicator.cpp
35) 36)
36set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD 17) 37set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD 17)
37set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD_REQUIRED ON) 38set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD_REQUIRED ON)
diff --git a/ap_state.cpp b/ap_state.cpp index d85fde5..4d7ddb7 100644 --- a/ap_state.cpp +++ b/ap_state.cpp
@@ -8,6 +8,8 @@
8#include <list> 8#include <list>
9#include <thread> 9#include <thread>
10 10
11#include "game_data.h"
12
11constexpr int AP_MAJOR = 0; 13constexpr int AP_MAJOR = 0;
12constexpr int AP_MINOR = 4; 14constexpr int AP_MINOR = 4;
13constexpr int AP_REVISION = 0; 15constexpr int AP_REVISION = 0;
@@ -64,7 +66,7 @@ void APState::Connect(std::string server, std::string player,
64 std::cout << "Location: " << location_id << std::endl; 66 std::cout << "Location: " << location_id << std::endl;
65 } 67 }
66 68
67 tracker_frame_->Refresh(); 69 RefreshTracker();
68 }); 70 });
69 71
70 apclient_->set_slot_disconnected_handler([&]() { 72 apclient_->set_slot_disconnected_handler([&]() {
@@ -84,7 +86,7 @@ void APState::Connect(std::string server, std::string player,
84 std::cout << "Item: " << item.item << std::endl; 86 std::cout << "Item: " << item.item << std::endl;
85 } 87 }
86 88
87 tracker_frame_->Refresh(); 89 RefreshTracker();
88 }); 90 });
89 91
90 apclient_->set_slot_connected_handler([&](const nlohmann::json& slot_data) { 92 apclient_->set_slot_connected_handler([&](const nlohmann::json& slot_data) {
@@ -151,11 +153,40 @@ void APState::Connect(std::string server, std::string player,
151 interval--; 153 interval--;
152 } 154 }
153 155
154 if (!connected) { 156 if (connected) {
157 for (const MapArea& map_area : GetGameData().GetMapAreas()) {
158 for (int section_id = 0; section_id < map_area.locations.size();
159 section_id++) {
160 const Location& location = map_area.locations.at(section_id);
161
162 int64_t ap_id = apclient_->get_location_id(location.ap_location_name);
163 if (ap_id == APClient::INVALID_NAME_ID) {
164 std::cout << "Could not find AP location ID for "
165 << location.ap_location_name << std::endl;
166 } else {
167 ap_id_by_location_id_[{map_area.id, section_id}] = ap_id;
168 }
169 }
170 }
171
172 RefreshTracker();
173 } else {
155 client_active_ = false; 174 client_active_ = false;
156 } 175 }
157} 176}
158 177
178bool APState::HasCheckedGameLocation(int area_id, int section_id) const {
179 std::tuple<int, int> location_key = {area_id, section_id};
180
181 if (ap_id_by_location_id_.count(location_key)) {
182 return checked_locations_.count(ap_id_by_location_id_.at(location_key));
183 } else {
184 return false;
185 }
186}
187
188void APState::RefreshTracker() { tracker_frame_->UpdateIndicators(); }
189
159APState& GetAPState() { 190APState& GetAPState() {
160 static APState* instance = new APState(); 191 static APState* instance = new APState();
161 return *instance; 192 return *instance;
diff --git a/ap_state.h b/ap_state.h index 5f9e952..b5a94e3 100644 --- a/ap_state.h +++ b/ap_state.h
@@ -6,6 +6,7 @@
6#include <mutex> 6#include <mutex>
7#include <set> 7#include <set>
8#include <string> 8#include <string>
9#include <tuple>
9 10
10#include "game_data.h" 11#include "game_data.h"
11#include "tracker_frame.h" 12#include "tracker_frame.h"
@@ -20,20 +21,24 @@ class APState {
20 21
21 void Connect(std::string server, std::string player, std::string password); 22 void Connect(std::string server, std::string player, std::string password);
22 23
24 bool HasCheckedGameLocation(int area_id, int section_id) const;
25
23 private: 26 private:
27 void RefreshTracker();
28
24 TrackerFrame* tracker_frame_; 29 TrackerFrame* tracker_frame_;
25 30
26 std::unique_ptr<APClient> apclient_; 31 std::unique_ptr<APClient> apclient_;
27 bool client_active_ = false; 32 bool client_active_ = false;
28 std::mutex client_mutex_; 33 std::mutex client_mutex_;
29 34
30 std::set<int> inventory_; 35 std::set<int64_t> inventory_;
31 std::set<int> checked_locations_; 36 std::set<int64_t> checked_locations_;
32 37
33 std::map<int, int> ap_id_by_location_id_; 38 std::map<std::tuple<int, int>, int64_t> ap_id_by_location_id_;
34 std::map<int, int> ap_id_by_door_id_; 39 std::map<int, int64_t> ap_id_by_door_id_;
35 std::map<int, int> ap_id_by_door_group_id_; 40 std::map<int, int64_t> ap_id_by_door_group_id_;
36 std::map<LingoColor, int> ap_id_by_color_; 41 std::map<LingoColor, int64_t> ap_id_by_color_;
37}; 42};
38 43
39APState& GetAPState(); 44APState& GetAPState();
diff --git a/area_popup.cpp b/area_popup.cpp index 62cbe4d..e46e4ec 100644 --- a/area_popup.cpp +++ b/area_popup.cpp
@@ -1,37 +1,51 @@
1#include "area_popup.h" 1#include "area_popup.h"
2 2
3#include "ap_state.h"
3#include "game_data.h" 4#include "game_data.h"
4 5
5AreaPopup::AreaPopup(wxWindow* parent, int area_id) 6AreaPopup::AreaPopup(wxWindow* parent, int area_id)
6 : wxPanel(parent, wxID_ANY), area_id_(area_id) { 7 : wxPanel(parent, wxID_ANY), area_id_(area_id) {
7 const MapArea& map_area = GetGameData().GetMapArea(area_id); 8 const MapArea& map_area = GetGameData().GetMapArea(area_id);
8 9
9 wxBoxSizer* list_sizer = new wxBoxSizer(wxVERTICAL); 10 wxFlexGridSizer* section_sizer = new wxFlexGridSizer(2, 10, 10);
10 11
11 wxStaticText* top_label = new wxStaticText(this, -1, map_area.name);
12 top_label->SetForegroundColour(*wxBLACK);
13 top_label->SetFont(top_label->GetFont().Bold());
14 list_sizer->Add(top_label, wxSizerFlags().Center().DoubleBorder(wxDOWN));
15
16 bool is_first = true;
17 for (const Location& location : map_area.locations) { 12 for (const Location& location : map_area.locations) {
18 wxSizerFlags sizer_flags = wxSizerFlags().Left(); 13 EyeIndicator* eye_indicator = new EyeIndicator(this);
19 if (!is_first) { 14 section_sizer->Add(eye_indicator, wxSizerFlags().Expand());
20 sizer_flags = sizer_flags.Border(wxUP); 15 eye_indicators_.push_back(eye_indicator);
21 }
22 16
23 wxStaticText* section_label = new wxStaticText(this, -1, location.name); 17 wxStaticText* section_label = new wxStaticText(this, -1, location.name);
24 section_label->SetForegroundColour(*wxBLACK); 18 section_label->SetForegroundColour(*wxWHITE);
25 list_sizer->Add(section_label, sizer_flags); 19 section_sizer->Add(
26 20 section_label,
27 is_first = false; 21 wxSizerFlags().Align(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL));
22 section_labels_.push_back(section_label);
28 } 23 }
29 24
30 wxBoxSizer* top_sizer = new wxBoxSizer(wxVERTICAL); 25 wxBoxSizer* top_sizer = new wxBoxSizer(wxVERTICAL);
31 top_sizer->Add(list_sizer, wxSizerFlags().DoubleBorder(wxALL)); 26
27 wxStaticText* top_label = new wxStaticText(this, -1, map_area.name);
28 top_label->SetForegroundColour(*wxWHITE);
29 top_label->SetFont(top_label->GetFont().Bold());
30 top_sizer->Add(top_label,
31 wxSizerFlags().Center().DoubleBorder(wxUP | wxLEFT | wxRIGHT));
32
33 top_sizer->Add(section_sizer, wxSizerFlags().DoubleBorder(wxALL).Expand());
32 34
33 SetSizerAndFit(top_sizer); 35 SetSizerAndFit(top_sizer);
34 36
35 SetBackgroundColour(*wxLIGHT_GREY); 37 SetBackgroundColour(*wxBLACK);
36 Hide(); 38 Hide();
37} 39}
40
41void AreaPopup::UpdateIndicators() {
42 const MapArea& map_area = GetGameData().GetMapArea(area_id_);
43 for (int section_id = 0; section_id < map_area.locations.size();
44 section_id++) {
45 bool checked = GetAPState().HasCheckedGameLocation(area_id_, section_id);
46 const wxColour* text_color = checked ? wxWHITE : wxGREEN;
47
48 section_labels_[section_id]->SetForegroundColour(*text_color);
49 eye_indicators_[section_id]->SetChecked(checked);
50 }
51}
diff --git a/area_popup.h b/area_popup.h index c3de4bb..b602b63 100644 --- a/area_popup.h +++ b/area_popup.h
@@ -7,12 +7,19 @@
7#include <wx/wx.h> 7#include <wx/wx.h>
8#endif 8#endif
9 9
10#include "eye_indicator.h"
11
10class AreaPopup : public wxPanel { 12class AreaPopup : public wxPanel {
11 public: 13 public:
12 AreaPopup(wxWindow* parent, int area_id); 14 AreaPopup(wxWindow* parent, int area_id);
13 15
16 void UpdateIndicators();
17
14 private: 18 private:
15 int area_id_; 19 int area_id_;
20
21 std::vector<wxStaticText*> section_labels_;
22 std::vector<EyeIndicator*> eye_indicators_;
16}; 23};
17 24
18#endif /* end of include guard: AREA_POPUP_H_03FAC988 */ 25#endif /* end of include guard: AREA_POPUP_H_03FAC988 */
diff --git a/area_window.cpp b/area_window.cpp index 2f334e4..ca327b8 100644 --- a/area_window.cpp +++ b/area_window.cpp
@@ -2,6 +2,7 @@
2 2
3#include <iostream> 3#include <iostream>
4 4
5#include "ap_state.h"
5#include "game_data.h" 6#include "game_data.h"
6 7
7AreaWindow::AreaWindow(wxWindow* parent, int area_id, AreaPopup* popup) 8AreaWindow::AreaWindow(wxWindow* parent, int area_id, AreaPopup* popup)
@@ -15,6 +16,8 @@ AreaWindow::AreaWindow(wxWindow* parent, int area_id, AreaPopup* popup)
15 Bind(wxEVT_LEAVE_WINDOW, &AreaWindow::OnLeaveWindow, this); 16 Bind(wxEVT_LEAVE_WINDOW, &AreaWindow::OnLeaveWindow, this);
16} 17}
17 18
19void AreaWindow::UpdateIndicators() { Redraw(); }
20
18void AreaWindow::OnPaint(wxPaintEvent& event) { 21void AreaWindow::OnPaint(wxPaintEvent& event) {
19 if (GetSize() != rendered_.GetSize()) { 22 if (GetSize() != rendered_.GetSize()) {
20 Redraw(); 23 Redraw();
@@ -29,12 +32,27 @@ void AreaWindow::OnEnterWindow(wxMouseEvent& event) { popup_->Show(); }
29void AreaWindow::OnLeaveWindow(wxMouseEvent& event) { popup_->Hide(); } 32void AreaWindow::OnLeaveWindow(wxMouseEvent& event) { popup_->Hide(); }
30 33
31void AreaWindow::Redraw() { 34void AreaWindow::Redraw() {
35 const wxBrush* brush_color = wxGREY_BRUSH;
36
37 const MapArea& map_area = GetGameData().GetMapArea(area_id_);
38 int unchecked_sections = 0;
39 for (int section_id = 0; section_id < map_area.locations.size();
40 section_id++) {
41 if (!GetAPState().HasCheckedGameLocation(area_id_, section_id)) {
42 unchecked_sections++;
43 }
44 }
45
46 if (unchecked_sections > 0) {
47 brush_color = wxGREEN_BRUSH;
48 }
49
32 int actual_border_size = GetSize().GetWidth() * BORDER_SIZE / EFFECTIVE_SIZE; 50 int actual_border_size = GetSize().GetWidth() * BORDER_SIZE / EFFECTIVE_SIZE;
33 51
34 rendered_ = wxBitmap(GetSize()); 52 rendered_ = wxBitmap(GetSize());
35 wxMemoryDC dc; 53 wxMemoryDC dc;
36 dc.SelectObject(rendered_); 54 dc.SelectObject(rendered_);
37 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, actual_border_size)); 55 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, actual_border_size));
38 dc.SetBrush(*wxGREEN_BRUSH); 56 dc.SetBrush(*brush_color);
39 dc.DrawRectangle({0, 0}, GetSize()); 57 dc.DrawRectangle({0, 0}, GetSize());
40} 58}
diff --git a/area_window.h b/area_window.h index c9abc4c..3e7c001 100644 --- a/area_window.h +++ b/area_window.h
@@ -21,6 +21,8 @@ class AreaWindow : public wxWindow {
21 21
22 AreaPopup* GetPopup() { return popup_; } 22 AreaPopup* GetPopup() { return popup_; }
23 23
24 void UpdateIndicators();
25
24 private: 26 private:
25 void OnPaint(wxPaintEvent& event); 27 void OnPaint(wxPaintEvent& event);
26 void OnEnterWindow(wxMouseEvent& event); 28 void OnEnterWindow(wxMouseEvent& event);
diff --git a/assets/checked.png b/assets/checked.png new file mode 100644 index 0000000..ad3028c --- /dev/null +++ b/assets/checked.png
Binary files differ
diff --git a/assets/unchecked.png b/assets/unchecked.png new file mode 100644 index 0000000..4ff77a3 --- /dev/null +++ b/assets/unchecked.png
Binary files differ
diff --git a/eye_indicator.cpp b/eye_indicator.cpp new file mode 100644 index 0000000..c490589 --- /dev/null +++ b/eye_indicator.cpp
@@ -0,0 +1,47 @@
1#include "eye_indicator.h"
2
3EyeIndicator::EyeIndicator(wxWindow* parent) : wxWindow(parent, wxID_ANY) {
4 SetMinSize({32, 32});
5
6 Redraw();
7
8 Bind(wxEVT_PAINT, &EyeIndicator::OnPaint, this);
9}
10
11void EyeIndicator::SetChecked(bool checked) {
12 if (intended_checked_ != checked) {
13 intended_checked_ = checked;
14
15 Redraw();
16 }
17}
18
19const wxImage& EyeIndicator::GetUncheckedImage() {
20 static wxImage* unchecked_image =
21 new wxImage("assets/unchecked.png", wxBITMAP_TYPE_PNG);
22 return *unchecked_image;
23}
24
25const wxImage& EyeIndicator::GetCheckedImage() {
26 static wxImage* checked_image =
27 new wxImage("assets/checked.png", wxBITMAP_TYPE_PNG);
28 return *checked_image;
29}
30
31void EyeIndicator::OnPaint(wxPaintEvent& event) {
32 if (GetSize() != rendered_.GetSize() ||
33 intended_checked_ != rendered_checked_) {
34 Redraw();
35 }
36
37 wxPaintDC dc(this);
38 dc.DrawBitmap(rendered_, 0, 0);
39}
40
41void EyeIndicator::Redraw() {
42 rendered_ =
43 wxBitmap((intended_checked_ ? GetCheckedImage() : GetUncheckedImage())
44 .Scale(GetSize().GetWidth(), GetSize().GetHeight(),
45 wxIMAGE_QUALITY_NORMAL));
46 rendered_checked_ = intended_checked_;
47}
diff --git a/eye_indicator.h b/eye_indicator.h new file mode 100644 index 0000000..e8fd890 --- /dev/null +++ b/eye_indicator.h
@@ -0,0 +1,30 @@
1#ifndef EYE_INDICATOR_H_778150F2
2#define EYE_INDICATOR_H_778150F2
3
4#include <wx/wxprec.h>
5
6#ifndef WX_PRECOMP
7#include <wx/wx.h>
8#endif
9
10class EyeIndicator : public wxWindow {
11 public:
12 EyeIndicator(wxWindow* parent);
13
14 void SetChecked(bool checked);
15
16 private:
17 static const wxImage& GetUncheckedImage();
18 static const wxImage& GetCheckedImage();
19
20 void OnPaint(wxPaintEvent& event);
21
22 void Redraw();
23
24 bool intended_checked_ = false;
25
26 wxBitmap rendered_;
27 bool rendered_checked_ = false;
28};
29
30#endif /* end of include guard: EYE_INDICATOR_H_778150F2 */
diff --git a/game_data.cpp b/game_data.cpp index 54a01ed..af5f665 100644 --- a/game_data.cpp +++ b/game_data.cpp
@@ -252,7 +252,10 @@ GameData::GameData() {
252 MapArea &map_area = map_areas_[area_id]; 252 MapArea &map_area = map_areas_[area_id];
253 // room field should be the original room ID 253 // room field should be the original room ID
254 map_area.locations.push_back( 254 map_area.locations.push_back(
255 {.name = panel.name, .room = panel.room, .panels = {panel.id}}); 255 {.name = panel.name,
256 .ap_location_name = room_name + " - " + panel.name,
257 .room = panel.room,
258 .panels = {panel.id}});
256 } 259 }
257 } 260 }
258 261
@@ -278,8 +281,10 @@ GameData::GameData() {
278 int area_id = AddOrGetArea(area_name); 281 int area_id = AddOrGetArea(area_name);
279 MapArea &map_area = map_areas_[area_id]; 282 MapArea &map_area = map_areas_[area_id];
280 // room field should be the original room ID 283 // room field should be the original room ID
281 map_area.locations.push_back( 284 map_area.locations.push_back({.name = section_name,
282 {.name = section_name, .room = door.room, .panels = door.panels}); 285 .ap_location_name = door.location_name,
286 .room = door.room,
287 .panels = door.panels});
283 } 288 }
284 } 289 }
285} 290}
diff --git a/game_data.h b/game_data.h index 00d6328..4f93d92 100644 --- a/game_data.h +++ b/game_data.h
@@ -52,7 +52,7 @@ struct Room {
52 52
53struct Location { 53struct Location {
54 std::string name; 54 std::string name;
55 int location_id = -1; 55 std::string ap_location_name;
56 int room; 56 int room;
57 std::vector<int> panels; 57 std::vector<int> panels;
58}; 58};
diff --git a/tracker_frame.cpp b/tracker_frame.cpp index d58dfe8..cd2060c 100644 --- a/tracker_frame.cpp +++ b/tracker_frame.cpp
@@ -34,13 +34,18 @@ TrackerFrame::TrackerFrame()
34 Bind(wxEVT_MENU, &TrackerFrame::OnExit, this, wxID_EXIT); 34 Bind(wxEVT_MENU, &TrackerFrame::OnExit, this, wxID_EXIT);
35 Bind(wxEVT_MENU, &TrackerFrame::OnConnect, this, ID_CONNECT); 35 Bind(wxEVT_MENU, &TrackerFrame::OnConnect, this, ID_CONNECT);
36 36
37 new TrackerPanel(this); 37 tracker_panel_ = new TrackerPanel(this);
38} 38}
39 39
40void TrackerFrame::SetStatusMessage(std::string message) { 40void TrackerFrame::SetStatusMessage(std::string message) {
41 SetStatusText(message); 41 SetStatusText(message);
42} 42}
43 43
44void TrackerFrame::UpdateIndicators() {
45 tracker_panel_->UpdateIndicators();
46 Refresh();
47}
48
44void TrackerFrame::OnAbout(wxCommandEvent &event) { 49void TrackerFrame::OnAbout(wxCommandEvent &event) {
45 wxMessageBox("Lingo Archipelago Tracker by hatkirby", 50 wxMessageBox("Lingo Archipelago Tracker by hatkirby",
46 "About lingo-ap-tracker", wxOK | wxICON_INFORMATION); 51 "About lingo-ap-tracker", wxOK | wxICON_INFORMATION);
diff --git a/tracker_frame.h b/tracker_frame.h index 10dfc9d..082c12c 100644 --- a/tracker_frame.h +++ b/tracker_frame.h
@@ -7,16 +7,22 @@
7#include <wx/wx.h> 7#include <wx/wx.h>
8#endif 8#endif
9 9
10class TrackerPanel;
11
10class TrackerFrame : public wxFrame { 12class TrackerFrame : public wxFrame {
11 public: 13 public:
12 TrackerFrame(); 14 TrackerFrame();
13 15
14 void SetStatusMessage(std::string message); 16 void SetStatusMessage(std::string message);
15 17
18 void UpdateIndicators();
19
16 private: 20 private:
17 void OnExit(wxCommandEvent &event); 21 void OnExit(wxCommandEvent &event);
18 void OnAbout(wxCommandEvent &event); 22 void OnAbout(wxCommandEvent &event);
19 void OnConnect(wxCommandEvent &event); 23 void OnConnect(wxCommandEvent &event);
24
25 TrackerPanel *tracker_panel_;
20}; 26};
21 27
22#endif /* end of include guard: TRACKER_FRAME_H_86BD8DFB */ 28#endif /* end of include guard: TRACKER_FRAME_H_86BD8DFB */
diff --git a/tracker_panel.cpp b/tracker_panel.cpp index 0e78cc5..1aa7dcf 100644 --- a/tracker_panel.cpp +++ b/tracker_panel.cpp
@@ -13,6 +13,7 @@ TrackerPanel::TrackerPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY) {
13 AreaPopup *area_popup = new AreaPopup(this, map_area.id); 13 AreaPopup *area_popup = new AreaPopup(this, map_area.id);
14 area_popup->SetPosition({0, 0}); 14 area_popup->SetPosition({0, 0});
15 area_popup->Raise(); 15 area_popup->Raise();
16 area_popups_.push_back(area_popup);
16 17
17 AreaWindow *area_window = new AreaWindow(this, map_area.id, area_popup); 18 AreaWindow *area_window = new AreaWindow(this, map_area.id, area_popup);
18 area_window->Lower(); 19 area_window->Lower();
@@ -24,6 +25,18 @@ TrackerPanel::TrackerPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY) {
24 Bind(wxEVT_PAINT, &TrackerPanel::OnPaint, this); 25 Bind(wxEVT_PAINT, &TrackerPanel::OnPaint, this);
25} 26}
26 27
28void TrackerPanel::UpdateIndicators() {
29 Redraw();
30
31 for (AreaWindow *area_window : area_windows_) {
32 area_window->UpdateIndicators();
33 }
34
35 for (AreaPopup *area_popup : area_popups_) {
36 area_popup->UpdateIndicators();
37 }
38}
39
27void TrackerPanel::OnPaint(wxPaintEvent &event) { 40void TrackerPanel::OnPaint(wxPaintEvent &event) {
28 if (GetSize() != rendered_.GetSize()) { 41 if (GetSize() != rendered_.GetSize()) {
29 Redraw(); 42 Redraw();
diff --git a/tracker_panel.h b/tracker_panel.h index ae15271..20d4f92 100644 --- a/tracker_panel.h +++ b/tracker_panel.h
@@ -13,6 +13,8 @@ class TrackerPanel : public wxPanel {
13 public: 13 public:
14 TrackerPanel(wxWindow *parent); 14 TrackerPanel(wxWindow *parent);
15 15
16 void UpdateIndicators();
17
16 private: 18 private:
17 void OnPaint(wxPaintEvent &event); 19 void OnPaint(wxPaintEvent &event);
18 20
@@ -22,6 +24,7 @@ class TrackerPanel : public wxPanel {
22 wxBitmap rendered_; 24 wxBitmap rendered_;
23 25
24 std::vector<AreaWindow *> area_windows_; 26 std::vector<AreaWindow *> area_windows_;
27 std::vector<AreaPopup *> area_popups_;
25}; 28};
26 29
27#endif /* end of include guard: TRACKER_PANEL_H_D675A54D */ 30#endif /* end of include guard: TRACKER_PANEL_H_D675A54D */