From 2263961d4de14fdca5ecbc48de480107e3122f39 Mon Sep 17 00:00:00 2001 From: Jonathan Li Date: Mon, 7 Sep 2015 17:58:36 +0100 Subject: [PATCH 1/5] gui: Simplify and rework EmbeddedImage class The wxImage Scale/Rescale methods with wxIMAGE_QUALITY_HIGH upsamples and downsamples using the bicubic and box resampling methods respectively, so let's just use that instead of the ResampleBox method, which is undocumentated and probably shouldn't be used. The Rescale function also modified the image when it was not supposed to. Fix it, and rename it scale to avoid confusion with the wxWidgets class. --- pcsx2/gui/Resources/EmbeddedImage.h | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/pcsx2/gui/Resources/EmbeddedImage.h b/pcsx2/gui/Resources/EmbeddedImage.h index b68199802d..91051ecd08 100644 --- a/pcsx2/gui/Resources/EmbeddedImage.h +++ b/pcsx2/gui/Resources/EmbeddedImage.h @@ -26,8 +26,7 @@ class IEmbeddedImage { public: virtual const wxImage& Get()=0; - virtual wxImage Rescale( int width, int height )=0; - virtual wxImage Resample( int width, int height )=0; + virtual wxImage Scale( int width, int height )=0; }; ////////////////////////////////////////////////////////////////////////////////////////// @@ -59,7 +58,7 @@ protected: m_Image.LoadFile( joe, ImageType::GetFormat() ); if( m_ResampleTo.IsFullySpecified() && ( m_ResampleTo.GetWidth() != m_Image.GetWidth() || m_ResampleTo.GetHeight() != m_Image.GetHeight() ) ) - m_Image = m_Image.ResampleBox( m_ResampleTo.GetWidth(), m_ResampleTo.GetHeight() ); + m_Image.Rescale( m_ResampleTo.GetWidth(), m_ResampleTo.GetHeight(), wxIMAGE_QUALITY_HIGH ); } } @@ -107,31 +106,15 @@ public: // ------------------------------------------------------------------------ // Performs a pixel resize of the loaded image and returns a new image handle (EmbeddedImage - // is left unmodified). Useful for creating ugly versions of otherwise nice graphics. Do - // us all a favor and use Resample() instead. + // is left unmodified). // - // (this method included for sake of completeness only). - // - wxImage Rescale( int width, int height ) - { - _loadImage(); - if( width != m_Image.GetWidth() || height != m_Image.GetHeight() ) - return m_Image.Rescale( width, height ); - else - return m_Image; - } - // ------------------------------------------------------------------------ - // Implementation Note: This function uses wxWidgets ResampleBox method to resize the image. - // wxWidgets ResampleBicubic appears to be buggy and produces fairly poor results when down- - // sampling images (basically resembles a pixel resize). ResampleBox produces much cleaner - // results. - // - wxImage Resample( int width, int height ) + wxImage Scale( int width, int height ) { _loadImage(); + // Not strictly necessary - wxWidgets does the dimensions check anyway. if( width != m_Image.GetWidth() || height != m_Image.GetHeight() ) - return m_Image.ResampleBox( width, height ); + return m_Image.Scale( width, height, wxIMAGE_QUALITY_HIGH ); else return m_Image; } From 5cf94e5a15705bf0296047f63f7bb01726732444 Mon Sep 17 00:00:00 2001 From: Jonathan Li Date: Sun, 6 Sep 2015 21:08:14 +0100 Subject: [PATCH 2/5] gui: Allow screenshot icon to be themed. The logo and all the other icons can apparently be themed (though theming is a bit broken). Let's allow the camera screenshot to be themed as well. --- pcsx2/gui/App.h | 2 ++ pcsx2/gui/AppRes.cpp | 28 +++++++++++++++++++ pcsx2/gui/Dialogs/BaseConfigurationDialog.cpp | 5 +--- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/pcsx2/gui/App.h b/pcsx2/gui/App.h index 1018b702b9..40dc665655 100644 --- a/pcsx2/gui/App.h +++ b/pcsx2/gui/App.h @@ -242,6 +242,7 @@ public: ScopedPtr ToolbarImages; ScopedPtr IconBundle; ScopedPtr Bitmap_Logo; + ScopedPtr ScreenshotBitmap; ScopedPtr GameDB; pxAppResources(); @@ -559,6 +560,7 @@ public: pxAppResources& GetResourceCache(); const wxIconBundle& GetIconBundle(); const wxBitmap& GetLogoBitmap(); + const wxBitmap& GetScreenshotBitmap(); wxImageList& GetImgList_Config(); wxImageList& GetImgList_Toolbars(); diff --git a/pcsx2/gui/AppRes.cpp b/pcsx2/gui/AppRes.cpp index 8d0d6f60b7..0585df3e76 100644 --- a/pcsx2/gui/AppRes.cpp +++ b/pcsx2/gui/AppRes.cpp @@ -23,6 +23,7 @@ #include "Resources/EmbeddedImage.h" #include "Resources/BackgroundLogo.h" +#include "Resources/ButtonIcon_Camera.h" #include "Resources/ConfigIcon_Cpu.h" #include "Resources/ConfigIcon_Video.h" @@ -149,6 +150,28 @@ const wxBitmap& Pcsx2App::GetLogoBitmap() return *logo; } +const wxBitmap& Pcsx2App::GetScreenshotBitmap() +{ + ScopedPtr& screenshot(GetResourceCache().ScreenshotBitmap); + if (screenshot) return *screenshot; + + wxFileName mess; + bool useTheme = (g_Conf->DeskTheme != L"default"); + + if (useTheme) + { + wxDirName theme(PathDefs::GetThemes() + g_Conf->DeskTheme); + mess = theme.ToString(); + } + + wxImage img; + EmbeddedImage temp; // because gcc can't allow non-const temporaries. + LoadImageAny(img, useTheme, mess, L"ButtonIcon_Camera", temp); + screenshot = new wxBitmap(img); + + return *screenshot; +} + wxImageList& Pcsx2App::GetImgList_Config() { ScopedPtr& images( GetResourceCache().ConfigImages ); @@ -168,6 +191,11 @@ wxImageList& Pcsx2App::GetImgList_Config() // GCC Specific: wxT() macro is required when using string token pasting. For some // reason L generates syntax errors. >_< + // TODO: This can be fixed with something like + // #define L_STR(x) L_STR2(x) + // #define L_STR2(x) L ## x + // but it's probably best to do it everywhere at once. wxWidgets + // recommends not to use it since v2.9.0. #undef FancyLoadMacro #define FancyLoadMacro( name ) \ diff --git a/pcsx2/gui/Dialogs/BaseConfigurationDialog.cpp b/pcsx2/gui/Dialogs/BaseConfigurationDialog.cpp index 96b3e336e0..962015dd71 100644 --- a/pcsx2/gui/Dialogs/BaseConfigurationDialog.cpp +++ b/pcsx2/gui/Dialogs/BaseConfigurationDialog.cpp @@ -22,9 +22,6 @@ #include "ModalPopups.h" #include "Panels/ConfigurationPanels.h" -#include "Resources/EmbeddedImage.h" -#include "Resources/ButtonIcon_Camera.h" - #include #include #include @@ -187,7 +184,7 @@ void Dialogs::BaseConfigurationDialog::AddOkCancel( wxSizer* sizer ) if( wxWindow* apply = FindWindow( wxID_APPLY ) ) apply->Disable(); SomethingChanged_StateModified_IsChanged(); - wxBitmapButton& screenshotButton( *new wxBitmapButton( this, wxID_SAVE, EmbeddedImage().Get() ) ); + wxBitmapButton& screenshotButton(*new wxBitmapButton(this, wxID_SAVE, wxGetApp().GetScreenshotBitmap())); screenshotButton.SetToolTip( _("Saves a snapshot of this settings panel to a PNG file.") ); *m_extraButtonSizer += screenshotButton|pxMiddle; From 59ffed85ba297dc77721d3a2d8cd6dae44073e3c Mon Sep 17 00:00:00 2001 From: Jonathan Li Date: Mon, 7 Sep 2015 18:28:33 +0100 Subject: [PATCH 3/5] gui: Fix image list scaling The listbook images aren't rescaled unless the embedded icons are used. Make sure all the images are correctly rescaled. --- pcsx2/gui/AppRes.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pcsx2/gui/AppRes.cpp b/pcsx2/gui/AppRes.cpp index 0585df3e76..e4e52eeeb8 100644 --- a/pcsx2/gui/AppRes.cpp +++ b/pcsx2/gui/AppRes.cpp @@ -177,7 +177,8 @@ wxImageList& Pcsx2App::GetImgList_Config() ScopedPtr& images( GetResourceCache().ConfigImages ); if( !images ) { - images = new wxImageList(32, 32); + int image_size = g_Conf->Listbook_ImageSize; + images = new wxImageList(image_size, image_size); wxFileName mess; bool useTheme = (g_Conf->DeskTheme != L"default"); @@ -200,10 +201,10 @@ wxImageList& Pcsx2App::GetImgList_Config() #undef FancyLoadMacro #define FancyLoadMacro( name ) \ { \ - EmbeddedImage temp( g_Conf->Listbook_ImageSize, g_Conf->Listbook_ImageSize ); \ - m_Resources->ImageId.Config.name = images->Add( LoadImageAny( \ - img, useTheme, mess, L"ConfigIcon_" wxT(#name), temp ) \ - ); \ + EmbeddedImage temp; \ + LoadImageAny(img, useTheme, mess, L"ConfigIcon_" wxT(#name), temp); \ + img.Rescale(image_size, image_size, wxIMAGE_QUALITY_HIGH); \ + m_Resources->ImageId.Config.name = images->Add(img); \ } FancyLoadMacro( Paths ); From bcc125ceb647b9a76b3012f98c99e00d4ab2d088 Mon Sep 17 00:00:00 2001 From: Jonathan Li Date: Mon, 7 Sep 2015 18:33:14 +0100 Subject: [PATCH 4/5] gui:windows: Implement image DPI scaling This should reproduce the old non-DPI aware pre-wxWidgets 3.0 behaviour for the main dialogs, except the font rendering should be better. And add comments that I should have already added but didn't. --- pcsx2/gui/AppRes.cpp | 11 ++++++++--- pcsx2/gui/MSWstuff.cpp | 4 +++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/pcsx2/gui/AppRes.cpp b/pcsx2/gui/AppRes.cpp index e4e52eeeb8..7621378bb6 100644 --- a/pcsx2/gui/AppRes.cpp +++ b/pcsx2/gui/AppRes.cpp @@ -21,6 +21,8 @@ #include #include +#include "MSWstuff.h" + #include "Resources/EmbeddedImage.h" #include "Resources/BackgroundLogo.h" #include "Resources/ButtonIcon_Camera.h" @@ -145,7 +147,8 @@ const wxBitmap& Pcsx2App::GetLogoBitmap() wxImage img; EmbeddedImage temp; // because gcc can't allow non-const temporaries. LoadImageAny( img, useTheme, mess, L"BackgroundLogo", temp ); - logo = new wxBitmap( img ); + float scale = MSW_GetDPIScale(); // 1.0 for non-Windows + logo = new wxBitmap(img.Scale(img.GetWidth() * scale, img.GetHeight() * scale, wxIMAGE_QUALITY_HIGH)); return *logo; } @@ -167,7 +170,8 @@ const wxBitmap& Pcsx2App::GetScreenshotBitmap() wxImage img; EmbeddedImage temp; // because gcc can't allow non-const temporaries. LoadImageAny(img, useTheme, mess, L"ButtonIcon_Camera", temp); - screenshot = new wxBitmap(img); + float scale = MSW_GetDPIScale(); // 1.0 for non-Windows + screenshot = new wxBitmap(img.Scale(img.GetWidth() * scale, img.GetHeight() * scale, wxIMAGE_QUALITY_HIGH)); return *screenshot; } @@ -177,7 +181,7 @@ wxImageList& Pcsx2App::GetImgList_Config() ScopedPtr& images( GetResourceCache().ConfigImages ); if( !images ) { - int image_size = g_Conf->Listbook_ImageSize; + int image_size = MSW_GetDPIScale() * g_Conf->Listbook_ImageSize; images = new wxImageList(image_size, image_size); wxFileName mess; bool useTheme = (g_Conf->DeskTheme != L"default"); @@ -219,6 +223,7 @@ wxImageList& Pcsx2App::GetImgList_Config() return *images; } +// This stuff seems unused? wxImageList& Pcsx2App::GetImgList_Toolbars() { ScopedPtr& images( GetResourceCache().ToolbarImages ); diff --git a/pcsx2/gui/MSWstuff.cpp b/pcsx2/gui/MSWstuff.cpp index 2ac3fca86c..cb80736c78 100644 --- a/pcsx2/gui/MSWstuff.cpp +++ b/pcsx2/gui/MSWstuff.cpp @@ -28,11 +28,13 @@ void MSW_SetWindowAfter( WXWidget hwnd, WXWidget hwndAfter ) #endif } +// Text scales automatically on Windows but that's about it. The dialog widths +// and images need to be scaled manually. float MSW_GetDPIScale() { #ifdef __WXMSW__ HDC screen = GetDC(0); - float scale = GetDeviceCaps(screen, LOGPIXELSX) / 96.0; + float scale = GetDeviceCaps(screen, LOGPIXELSX) / 96.0; // 96.0 dpi = 100% scale ReleaseDC(NULL, screen); return scale; From d8a7bfd4382854c6ba6dc71ddaeaa724f5516f34 Mon Sep 17 00:00:00 2001 From: Jonathan Li Date: Sun, 6 Sep 2015 21:23:02 +0100 Subject: [PATCH 5/5] gui: Adjust mainframe size and status bar position There are a few odd things with Windows and the background logo. 1. The windows containing the logo is smaller than the logo. 2. The fitting algorithm doesn't work at 200% DPI. Both make no sense, but can apparently be worked around. --- pcsx2/gui/MainFrame.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pcsx2/gui/MainFrame.cpp b/pcsx2/gui/MainFrame.cpp index d1bfdbb429..41f38e9c9c 100644 --- a/pcsx2/gui/MainFrame.cpp +++ b/pcsx2/gui/MainFrame.cpp @@ -348,7 +348,9 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title) // ------------------------------------------------------------------------ - wxSize backsize( m_background.GetSize() ); + // The background logo and its window size are different on Windows. Use the + // background logo size, which is what it'll eventually be resized to. + wxSize backsize(m_background.GetBitmap().GetWidth(), m_background.GetBitmap().GetHeight()); wxString wintitle; if( PCSX2_isReleaseVersion ) @@ -385,6 +387,10 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title) wxBoxSizer& joe( *new wxBoxSizer( wxVERTICAL ) ); joe.Add( &m_background ); SetSizerAndFit( &joe ); + // Makes no sense, but this is needed for the window size to be correct for + // 200% DPI on Windows. The SetSizerAndFit is supposed to be doing the exact + // same thing. + GetSizer()->SetSizeHints(this); // Use default window position if the configured windowpos is invalid (partially offscreen) if( g_Conf->MainGuiPosition == wxDefaultPosition || !pxIsValidWindowPosition( *this, g_Conf->MainGuiPosition) )