From 02c331f4e766558bba580d5b7db883357be005d5 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Wed, 3 May 2023 12:43:16 -0400 Subject: Changes to make it work better on Windows AreaWindows are now no longer separate controls but are instead just painted onto the TrackerPanel. This lets us avoid the complexity of z-ordering with sibling controls. We can also use the mouse motion event to display and hide the popups, which conveniently doesn't fire when the mouse is over a popup, so the popup won't hide until you mouse off of the window AND popup. --- tracker_panel.cpp | 117 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 85 insertions(+), 32 deletions(-) (limited to 'tracker_panel.cpp') diff --git a/tracker_panel.cpp b/tracker_panel.cpp index 1aa7dcf..73cac41 100644 --- a/tracker_panel.cpp +++ b/tracker_panel.cpp @@ -1,7 +1,13 @@ #include "tracker_panel.h" +#include "ap_state.h" #include "area_popup.h" #include "game_data.h" +#include "tracker_state.h" + +constexpr int AREA_ACTUAL_SIZE = 64; +constexpr int AREA_BORDER_SIZE = 5; +constexpr int AREA_EFFECTIVE_SIZE = AREA_ACTUAL_SIZE + AREA_BORDER_SIZE * 2; TrackerPanel::TrackerPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY) { map_image_ = wxImage("assets/lingo_map.png", wxBITMAP_TYPE_PNG); @@ -10,30 +16,26 @@ TrackerPanel::TrackerPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY) { } for (const MapArea &map_area : GetGameData().GetMapAreas()) { - AreaPopup *area_popup = new AreaPopup(this, map_area.id); - area_popup->SetPosition({0, 0}); - area_popup->Raise(); - area_popups_.push_back(area_popup); - - AreaWindow *area_window = new AreaWindow(this, map_area.id, area_popup); - area_window->Lower(); - area_windows_.push_back(area_window); + AreaIndicator area; + area.area_id = map_area.id; + + area.popup = new AreaPopup(this, map_area.id); + area.popup->SetPosition({0, 0}); + + areas_.push_back(area); } Redraw(); Bind(wxEVT_PAINT, &TrackerPanel::OnPaint, this); + Bind(wxEVT_MOTION, &TrackerPanel::OnMouseMove, this); } void TrackerPanel::UpdateIndicators() { Redraw(); - for (AreaWindow *area_window : area_windows_) { - area_window->UpdateIndicators(); - } - - for (AreaPopup *area_popup : area_popups_) { - area_popup->UpdateIndicators(); + for (AreaIndicator& area : areas_) { + area.popup->UpdateIndicators(); } } @@ -44,6 +46,21 @@ void TrackerPanel::OnPaint(wxPaintEvent &event) { wxPaintDC dc(this); dc.DrawBitmap(rendered_, 0, 0); + + event.Skip(); +} + +void TrackerPanel::OnMouseMove(wxMouseEvent &event) { + for (AreaIndicator &area : areas_) { + if (area.real_x1 <= event.GetX() && event.GetX() < area.real_x2 && + area.real_y1 <= event.GetY() && event.GetY() < area.real_y2) { + area.popup->Show(); + } else { + area.popup->Hide(); + } + } + + event.Skip(); } void TrackerPanel::Redraw() { @@ -70,30 +87,66 @@ void TrackerPanel::Redraw() { map_image_.Scale(final_width, final_height, wxIMAGE_QUALITY_NORMAL) .Size(panel_size, {final_x, final_y}, 0, 0, 0)); - for (AreaWindow *area_window : area_windows_) { - const MapArea &map_area = - GetGameData().GetMapArea(area_window->GetAreaId()); + wxMemoryDC dc; + dc.SelectObject(rendered_); + + for (AreaIndicator& area : areas_) { + const wxBrush *brush_color = wxGREY_BRUSH; + + const MapArea &map_area = GetGameData().GetMapArea(area.area_id); + bool has_reachable_unchecked = false; + bool has_unreachable_unchecked = false; + for (int section_id = 0; section_id < map_area.locations.size(); + section_id++) { + if (!GetAPState().HasCheckedGameLocation(area.area_id, + section_id)) { + if (GetTrackerState().IsLocationReachable(area.area_id, + section_id)) { + has_reachable_unchecked = true; + } else { + has_unreachable_unchecked = true; + } + } + } + + if (has_reachable_unchecked && has_unreachable_unchecked) { + brush_color = wxYELLOW_BRUSH; + } else if (has_reachable_unchecked) { + brush_color = wxGREEN_BRUSH; + } else if (has_unreachable_unchecked) { + brush_color = wxRED_BRUSH; + } + int real_area_size = - final_width * AreaWindow::EFFECTIVE_SIZE / image_size.GetWidth(); - area_window->SetSize({real_area_size, real_area_size}); - area_window->SetPosition({ - final_x + (map_area.map_x - (AreaWindow::EFFECTIVE_SIZE / 2)) * - final_width / image_size.GetWidth(), - final_y + (map_area.map_y - (AreaWindow::EFFECTIVE_SIZE / 2)) * - final_width / image_size.GetWidth(), - }); - - AreaPopup *area_popup = area_window->GetPopup(); + final_width * AREA_EFFECTIVE_SIZE / image_size.GetWidth(); + int actual_border_size = + real_area_size * AREA_BORDER_SIZE / AREA_EFFECTIVE_SIZE; + 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(); + + 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}); + + 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(); - if (popup_x + area_popup->GetSize().GetWidth() > panel_size.GetWidth()) { - popup_x = panel_size.GetWidth() - area_popup->GetSize().GetWidth(); + 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(); + 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}); + area.popup->SetPosition({popup_x, popup_y}); } } -- cgit 1.4.1