From ba59d40760e2a5a11bfbe2f7cf6b0e2a71b590d7 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Fri, 7 Mar 2025 14:33:11 -0500 Subject: Better high-DPI handling for rest of app --- src/area_popup.cpp | 68 ++++++++++++++++++++++++++++++----------------- src/area_popup.h | 3 +++ src/connection_dialog.cpp | 9 ++++--- src/ipc_dialog.cpp | 5 ++-- src/report_popup.cpp | 52 ++++++++++++++++++++++++------------ src/report_popup.h | 3 +++ src/subway_map.cpp | 7 ++++- src/tracker_panel.cpp | 15 ++++++++--- src/tracker_panel.h | 4 +++ 9 files changed, 114 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/area_popup.cpp b/src/area_popup.cpp index 467a2bc..aabf20b 100644 --- a/src/area_popup.cpp +++ b/src/area_popup.cpp @@ -15,20 +15,16 @@ AreaPopup::AreaPopup(wxWindow* parent, int area_id) : wxScrolledCanvas(parent, wxID_ANY), area_id_(area_id) { SetBackgroundStyle(wxBG_STYLE_PAINT); - 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)); + LoadIcons(); + // TODO: This is slow on high-DPI screens. SetScrollRate(5, 5); SetBackgroundColour(*wxBLACK); Hide(); Bind(wxEVT_PAINT, &AreaPopup::OnPaint, this); + Bind(wxEVT_DPI_CHANGED, &AreaPopup::OnDPIChanged, this); UpdateIndicators(); } @@ -36,15 +32,17 @@ AreaPopup::AreaPopup(wxWindow* parent, int area_id) void AreaPopup::UpdateIndicators() { const MapArea& map_area = GD_GetMapArea(area_id_); + wxFont the_font = GetFont().Scale(GetDPIScaleFactor()); + // Start calculating extents. wxMemoryDC mem_dc; - mem_dc.SetFont(GetFont().Bold()); + mem_dc.SetFont(the_font.Bold()); wxSize header_extent = mem_dc.GetTextExtent(map_area.name); - int acc_height = header_extent.GetHeight() + 20; + int acc_height = header_extent.GetHeight() + FromDIP(20); int col_width = 0; - mem_dc.SetFont(GetFont()); + mem_dc.SetFont(the_font); TrackerPanel* tracker_panel = dynamic_cast(GetParent()); @@ -68,7 +66,8 @@ void AreaPopup::UpdateIndicators() { real_locations.push_back(section_id); wxSize item_extent = mem_dc.GetTextExtent(location.name); - int item_height = std::max(32, item_extent.GetHeight()) + 10; + int item_height = + std::max(FromDIP(32), item_extent.GetHeight()) + FromDIP(10); acc_height += item_height; if (item_extent.GetWidth() > col_width) { @@ -80,7 +79,8 @@ void AreaPopup::UpdateIndicators() { for (int painting_id : map_area.paintings) { const PaintingExit& painting = GD_GetPaintingExit(painting_id); wxSize item_extent = mem_dc.GetTextExtent(painting.display_name); - int item_height = std::max(32, item_extent.GetHeight()) + 10; + int item_height = + std::max(FromDIP(32), item_extent.GetHeight()) + FromDIP(10); acc_height += item_height; if (item_extent.GetWidth() > col_width) { @@ -89,8 +89,8 @@ void AreaPopup::UpdateIndicators() { } } - int item_width = col_width + 10 + 32; - int full_width = std::max(header_extent.GetWidth(), item_width) + 20; + int item_width = col_width + FromDIP(10 + 32); + int full_width = std::max(header_extent.GetWidth(), item_width) + FromDIP(20); Fit(); SetVirtualSize(full_width, acc_height); @@ -101,14 +101,14 @@ void AreaPopup::UpdateIndicators() { mem_dc.SetBrush(*wxBLACK_BRUSH); mem_dc.DrawRectangle({0, 0}, {full_width, acc_height}); - mem_dc.SetFont(GetFont().Bold()); + mem_dc.SetFont(the_font.Bold()); mem_dc.SetTextForeground(*wxWHITE); mem_dc.DrawText(map_area.name, - {(full_width - header_extent.GetWidth()) / 2, 10}); + {(full_width - header_extent.GetWidth()) / 2, FromDIP(10)}); - int cur_height = header_extent.GetHeight() + 20; + int cur_height = header_extent.GetHeight() + FromDIP(20); - mem_dc.SetFont(GetFont()); + mem_dc.SetFont(the_font); for (int section_id : real_locations) { const Location& location = map_area.locations.at(section_id); @@ -131,7 +131,7 @@ void AreaPopup::UpdateIndicators() { wxBitmap* eye_ptr = checked ? &checked_eye_ : &unchecked_eye_; - mem_dc.DrawBitmap(*eye_ptr, {10, cur_height}); + mem_dc.DrawBitmap(*eye_ptr, {FromDIP(10), cur_height}); bool reachable = IsLocationReachable(location.ap_location_id); const wxColour* text_color = reachable ? wxWHITE : wxRED; @@ -140,9 +140,10 @@ void AreaPopup::UpdateIndicators() { wxSize item_extent = mem_dc.GetTextExtent(location.name); mem_dc.DrawText( location.name, - {10 + 32 + 10, cur_height + (32 - mem_dc.GetFontMetrics().height) / 2}); + {FromDIP(10 + 32 + 10), + cur_height + (FromDIP(32) - mem_dc.GetFontMetrics().height) / 2}); - cur_height += 10 + 32; + cur_height += FromDIP(10 + 32); } if (AP_IsPaintingShuffle() && !tracker_panel->IsPanelsMode()) { @@ -155,14 +156,14 @@ void AreaPopup::UpdateIndicators() { bool checked = reachable && AP_IsPaintingChecked(painting.internal_id); wxBitmap* eye_ptr = checked ? &checked_eye_ : &unchecked_eye_; - mem_dc.DrawBitmap(*eye_ptr, {10, cur_height}); + mem_dc.DrawBitmap(*eye_ptr, {FromDIP(10), cur_height}); wxSize item_extent = mem_dc.GetTextExtent(painting.display_name); mem_dc.DrawText(painting.display_name, - {10 + 32 + 10, - cur_height + (32 - mem_dc.GetFontMetrics().height) / 2}); + {FromDIP(10 + 32 + 10), + cur_height + (FromDIP(32) - mem_dc.GetFontMetrics().height) / 2}); - cur_height += 10 + 32; + cur_height += FromDIP(10 + 32); } } } @@ -174,3 +175,20 @@ void AreaPopup::OnPaint(wxPaintEvent& event) { event.Skip(); } + +void AreaPopup::OnDPIChanged(wxDPIChangedEvent& event) { + LoadIcons(); + UpdateIndicators(); +} + +void AreaPopup::LoadIcons() { + // TODO: We do not have to read these in and scale them for every single + // popup. + unchecked_eye_ = + wxBitmap(wxImage(GetAbsolutePath("assets/unchecked.png").c_str(), + wxBITMAP_TYPE_PNG) + .Scale(FromDIP(32), FromDIP(32))); + checked_eye_ = wxBitmap( + wxImage(GetAbsolutePath("assets/checked.png").c_str(), wxBITMAP_TYPE_PNG) + .Scale(FromDIP(32), FromDIP(32))); +} diff --git a/src/area_popup.h b/src/area_popup.h index 00c644d..3326406 100644 --- a/src/area_popup.h +++ b/src/area_popup.h @@ -15,6 +15,9 @@ class AreaPopup : public wxScrolledCanvas { private: void OnPaint(wxPaintEvent& event); + void OnDPIChanged(wxDPIChangedEvent& event); + + void LoadIcons(); int area_id_; diff --git a/src/connection_dialog.cpp b/src/connection_dialog.cpp index 45a5b53..b55a138 100644 --- a/src/connection_dialog.cpp +++ b/src/connection_dialog.cpp @@ -7,17 +7,18 @@ ConnectionDialog::ConnectionDialog() server_box_ = new wxTextCtrl( this, -1, wxString::FromUTF8(GetTrackerConfig().connection_details.ap_server), - wxDefaultPosition, {300, -1}); + wxDefaultPosition, FromDIP(wxSize{300, -1})); player_box_ = new wxTextCtrl( this, -1, wxString::FromUTF8(GetTrackerConfig().connection_details.ap_player), - wxDefaultPosition, {300, -1}); + wxDefaultPosition, FromDIP(wxSize{300, -1})); password_box_ = new wxTextCtrl( this, -1, wxString::FromUTF8(GetTrackerConfig().connection_details.ap_password), - wxDefaultPosition, {300, -1}); + wxDefaultPosition, FromDIP(wxSize{300, -1})); - wxFlexGridSizer* form_sizer = new wxFlexGridSizer(2, 10, 10); + wxFlexGridSizer* form_sizer = + new wxFlexGridSizer(2, FromDIP(10), FromDIP(10)); form_sizer->Add( new wxStaticText(this, -1, "Server:"), diff --git a/src/ipc_dialog.cpp b/src/ipc_dialog.cpp index 1e09a2f..6763b7f 100644 --- a/src/ipc_dialog.cpp +++ b/src/ipc_dialog.cpp @@ -13,12 +13,13 @@ IpcDialog::IpcDialog() : wxDialog(nullptr, wxID_ANY, "Connect to game") { } address_box_ = new wxTextCtrl(this, -1, wxString::FromUTF8(address_value), - wxDefaultPosition, {300, -1}); + wxDefaultPosition, FromDIP(wxSize{300, -1})); wxButton* reset_button = new wxButton(this, -1, "Use Default"); reset_button->Bind(wxEVT_BUTTON, &IpcDialog::OnResetClicked, this); - wxFlexGridSizer* form_sizer = new wxFlexGridSizer(3, 10, 10); + wxFlexGridSizer* form_sizer = + new wxFlexGridSizer(3, FromDIP(10), FromDIP(10)); form_sizer->Add( new wxStaticText(this, -1, "Address:"), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT)); diff --git a/src/report_popup.cpp b/src/report_popup.cpp index d772b32..74216c3 100644 --- a/src/report_popup.cpp +++ b/src/report_popup.cpp @@ -12,20 +12,16 @@ ReportPopup::ReportPopup(wxWindow* parent) : wxScrolledCanvas(parent, wxID_ANY) { SetBackgroundStyle(wxBG_STYLE_PAINT); - 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)); + LoadIcons(); + // TODO: This is slow on high-DPI screens. SetScrollRate(5, 5); SetBackgroundColour(*wxBLACK); Hide(); Bind(wxEVT_PAINT, &ReportPopup::OnPaint, this); + Bind(wxEVT_DPI_CHANGED, &ReportPopup::OnDPIChanged, this); } void ReportPopup::SetDoorId(int door_id) { @@ -41,14 +37,18 @@ void ReportPopup::Reset() { void ReportPopup::UpdateIndicators() { wxMemoryDC mem_dc; + wxFont the_font = GetFont().Scale(GetDPIScaleFactor()); + mem_dc.SetFont(the_font); + const std::map& report = GetDoorRequirements(door_id_); - int acc_height = 10; + int acc_height = FromDIP(10); int col_width = 0; for (const auto& [text, obtained] : report) { wxSize item_extent = mem_dc.GetTextExtent(text); - int item_height = std::max(32, item_extent.GetHeight()) + 10; + int item_height = + std::max(FromDIP(32), item_extent.GetHeight()) + FromDIP(10); acc_height += item_height; if (item_extent.GetWidth() > col_width) { @@ -56,8 +56,8 @@ void ReportPopup::UpdateIndicators() { } } - int item_width = col_width + 10 + 32; - int full_width = item_width + 20; + int item_width = col_width + FromDIP(10 + 32); + int full_width = item_width + FromDIP(20); Fit(); SetVirtualSize(full_width, acc_height); @@ -68,22 +68,23 @@ void ReportPopup::UpdateIndicators() { mem_dc.SetBrush(*wxBLACK_BRUSH); mem_dc.DrawRectangle({0, 0}, {full_width, acc_height}); - mem_dc.SetFont(GetFont()); + mem_dc.SetFont(the_font); - int cur_height = 10; + int cur_height = FromDIP(10); for (const auto& [text, obtained] : report) { wxBitmap* eye_ptr = obtained ? &checked_eye_ : &unchecked_eye_; - mem_dc.DrawBitmap(*eye_ptr, wxPoint{10, cur_height}); + mem_dc.DrawBitmap(*eye_ptr, wxPoint{FromDIP(10), cur_height}); mem_dc.SetTextForeground(obtained ? *wxWHITE : *wxRED); wxSize item_extent = mem_dc.GetTextExtent(text); mem_dc.DrawText( - text, wxPoint{10 + 32 + 10, - cur_height + (32 - mem_dc.GetFontMetrics().height) / 2}); + text, wxPoint{FromDIP(10 + 32 + 10), + cur_height + + (FromDIP(32) - mem_dc.GetFontMetrics().height) / 2}); - cur_height += 10 + 32; + cur_height += FromDIP(10 + 32); } } @@ -96,3 +97,20 @@ void ReportPopup::OnPaint(wxPaintEvent& event) { event.Skip(); } + +void ReportPopup::OnDPIChanged(wxDPIChangedEvent& event) { + LoadIcons(); + UpdateIndicators(); +} + +void ReportPopup::LoadIcons() { + // TODO: We do not have to read these in and scale them for every single + // popup. + unchecked_eye_ = + wxBitmap(wxImage(GetAbsolutePath("assets/unchecked.png").c_str(), + wxBITMAP_TYPE_PNG) + .Scale(FromDIP(32), FromDIP(32))); + checked_eye_ = wxBitmap( + wxImage(GetAbsolutePath("assets/checked.png").c_str(), wxBITMAP_TYPE_PNG) + .Scale(FromDIP(32), FromDIP(32))); +} diff --git a/src/report_popup.h b/src/report_popup.h index 9e141bf..4ccc913 100644 --- a/src/report_popup.h +++ b/src/report_popup.h @@ -19,6 +19,9 @@ class ReportPopup : public wxScrolledCanvas { private: void OnPaint(wxPaintEvent& event); + void OnDPIChanged(wxDPIChangedEvent& event); + + void LoadIcons(); int door_id_ = -1; diff --git a/src/subway_map.cpp b/src/subway_map.cpp index c554b16..f742d12 100644 --- a/src/subway_map.cpp +++ b/src/subway_map.cpp @@ -50,7 +50,7 @@ SubwayMap::SubwayMap(wxWindow *parent) : wxPanel(parent, wxID_ANY) { Bind(wxEVT_LEFT_DOWN, &SubwayMap::OnMouseClick, this); Bind(wxEVT_TIMER, &SubwayMap::OnTimer, this); - zoom_slider_ = new wxSlider(this, wxID_ANY, 0, 0, 8, {15, 15}); + zoom_slider_ = new wxSlider(this, wxID_ANY, 0, 0, 8, FromDIP(wxPoint{15, 15})); zoom_slider_->Bind(wxEVT_SLIDER, &SubwayMap::OnZoomSlide, this); help_button_ = new wxButton(this, wxID_ANY, "Help"); @@ -252,6 +252,9 @@ void SubwayMap::OnPaint(wxPaintEvent &event) { SetZoomPos({zoom_x_, zoom_y_}); SetUpHelpButton(); + + zoom_slider_->SetSize(FromDIP(15), FromDIP(15), wxDefaultCoord, + wxDefaultCoord, wxSIZE_AUTO); } wxBufferedPaintDC dc(this); @@ -620,6 +623,8 @@ void SubwayMap::Redraw() { } void SubwayMap::SetUpHelpButton() { + help_button_->SetSize(wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, + wxDefaultCoord, wxSIZE_AUTO); help_button_->SetPosition({ GetSize().GetWidth() - help_button_->GetSize().GetWidth() - 15, 15, diff --git a/src/tracker_panel.cpp b/src/tracker_panel.cpp index 3f51cd5..81b58cc 100644 --- a/src/tracker_panel.cpp +++ b/src/tracker_panel.cpp @@ -66,9 +66,9 @@ void TrackerPanel::SetPanelsMode() { panels_mode_ = true; } void TrackerPanel::SetSavedataPath(std::string savedata_path) { if (!savedata_path_) { - wxButton *refresh_button = - new wxButton(this, wxID_ANY, "Refresh", {15, 15}); - refresh_button->Bind(wxEVT_BUTTON, &TrackerPanel::OnRefreshSavedata, this); + refresh_button_ = new wxButton(this, wxID_ANY, "Refresh"); + refresh_button_->Bind(wxEVT_BUTTON, &TrackerPanel::OnRefreshSavedata, this); + SetUpRefreshButton(); } savedata_path_ = savedata_path; @@ -97,6 +97,10 @@ void TrackerPanel::RefreshSavedata() { void TrackerPanel::OnPaint(wxPaintEvent &event) { if (GetSize() != rendered_.GetSize()) { Redraw(); + + if (refresh_button_ != nullptr) { + SetUpRefreshButton(); + } } wxBufferedPaintDC dc(this); @@ -316,3 +320,8 @@ void TrackerPanel::Redraw() { area.popup->SetPosition({popup_x, popup_y}); } } + +void TrackerPanel::SetUpRefreshButton() { + refresh_button_->SetSize(FromDIP(15), FromDIP(15), wxDefaultCoord, + wxDefaultCoord, wxSIZE_AUTO); +} diff --git a/src/tracker_panel.h b/src/tracker_panel.h index 822d181..b7067f5 100644 --- a/src/tracker_panel.h +++ b/src/tracker_panel.h @@ -48,11 +48,15 @@ class TrackerPanel : public wxPanel { void RefreshSavedata(); + void SetUpRefreshButton(); + wxImage map_image_; wxImage player_image_; wxBitmap rendered_; wxBitmap scaled_player_; + wxButton *refresh_button_ = nullptr; + int offset_x_ = 0; int offset_y_ = 0; double scale_x_ = 0; -- cgit 1.4.1